2013-12-21 3 views
1

좋은 하루. 나는 OpenFileDialog를 작동하도록 클래스를 만든 :GetOpenFileName 때 C++ WinAPI 오류

#include <Windows.h> 

enum DialogResult { OK, Cancel }; 

class IFileDialog 
{ 
public: 
    TCHAR FileName[MAX_PATH]; 
    LPTSTR Title; 
    virtual DialogResult Show() = 0; 
}; 

class COpenFileDialog : public IFileDialog 
{ 
public: 
    LPTSTR Filter; 
    LPTSTR DefExt; 
    COpenFileDialog(HWND hWnd); 
    DialogResult Show(); 
private: 
    OPENFILENAME m_ofn; 
}; 

COpenFileDialog::COpenFileDialog(HWND hWnd) 
{ 
    //FileName[0] = '\0'; 

    ZeroMemory(&m_ofn, sizeof(m_ofn)); 

    m_ofn.lStructSize = sizeof(m_ofn); 
    m_ofn.hwndOwner = hWnd; 
    m_ofn.lpstrFilter = Filter; 
    m_ofn.nMaxFile = MAX_PATH; 
    m_ofn.lpstrFile = FileName; 
    m_ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 
    m_ofn.lpstrDefExt = DefExt; 
} 

DialogResult COpenFileDialog::Show() 
{ 
    return GetOpenFileName(&m_ofn) ? DialogResult::OK : DialogResult::Cancel; 
} 

콜링 :

COpenFileDialog hDialog = COpenFileDialog(hMainWindow); 
hDialog.Filter = "M&B Scenes\0*.sco\0"; 
hDialog.DefExt = "sco"; 
hDialog.Title = ""; 

if(hDialog.Show() == DialogResult::OK) 
{ 
    //TODO 
} 

그러나이 프로그램은 hDialog.Show()에 반함, 오히려 통화 GetOpenFilename에 (& m_ofn) : 0x000007FDFC5D21A3에서 처리되지 않은 예외 (SHCore.dll) ScoEditor.exe : 0xC0000005 : 액세스 위반 읽기 위치 0x000000E600000000.

어떻게 해결할 수 있습니까?

+0

이것은 문제가 아니지만 const가 아닌'char' 포인터에 문자열 리터럴을 할당한다는 점에 유의하십시오. 'Filter','DefExt'와'Title'의 타입을'LPCTSTR'으로 바꾸는 것이 우연히 그들에게 쓰는 것을 피하십시오. – eran

답변

3

귀하의 생성자는 m_ofn.lpstrFilter = Filter;이지만, Filter은 아직 초기화되지 않았습니다. 나중에 코드가 Filter을 수정하지만 m_ofn.lpstrFilter 내부의 값을 업데이트하지 못합니다. 따라서 초기화되지 않은 lpstrFilterGetOpenFileName으로 전달합니다.

호출시 중단 점을 GetOpenFileName으로 설정하고 전달중인 m_ofn의 내용을보고 코드를 디버깅 한 경우이 코드를 발견했을 것입니다.