Windows 可以在单个控件上管理多个焦点吗?
我正在构建一个具有多个焦点的自定义控件。例如,在 1 个控件内,假设有 3 个区域(可以定义为画布上的矩形)能够获得焦点。根据焦点所在,我不希望周围有默认的 Windows 虚线,而是需要一些特殊处理。我什至不知道如何让 1 个自定义控件拥有自己的焦点。
最初的项目是一个单一的 TPanel,上面有一些 VCL 控件,当然每个控件都有自己的窗口,因此有自己的焦点。但现在我将它放入自己的自定义类中,这 3 个控件将不再存在(它们仅作为原型出现在版本 1 中),现在我需要以某种方式模仿这些不同区域的焦点。
我想类似于 TListBox 这样简单的东西,其中该控件中的某些项目获得焦点,而不是整个控件本身。
这是一张图片,可以帮助演示我正在制作的内容...
顶部的图片是原始图片与按钮。但底部的那个是我正在建造的新的,全部是定制绘制的。
详细地说,在我重新发明轮子之前,我想看看 Windows 是否已经对这种类型的场景进行了特殊处理。
我并不是在寻找“最简单”的方法来实现这一目标。而且我也不希望建议恢复到我之前的样子,因为有很多原因我不希望 1 个控件与多个其他控件一起使用。我只需要一个是或否,以及一个解释。
更多
我刚刚意识到主要关心的是tab
键的使用。该控件必须首先获得焦点,开始将焦点集中在它应该关注的任何子项上,然后响应我的命令上的 tab
直到到达末尾,然后将 Tab 键传递到下一个控件。然后还需要shift+tab。我到底要如何实现这个选项卡?这就是我陷入困境的地方,但我突然意识到这是我问的主要原因。
I'm building a custom control which is to have multiple focus points. For example, within 1 control, let's say there's 3 regions (could be defined as a rect on the canvas) which are to be able to have focus. Depending on which one has focus, I don't want the default Windows dotted line around it, but some special handling. I know nothing about how to even give 1 custom control its own focus.
The original project was a single TPanel with a few VCL controls on it, each of course being its own window, thus having its own focus. But now I'm putting it into a custom class of its own, which these 3 controls will no longer exist (they were only there in version 1 as a prototype) and I need to now somehow mimic the focus in these different regions.
I guess similar to something as simple as a TListBox, where certain items within that control get the focus instead of the entire control its self.
Here's a picture to help demonstrate what I'm making...
The one on the top is the original with the buttons. But the one on the bottom is the new one I'm building which is all custom drawn.
To elaborate, I'd like to see if Windows already has special handling for this type of scenario before I go and re-invent the wheel.
I'm not looking for the "Easiest" way to accomplish this. And I also do not want recommendations to revert back to how I had it before, because there's many reasons I don't want 1 control with multiple other controls within. I just need a yes or no, with an explanation.
More
I just realized the main concern is the use of the tab
key. The control has to first get the focus, start the focus on whichever sub-item it's supposed to, then respond to tab
on my command until it reaches the end, then pass the tabbing over to the next control. Then it also needs shift+tab as well. How on earth would I implement this tabbing? That's where I got stuck, but it just struck me that this is the main reason I'm asking.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(3)
不,您无法让窗口识别同一窗口句柄内的多个键盘焦点点,因为带有窗口句柄的每个控件要么具有或不具有键盘焦点。多个控件之间的“内在焦点”由你来梳理。
正如您已经知道的,完成此操作的最简单方法是拥有多个带有自己的窗口句柄的子控件,这就是您所说的正在做的事情:
TMyThreeEditControls = class(TControl) // parent has no window handle!!!!
protected
FEdit1:TEdit;
FEdit2:TEdit;
FEdit3:TEdit;
...
end
在上面的情况中,父控件是一个 TControl,它创建了几个子控件,在我上面的示例中,所有三个都有自己的窗口句柄,因此 Windows 可以在您点击 Tab 时显示键盘焦点,并将处理鼠标焦点作为 Windows 公共控件库功能的一部分。
简而言之,在主控件中包含子对象(其他控件)的“复合”方法(您试图摆脱这种方法)实际上是让 Windows 完成大部分工作的唯一方法。
另一方面,您可能正在寻找的不是一种让控件绘画本身的方法,而是一些使某些东西看起来像集中在您自己的自定义绘画例程中的代码,如果这就是您正在寻找的,您应该查看 VCL 源代码或 about.com 上的链接有关如何进行的示例告诉 Windows 绘制焦点矩形等。about.com 链接是一个模仿,不使用真正的 Windows 代码以 Windows 主题感知的方式绘制焦点。
更新:您可能也在寻找确定鼠标坐标是否在指定矩形内的方法(该矩形代表您的情况下的按钮),如果是,则为鼠标绘制“热状态”按钮。如果您想自己构建一个控件,还有更多的子任务需要完成,我建议您研究 VCL 源代码中的现有控件,例如 TStringGrid 和 TCategoryButtons,以查看您需要的 MouseMove、MouseDown 和 MouseUp 处理代码去做你想做的事情。特别是,StringGrid 源代码是查看如何在具有单个窗口句柄的单个控件中使用“tab 键”的方法,因为在该控件中可以使用 tab 键(如果打开了正确的选项)在字符串网格内的所有单元格之间导航,就好像每个单元格都是一个单独的控件,即使它们都是一个控件。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
关于 TAB 键的处理 - 应该是这样的:您处理 WM_GETDLGCODE 消息 表示您要处理TAB 键,即
在重写的
KeyDown
方法中,您决定响应它做什么,例如About the handling of the TAB key - it should be something like this: you handle the WM_GETDLGCODE message to indicate that you want to proccess the TAB key, ie
and the in the overriden
KeyDown
method you decide what to do in response of it, something like