我有C ++代码来显示对话框选择器文件。我想用户只能选择指定的类型文件。我的对话框可以显示指定的类型文件,但用户可以在文件名中输入其他类型文件,如我的图片
那么,如何让用户只输入lpstrFilter
中指定的文件名和搜索类型文件?或者我可以禁用文件名框吗?
这是我的代码:
const wchar_t* ChooserFile(const char* typeFile)
{
try
{
ZeroMemory( &sfn , sizeof( sfn));
sfn.lStructSize = sizeof ( sfn );
sfn.hwndOwner = NULL ;
wchar_t w_syFile[MAX_PATH];
//mbstowcs(w_syFile, syFile, strlen(syFile)+1);//Plus null
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, w_syFile, MAX_PATH, syFile, _TRUNCATE);
sfn.lpstrFile = w_syFile ;
sfn.lpstrFile[0] = _T('\0');
sfn.nMaxFile = sizeof( syFile );
//TypeFile
sfn.lpstrFilter = TEXT("Microsoft Office Word Documents (*.xlsx)\0*.XLSX\0");
sfn.nFilterIndex =1;
sfn.lpstrFileTitle = NULL ;
sfn.nMaxFileTitle = 0 ;
sfn.lpstrInitialDir=NULL;
//sfn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT|OFN_EXPLORER | OFN_ENABLEHOOK ;
sfn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_NOVALIDATE|OFN_HIDEREADONLY ;
if (GetOpenFileName( &sfn ) != TRUE)
{
wstrPathFile = TEXT("");
return wstrPathFile.c_str();
}
DWORD retval=0;
//BOOL success;
TCHAR buffer[BUFSIZE]=TEXT("");
TCHAR buf[BUFSIZE]=TEXT("");
TCHAR** lppPart={NULL};
wchar_t wstrPath[BUFSIZE];
retval = GetFullPathNameW(sfn.lpstrFile,sfn.nMaxFile,wstrPath,lppPart);
if (retval==0)
{
wstrPathFile = TEXT("");
return wstrPathFile.c_str();
}
std::wstring s(wstrPath);
wstrPathFile = s;
wcout<<wstrPathFile<<endl;
return wstrPathFile.c_str();
}
catch (...)
{
PrintToFile("ChooserFile","Error");
wstrPathFile = TEXT("");
return wstrPathFile.c_str();
}
}
答案 0 :(得分:4)
我想用户只能选择指定的文件类型。
您无法通过在文件名编辑控件中输入来阻止用户选择他们喜欢的任何文件。因此,您应该让他们这样做,而是验证文件名是否符合您的要求。
你有几个选择:
lpfnHook
结构的OPENFILENAME
成员中提供钩子过程。当用户尝试接受文件时,会收到CDN_FILEOK
通知消息。执行验证以响应该消息。如果文件名不符合要求,则显示该效果的消息并返回非零值以强制对话框保持打开状态。答案 1 :(得分:0)
您的代码正在评论OFN_EXPLORER
和OFN_ENABLEHOOK
标记,因此您必须已经了解Explorer-style hooking的存在。正如其他人告诉您的那样,您可以使用该钩子来捕获CDN_FILEOK
通知以接受/拒绝所选文件名。例如:
UINT_PTR CALLBACK MyOFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
if (uiMsg == WM_NOTIFY)
{
LPOFNOTIFY ofn = (LPOFNOTIFY) lParam;
if (ofn->hdr.code == CDN_FILEOK)
{
LPOPENFILENAMEW lpOFN = (LPOPENFILENAMEW) ofn->lpOFN;
LPWSTR lpExt = PathFindExtensionW(lpOFN->lpstrFile);
if (lstrcmpiW(lpExt, L".XLSX") != 0)
{
SetWindowLongPtr(hdlg, DWL_MSGRESULT, 1);
return 1;
}
}
}
return 0;
}
std::wstring ChooserFile(const char* typeFile)
{
OPENFILEAMEW sfn = {0};
wchar_t w_syFile[MAX_PATH+1] = {0};
size_t convertedChars = 0;
sfn.lStructSize = sizeof(sfn);
sfn.hwndOwner = NULL;
mbstowcs_s(&convertedChars, w_syFile, MAX_PATH, syFile, _TRUNCATE);
sfn.lpstrFile = w_syFile;
sfn.nMaxFile = MAX_PATH;
//TypeFile
sfn.lpstrFilter = L"Microsoft Office Word Documents (*.xlsx)\0*.XLSX\0";
sfn.nFilterIndex = 1;
sfn.lpstrFileTitle = NULL;
sfn.nMaxFileTitle = 0;
sfn.lpstrInitialDir = NULL;
sfn.lpfnHook = &MyOFNHookProc;
sfn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOVALIDATE | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLEHOOK;
if (!GetOpenFileNameW(&sfn))
return L"";
WCHAR szPath[MAX_PATH+1] = {0};
DWORD retval = GetFullPathNameW(sfn.lpstrFile, MAX_PATH, szPath, NULL);
if ((retval == 0) || (retval > MAX_PATH))
return L"";
std::wstring wstrPath(szPath, retval);
std::wcout << wstrPath << endl;
return wstrPath;
}