如何使用无窗口控件?

发布于 2024-08-22 18:17:23 字数 1706 浏览 11 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

梦醒时光 2024-08-29 18:17:23

构建无窗口控件并将它们装入Delphi 的VCL 框架是徒劳的。

您以 Internet Explorer 为例。但在这种情况下,它完全负责其上的所有内容。对于主动控件是什么,它有自己的内部概念,但从外部看它是什么样子:它只是一个巨大的控件。当您询问操作系统什么具有焦点时,单个浏览器控件具有焦点,无论浏览器的哪个子控件似乎具有焦点。

当您按 Tab 时,操作系统看起来就像浏览器只是简单地使用了一个制表符,就像编辑控件一样。编辑控件将光标移动到几个空格上并将制表符添加到其内部缓冲区;浏览器控件将光标移动到显示的另一个区域。

您正在考虑在 Delphi TForm 上完成所有这些工作。 Delphi 表单已经有一个用于管理主动控制和处理击键的框架,您将不得不与这一切作斗争。如果您想要无窗口控件,请采用 Internet Explorer 路线并构建您自己的容器控件来容纳它们,以便您可以继续掌控其中发生的所有事情。

你的容器可以是一个 VCL 控件,但你放在它上面的东西可能不能——它们仍然期望使用 VCL 焦点和键盘处理规则。请注意,您也不能将普通的 Windows 控件放入 Internet Explorer 中。您放置在那里的任何内容都需要通过特定的 ActiveX 接口。也许您也需要接口,或者您可以创建自己的一组控制类,这些类源自您设计的与容器一起使用的某些特殊祖先类。不要从TGraphicControl开始;它在 VCL 中过于根深蒂固,无法用作分支控制库的基础。

这将是一项繁重的工作,但话又说回来,Internet Explorer 也是如此。

It's futile to build windowless controls and fit them into Delphi's VCL framework.

You bring up Internet Explorer as an example. But in that case, it's entirely in charge of everything that resides on it. It has its own internal notion of what the active control is, but think about what it looks like from the outside: It's just one giant control. When you ask the OS what has focus, the single browser control has it, no matter which of the browser's subcontrols appears to have focus.

When you press Tab, it looks to the OS as though the browser has simply consumed a tab character, just like edit controls do. Edit controls move the cursor over a few spaces and add tab characters to their internal buffers; browser controls move the cursor to another region of the display.

You're thinking of doing all this on a Delphi TForm. Delphi forms already have a framework for managing the active control and handling keystrokes, and you're going to have to fight it all. If you want windowless controls, go the Internet Explorer route and build your own container control to hold them so that you can remain in charge of everything that happens inside it.

Your container can be a VCL control, but the things you put on it probably can't — they'll still be expecting to use the VCL focus- and keyboard-handling rules. Notice how you can't put ordinary Windows controls in Internet Explorer, either. Anything you put there needs to go through specific ActiveX interfaces. Maybe you'll need interfaces, too, or maybe you can just make your own set of control classes that descend from some special ancestor class you design to work with your container. Don't start with TGraphicControl; it's too entrenched in the VCL to be usable as the basis for your offshoot control library.

It will be a lot of work, but then again, so was Internet Explorer.

ま柒月 2024-08-29 18:17:23

是的,这是徒劳的。
这不是 Delphi 的错,你只是在与 Windows 本身作斗争。
如果您需要一个行为类似于窗口控件的控件,请使用窗口控件。
你是对的,尝试从头开始重新创建窗口控件的整个 API 堆栈是一件痛苦的事情。

Yes, it is futile.
And it's not Delphi's fault, you're just fighting Windows itself.
If you need a control that behaves like a windowed control, use a windowed one.
And you're right, trying to recreate the whole API stack of windowed controls from scratch is a pain.

靖瑶 2024-08-29 18:17:23

是的,你差不多已经弄清楚了。使用无窗口控件意味着您将失去 Windows 可以为您提供的一切帮助。在一个实际的窗口上放置多个以上的窗口是很痛苦的。

Yup, you pretty much have it figured out. Using windowless controls means that you lose everything Windows can do to help you. Having more than a couple on a single actual window is pain.

时光病人 2024-08-29 18:17:23

这些程序中的大多数很可能最初不是使用 RAD 类型的工具开发的,因此别无选择,只能重新发明轮子。 Delphi 的最大优势之一是深入的 VCL 和第 3 方组件支持,可提供您想要的外观。

我非常成功地使用了一项技术来减少基于复杂(税务准备)表单的应用程序中使用的窗口句柄数量,该技术是在画布上绘制文本,并将单个 TCustomEdit 后代移动到用户正在编辑的位置。捕获 TAB/向上/向下键并将编辑移动到适当的位置非常简单。我们发现的挑战是在鼠标悬停区域周围绘制一个热矩形。我们最终得到了 TObject 的网格数组,其中数组元素为 nil(无字段)、TLIst(网格包含多个字段)或包含字段描述符的类。这减少了我们必须执行的范围检查量,因为该框更有可能只包含一个字段,或最多 4 个字段。

Most of these programs were most likely not originally developed using RAD type tools so had no choice but to re-invent the wheel. One of the largest advantages of Delphi is the deep VCL and 3rd party component support to provide the look you desire.

One technique that I have used with great success to reduce the amount of window handles used in a complex (tax preparation) form based application was to draw the text on a canvas, and moved a single TCustomEdit decendant to the position the user was editing. It was trivial to capture the TAB/Up/Down keys and move the edit to the appropriate position. The challenge we discovered was in drawing a hot rectangle around the mouse hovered field. We ended up with a grid array of TObject, where the array element would be nil (no field), a TLIst (grid contains multiple fields) or a a class that contained our field descriptor. This reduced the amount of range checks we had to perform since it was more likely that the box only contained a single field, or at most 4 fields.

月亮是我掰弯的 2024-08-29 18:17:23

我不知道你的问题到底是什么,但我认为这段历史可能是相关的……

我们有一个需要填写十几个表格的申请表。用户可以填写附加表格,也可以更改应用程序本身填写的值。

现在,在我们的第一个实现中,我们为每个输入字段使用窗口组件,以便这些字段可以接收焦点和输入。事实证明这是一个大问题,因为所有这些窗口都占用了大量资源。

现在,我们为每个输入字段提供了无窗口控件。这意味着我们最终得到的只是表单及其输入字段的组合图。当用户在绘图内部单击或使用某些击键来移动/设置焦点时,我们会为单击的字段创建一个新的窗口控件。当用户移动到下一个输入字段时,我们销毁第一个窗口,并创建一个新窗口。这样我们就只有一个窗口控件,这再次给我们带来了很好的速度提升。

再说一遍 - 我不知道你真正想要管理什么。 TWinControl 是 TWinControl 是有原因的,但可能有一个解决方案可以满足你想要的,无论那是什么......

I have no idea of what your problem really is, here, but I think this little history may be relevant...

We have an application which fills out a dozen forms. The user may fill out additional forms, and also change values filled out by the application it self.

Now, in our first implementation, we used windowed components for every single input field, so that the fields could receive focus and input. That turned out to be a big problem, because all this windows took a lot of resources.

We now have windowless controls for every input field. That means that all we end up with, is a combined drawing of the form and its input fields. When the user clicks inside the drawing, or uses some keystrokes to move/set focus, we create a new windowed control for the clicked field. When the user moves to the next input field, we destroy the first window, and create a new one. This way we only have one windowed control which again gave us a nice speed improvement.

Again - I have no idea of what you really want to manage. TWinControl is a TWinControl for a reason, but there may be a solution to what you want, what ever that would be...

鼻尖触碰 2024-08-29 18:17:23

fpGUI Toolkit 是您想要的示例。源代码库中最新的fpGUI代码是基于多窗口设计的。这个简单意味着每个小部件/组件都有一个窗口句柄,但 Windows 或 Linux 对该窗口不执行任何操作,除了基本通知消息(mouseenter、mouseexit 等)之外。 fpGUI 仍然可以完全控制每个组件的去向、它们是否可聚焦、它们的外观等。fpGUI 中的一些小部件/组件也是非窗口组件。例如:TfpgScrollbar、TfpgMainMenu、ComboBox 中的按钮等。

如果您想要一个真正的非窗口版本,则意味着只有一个具有窗口句柄的顶级窗口,该窗口内的所有其他小部件/组件实际上并不存在于操作系统中(它们没有窗口句柄),那么 fpGUI 也可以提供帮助。 fpGUI Toolkit最初的设计就是基于这样的设计。再次在源代码存储库中查找 v0.4 代码分支。在设计中,fpGUI 必须处理所有事情,创建 mouseenter/mouseleave 事件、转换容器组件的坐标系统、处理(假)组件焦点状态等......是的,初始设计需要大量工作,但随后你有一个非常可移植的框架,也可以轻松应用于其他操作系统。

是的,fpGUI 完全以 Object Pascal 语言实现,使用 Free Pascal 编译器为我提供跨平台支持。目前,fpGUI 可在 Windows、Linux(32 和 64 位)、Windows Mobile 和嵌入式 Linux (ARM) 设备上运行。

fpGUI Toolkit is an example of what you want. The latest fpGUI code in the source code repository is based on a multi-windowed design. That simple means every widget/component has a window handle, but Windows or Linux does nothing with that window, other that basic notification messages (mouseenter, mouseexit, etc). fpGUI still has full control over where each component goes, if they are focusable, how they look etc. Some widgets/components in fpGUI are non-windowed components too. eg: TfpgScrollbar, TfpgMainMenu, the button in a ComboBox etc.

If you want a true non-windowed version, mean there is only one top-level window that has a window handle, all other widgets/components inside that window doesn't actually exist to the OS (they have no window handles), then fpGUI can help too. The initial design of fpGUI Toolkit was based on such a design. Again, look in the source code repository for the v0.4 branch of code. I that design, fpGUI had to handle absolutely everything, creating mouseenter/mouseleave events, translate co-ordinate systems for container components, handle (fake) component focus states etc... Yes the initial design is a LOT of work, but then you have a very portable framework which can easily be applied to other OSes too.

And yes, fpGUI is fully implemented in the Object Pascal language using the Free Pascal compiler to give me cross-platform support. Currently fpGUI runs on Windows, Linux (32 & 64-bit), Windows Mobile and Embedded Linux (ARM) devices.

手心的温暖 2024-08-29 18:17:23

我认为 fgGUI 可能会帮助你。

请先检查其 Wiki

我认为您可以在 Delphi 中的应用程序中使用这个框架,因为它完全是用 Pascal 编写的。实际上它是基于 FreePascal ;)

HTH

I think fgGUI may help you out.

Do check its Wiki first.

I think you can use this framework for your application in Delphi as it is written totally in Pascal. Actually it is based on FreePascal ;)

HTH

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文