Forum > LCL

Help with TFrame

(1/2) > >>

VTwin:
I am trying to understand how a TFrame works. Attached is a simple example project that does not work.

Any help is appreciated.

wp:
Frames are great components to split code out of an overcrowded unit into their own units. But when you are careless they can be quite nasty...

I confirm that in your example the paintbox OnPaint handler implemented in the frame is not executed. Opening the lfm file in an external editor I see that the instances Frame1_1 and Frame1_2 inserted into Form1 at designtime do have nil as OnPaint handlers. This is wrong - it should be the event handler inherited from the frame class, and since this is the default there should not be any OnPaint handler in the lfm for the frames in Form1. This happens too easily when you try to attach an event handler to frames' Paintbox and then change you mind and delete the handler in Form1 - no Frame1_1.Paintbox1 does not have an OnPaint handler any more! The same happens very easily with normal properties of the controls on the frame.

The only way to fix this is to delete the lines "OnPaint = nil" (of Frame1_1.Paintbox1 and Frame1_2.Paintbox) from the lfm in an external editor. You can do it in the IDE, too, when you right-click on the form in the designer and select "View source (.lfm)". But then you MUST reload the entire project to clear internal caches, and I think you must also do a "Run" > "Build".

See "frame1-wp.zip" (I took the freedom to change the OnPaint code of the frame's Paintbox a bit in order to show that something is happening when the checkbox is clicked).

You can avoid this hassle when you do not insert frames at designtime, but at runtime - see "frame1-wp-runtime.zip". This way the frame does not exist on the form at designtime, and there is absolutely no chance that you might want to click somewhere on the frame. However there an issue to be mentioned here, too: Frames created at runtime automatically get the name derived from the class - i.e. all instances of TFrame1 are named "Frame1_1" (I think this is a bug). And of course, the IDE does not like this when you add the same frame a second time! To avoid this give each inserted frame a unique name after creation, or, better, simply set it to an empty string.

VTwin:
Wow. Thanks for the working examples wp, they are invaluable. The example in the wiki does not address these complexities.

I hoped using frames might be simpler than my current method. I use the anchor editor to lay everything out at design time, and then attach the controls to a wrapper class which takes care of the painting. For my purposes, frames are not a simpler solution.

wp:

--- Quote from: VTwin on January 23, 2023, 04:02:38 pm ---The example in the wiki does not address these complexities.

--- End quote ---
Are you referring to this article: https://wiki.lazarus.freepascal.org/Frames ?


--- Quote from: VTwin on January 23, 2023, 04:02:38 pm ---For my purposes, frames are not a simpler solution.

--- End quote ---
Usually they are, in particular for complex forms with tabcontrols/notebooks and many groupboxes offering always the same logical functionality. Such forms usually have thousands of lines for the gui event handlers. When you move each tabsheet into a frame all the related event handlers go with it, and in the end only the essential code is left. Look at the TAChart sample project in components/tachart/demo/charteditor for a more complex example.

VTwin:
Yes.

I am sure there are numerous cases where they are very useful. In my case, it is just two or three controls, my solution would not work for more complex groups.

I will have a look at TAChart.

Thanks. 

Navigation

[0] Message Index

[#] Next page

Go to full version