0

更新以反映我的请求的更实用的描述。

ComboBox从功能上讲,我需要一个不直接从System.Windows.Forms.ComboBox类继承的只读文件。我需要将文本框部分设为只读,以便用户可以复制输入框中的文本但不能更改它。这不是使用DropDownvsDropDownList模式的情况。

使用本文和一些实验,我已经处理了文本框部分,但由于下面列出的技术原因,仍然需要防止下拉组件的更改。我仍然需要以下之一:

  1. 禁用 - 上的下拉按钮ComboBox以防止其打开
  2. 防止下拉菜单ComboBox在单击时打开
  3. 防止从下拉列表中选择项目更改控件中的选择(可能通过拦截和忽略单击项目通知消息)

我在我的应用程序中使用KryptonToolkit来获得视觉美感。对于KryptonComboBox控件,它有一个内部的扩展System.Windows.Forms.ComboBox类来拦截绘图调用。它公开了对该ComboBox对象的访问权限,因此我可以访问它的Handle.

我使用A Complete Read Only ComboBox代码作为基础来创建KryptonComboBox. 您必须使用来获取 Windows 控件的实际句柄,而不是KryptonComboBox.Handle在调用中使用。通过这样做,我可以在 ComboBox 的文本框部分正确设置只读模式。SendMessage()KryptonComboBox.ComboBox.Handle

但!由于扩展控件的基类 isKryptonComboBox和 not ComboBox,所以当WndProc()调用 时,它是针对KryptonComboBox. 因此,当控件处于只读模式时,我无法阻止控件对单击的下拉项执行操作(更改选择)。

如何拦截(并可能忽略)来自现有 ComboBox 控件的 WM_COMMAND 消息。具体来说,我希望在某些情况下忽略消息 273 链。有没有办法在功能上对“外部”ComboBox控件做同样的事情,我可以从继承的控件中做同样的事情?既然我有Handlefor the ComboBox,我可以使用类似的东西SetWindowsHookEx()来拦截消息吗?

4

1 回答 1

0

所以我找到了一个解决方案,可以“插入”控件的命令消息并能够中断它们。它涉及使用System.Windows.Forms.NativeWindow该类来创建一个监听ComboBox器(据我所知)称为子类化。

监听类:

private class ComboBoxListener : NativeWindow, IDisposable {
    private ComboBox m_oComboBox;

    private EventHandler m_oComboBox_HandleCreated;
    private EventHandler m_oComboBox_HandleDestroyed;

    public ComboBoxListener(ComboBox oComboBox) {
        // Save the combobox and assign the handle if it's already created
        m_oComboBox = oComboBox;
        if (m_oComboBox.IsHandleCreated) {
            AssignHandle(m_oComboBox.Handle);
        }

        // Subscribe to the handle events of the combobox
        m_oComboBox.HandleCreated += m_oComboBox_HandleCreated = new EventHandler(ComboBox_HandleCreated);
        m_oComboBox.HandleDestroyed += m_oComboBox_HandleDestroyed = new EventHandler(ComboBox_HandleDestroyed);
    }

    ~ComboBoxListener() {
        Dispose(false);
    }

    public void Dispose() {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool bDisposing) {
        if (bDisposing && (m_oComboBox != null) && !m_oComboBox.IsDisposed) {
            // Unsubscribe from the combo box
            m_oComboBox.HandleCreated -= m_oComboBox_HandleCreated;
            m_oComboBox.HandleDestroyed -= m_oComboBox_HandleDestroyed;
        }
        m_oComboBox = null;

        // If a handle is currently assigned, release it
        if (this.Handle != IntPtr.Zero) {
            ReleaseHandle();
        }
    }

    private void ComboBox_HandleCreated(object sender, EventArgs e) {
        AssignHandle(m_oComboBox.Handle);
    }

    private void ComboBox_HandleDestroyed(object sender, EventArgs e) {
        ReleaseHandle();
    }

    protected override void WndProc(ref Message m) {
        // Do checks for whether to ignore the message
        // If ignoring, just call return and skip the base.WndProc(ref m) call
        base.WndProc(ref m);
    }
}

然后在派生类的构造函数中KryptonComboBox添加:

m_oComboBoxListener = new ComboBoxListener(this);

并在覆盖中添加了清理Dispose(bool disposing)

// Dispose the listener
if (disposing && (m_oComboBoxListener != null)) {
    m_oComboBoxListener.Dispose();
}
m_oComboBoxListener = null;
于 2014-10-17T15:35:13.757 回答