2016-11-10 64 views
0

我想使用GetOpenFileNameA打开一个对话框。但是,该对话框不会打开。相反,我得到一个很好的CommDlgError 2.搜索谷歌和StackOverflow的这个错误没有产生任何有用的结果。调用GetOpenFileNameA会导致常见的对话框错误2

令人困惑的是,此代码适用于也使用Visual Studio的学校计算机,尽管它是不同的版本。

说明:未在此代码块中声明的所有变量都是只能在主代码模块内访问的“全局”变量。

void GetInputFile() 
{ 
    char szFileNameIN[MAX_PATH]; 
    char szFileNameOUT[MAX_PATH]; 

    // get the input file name 
    OPENFILENAME ofn; 
    ZeroMemory(&fInputPath, sizeof(fInputPath)); 
    ZeroMemory(&ofn, sizeof(ofn)); 
    ofn.lStructSize = sizeof(ofn); 
    ofn.hwndOwner = NULL; 
    ofn.lpstrFilter = LPWSTR("Any File\0*.*\0"); 
    ofn.lpstrFile = LPWSTR(fInputPath); 
    ofn.nMaxFile = MAX_PATH; 
    ofn.lpstrFileTitle = LPWSTR(szFileNameIN); 
    ofn.nMaxFileTitle = MAX_PATH; 
    ofn.lpstrTitle = LPWSTR("Select an input File"); 
    ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST; 
    if (GetOpenFileNameA(LPOPENFILENAMEA(&ofn))) // user selected an input file 
    { 
    } 
    else { 
     // Get error 
     TCHAR error[MAX_LOADSTRING]; 
     wsprintf(error,TEXT("%i"),CommDlgExtendedError()); 
     MessageBox(NULL,error,TEXT("ERROR"),MB_OK); 
    } 

} 
+3

使用LPWSTR和LPOPENFILENAMEA蒙上只告诉你,你没有错,它并没有从这样做是错误阻止你停止编译器。如果你真的*不关心本地化,那就用OPENFILENAMEA代替。并删除演员。 –

+0

您正在调用具有为Unicode版本设置的结构的函数的ANSI版本。你为什么期望**不会失败? –

+0

@HansPassant:感谢您的输入。 – moonman239

回答

4

那些可怕的(LPWSTR)蒙上告诉我,你与UNICODE编译的,所以您使用的是OPENFILENAME结构实际上是OPENFILENAMEW;考虑到您使用的是GetOpenFileNameA,您必须使用OPENFILENAMEA(或使用宽字符串直接使用GetOpenFileName)。作为一个经验法则,如果您必须将指针指向/来自不同于void *和类似的任何东西,那么您可能做错了事;添加指针转换只会使编译器无声,不会使错误消失)

+0

实际上,它是'UNICODE'预处理符号,它控制着Windows API的通用文本映射。 '_UNICODE'用于CRT。如果你想使用宽字符串,那么调用的API是'GetOpenFileNameW'; 'GetOpenFileName'是一个宏,它只应该与通用文本映射一起使用(或者根本不用)。 – IInspectable

+0

'_UNICODE' /'UNICODE':wops,固定的,我总是忘记谁是谁。 'TCHAR':15年前,我会同意,今天除了与旧代码的一致性之外,'TCHAR'不再有任何好处。 'TCHAR's有感染你的代码的倾向,不像'wchar_t'在库代码(有'wstring'但没有'tstring')那么广泛支持,CRT映射看起来很丑陋('_tcslen',严重吗? ,呃'_T')。因此,除非你仍然以Win 9x为目标,否则我会假设它们是W,或者编写我自己的UTF8-> UTF16包装器并在其他地方使用UTF8字符,只使用“未修饰”的API(更易于阅读)。 –

2

您正在使用TCHAR版本的OPENFILENAME。由于您正在为其字段分配Unicode字符串指针,这意味着您的项目正在编译定义UNICODE,所以TCHAR映射到wchar_tOPENFILENAME映射到OPENFILENAMEW。但是,您正在使用ANSI字符缓冲区和ANSI版本GetOpenFileName(),并在所有位置使用不正确的类型转换。

因此摆脱所有的类型强制转换,然后或者:

  1. 使用适当TCHAR类型和API的一切:

    void GetInputFile() 
    { 
        TCHAR szFileNameIN[MAX_PATH]; 
        TCHAR szFileNameOUT[MAX_PATH]; 
    
        // get the input file name 
        OPENFILENAME ofn; 
        ZeroMemory(&fInputPath, sizeof(fInputPath)); 
        ZeroMemory(&ofn, sizeof(ofn)); 
        ofn.lStructSize = sizeof(ofn); 
        ofn.hwndOwner = NULL; 
        ofn.lpstrFilter = TEXT("Any File\0*.*\0"); 
        ofn.lpstrFile = fInputPath; // must be TCHAR[]... 
        ofn.nMaxFile = MAX_PATH; 
        ofn.lpstrFileTitle = szFileNameIN; 
        ofn.nMaxFileTitle = MAX_PATH; 
        ofn.lpstrTitle = TEXT("Select an input File"); 
        ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST; 
        if (GetOpenFileName(&ofn)) // user selected an input file 
        { 
        } 
        else 
        { 
         // Get error 
         TCHAR error[MAX_LOADSTRING]; 
         wsprintf(error, TEXT("%i"), CommDlgExtendedError()); 
         MessageBox(NULL, error, TEXT("ERROR"), MB_OK); 
        } 
    } 
    
  2. 使用适当CHAR/WCHAR类型和一切的API:

    void GetInputFile() 
    { 
        WCHAR szFileNameIN[MAX_PATH]; 
        WCHAR szFileNameOUT[MAX_PATH]; 
    
        // get the input file name 
        OPENFILENAMEW ofn; 
        ZeroMemory(&fInputPath, sizeof(fInputPath)); 
        ZeroMemory(&ofn, sizeof(ofn)); 
        ofn.lStructSize = sizeof(ofn); 
        ofn.hwndOwner = NULL; 
        ofn.lpstrFilter = L"Any File\0*.*\0"; 
        ofn.lpstrFile = fInputPath; // must be WCHAR[]... 
        ofn.nMaxFile = MAX_PATH; 
        ofn.lpstrFileTitle = szFileNameIN; 
        ofn.nMaxFileTitle = MAX_PATH; 
        ofn.lpstrTitle = L"Select an input File"; 
        ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST; 
        if (GetOpenFileNameW(&ofn)) // user selected an input file 
        { 
        } 
        else 
        { 
         // Get error 
         WCHAR error[MAX_LOADSTRING]; 
         wsprintfW(error, L"%i", CommDlgExtendedError()); 
         MessageBoxW(NULL, error, L"ERROR", MB_OK); 
        } 
    } 
    

    void GetInputFile() 
    { 
        CHAR szFileNameIN[MAX_PATH]; 
        CHAR szFileNameOUT[MAX_PATH]; 
    
        // get the input file name 
        OPENFILENAMEA ofn; 
        ZeroMemory(&fInputPath, sizeof(fInputPath)); 
        ZeroMemory(&ofn, sizeof(ofn)); 
        ofn.lStructSize = sizeof(ofn); 
        ofn.hwndOwner = NULL; 
        ofn.lpstrFilter = "Any File\0*.*\0"; 
        ofn.lpstrFile = fInputPath; // must be CHAR[]... 
        ofn.nMaxFile = MAX_PATH; 
        ofn.lpstrFileTitle = szFileNameIN; 
        ofn.nMaxFileTitle = MAX_PATH; 
        ofn.lpstrTitle = "Select an input File"; 
        ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST; 
        if (GetOpenFileNameA(&ofn)) // user selected an input file 
        { 
        } 
        else 
        { 
         // Get error 
         CHAR error[MAX_LOADSTRING]; 
         wsprintfA(error, "%i", CommDlgExtendedError()); 
         MessageBoxA(NULL, error, "ERROR", MB_OK); 
        } 
    } 
    
相关问题