Замена обратной косой черты на двойную или прямую косую черту в пути к файлу LPSTR

Я пытаюсь отправить сообщение в 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 на статический путь к файлу работает!

Как мне заменить обратную косую черту в пути к файлу?

Спасибо миллион раз!

0

Решение

Есть несколько проблем с вашим кодом:

  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());
1

Другие решения

Я согласен с Коди Греем в том, что вам нужны экранирующие экраны только для строковых литералов и что вы, похоже, смешиваете символы 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,

0

По вопросам рекламы [email protected]