简体   繁体   English

使用NativeWindow for ComboBox会导致Dispose-method中出现异常

[英]Use of NativeWindow for ComboBox causes exception in Dispose-method

In C# Windows.Forms I want to intercept the paste-windowmessage for a combobox. 在C#Windows.Forms中,我想截取一个组合框的paste-windowmessage。 As this doesn't work by overriding the WndProc-method of the combobox, because I would need to override the WndProc of the textbox inside the combobox, I decided to create a custom class of type NativeWindow which overrides the WndProc. 因为这不能通过覆盖组合框的WndProc方法来工作,因为我需要覆盖组合框内文本框的WndProc,我决定创建一个类型为NativeWindow的自定义类,它会覆盖WndProc。 I assign the handle and release it, when the combobox-handle gets destroyed. 当组合框处理被破坏时,我分配句柄并释放它。 But when Dispose for the combobox is called the problem is that I get an InvalidOperationException saying that an invalid cross-thread operation occured and that the combobox was accessed from a thread other than the thread it was created on. 但是当调用组合框的Dispose时,问题是我得到一个InvalidOperationException,表示发生了无效的跨线程操作,并且组件框是从其创建的线程以外的线程访问的。 Any ideas what is going wrong here? 任何想法在这里出了什么问题?

In the following you'll see, how my classes look like: 在下面你将看到我的课程如何:

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();
        }
    }
}

Per Hans' suggestion, I modified the code to use CB_GETCOMBOBOXINFO from one of his own examples. 根据汉斯的建议,我修改了代码, 以便从他自己的一个例子中使用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);
    }

  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM