LPCWSTR返回字符串首字符异常问题求助
问题修复:Common Item Dialog返回路径首字符乱码
核心错误分析与修复步骤
- 数组指针类型不匹配:对话框过程中
String = &StringBuffer;是错误赋值,&StringBuffer是指向整个数组的指针,而非数组首地址。应改为String = StringBuffer;,直接让指针指向数组起始位置。 - GetDisplayName参数误用:
OpenDirectory里LPCWSTR pszFilePath = &Buffer;同样类型错误,且GetDisplayName会自动分配内存,无需绑定本地数组。应初始化为NULL,由函数返回分配好的字符串指针。 - 悬空指针问题:赋值返回指针后立即调用
CoTaskMemFree(pszFilePath),导致外部指针指向已释放的内存,出现乱码。需先将字符串复制到外部缓冲区,再释放内存。
修改后的完整代码
LPNMHDR pnmh = (LPNMHDR)lParam; HWND Parent = GetParent(hDialog); wchar_t StringBuffer[150] = {0}; // 直接初始化数组为0,替代循环赋值 LPCWSTR String = StringBuffer; // 正确指向数组首地址 switch (Message) { case WM_INITDIALOG: return FALSE; case WM_NOTIFY: { switch (pnmh->code) { case PSN_SETACTIVE: PropSheet_SetWizButtons(Parent, PSWIZB_NEXT | PSWIZB_BACK | PSWIZB_CANCEL); return FALSE; } return FALSE; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_PjDirBrowse: { switch (HIWORD(wParam)) { case BN_CLICKED: OpenDirectory(&String); if (String != NULL && String[0] != L'\0') // 增加空字符串判断 { Environment.ProjectPath = String; SetDlgItemTextW(hDialog, IDC_EDIT1, String); } return FALSE; } } return FALSE; } return FALSE; } } return FALSE; } // 修正后的OpenDirectory函数 void OpenDirectory(LPCWSTR* ReturnString) { //CoCreate Folder Open Dialog Object IFileDialog* pfd = NULL; HRESULT hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, &IID_IFileOpenDialog, &pfd); if (SUCCEEDED(hr)) { //flags DWORD dwFlags; hr = pfd->lpVtbl->GetOptions(pfd, &dwFlags); if (SUCCEEDED(hr)) { hr = pfd->lpVtbl->SetOptions(pfd, dwFlags | FOS_FORCEFILESYSTEM | FOS_PICKFOLDERS); if (SUCCEEDED(hr)) { IShellItem* MyDocuments; hr = SHGetKnownFolderItem(&FOLDERID_DocumentsLibrary, KF_FLAG_DEFAULT, NULL, &IID_IShellItem, &MyDocuments); if (SUCCEEDED(hr)) { hr = pfd->lpVtbl->SetFolder(pfd, MyDocuments); if (SUCCEEDED(hr)) { hr = pfd->lpVtbl->Show(pfd, NULL); if (SUCCEEDED(hr)) { IShellItem* psiResult; hr = pfd->lpVtbl->GetResult(pfd, &psiResult); if (SUCCEEDED(hr)) { LPCWSTR pszFilePath = NULL; // 初始化为NULL,由函数分配内存 hr = psiResult->lpVtbl->GetDisplayName(psiResult, SIGDN_FILESYSPATH, &pszFilePath); if (SUCCEEDED(hr)) { TaskDialog(NULL, NULL, L"CommonFileDialogApp", pszFilePath, NULL, TDCBF_OK_BUTTON, TD_INFORMATION_ICON, NULL); // 将字符串复制到外部缓冲区,避免悬空指针 if (ReturnString != NULL && *ReturnString != NULL) { wcscpy_s((wchar_t*)*ReturnString, 150, pszFilePath); } CoTaskMemFree(pszFilePath); // 现在释放才安全 } psiResult->lpVtbl->Release(psiResult); } } } MyDocuments->lpVtbl->Release(MyDocuments); } } } pfd->lpVtbl->Release(pfd); } }
内容的提问来源于stack exchange,提问作者Dave B.
相关产品推荐
相关产品推荐

