在LPSTR文件路径中用双反斜杠或正斜杠替换反斜杠

时间:2013-07-24 09:25:59

标签: c++ winapi openfiledialog wchar-t

我正在尝试将消息发布到WIN32 API以打开WAV文件。我可以通过将LPARAM参数设置为L“C:/path/file.wav”来实现这一点。这非常有用!但是,我一直在尝试使用对话框生成文件路径的字符串。 OpenFileDialog函数可以将选定的文件路径作为LPSTR数据类型返回,这听起来很完美!但是,此文件路径被识别为Windows文件路径,因此由反斜杠组成。由于这些反斜杠不会被转义或替换为正斜杠,因此编译器会因为形成的通用字符名称不正确而开始哭泣。因此,替换\或/的LPSTR文件路径中的所有\似乎微不足道。我一直试图以多种方式做到这一点,但似乎没有任何效果。

wchar_t* SelectAudioFile(HWND windowHandle) {
    OPENFILENAME ofn;      // common dialog box structure
    char szFile[260];      // buffer for file name

    // Initialize OPENFILENAME
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = windowHandle;
    ofn.lpstrFile = (LPWSTR)szFile;

    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = sizeof(szFile);

    ofn.lpstrFilter = L"Waveform Audio File Format (*.wav)\0*.wav\0";

    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

    // Display the Open dialog box.

    if (GetOpenFileName(&ofn)==TRUE) {
        CreateFile(ofn.lpstrFile,
            GENERIC_READ,
            0,
            (LPSECURITY_ATTRIBUTES) NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            (HANDLE) NULL);
        MessageBox(windowHandle,ofn.lpstrFile,0,0);
    }

     //Here the backslash should be escaped or replaced.

    const wchar_t * currentPath = ofn.lpstrFile; //This is a LPSTR 
    wchar_t * newPath;
    int filePathLength = sizeof(currentPath);

    for (int i=0; i < filePathLength; i++) {
        if (currentPath[i] == "\\") {
            newPath[i] = "\\\\";
        } else {
            newPath[i] = filePath[i];
        }
    }
    return newPath;


}

以下行会发布一条消息,告诉它在路径

打开某个文件
PostMessageW(hwnd, WMA_OPEN, 0, (LPARAM)SelectAudioFile(hwnd)); 

因此,用静态文件路径替换LPARAM会起作用!

我应该如何替换文件路径中的反斜杠?

万分感谢!

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

  1. 您错误地混合了Ansi和Unicode。

  2. 您正在返回一个指向您尚未为其分配任何内存的本地缓冲区的指针。

  3. 您正在使用PostMessage()异步发布可能超出范围的本地缓冲区,并在窗口处理消息之前变为无效。

  4. 即使GetOpenFileName()失败或被取消,您也会发布消息。

  5. 请改为尝试:

    bool SelectAudioFile(HWND windowHandle, wchar_t *audioFile, int maxAudioFile)
    {
        OPENFILENAMEW ofn = {0};
    
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = windowHandle;
        ofn.lpstrFile = audioFile;
        ofn.nMaxFile = maxAudioFile;
        ofn.lpstrFilter = L"Waveform Audio File Format (*.wav)\0*.wav\0";
        ofn.nFilterIndex = 1;
        ofn.lpstrFileTitle = NULL;
        ofn.nMaxFileTitle = 0;
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    
        if (GetOpenFileNameW(&ofn))
        {
            MessageBoxW(windowHandle, audioFile, 0, 0);
            return true;
        }
    
        return false;
    }
    

    wchar_t szAudioFile[MAX_PATH+1] = {0};
    if (SelectAudioFile(hwnd, szAudioFile, MAX_PATH))
        SendMessageW(hwnd, WMA_OPEN, 0, (LPARAM)szAudioFile); 
    

    可替换地:

    #include <string>
    
    std::wstring SelectAudioFile(HWND windowHandle)
    {
        OPENFILENAMEW ofn = {0};
        wchar_t szFile[MAX_PATH+1] = {0};
    
        ofn.lStructSize = sizeof(ofn);
        ofn.hwndOwner = windowHandle;
        ofn.lpstrFile = szFile;
        ofn.nMaxFile = MAX_PATH;
        ofn.lpstrFilter = L"Waveform Audio File Format (*.wav)\0*.wav\0";
        ofn.nFilterIndex = 1;
        ofn.lpstrFileTitle = NULL;
        ofn.nMaxFileTitle = 0;
        ofn.lpstrInitialDir = NULL;
        ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    
        if (GetOpenFileNameW(&ofn))
            MessageBoxW(windowHandle, szFile, 0, 0);
    
        return szFile;
    }
    

    std::wstring audioFile = SelectAudioFile(hwnd);
    if (audioFile.length() > 0)
        SendMessageW(hwnd, WMA_OPEN, 0, (LPARAM)audioFile.c_str()); 
    

答案 1 :(得分:0)

我同意Cody Gray的说法,你只需要为字符串文字提供转义反斜,并且你似乎在代码中混合了Unicode和非Unicode字符;如果您的项目使用Unicode字符集,则需要更改以下内容:

  • szFile应为wchar_t类型(手动投射类型时务必注意!)
  • ofn.nMaxFile应分配_countof(szFile)而不是sizeof()
  • CreateFile()的调用似乎是不必要的
  • filePathLength应分配strlen(currentPath)而不是sizeof(currentPath)
  • 如果要返回指向szFile[]的指针,szFile需要声明为静态或定义为函数外的全局变量

\替换/newPath是一个本地指针,你没有为它分配内存然后返回这个值,所以即使你把它声明为{{1} ,函数返回时内存地址无效 - 最好只替换wchar_t newPath[_MAX_PATH]的值。