0

我正在尝试向 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 是可行的!

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

感谢一百万次!

4

2 回答 2

1

您的代码有几个问题:

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

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

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

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

试试这个:

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()); 
于 2013-07-24T22:03:36.487 回答
0

我同意 Cody Gray 的观点,即您只需要对字符串文字进行转义反冲,并且您似乎在代码中混合了 Unicode 和非 Unicode 字符;如果您的项目使用 Unicode 字符集,则需要更改以下内容:

  • szFile应该是类型wchar_t(当你手动转换类型时要小心!)
  • ofn.nMaxFile应该分配_countof(szFile)而不是sizeof()
  • 调用CreateFile()似乎是不必要的
  • filePathLength应该分配strlen(currentPath)而不是sizeof(currentPath)
  • 如果您要返回指向 的指针szFile[],则szFile需要将其声明为静态或定义为函数外部的全局变量

替换\/:newPath是一个本地指针,你不会为它分配内存然后返回这个值,所以即使你将它声明为wchar_t newPath[_MAX_PATH],当函数返回时内存地址也将是无效的——最好只替换 的值currentPath

于 2013-07-24T14:35:45.297 回答