0

GetOpenFileNameの関数を使用Winapiしており、ファイル選択ダイアログにフィルターを適用しています。

これは完全に機能します:

LPSTR mfilter = "Filter\0*.PDF\0";
ofn.lpstrFilter = mfilter;

if(GetOpenFileName(&ofn)){
...

ここに画像の説明を入力

これは失敗します (ダイアログは開きますが、フィルターは適用されません):

string mfilter = "Filter\0*.PDF\0";
ofn.lpstrFilter = mfilter.c_str();

if(GetOpenFileName(&ofn)){
...

ここに画像の説明を入力

std:stringパラメータを介してファイル拡張子を取得しているため、使用する必要があり、このタイプは連結を容易にしますが、非互換性の問題が発生しています...

期待どおりに機能する場合、これは私のコードになります(前の例と同じように失敗します):

const char * ext = &(4:); //Ampersand parameter (from CA Plex) It contains "PDF"
string mfilter = "Filter\0*." + ext + "\0"; //Final string: Filter\0*.PDF\0;
ofn.lpstrFilter = mfilter.c_str();

このメソッドを使用すると、実行時例外が発生します。

string mf;
mf.append("Filter")
.append('\0')
.append("*.pdf")
.append('\0');

ofn.lpstrFilter = mf.c_str();

ここに画像の説明を入力

4

3 に答える 3

0

関数は TCHAR を使用し、UNICODE文字セットが使用されているGetOpenFileName場合、TCHAR は WCHAR になります。

次に例を示します。

std::wstring getOpenFileName(HWND hWnd, const std::wstring& sFilter)
{
    wchar_t buffer[MAX_PATH] = L"";

    OPENFILENAMEW ofn = {0};

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hWnd;
    ofn.lpstrFilter = sFilter.c_str();
    ofn.nFilterIndex = 1;
    ofn.lpstrFile = buffer;
    ofn.nMaxFile = MAX_PATH;
    ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;

    if( !::GetOpenFileNameW( &ofn ) )
        return L"";

    return buffer;
}

lpstrFilterに基づいてパラメータ化する場合は、 UNICODEの場合はgetにstd::wstring使用できます。wstring::c_str()LPCTSTRconst wchar*

重要:問題は、 を受け取るstd::wstringコンストラクターconst wchar*が、入力が C 文字列であると想定していることです。C 文字列は '\0' で終了するため、'\0' 文字に達すると解析が停止します。これを補うには、char 配列へのポインターと length の 2 つのパラメーターを取るコンストラクターを使用する必要があります。string::push_back()method を使用して NULL を追加することもできます。

std::wstring sFilter = L"PDF Files";
sFilter.push_back('\0');
sFilter.append(L"*.pdf");
sFilter.push_back('\0');
于 2015-12-10T12:48:04.247 に答える