最低100ポイント。VCのMFCプログラミングについて質問です。

CFileDialogダイアログの右上に出てくる
ToolbarWindow32の言葉を英語にしたい!

ToolbarWindow32内のアイコンにカーソルをあわせると、

『直前に表示したフォルダへ移動』
『1つ上のフォルダへ』
『新しいフォルダの作成』
『表示メニュー』---『縮小版』
         |-『並べて表示』
         |-『アイコン』
         |-『一覧』
         |-『詳細』

など表示されます。これらを英語表記にしたいのですが、
よい方法はありませんでしょうか?

せめて文字と対応するIDがわかれば、
フックし、ダイアログ生成時に文字を置き換えることも可能に思えるのですが、
spy++では、アイコン説明用のテキストのIDを取得することができません。

※質問文を理解できない回答者は回答しないでください。また、
 無理やりな回答にはポイントを払いません。 
 解決に至らなくても問題に対し前向きに検討していただいた回答については
 100ポイント以上差し上げます。宜しくお願いします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2007/06/14 13:25:24
  • 終了:2007/06/21 13:30:59

回答(1件)

id:jack_sonic No.1

じゃっくそにっく回答回数123ベストアンサー獲得回数252007/06/20 23:05:37

ポイント60pt

こんにちは。

ファイル選択ダイアログのツールチップの書き換えのサンプルプロジェクトソースを書きましたので、参照下さい。

■実行画面サンプル

[f:id:jack_sonic:20070620224213j:image]


■詳細,プロジェクトソースファイルのダウンロードはこちら

VC++/各種選択ダイアログのツールチップを書き換える - 情報処理研究所 ジャックズラボ(jack's Lab)


■簡単な説明(詳細な技法は、ソースをご覧下さい)

0. Static文字列は、ローカルフックを使って文字列を書き換えます。

1. ファイル選択ダイアログウィンドウのウィンドウプロシージャを書き換えてサブクラス化し、

ウィンドウメッセージ、WM_NOTIFY をキャッチします。

2. WM_NOTIFYをキャッチした中で、

更に、ツールチップイベントを表す

TTN_NEEDTEXT/TTN_NEEDTEXTA/TTN_NEEDTEXTWをキャッチします。

UnicodeのNT系だとWになります。

3.lParamから取り出したpNMHDR->IDFromのボタンのIDに応じて、

TOOLTIPTEXT構造体を参照し、ツールチップを書き換えます。


4.CFileDialogExの作成について

CFileDialogExのOnInitDialog()及び

DoModal()をオーバーライドし、

OnInitDialogでウィンドウプロシージャのサブクラス化、

DoModal()でローカルフック関数のセットアップ関数を呼び出します。


その他. ポップアップを抑制するには、

NM_CUSTOMDRAWをキャッチし、

ポップアップメニューウィンドウを取得して消します。

/////////////////////////////////////////////////////////////////////////

■ソースの主部: 自作のDialogFunc(h/cpp), FileDialogEx(h/cpp)を使います。

■DialogFunc.h ヘッダファイル
// DialogFunc.h
#pragma once

// カラー選択ダイアログ表示関数
// (オーナーウィンドウ, 結果格納COLORREF, 初期カラー, 初期カラーを使うかどうか)
BOOL ColorDlg(HWND hWnd, COLORREF* p_crResult, 
			  COLORREF crFirst, BOOL bUseFirstColor, DWORD dwSpCustomColors[] );
// プロトタイプ宣言
LRESULT CALLBACK LocalHookProc (int nCode, WPARAM wParam ,LPARAM lParam );
int AfxMessageBoxHooked( LPCSTR message , UINT nType );
// フックする
HHOOK SetLocalCBTHook();

// ファイルダイアログをDoModalする
int	HookFileDialogDoModal( CFileDialog * pFileDialog );
// 色選択ダイアログを出す
int CustomFileOpenDialog(HWND hWnd, HINSTANCE hInstance);
// ウィンドウプロシージャ
LRESULT CALLBACK wprocToolBar(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK wprocDialog(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK wprocPopup(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
// ツールチップ処理
BOOL OnToolTipFileDialog(NMHDR* pNMHDR, LRESULT* pResult);
// OFNのフックプロシージャ
UINT CALLBACK OFNHookProcFDialog(HWND hdlg, UINT msg, WPARAM wParam,LPARAM lParam);

// サブクラス化関数
int	subclassToolBarProc(HWND hwnd);	// ツールバー
int subclassDialogProc(HWND hwnd);	// ダイアログ
int subclassPopupProc(HWND hwnd);	// ポップアップ

////////////////////////////////////////////////////////////////////////////////////////////
//				ウィンドウメッセージ関連
static WNDPROC wprocDialogOld=NULL;	// 退避するウィンドウプロシージャ
static WNDPROC wprocToolBarOld=NULL;	// 退避するウィンドウプロシージャ
static WNDPROC wprocPopupOld=NULL;		// 退避するウィンドウプロシージャ

/////////////////////////////
// 置換情報構造体
typedef struct tagRepItem {
	char strBefore[100];	// 置換前文字
	char strAfter[100];		// 置換後文字
	HFONT*	phFont;			// 適用フォントへのポインタ
} stRepItem;
// タイトルの情報と関連付ける置換配列
typedef struct tagRepTitle {
	char strBefore[100];	// 置換前タイトル
	char strAfter[100];		// 置換後タイトル
	HFONT* phFont;			// 適用フォントへのポインタ
	const stRepItem * pRepItem;		// 使用する置換配列
	int aryLength;
} stRepTitle;
/////////////////////////////////
typedef struct tagToolTipRep
{
	UINT nID;
	char strToolTip[MAX_PATH];
} strucToolTipRep;



/////////////////////////////////////////////////////////////
//		ツールチップ書き換え情報(ファイル選択ダイアログ用)
//		ID, 文字列
//		WindowsNT系 Unicode
static const strucToolTipRep aryToolTipRep[]=
{
	{0xa00b, _T("move to the previous displayed folder") },	// 直前に表示したフォルダに移動
	{0xa001, _T("move to upper folder") },	// 1つ上のフォルダへ
	{0xa002, _T("create a new folder") },	// 新しいフォルダの作成
	{0xa00a,  _T("display menu") }	// 表示メニュー
};

static const int len_aryToolTipRep = sizeof(aryToolTipRep)/ sizeof( strucToolTipRep);
//////////////////////////////////////////////////////////////////
// フックハンドル用の変数をグローバルで宣言する。
static HHOOK MyHookHandle;	// フックハンドル変数

static int LangRep = 1;		// 書き換えを行うかどうかのフラグ

// OKの文字列と、キャンセルの文字列
// ボタンの文字を変更したい場合はここを変更してください
static LPCSTR strOK = "OK";			// OKボタンの文字
static LPCSTR strCancel = "Cancel";	// キャンセルボタンの文字
// フォント情報
static LOGFONT rLogfont;			// 論理フォント変数
static HFONT hFontSmall=NULL;		// 小さめのフォント


// 置換情報を含む構造体配列定義
static const stRepItem repColDlg[] =
{
	{"キャンセル" , "cancel" , NULL},
	{"基本色(&B):", "BaseColor(&B)", NULL},
	{"作成した色(&C):", "CreatedColor(&C): to change color from white,down Light", &hFontSmall},
	{"色の作成(&D) >>" , "Create Color(&D) >>", NULL},
	{"色合い(&E):", "Hue(&E):", NULL},
	{"鮮やかさ(&S):", "Saturation(&S):", &hFontSmall },
	{"明るさ(&L):", "Light(&L):", NULL },

	{"赤(&R):", "Red(&R):", NULL},
	{"緑(&G):", "Green(&G):", &hFontSmall},
	{"青(&U):", "Blue(&U):", NULL},
	{"色の追加(&A)", "Add Color(&A)", NULL},
	{"色" , "col", NULL},
	{"| 純色(&O)" , "| pure col(&O)", &hFontSmall}

};
// ファイルを開くダイアログ用
static const stRepItem repFileDlg[] =
{
	{"ファイルの場所(&I):", "Location(&I):" , NULL},
	{"ファイル名(&N):", "File Name(&N):", NULL},
	{"ファイルの種類(&T):", "File Type(&T):", NULL},
	{"キャンセル", "Cancel", NULL},
	{"開く(&O)", "Open(&O)", NULL},
	{"表示メニュー", "Menu" , NULL},
	{"縮小版(&H)", "mini(&H)" , NULL}
};
// タイトルと関連付けの定義
static const stRepTitle repTitle[] = 
{
	{ "色の設定", "Color Settings", NULL , repColDlg,  sizeof(repColDlg)/sizeof(stRepItem) },
	{ "ファイルを開く", "Open File", NULL , repFileDlg,  sizeof(repFileDlg)/sizeof(stRepItem) }
};
■DialogFunc.cpp
#include "StdAfx.h"  // VC++のときインクルード
// StfAfx.hインクルード プリコンパイル済み~のエラーを出さないために必要
// ヘッダインクルード
#include "DialogFunc.h"

//#include "DebugEx.h"


///////////////////////////////////////////////////////////////////////////////
//
//			ダイアログのサブクラス化ウィンドウプロシージャ
//
LRESULT CALLBACK wprocDialog(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
	int i;
	HINSTANCE hInst = AfxGetApp()->m_hInstance; // インスタンス
	TOOLTIPTEXTW* lpTTTW;				// ToolTipText構造体
	NMHDR* pNMHDR = (NMHDR*) lParam;	// NMHDR
	UINT	nID;				// ID
	BOOL	flgRepTTT = false;	// ToolTip書き換えを行ったかどうか
	LRESULT * pResult=NULL;
	NMCUSTOMDRAW  *lpNMCustomDraw;
	HWND hPopupMenu = NULL;
	HWND hMenuItem=NULL ;
	UINT itemID=NULL;
	CString strBuf;
	char strCharBuf[MAX_PATH];
	_tcscpy(strCharBuf, "");
	static MENUITEMINFO	menuInfo;
	static HMENU hmenu=NULL;

	// メッセージトレース
	//traceMsg(hwnd, iMsg,wParam,lParam);

	// メッセージ判断
	if( iMsg == WM_INITDIALOG )
	{


	}else if ( iMsg == WM_NOTIFY ){
			
		//traceCode(hwnd, pNMHDR->code , wParam, lParam);
		// ツールチップ	
		if( OnToolTipFileDialog(pNMHDR, pResult) ) return TRUE;

		// カスタムドロー
		if( pNMHDR->code == NM_CUSTOMDRAW){

			// ポップアップメニューに対する処理
			// ポップアップメニューのウィンドウをキャッチ
			hPopupMenu = 	FindWindow("#32768",NULL);

			if (hPopupMenu && IsWindowVisible(hPopupMenu))
			{
					// ポップアップを消す
					PostMessage(hPopupMenu, WM_KEYDOWN, VK_ESCAPE, 0);
			}




		}

	}else if( iMsg == WM_PAINT){

	
	}
	// 元のウィンドウプロシージャを呼び出す
	return (::CallWindowProc(wprocDialogOld,hwnd,iMsg,wParam,lParam));

}

/////////////////////////////////////////////////////
//
//			ポップアップのサブクラス化ウィンドウプロシージャ
//
LRESULT CALLBACK wprocPopup(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{

	// 元のウィンドウプロシージャを呼び出す
	return (::CallWindowProc(wprocPopupOld,hwnd,iMsg,wParam,lParam));

}
/////////////////////////////////////////////////////
//
//			ツールバーのサブクラス化ウィンドウプロシージャ
//
LRESULT CALLBACK wprocToolBar(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
	int i;
	HINSTANCE hInst = AfxGetApp()->m_hInstance; // インスタンス
	TOOLTIPTEXTW* lpTTTW;				// ToolTipText構造体
	NMHDR* pNMHDR = (NMHDR*) lParam;	// NMHDR
	//traceMsg(hwnd, iMsg,wParam,lParam);
	// メッセージ判断
	switch (iMsg) 
	{
		case WM_NOTIFY:	// Notify
		case WM_PAINT:
			break;
	}	// 元のウィンドウプロシージャを呼び出す
	return (::CallWindowProc(wprocToolBarOld,hwnd,iMsg,wParam,lParam));


}
//////////////////////////////////////////////////////////////////
//
//			ツールチップ
//
BOOL OnToolTipFileDialog(NMHDR* pNMHDR, LRESULT* pResult)
{
	int i;
	HINSTANCE hInst = AfxGetApp()->m_hInstance; // インスタンス
	//NMHDR* pNMHDR = (NMHDR*) lParam;	// NMHDRポインタ
	UINT	nID;				// ID
	TOOLTIPTEXTW* pTTTW;				// ToolTipText構造体
	TOOLTIPTEXTA* pTTTA;
	BOOL	flgTTT = false;	// ToolTip書き換えを行ったかどうか

	//TRACE( " CFileDialogEx::OnToolTip \n");

	if( pNMHDR->code == TTN_NEEDTEXT || pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW)
	{

		// どこからのIDか
		nID = pNMHDR->idFrom;
#ifndef _UNICODE

		if (pNMHDR->code == TTN_NEEDTEXTA)
		{
			pTTTA = (LPTOOLTIPTEXTA)pNMHDR;
			pTTTA->hinst = hInst;
			for( i = 0; i < len_aryToolTipRep ; i++){
				if ( nID == aryToolTipRep[i].nID ){
					lstrcpyn( pTTTA->szText, aryToolTipRep[i].strToolTip, MAX_PATH);
					flgTTT = TRUE;
				}
			}
		}else{
			pTTTW = (LPTOOLTIPTEXTW)pNMHDR;
			pTTTW->hinst = hInst;
			for( i = 0; i < len_aryToolTipRep ; i++){
				if ( nID == aryToolTipRep[i].nID ){
					_mbstowcsz(pTTTW->szText, aryToolTipRep[i].strToolTip, MAX_PATH);
					flgTTT = TRUE;
				}
			}

		}
#else

		if (pNMHDR->code == TTN_NEEDTEXTA)
		{
			pTTTA = (LPTOOLTIPTEXTW)lParam;
			pTTTA->hinst = hInst;

			for( i = 0; i < len_aryToolTipRep ; i++){
				if ( nID == aryToolTipRep[i].nID ){
				_wcstombsz(pTTTA->szText, aryToolTipRep[i].strToolTip, MAX_PATH);
					flgTTT = TRUE;
				}
			}

		}else{
			pTTTW = (LPTOOLTIPTEXTW)lParam;
			pTTTW->hinst = hInst;
			for( i = 0; i < len_aryToolTipRep ; i++){
				if ( nID == aryToolTipRep[i].nID ){
					lstrcpyn(pTTTW->szText, aryToolTipRep[i].strToolTip, MAX_PATH);
					flgTTT = TRUE;
				}
			}
		}
#endif
		if ( flgTTT ) return TRUE;
		else 		return FALSE;


	}else
	{
		return FALSE;
	}
}

//////////////////////////////////////////////////////////////////////////////////////
// サブクラス化プロシージャ
int subclassToolBarProc(HWND hwnd)
{
	TRACE(" new ToolBar WndProc\n");
	// ツールバーのウィンドウプロシージャ							
	wprocToolBarOld=(WNDPROC)SetWindowLong(hwnd , GWL_WNDPROC,(DWORD)wprocToolBar);
	return 1;

}
int subclassDialogProc(HWND hwnd)
{
	TRACE(" new ToolBar WndProc\n");
	// ツールバーのウィンドウプロシージャ							
	wprocDialogOld=(WNDPROC)SetWindowLong(hwnd , GWL_WNDPROC,(DWORD)wprocDialog);
	return 1;
}
int subclassPopupProc(HWND hwnd)
{
	TRACE(" new Popup WndProc\n");
	// ツールバーのウィンドウプロシージャ							
	wprocPopupOld=(WNDPROC)SetWindowLong(hwnd , GWL_WNDPROC,(DWORD)wprocPopup);
	return 1;
}


////////////////////////////////////////////////////////////////////
//
//		ダイアログ文字列書き換えのための
//		フック関数(ローカルフック用)
//		※ グローバル関数である必要があります。
//		この関数の中を変えるときは慎重に行って下さい。
//
LRESULT CALLBACK LocalHookProc (int nCode, WPARAM wParam ,LPARAM lParam )
{
	// コード判断
	if (nCode >= 0)
	{
		if ( nCode == HCBT_ACTIVATE)
		{

			if( LangRep == 1 ){
               //論理フォント構造体の指定
               rLogfont.lfHeight= 10 ;// 大きさ
               rLogfont.lfWidth= 0 ;
               rLogfont.lfEscapement= 0 ;
               rLogfont.lfOrientation= 0 ;
               rLogfont.lfWeight= 0 ;
               rLogfont.lfItalic= FALSE ;
               rLogfont.lfUnderline= FALSE ;
               rLogfont.lfStrikeOut= FALSE ;
               rLogfont.lfCharSet= ANSI_CHARSET ;
               rLogfont.lfOutPrecision= OUT_DEFAULT_PRECIS ;
               rLogfont.lfClipPrecision= CLIP_DEFAULT_PRECIS ;
               rLogfont.lfQuality= DEFAULT_QUALITY ;
               rLogfont.lfPitchAndFamily= VARIABLE_PITCH | FF_SWISS ;
               wsprintf(rLogfont.lfFaceName,_T("MS UI Gothic"));

               //フォントを作成
                hFontSmall = CreateFontIndirect(&rLogfont) ;

				int i,numAry;
				const stRepItem * pRepItem=NULL;
				char strType[50];
				strcpy(strType, "");
				HWND myWnd;
				// タイトルの書き換え
				for( i = 0; i < (sizeof(repTitle)/sizeof(stRepTitle)) ; i++)
				{
					char buff[50];
					GetWindowText((HWND)wParam,buff, sizeof(buff));
					if( strcmp(buff,repTitle[i].strBefore ) == 0 )
					{
						// 一致したものがあった
						SetWindowText((HWND)wParam, repTitle[i].strAfter );

						pRepItem = repTitle[i].pRepItem;
						// レングスを格納
						numAry = repTitle[i].aryLength;
						int k;
						//
						for(  k = 0; k < numAry ; k++)
						{
							// FindWindowEx(親ウィンドウ, 開始子ウィンドウ番号, クラス名 , キャプション);
							myWnd =  FindWindowEx( (HWND)wParam,  0, NULL, pRepItem[k].strBefore );
							if( myWnd != 0)
							{
								SetWindowText(myWnd, pRepItem[k].strAfter );
								if( pRepItem[k].phFont != NULL)
								{
									// フォントの変更
									::SendMessage(myWnd,WM_SETFONT,(WPARAM)*pRepItem[k].phFont,(LPARAM) 1);

								}
							}
						}

						break;
					}
				}

			}			
			// OKボタン(IDOK)の内容を書き換える
			SetDlgItemText( ( HWND )wParam, IDOK, strOK );
			// キャンセルボタン(IDCANCEL)の内容を書き換える
			SetDlgItemText( ( HWND )wParam, IDCANCEL, strCancel );

			HRESULT ret;
			// フック関数をアンインストール(フック解除!)
			ret = UnhookWindowsHookEx ( MyHookHandle );
			MyHookHandle = NULL;
		}
	}
	// 次のフックに渡す
	return CallNextHookEx ( MyHookHandle, nCode, wParam, lParam);
}
/////////////////////////////////////////////////////////////
//
//			ファイル選択ダイアログをフック付きで呼び出す関数
//
int	HookFileDialogDoModal( CFileDialog * pFileDialog )
{

	MyHookHandle = SetWindowsHookEx ( WH_CBT, LocalHookProc, NULL, GetCurrentThreadId( ) ); 

	return pFileDialog->DoModal();

}

HINSTANCE         Instance;

///////////////////////////////////////////////////////////////////////////
//
//
int CustomFileOpenDialog(HWND hWnd, HINSTANCE hInstance)
{
    char file_name[MAX_PATH];
    int result;
	// OPENFILENAME 構造体
    OPENFILENAME open_file_name;

    file_name[0]='\0';
    // 構造体クリア
	ZeroMemory(&open_file_name, sizeof(open_file_name));
	// 構造体パラメータ設定
    open_file_name.lStructSize = sizeof(open_file_name);
    open_file_name.hwndOwner = hWnd;
    open_file_name.hInstance = hInstance;
    open_file_name.lpstrFilter = "files(*.*)\0*.*\0";
    open_file_name.nFilterIndex = 0;
    open_file_name.lpstrFile = file_name;
    open_file_name.nMaxFile = sizeof(file_name);
    open_file_name.lpstrFileTitle = NULL;
    open_file_name.nMaxFileTitle = 0;
    open_file_name.lpstrTitle = "Select file";
    open_file_name.Flags = OFN_FILEMUSTEXIST |
                           OFN_HIDEREADONLY |
                           OFN_PATHMUSTEXIST|
                           OFN_SHOWHELP |
                           OFN_EXPLORER |       //Explorer Style
                           OFN_ENABLESIZING |   //サイズを変更できるようにする
                           OFN_ENABLEHOOK |     //フックプロシージャを使う
                           OFN_ENABLETEMPLATE;  //ダイアログをカスタムする
   // open_file_name.lpfnHook = OFNHookProc;   //フックプロシージャのアドレス
    open_file_name.lpTemplateName = NULL ; //MAKEINTRESOURCE(IDD_CUSTOM);
  //                                                //追加するダイアログリソース
    result = GetOpenFileName(&open_file_name);
    
    return  result;
}



///////////////////////////////////////////////////////////
//
//	ColorDlg() カラー選択ダイアログ関数
//	カスタムカラー配列はstaticで保存されます。
//		@param  hWnd		:   オーナーウィンドウ
//		@param  p_crResult	:	結果を受け取るCOLORREFのポインタ 
//		@param	crFirst		:  初期選択色
//		@param	bUserFirstColor: 初期選択色を使うかどうか
//		@param dwSpCustomColors[] 
//					: カスタムカラー配列を独自に指定する場合(NULL: デフォルト保存)
//		@return TRUE:選択 , FALSE :キャンセル
//
BOOL ColorDlg(HWND hWnd, COLORREF* p_crResult, 
			  COLORREF crFirst, BOOL bUseFirstColor, DWORD dwSpCustomColors[] )
{
	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください

	// CHOOSECOLOR構造体定義
	CHOOSECOLOR cc;
	// カスタムカラーボックスのデータ配列定義
	// 16個のCOLORREF変数の配列 ( staticで宣言すること)
	static DWORD       dwDefaultCustomColors[16];   
	// COLORREF構造体定義
	static COLORREF crDefaultFirst = RGB(255,255,255);

	// CHOOSECOLOR構造体クリア
	ZeroMemory(&cc,sizeof(CHOOSECOLOR));
	// CHOOSECOLOR構造体サイズ設定
	cc.lStructSize = sizeof(CHOOSECOLOR);
	// オーナーウィンドウ設定
	cc.hwndOwner =(HWND ) hWnd;
	// カスタムカラーボックスのデータ配列設定
	cc.lpCustColors = ( dwSpCustomColors != NULL)? dwSpCustomColors: dwDefaultCustomColors;

	// 	初期選択色
	cc.rgbResult =  (bUseFirstColor == TRUE)? crFirst: crDefaultFirst;
	// フラグ設定
	// CC_FULLOPEN : カスタムカラー設定表示
	// CC_RGBINIT  : rgbResultの色を初期選択
	// CC_ANYCOLOR : 使用可能な全ての色を表示する
	cc.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;
	

	// フック関数(MsgBoxHookProc)をインストールする SetWindowHookEx
	MyHookHandle = SetWindowsHookEx ( WH_CBT, LocalHookProc, NULL, GetCurrentThreadId( ) ); 

	// カラーダイアログを表示
	if(ChooseColor(&cc)){
		*p_crResult = cc.rgbResult;
		return TRUE;
	}
	return FALSE;
}
//////////////////////////////////////////////////////////////////////////////
//
//	OFNで設定するフックプロシージャ
UINT CALLBACK OFNHookProcFDialog(HWND hdlg, UINT msg, WPARAM wParam,LPARAM lParam)
{
	HWND hwndTB=NULL;
    switch(msg){
        case WM_INITDIALOG:
			TRACE("WM_INITDIALO\n");
           break;
		case WM_NOTIFY:
			break;
		case WM_PAINT:
			break;
        case WM_COMMAND:
            break;

    }
    return FALSE;
}
/////////////////////////////////////////////////////////////////////
//
//		AfxMessageBoxHooked(メッセージ, 
//
int AfxMessageBoxHooked( LPCSTR message , UINT nType )
{
	// フック関数(MsgBoxHookProc)をインストールする SetWindowHookEx
	MyHookHandle = SetWindowsHookEx ( WH_CBT, LocalHookProc, NULL, GetCurrentThreadId( ) ); 
	return ( AfxMessageBox(message, nType) ); 

}
///////////////////////////////////////////////////////////////
//   生成時のローカルフックをセット
HHOOK SetLocalCBTHook()
{
	MyHookHandle = SetWindowsHookEx ( WH_CBT, LocalHookProc, NULL, GetCurrentThreadId( ) ); 
	return MyHookHandle;
}

---------------------------------------------------------

■FileDialogEx.h
#if !defined(AFX_FILEDIALOGEX_H__41400550_A694_4721_BEB6_515F13D27D23__INCLUDED_)
#define AFX_FILEDIALOGEX_H__41400550_A694_4721_BEB6_515F13D27D23__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// FileDialogEx.h : ヘッダー ファイル
//
#include "DialogFunc.h"


/////////////////////////////////////////////////////////////////////////////
// CFileDialogEx ダイアログ

class CFileDialogEx : public CFileDialog
{
	DECLARE_DYNAMIC(CFileDialogEx)

public:
	CFileDialogEx(BOOL bOpenFileDialog, // TRUE ならば FileOpen、 FALSE ならば FileSaveAs
		LPCTSTR lpszDefExt = NULL,
		LPCTSTR lpszFileName = NULL,
		DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		LPCTSTR lpszFilter = NULL,
		CWnd* pParentWnd = NULL);
	// オーバーライド
	BOOL CFileDialogEx::OnInitDialog();
	int DoModal();
protected:
	// メッセージマップマクロ
	//{{AFX_MSG(CFileDialogEx)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。

#endif // !defined(AFX_FILEDIALOGEX_H__41400550_A694_4721_BEB6_515F13D27D23__INCLUDED_)

■FileDialogEx.cpp
// FileDialogEx.cpp : インプリメンテーション ファイル
//

#include "stdafx.h"
#include "DialogSampleEx.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include "FileDialogEx.h"

#include "DialogFunc.h"


/////////////////////////////////////////////////////////////////////////////
// CFileDialogEx

IMPLEMENT_DYNAMIC(CFileDialogEx, CFileDialog)

CFileDialogEx::CFileDialogEx(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
		DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
		CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
}

// メッセージマップマクロ
BEGIN_MESSAGE_MAP(CFileDialogEx, CFileDialog)
	//{{AFX_MSG_MAP(CFileDialogEx)
		// メモ -  ClassWizard はこの位置にマッピング用のマクロを追加または削除します。
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()



/////////////////////////////////////////////////////////////
//
//			OnInitDialog()
//
BOOL CFileDialogEx::OnInitDialog() 
{
	CFileDialog::OnInitDialog();

	CWnd *pWD = this->GetParent();

	
	// !! サブクラス化する
	// ダイアログのウィンドウプロシージャを設定して古いほうを退避(ダイアログ)
	subclassDialogProc(pWD->m_hWnd);

	return TRUE;
}
///////////////////////////////////////////////////////////
//
//
//
int CFileDialogEx::DoModal()
{
	SetLocalCBTHook();
	return ( CFileDialog::DoModal());
}

------------------------------------------

■使い方

DialogFunc.h/cpp, CFileDialogEx.h/cppを

プロジェクトに組み込み、

CFileDialogEx.hをインクルードして使います。

呼び出し方は通常のCFileDialogと同じです。

カスタマイズ方法でわからないことがあれば直接ご連絡下さい。

void CDialogSampleExDlg::OnButton2() 
{
	// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
		CFileDialogEx dlg(TRUE, NULL, NULL,
					OFN_FILEMUSTEXIST |	OFN_HIDEREADONLY,
					_T("All files(*.*)|*.*||"));
	char szFileNameBuffer[10000] = {0};      // ファイル名を保存させる為のバッファ
	dlg.m_ofn.lpstrFile = szFileNameBuffer;  // バッファの割り当て
	dlg.m_ofn.nMaxFile  = 10000;             // 最大文字数の設定


	if( dlg.DoModal()  == IDOK)
	{
		POSITION pos = dlg.GetStartPosition();
		while(pos)
		{
			AfxMessageBox(dlg.GetNextPathName(pos));
		}
	}
}
  • id:jack_sonic
    補足:
    display menuのプルダウンメニューは、
    ツールチップではなく書き換えの対象にならないので、
    VK_ESCAPE送信で故意に出ないようにしてあります。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません