1

使用 C++,我已经花了很多时间试图弄清楚这一点。这段代码来自一个工作程序,我正在用 C# 重写它,但是发生了一些我不明白的事情。

下面的代码正是我按下“Step Into”时运行的代码。现在从 ::SendMessage(...) 到 ::OnCopyData(..) 的 pCopyDataStruct 包含数据如何?

主文件

void COTP::main()
{
    //string will be returned using WM_COPYDATA message
    ::SendMessage(hWnd, 33508, (WPARAM)GetSafeHwnd(), 11);

    // WPARAM is a typedef for UINT_PTR which is an unsigned int.
}

afxwin2.inl

_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
    { return this == NULL ? NULL : m_hWnd; }

主文件

BOOL COTP::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
    CString str, str2;

    switch (pCopyDataStruct->dwData)
    {
        case JRC_COPYDATA_ID_TRACK_FILENAME:
            str = (LPCTSTR)pCopyDataStruct->lpData;
            break;
    }
}

任何帮助都非常感谢,我已经查看了今晚可以查看的所有 msdn 文档,似乎我在某个地方遗漏了一些简单的东西。认为这可能是一个回调,但这似乎不对。

4

2 回答 2

2

该代码正在向特定窗口发送消息 (33508)。显然,接收窗口通过向您在原始调用中传递的消息发送WM_COPYDATA消息来处理该消息。它本质上是实现一个回调机制。HWNDWPARAMSendMessage()

原始消息编号 (33508) 不是标准 Win32 消息之一(至少不是我认识的),因此它可能是自定义消息。此外,它用于响应的事实WM_COPYDATA表明接收窗口处于不同的进程中(即,不属于您的应用程序)。

于 2013-05-18T05:15:55.217 回答
1

好吧,现在想通了。在此页面此处的帮助下。以下是我目前用于 C# 的内容。这绝不是完成的代码,但这确实有效并且有利于学习。

点击计算按钮,

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    public static extern IntPtr GetActiveWindow();

    private void btnCalculate_Click(object sender, EventArgs e)
    {
        int hwnd = 0;
        hwnd = Win32.FindWindow("The App pulling from", "Window");

        int s = (int)GetActiveWindow();
        int s3 = Win32.SendMessage(hwnd, 33508, s, 11);

然后会发生回调并激活 WndProc(ref Message m),

    protected override void WndProc(ref Message m)
    {
        // Prevents error creating window handle message.
        base.WndProc(ref m);

        // WM_COPYDATA
        // m.Msg = 0x4a
        //msg=0x4a (WM_COPYDATA) hwnd=0x251e62 wparam=0x69063e lparam=0x1c42cca0 result=0x0
        if (m.Msg == 0x4a)
        {
            Console.WriteLine(m);
            WndProc(m.HWnd, m.Msg, m.WParam, m.LParam);
        }
    } 

    public struct CopyDataStruct : IDisposable
    {
        public IntPtr dwData;
        public int cbData;
        public IntPtr lpData;

        public void Dispose()
        {
            if (this.lpData != IntPtr.Zero)
            {
                LocalFree(this.lpData);
                this.lpData = IntPtr.Zero;
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public unsafe struct DataStruct
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 300)]
        public string s;
        public double d;
        public char c;
    };

    protected void WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
    {
        CopyDataStruct cps = (CopyDataStruct)Marshal.PtrToStructure(lParam, typeof(CopyDataStruct));
        DataStruct data = (DataStruct)Marshal.PtrToStructure(cps.lpData, typeof(DataStruct));
        // data.s is what we needed.
        Console.WriteLine(data.s);
    }

非常感谢所有回复的人!如果没有您的帮助,我相信我会放弃。:)

于 2013-05-18T15:33:10.563 回答