WM_COPYDATAを用いたプロセス間通信について – プログラミング – Home

WM_COPYDATAを用いたプロセス...
 
通知
すべてクリア

[解決済] WM_COPYDATAを用いたプロセス間通信について


PON
 PON
(@PON)
ゲスト
結合: 18年前
投稿: 21
Topic starter  

[環境]WinXP Pro / Visual Stdio 2005 VC++

VC++初心者のものです。
過去ログを拝見したのですがうまくいかないので、申し訳ありませんが、
質問させてください。。。

[やりたいこと]
・ダイアログベースで作成した2つのexe間で、SendMessageと
 WM_COPYDATAを用いたプロセス間通信

[現在までにしたこと]
●1. VS2005で新規ソリューション(ダイアログベース)を2つ
(送信側mes_send・受信側mes_recv)作成

●2. 送信側mes_sendにはボタンを1つ追加し、そのボタンを押すと、
 以下のSendMessageのコードが走るようにする。

void Cmes_sendDlg::OnBnClickedButton1()
{
HWND recv_wind;

recv_wind = ::FindWindow(NULL, (LPCTSTR)_T(mes_recv));

::SendMessage( recv_wind, WM_COPYDATA, 0, 0 );

}

●3. 受信側mes_recvには、Cmes_recvDlgに、WM_COPYDATAのハンドラを追加。
ハンドラ内には、確認用のAfxMessageBoxのみいれておく。

BOOL Cmes_recvDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
AfxMessageBox(_T(Message Recieve));
return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

●4. 両方の起動をかけて、送信側mes_sendのボタンを押すが、受信側mes_recv
 はまったく反応せず。

[デバッグ状況]
■送信側mes_sendのrecv_windの値は、spy++で確認した受信側mes_recvの
 ウィンドウ番号が入っている。
 -- ウィンドウ 00030D6C 'mes_recv'#32770(ダイアログ)
■受信側mes_recvのAfxMessageBoxでブレークを張って、送信側mes_sendの
 ボタンを押しても、ブレークにひっかからない。

状況は以上です。
なお余談ですが、ダイアログベースではなくシングルドキュメントだと、
findWindowすら動作しません。。。
どなたか、お分かりの方、ご返信よろしくお願いします。

 


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

SendMessage時、WPARAM,LPARAMを(0ではない)ちゃんとした値を設定してもダメですか?


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

確認ですが、OnCopyDataはどうやって追加されましたか。
直接、何かからのコピペですか。MESSAGE_MAPには正しく追加されていますか。


返信引用
PON
 PON
(@PON)
ゲスト
結合: 18年前
投稿: 21
Topic starter  

επιστημηさん
Banさん

ご返信ありがとうございます!

>Banさん
いえ、コピペではなく、プロパティからハンドラ追加を行いました。
MESSAGE_MAPにも登録されています。

>επιστημηさん

改めてきちんとデータを入れると、うまくいきました!!

void Cmes_sendDlg::OnBnClickedButton1()
{
  HWND recv_wind1,recv_wind2;
WPARAM wParam;
LPARAM lParam;
COPYDATASTRUCT cds;

CHAR lpszData[] = This is TEST.;

cds.dwData = 1;
cds.cbData = sizeof(lpszData);
cds.lpData = (LPVOID)lpszData;

recv_wind1 = ::FindWindow(NULL, (LPCTSTR)_T(mes_send));
recv_wind2 = ::FindWindow(NULL, (LPCTSTR)_T(mes_recv));

wParam = (WPARAM)recv_wind1; //送信側のウィンドウハンドラ
lParam = (LPARAM)&cds; //送信するデータ

::SendMessage( recv_wind2, WM_COPYDATA, wParam, lParam );
}

としてみたら、うまく動作しました。その後の追試の結果、

***************************************************
●第3引数は0でも動作するが、
 第4引数に、必ず何かデータを入れないと、動作しない
***************************************************

としなければ動作しないようです(間違ってるかもしれませんが、、、)
「送るデータが無くてもメッセージは届くだろ」と
安直に考えていた自分のミスです。。。。orz

どうもありがとうございました!!


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> wParam = (WPARAM)recv_wind1; //送信側のウィンドウハンドラ
は自分自身なら、this->GetSafeHwnd(); でウィンドウハンドルが取れます。

私も試しにやってみたんですが、mes_recv側に実験用にボタンを作って、

this->SendMessage( WM_COPYDATA, 0L, 0L );

と記述して、きちんとOnCopyDataが呼ばれていたので、LPARAMは関係ないのかなぁと
思っていました。WM_COPYDATAのヘルプを再度確認してみなければならなそうです。

ところで
> ダイアログベースではなくシングルドキュメントだと、findWindowすら動作しませ
ん。。。
こちらはその後どうなりましたか?


返信引用
PON
 PON
(@PON)
ゲスト
結合: 18年前
投稿: 21
Topic starter  

>Blueさん
どうも追試ありがとうございます!!

this->GetSafeHwnd();
ってのを使えば、自分のウィンドウハンドル取得できるんですね、、、
でもLPARAM、、、いまいちまだつかめません。。。

> ダイアログベースではなくシングルドキュメントだと、
> findWindowすら動作しません。。。

この件ですが、午後にいろいろ試しまして、少しわかりました。

[ダイアログベースでやった場合]

Spy++で

-- ウィンドウ 00030D6C 'mes_recv'#32770(ダイアログ)

のように表示されたので、findWindowの引数をmes_recvにしていました。
つまり、「なーんだ、ファイル名でウィンドウを探せばいいのか」と
そのときは考えました。

で、

[シングル(SDI)でmes_recvを作った場合]

同じようにSpy++でみると、

-- ウィンドウ 00040A2E '無題 - mes_recv' Afx00400000b:b:00010013:00(以下略)

のように表示されていました。ダイアログのときと違ってわけのわかんない
数字がいっぱいあったのでびっくりしましたが、「きっとダイアログのときと
同じはず」と思い、

recv_wind = ::FindWindow(NULL, (LPCTSTR)_T(mes_recv));

と書いたのですが、どうやってもrecv_windに値が入らない。。。。

で、本日午後、結果的に、

●recv_wind = ::FindWindow(NULL, (LPCTSTR)_T(無題 - mes_recv));

という風に、ファイル名以外の部分も付け加えると、ウィンドウハンドルを
引くことができました。
ダイアログベースのときはファイル名でよかったのに、
SDIだとなんかわかんない名前をつけないと駄目なんでしょうか、、

以上、ご報告まで。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 23年前
投稿: 240
 

>SDIだとなんかわかんない名前をつけないと駄目なんでしょうか、、

ウインドウタイトルで検索しているのですからですね。
無題の部分は、開いているドキュメントのファイル名になっています。
(つまり、ファイルを開けば名前も変わります)

SDIでも(MFC正規の方法で)ウインドウタイトルを変更すればよいでしょう。

また、FindWindowを使わないで、ウィンドウハンドルを取得する方法もあります。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました