Hi,
The Windows API function to select a directory is really bad, so I'm trying to use GetOpenFileName() instead.
For that, the idea is to set a hook function, so that when the user hits the OK button without having actually selected a file, the hook function retrieves the currently selected folder, and closes the dialog.
The initial file filter is the 0x01 character (not shown below, but it's there), so that the dialog is only showing folders, allowing the user to navigate them without seing the files.
Here is the code I'm trying to use:
#include <windows.h>
#include <stdio.h>
UINT_PTR CALLBACK OFNHookProc(
_In_ HWND hdlg,
_In_ UINT uiMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
int i, idCtrl, lTime;
NMHDR *pnmh;
OFNOTIFY *pnot;
char buff[2000];
switch (uiMsg)
{ case WM_NOTIFY:
i = 0;
pnot = (OFNOTIFY *)lParam;
pnmh = &pnot->hdr;
switch(pnmh->code)
{ case CDN_FILEOK:
i = CommDlg_OpenSave_GetFolderPath(hdlg, buff, 2000);
break;
case CDN_FOLDERCHANGE:
i = CommDlg_OpenSave_GetFolderPath(hdlg, buff, 2000);
lTime = GetCurrentTime () ;
PostMessage (hdlg, IDCANCEL, 0, lTime);
break;
}
break;
}
return(0);
}
void main(int argc, char **argv)
{
OPENFILENAME ofn; // common dialog box structure
char szFile[260]; // buffer for file name
HWND hwnd; // owner window
HANDLE hf; // file handle
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "Folders\\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ENABLEHOOK |OFN_EXPLORER|OFN_ENABLESIZING;
ofn.lpfnHook = OFNHookProc;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)==TRUE)
hf = CreateFile(ofn.lpstrFile,
GENERIC_READ,
0,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
}
I'm having 4 problems here:
The displayed dialog box is the pre-W7 dialog one, rather than the new one displayed when "OFN_ENABLEHOOK |OFN_EXPLORER" is not used.
The "case CDN_FILEOK" part is never reached. Whatever the user action, it always goes to "case CDN_FOLDERCHANGE".
"i = CommDlg_OpenSave_GetFolderPath(hdlg, buff, 2000);" does not work. i is set to 0, and buff is not updated with the current folder.
"PostMessage (hdlg, IDCANCEL, 0, lTime);" does not make the dialog return.
So, basically, nothing work. :)
I'm probably missing something vey obvious, any idea?
Here are the links that helped me write this useless code:
http://winapi.freetechsecrets.com/win32/WIN32CDMGETFOLDERPATH_New__Windows_NT.htm
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646960(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms646951(v=vs.85).aspx
http://winapi.freetechsecrets.com/win32/WIN32ExplorerStyle_Hook_Procedures.htm
Any help be greatly appreciated.