如何在選擇目錄時也能新增目錄呢 ? |
尚未結案
|
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
請教各位 : 我現在是用 SelectDirectory("選擇目錄", "", Dir) 來開啟一個對話框,
讓使用者選擇目錄。 可是現在的問題是,使用者只能選擇目錄,卻無法新建目錄,
可是我們有些軟體裡頭,在選擇目錄的對話框裡,又有另一個按鈕可以讓使用者新建目錄。 我想請問,這要怎麼辦到呢 ? --
http://www.csie.nctu.edu.tw/~chtai/software.php
好用免費軟體的收集網頁
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
shychef
一般會員 ![]() ![]() 發表:5 回覆:10 積分:3 註冊:2004-10-02 發送簡訊給我 |
AnsiString Dir = "C:\\Program Files";
if (SelectDirectory(Dir, TSelectDirOpts() << sdAllowCreate << sdPerformCreate << sdPrompt,SELDIRHELP))
Label1->Caption = Dir; 執行後,在
Directory Name:
C:\Program Files在這後面加 \myDirectory
就會跳出對話方塊,問你是不是要新增myDirectory這個目錄
|
RedSnow
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
chtai 您好: 由 Help 對 SelectDirectory() 的說明可以知道,它有兩種方式可以呼叫,您使用的是第一種方式,但是第一種方式沒有提供 Options 的設定,而第二種方式則有提供一些設定選項,建立新目錄的選項就是其中之一,Help 的範例也有做該選項的設定,而這兩種呼叫方式的參數設定是不一樣的,如下:
extern PACKAGE bool __fastcall SelectDirectory(
const AnsiString Caption, const WideString Root,
AnsiString &Directory); extern PACKAGE bool __fastcall SelectDirectory(
AnsiString &Directory, TSelectDirOpts Options, int HelpCtx);
而這兩種方式所呼叫出來的選擇視窗,其型態也是不一樣的,如果您能接受第二種呼叫方式所產生的視窗,也就是 Help 範例所產生的對話框樣式:
#include那就 OK 了。 但是如果您想使用您現在所呼叫的那種對話框,而且也仍想要有建立新目錄的功能的話,那麼就可能要改用其它方式來處理了,我的印象中好像是與 SHBrowseForFolder() 有關,但我並不是很確定,您若是實際上需要的是這種樣式的對話框,那我就得再查查看了。 |
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
引言: AnsiString Dir = "C:\\Program Files"; if (SelectDirectory(Dir, TSelectDirOpts() << sdAllowCreate << sdPerformCreate << sdPrompt,SELDIRHELP)) Label1->Caption = Dir; 執行後,在 Directory Name: C:\Program Files在這後面加 \myDirectory 就會跳出對話方塊,問你是不是要新增myDirectory這個目錄謝謝回應, 這個我也有試過,可是它的介面太醜了, 我不喜歡。 -- http://www.csie.nctu.edu.tw/~chtai/software.php 好用免費軟體的收集網頁
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
RedSnow
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
引言: 但是如果您想使用您現在所呼叫的那種對話框,而且也仍想要有建立新目錄的功能的話,那麼就可能要改用其它方式來處理了,我的印象中好像是與 SHBrowseForFolder() 有關,但我並不是很確定,您若是實際上需要的是這種樣式的對話框,那我就得再查查看了。感謝您的回應,我也有在 help 看到它的範例了, 只可惜第二種的介面太醜了, 所以客戶要求,要用第一種的介面,然後又可以建立新目錄
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
RedSnow
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
|
RedSnow
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
chtai 您好: 以下就是我整理好的程式碼,我將 SHBrowseForFolder() 寫成一個自定函式,命名為 SetDirectory(),共使用三個參數,我僅加註了部份說明,整個函式的重點在 BROWSEINFO 及 SHBrowseForFolder(),相關用途與設定方式可參考 Help 上的說明,以便視個人的需要去做調整:
#include |
andychang1690
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:20 回覆:694 積分:442 註冊:2003-03-14 發送簡訊給我 |
幫RedSnow大大補充: bi.ulFlags = // 新式樣(BIF_NEWDIALOGSTYLE)創建一個更大的,可變大小的對話方塊,對應的按鈕是"Make New Folder"-- // 如果你指定 BIF_EDITBOX--則有一個編輯框,用戶可以敲入文件夾的名字。 // 其他標誌還有 BIF_BROWSEFORCOMPUTER,用於顯示電腦, // BIF_BROWSEFORPRINTER 用於印表機。 // BIF_RETURNONLYFSDIRS 告訴 Windows 僅返回文件系統目錄,而非偽文件夾,如網路鄰居, // BIF_STATUSTEXT 創建一個狀態視窗,你可以設置其文本。 // (新式對話方塊不支援 BIF_STATUSTEXT)。 // 完整的標誌清單請參考 BROWSEINFO 文檔。--->>>VC,不是BCB Windows SDK 請參考!Andy Chang 發表人 - andychang1690 於 2005/06/08 23:50:17
------
Andy Chang |
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
引言: bi.lpfn = reinterpret_cast繼續請教,這兩句是什麼意思呢 ? 我看了看 MSDN, 不是只要設定 bi 裡的 pidlRoot 就可以指定起始目錄了嗎 ? -- http://www.csie.nctu.edu.tw/~chtai/software.php 好用免費軟體的收集網頁
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
andychang1690
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:20 回覆:694 積分:442 註冊:2003-03-14 發送簡訊給我 |
[Code]chtai:
Windows API函數SHBrowseForFolder,
完整聲明為WINSHELLAPI LPITEMIDLIST WINAPI SHBrowseForFolder(LPBROWSEINFO lpbi),返回一個ITEMIDLIST類型的指標,
通過這個指標調用函數SHGetPathFromIDList可以確定所選擇的目錄的全名稱。入參為BROWSEINFO結構的指標,這個結構較為複雜,
成員如下所示:
HWND hwndOwner; // 擁有對話方塊的窗口,可以設置為Application->Handle
LPCITEMIDLIST pidlRoot; // ITEMIDLIST類型的指標,表示在哪個路徑下選擇,一般可以設置為NULL
LPSTR pszDisplayName; // 選擇後,所選目錄的名稱(不包含父級目錄)被拷貝到這個指標指向的位置
LPCSTR lpszTitle; // 作為標題顯示在對話方塊中目錄樹的上面,可以根據實際情況設置
UINT ulFlags; // 標誌位元,有點複雜,一般設置為BIF_RETURNONLYFSDIRS
BFFCALLBACK lpfn; // 回調函數,一般不用,設置為NULL
LPARAM lParam; // 預定義的對話方塊傳遞給回調函數的值
int iImage; // 與所選目錄相關聯的圖示在系統圖示集合中的索引
可以看出,使用函數SHBrowseForFolder還真麻煩 請參考! Andy Chang
------
Andy Chang |
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
多謝回應 :) 那再請教的是,若我想指定初始的選擇目錄 (例如 D:\MyApp ),
又不想用 RedSnow 大哥程式裡的那兩行 (因為我還不是很懂:p)
(我明明有 include shlobj.h 了, 它卻說 undefined symbal BrowseCallbackProc )
那要怎麼辦到才好呢 ? --
http://www.csie.nctu.edu.tw/~chtai/software.php
好用免費軟體的收集網頁 發表人 - chtai 於 2005/06/09 18:04:07
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
RedSnow
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
chtai 您好: 真是抱歉,我剪貼資料貼上來時漏了一段,今天又出門一整天,因此剛剛才看到,補上 BrowseCallbackProc() 程序如下:
int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lpData){ if(uMsg == BFFM_INITIALIZED){ PCSTR prevDir = reinterpret_cast (lpData); if(DirectoryExists(prevDir)) SendMessage(hwnd, BFFM_SETSELECTION, static_cast這一段放在 SetDirectory() 自定函式之前即可 (前一篇也補上去了,以免其他人參考時也漏掉)。 這個 CallBack 程序是必要的,否則對話框起始時會無法指向 StartDir 設定的目錄,您可以試著將 bi.lpfn 參數設為 NULL,然後比較一下有何差異就知道了。 發表人 - RedSnow 於 2005/06/09 22:28:08 |
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
引言:請問最後一行的 static_castint CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lpData){ if(uMsg == BFFM_INITIALIZED){ PCSTR prevDir = reinterpret_cast (lpData); if(DirectoryExists(prevDir)) SendMessage(hwnd, BFFM_SETSELECTION, static_cast
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
andychang1690
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:20 回覆:694 積分:442 註冊:2003-03-14 發送簡訊給我 |
chtai:我微修改RedSnow的程式相信比較簡單一些! TForm1 *Form1; AnsiString StartDirectory ; // 設定對話框起始目錄;變成全域變數 int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lpData) { if(uMsg == BFFM_INITIALIZED) return SendMessage(hwnd, BFFM_SETSELECTION, true, (LPARAM)(LPCTSTR)(StartDirectory.c_str())); else return 1; } // 使用範例 void __fastcall TForm1::Button1Click(TObject *Sender) { StartDirectory = "C:\\"; // 設定對話框起始目錄 AnsiString SelectedDirectory; // 儲存被選擇目錄的路徑字串 AnsiString DirectoryName; // 儲存被選擇目錄的名稱字串 if(SetDirectory(StartDirectory, &SelectedDirectory, &DirectoryName)){ ShowMessage("選擇目錄:" SelectedDirectory "\n目錄名稱:" DirectoryName); } } crstypes.inc Const MAX_PATH = 260 ' Max Directory Path Length 還有要注意 GlobalFree(ItemID); // 返回的ItemID佔用了系統資源,不要忘了釋放 資源一定要釋放! 請參考!Andy Chang
------
Andy Chang |
RedSnow
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
chtai 您好:
引言:請問最後一行的 static_cast (1L) 裡的 1L 是哪來的阿? 完全沒看到這個變數阿~不知道您為何會認為 1L 會是一個變數?1L 是一個採用 "後綴表示規則" 的常數,而不是什麼變數,L 是 long-suffix (長整數字尾) 的意思,1L 是代表 "長整數 1"。 引言:還有像是 MAX_PATH 也是,都是在哪定義的阿MAX_PATH 在 windef.h 裡有定義,SHBrowseForFolder() 引用 shlobj.h,而 shlobj.h 引用了其它的 .h 檔案,在一連串的引用過程中,只要其中有一檔案引用到了 windef.h 檔,MAX_PATH 就不會是未宣告的狀態。 引言:為什麼各位強者都知道這些東西怎麼用阿查閱文件 參考範例 搜尋資料 詢問 練習 .... 經驗累積 = 知道如何使用。 引言:另外,有辦法讓 StartDir 展開嗎?不知道您想要展開 StartDir 的什麼?請再描述得具體一點。 發表人 - RedSnow 於 2005/06/10 11:02:30 |
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
引言:哎呀~~對耶, 我怎麼把這基本的東西都給忘了 ... 糗了引言:請問最後一行的 static_cast (1L) 裡的 1L 是哪來的阿? 完全沒看到這個變數阿~不知道您為何會認為 1L 會是一個變數?1L 是一個採用 "後綴表示規則" 的常數,而不是什麼變數,L 是 long-suffix (長整數字尾) 的意思,1L 是代表 "長整數 1"。
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
RedSnow
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
chtai 您好: 原本查看 MSDN 的 BrowseCallbackProc 文件時,看到一個訊息類型是 BFFM_SETEXPANDED,按照文件的說明來看,應該是可以使用和 BFFM_SETSELECTION 相同的參數,然後交由 SendMessage() 來設定截點的展開動作,但我就是試不出來,不知是否與 Shell DLL 的版本有關?
#define BFFM_SETEXPANDED (WM_USER 106) SendMessage(hwnd, BFFM_SETEXPANDED, static_cast因此我改用其它方式,先設法取得對話框上 TreeView 的 Handle 值,然後再取得被圈選的節點,最後再展開節點,以下是我加上節點展開處理後的 BrowseCallbackProc: int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM wParam, LPARAM lpData){ if(uMsg == BFFM_INITIALIZED){ PCSTR prevDir = reinterpret_cast (lpData); if(DirectoryExists(prevDir)){ SendMessage(hwnd, BFFM_SETSELECTION, static_cast以上程序在我的環境可以正常運作,但是因為兩個 GetDlgItem() 函式的物件代碼 (0 與 0x64) 都是以 SPY 取得的,不知其是否具備固定性?因此請您自行測試一下 (包含 BFFM_SETEXPANDED 的 SendMessage 也可以試試看),看是否能達到您的需求? |
chtai
高階會員 ![]() ![]() ![]() ![]() 發表:68 回覆:238 積分:116 註冊:2004-05-21 發送簡訊給我 |
引言: 以上程序在我的環境可以正常運作,但是因為兩個 GetDlgItem() 函式的物件代碼 (0 與 0x64) 都是以 SPY 取得的,不知其是否具備固定性?因此請您自行測試一下 (包含 BFFM_SETEXPANDED 的 SendMessage 也可以試試看),看是否能達到您的需求?報告: 物件代碼 (0 與 0x64) 在我的電腦 (WinXP SP2 BCB6) 可以正常執行。 可是 BFFM_SETEXPANDED 無效,真是奇也怪哉~ 若有其他前輩知道原因,還望不吝指點一二
------
My Web: http://nelson.csie.us My Blog: http://blog.nelson.csie.us |
licheer
一般會員 ![]() ![]() 發表:23 回覆:20 積分:8 註冊:2007-08-19 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |