【问题标题】:Keyboard focus: looking for a general strategy键盘焦点:寻找通用策略
【发布时间】:2012-09-26 15:24:48
【问题描述】:

我的应用程序有一个很大的图形区域,在侧面板中有一些控件(滑块、按钮、文本编辑控件)。图形区域可以理解一些键盘命令。

我的问题是,当侧面板中的控件处于焦点时,主图形区域不会收到任何键盘命令,所以这会让用户感到困惑。但是,对于某些控件,这是有意的,例如文本编辑控件。

我想要的是尽早自动返回图形区域的焦点(我称之为“贪婪”焦点) - 例如当文本编辑完成时(Enter 键),或者当用户从组合框中选择了一个项目时。

我正在寻找一种干净而强大的策略来处理该问题,无论是使用 Windows API 还是 Borland Vcl。

如果您想分享您的想法,我们将不胜感激。

【问题讨论】:

  • 由于您希望图形区域成为处理键盘快捷键的区域,因此每当不应该这样做的区域获得焦点时,它应该将焦点更改为 gfx 区域。您是否尝试过在控件失去焦点(即,当它们收到 WM_KILLFOCUS 消息时)或当它们的封闭容器获得焦点时切换焦点?
  • 是的,这是一个很有前途的方法,我已经开始走这条路了。然而,魔鬼在细节中。我的 WM_KILLFOCUS 处理程序适用于某些控件,但不适用于其他控件。例如,复选框变得不可点击。显然他们需要集中注意力来改变他们的状态。

标签: c++ winapi keyboard c++builder


【解决方案1】:

我还没有完全解决这个问题,但是在表单级别拦截的一个非常有用的消息是CM_DIALOGKEY(仅限 Borland Vcl)。它为通常用于在 UI 中导航的每个键发送。也就是说,光标键、tab 和 shift-tab、Enter 和可能的其他键。

我为CM_DIALOGKEY 添加了一个事件处理程序,它将焦点返回到图形区域并将按键转发到该组件。这样用户仍然可以通过键盘控制 UI 元素(对于文本输入很重要),但光标键由图形区域处理。

【讨论】:

    【解决方案2】:

    我知道你的意思我在一些 BIG 应用程序 lice CAD/CAM 上遇到了类似的问题......

    我的解决方案简单、强大,而且我使用了多年。

    1.该 gfx 区域的所有击键处理

    • 必须在该区域所在的Form的事件中完成
    • 不在面板中,无论是油漆盒...

    2.create unfocus 函数(最好是form的成员,但不是必须的)

    • 此函数将失去任何 VCL 项的焦点
    • 所以重点是形成自己想要的东西
    • 我正在使用这个:

      //---------------------------------------------------------------------------
      void main_unfocus()
          {          
          Main->bt_unfocus->Visible=true;
          Main->bt_unfocus->SetFocus();
          Main->bt_unfocus->Visible=false;
          }
      //---------------------------------------------------------------------------
      
    • Main 是表单指针

    • bt_unfocus 是按钮(可以是任何可聚焦的 VCL 组件)
    • 我一般把这个按钮放在App的左上角,大小设置为2x2像素
    • 一开始是不可见的
    • 想法是将焦点设置为它(但首先取消隐藏它,以免引发异常)
    • 然后将其隐藏,使其失去焦点
    • 在 BCB5 和 BDS2006 中运行良好(没有与任何其他 IDE 一起使用)
    • 如您所见,大多数情况下此组件是不可见的

    4.现在何时调用 main_unfocus ?

    • 当您使用鼠标从 gfx 区域的外部移动到内部时(OnMouseMove 事件)
    • 或者当你点击它时
    • 您也可以将此与记住焦点是否在 gfx 区域相结合
    • 这可以通过 OnExit 之类的事件来完成 ...
    • 或者当焦点位于编辑框内时按 Esc ...\
    • 我相信您已经掌握了这个想法并根据您的需要进行调整

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-01
      相关资源
      最近更新 更多