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

2

string mfilter = "Filter\0*.PDF\0";

你正在调用一个std::string构造函数,它在第一个终止字符串\0

以下代码:

string mfilter = "Filter\0*.PDF\0";
cout << "string:" << mfilter << "   len: " << mfilter.length() << endl;

印刷

string: Filter   len: 6

该字符串仅在第一个\0终止符之前构造。做字符串只由单词“Filter”组成。

于 2015-12-10T12:01:32.343 回答
0

GetOpenFileName函数使用 TCHAR,如果使用UNICODE字符集,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;
}

如果您想根据您的参数进行参数化lpstrFilterstd::wstring您可以使用wstring::c_str()来获取UNICODELPCTSTRconst wchar*情况。

重要提示:问题std::wstring在于采用 a 的构造函数const wchar*假定输入是 C 字符串。C 字符串以 '\0' 终止,因此在到达 '\0' 字符时停止解析。为了弥补这一点,您需要使用带有两个参数的构造函数,一个指向 char 数组的指针和一个 length。您还可以使用string::push_back()方法来附加 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 回答
0
string mfilter = "Filter\0*.PDF\0";

这将调用一个std::basic_string使用以 null 结尾的 string的构造函数。它将停止解析字符串文字"Filter"

试试这个:

string mfilter( "Filter\0*.PDF", 13 ); // need double null at end

这调用了一个std::basic_string构造函数,该构造函数使用“s 指向的字符串的第一个 count 个字符。s可以包含空字符。”

如果您经常遇到此问题,您必须自己计算字符数,或者编写包装代码。


相关:std::basic_string构造函数


至于您的运行时错误:

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

append() 没有单一字符类型的重载。您可能正在const CharT* s使用空指针达到过载。

使用append( 1, '\0' )append( "", 1 ),其中任何一个都应附加一个空字节。

于 2015-12-10T14:00:29.537 回答