我知道这个帖子很旧,但我最近遇到了同样的问题。
我发现当单击 OK 按钮时,对话框会发出 CDN_FOLDERCHANGE 消息,但文件夹实际上没有更改(与上次调用时相同)。
所以我想出了下面的钩子程序:
UINT_PTR CALLBACK openfilename_cb (
HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
NMHDR *nmhdr;
OFNOTIFY *ofnotify;
static char dir_now[PATH_MAX], dir_prev[PATH_MAX];
do_debug (5, "openfilename_cb(): hwnd=%p, msg=%d\n", hwnd, msg);
switch (msg)
{
case WM_INITDIALOG:
do_debug (2, "openfilename_cb(): WM_INITDIALOG\n");
break;
case WM_NOTIFY:
ofnotify = (OFNOTIFY *)lParam;
nmhdr = &ofnotify->hdr;
do_debug (4,"openfilename_cb(): WM_NOTIFY, hwnd=%p, id=%d, code=%d\n",
nmhdr->hwndFrom, nmhdr->idFrom, nmhdr->code);
switch (nmhdr->code)
{
case CDN_INITDONE:
do_debug (3, "openfilename_cb(): CDN_INITDONE\n");
dir_prev[0] = '\0';
break;
case CDN_FILEOK:
do_debug (3, "openfilename_cb(): CDN_FILEOK\n");
break;
case CDN_FOLDERCHANGE:
do_debug (3, "openfilename_cb(): CDN_FOLDERCHANGE\n");
SendMessage (nmhdr->hwndFrom, CDM_GETFOLDERPATH, sizeof(dir_now),
(LPARAM)dir_now);
do_debug (3, " directory=%s\n", dir_now);
if (ofnotify->lpOFN->lCustData & FN_OPENDIR)
{
if (stricmp(dir_now, dir_prev) == 0)
{
/* user clicked the OK button */
strncpy (ofnotify->lpOFN->lpstrFile, dir_now, PATH_MAX);
ofnotify->lpOFN->lCustData = MAGIC;
PostMessage (nmhdr->hwndFrom, WM_COMMAND, IDCANCEL, 0);
do_debug (3, " closing dialog\n");
break;
}
strncpy (dir_prev, dir_now, sizeof(dir_prev));
}
break;
case CDN_HELP:
do_debug (3, "openfilename_cb(): CDN_HELP\n");
break;
case CDN_SELCHANGE:
do_debug (3, "openfilename_cb(): CDN_SELCHANGE\n");
break;
case CDN_SHAREVIOLATION:
do_debug (3, "openfilename_cb(): CDN_SHAREVIOLATION\n");
break;
case CDN_TYPECHANGE:
do_debug (3, "openfilename_cb(): CDN_TYPECHANGE\n");
break;
} /* switch (nmhdr->code) */
break; /* WM_NOTIFY */
} /* switch (msg) */
return 0;
}
确保在 OPENFILENAME 结构标志成员中设置 OFN_ENABLEHOOK 和 OFN_EXPLORER 位,以便调用挂钩过程。当然,将 lpfnHook 成员设置为钩子函数的地址。
我发现无论是否使用钩子程序,对话框看起来都大不相同(元素的排序方式不同,左窗格中有一个树形视图与大图标,也许更多)。
你必须与你的调用函数来回沟通你想要/已经选择了一个目录。为此,我使用了 OPENFILENAME 结构的 lCustData 成员。
我使用 Windows 10 版本 19042.1052 64 位和 Windows XP 32 位进行了测试。
约翰内斯