質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

12700閲覧

[C++(MFC)]メッセージを受信出来るときと出来ないときの違い

moredeep

総合スコア1507

MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

3クリップ

投稿2017/06/11 01:04

編集2017/06/16 00:09

###前提・実現したいこと
仕事で、MFCを使うことが度々ありますが、毎回といっていいほど、メッセージが受信できずに困ることがあります。
いつもは対処療法のように、色々なところを少しずつ変更し、メッセージが受信できたらOKとしていますが、毎回毎回時間がかかりすぎています。

OnCreateのタイミングをずらした(必要なとき→親のOnCreate直後に変更した)ら出来るようになった等、原因がまったくわからないがとりあえず出来た、が多いので、ちゃんとした原因が知りたいです。

こういった、メッセージ自体が飛ばない問題の、予防的な解決方法をご存知の方、また、そういった情報が載っているサイトをご存知の方いらっしゃいましたら、教えていただけませんでしょうか。
調べると、たいてい解決方法は見つかりますが、見つけて試すより、はじめから問題がないものを作りたいです。

###発生している問題・エラーメッセージ
メッセージが受信できない場合がある。

以下最近起きて、解決していない問題
例1:OnPaintがこない
MFC ActiveXオブジェクトを、以下の親子関係で作成し、ダイアログに貼り付ける
COleControl->CFrameWnd(COleControlはCFrameWndを表示するだけ)
→テスト用プロジェクトのダイアログに貼り付けたとき、OnPaintが受信できなかった
→テスト用プロジェクトをコピーし、ダイアログに貼り付けたとき、OnPaintが受信できた
→両者の違いは、何処からも呼ばれていない関数を削除したかどうかのみ
→Send(or Post)Message(WM_PAINT)を実行時は、OnPaintが呼ばれる

例2:OnTimerがこない
COleControlのOnDraw関数にてSetTimer(1, 50, NULL)を実行(戻り値は1)
→OnTimerが呼ばれない
→他のActiveXオブジェクトで上記と同じことをしているものは、OnTimerが実行されている
→Send(or Post)Message(WM_TIMER)を実行時は、OnTimerが呼ばれる


上記例1は一応の解決、例2はきちんと解決したので載せておきます。
例1:OnPaintがこない
→問題のあるプロジェクトをコピーし、コードには修正を加えずに実行すると、何度試してもうまくいくため、プロジェクトに問題があると判断

例2:OnTimerがこない
COleControlの子ウィンドウにOnPaintを設定しているが、そこで親クラスのOnPaintを呼ぶようになっていなかった
→子ウィンドウ側のクラスのOnPaintに、"__super::OnPaint()"を追記することで解決できた

やはり一口にメッセージが来ないといっても、様々な原因があります。
予防的な解決方法だけでなく、問題が起きた時の原因特定のヒントになりうるもの等も、教えていただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

MFCに関する情報提供のみですが。

MFCは古い技術なので、現在はネット上での情報は少ないです。
前世紀までは、Tipsなどをまとめた個人サイトもまだたくさんあったはずですが、今はほとんど残っていないようです。
WikipediaのMFCで挙げられている外部サイトもほとんどリンク切れになっていますね。

ということで、現時点では以下くらいでしょうか?

まずは以下のMSDNを1次情報として挙げます。テクニカルノートやサンプルが有用だと思います。

MFCの記事が載っている可能性があります。ただ、最古で2003年からと、すでにMFCの話題は少ないと思いますが。

MFCに関する過去記事やサンプルもまだ残っています。

この2つはMFCに関する過去ログが豊富です。

また、以下の定番の書籍をあたるのもよいでしょう。

どちらも絶版ですが、図書館にはおいている可能性はあります。

プログラミング情報誌C MAGAZINEにも時々MFCの記事や連載が載っていました。
すでに廃刊してますが、Kindle版が購入できるようです。
月刊C MAGAZINE 1998年12月号
MFC教養講座 Skill UP! MFCという連載が載っていますね。

以上、今回あらためてMFCの情報を探してみたのですが、どんどんネット上から消えていっているのに驚きました。

補足:MFCは今年で25才。まだまだ現役のようです。
デスクトップ開発に欠かせないMFCがデビューから25周年を迎える
Happy 25th Birthday MFC!

投稿2017/06/23 07:54

編集2017/06/23 08:15
can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

PineMatsu

2017/06/23 08:03

VS2012だったかな、MFCのマルチバイト用のライブラリが別途ダウンロードしてインストールしないといけない事になっていて「え?」と思いました。しかもスタティックリンクするとかなりサイズがでかくなる。 VS2015から、ライブラリは復活しましたが。 新規アプリでMFCを使おうとは思いません。たぶんC#とかを選択するでしょうね。まあ、MFCはそのうち消え行く運命かもしれませんね。
can110

2017/06/23 08:18

2005~2010くらいかな? MFC(VC)ランタイムがside-by-side展開になって面倒になったり色々ありましたねぇ ただ開発チームによると「まだだ!まだ終わらんよ!」だそうですw
PineMatsu

2017/06/23 08:26

そうなんだ、まだまだ意気盛んですね。しかし25周年ですか。個人的には余り好きじゃないですが、思い入れが強い人達が未だ残ってるんですね。それならもっと軽量にして欲しいですね。 新規アプリでC++というなら、Win32++の様な軽量のライブラリを使いますね。MFCライクなクラス構成なので、MFCを知っている人には使いやすい。ただ、OLEとかってなるとちょっとつらいですけど。
can110

2017/06/23 08:52

私にとっては長く付き合ってきましたし、これでご飯も食べてこれたので愛憎相半ばといったところでしょうか?慣れの部分も大きいですが、あまり凝らなければそれなりに手早く作れて使いやすいとは思います。ちょっと複雑な処理をしようとすると、色々と苦労もありましたが。 Win32++やWTLも気になってる(た)のですが、結局、慣れたMFCでいいや、で今に至りますね。
moredeep

2017/06/26 23:55 編集

返事が遅くなり、申し訳ありません。 情報、ありがとうございます。 VC++ ラウンジやmfc-ml等はよく見ていたのですが、codeguruは見たことすらなかったです。 どんどん情報が消えて行ってしまう中、これだけの情報源を頂けて、ありがたく思います。 これからは頂いた情報源のなかからも、情報を探して、知識を蓄積していこうと思います。
guest

0

MFCではメッセージマップのマクロを使って処理を書いていると思うのですが、実際にはどのようにされているのでしょうか?

ウィンドウ メッセージ (MFC)

投稿2017/06/20 08:20

PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moredeep

2017/06/26 23:38

ご回答ありがとうございます。 返事が遅くなり、申し訳ありません。 ヘッダにて、 protected: // Message maps DECLARE_MESSAGE_MAP() afx_msg void OnPaint(); afx_msg void OnTimer(UINT_PTR nIDEvent); とし、 BEGIN_MESSAGE_MAP(ClassName, ParentClassName) ON_WM_PAINT() ON_WM_TIMER() END_MESSAGE_MAP() としています。(他にもメッセージは受け取っていますが割愛) なお、他のメッセージは正しく受け取れること、正常に動作する別クラスからのコピーであることから、ここはあまり疑っていません。
guest

0

COleControlのウィンドウ生成のタイミングに問題がありそうです。
ウィンドウ生成が行われていない時点では、メッセージハンドラは呼ばれませんので。

これのタイミングは、OCXの属性として「表示時にアクティブ」にしているとか。
その他の属性の絡みや、コンテナ側の表示やにアクティベイトのタイミングと絡んできます。
そのあたりを見直した方が良いと思います。

OnSetClientSite()ハンドラで、以下のようなコードを入れとくのも、いいかもしれません。

C++

1 if (AmbientUserMode()) { 2 if (m_hWnd == 0) { 3 RecreateControlWindow(); 4 } 5 } 6

投稿2017/06/12 00:42

Harahira

総合スコア243

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

moredeep

2017/06/13 00:59

ご回答ありがとうございます。 ウィンドウ生成が行われていない時点では、メッセージハンドラは呼ばれない、ということは、例2のことをおっしゃっているのでしょうか。 こちら、ウィンドウの生成が完了した後、ボタンのクリックイベント等でSetTimerを呼んでも、OnTimerは呼ばれません。 OnSetClientSite()も試させて頂きましたが、動かないようです。 一応、OnTimerが呼ばれない原因として、メッセージのキューがいっぱいになっている可能性があるので、現在はそちらで調べています。 ただ、OnTimerは動かないなら動かないで他のやり方ができるので、調査の優先度が低く、あまり調査は進んでいない状況です。 また、OCXの属性、ActiveXコントロールを張り付けるダイアログ等は全て同一で、COleControl内の処理のみが異なる、別のActiveXプロジェクトでは、上記の問題は起きません。 (OnPaintも、OnTimerも) よって、例に挙げている問題は、処理の順番やタイミングがおかしいのだと思います。
Harahira

2017/06/16 02:44

実際、提示された情報だけでは何が起きているかは正確にはわかりません。 Windowsメッセージが受信出来ないような事態は、通常は起きません。 また、メッセージキューが一杯になるような事態も、通常は起きません。 もし、そうであるならばWindowsアプリケーションとしての作りに問題があると思われます。 従って、「予防的な解決方法」や、「はじめから問題がないものを作りたい」場合は、Windowsプログラミングについて、より深く勉強して頂くのが適当と思います。
moredeep

2017/06/19 00:55

>Windowsプログラミングについて、より深く勉強して頂くのが適当と思います。 その必要があるのは重々承知しています。 MFCについては、メッセージループの処理だったり、ウィンドウの作成過程等の基本的な部分は概ね理解できています。 ですが、私が求めている細かいメッセージ毎の仕様等の情報は、MSDNだったり、スタックオーバーフローだったりに、分散して載っている情報を纏めて、はじめて理解出来るものばかりです。 何ページも見比べて、内容を照らし合わせ、理解していくのはあまりに非効率です。 MFCであれば、先達がいくらでもいらっしゃいますので、どこかに情報を纏めてあったり、色々とご存知の方がいらっしゃるかと思い、質問させていただいております。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問