我想添加一个选择文件对话框到我的项目,现在只能由用户输入文件名。C++ win32控制台应用程序使用Windows API添加“选择文件”对话框
我做了一些搜索,它似乎Windows API与GetOpenFileName函数是我这样做的最简单的方法。但是,当我复制&粘贴示例代码无论是从MSDN或其他网站,我有一些构建错误。
我使用的Visual Studio 2017而我使用的示例代码是从http://www.cplusplus.com/forum/windows/169960/:
#include <iostream>
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
int main()
{
char filename[ MAX_PATH ];
OPENFILENAME ofn;
ZeroMemory(&filename, sizeof(filename));
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL; // If you have a window to center over, put its HANDLE here
ofn.lpstrFilter = "Text Files\0*.txt\0Any File\0*.*\0";
ofn.lpstrFile = filename;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrTitle = "Select a File, yo!";
ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;
if (GetOpenFileNameA(&ofn))
{
std::cout << "You chose the file \"" << filename << "\"\n";
}
else
{
// All this stuff below is to tell you exactly how you messed up above.
// Once you've got that fixed, you can often (not always!) reduce it to a 'user cancelled' assumption.
switch (CommDlgExtendedError())
{
case CDERR_DIALOGFAILURE : std::cout << "CDERR_DIALOGFAILURE\n"; break;
case CDERR_FINDRESFAILURE : std::cout << "CDERR_FINDRESFAILURE\n"; break;
case CDERR_INITIALIZATION : std::cout << "CDERR_INITIALIZATION\n"; break;
case CDERR_LOADRESFAILURE : std::cout << "CDERR_LOADRESFAILURE\n"; break;
case CDERR_LOADSTRFAILURE : std::cout << "CDERR_LOADSTRFAILURE\n"; break;
case CDERR_LOCKRESFAILURE : std::cout << "CDERR_LOCKRESFAILURE\n"; break;
case CDERR_MEMALLOCFAILURE : std::cout << "CDERR_MEMALLOCFAILURE\n"; break;
case CDERR_MEMLOCKFAILURE : std::cout << "CDERR_MEMLOCKFAILURE\n"; break;
case CDERR_NOHINSTANCE : std::cout << "CDERR_NOHINSTANCE\n"; break;
case CDERR_NOHOOK : std::cout << "CDERR_NOHOOK\n"; break;
case CDERR_NOTEMPLATE : std::cout << "CDERR_NOTEMPLATE\n"; break;
case CDERR_STRUCTSIZE : std::cout << "CDERR_STRUCTSIZE\n"; break;
case FNERR_BUFFERTOOSMALL : std::cout << "FNERR_BUFFERTOOSMALL\n"; break;
case FNERR_INVALIDFILENAME : std::cout << "FNERR_INVALIDFILENAME\n"; break;
case FNERR_SUBCLASSFAILURE : std::cout << "FNERR_SUBCLASSFAILURE\n"; break;
default : std::cout << "You cancelled.\n";
}
}
}
当我&复制粘贴到VS,它显示以下内容:
Severity Code Description Project File Line Suppression State
Error C2440 '=': cannot convert from 'char [260]' to 'LPWSTR' ConsoleApplication1 c:\users\xfan0\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp 18
Severity Code Description Project File Line Suppression State
Error C2440 '=': cannot convert from 'const char [19]' to 'LPCWSTR' ConsoleApplication1 c:\users\xfan0\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp 20
Severity Code Description Project File Line Suppression State
Error C2664 'BOOL GetOpenFileNameA(LPOPENFILENAMEA)': cannot convert argument 1 from 'OPENFILENAME *' to 'LPOPENFILENAMEA' ConsoleApplication1 c:\users\xfan0\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp 23
Severity Code Description Project File Line Suppression State
Error (active) E0167 argument of type "OPENFILENAME *" is incompatible with parameter of type "LPOPENFILENAMEA" ConsoleApplication1 c:\Users\XFAN0\Documents\Visual Studio 2017\Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp 23
试过搜索但没有找到我的运气:(
您的构建默认为期望宽字符字符串,但您使用的是MBCS字符串。您可以在调用Windows API时将代码更改为使用宽字符串,也可以更改项目设置(项目属性 - >常规 - >字符集 - >使用多字节字符集)。 –
在某些地方,您抓取的示例代码明确调用了MBCS版本(例如'GetOpenFileNameA'),但它并不一致(例如,“OPENFILENAME”默认为“OPENFILENAMEW”而不是“OPENFILENAMEA”)。在现代Windows程序中,使用API的宽字符串版本是首选。 MBCS功能主要是为了向后兼容,并且有其局限性。 –
很酷。其实我试过这个设置,但是当我测试另一个例子的时候,它不起作用。 –