- So, I have an application that loads different plugins and creates a new tab on a TPageControl for each one.
- Each DLL has a TForm associated with it.
- The forms are created with their parent hWnd as the new TTabSheet.
Since the TTabSheets aren't a parent of the form as far as VCL is concerned (didn't want to use dynamic RTL, and plugins made in other languages) I have to handle resizes manually. I do this like below:
var ChildHandle : DWORD; begin If Assigned(pcMain.ActivePage) Then begin ChildHandle := FindWindowEx(pcMain.ActivePage.Handle, 0, 'TfrmPluginForm', nil); If ChildHandle > 0 Then begin SetWindowPos(ChildHandle, 0, 0, 0, pcMain.ActivePage.Width, pcMain.ActivePage.Height, SWP_NOZORDER + SWP_NOACTIVATE + SWP_NOCOPYBITS); end; end;
Now, my problem is that when the application is resized, all the TGroupBoxes and the TLabels inside the TGroupBoxes flicker. The TLabels that are not inside TGroupboxes are fine and don't flicker.
Things I've tried:
- WM_SETREDRAW followed by a RedrawWindow
- ParentBackground on the TGroupBoxes and TLabels set to False
- DoubleBuffer := True
- LockWindowUpdate (Yes, even though I know it's very very wrong)
- Transparent := False (even overriding create to edit ControlState)
Any ideas?
The only thing I have found to work well is to use the
WS_EX_COMPOSITED
window style. This is a performance hog so I only enable it when in a sizing loop. It is my experience that, with the built-in controls, in my app, flickering only occurs when resizing forms.You should first perform a quick test to see if this approach will help you by simply adding the
WS_EX_COMPOSITED
window style to all your windowed controls. If that works you can consider the more advanced approach below:Quick hack
Call this, for example, in the
OnShow
for yourTForm
, passing the form instance. If that helps then you really should implement it more discerningly. I give you the relevant extracts from my code to illustrate how I did that.Full code
This won't compile for you, but it should contain some useful ideas.
ControlEnumerator
is my utility to turn a recursive walk of the child controls into a flatfor
loop. Note that I also use a custom splitter that calls BeginSizing/EndSizing when it is active.Another useful trick is to use
TStaticText
instead ofTLabel
which you occasionally need to do when you have deep nesting of page controls and panels.I've used this code to make my app 100% flicker free but it took me ages and ages of experimenting to get it all in place. Hopefully others can find something of use in here.