- - PR -
C# .Net SendMessageで他のアプリに文言を送信したい
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2005-07-25 12:05
はじめまして。Netなどで調べたのですが、解決方法が見つからないため、
こちらのお力を借りたいと思います。 いま、A.exeからB.exeへメッセージを送信することを考えています。 C++でしたら、 送信元(A.exe) HWND hWnd = 0; char msg[256]; strcpy(msg,"hello"); COPYDATASTRUCT cds; cds.dwData = 1; cds.cbData = strlen(msg) + 1; cds.lpData = (LPVOID)msg; hWnd = ::FindWindow(NULL,"B"); if(hWnd != 0){ ::SendMessage(hWnd,WM_COPYDATA, 0, (LPARAM)&cds); } 受信側(B.exe) WindowProc内 COPYDATASTRUCT *pdat = (COPYDATASTRUCT*)lParam; m_edit = (char*)pdat->lpData; で受信側で「hello」と受け取ることができます。 しかし、C#で記述に変換しようと試みたのですが・・・・ 送信元(A.exe) [DllImport("USER32.dll")] private static extern IntPtr SendMessage (IntPtr hWnd , int msg , IntPtr wp, IntPtr lp); struct COPYDATASTRUCT { public long dwData; public long cbData; public string lpData; } private void button1_Click(object sender, System.EventArgs e) { int hWnd = 0; COPYDATASTRUCT st = new COPYDATASTRUCT(); string msg = "hello"; st.dwData = 0; st.cbData = msg.Length+1; st.lpData = msg; hWnd = FindWindow(null,"B"); if(hWnd != 0) { IntPtr lparam; lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(st)); SendMessage((System.IntPtr)hWnd, 0x004A, this.Handle, lparam); } } 受信側(B.exe) struct COPYDATASTRUCT { public long dwData; public long cbData; public string lpData; } protected override void WndProc(ref Message m) { // Listen for operating system messages. if(m.Msg == 0x004A) { COPYDATASTRUCT st = new COPYDATASTRUCT(); st = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT)); textBox1.Text = st.lpData; } base.WndProc(ref m); } とすると、「U駆d。」こんな文字化けしたものが送信されてしまいます。 何か足りない処理や、間違った処理などがあるのでしょうか。 お知恵を貸して頂けませんでしょうか。 | ||||
|
投稿日時: 2005-07-25 12:19
Marshal.AllocCoTaskMem/AllocHGlobalは、文字通りメモリを確保するメソッドです。
勝手に構造体の中身をコピーしたりする機能はありません。 構造体インスタンスを確保したメモリ領域にコピーするにはMarshal.StructureToPtrメソッドを使用します。 またAllocした領域をFreeCoTaskMem/FreeHGlobalするのを忘れないで下さい。リークします。 追記: 実は、SendMessageの宣言を static extern uint SendMessage(IntPtr window, int msg, IntPtr wParam, ref COPYDATASTRUCT lParam); のようにしてやるとMarshalクラスの出番が無くなったりします。 [ メッセージ編集済み 編集者: Hongliang 編集日時 2005-07-25 12:40 ] | ||||
|
投稿日時: 2005-07-25 12:54
Hongliangさんありがとうございます。
コピーする機能はないんですね・・・・。勉強になります。 早速、追記の宣言で動作を確認させてもらいました。 Marshalの出番をなくすことができました〜〜 しかし、受信側では、相変わらず、文字化けしてしまっています。 | ||||
|
投稿日時: 2005-07-25 13:29
手元ではできるのになー、と思って改めてももさんのコードをチェックしてみました。
で、はたと気付きました。 COPYDATASTRUCTUREの定義ですね。 MSDNのをそのままコピーしますが、
まず、DWORDは32ビット値です。.NETならUInt32(Int32)に相当しますね。 またULONG_PTRはプラットフォーム依存のポインタ、つまり32bitOSなら32ビットですから、こちらはIntPtrで宣言すべきでしょう。 | ||||
|
投稿日時: 2005-07-25 14:13
Hongliangさんありがとうございます。
構造体の宣言を struct COPYDATASTRUCT { public IntPtr dwData; public UInt32 cbData; public string lpData; } と変えたところ・・・・ 文字を送信することができました〜〜〜〜〜〜〜!! 丁寧に教えて頂きありがとうございました。 |
1