環境は Windows XP(SP3), VC++6.0 MFC です。
現象はユーザ定義メッセージを使用した場合にDebug版ではエラーにならず、リリース版
ではメモリエラー(メモリがreadになることができませんでした)が発生して落ちてしま
います。過去ログ等からnew、deleteや配列によるメモリ問題が怪しいと思い調査しまし
たが原因が不明です。アドバイスを頂けないでしょうか?
原因を特定するために最小限のソースにてデバッグ中です。
<プログラム内容>
ダイアログアプリケーションでButton1をクリックすると関数OnButton1でメッセージ
(WM_MYMESSAGE)を発行して、メッセージマップで関連づけされた関数On_MyMessage()が
呼ばれる。関数On_MyMessage()のHellow がメッセージボックスで出力された後、メモ
リエラーで落ちます。どこが間違えているのでしょうか?
ヘッダファイルに
//{{AFX_MSG(CTest7Dlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButton1();
afx_msg void MyMessage(); //これを追加
//}}AFX_MSG
**.cppに
BEGIN_MESSAGE_MAP(CxxxDlg, CDialog)
//{{AFX_MSG_MAP(CxxxDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_MYMESSAGE,On_MyMessage) //これを追加
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CxxxDlg::OnButton1()
{
this->SendMessage(WM_MYMESSAGE); //これを追加
}
void Cxxx7Dlg::On_MyMessage()
{
AfxMessageBox(Hellow);
}
・On_MyMessage の関数の宣言が間違ってます。ってこれはコンパイルエラーにならない
んでしたっけ?
・WM_MYMESSAGE はどうやって定義していますか?
>On_MyMessage の関数の宣言が間違ってます。ってこれはコンパイルエラーにならない
>んでしたっけ?
すみません、私の記載ミスです。
関数定義は
//{{AFX_MSG(CTest7Dlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnButton1();
afx_msg void On_MyMessage(); //これを追加
//}}AFX_MSG
>WM_MYMESSAGE はどうやって定義していますか?
CxxxDlg.cppのファイル上部で
#define WM_MYMESSAGE (WM_APP+1)
と定義しています。
#define WM_MYMESSAGE (WM_USER+1) も試しましたが同じでした。
というより CxxxDlg と Cxxx7Dlg と CTest7Dlg といろいろあってどれが本当?
Dialog は何種類あるわけ?
SendMessage する相手先の this + HWND はきっちり存在しているわけ?
不正確な質問したら不正確な答えが返ってくるだけ。
俺はもうパスね。
結局のところ関数の型が違います。
ON_MESSAGEに割り当てる関数の型は
afx_msg LRESULT (CWnd::*)(WPARAM, LPARAM)
です。型が違えば引数や戻り値の情報の関係上メモリがおかしくなるというわけです。
http://msdn.microsoft.com/ja-jp/library/k35k2bfs(VS.80).aspx
> ・On_MyMessage の関数の宣言が間違ってます。ってこれはコンパイルエラーにならな
> いんでしたっけ?
> 結局のところ関数の型が違います。
VC 6.0 は、LRESULTを返さなくても、「afx_msg void xx()」と定義すれば
エラーにもならないし、動いてしまいます。
正式な型じゃないと動かなくなったのは、「.net」からじゃないかな?
少なくとも.net 2003はエラーになります。
皆さんに指摘してもらったのですから、正式の型も覚えておいたほうがいいですね。
tetrapodさんの意見にもあるとおり、
・CxxxDlg.cpp から CxxxDlg.cppへ送るのか?
・起動時に最初に有効になるダイアログは?
これが分からないとだめですね。
あと、
>this->SendMessage(WM_MYMESSAGE);
は
GetParent()->SendMessage(WM_MYMESSAGE);
に変えてみましょう。
> VC 6.0 は、LRESULTを返さなくても、「afx_msg void xx()」と定義すれば
>エラーにもならないし、動いてしまいます。
> 正式な型じゃないと動かなくなったのは、「.net」からじゃないかな?
>少なくとも.net 2003はエラーになります。
以前同じ内容で悩みましたが・・
VC 6.0でもDebug版は動きますが、Release版では駄目でした。
#戻り値は大丈夫ですが、引数は駄目だったはず。
> 引数は駄目だったはず。
そりゃそーだ、スタックぐずぐずになっちまう。
Debug版で動くのが不思議なくらい。
>#戻り値は大丈夫ですが、引数は駄目だったはず。
すみません、そうでした。
afx_msg void On_MyMessage(UINT wParam, LONG lParam)
が正解ですね。
どうも失礼しました。
>正解ですね。
正解ですか。。。?
(単にうごくようにしただけなきも。
引数もsizeof(UINT)==sizeof(WPARAM),sizeof(LONG)==sizeof(LPARAM)でないとまずそう)
実際に使う時に無理やりキャストされているのかどうか知らないけど、
戻り値はどうなるのですかね?
>afx_msg void On_MyMessage();
↓
afx_msg LRESULT On_MyMessage(WPARAM, LPARAM)
>void Cxxx7Dlg::On_MyMessage()
>{
> AfxMessageBox(Hellow);
>}
LRESULT Cxxx7Dlg::On_MyMessage(WPARAM, LPARAM)
{
AfxMessageBox(Hellow);
return 0L;
}
>#戻り値は大丈夫ですが、引数は駄目だったはず。
これはRelease版で動作するかどうかについてです。
記述、動作共に正しいのはBlueさん指摘の通り以下のようになります
afx_msg LRESULT On_MyMessage(WPARAM wPalam, LPARAM lParam );
Blueさん他、みなさんありがとうございました。
会社から書き込みができず、ご返答が送れてしまいました。
Bulueさんご指摘のように、
afx_msg LRESULT On_MyMessage(WPARAM wPalam, LPARAM lParam );
とすることで正しく動作しました。
ありがとうございます。
>tetrapod様
>というより CxxxDlg と Cxxx7Dlg と CTest7Dlg といろいろあってどれが本当?
>Dialog は何種類あるわけ?
申し訳ありません。記載みすです。
CxxxDlg、Cxxx7Dlg、CTest7Dlgはすべて同一ダイアログです。
ダイアログはひとつです。
以上ありがとうございました。