根据文件名长度计算lpstrFile长度]

场景:

1. 使用GetOpenFileName 时, 需要预先自定义lpstrFile的长度比如,buf[1024], 但是如果选择的文件过多怎么办?总不能创建一个超大的内存空间吧,

如果选择少时又浪费内存。

2. 微软的MSDN的坏处就是不提供实际的例子,而在别的地方提供,,难道他们没遇到这类普通的问题?

3. 这里stackoverflow提供了一个微软使用lpfnHook 的例子来解决这个问题,这个例子对于unicode是有问题的,计算长度没有x2. 这个bug困扰了我半天。

找这个解决方案也找了半天。

static unsigned int CALLBACK DialogHook(HWND hwnd, UINT uMsg, WPARAM wParam,LPARAM lParam){static HWND hwndParentDialog;LPOFNOTIFY lpofn;int cbLength;static LPTSTR lpsz = NULL;static int LastLen;switch (uMsg){case WM_INITDIALOG:// You need to use a copy of the OPENFILENAME struct used to// create this dialog. You can store a pointer to the// OPENFILENAME struct in the ofn.lCustData so you can// retrieve it here in the lParam. Once you have it, you// need to hang on to it. Using window properties provides a// good thread safe solution to using a global variable.if(!SetProp(GetParent(hwnd), L"OFN", (void *) lParam))MessageBox(NULL, L"SET PRop Failed", L"ERROR", MB_OK);return (0);case WM_COMMAND:{OutputDebugString(L"command\n");}break;case WM_NOTIFY:// The OFNOTIFY struct is passed in the lParam of this// message.lpofn = (LPOFNOTIFY) lParam;switch (lpofn->hdr.code){case CDN_SELCHANGE:LPOPENFILENAME lpofn;cbLength = CommDlg_OpenSave_GetSpec(GetParent(hwnd), NULL, 0);cbLength += _MAX_PATH;// The OFN struct is stored in a property of dialog windowlpofn = (LPOPENFILENAME) GetProp(GetParent(hwnd),L"OFN");if (lpofn->nMaxFile < cbLength){// Free the previously allocated buffer.if(lpsz)HeapFree(GetProcessHeap(),0,lpsz);// Allocate a new buffer, 注意要乘以2lpsz = (LPTSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,cbLength*2);if (lpsz){lpofn->lpstrFile = lpsz;lpofn->nMaxFile = cbLength;}}break;}return (0);case WM_DESTROY:// Also need to free the property with the OPENFILENAME// struct.RemoveProp(GetParent(hwnd), L"OFN");return (0);}return (0);} void OpenSelectFileWindow(std::vector<std::wstring>& file_paths,const wchar_t* filter,const wchar_t* title){OPENFILENAME ofn = { sizeof ofn };wchar_t file[1024];file[0] = ‘\0’;ofn.lpstrFile = file;ofn.lpstrFilter = filter;ofn.nMaxFile = 1024;ofn.lpstrTitle = title;ofn.hwndOwner = m_hWnd;ofn.lpfnHook = DialogHook;ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_ENABLEHOOK;BOOL res = GetOpenFileName(&ofn);wchar_t *temp_buf = ofn.lpstrFile;if(res!=0){size_t len = lstrlen(temp_buf);//文件夹std::wstring dir;dir.append(temp_buf,len);wchar_t *pos = temp_buf+len;while(*(++pos)){len = lstrlen(pos);std::wstring path;path.append(dir).append(L"\\").append(pos,len);file_paths.push_back(path);pos+=len;}if(!file_paths.size()){//只有一个文件时,不会出现目录和文件名分开的情况.file_paths.push_back(dir);}}}

注意: 稍微不负责任点的初级程序员估计会申请超大空间解决吧。

参考:

?rq=1

https://support.microsoft.com/en-us/kb/131462

背着背包的路上,看过许多人,

根据文件名长度计算lpstrFile长度]

相关文章:

你感兴趣的文章:

标签云: