DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C#のSendMessageで送信したメッセージを、C++アプリで受信する方法

環境/言語:[Visual C# .NET]
分類:[.NET]

過去の掲示板
http://dobon.net/vb/bbs/log3-4/2445.html#2445
に、「SendMessage() APIで送信したメッセージをC#アプリ側で受信する方法」がありますが、
これの逆で、C#のSendMessageで送信したメッセージをC++アプリで受信することを実装したいのですが、うまく動作しません。

C#アプリ側のSendMessage()でメッセージ(0x004A)を送信しても、C++アプリ側ではWM_COPYDATAで受け取れません。

何かご存知の方は、ご教授下さい。
> これの逆で、C#のSendMessageで送信したメッセージをC++アプリで受信することを実装したいのですが、うまく動作しません。
>
> C#アプリ側のSendMessage()でメッセージ(0x004A)を送信しても、C++アプリ側ではWM_COPYDATAで受け取れません。

これだけだと「そうですか、残念でしたね…」
としか言いようがない気がするのですが^^;;;

とりあえず、ググってみました
http://www.google.co.jp/search?complete=1&hl=ja&q=vc%2B%2B+wm_copydata&lr=
2006/07/28(Fri) 16:29:35 編集(投稿者)

WM_COPYDATAでSendMessage時にlParamに値を設定していますか?
0(IntPtr.Zero)だと、うまくいかないらしいです。

参考)VC++同士のWM_COPYDATAの場合ですが。
WM_COPYDATAを用いたプロセス間通信について
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200607/06070029.txt
一応試しに、C#の勉強がてらやってみた。

C#
// 参考)http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=31174&forum=7

using System;
using System.Runtime.InteropServices;

public class CopyDataTest
{
    private static uint WM_COPYDATA = 0x004A;
    [DllImport("user32.dll")]
    private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage (IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    //private static extern IntPtr SendMessage (IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
    private struct COPYDATASTRUCT
    {
        public IntPtr dwData;
        public uint   cbData;
        public IntPtr lpData;
    }
    
    public static void Main(string[] args)
    {
        string s = "ほげ";
        
        IntPtr hWnd = FindWindow(null, "recv");
        
        COPYDATASTRUCT cds = new COPYDATASTRUCT();
        cds.dwData = IntPtr.Zero;
        cds.lpData = Marshal.StringToHGlobalUni(s);
        cds.cbData = (uint)((s.Length + 1) * 2);
        
        IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(cds));
        Marshal.StructureToPtr(cds, pnt, false);
        
        // やはりlParamをIntPtr.Zeroにすると、C++のウィンドウに通知されない
        SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, pnt);
        //SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds);
    }
}


C++・・・手抜きのためMFCでWM_COPYDATAをハンドル。

BOOL CRecvDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
    // TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処理を呼び出してください
    CString str( ( LPCWSTR )pCopyDataStruct->lpData );
    AfxMessageBox( str );

    return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}
いくら Main メソッドのみですぐ終わるとは言え、確保したアンマネージドメモリは解放しておくべきかと。
■No16886に返信(Hongliangさんの記事)
> 確保したアンマネージドメモリは解放しておくべきかと。
普通に忘れていましたね。。。ご指摘ありがとうございました。
lParamを0にしていたことが原因だったようです。解決しました!
みなさま、いろいろ教えてくださってありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板