ウィンドウメッセージ

[戻る]
竹氏 2005/03/30(水) 22:47:21
こんにちは。
いつも勉強させてもらっています。

開発環境
WindowsXP、VisualC++6.0、ダイアログベース

アプリケーション同士のメッセージの通信を行いたいです。
文字列の送受信を行います。
送信側と受信側は別のアプリケーションです。
下記のコードは正しく動作します。

////////////////////////////////////////////////////////////
送信クライアント側
cWnd->SendMessage(WM_COPYDATA, (WPARAM)m_hWnd, (LPARAM)&cds);

受信サーバ側
OnCopyDataに書いてあること

pWnd->GetWindowText(bu1, sizeof(bu1));
sprintf(buf, "%s", pCopyDataStruct->lpData);
MessageBox(buf);
////////////////////////////////////////////////////////////

で、下記のコードが動作しません。
送信側
cWnd->PostMessage(WM_COPYDATA, (WPARAM)m_hWnd, (LPARAM)&cds);

受信側
OnTimerにかいてあります。1000msec位のインターバル
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)){
  if (!GetMessage(&msg, NULL, 0, 0)){
    return;
  }
  TranslateMessage(&msg);
  DispatchMessage(&msg);

  if (msg.message == WM_COPYDATA){
    MessageBox("asfdasfas");  //正しく受信できたらここに飛ぶはず?
  }
}

どこか悪いところがありますでしょうか?
ご教授ください。

竹氏 2005/03/30(水) 23:16:24
すいません。
追加です。
パイプ、ソケット(Winsock)は使用したくありません。

受信したデータはmsgに入っていると考えてよいのでしょうか?

シャノン 2005/03/30(水) 23:50:10
PostMessage じゃダメで、必ず SendMessage を使わなければならなかったような気がし
ますが、WM_COPYDATA のヘルプには、そんなことは書いてありませんでした。

Ban 2005/03/31(木) 00:30:44
同種の制限が載ってたはずだと思って調べましたが、ずばりのものは CE の方のみに
書いてありました。

<MSDN>
An application must use the SendMessage function to send this message,
not the PostMessage function. 
</MSDN>

CE 以外でも原則は SendMessage のようですが、多少制限はゆるくなっているらしく、
一定の制限を満たせば Post でもいけるように読めます。

see にも PostMessage はないですし、記述はいずれも send ですがダメとは書いてない
。
 <MSDN>
    An application sends the WM_COPYDATA message to pass data to another
    application. 
      -- snip --
    To send this message, call the SendMessage function as follows. 
 </MSDN>


ということで、提示コードでは使っているバッファ領域がこの辺りの条件を
満たしていないのではないでしょうか。
 <MSDN>
    While this message is being sent, the referenced data must not be changed
    by another thread of the sending process. 
 </MSDN>

くまさん 2005/03/31(木) 09:23:18
VC++.net2002のヘルプには、

An application sends the WM_COPYDATA message to pass data to another application. 

To send this message, call the SendMessage function with the following
parameters (do not call the PostMessage function). 

とありました。

Ban 2005/03/31(木) 10:20:51
> To send this message, call the SendMessage function with the following
> parameters (do not call the PostMessage function). 

手元の MSDN (2001/10) を見たら確かにそう書いてありました。(ご指摘を受けて別の MSDN を確認)

今バージョンが分からない/確認できないのですが、自宅の新しい奴ではその文言が
見当たらなかった気が....。(仕様変更で制限が緩くなっているのでしょうか)

> WindowsXP、VisualC++6.0、ダイアログベース

PlatformSDK のバージョンアップなどにも依存しそうですが、
SendMessage にしておく方が無難かと思います。

シャノン 2005/03/31(木) 20:31:46
SendMessage ならば、SendMessage を呼んでから戻るまでの間に、受信側でメッセージ
が同期的に処理されることが保障されますから、SendMessage を呼んでいる関数の中で
宣言したローカル変数も、受信側が処理している間は存在しています。
PostMessage だと非同期に処理されるため、受信側がキューからメッセージを取り出し
た時には、既に送信側は関数を抜けて、ローカル変数が解体されている可能性がありま
す。
逆に言えば、PostMessage でも、受信側がメッセージを処理するときに、まだ 
COPYDATASTRUCT::lpData が指しているデータが生きていればいいわけですね。

…たぶんね。

Ban 2005/03/31(木) 22:05:34
> …たぶんね。

たぶん、ですね。

# .NET2003 の MSDN には、やっぱり Post〜ダメって書いてなかったです。仕変かな。

竹氏 2005/03/31(木) 22:51:14
シャノンさん、Banさん、くまさんさん?
どうもありがとうございます。

ご指摘を受けて無難そうなSendMessageで行くことになりました。
実際に解決はしていないのですが、解決にしてしまってよろしいでしょうか?

アドバイスありがとうございました。

古いスレッドには追加発言できません。