Updating a custom component when moving other components in a form

I am looking at replacing the old custom form constructor with the Delphi form constructor. Our application used a special program to create forms that could be used by our own report author. It's hard to maintain an old application and using Delphi for the form designer seems to be a good option. An application using these forms is also written in Delphi, but these forms will not actually be displayed as real forms, we will just iterate over the components and generate our report.

One of the features of the current form designer is the "neighbor list". The neighbor list keeps track of the next top, bottom, right, and left cells for each cell in the form. The old constructor updates this list when the form is saved at the design stage.

Everything else I need is very easy to track maps according to your typical control properties (position, height, width, etc.). I cannot figure out how to create and save neighbor type information in dfm.

Is there any way for a component on a form during development to have an event fire when something in the form changes? Or an event when the form is saved?

I thought of two approaches to the problem 1) Store the neighbor information in each separate control. It will be some kind of work, but there is still a problem of getting out of sync when other controls on the form move, if I cannot get an event that will tell me when to update.

2) Have a non-visual component that just keeps track of the list. I could add a page for the custom property editor, which also has a refresh button on it that will regenerate the list, but then I would not have to click on it before the final version is saved. I see that this step has been missed and would rather have something that just works.

I could also change the application to dynamically search for neighbors at runtime, but I was hoping I could find a way to make it work during development.

A solution for any version of Delphi will work.

Any comments as to why this is a bad idea in general will also be appreciated, as I have not 100% convinced myself that this is the right approach. :-)

+1
source share
2 answers

Create a new TForm descendant and override the DefineProperties function to load and save the list as part of the streaming process. Marco Cantu talks about the details of adding new development-time forms in his Delphi Developer Handbook , but you can probably avoid just calling RegisterCustomModule in your registration procedure.

Alternatively, you can create a TApplicationEvents object (AppEvnts.pas), assign an OnMessage handler OnMessage and monitor WM_SIZE messages. You can then use FindControl to get the TWinControl the message is for and check to see if it matches your form. Make sure that any filtering you do here is fast, because OnMessage will see every message for the entire IDE.

+3
source

Use the TComponent.Notification method. He called all components with a common owner when any of them was inserted or removed from its owner. You can also call FreeNotification to receive notifications about components with different owners.

For example, when the PopupMenu property PopupMenu set to a button, the button calls the method of the FreeNotification component. If the menu is later removed, it will call Notification on the button, and the button will clear its PopupMenu property, since it no longer refers to a valid object.

You can override Notification to track insertions and deletions. A more difficult task is to keep track of when the component moves, if you need to know something. Just because the component was your left neighbor when it was added does not mean that it will remain your left neighbor forever. (In fact, the position is probably not valid in all cases.) At the time of execution, the positions of the controls will probably not change, so if you have a way to detect the relative positions of the controls, the Loaded method is a good place to do this. This method is called after reading DFM and all properties of the components are set.

0
source

Source: https://habr.com/ru/post/1304586/


All Articles