问题描述
我正在考虑用Delphi的表单设计器代替旧的自定义表单设计器。我们的应用程序使用了一个自定义程序来生成可用于我们自己的报表编写器的表单。维护旧应用程序很困难,将Delphi用于表单设计器似乎是一个不错的选择。使用这种形式的应用程序也是用Delphi编写的,但是这些形式实际上并不会显示为真实形式,我们只是遍历各个组件并生成报告。
I am looking at replacing an old custom form designer with Delphi's form designer. Our application used a custom program for generating forms that could be used our own report writer. It is difficult to maintain the old application and using Delphi for the form designer seems to be a good option. The application that uses this forms is also written in Delp but these forms will not actually be displayed as real forms, we will just iterate through the components and generate our report.
当前表单设计器的功能之一是邻居列表。邻居列表跟踪表单上每个单元格的下一个顶部,底部,右侧和左侧单元格。在设计阶段保存表单时,旧设计师会更新此列表。
One of the features of the current form designer is a "neighbors list". The neighbors list keeps track of the next top, bottom, right, and left cell for every cell on the form. The old designer updates this list when the form is saved during the design phase.
我需要非常容易地跟踪地图到您的典型控件属性(位置,高度,宽度等)。我不知道如何在dfm中生成和保存这种类型的邻居信息。
Everything else I need to keep track of maps very easily to your typical control properties (position, height, width, etc.). I can't figure out how to generate and save this type of neighbor information in the dfm.
在设计时,窗体上的组件是否有任何方法可以在窗体上的任何内容发生更改时触发事件?还是保存表单时发生了什么事?
Is there any way for a component on a form, at design time, to get an event fired when anything on the form changes? Or an event when the form is saved?
我想过两种解决方法
1)将邻居信息保留在每个单独的控件中。那样就可以了,但是仍然有一个问题,那就是在移动窗体上的其他控件时,如果我无法获得一个让我知道何时更新的事件,则该同步将不同步。
I have thought about two approaches to the problem1) Keep the neighbor information in each individual control. That will kind of work, but still has the problem of getting out of sync when other controls on the form are moved unless I can get an event that let's me know when to update.
2)具有一个不可见的组件,它只能跟踪列表。我可以添加一个自定义属性编辑器页面,该页面上具有更新按钮,可以重新生成列表,但是随后我需要记住单击该按钮,然后保存最终版本。我可以看到错过了这一步,宁愿会有一些可以正常工作的东西。
2) Have a non-visual component that just keeps track of the list. I could add a custom property editor page that has and "update" button on it that would regenerate the list, but then I would need to remember to click that before the final version was saved. I can see that step being missed and would rather have something that just works.
我还可以更改应用程序以在运行时动态查找邻居,但是我希望可以找到一种使其在设计时起作用的方法。
I could also change the application to dynamically find the neighbors at runtime, but I was hoping I could find a way to make it work at design time.
任何版本的Delphi的解决方案都可以。
A solution for any version of Delphi would work.
对于为什么这是一个坏主意的任何评论也将不胜感激,因为我没有100%地说服自己这是正确的方法。 :-)
Any comments as to why this is a bad idea in general will also be appreciated as I have not convinced myself 100% that this is the right approach. :-)
推荐答案
创建新的TForm后代并覆盖 DefineProperties
用于在流式处理过程中加载和保存列表的功能。 MarcoCantù在他的中介绍了添加新设计时间表单的详细信息。 ,但您可能只需要在Register过程中调用 RegisterCustomModule
就可以逃脱。
Create a new TForm descendant and override the DefineProperties
function to load and save the list as part of the streaming process. Marco Cantù covers the details for adding new design time forms in his Delphi Developer's Handbook, but you can probably get away with just calling RegisterCustomModule
in your Register procedure.
或者,您可以创建 TApplicationEvents
对象(AppEvnts.pas),分配一个 OnMessage
处理程序,并观察任何 WM_SIZE
消息。然后,您可以使用 FindControl
来获取该消息所针对的TWinControl,并检查它是否是您的表单的父项。确保您在此处执行的任何过滤都是快速的,因为OnMessage将看到整个IDE的每条消息。
Alternatively you could create a TApplicationEvents
object (AppEvnts.pas), assign an OnMessage
handler, and watch for any WM_SIZE
messages. You can then use FindControl
to get the TWinControl that the message is for and check to see if it's parented to your form. Make sure whatever filtering you do here is fast, since OnMessage will see every message for the entire IDE.
这篇关于移动表单上的其他组件时更新自定义组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!