Can a TFrame be made to float outside the main form, i.e. make the desktop its parent? I tried setting Parent to nil and ParentWindow to the GetDesktopWindow but it remains invisible. Is this related to TFrame not being the same as a TForm? I've never quite understood the difference..
/sub
ReplyDeleteIs there a reason why you cannot place the TFrame on a borderless form? Would that not give you the same behaviour without having to resort to more complicated solutions?
ReplyDeleteI use frames because it works better when their parent is the main form. When dragging on/off the main form (making them "float") I'd need to dynamically add/remove the form. It's possible, but I prefer to avoid it if there is an easy answer to my question. You say the solution is complicated, does that mean you know why setting the ParentWindow does not work?
ReplyDeleteFor me, reframing requires setting Owner as well as Parent - does that help?
ReplyDeleteOn second thought - that alone won't help at all. You would need to create a new form and your frame on that form.
ReplyDeleteDockable forms tutorial.
ReplyDeleteyoutube.com - Delphi Programming Tutorial #32 - Dockable Forms
Yeah, that works (but now I cannot drag the frame any more). I guess this is one of those areas where a form and frame differ a lot. Thanks.
ReplyDeleteThanks Lars Fosdal , please note I have no issue doing this with forms, the question was if I can do it with frames without using a form (and break existing functionality).
ReplyDeleteI do not specifically know why it does not work, save to say that a TFrame ultimately is designed to be used in conjunction with a form or another frame. This leads me to consider that without being placed on a parent form or frame it may not paint its controls as one would expect. Perhaps tracing through your code and into the library code would help you determine why it is not painting.
ReplyDeleteI guess what I am saying is that to make it work, you could well face a steep learning curve, so my suggestion was see if you could consider another option.
On facebook you just drop a thank you video into the comment and you're done. On G+ I need to post a public video to youtube first, and then link to it here.
ReplyDeleteyoutube.com - VidBlasterX 170220142649
Looks good. Glad to hear you found a way to make it work.
ReplyDeleteMike Versteeg Or share it here directly from YouTube.
ReplyDeleteWhen I create the form you see a brief flash. I cannot seem to find a way to create the form and position it correctly without making it visible first, which draws it at (0,0). So in slomo you would see the empty form appear in the top-left corner, then it moves to the right position, and then the frame is painted over it. Works fine, looks less pro. Any ideas how to avoid the flash?
ReplyDeleteMike Versteeg Would it be possible to override the paint routine for the form and disable paint until it is in the right position? You would probably have to do some extra message trickery to handle borders and tool bar painting (non-client area).
ReplyDeleteYou can't make a frame be a top level window. It needs to be parented.
ReplyDeleteDavid Heffernan Should that read "parented"?
ReplyDeleteLars Fosdal I would think keeping it invisible would do that, but apparently that disables everything. I'll look into your suggestion, thanks.
ReplyDeleteI tried locking the form's canvas, Perform(WM_SETREDRAW..) and SendMessage(..WM_SETREDRAW..), none of those help. Only solution that sort of works is LockWindowUpdate() as it does delay any drawing until the frame is reparented and ready to be painted on the right spot, but it causes my entire main window to flash (repaint) when I unlock.
ReplyDeleteLockWindowUpdate is the most promising, but unfortunately it only postpones all paints, it does not prevent the ones I want to skip.
Possibly something you have already thought about, but does changing the double buffering setting for the different controls make any difference?
ReplyDeleteIt's not the flashing of controls on the form that is the problem, but the creation of the form and the fact you cannot position it before it is made visible. So when you create it, it is first drawn at 0,0 before you can position it correctly. No doubt there'llbe some issues after that, but at least they would be in-place, not somewhere else.
ReplyDeleteI am using Delphi 10.1 and if I create a standard VCL forms project, two forms (Unit2 and Unit3, TForm2 and TForm3 respectively, TForm2 being the main form), If I create a single button on TForm2 with the following event code, it works for me with no flicker.
ReplyDeleteprocedure TForm2.Button1Click(Sender: TObject);
var
f: TForm3;
begin
f := TForm3.Create(Self);
DoubleBuffered := True;
f.DoubleBuffered := True;
f.Parent := Self;
f.Show;
f.top := random(100);
f.left := random(100);
SetFocus;
end;
The initial DoubleBuffererd := True should be in the form create, but I just put it here for speed. What happens if you do the same?
Your form will be painted at 0,0 when you call Show, then move to a random position. You may not notice it as this is a very light app and probably happen too fast, but it does happen. Setting DoubleBuffered has no effect on this problem.
ReplyDeleteYou may well be right. I have not observed any repainting and without doublebuffered being set I did see the repainting that you mention.
ReplyDeleteIt's really quite odd you cannot set left & top when the form isn't yet visible. Not sure if that is by design or some bug.
ReplyDeleteYou can. I have done some tracing. It looks as though a TForm's default show code will attempt to reposition and resize the form depending on the properties set for Position and DefaultMonitor. Try setting the DefaultMonitor to dmDesktop and Position to poDefaultSizeOnly. Then resize the form after the show. Ensure that the child form is also double buffered. I have tried this with around 50 controls on the child form, including a large image and it certainly appears to be OK for me.
ReplyDeleteThe alternative would be to create your own TForm descendent that overrides this awkward behaviour and sets the properties correctly and at the right time.
Indeed, that fixes the issue! Thank you!
ReplyDeleteExcellent. Glad to have helped.
ReplyDelete