VC6
WindowsXP
MFC
です。
MFCで作成したダイアログにチェックボックスを追加しました。
今HogeDlg.cppのチャックボックスを
他のTest.cpp、Test2.cppで参照したいと考えています。
CHogeDlg* g_Dlg = (CHogeDlg*)AfxGetMainWnd();
とし、
g_Dlg->m_chkBox
とし、コンパイルは通るのですが、
実行するとg_Dlg->m_chkBox
g_DlgのhWndの値が???となってエラーになってしまいます。
とにかくやりたいことは、ダイアログ以外の場所でダイアログのチェックボックスや変
数などを参照したいということです。
初心者なので、どなたかわかるかた教えてください。
AfxGetMainWnd()はそのスレッドの「メインウインドウ」を戻しますが、
CHogeDlgは「メインウインドウ」ですか(質問)。
本当は、メインウインドウと対象のDLGは別のものでは
ありませんか(確認)。
えーと、C++に関する知識はどの程度ありますか?
純粋にC++言語の文法とか使い方の知識の事を言っています。
これによっては説明方法に差が出たりするのでざっくりで良いので
ある程度は書いておいた方が良いです。
自分で自作のクラスを作成して使う事ができる程度とか
そんな話です。
あと、今の説明では内容がかなり足りません。
プロジェクトを作成する時に選んだ種別とか、
ダイアログベース、SDI、MDIのどれなのかとか、
そういう情報も必要になります。
そもそもCHogeDlgってどういうタイミングで表示される物なのかとかも
説明してくれないとご本人には当たり前の事でも掲示板を読んでいる側からはわかりません。
AfxGetMainWndを呼び出すタイミングによってはポインタがうまく取得出来ていない可能
性もありますし。
で、考え方の話ですけれど。
Test.cppとかTest2.cppと言っているのはどういうクラスなんでしょう?
これらのクラスとCHogeDlgの関係は?
単純にCHogeDlgから値が取れれば良いと考えるのではなくて
クラスとクラスの関係を考えてどうするのかベストかを考える必要があります。
例えばですが、CHogeDlgがTest.cppとかTest2.cppのクラスのインスタンスを
保持しているのならTest.cppのクラスの方からCHogeDlgを参照するのではなくて
CHogeDlgがTest.cppのクラスに情報を引き渡すとかそういう考え方もあります。
今、提示されている情報ではその辺の関係が説明されていないので
アプローチ的に良いのかも分かりません。
情報を得るための方法は色々ありますが、クラスとクラスの関係を考えて
組み立てた方がいいです。
これは慣れてからと言わず、最初からそれを意識して考えた方が良いですよ。
とりあえず
CHogeDlg* g_Dlg = (CHogeDlg*)AfxGetMainWnd();
if( g_Dlg!=NULL )
{
// TODO: ここからですね
}
あ、g_Dlgの g_ は何を意味してるのかな?
ひょっとしてグローバル?
だとしたら、どっかで一度だけ AfxGetMainWnd() を呼び出して
そのポインタをずっと使いましょう的な事で、その一度だけの
呼び出しが生成前だったりして
あ、想像ですよ。。。
あれ?
if( g_Dlg!=NULL )
{
// TODO: ここからですね
}
ぢゃ足りないね
if( (g_Dlg!=NULL)&&
(g_Dlg->GetSafeHwnd()!=NULL) )
{
// TODO: ここからですね
}
に変更です
CRuntimeClass* p = ::AfxGetMainWnd()->GetRuntimeClass();
としてpを調べると幸せになれそうな予感。
もう一気に
CHogeDlg* dlg =reinterpret_cast<CHogeDlg*>(theApp.m_pMainWnd);
にしちゃったりして…
でも,メンバをパブリックにするのをやめちゃって,
DDXでチャックボックス(?)の内容を別の所に引きずり出しちゃって
その変数を参照にするとか。。。
あ,本質がズレましたね
問題点としてはいくつかに分類できるのだと思う。
・ AfxGetMainWnd() は本当に CHogeDlg* を返すのか?
・この AfxGetMainWnd() を呼んだ時点で CHogeDlg の実体はあるのか?
・ g_Dlg の示す先をアクセスした時点で CHogeDlg の実体はあるのか?
・ ->m_chkBox と書いてチェックボックスにアクセスしたいタイミングで
本当にその m_chkBox は有効か? (まだ存在しないとか、もう処分済みとか)
・ CWnd は別スレッドからアクセスしてはいけないが問題ないか?
まだあるが省略
InitDialog 以前にコントロールにアクセスしようとして失敗しているに1票
で、どう解決すればよいか・・・だけど
掲示板で書ける分量ではないのでお勉強しておくんなまし。
> ダイアログ以外の場所でダイアログのチェックボックスや変数などを参照したい
というのがそもそも [ダイアログ] の仕様に反しているので
案件から見直したほうがいい。[モーダル] なら特に。
まあ、考え方としてはダイアログのチェックボックスの値が
わかれば良いというような思考方法ではなくて
クラス構成とかウインドウと自作のクラスの関係とか
そういう部分まで考えた上で組み立てないと構成が
崩れてしまってその辻褄を合わせるために更に構成が
おかしくなると言うようになってしまうので、
クラスの構成は良く考えましょうと言う部分ですかね。
単にクラスの中が覗ければ良いと言うのはどうかと思います。
と、ご本人から説明が無いのでなんか憶測だけで話しちゃってますが。
個人的にはDLGベースのプロジェクトにしていて
そのDLGのチェックボックスをわざわざ外部から弄りたい仕様とか考えられない
よってAfxGetMainWnd()はDLGのハンドルを返してない
って思ったのですが後は主様レス待ちすね
みなさんありがとうございます。
このままだとみなさんが注意しているようにただクラス内を参照できるだけでOKとして
しまい、後で自分が困る気がします。
→いちおメインのhWndを取得することでできました。
勉強してから再度質問しますので、とりあえずここで閉じます。
ありがとうございました。