プロジェクトにファイル選択ダイアログボックスを追加しようとしていますが、これはユーザーがファイル名を入力するだけです。C++ win32 console app Windows APIを使用してファイルを選択ダイアログボックスを追加する
私はいくつかの検索を行い、GetOpenFileName関数を使用したWindows APIがこれを行う最も簡単な方法だと思われます。しかし、私が&をコピーしてMSDNか他のウェブサイトからのサンプルコードを貼り付けると、ビルドエラーが発生します。
私は、Visual Studio 2017を使用していますが、私が使用したコード例はhttp://www.cplusplus.com/forum/windows/169960/からです:
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
はしてみました:
#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";
}
}
}
私が対に&ペーストをコピーし、それは以下を示しそれを検索しても私の運が見つかりませんでした:(
ビルドのデフォルトはワイド文字列ですが、MBCS文字列を使用しています。 Windows APIを呼び出すときにワイド文字列を使用するようにコードを変更するか、プロジェクトの設定を変更することができます(プロジェクトプロパティ - >一般 - >文字セット - >複数バイト文字セットを使用する)。 –
ここで取得したコード例では、MBCSのバージョン(GetOpenFileNameAなど)を明示的に呼び出していますが、一貫して実行していません(たとえば、OPENFILENAMEがOPENFILENAMEEWではなくOPENFILENAMEWにデフォルト設定されています)。現代のWindowsプログラムでは、ワイド文字列のAPIを使用することをお勧めします。 MBCSの機能は主に下位互換性のためであり、制限があります。 –
Cool。実際に私はその設定を試みましたが、別の例を試してみたところ、Lolは動作しませんでした。 –