_WIN32_WINNT=0x500 정의 된 프로그램에서 CFileDialog 사용하기
"Windows 2000 스타일의 파일상자"
1. CFileDialog는 내부적으로 ::GetOpenFileName() 을 사용한다.
GetOpenFileName에 들어가는 구조체인 OPENFILENAME 가 windows 2000 이상에서는 다르다.
OPENFILENAME은 commdlg.h 에 정의되어 있고,
CFileDialog는 AFXDLGS.h에 정의되어 있어서 문제가 된다.
따라서, _WIN32_WINNT=0x500가 정의가 되면 구조체의 삭제시에 에러가난다.
2. Windows 2000 이상에서는 Place Bar 가 들어간 파일상자가 사용된다.
그것은 OPENFILENAME구조체에 변경이 생겼기 때문이다.
(따라서, CFileDialog의 CString m_strFilter; 부분을 먹어버린다.)
다음과 같이 #if (_WIN32_WINNT >= 0x0500) 로 감싸진 3개의 변수가 보인다.
typedef struct tagOFNA {
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCSTR lpstrFilter;
LPSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPSTR lpstrFile;
DWORD nMaxFile;
LPSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCSTR lpstrInitialDir;
LPCSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCSTR lpTemplateName;
#ifdef _MAC
LPEDITMENU lpEditInfo;
LPCSTR lpstrPrompt;
#endif
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAMEA, *LPOPENFILENAMEA;
3. OPENFILENAME구조체는 commdlg.h 내에 존재한다.
commdlg.h는 vc/include, sdk/include, ddk/include 내에 존재한다.
그 중, vc/include 에 있는 것은 windows2000 이상의 것에 대한 언급이 없다.
4. 따라서, windows 2000이상/windows 2000 이하에서 각각에 맞게 잘쓰기..
0) vc7을 쓴다. -_-;;;
1) vc/include/commdlg.h를 컴파일되게 하고 CFileDialogEx를 사용한다.
(http://msdn.microsoft.com/msdnmag/issues/0800/c/)
보통 문제가 생길 경우 include 순서를 잘 맞추라고 권장한다.
2) sdk-ddk/include/comdlg.h를 컴파일되게 하고
vc/include/afxdlgs.h 에서 다음과 같이 고친다.
OPENFILENAME_NT4 m_ofn;
3) sdk-ddk/include/comdlg.h를 컴파일되게 하고
::GetFileOpenName()을 직접 불러준다.