воспроизведение файлов после их принятия через открытое диалоговое окно

Я новый участник и присоединился к этому сайту после того, как много раз обращался к нему, когда у меня возникали проблемы с программированием. Я пытаюсь закодировать медиаплеер (Win32 SDK VC++ 6.0) для своего проекта в колледже, и я застрял. Я искал на различных форумах и в msdn и, наконец, нашел функцию GetShortPathName, которая позволяет мне просматривать папки и файлы, в именах которых есть пробелы. Я вставлю код сюда, чтобы было намного понятнее, что я пытаюсь сделать.

case IDM_FILE_OPEN :
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hwnd;
    ofn.lpstrFilter = "Media Files (All Supported Types)\0*.avi;*.mpg;*.mpeg;*.asf;*.wmv;*.mp2;*.mp3\0"
                                      "Movie File (*.avi;*.mpg;*.mpeg)\0*.avi;*.mpg;*.mpeg\0"
                                      "Windows Media File (*.asf;*.wmv)\0*.asf;*.wmv\0"
                                      "Audio File (*.mp2;*.mp3)\0*.mp2;*.mp3\0"
                                      "All Files(*.*)\0*.*\0";   
                    ofn.lpstrFile = szFileName;
                    ofn.nMaxFile = MAX_PATH;
                    ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_CREATEPROMPT;
                    ofn.lpstrDefExt = "mp3";

                    if(GetOpenFileName(&ofn))
                    {

                        length = GetShortPathName(szFileName, NULL, 0);
                        buffer = (TCHAR *) malloc (sizeof(length));
                        length = GetShortPathName(szFileName, buffer, length);

                        for(i = 0 ; i < MAX_PATH ; i++)
                        {
                            if(buffer[i] == '\\')
                                buffer[i] = '/';
                        }

                        SendMessage(hList,LB_ADDSTRING,0,(LPARAM)buffer);
                        mciSendString("open buffer alias myFile", NULL, 0, NULL);
                        mciSendString("play buffer", NULL, 0, NULL);
                    }

                    return 0;

используя функцию GetShortPathName, я получаю путь как: D:/Mp3z/DEEPBL~1/03SLEE~1.mp3 Помещая этот путь непосредственно в случай с кнопкой Play

mciSendString("open D:/Mp3jh/DEEPBL~1/03SLEE~1.mp3 alias myFile", NULL, 0, NULL);
mciSendString("play myFile", NULL, 0, NULL);

файл открывается и воспроизводится нормально. Но как только я пытаюсь открыть и воспроизвести его через диалоговое окно открытия файла, ничего не происходит. Любой вклад приветствуется.


person Salil    schedule 13.02.2012    source источник
comment
Как вы думаете, зачем вам нужен короткий путь?   -  person Cody Gray    schedule 13.02.2012
comment
Не используйте короткое имя. Просто избегайте пробелов в имени, добавляя кавычки к имени файла: "open \"path/to/file/with spaces in.mp3\" alias myFile"   -  person David Heffernan    schedule 13.02.2012


Ответы (1)


Похоже, проблема в том, что вы передаете имя переменной buffer функции mciSendString в виде строки, а не передаете содержимое буфера.

Вам нужно соединить аргументы, которые вы хотите передать (open и alias myFile), с содержимым аргумента buffer.

Код также можно значительно упростить, заменив malloc автоматическим массивом. Вам не нужно malloc это, потому что вам это не нужно за пределами области блока. (И в любом случае вам не следует использовать malloc в коде C++; вместо этого используйте new[].)

Вот измененный фрагмент кода, показанный в вашем вопросе:
(Предупреждение: изменения сделаны с использованием только моих глаз в качестве компилятора! Обращайтесь с осторожностью.)

if(GetOpenFileName(&ofn))
{
    // Get the short path name, and place it in the buffer array.
    // We know that a short path won't be any longer than MAX_PATH, so we can
    // simply allocate a statically-sized array without futzing with new[].
    //
    // Note: In production code, you should probably check the return value
    // of the GetShortPathName function to make sure it succeeded.
    TCHAR buffer[MAX_PATH];
    GetShortPathName(szFileName, buffer, MAX_PATH);

    // Add the short path name to your ListBox control.
    //
    // Note: In C++ code, you should probably use C++-style casts like
    // reinterpret_cast, rather than C-style casts!
    SendMessage(hList, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(buffer));

    // Build the argument string to pass to the mciSendString function.
    // 
    // Note: In production code, you probably want to use the more secure
    // alternatives to the string concatenation functions.
    // See the documentation for more details.
    // And, as before, you should probably check return values for error codes.
    TCHAR arguments[MAX_PATH * 2];   // this will definitely be large enough
    lstrcat(arguments, TEXT("open"));
    lstrcat(arguments, buffer);
    lstrcat(arguments, TEXT("alias myFile"));
    // Or, better yet, use a string formatting function, like StringCbPrintf:
    // StringCbPrintf(arguments, MAX_PATH * 2, TEXT("open %s alias myFile"),
    //                buffer);

    // Call the mciSendString function with the argument string we just built.
    mciSendString(arguments, NULL, 0, NULL);
    mciSendString("play myFile", NULL, 0, NULL);
}

Обратите внимание, что, как показывает приведенный выше код, работа со строками в стиле C (массивами символов) является настоящей головной болью. C++ предоставляет лучшую альтернативу в виде класса std::string. Вы должны настоятельно рассмотреть возможность использования этого вместо этого. Для вызова функций Windows API вам по-прежнему потребуется строка в стиле C, но вы можете получить одну из них, используя метод c_str класса std::string.

person Cody Gray    schedule 13.02.2012
comment
Спасибо вам, ребята. Я использовал strcpy и strcat, и это сработало. Спасибо Коди Грей за код. Это похоже на то, что я сделал. - person Salil; 13.02.2012