调用 Win32 应用时崩溃"GetOpenFileName"



我有一个win32程序,我想调用GetOpenFileName(),但每次它崩溃和CommDlgExtendedError()返回错误代码为1008。请帮帮我。

char Filestring[MAX_PATH] = "";
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile = (LPWSTR)Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn) == TRUE)
{
}
else
{
int err = CommDlgExtendedError();
}

您正在使用GetOpenFileName()API的TCHAR版本,它映射到ANSI (GetOpenFileNameA())或Unicode (GetOpenFileNameW()) API,具体取决于是否定义了UNICODE

由于ofn.lpstrFile正在接受LPWSTR(wchar_t*)指针,期望它指向wchar[]缓冲区,因此您的项目明确定义了UNICODE。但是你给它一个指向char[]缓冲区的类型转换指针,它有1/2的存储空间,而不是你告诉API可供它写入。

您对ofn.lpstrFile字段的类型强制转换依赖于API。代码正在调用Unicode API,因此它将Unicode数据写入char[]缓冲区,为您提供mojibake输出,并冒缓冲区溢出的风险。

你应该使用TCHAR[]缓冲区来匹配API的期望,例如:

TCHAR Filestring[MAX_PATH] = TEXT("");
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileName(&ofn))
{
...
}
else
{
int err = CommDlgExtendedError();
...
}

否则,根据所需的字符编码显式使用ANSI或Unicode API,例如:

CHAR Filestring[MAX_PATH] = "";
OPENFILENAMEA ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileNameA(&ofn))
{
...
}
else
{
int err = CommDlgExtendedError();
...
}
WCHAR Filestring[MAX_PATH] = L"";
OPENFILENAMEW ofn = { 0 };
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = Filestring;
ofn.nMaxFile = MAX_PATH;
if (GetOpenFileNameW(&ofn))
{
...
}
else
{
int err = CommDlgExtendedError();
...
}

最新更新