处理派生C#用户控制窗口的通知 [英] Handling windows notifications in derived C# user control

查看:270
本文介绍了处理派生C#用户控制窗口的通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何处理任何列出的树视图通知的这里在从.NET TreeView控件派生的C#类?

How can I handle any of the tree view notifications listed here in a C# class that is derived from the .NET TreeView control?

我试图处理click通知,对于举例来说,像这样的:

I tried to handle the click notification, for example, like this:

class ExtendedTreeView : TreeView
{
    private const Int32 NM_FIRST = (Int32)(0U - 0U);
    private const Int32 NM_CLICK = unchecked((Int32)((UInt32)NM_FIRST - 2U));

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == NM_CLICK)
        {
            MessageBox.Show("NM_CLICK");
        }
        base.WndProc(ref m);
    }
}



但从未显示消息框。这是我第一次尝试使用Win32 API的修改.NET控件的行为,所以我不知道哪里出了问题。

But the message box is never shown. This is the first time I try to use Win32 API to modify the behaviour of a .NET control, so I have no idea what goes wrong.

这是正确的做法?处理这些通知

Is this the correct approach to handle these notifications?

FYI:我知道,.NET TreeView控件具有click事件。这只是第一个测试。后来我想启用 TVS_EX_MULTISELECT 的风格。由于当启用 TVS_EX_MULTISELECT 的.NET TreeView控件不会触发任何 AfterSelect 事件,我想调查的行为在 TVN_SELCHANGED TVN_ITEMCHANGED 的通知后。

FYI: I know that the .NET TreeView control has a click event. This is just a first test. Later I want to enable the TVS_EX_MULTISELECT style. Since the .NET TreeView control does not fire any AfterSelect events when TVS_EX_MULTISELECT is enabled, I want to investigate the behaviour of the TVN_SELCHANGED and TVN_ITEMCHANGED notifications later.

推荐答案

这不是那么简单。检查 MSDN文章的通知NM_CLICK交付作为一个WM_NOTIFY消息。它被发送到的的树视图的。的Winforms具有到位管道回声回原来的控制,以使消息通过从树视图派生的类进行处理和定制事件处理。 。这是通过添加为0x2000的消息,WM_REFLECT中的WinForms源代码值来完成

It is not that simple. Check the MSDN article, the NM_CLICK notification is delivered as a WM_NOTIFY message. And it is sent to the parent of the treeview. Winforms has plumbing in place to echo it back to the original control to allow the message to be handled by a class derived from TreeView and customize the event handling. That's done by adding 0x2000 to the message, the value of WM_REFLECT in the Winforms source code.

因此​​,代码应该是这样的:

So the code should look like this:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class ExtendedTreeView : TreeView {
    protected override void WndProc(ref Message m) {
        if (m.Msg == WM_REFLECT + WM_NOFITY) {
            var notify = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR));
            if (notify.code == NM_CLICK) {
                MessageBox.Show("yada");
                m.Result = (IntPtr)1;
                return;
            }

        }
        base.WndProc(ref m);
    }
    private const int NM_FIRST = 0;
    private const int NM_CLICK = NM_FIRST - 2;
    private const int WM_REFLECT = 0x2000;
    private const int WM_NOFITY = 0x004e;

    [StructLayout(LayoutKind.Sequential)]
    private struct NMHDR {
        public IntPtr hwndFrom;
        public IntPtr idFrom;
        public int code;
    }
}



要注意的是TreeView中已经做了这一切,这是怎样的NodeMouseClick,点击并获取生成鼠标点击事件。那这是否也代码工作围绕在本地控制一些怪癖所以一定要提交到使用它之前真的需要这一点。如果你想知道这是怎么回事查看参考源。

Beware that TreeView already does all this, that's how the NodeMouseClick, Click and MouseClick events get generated. The code that does this also works around some quirks in the native control so be sure you really need this before committing to use it. Review the Reference Source if you want to know what's going on.

这篇关于处理派生C#用户控制窗口的通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆