MFCを使わずにユーザー定義メッセージを取得する方法をお教え頂けませんか?
①作成の手順はC++(MFCでない)自作クラスを作成しMFCプロジェクト内で使用します。
②送信側はSendMessageやPostMessageにより呼び出します。(ウィンドウハンドル指定)
補足:MFCを使ってユーザー定義メッセージを受取る方法は以下になります。
http://oissu2.blog77.fc2.com/blog-entry-18.html
この場合、ウィンドウハンドルとメッセージマップが整備しているので簡単に作れます。
自作クラス(MFC無)の場合はどのようにするか分からない状況です。。
宜しくお願いします。
一番てっとり早いのは
CreateWindowでメッセージ取得関数による取得でしょうか?
これですと、わざわざウィンドウを作る事になるので、出来れば避けたいです。
MFCはWin32SDKのラッパーに過ぎません。全てのMFCの仕組みは
Win32SDKの関数の組み合わせで実装されています。
1.Win32SDKのSendMessage()、PostMessage()で送付されるメッセージは、
その第一引数であるHWNDを持つウインドウの実体の原型となったウインドウクラスが所
有する
コールバック関数がが受け取ります。これ以外の方法はありません。
MFCはこの仕組みをラップしているだけです。
2.CWndの派生クラスを使わなくてもWin32SDKでウインドウを作成できます。
RegisterClassEx()、CreateWindow()関数を参照してみてください。
3.ウインドウ以外ではスレッドがメッセージを受け取ることができます。
PostThreadMessage()を参照してみてください。ただし受け取る側のスレッドにも
コールバックが必要になります。
さて、具体的な目的が明らかにされない質問に対する回答では、
上記のようなわりと具体的でない回答になってしまいます。
より鮮明な解決方法を望む場合は、やりたいことを具体的に書いた方が良いでしょう。
以下は質問に対する質問になってしまいますが、事情が許するならば答えてみてはどうで
しょう。
A.なぜメッセージを送付する必要があったのでしょうか。
B.メッセージ以外で実装する方法はありませんでしたか。
C.そもそもどういう仕組みを実現しようとしてますか。
momさん、仲澤さん
前回のスレの続きだとすると、
1.アプリケーションからDLLにメッセージを送りたい。
2.DLLをMFC拡張DLLにしたくない。
3.2のことからW32SDKのみでDLLを作りたい。
ということですか?
追記です。
VS2013でW32SDKのみでDLL作成できます。
猫でもわかるプログラミング WINDOWS SDK編
でDLLの作り方も載っています。
参考にしてみたらどうですか。
ご連絡有難うございます。
今は方法を探しているので、抽象的なお話が出来ていて助かってます。
そもそも、以下の質問でコールバック関数を実現したい事から始まりました。
http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vclng.cgi?print+201507/15070001.txt
しかし、上記内容は現実的に難しいため、MFC使わないを使わない独自C++クラス
にメッセージ取得を行えればと考えていた次第です。
CreateWindowをするまでの事ではないと考えてました。
>3.ウインドウ以外ではスレッドがメッセージを受け取ることができます。
> PostThreadMessage()を参照してみてください。ただし受け取る側のスレッドにも
> コールバックが必要になります。
PostMessage,SendMessageなどは送信側になりますよね?
PostThreadMessage()も通知するための送信メソッドになるのではないでしょうか?
今は受け取る側の仕組みをどうすれば良いか悩んでます。
ITOさん、ご連絡ありがとうございます。
1.アプリケーションからDLLにメッセージを送りたい。
→DLLからアプリケーションにメッセージを送りたいです。
2.DLLをMFC拡張DLLにしたくない。
3.2のことからW32SDKのみでDLLを作りたい。
→DLLはC# COM DLLで行いたいです。
→アプリケーションはMFCになります。
以上、宜しくお願い致します。
まず、アプリケーションが主ウインドウを持っているなら、
そのHWNDに対してPostMessage()するだけです。
それで話はおわりです。
そうでない場合はスレッドを作成してそのスレッドハンドルを
DLLに渡してPostThreadMessage()してもらうしかありません。
メッセージを取得する関数はいくつもあって、目的により
使用するものが異なります。GetMessage() WaitMessage()
等を調べてみてはどうでしょう。
そのどちらも持たないクラスに直接メッセージを
送付する方法が無いことは既に述べたとおりです。
いずれにしても、このあたりをやろうと思ったら、Win32SDKで、
サクッとウインドウが表示できる程度の知識が必要です。
そうでないと、話がかみあわないでしょう。
簡単な解決方法を知りたい場合は、実現したいことの
詳細を説明するしか手段はありません。
補足:(このあたりも調べましょう)
MFC拡張DLLと、内部でMFCのクラスをを使っているだけのDLLとは、
まったく異なるものです。現在MFC拡張DLLは非推奨で現実的には
使ってはいけない状態です。
C++と.NET間のコールバックは可能なので、元の記事に回答しました。
仲澤@失業者さん
色々とアドバイス有難うございます。
ハンドルに対してメッセージを送信する方法は十分理解出来ました。
>メッセージを取得する関数はいくつもあって、目的により
>使用するものが異なります。GetMessage() WaitMessage()
>等を調べてみてはどうでしょう。
メッセージを取得する方法は例えば_beginthreadexメソッドでスレッドを作った場合
この関数で指定したコールバック関数内でGetMessage() WaitMessage()を使い
メッセージを拾うという事ですか??
YESの場合、非常にクリアになりました^^
>MFC拡張DLLと、内部でMFCのクラスをを使っているだけのDLL
この区別がつきません。DLL側のプロジェクト設定では
「MFC指定」 or「MFCなし」しか行えないのではないでしょうか?
うーーん、
DLLをC#で作らなければいけない理由がわかりませんね。
いっそうDLLでなくCOM / DCOMアプリとして作るていう手もありますよね。
ただ、COMインタフェースを使うことになるので動作が遅くなると思いますね。
昔エクセルをCOMインタフェースしているソフトを見ましたが、そんなに違和感なかった
です。
c#なら作りやすいのではないでしょうか?
メッセージを受け取るには、対象のスレッド内で無限ループを作り、
その中でGetMessage()するのが普通です。
HWNDがある場合の例を以下に示します。
// このコードは一般にメッセージループと言われます。
// このコードの前で実行モジュールのインスタンスハンドルに対して
// ウインドウクラス登録を行い、かつウインドウを作っておく必要があります
MSG msg;
int res;
while(1){
res = DWORD(::GetMessage( &msg,NULL,0,0)));
if( BOOL(res)==FALSE) break; // ==WM_QUITなら脱出
if( res==-1) break; // errなら脱出
::TranslateMessage( &msg);//キーメッセージの変換
::DispatchMessage( &msg);//メッセージを自身のメインHWNDのコールバックに転送
}
・一般にMFC拡張のDLLとはMFC自体を変更してそれを提供する方法です。
・DLLの中でたとえばCWndを使ってもMFCLを
ダイナミックにリンクしている場合は上にあたりません。
追記、
>この区別がつきません。
僕が質問した、
>2.DLLをMFC拡張DLLにしたくない。
です。
MFC拡張DLLとは、
おおざっぱにいうと、普通はDLL内でメッセージループを作るのはかなり難しいです。
それを、MFCのDLLをリンクさせてメッセージループを実現させているDLL
ということになりますね。
本来、DLLをは一般的なLIBを拡張させたものです。
しくみはLIBとほぼ同一でなければならないと僕は思います。
まぁー、MFC拡張DLLはそれにUIの機能を付けたのだから、
仲澤さんの言う、
>現在MFC拡張DLLは非推奨で現実的には使ってはいけない状態です。
これもわかりますね。
ITOさん
>DLLをC#で作らなければいけない理由がわかりませんね。
>いっそうDLLでなくCOM / DCOMアプリとして作るていう手もありますよね。
C#をDLLで作るのは単に仕様なだけです。
個人的には今回アドバイス頂いた様に、面倒なので作りたくありませんでした。。苦笑
DCOMとはまた新たな発想ですね。
>C#なら作りやすいのではないでしょうか?
一応動作確認としてC#アプリでの実装、動作確認はしました。
既に終わっており問題はありませんでした。
仲澤@失業者さん
メッセージ取得メソッドまでのご説明有難うございます。
この手の方法は何度も行っているので、大丈夫そうです。
>・一般にMFC拡張のDLLとはMFC自体を変更してそれを提供する方法です。
なんと、MFC自体を改良するという事ですか。
ここまでは私の中では想定外の改修内容と考えてました。
ひとまず解決出来ました^^
解決内容:作成したスレッドのハンドルをDLLへ渡し、DLLから設定されたハンドルへ
PostThreadMessageメソッドを送る。スレッド側ではGetMessageによるメッセージループ
を行い、通知を受ける。
色々と有難うございました。
それにしてもMFC拡張DLL、これは普通行うのでしょうか?
Microsoftから提供されたMFCを改良するのですよね・・・・?