CMyMultiOfn クラスの構成の概略
全体の見通しをよくするために、実際のコーディングと構成が異なっています。
////////////////////////////////////////////////////////////////////////
// MyMultiOfn.h
//
#ifndef
_MYMULTIOFN_H_
#define
_MYMULTIOFN_H_
#include
"windows.h"
#include
"tchar.h"
#include
"commdlg.h"
#include
"dlgs.h"
#include
"cderr.h"
class CMyMultiOfn
{
public:
CMyMultiOfn ( ) ;
~CMyMultiOfn ( ) ;
GetOpenFileName ( ) ;
OPENFILENAME m_ofn ;
LPTSTR m_lpstrNewFile ;
/* NT 系でバッファーサイズが不足した場合に、臨時にバッファーをこのポインターに確保する */
} ;
CMyMultiOfn multiOfn ;
#endif
// _MYMULTIOFN_H_ :
////////////////////////////////////////////////////////////////////////
// MyMultiOfn.cpp
//
#include
"MyMultiOfn.h"
// ファイル開くダイアログの終了直前にバッファーサイズの調整を行う関数
static void MyOfnResizeBuffer ( ) ;
/*--- ウィンドプロシージャ ---------------------------------------*/
// OPENFILENAME::lpfnHook メンバーでフックしたダイアログ
static UINT CALLBACK MyOfnChildDlgProc ( HWND, UINT, WPARAM, LPARAM ) ;
// ファイル開くダイアログの一番親のダイアログ
static UINT CALLBACK MyOfnMainProc ( HWND, UINT, WPARAM, LPARAM ) ;
// ファイル開くダイアログのリストビュー
static LRESULT CALLBACK MyOfnListProc ( HWND, UINT, WPARAM, LPARAM ) ;
// ファイル開くダイアログのエディットコンロトール
static LRESULT CALLBACK MyOfnEditProc ( HWND, UINT, WPARAM, LPARAM ) ;
/*--- デフォルトのウィンドプロシージャ -------------------------------*/
static DLGPROC MyOfnMainDlgOldProc ;
static WNDPROC MyOfnListOldProc ;
static WNDPROC MyOfnEditOldProc ;
/***********************************************************************
コンストラクタ
***********************************************************************/
CMyMultiOfn::CMyMultiOfn ( )
{
m_lpstrNewFile = NULL ;
// OPENFILENAME 構造体の初期化処理
ZeroMemory ( &m_ofn, sizeof ( OPENFILENAME ) ;
m_ofn.lStructSize = sizeof ( OPENFILENAME ) ;
m_ofn.hInstance = GetModuleHandle ( NULL ) ;
m_ofn.nMaxFile = MAX_PATH ;
m_ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_ENABLEHOOK ;
m_ofn.lpfnHook = MyOfnChildDlgProc ;
}
/***********************************************************************
デストラクタ
***********************************************************************/
CMyMultiOfn::~CTlMultiOfn ( )
{
if ( m_ofn.lpstrFile )
delete [] m_ofn.lpstrFile ;
if ( m_lpstrNewFile )
delete [] m_lpstrNewFile ;
}
/***********************************************************************
ファイル開くダイアログを呼び出す関数
***********************************************************************/
void CMyMultiOfn::GetOpenFileName ( )
{
DWORD nError ;
// 初期のバッファーを確保する
if ( !m_ofn.lpstrFile )
if ( ! ( m_ofn.lpstrFile = new TCHAR [m_ofn.nMaxFile] ) )
throw CDERR_MEMALLOCFAILURE ;
// ファイル開くダイアログを呼び出す
if ( ::GetOpenFileName ( &m_ofn ) )
return ;
// エラー処理
nError = ::CommDlgExtendedError ( ) ;
if
( nError == FNERR_BUFFERTOOSMALL && m_lpstrNewFile ) {
/* ここに m_ofn.lpstrFile のポイント先を m_lpstrNewFile に変更する処理を記述 */
} else {
throw nError ;
}
}
/***********************************************************************
OPENFILENAME::lpfnHook メンバーでフックしたダイアログプロシージャ
***********************************************************************/
UINT CALLBACK MyOfnChildDlgProc ( HWND hWnd, UINT wm, WPARAM wp, LPARAM lp )
{
switch ( wm ) {
case
WM_INITDIALOG:
/* ここに親ダイアログをサブクラス化する処理を記述 */
break ;
case WM_NOTIFY:
switch ( ( ( LPOFNOTIFY ) lp ) -> hdr.code ) {
case CDN_FOLDERCHANGE:
/* ここにエディットコントロールの表示をクリアする処理と、リストコントロールのハンドルが変化していればサブクラス化し直す処理とを記述 */
break ;
case CDN_INITDONE:
/* ここにユーザー入力を禁止するためにエディットコントロールをサブクラス化する処理を記述 */
break ;
}
}
return FALSE ;
}
/***********************************************************************
ファイル開くダイアログの一番親のダイアログプロシージャ
***********************************************************************/
UINT CALLBACK MyOfnMainProc ( HWND hWnd, UINT wm, WPARAM wp, LPARAM lp )
{
switch ( wm ) {
case WM_DESTROY:
/* ここに元のプロシージャに戻す処理を記述 */
break ;
case WM_COMMAND:
if ( LOWORD ( wp ) == IDOK )
/* ファイル開くダイアログの終了直前にバッファーサイズ調整を行う */
MyOfnResizeBuffer ( ) ;
break ;
}
return CallWindowProc ( ( WNDPROC ) MyOfnMainOldProc, hWnd, wm, wp, lp ) ;
}
/***********************************************************************
ファイル開くダイアログのリストビュー ウィンドウプロシージャ
***********************************************************************/
LRESULT CALLBACK MyOfnListProc ( HWND hWnd, UINT wm, WPARAM wp, LPARAM lp )
{
switch
( wm ) {
case
WM_DESTROY:
/* ここに元のプロシージャに戻す処理を記述 */
break
;
case WM_KEYDOWN:
if ( ( int ) wp == VK_RETURN )
/* ファイル開くダイアログの終了直前にバッファーサイズ調整を行う */
MyOfnResizeBuffer ( ) ;
break ;
}
return CallWindowProc ( MyOfnListOldProc, hWnd, wm, wp, lp ) ;
}
/***********************************************************************
ファイル開くダイアログのエディット ウィンドウプロシージャ
***********************************************************************/
LRESULT CALLBACK MyOfnEditProc ( HWND hWnd, UINT wm, WPARAM wp, LPARAM lp )
{
switch ( wm ) {
case WM_DESTROY:
/* ここに元のプロシージャに戻す処理を記述 */
break ;
case WM_KEYDOWN:
case WM_CHAR:
case WM_PASTE:
/* TRUE を返してユーザー入力を禁止する */
return TRUE ;
}
return CallWindowProc ( MyOfnEditOldProc, hWnd, wm, wp, lp ) ;
}
/***********************************************************************
ファイル開くダイアログの終了直前にバッファーサイズ調整を行う関数
***********************************************************************/
void MyOfnResizeBuffer ( )
{
/* ここに必要なバッファーサイズを求める処理を記述 */
DWORD nRequestSize = 0 ;
if
( nRequestSize < multiOfn->m_ofn.nMaxFile ) {
/* バッファーサイズが小さ過ぎた場合の処理 */
/*
( 1 ) 新たなバッファーを multiOfn->m_lpstrNewFile に確保する処理
( 2 ) ::GetVersionEx を使って Windows 9X 系か NT 系か判定する
9X 系 : 新バッファーを OPENFILENAME::lpstrFile メンバーのポイント先とする
NT 系 : 新バッファーにパスとファイル名を格納し、書式を整える
*/
}
}