みなさん、こんにちは。
ウインドウクラス名の変更について、お聞きしたい事があり
ます。
ダイアログベースのアプリを作成する場合に、ダイアログ生
成時のウインドウクラス名の設定方法が(ウインドウクラス
名の変更でも良いのですが)わかりません。
確か、ダイアログのウインドウクラス名は固定だったような
気がするのですが(間違っていたらすみません)
ダイアログ生成時のウインドウクラス名の登録(又は生成後の
ウインドウクラス名の変更)は可能でしょうか?
(プロセス間で、ウインドウクラス名を使用してメッセージの
やり取りを行いたいのですが・・・)
何方か、詳しい方がいらっしゃいましたら、ご教授お願い致
します。
それでは、宜しくお願い致します。
MSDNの「Custom Dialog Boxes」に独自の
ウィンドウクラスを使う方法が記載されています。
簡単にまとめると、
普通のウィンドウクラスと違う点は次の2点です。
・ウィンドウプロシージャは、DefWindowProcの代わりにDefDlgProcを呼ぶ
(MFCの場合は、WNDCLASS::lpfnWndProcにDefDlgProcをセット)
・WNDCLASS::cbWndExtraにDLGWINDOWEXTRAをセットする
上記のクラスを使うためにリソースを修正します。
VC++のリソースエディタはクラス名に対応していないので、
.rcファイルをテキストエディタ等で開いて、
ダイアログの定義に以下を追加します。
CLASS クラス名
dairygoodsさん、回答ありがとうございました。
教えて頂いた方法を参考にして下記のようにMKしました。
CSapmleApp(CWinAppの派生クラス)::InitInstance
-------------------------------------------------------
BOOL CSapmleApp::InitInstance()
{
・
・
・
WNDCLASS wc;
wc.style = CS_DBLCLKS;
wc.lpfnWndProc = DefDlgProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.hInstance = m_hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = _T(clsSampleDialog);
if( !AfxRegisterClass( &wc ) )
{
return FALSE;
}
・
・
・
}
-------------------------------------------------------
教えていただいた方法ですと、リソースを変更しなくては
いけないのですが、その場合、例えば、ダイアログベース
アプリの起動パラメータ(コマンドライン)でダイアログ
のクラス名を変更するような仕様だとクラス名の変更は無
理ですよね。(リソースの[CLASS]の名称とwc.lpszClas
sNameは同じ)
NEGさん、回答ありがとうございます。
NEGさんから教えて頂いた方法を参考に、下記のようにMK(サン
プルと同じ)しました。(リソースのクラス名は”clsClassNameCha
nge”に設定しました)
----------------------------------------------------------
CClassNameChangeApp(CWinAppの派生クラス)::InitInstance
----------------------------------------------------------
BOOL CClassNameChangeApp::InitInstance()
{
・
・
・
WNDCLASS wdc;
HINSTANCE hin;
LPCSTR lpClassName = clsNewClassNameChange;
hin=AfxGetInstanceHandle();
if(!::GetClassInfo(hin,nam,&wdc))
{
::GetClassInfo(hin,#32770,&wdc);
wdc.lpszClassName=lpClassName;
wdc.hIcon=::LoadIcon(hin,MAKEINTRESOURCE(IDR_MAINFRAME));
::RegisterClass(&wdc);
}
CClassNameChangeDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
・
・
・
}
-------------------------------------------------------
実行結果なんですが、こちらもダイアログ自体表示されず、終了してし
まいました。
何かソース上に問題がありますでしょうか?
NEG さん
> http://www24.cds.ne.jp/~neg/pro/piyo1/window/cnam.html
なるほど。
リソースエディタでもクラス名を修正できるんですね。
参考になりました。
たまちゃん さん
実行時にクラス名を決めるとなると、
次のようにすればできるかもしれません。
1. LoadResourceで自分でダイアログリソースを読み込む。
2. ロードしたDLGTEMPLATEEXの内容を修正する。
3. CDialog::InitModalIndirect()を使って
修正したダイアログテンプレートからダイアログを生成する。
(CDialogのコンストラクタにはリソースIDを指定しない)
それよりも、単純にウィンドウ名で検索するか、
SetWindowLong(GWL_USERDATA,..);
でアプリケーション固有の値を登録して
それをキーに検索するといった別の方法を考えてみては?
dairygoodsさん、回答ありがとうごさいます。
>実行時にクラス名を決めるとなると、
>次のようにすればできるかもしれません。
>1. LoadResourceで自分でダイアログリソースを読み込む。
>2. ロードしたDLGTEMPLATEEXの内容を修正する。
>3. CDialog::InitModalIndirect()を使って
> 修正したダイアログテンプレートからダイアログを生成する。
> (CDialogのコンストラクタにはリソースIDを指定しない)
いろいろ挑戦してみましたが、うまく動作致しません。
LoadResourceやInitModalIndirectについて詳しい解説等がある
HPをご存知ではないですか?
調べてはいるのですが、なかなか見つからないので・・・。
もし、ご存知でしたら教えて下さい。
>それよりも、単純にウィンドウ名で検索するか、
>SetWindowLong(GWL_USERDATA,..);
>でアプリケーション固有の値を登録して
>それをキーに検索するといった別の方法を考えてみては?
パラメータでクラス名を変更するのが仕様の為、他の方法で実現
するのは無理みたいなんです。
> いろいろ挑戦してみましたが、うまく動作致しません。
> LoadResourceやInitModalIndirectについて詳しい解説等がある
> HPをご存知ではないですか?
自分で言っておいて、あまり詳しくないですが、
CDialog::DoModal()のソースを見るとリソースのロードの
しかたは分かると思います。
ところで、ダイアログ自身のクラス名に拘らなくても、
次のようにしてもいいんじゃないでしょうか?
案1. 普通のウィンドウの中にダイアログを埋め込む
(SDIの簡易版みたいな作り)
案2. 別途普通のウィンドウを作り、非表示にしておく