フォームビューで、検索置換ダイアログで、コールバック関数を呼び出すには

解決


ごま  2008-06-27 15:15:14  No: 68615

.NET2005 MFC です。

検索置換ダイアログを使いたく、手もとの参考書を頼りにコーディングしたのですが、フォームビューでコールバック関数を呼び出すことができません。
(ダイアログベースでは呼び出せます)

ソースファイルでは、

LONG C***View::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
     return 1L;
}
をタイプし、

static UINT WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING); 
を宣言し、

BEGIN_MESSAGE_MAPの中に、

WN_REGISTERED_MESSAGE(WM_FINDREPLACE, OnFindReplace)

を置きました。

ヘッダファイルでは、
DECLARE_MESSAGE_MAP()の下に

afx_msg LONG OnFindReplace(WPARAM wParam, LPARAM lParam);

を置きました。

ダイアログベースでは、これでOnFindReplaceが呼び出されるのですが、
フォームビューでは、ブレークポイントを置いてみても、素通りです。

アドバイスをお願いします。


επιστημη  URL  2008-06-27 20:13:14  No: 68616

Viewじゃなく、もいっこ上のMainFrameが受けたらどうなります?


ごま  2008-06-28 14:30:32  No: 68617

επιστημηさん、ありがとうございました。
解決しました。

関連して、2点、アドバイスを頂けませんでしょうか。

1.
上記のコードで、
LONG C***View::OnFindReplace(WPARAM wParam, LPARAM lParam)
の中で、戻り値が「1L」となっています。
この「1L」は、どこでも定義していませんし、いったい何なのでしょうか。

2.
OnFindReplace(WPARAM wParam, LPARAM lParam)の中のコードが長いので、C***Viewの中に、「関数の追加」で
LONG C***View::OnFindReplace(WPARAM wParam, LPARAM lParam)
をつくり、CMainFrame側の
LONG CMainFrame::OnFindReplace(WPARAM wParam, LPARAM lParam)
から、ポインタで呼び出すようにしようかと思いました。

LONG CMainFrame::OnFindReplace(WPARAM wParam, LPARAM lParam)
自体がコールバック関数だと思うのですが、このような書き方は「あり」なのでしょうか。
「そんなことは、どちらでも自分の好きなようにしろ」と言われそうですが、どちらがモアベターなのでしょうか。

初心者まるだしで、お恥ずかしいのですが、アドバイスをお願いいたします。


ごま  2008-06-28 14:44:26  No: 68618

申し訳ありません。

「1L」は分かりました。
LONG型の 1 ということですね。

ただ、2.については以前から、どちらにするか迷うことがあり、アドバイスを頂けませんでしょうか。


επιστημη  URL  2008-06-28 15:51:20  No: 68619

2.僕ならおそらく、Frameから(Viewではなく)Documentのメンバを呼び出します。


επιστημη  URL  2008-06-28 16:15:23  No: 68620

2.僕ならおそらく、Frameから(Viewではなく)Documentのメンバを呼び出します。


ごま  2008-06-28 16:29:34  No: 68621

επιστημηさん、ありがとうございます。

> Frameから(Viewではなく)Documentのメンバを呼び出します。

初心者で、ピントがずれた問いかもしれませんが、その場合、検索や置換えのコード自体をDocumentクラスに置くということはないと思うのですが、どのような構成になるのでしょうか。

また、Viewクラスにせよ、Documentクラスにせよ、「関数の追加」で、関数を追加しようとした場合、.NET2005 では、型を「LONG型」とタイプしても、「long型」になってしまいました。

LONG CMainFrame::OnFindReplace(WPARAM wParam, LPARAM lParam)
から呼び出す場合、呼び出される関数は、「long型」でかまわないのでしょうか。

それとも、
LONG C***View::OnFindReplace(WPARAM wParam, LPARAM lParam)
または、
LONG C***Doc::OnFindReplace(WPARAM wParam, LPARAM lParam)
と、すべて手でタイプしたほうがいいのでしょうか。

申し訳ありませんが、アドバイスをお願いします。


επιστημη  URL  2008-06-28 16:36:57  No: 68622

>> Frameから(Viewではなく)Documentのメンバを呼び出します。
> 検索や置換えのコード自体をDocumentクラスに置くということはないと思うのですが、どのような構成になるのでしょうか。

DocumentからUpdateAllViewsすればView::OnUpdateが呼ばれます。
そこで検索なり置換なり。

>「関数の追加」で、関数を追加しようとした場合、.NET2005 では、型を「LONG型」とタイプしても、「long型」になってしまいました。

ごめんなさい、「関数の追加」を使ったことないのでわかりません。


rin  2008-06-29 08:06:22  No: 68623

少し話が前後してしまうのですが

検索ダイアログを作成したときに設定したオーナーウィンドウに対し
コールバック関数の呼び出しがされるのだから
CFormViewを、オーナーにして検索ダイアログを出すようにする
という手はどうでしょうか?

>LONG CMainFrame::OnFindReplace(WPARAM wParam, LPARAM lParam)
>から呼び出す場合、呼び出される関数は、「long型」でかまわないのでしょうか。
構わない。
ソース上の「LONG」にカーソルを合わせ、右クリック。
メニューにでてくる「定義へ移動」を選ぶと、どうして構わないか解るはず

それ以前に、「コールバック関数の中から呼び出す別の関数」は、
コールバック関数の型になっている必要はありません。
#ダイアログで試したとき
#文字列操作の関数などを呼び出したりしてないでしょうか?


ごま  2008-06-29 14:12:02  No: 68624

επιστημηさん、rinさん、ありがとうございます。

結局、シンプルに、CMainFrameから、C***Viewに置いた関数を呼び出すことにしました。

CFormViewをオーナーにすると、検索置換ダイアログのボタンを押しても、メッセージIDを受け取ることができません。
それがそもそもの発端でした。
なにか方法がありますでしょうか。


rin  2008-07-01 21:34:03  No: 68625

試してみましたが
CFormViewのハンドルをちゃんと渡していれば、CFormViewにメッセージは飛んできます
特別な関数やら特殊な手法は一切やらずにできます(それゆえ「コツ」みたいなものを提示できないです)

今回、επιστημηさんのアドバイスで
CFormViewからCMainFrameに、メッセージの受取先を変更したようですが
その修正前は、どこでどのように検索ダイアログのオーナーを
CFormViewに設定してたのでしょうか?
#検索ダイアログの出し方や、FINDREPLACEの設定など


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加