0

WAV ファイルを開くメッセージを WIN32 API に送信しようとしています。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 を静的ファイルパスに置き換えるとうまくいきます!

ファイルパスのバックスラッシュを置き換えるにはどうすればよいですか?

100万回ありがとう!

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

文字列リテラルに対してのみエスケープ バックラッシュが必要であり、コード内で Unicode 文字と非 Unicode 文字が混在しているように見えることについては、Cody Gray に同意します。プロジェクトで Unicode 文字セットを使用している場合は、次を変更する必要があります。

  • szFile型でなければなりませんwchar_t(手動で型をキャストするときは常に注意してください!)
  • ofn.nMaxFile_countof(szFile)代わりに割り当てる必要がありますsizeof()
  • への呼び出しはCreateFile()不要のようです
  • filePathLengthstrlen(currentPath)代わりに割り当てる必要がありますsizeof(currentPath)
  • へのポインターを返す場合は、szFile[]静的szFileに宣言するか、関数の外でグローバル変数として定義する必要があります

:で置き換える\のはローカル ポインターです。メモリを割り当ててからこの値を返すわけではないため、 として宣言したとしても、関数が戻るとメモリ アドレスは無効になります。/newPathwchar_t newPath[_MAX_PATH]currentPath

于 2013-07-24T14:35:45.297 に答える