コールバック関数内でのメッセージ処理

[戻る]
kuro 2008/04/14(月) 21:15:42
質問させてください。

EXE側で定義したコールバック関数をDLLで実行させ、
コールバック関数内でEXE側にメッセージを飛ばしたいのですが、
うまくいきません。

EXE側
CXXXDlg.h
static CXXXDlg* m_pdlg;

CXXXDlg.cpp
CXXXDlg* CXXXDlg::m_pdlg = (CXXXDlg*)AfxGetMainWnd();

コールバック関数内

CXXXDlg* dlg = (CXXXDlg*)AfxGetMainWnd();
dlg->m_pdlg->PostMessage(パラメータ);

としたのですが、メッセージが飛ばずに落ちてしまいます。
デバックしてみたのですが、関数内のm_pdlgの値が入っていませんでした。
m_pdlgとdlgを二重に定義しているのが、間違っている気がしますが
どうしてよいか分かりません。
お願いします。
環境: XP VS2005 MFCアプリケーション

wclrp ( 'o') 2008/04/14(月) 21:50:03
省略してあるところが気になる。

class CXXXDlg {
static CXXXDlg* m_pdlg;
じゃなくて
ただの
static CXXXDlg* m_pdlg;
だったらm_pdlgはCXXXDlgのメンバ変数じゃなくて別の変数だし。

そもそもstaticメンバ変数ならdlg->m_pdlgなんてしないし。

kuro 2008/04/14(月) 21:54:35
>class CXXXDlg {
>static CXXXDlg* m_pdlg;
上記のようにCXXXDlgクラスのメンバにしています。

staticメンバへのアクセスはどのようにしたらよいのでしょう?
CXXXDlg::m_pdlg->PostMessage()
としてもだめでした...

kuro 2008/04/14(月) 21:54:36
>class CXXXDlg {
>static CXXXDlg* m_pdlg;
上記のようにCXXXDlgクラスのメンバにしています。

staticメンバへのアクセスはどのようにしたらよいのでしょう?
CXXXDlg::m_pdlg->PostMessage()
としてもだめでした...

wclrp ( 'o') 2008/04/14(月) 22:02:09
あっ!

関数の外にある
> CXXXDlg* CXXXDlg::m_pdlg = (CXXXDlg*)AfxGetMainWnd();
この変数の初期化は
メインウィンドウを作成する関数より先に実行される。

当然メインウィンドウはないので
AfxGetMainWnd()は期待通りにならない。

つまり
>コールバック関数内
>デバックしてみたのですが、関数内のm_pdlgの値が入っていませんでした。
ではなく
コールバック関数が呼ばれるよりも前
最初からm_pdlgに値が入っていない。

メインウィンドウを作成した後にする。
CWinAppのm_pMainWndだっけ?

kuro 2008/04/15(火) 00:23:53
>メインウィンドウを作成した後にする。
>CWinAppのm_pMainWndだっけ?
ありがとうございます、そういうことだったんですね。

<CXXXDlg.h>
static CXXXDlg* m_pWin; ←追加


<CWinApp>
CXXXDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
dlg.m_pWin = (CCallDlg*)AfxGetApp()->m_pMainWnd; ←追加

上記のように追加しましたが、
error LNK2001: 外部シンボル がでてしまいました。
staticのアクセスがまずいみたいです。

初歩的はことですみません。

wclrp ( 'o') 2008/04/15(火) 07:56:21
同じm_pdlgがあるのにm_pWinに変えた理由がわからない。

CXXXDlg* CXXXDlg::m_pWin;
を用意しないとダメ。


staticメンバ変数は使わなくても実現できると俺は思っている。
実際に試したわけじゃないけどね。

それよりも、

DoModalは、ダイアログを閉じるまでリターンされない。
つまり
>dlg.m_pWin = (CCallDlg*)AfxGetApp()->m_pMainWnd; ←追加
を実行するときはダイアログを閉じた後だよ。

結局dlg.m_pWinは設定されてないまま。
設定された時はプログラムが終了するとき。


EXE側で定義したコールバック関数は
dlg.DoModal()を実行する前に呼ばれるとか変なことはないよね。
(念のため)


EXE側で定義したコールバック関数内

CWnd* mainWnd = AfxGetMainWnd();
if(mainWnd != NULL) mainWnd->PostMessage(パラメータ);

だって、
 dlg->m_pdlg
 dlg.m_pWin
 AfxGetApp()->m_pMainWnd
 AfxGetMainWnd()
どれもメインウィンドウだから。

PostMessageを使いたいだけならCWndのメンバ関数だからキャストもいらない。

繰り返すけど、実際に試したわけじゃないので、うまくいくか知らないよ。

kuro 2008/04/15(火) 09:46:40
おはようございます。

>つまり
>>dlg.m_pWin = (CCallDlg*)AfxGetApp()->m_pMainWnd; ←追加
>を実行するときはダイアログを閉じた後だよ
そうでした、ありがとうございます。


>EXE側で定義したコールバック関数内

>CWnd* mainWnd = AfxGetMainWnd();
>if(mainWnd != NULL) mainWnd->PostMessage(パラメータ);

上記のようにしてみたのですが、mainWndに値が取得できません。
なぜでしょうか?
mainWndをCXXXDlgのメンバにしてみたのですがだめでした。

kuro 2008/04/15(火) 10:41:07
[[解決]]
static CWnd* mainWnd; (グローバル)

として、OnInitDialog()内で
 extern CWnd* mainWnd;
  mainWnd = AfxGetMainWnd();


EXE側で定義したコールバック関数内
  extern CWnd* mainWnd;
  if(mainWnd != NULL) mainWnd->PostMessage(パラメータ);

上記のようにしたところ、メッセージが飛びました。

wclrp ( 'o')さん、色々ありがとうございました!

古いスレッドには追加発言できません。