Gord P 14 Posted October 9 I guess I have always assumed that is the case and code accordingly. I made an extremely simple program and couldn't get the event to fire a second time, so it seems right but may not have captured all scenarios. The constructor for sure only gets called once, but some things are not accessible at the time the constructor is called if I recall correctly. Share this post Link to post
corneliusdavid 218 Posted October 9 Not necessarily. If you hide the form, then show it again later, the OnShow event will get fired again. Basically, calling Show or ShowModal when the form is hidden or manually toggling the Visible property (which is what Show and Hide do) will trigger the OnShow event. Attached is a sample project to demonstrate. OnShowTest.zip Share this post Link to post
Gord P 14 Posted October 9 Thanks. (I don't have Delphi, but I got the gist from the code). I guess I should have been more explicit. The main form will not be programmatically hidden (i.e. the main form's Visible property will not be set to false, and its Hide() method will not be called). I was just wondering if something in Windows could trigger an OnShow event even if I don't trigger one intentionally myself. Simply minimizing and restoring doesn't trigger it. I don't know if there is something else that might. I don't think so, but was just wondering. Share this post Link to post
corneliusdavid 218 Posted October 9 26 minutes ago, Gord P said: The main form will not be programmatically hidden (i.e. the main form's Visible property will not be set to false, and its Hide() method will not be called). In that case, it's reasonable to expect it will only be called once. What I see a lot of people do to make certain code is only called once is to set a boolean flag to False in OnCreate, then in OnActivate, check that flag, and if false, set it to true and do your one-time code. That way, even if some future part of your program decides to hide the form, you won't have to worry that your code is executed more than once. 28 minutes ago, Gord P said: I was just wondering if something in Windows could trigger an OnShow event As far as I know, no. 28 minutes ago, Gord P said: Simply minimizing and restoring doesn't trigger it. Correct. Share this post Link to post
Uwe Raabe 2061 Posted October 9 9 hours ago, Gord P said: some things are not accessible at the time the constructor is called if I recall correctly Can you be more explicit, what these some things may be? Share this post Link to post
Anders Melander 1802 Posted October 9 10 minutes ago, Uwe Raabe said: Can you be more explicit, what these some things may be? The properties that are calculated/updated on demand when the form or its controls are shown comes to mind. For example the position/size of aligned controls. Share this post Link to post
ConstantGardener 31 Posted October 9 8 hours ago, corneliusdavid said: In that case, it's reasonable to expect it will only be called once. What I see a lot of people do to make certain code is only called once is to set a boolean flag to False in OnCreate, then in OnActivate, check that flag, and if false, set it to true and do your one-time code. That way, even if some future part of your program decides to hide the form, you won't have to worry that your code is executed more than once. As far as I know, no. Correct. I think the onShow is also triggert if you change the VCL.Skin in your program? Share this post Link to post
Uwe Raabe 2061 Posted October 9 (edited) 1 hour ago, Anders Melander said: The properties that are calculated/updated on demand when the form or its controls are shown comes to mind. For example the position/size of aligned controls. But the OnShow event is called before the position and size of the form are set. Thus OnResize is called after OnShow. Edited October 9 by Uwe Raabe Share this post Link to post
corneliusdavid 218 Posted October 9 50 minutes ago, ConstantGardener said: I think the onShow is also triggert if you change the VCL.Skin in your program? Yes, you're right. Good point. 1 Share this post Link to post
Gord P 14 Posted October 9 3 hours ago, Uwe Raabe said: Can you be more explicit, what these some things may be? I was afraid someone might ask me to clarify that so I went through some older code hoping to find comments I left behind in the constructor or the OnShow event that might have explained where I ran into problems previously. Alas, my commenting skills are gradually getting better, but started from a weak place. I *think* I ran into issues with either (or both) some UI stuff that wasn't created yet for some reason and/or calling a function. I could totally be wrong here, but I just remember having some issues at some point a while back. I suppose the thing to do, would be to try it in the constructor again and see if anything arises during the build because for sure the constructor only gets called once. Share this post Link to post
Gord P 14 Posted October 9 1 hour ago, ConstantGardener said: I think the onShow is also triggert if you change the VCL.Skin in your program? Good to know. Thanks. 1 Share this post Link to post
Anders Melander 1802 Posted October 9 3 hours ago, Uwe Raabe said: But the OnShow event is called before the position and size of the form are set. Thus OnResize is called after OnShow. You asked about "things not accessible at the time the constructor is called" which is what I addressed. I can't see how the workings of OnShow and OnResize is relevant to that. Share this post Link to post
FredS 138 Posted October 11 On 10/9/2024 at 7:02 AM, ConstantGardener said: I think the onShow is also triggert if you change the VCL.Skin in your program? I believe OnShow is also fired when a form is recreated, skin change is one of those, but the OS can trigger it as well. Share this post Link to post
Anders Melander 1802 Posted October 11 22 minutes ago, FredS said: the OS can trigger it as well. How? Share this post Link to post
FredS 138 Posted October 11 1 minute ago, Anders Melander said: How? Changing OS Text size was one I remember. Share this post Link to post
Anders Melander 1802 Posted October 11 8 minutes ago, FredS said: Changing OS Text size was one I remember. If you mean the, undocumented, TextScaleFactor setting then no, that doesn't do it. Share this post Link to post
FredS 138 Posted October 11 3 minutes ago, Anders Melander said: If you mean the, undocumented, TextScaleFactor setting then no, that doesn't do it. Well the documentation language is always MAY 'Recreate the Window', so your mileage may vary. Think some API like SetWindowPos and MoveWindow have that, I know I ran into it while switching desktops via API.. Simpler just to add a FirstShown Property. Share this post Link to post
Anders Melander 1802 Posted October 11 5 minutes ago, FredS said: Well the documentation language is always MAY 'Recreate the Window', so your mileage may vary. Think some API like SetWindowPos and MoveWindow have that, I know I ran into it while switching desktops via API.. I don't believe this is true at the Windows API level; AFAIK Windows will not destroy a window handle unless you tell it to do so. But as you know, the VCL on the other hand will do so if it needs to change some attributes that can only be set by CreateWindow(Ex). Share this post Link to post
Remy Lebeau 1420 Posted October 11 1 hour ago, Anders Melander said: But as you know, the VCL on the other hand will do so if it needs to change some attributes that can only be set by CreateWindow(Ex). The VCL has a habit of recreating a whole window even if CreateWindow/Ex() is not actually required. Many UI attributes can actually be updated dynamically via SetWindowLong/Ptr() or control-specific APIs, but the VCL doesn't do things that way in most cases (sometimes it does). Share this post Link to post
pyscripter 694 Posted October 11 2 hours ago, FredS said: Simpler just to add a FirstShown Property. First statement in my FormShow method. // Do not execute again OnShow := nil; 1 Share this post Link to post
FredS 138 Posted October 11 1 hour ago, pyscripter said: First statement in my FormShow method. // Do not execute again OnShow := nil; A boolean value turned out to be better because at times there are things that should be run OnShow v. OnFirstShow.. Share this post Link to post
Uwe Raabe 2061 Posted October 12 9 hours ago, FredS said: A boolean value turned out to be better because at times there are things that should be run OnShow v. OnFirstShow.. Even that can be handled with initially wiring FormFirstShow with OnShow and inside wiring the regular FormShow. Not that I am actually promoting this approach, but I am neither a friend of these Run-Once-Booleans cluttering a class declaration. Share this post Link to post
DenkDirNix 0 Posted October 12 Searching the VCL-Sources via "CM_SHOWINGCHANGED" leads to procedure "Vcl.Controls.TWinControl.UpdateControlState". That one is called for example when changing the Parent of a TForm. The attached list of procedures calling "UpdateControlState", produced by my Reference-Tool, is only as picture available, sorry . You find the callers names in bold on the right side... Share this post Link to post
FredS 138 Posted October 12 6 hours ago, Uwe Raabe said: Even that can be handled with initially wiring FormFirstShow with OnShow and inside wiring the regular FormShow. Not that I am actually promoting this approach, but I am neither a friend of these Run-Once-Booleans cluttering a class declaration. Which what I ended up doing in a base form. Still that single bit boolean is a quick fix if needed. Share this post Link to post