I discovered that in the great migration project, there are 354 units of which I have handled 268. Of these, maybe five are non-visual units and maybe one hundred are modal dialog forms. The rest - 168 so far - are forms defined as mdi child. The major problems that I have had to face so far were converting the database components1 and maintaining table indices2.
Until I came across unit Manage150. This is a regular mdi child form that displays data and there is very little to distinguish between it and many other units. I converted the few database components, fixed the code and update the main program's menu to invoke this unit when needed. I ran the program, clicked on the main menu ... and nothing happened. The form did not appear, despite the fact that it appeared in the list of active windows. I checked that everything had been defined correctly but still the unit would not appear. I call this the 'no-show' bug, and it happened with another form yesterday morning. What does CoPilot have to say about this?
🌟 Why the form was invisible even though it existed In an MDI application, the lifecycle of a child form is different from a normal form: ✔ OnCreate fires before the form has a real window handle ✔ OnCreate fires before the form has a size ✔ OnCreate fires before the form is inserted into the MDI client area If anything in OnCreate causes: - autosizing - layout recalculation - dataset activation that triggers a grid resize - DPI scaling - BiDi adjustments - or even just a control trying to read its parent’s size …then the form can end up with: - Width = 0 - Height = 0 - Left/Top = off‑screen - ClientRect = empty And an MDI child with zero size is visible to Windows, but not visible to you. That’s why it appeared in the Window menu but not on screen.
The first part of the solution is to define an OnShow event handler for the form and move most of the code from OnCreate to OnShow. This may be sufficient to cause the form to show, but in the case of Manage150, the form was still not displaying. What eventually causes the form to show are the following four lines in OnShow:
left:= 8; top:= 8; width:= 480; // according to the hard coded width height:= 320; // ditto
Once those lines have been added to OnShow then the form will display. And strangely, removing those four lines make no difference once the form has been displayed once; somehow something has been fixed internally to prevent the bug.
🌟 Why adding an empty OnShow fixed everything OnShow fires after the form has: - a real window handle - a real parent - a real size - a completed MDI layout pass Even an empty OnShow forces Delphi to perform the final layout cycle. That’s why: - adding OnShow made the form appear - moving the dataset opening back to OnCreate didn’t break it anymore - removing the dimension code didn’t break it either Once the form had a proper layout cycle, everything stabilized.
So if I have another case of a form not showing, I will know what to do.
Internal links
[1] 2087
[2] 2088
| Title | Tags | ||
|---|---|---|---|
| 163 | Left/right hemisperes of the brain | Psychology, The brain | |
| 691 | Research questionnaire / 4 | DBA | |
| 1734 | Introducing the Kobo | Kindle, Kobo | |
| 1913 | My (compulsory) army service - part five | Israel, Army service |
No comments:
Post a Comment