代码之家  ›  专栏  ›  技术社区  ›  Nicholas Miller

Windows窗体组合框将在选定项目之前窃取焦点

  •  2
  • Nicholas Miller  · 技术社区  · 6 年前

    我在使用标准Windows窗体时遇到了一个特殊问题 ComboBox 。 基本上,如果我单击 组合框 ,然后再次单击它或单击escape退出下拉列表,焦点被盗。下面的动画显示了如何执行此操作:

    ComboBox Stealing Focus

    当焦点被盗时, WM_SETFOCUS 没有收到消息,这会产生一些有趣的后果:

    • 高度 + F4级 命令不会关闭激活的窗口。
    • 单击 TabControl 不切换页面。
    • 无法使用切换聚焦控制 选项卡 转移 + 选项卡

    可以想象,这会使应用程序处于一种不可接受的状态,因为用户可能不知道为什么,或者更重要的是,不知道如何解决这个焦点问题,并且会因为没有响应而认为存在错误。

    经过一些测试,我发现可以通过从冒犯者中选择一个项目来恢复注意力 组合框

    当下拉列表退出而未选择项目时,如何防止组合框窃取焦点?


    我从Spy++收集了一些日志来演示第三个项目符号(切换焦点)。 如图所示,按下tab键,但 WM\U设置焦点 不受Spy++监控。

    <000434> 0025574E R WM_NCCALCSIZE fuValidRect:0000 lpncsp:007CE9CC
    <000435> 0025574E S WM_NCCALCSIZE fCalcValidRects:True lpncsp:007CE9CC
    <000436> 0025574E R WM_NCCALCSIZE fuValidRect:0000 lpncsp:007CE9CC
    <000437> 0025574A P WM_LBUTTONUP fwKeys:0000 xPos:237 yPos:26
    <000438> 0025574E P WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:236 yPos:-7
    <000439> 0025574A P WM_LBUTTONUP fwKeys:0000 xPos:237 yPos:26
    <000440> 0025574A P WM_KEYDOWN nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    <000441> 0025574A P WM_KEYUP nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:1 fUp:1
    <000442> 0025574A P WM_KEYDOWN nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    <000443> 0025574A P WM_KEYUP nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:1 fUp:1
    <000444> 0025574A P WM_KEYDOWN nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    <000445> 0025574A P WM_KEYUP nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:1 fUp:1
    <000446> 0025574A P WM_KEYDOWN nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    

    但是,在下拉列表中选择和项后,focus可以更改并捕获Spy++ WM\U设置焦点 消息。

    <000742> 002555E0 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:007CCFA4
    <000743> 002555E0 R WM_NCCALCSIZE fuValidRect:0000 lpncsp:007CCFA4
    <000744> 002555E0 S WM_NCCALCSIZE fCalcValidRects:True lpncsp:007CCC94
    <000745> 002555E0 R WM_NCCALCSIZE fuValidRect:0000 lpncsp:007CCC94
    <000746> 0025574E R WM_KEYDOWN
    <000747> 0025574A P WM_KEYUP nVirtKey:VK_DOWN cRepeat:1 ScanCode:50 fExtended:1 fAltDown:0 fRepeat:1 fUp:1
    <000748> 0025574A P WM_KEYDOWN nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    <000749> 0025574A S WM_KILLFOCUS hwndGetFocus:00265748
    <000750> 0025574A R WM_KILLFOCUS
    <000751> 00265748 S WM_SETFOCUS hwndLoseFocus:0025574A
    <000752> 00265748 R WM_SETFOCUS
    <000753> 00265748 P WM_KEYUP nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:1 fUp:1
    <000754> 00265748 P WM_KEYDOWN nVirtKey:VK_TAB cRepeat:1 ScanCode:0F fExtended:0 fAltDown:0 fRepeat:0 fUp:0
    <000755> 00265748 S WM_KILLFOCUS hwndGetFocus:00255770
    <000756> 00265748 R WM_KILLFOCUS
    

    我最初认为窃取焦点的行为是 组合框 在没有正确重新激活父窗口的情况下,为下拉显示创建新窗口。但单击任务栏中的应用程序图标将导致 WM_ACTIVATE 消息将出现在Spy++中,而不会再次检索焦点。

    1 回复  |  直到 4 年前
        1
  •  1
  •   Dru Steeby    6 年前

    您可能想在此处查看此主题:

    Cannot tab out of databound Winforms dropdown list

    数据绑定可能会在后台的数据验证中引发异常。