使用本地窗口对组合的方法是dispose方法中的例外



在c#windows.forms中,我想拦截combobox的粘贴窗口。由于这无法通过覆盖ComboBox的WNDProc-Method来效用,因为我需要覆盖Combobox内部文本框的WNDProc,因此我决定创建一个自定义类型的本机温dow类,从而覆盖WNDProc。当Combobox Handle被破坏时,我分配了手柄并释放它。但是,当将Combobox处置时,问题是我得到了一个InvalidOperationException,说发生了无效的跨线程操作,并且从其创建的线程以外的线程中访问了Combobox。有什么想法这里出了什么问题?

在下面您会看到,我的课程是什么样的:

public class MyCustomComboBox : ComboBox
{
    private WinHook hook = null;
    public MyCustomComboBox()
        : base()
    {
        this.hook = new WinHook(this);
    }
    private class WinHook : NativeWindow
    {
        public WinHook(MyCustomComboBox parent)
        {
            parent.HandleCreated += new EventHandler(this.Parent_HandleCreated);
            parent.HandleDestroyed += new EventHandler(this.Parent_HandleDestroyed);
        }
        protected override void WndProc(ref Message m)
        {
            // do something
            base.WndProc(ref m);
        }
        private void Parent_HandleCreated(object sender, EventArgs e)
        {
            MyCustomComboBox cbx = (MyCustomComboBox)sender;
            this.AssignHandle(cbx.Handle);
        }
        private void Parent_HandleDestroyed(object sender, EventArgs e)
        {
            this.ReleaseHandle();
        }
    }
}

根据汉斯的建议,我从他自己的一个示例中修改了使用cb_getcomboboxinfo的代码。

public class PastelessComboBox : ComboBox {
    private class TextWindow : NativeWindow {
      [StructLayout(LayoutKind.Sequential)]
      private struct RECT {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
      }
      private struct COMBOBOXINFO {
        public Int32 cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public int buttonState;
        public IntPtr hwndCombo;
        public IntPtr hwndEdit;
        public IntPtr hwndList;
      }
      [DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
      private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp);
      public TextWindow(ComboBox cb) {
        COMBOBOXINFO info = new COMBOBOXINFO();
        info.cbSize = Marshal.SizeOf(info);
        SendMessageCb(cb.Handle, 0x164, IntPtr.Zero, out info);
        this.AssignHandle(info.hwndEdit);
      }
      protected override void WndProc(ref Message m) {
        if (m.Msg == (0x0302)) {
          MessageBox.Show("No pasting allowed!");
          return;
        }
        base.WndProc(ref m);
      }
    }
    private TextWindow textWindow;
    protected override void OnHandleCreated(EventArgs e) {
      textWindow = new TextWindow(this);
      base.OnHandleCreated(e);
    }
    protected override void OnHandleDestroyed(EventArgs e) {
      textWindow.ReleaseHandle();
      base.OnHandleDestroyed(e);
    }
  }

相关内容

  • 没有找到相关文章