如何在Windows Forms应用程序中使用这个WndProc?

4
请指导我如何在Windows Forms应用程序中使用WndProc
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if (msg == NativeCalls.APIAttach && (uint)lParam == NativeCalls.SKYPECONTROLAPI_ATTACH_SUCCESS)
    {
        // Get the current handle to the Skype window
        NativeCalls.HWND_BROADCAST = wParam;
        handled = true;
        return new IntPtr(1);
    }

    // Skype sends our program messages using WM_COPYDATA. the data is in lParam
    if (msg == NativeCalls.WM_COPYDATA && wParam == NativeCalls.HWND_BROADCAST)
    {
        COPYDATASTRUCT data = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
        StatusTextBox.AppendText(data.lpData + Environment.NewLine);

        // Check for connection
        if (data.lpData.IndexOf("CONNSTATUS ONLINE") > -1)
            ConnectButton.IsEnabled = false;

        // Check for calls
        IsCallInProgress(data.lpData);
        handled = true;
        return new IntPtr(1);
    }

    return IntPtr.Zero;
}

我见过人们在WPF中像这样使用上述代码:
protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);

    // Attach WndProc
    HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
    source.AddHook(WndProc);
}

6
你有什么问题? - Ashley Medway
如何在Windows窗体应用程序中附加上述的WndProc函数? - Thomas
如何挂钩和取消挂钩上述的WndProc? - Thomas
这是一个示例:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.wndproc%28v=vs.110%29.aspx - Sriram Sakthivel
2个回答

4

C#中WndProc的原型为:

protected virtual void WndProc(ref Message m)

因此,您需要在您的类中覆盖此过程,假设它派生自Control
protected override void WndProc(ref Message m)
{
    Boolean handled = false; m.Result = IntPtr.Zero;
    if (m.Msg == NativeCalls.APIAttach && (uint)m.Param == NativeCalls.SKYPECONTROLAPI_ATTACH_SUCCESS)
    {
        // Get the current handle to the Skype window
        NativeCalls.HWND_BROADCAST = m.WParam;
        handled = true;
        m.Result = new IntPtr(1);
    }

    // Skype sends our program messages using WM_COPYDATA. the data is in lParam
    if (m.Msg == NativeCalls.WM_COPYDATA && m.WParam == NativeCalls.HWND_BROADCAST)
    {
        COPYDATASTRUCT data = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
        StatusTextBox.AppendText(data.lpData + Environment.NewLine);

        // Check for connection
        if (data.lpData.IndexOf("CONNSTATUS ONLINE") > -1)
            ConnectButton.IsEnabled = false;

        // Check for calls
        IsCallInProgress(data.lpData);
        handled = true;
        m.Result = new IntPtr(1);
    }

    if (handled) DefWndProc(ref m); else base.WndProc(ref m);
}

谢谢你的回答,但我不明白为什么在调试时控件从未进入第二个if块?你能告诉我原因吗?谢谢。 - Thomas
抱歉,我编辑了我的帖子。问题在于函数底部m.Result总是被设置为零。在开头将其设置为零将解决此问题,也可能解决您的问题。 - Elvedin Hamzagic
问题仍然存在。 - Thomas
也许你的问题不在于 WndProc,而是 Skype。你能否设置断点并检查传入的消息?你是否收到正常的窗口消息? - Elvedin Hamzagic
我猜不会,因为我开发的应用程序是基于WPF的应用程序,它也可以捕获Skype声音并保存到文件中...这很好。只有我的应用程序出了问题。我想我可能漏掉了一些东西或者我的代码有一些错误,所以才会出现问题。 - Thomas
请您从以下URL下载我的应用并在您的设备上尝试运行,谢谢。此为下载链接,请下载其中的 SkypeCallTest.zip 文件:https://onedrive.live.com/#cid=C4A6F16F34D7540A&id=C4A6F16F34D7540A!126 - Thomas

4
你可以使用 Application.AddMessageFilter 方法。
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public class TestMessageFilter : IMessageFilter
{
    public bool PreFilterMessage(ref Message m)
    {
        // Blocks all the messages relating to the left mouse button. 
        if (m.Msg >= 513 && m.Msg <= 515)
        {
            Console.WriteLine("Processing the messages : " + m.Msg);
            return true;
        }
        return false;
    }
}

什么是IMessageFilter以及它的作用是什么?为什么你要建议我使用它? - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接