C++ 调用GetOpenFileNameA会导致常见对话框错误2
我正在尝试使用GetOpenFileNameA打开一个对话框。但是,该对话框不会打开。相反,我得到了一个很好的通讯错误2。在Google和StackOverflow中搜索此错误并没有产生任何有用的结果 令人困惑的是,这段代码在同样使用VisualStudio的学校计算机上运行,尽管版本不同 注意:此代码块中未声明的所有变量都是“全局”变量,只能在主代码模块中访问C++ 调用GetOpenFileNameA会导致常见对话框错误2,c++,winapi,C++,Winapi,我正在尝试使用GetOpenFileNameA打开一个对话框。但是,该对话框不会打开。相反,我得到了一个很好的通讯错误2。在Google和StackOverflow中搜索此错误并没有产生任何有用的结果 令人困惑的是,这段代码在同样使用VisualStudio的学校计算机上运行,尽管版本不同 注意:此代码块中未声明的所有变量都是“全局”变量,只能在主代码模块中访问 void GetInputFile() { char szFileNameIN[MAX_PATH]; char szF
void GetInputFile()
{
char szFileNameIN[MAX_PATH];
char szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAME ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = LPWSTR("Any File\0*.*\0");
ofn.lpstrFile = LPWSTR(fInputPath);
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = LPWSTR(szFileNameIN);
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = LPWSTR("Select an input File");
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(LPOPENFILENAMEA(&ofn))) // user selected an input file
{
}
else {
// Get error
TCHAR error[MAX_LOADSTRING];
wsprintf(error,TEXT("%i"),CommDlgExtendedError());
MessageBox(NULL,error,TEXT("ERROR"),MB_OK);
}
}
那些糟糕的(LPWSTR)
类型转换告诉我,您正在使用定义的UNICODE
进行编译,因此您使用的OPENFILENAME
结构实际上是OPENFILENAMEW
;如果您使用的是GetOpenFileNameA
,则必须使用OPENFILENAMEA
(或者使用带有宽字符串的直接GetOpenFileName
)
(请记住,根据经验法则,如果您必须从不同于void*
或类似对象的任何对象强制转换指针,则可能是做错了什么;添加指针强制转换只会使编译器沉默,而不会使错误消失)那些可怕的(LPWSTR)
cast告诉我您是使用定义的UNICODE
编译的,因此您使用的OPENFILENAME
结构实际上是OPENFILENAMEW
;如果您使用的是GetOpenFileNameA
,则必须使用OPENFILENAMEA
(或者使用带有宽字符串的直接GetOpenFileName
)
(请记住,根据经验法则,如果您必须从不同于
void*
或类似的对象中投射指针,则可能是做错了什么;添加指针投射只会使编译器静音,而不会使错误消失)您使用的是OPENFILENAME
版本的TCHAR
。由于您将Unicode字符串指针分配给其字段,这意味着您的项目是在定义了Unicode
的情况下编译的,因此TCHAR
映射到wchar\u t
,OPENFILENAME
映射到OPENFILENAMEW
。但是您使用的是ANSI字符缓冲区和ANSI版本的GetOpenFileName()
,并且到处都使用不正确的类型转换
因此,请删除所有类型强制转换,然后:
TCHAR
类型和API:
void GetInputFile()
{
TCHAR szFileNameIN[MAX_PATH];
TCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAME ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = TEXT("Any File\0*.*\0");
ofn.lpstrFile = fInputPath; // must be TCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = TEXT("Select an input File");
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)) // user selected an input file
{
}
else
{
// Get error
TCHAR error[MAX_LOADSTRING];
wsprintf(error, TEXT("%i"), CommDlgExtendedError());
MessageBox(NULL, error, TEXT("ERROR"), MB_OK);
}
}
void GetInputFile()
{
WCHAR szFileNameIN[MAX_PATH];
WCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAMEW ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = L"Any File\0*.*\0";
ofn.lpstrFile = fInputPath; // must be WCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = L"Select an input File";
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameW(&ofn)) // user selected an input file
{
}
else
{
// Get error
WCHAR error[MAX_LOADSTRING];
wsprintfW(error, L"%i", CommDlgExtendedError());
MessageBoxW(NULL, error, L"ERROR", MB_OK);
}
}
CHAR
/WCHAR
类型和API:
void GetInputFile()
{
TCHAR szFileNameIN[MAX_PATH];
TCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAME ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = TEXT("Any File\0*.*\0");
ofn.lpstrFile = fInputPath; // must be TCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = TEXT("Select an input File");
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)) // user selected an input file
{
}
else
{
// Get error
TCHAR error[MAX_LOADSTRING];
wsprintf(error, TEXT("%i"), CommDlgExtendedError());
MessageBox(NULL, error, TEXT("ERROR"), MB_OK);
}
}
void GetInputFile()
{
WCHAR szFileNameIN[MAX_PATH];
WCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAMEW ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = L"Any File\0*.*\0";
ofn.lpstrFile = fInputPath; // must be WCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = L"Select an input File";
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameW(&ofn)) // user selected an input file
{
}
else
{
// Get error
WCHAR error[MAX_LOADSTRING];
wsprintfW(error, L"%i", CommDlgExtendedError());
MessageBoxW(NULL, error, L"ERROR", MB_OK);
}
}
您使用的是
TCHAR
版本的OPENFILENAME
。由于您将Unicode字符串指针分配给其字段,这意味着您的项目是在定义了Unicode
的情况下编译的,因此TCHAR
映射到wchar\u t
,OPENFILENAME
映射到OPENFILENAMEW
。但是您使用的是ANSI字符缓冲区和ANSI版本的GetOpenFileName()
,并且到处都使用不正确的类型转换
因此,请删除所有类型强制转换,然后:
TCHAR
类型和API:
void GetInputFile()
{
TCHAR szFileNameIN[MAX_PATH];
TCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAME ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = TEXT("Any File\0*.*\0");
ofn.lpstrFile = fInputPath; // must be TCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = TEXT("Select an input File");
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)) // user selected an input file
{
}
else
{
// Get error
TCHAR error[MAX_LOADSTRING];
wsprintf(error, TEXT("%i"), CommDlgExtendedError());
MessageBox(NULL, error, TEXT("ERROR"), MB_OK);
}
}
void GetInputFile()
{
WCHAR szFileNameIN[MAX_PATH];
WCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAMEW ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = L"Any File\0*.*\0";
ofn.lpstrFile = fInputPath; // must be WCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = L"Select an input File";
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameW(&ofn)) // user selected an input file
{
}
else
{
// Get error
WCHAR error[MAX_LOADSTRING];
wsprintfW(error, L"%i", CommDlgExtendedError());
MessageBoxW(NULL, error, L"ERROR", MB_OK);
}
}
CHAR
/WCHAR
类型和API:
void GetInputFile()
{
TCHAR szFileNameIN[MAX_PATH];
TCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAME ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = TEXT("Any File\0*.*\0");
ofn.lpstrFile = fInputPath; // must be TCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = TEXT("Select an input File");
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn)) // user selected an input file
{
}
else
{
// Get error
TCHAR error[MAX_LOADSTRING];
wsprintf(error, TEXT("%i"), CommDlgExtendedError());
MessageBox(NULL, error, TEXT("ERROR"), MB_OK);
}
}
void GetInputFile()
{
WCHAR szFileNameIN[MAX_PATH];
WCHAR szFileNameOUT[MAX_PATH];
// get the input file name
OPENFILENAMEW ofn;
ZeroMemory(&fInputPath, sizeof(fInputPath));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = L"Any File\0*.*\0";
ofn.lpstrFile = fInputPath; // must be WCHAR[]...
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szFileNameIN;
ofn.nMaxFileTitle = MAX_PATH;
ofn.lpstrTitle = L"Select an input File";
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameW(&ofn)) // user selected an input file
{
}
else
{
// Get error
WCHAR error[MAX_LOADSTRING];
wsprintfW(error, L"%i", CommDlgExtendedError());
MessageBoxW(NULL, error, L"ERROR", MB_OK);
}
}
使用LPWSTR和LPOPENFILENAMEA强制转换只会阻止编译器告诉您您做错了,而不会阻止您做错。如果您真的不关心本地化,那么使用OPENFILENAMEA。并删除强制转换。您正在使用为Unicode版本设置的结构调用函数的ANSI版本。你为什么期望它不会失败?@HansPassant:谢谢你的输入。@KenWhite:我从我教授的样本中提取了这段代码。如果它是直接从你教授的样本中提取的,你应该问你的教授为什么他们的代码不起作用,而不是问我们。使用LPWSTR和LPOPENFILENAMEA强制转换只会阻止编译器告诉你你做错了,而不会阻止你做错。如果您真的不关心本地化,那么使用OPENFILENAMEA。并删除强制转换。您正在使用为Unicode版本设置的结构调用函数的ANSI版本。你为什么认为这不会失败?@HansPassant:谢谢你的输入。@KenWhite:我从我教授的样本中提取了这段代码。如果它是直接从你教授的样本中提取的,你应该问你教授为什么他们的代码不起作用,而不是问我们。实际上,这是
UNICODE
预处理器符号,它控制Windows API的通用文本映射<代码>\u UNICODE用于CRT。如果您希望使用宽字符串,那么要调用的API是GetOpenFileNameW
GetOpenFileName
是一个宏,它应该只与通用文本映射一起使用(或者实际上根本不应该使用)。\uUnicode
/UNICODE
:wops,修复了,我总是忘记谁是谁TCHAR
:15年前我会同意,今天除了与旧代码保持一致外,TCHAR
再也没有任何好处了TCHAR
s有感染代码的倾向,不像库代码中的wchar\t
那样得到广泛支持(有wstring
,但没有tstring
),CRT映射看起来很难看(\tcslen
,严重吗?还有,\t
)。因此,除非您仍然以Win 9x为目标,否则我要么使用“未修饰”的API(更易于阅读),假设它们是W,要么编写自己的UTF8->UTF16包装器,并在其他地方使用UTF8字符。实际上,控制Windows API的通用文本映射的是UNICODE
预处理器符号<代码>\u UNICODE用于CRT。如果您希望使用宽字符串,那么要调用的API是GetOpenFileNameW
GetOpenFileName
是一个宏,只应与通用文本映射一起使用(或者实际上根本不应使用)