2016-11-10 62 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); 
        } 
    } 
    
相關問題