0

我们有一个示例应用程序,其中包含“DropDownList”模式下的组合框的此类处理程序:

    private void comboBox1_Leave(object sender, EventArgs e)
    {
        comboBox1.SelectionStart = 0;
        comboBox1.SelectionLength = 0;
    }

上面的代码行为不同,具体取决于应用程序是否加载了 CALLWNDPROC 挂钩。如果应用程序中有一个 CALLWNDPROC 钩子——只要组合框失去焦点,上面的代码就会抛出异常。没有钩子 - 该代码不会抛出。

这些是异常描述中的几行:

System.ArgumentOutOfRangeException: InvalidArgument=Value of '-2136611475' is not valid for 'start'.
Parameter name: start
   at System.Windows.Forms.ComboBox.Select(Int32 start, Int32 length)
   at System.Windows.Forms.ComboBox.set_SelectionLength(Int32 value)
   at ComboCrash.Form1.comboBox1_Leave(Object sender, EventArgs e) in T:\tmp.proj\ComboCrash\ComboCrash\Form1.cs:line 32
   at System.Windows.Forms.Control.OnLeave(EventArgs e)
   at System.Windows.Forms.Control.NotifyLeave()
   at System.Windows.Forms.ContainerControl.UpdateFocusedControl()

问题是:安装钩子后出现这种不同行为的原因可能是什么?

PS1:我不是 C# 开发人员,但在我看来,文本选择的概念不适用于 DropDownList 组合框(因为它们没有文本框),对吗?

PS2:安装钩子的应用程序和钩子DLL是用C++编写的。钩子函数很简单:

return (CallNextHookEx(hook_handle, code, wParam, lParam));
4

1 回答 1

1

好的,因为没有建议,我会提供一些:

  1. 如果您的组合框是 DropDownList,则使用 SelectionStart 和 SelectionLength 属性是不正确的。在这些情况下,CB_GETEDITSEL 被发送到组合框的窗口——它不会返回任何可靠的东西(因为没有要查询的编辑控件)。所以 -只是不要这样做(或用 try-catch 附上相应的代码)!或者 - 始终检查组合框的类型。
  2. 违反先前的建议可能会导致 (a) 没有异常;(b) 未处理的异常或程序异常终止(取决于 JIT 设置)。如果您的环境中安装了系统范围的 WH_CALLWNDPROC 挂钩,情况 (b) 非常稳定。

2011 年 2 月更新 正如我在此处的评论中提到的,唯一的解决方法(读取 - 肮脏的 hack)是安装您自己的相同类型的钩子(WH_CALLWNDPROC),但如果消息适用于您的组合框,则不要调用其他钩子。是的,它很丑。

于 2009-06-10T10:10:45.440 回答