VC++ 2005 MFCアプリケーションのダイアログベースでアプリケーションを作成しており
ます。
ダイアログ上にエディットボックスを配置して、EN_CHANGEイベントで処理を行っている
のですが、この関数がOnInitDialog関数の前にも呼び出されてしまいます。
現在は、OnEnChange関数の中でDDXコントロールのNULLチェックを行い関数での処理を回
避しております。もっと良い方法は無いのでしょうか?
何か情報をご存知でしたらご教授願います。
なお、基本的なダイアログでは、このような現象が発生しないことを確認しておりま
す。
また、OnInitDialog関数、OnEnChange関数の前に呼び出される関数としてOnSize関数を
追加しておりますが、この関数では現在何も処理を行っておりません。
何故呼び出されるのか、OnEnChange関数にブレークポイントを張って、
コールスタックを調べてみたらいかがですか?
Kerryさん、早速の回答ありがとうございます。
汚くなってしまいますがプレー九ポイントを張った時の呼び出し履歴は下記の通りで
す。
*****************ここから****************
TestApp.exe!CTestAppDlg::OnEnChangeA() 行 895 C++
TestApp.exe!_AfxDispatchCmdMsg(CCmdTarget * pTarget=0x0012f778, unsigned int
nID=1019, int nCode=768, void (void)* pfn=0x004eddda, void *
pExtra=0x00000000, unsigned int nSig=56, AFX_CMDHANDLERINFO *
pHandlerInfo=0x00000000) 行 82 C++
TestApp.exe!CCmdTarget::OnCmdMsg(unsigned int nID=1019, int nCode=768, void *
pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) 行 381 +
0x27 バイト C++
TestApp.exe!CDialog::OnCmdMsg(unsigned int nID=1019, int nCode=768, void *
pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) 行 85 + 0x18
バイト C++
TestApp.exe!CWnd::OnCommand(unsigned int wParam=50332667, long lParam=722362)
行 2300 C++
TestApp.exe!CWnd::OnWndMsg(unsigned int message=273, unsigned int
wParam=50332667, long lParam=722362, long * pResult=0x0012e554) 行 1755 +
0x1e バイト C++
TestApp.exe!CWnd::WindowProc(unsigned int message=273, unsigned int
wParam=50332667, long lParam=722362) 行 1741 + 0x20 バイト C++
TestApp.exe!AfxCallWndProc(CWnd * pWnd=0x0012f778, HWND__ * hWnd=0x000a05cc,
unsigned int nMsg=273, unsigned int wParam=50332667, long lParam=722362) 行
240 + 0x1c バイト C++
TestApp.exe!AfxWndProc(HWND__ * hWnd=0x000a05cc, unsigned int nMsg=273,
unsigned int wParam=50332667, long lParam=722362) 行 389 C++
:
:
TestApp.exe!COleServerItem::OnSaveEmbedding(IStorage * lpStorage=0x0017e228)
行 747 + 0x18 バイト C++
:
:
TestApp.exe!CWnd::CreateDlgIndirect(const DLGTEMPLATE *
lpDialogTemplate=0x0017bd00, CWnd * pParentWnd=0x00000000, HINSTANCE__ *
hInst=0x00400000) 行 307 + 0x2a バイト C++
TestApp.exe!CDialog::DoModal() 行 536 + 0x20 バイト C++
TestApp.exe!CTestAppApp::InitInstance() 行 69 + 0xb バイト C++
TestApp.exe!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ *
hPrevInstance=0x00000000, char * lpCmdLine=0x00151f05, int nCmdShow=1) 行 37
+ 0xd バイト C++
TestApp.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ *
hPrevInstance=0x00000000, char * lpCmdLine=0x00151f05, int nCmdShow=1) 行 29
C++
TestApp.exe!__tmainCRTStartup() 行 315 + 0x35 バイト C
TestApp.exe!WinMainCRTStartup() 行 187 C
****************ここまで**************
nIDの1019はエディットボックスのIDです。
正しくOnEnChange関数を呼び出しているところを見るとハンドルなどは問題無いと思い
ます。
少しおかしく思ったのはOnCmdMsg関数のnCodeですが、ヘルプにあった下記の値のいずれ
でもないように思います。
CN_COMMAND 0
CN_EVENT (UINT)(-1)
CN_UPDATE_COMMAND_UI (UINT)(-2)
CN_OLECOMMAND (UINT)(-3)
CN_OLE_UNREGISTER (UINT)(-4)
私は初心者なのでこれ以上のことはよくわかりません。
これで何かわかる事があったらご指摘ください。
> なお、基本的なダイアログでは、
> このような現象が発生しないことを確認しております。
このような場合にしばしば役に立つ方法としては、
現象が発生するプロジェクトを基本的なダイアログに近づけてみることです。
コールスタックから有効な回答が付くかもしれませんので、
やらなくても良いかもしれませんが、今後のためにも
手順は理解しておいた方が得だと思います。
以下、その手順
バックアップを取り、現象と関係なさそうなソースを削除して、
ビルドして現象の発生を確認しましょう。
現象が確認できたら、あなたの問題は少し小さくなります。
現象が発生しなかったら、バックアップに戻り、別のところを削除して試します。
最終的には、基本的なダイアログに最小限の変更を加えたら、
現象が起きるようにします。つまり、新規プロジェクトから、現象発生までの
最小限の手順がわかりますので、それを掲示板で聞いてみればよいのです。
この過程で問題点に自分で気付くことも多いでしょう。
あきらかにおかしいのは
> TestApp.exe!COleServerItem::OnSaveEmbedding(IStorage *
> lpStorage=0x0017e228)
↑これでしょう。
ダイアログベースのアプリケーションでなんでこんなメソッドが
呼ばれるのか謎です。
まずは、たいちうさんがおっしゃるとおり、問題の範囲を狭める
必要があると思います。
可能な限りコードを削ってみて、どの部分のコードを実行したときに
おかしくなるのかをつきとめましょう。
たいちうさん、Kerryさんご指摘ありがとうございます。
教えていただいた手順で確認を行ったところ、スピンコントロールのAuto Buddyプロ
パティをTRUEにしていると関連付けられたOnEnChange関数が呼び出される事がわかり
ました。
よって、この値はFALSEのまま、OnInitDialogでスピンコントロールのメンバ関数
(SetBuddy)によりコントロールの関連付けを行う事にします。
いろいろとありがとうございました。