-5

I installed the new Delphi 10.2.2 Tokyo and started to move my projects over to it.

I found the following strange behavior in a Windows desktop application.

I have a Form with a size of 700x545. To prevent the user from resizing it, I use the OnCanResize event and set the Resize parameter to False.

In the OnCreate event, I set the desired Width/Height values. With Delphi 10.0 Seattle, it works well, but in 10.2.2 the size is set to 340x220 instead.

Obviously, it is set before the OnCreate event, because my changes in the OnCreate event are ignored, maybe because of my OnCanResize event.

In design time, I find the correct values in the Object Inspector.

Any ideas?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Christine Ross
  • 465
  • 5
  • 14
  • 1
    Why not make the form non-resizable by setting the `BorderStyle` properties and `BorderIcons` instead of responding to the `OnCanResize` event? Then set the form size in the IDE (you can also set the constraints if you are afraid you will accidentally resize the form in the IDE). Anyhow, are you using DPI scaling? – Andreas Rejbrand Jan 10 '18 at 20:24
  • Why do people insist on checking size when the form is created, *especially* when the form might be resized later? smh – Dave Nottage Jan 10 '18 at 23:49
  • You might have screwed some numbers here. The default size of a form is 320x240. – Uwe Raabe Jan 11 '18 at 07:46
  • @uwe raabe, Yes you are right 320 x 240 are the correct values – Christine Ross Jan 11 '18 at 13:30

2 Answers2

2

When a Form object is created, its underlying window can (and usually is) created during DFM streaming, before the OnCreate event is fired. So, it is possible for the Form to want to perform resize operations before you are ready for them. This has always been a possibility in all versions of Delphi, it is not new behavior in Tokyo.

If you are going to use the Form's OnCanResize event, you should make sure the Form object is fully constructed and initialized before you start setting the event's Resize parameter to False. For instance, add a Boolean member to your Form class and set it to True in the OnCreate event, then have the OnCanResize event set the Resize parameter to the opposite value of that Boolean.

Alternatively, instead of using the OnCanResize event, consider using the Form's Contraints property instead, or simply set the Form's BorderStyle property to a non-resizable style, like bsSingle or bsDialog. Either way will allow you to resize the Form in code while preventing the user from resizing the Form manually.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • When the DFM is loaded the properties are usually assigned before the events are assigned. This is controlled by the order of all properties in the published section. Thus the OnCanResize event should not yet be wired during loading of the DFM. – Uwe Raabe Jan 11 '18 at 07:30
  • Sorry, but I can't accept this as answer because it don't answer my question. I use the same code with Seattle and 10.2.2 and get different results. In Seattle the form comes up with the correct size, in 10.2.2 with the size 340 x 220. The DFM contains also the correct size of 700 x 545. There must be an action which overrides the dfm values with the default size 340 x 220. – Christine Ross Jan 11 '18 at 11:11
-2

Te difference between Seattle and 10.2.2 is following:

the oncanresize event is called twice before the oncreate event is called. The source comes from a TControl (i could not find out what control), the caller seems for me the ScaleforCurrentDPI procedure. In Seattle the oncanresize is never called before finishing the oncreate event.

For me it sounds like a bug when a onformdosomething event can be called before the oncreate event.

Christine Ross
  • 465
  • 5
  • 14
  • Have you thought about doing your magic in the OnShow event instead? – John Easley Jan 11 '18 at 20:44
  • Any wired event is called after the form is loaded whenever it is triggered. Why should the OnCreate event be special? If you don't want the OnCanResize handler being called during your OnCreate handler simply unwire it and rewire it when you finished your task. It would be quite confusing when events are fired only under some specific conditions. Seems you were just lucky with your code in Seattle. – Uwe Raabe Jan 11 '18 at 23:05
  • @uwe raabe: the oncreate event was special for me because it is the first event of a form. You call it loading, I would say creating, I'm wondering why you can call an other event before the object/form is created/exiting. – Christine Ross Jan 12 '18 at 10:38
  • As I said: the events are wired when the loading of the DFM is finished. This happens in the forms constructor. At the end of the loading process the method Loaded is called, which (for a form) calls ScaleForCurrentDpi. This is where the form size may be changed if the Design DPI and the current DPI differ. Later when all constructors have been executed (i.e. in AfterConstruction) the OnCreate event is fired. So it is not unlikely that some events may be fired before that. Perhaps it would have been better to name it AfterCreate instead of OnCreate. – Uwe Raabe Jan 12 '18 at 14:59