Winapi 通过“打开”对话框接受文件后播放文件

Winapi 通过“打开”对话框接受文件后播放文件,winapi,visual-c++,sdk,Winapi,Visual C++,Sdk,我是一名新会员,在我遇到一些编程问题时,我曾多次访问过这个网站,后来加入了这个网站。我正试图为我的大学项目编写一个媒体播放器(Win32 SDK VC++6.0),我被卡住了。我在各种论坛和msdn上进行了搜索,最后找到了GetShortPathName函数,它使我能够在名称中有空格的文件夹和文件中进行播放。我将把代码粘贴在这里,这样就可以更清楚地了解我要做的事情 case IDM_FILE_OPEN : ZeroMemory(&ofn, sizeof(ofn)); of

我是一名新会员,在我遇到一些编程问题时,我曾多次访问过这个网站,后来加入了这个网站。我正试图为我的大学项目编写一个媒体播放器(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;

文件打开并播放良好。但当我试图打开并通过“打开文件”对话框播放它时,什么也没有发生。任何输入都值得赞赏。

问题似乎在于,您将
缓冲区
变量的名称作为字符串传递给
mciSendString
函数,而不是传递缓冲区的内容

您需要将要传递的参数(
open
alias myFile
)与
buffer
的内容连接起来

通过使用自动数组替换
malloc
,代码也可以大大简化。您不需要
malloc
it,因为在块范围之外不需要它。(无论如何,你不应该在C++代码中使用<代码> MalOC < /COD>;使用<代码> NeX[]/COD> 下面是您问题中显示的代码的修改片段:
(警告:仅使用我的眼睛作为编译器所做的更改!请小心处理。)

if(GetOpenFileName(&ofn))
{
//获取短路径名,并将其放置在缓冲区数组中。
//我们知道短路径不会比MAX_路径长,所以我们可以
//只需分配一个静态大小的数组,而无需使用new[]进行进一步调整。
//
//注意:在生产代码中,您可能应该检查返回值
//以确保它成功。
TCHAR缓冲区[最大路径];
GetShortPathName(szFileName、缓冲区、最大路径);
//将短路径名添加到ListBox控件。
//
/cNote:在C++代码中,你应该使用类似C++的样式。
//重新解释_类型转换,而不是C样式转换!
SendMessage(hList,LB_ADDSTRING,0,reinterpret_cast(缓冲区));
//生成要传递给mciSendString函数的参数字符串。
// 
//注意:在生产代码中,您可能希望使用更安全的
//字符串连接函数的替代方法。
//有关更多详细信息,请参阅文档。
//和前面一样,您可能应该检查返回值中是否有错误代码。
TCHAR参数[MAX_PATH*2];//这肯定足够大了
lstrcat(参数,文本(“打开”);
lstrcat(参数、缓冲区);
lstrcat(参数、文本(“别名myFile”);
//或者,最好使用字符串格式函数,如StringCbPrintf:
//StringCbPrintf(参数,最大路径*2,文本(“打开%s别名myFile”),
//缓冲液);
//使用我们刚刚构建的参数字符串调用mciSendString函数。
mciSendString(参数,NULL,0,NULL);
mciSendString(“播放我的文件”,NULL,0,NULL);
}

注意,正如上面的代码所示,使用C样式字符串(字符数组)是AsS中的一个真正的问题。C++提供了一个更好的选择,其形式是 STD::String 类。你应该强烈地考虑使用它。要调用Windows API函数,您仍然需要C样式的字符串,但您可以使用

std::string
class.

为什么需要短路径名?不要使用短名称。只需通过在文件名中添加引号来转义名称中的空格:
“open\”path/to/file/。mp3\“alias myFile”
谢谢大家。我用了strcpy和strcat,效果很好。谢谢科迪·格雷的密码。这和我做的很相似。
mciSendString("open D:/Mp3jh/DEEPBL~1/03SLEE~1.mp3 alias myFile", NULL, 0, NULL);
mciSendString("play myFile", NULL, 0, NULL);
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);
}