2011-12-19 133 views
2

我一直在使用64位Windows 7机器上使用Visual C++ 2010 Express的简单Windows程序。到目前为止,我有简单的菜单和可编辑的文本区域。我试图让用户选择一个媒体文件(电影或音乐文件)并使用默认程序播放它。GetOpenFileName和系统函数调用运行时错误C++ win32 api

当用户从菜单File-> Play-> File from Computer选择时,它将运行以下代码。

case ID_PLAY_FFC: 
    { 
     system("cd c:/windows/system32/&&cmd.exe"); 
     FileOpen(hWnd); 
     system("cd c:/windows/system32/&&cmd.exe"); 
    } 
    break; 

问题是第一次系统调用按预期运行。第二个调用告诉我“cmd.exe不被识别为内部或外部命令,可操作程序或批处理文件”。我试过在File Open函数中放置第二个系统调用,它似乎在GetOpenFileName之前的任何地方工作,但不在之后。

我真的需要得到的唯一东西是文件路径,所以我想知道如果有人知道如何解决这个问题或更好的方法来实现这个?为的FileOpen()

代码:

void FileOpen(HWND hwnd) 
    { 
     OPENFILENAME ofn;   // common dialog box structure 
     char szFile[MAX_PATH];  // buffer for file name MAX_PATH = 260 
     HANDLE hf;     // file handle 

     // Initialize OPENFILENAME 
     ZeroMemory(&ofn, sizeof(ofn)); 
     ofn.lStructSize = sizeof(ofn); 
     ofn.hwndOwner = hwnd; 
     ofn.lpstrFile = szFile; 

     // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
     // use the contents of szFile to initialize itself. 
     ofn.lpstrFile[0] = '\0'; 
     ofn.nMaxFile = sizeof(szFile); 
     ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0"; 
     ofn.nFilterIndex = 1; 
     ofn.lpstrFileTitle = NULL; 
     ofn.nMaxFileTitle = 0; 
     ofn.lpstrInitialDir = NULL; 
     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 

     // Display the Open dialog box. 
     //system("cd c:/windows/system32/&&cmd.exe"); will execute here. 

     if (GetOpenFileName(&ofn)==TRUE) 
     { 
      //system("cd c:/windows/system32/&&cmd.exe"); but not here. 
      hf = CreateFile(ofn.lpstrFile, 
        GENERIC_READ, 
        0, 
        (LPSECURITY_ATTRIBUTES) NULL, 
        OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL, 
        (HANDLE) NULL); 
      if (hf == (HANDLE)-1) 
      { 
       MessageBox(NULL,"Could not open this file", "File I/O Error", MB_ICONSTOP); 
       return; 
      } 

     } 
    } 
+0

什么所有的系统调用呢?我不明白这一点的必要性。尝试在标志中包含“OFN_NOCHANGEDIR”。如果你想在默认播放器中播放一个文件,使用'ShellExecute'。 – 2011-12-19 00:30:33

回答

4

GetOpenFileName()功能改变工作目录和驱动器部分的它的操作。您致电cd不会更改工作驱动器,并且cmd.exe仍不在工作目录中。

的解决方案取决于你想到底该怎么做,但你可以指定完整路径cmd.exe(见%COMSPEC%环境变量),而不是依靠一个命令解释器,或OFN_NOCHANGEDIR标志传递给告诉它不要破坏工作目录。

请注意,(GUI)应用程序没有任何真正的原因需要特定的工作路径。你应该完全限定你所能做的一切。

0

调用system()开始一个新的进程,所以即使你的cd命令是有效的(他们都没有),它不会不要紧,因为你会被改变另一个进程的工作目录,而不是你的应用程序的过程。要设置应用程序的进程的工作目录,使用SetCurrentDirectory()代替system(),如:

case ID_PLAY_FFC:  
{  
    SetCurrentDirectory(TEXT("c:/windows/system32/"));  
    FileOpen(hWnd);  
    SetCurrentDirectory(TEXT("c:/windows/system32/"));  
}  
break; 

不过,你不需要做手工,因为GetOpenFileName()OFN_NOCHANGEDIR标志自动处理内部为您服务。无论调用进程的工作目录是什么,当指定OFN_NOCHANGEDIR时,GetOpenFileName()都会保留它。

试试这个:

case ID_PLAY_FFC: 
{ 
    FileOpen(hWnd); 
} 
break; 


void FileOpen(HWND hwnd) 
{ 
    OPENFILENAME ofn;   // common dialog box structure 
    TCHAR szFile[MAX_PATH+1]; // buffer for file name MAX_PATH = 260 

    // Zero out szFile so that GetOpenFileName does 
    // not use the contents to initialize itself. 
    ZeroMemory(szFile, sizeof(szFile)); 

    // Initialize OPENFILENAME 
    ZeroMemory(&ofn, sizeof(ofn)); 
    ofn.lStructSize = sizeof(ofn); 
    ofn.hwndOwner = hwnd; 
    ofn.lpstrFile = szFile; 
    ofn.nMaxFile = MAX_PATH; 
    ofn.lpstrFilter = TEXT("All\0*.*\0Text\0*.TXT\0"); 
    ofn.nFilterIndex = 1; 
    ofn.lpstrFileTitle = NULL; 
    ofn.nMaxFileTitle = 0; 
    ofn.lpstrInitialDir = NULL; 
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR; 

    // Display the Open dialog box. 
    if (GetOpenFileName(&ofn)==TRUE) 
    { 
     int ret = (int) ShellExecute(
          hwnd, 
          NULL, 
          ofn.lpstrFile, 
          NULL, 
          TEXT("c:/windows/system32/"), 
          SW_SHOWNORMAL); 
     if (ret <= 32) 
     { 
      MessageBox(NULL, TEXT("Could not open this file"), TEXT("File I/O Error"), MB_ICONSTOP); 
      return; 
     } 
    } 
}