如何为没有点击事件的内容设置点击处理程序?

时间:2015-07-29 17:15:31

标签: c# .net winforms

我通过Icon组件ErrorProvider(因为它本身不是Control)。我想将一个点击处理程序挂钩到图标本身。当它显示时我想让我的用户点击它并生成详细的弹出窗口或帮助文章界面来提供细节。它暴露了IntPtr句柄,但我在Win32世界中根本不熟悉。我认为这是我需要的东西(WndProc的东西,也许是??)因为我已经尝试在包含控件的表单上添加点击但是没有'切它。

我该怎么办?感谢。

1 个答案:

答案 0 :(得分:0)

ErrorProvider动态创建窗口以显示错误图标。检测那些窗口上的鼠标点击需要非常讨厌的代码。我只是告诉你它是如何完成的,我建议你不要实际使用它。启动一个新的WF应用程序并在表单上删除一个文本框和一个错误提供程序。粘贴此代码:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Reflection;

namespace WindowsFormsApplication1 {
  public partial class Form1 : Form, IMessageFilter {
    public Form1() {
      InitializeComponent();
      Application.AddMessageFilter(this);
      errorProvider1.SetError(textBox1, "Test");
    }

    protected override void OnFormClosing(FormClosingEventArgs e) {
      Application.RemoveMessageFilter(this);
      base.OnFormClosing(e);
    }

    public bool PreFilterMessage(ref Message m) {
      if (m.Msg == 0x201) {
        // MouseDown, check if the icon was clicked
        NativeWindow wnd = NativeWindow.FromHandle(m.HWnd);
        if (wnd == null) return false;
        Type t = wnd.GetType();
        if (t.Name != "ErrorWindow") return false;
        // Yes, use Reflection to find the control for that icon
        FieldInfo fi = t.GetField("items", BindingFlags.NonPublic | BindingFlags.Instance);
        System.Collections.ArrayList items = fi.GetValue(wnd) as System.Collections.ArrayList;
        if (items == null || items.Count == 0) return false;
        object item = items[0];
        FieldInfo fi2 = item.GetType().GetField("control", BindingFlags.NonPublic | BindingFlags.Instance);
        Control ctl = fi2.GetValue(item) as Control;
        // Got it.
        MessageBox.Show("You clicked the icon for " + ctl.Name);
      }
      return false;
    }
  }
}