PDA

View Full Version : Executing some code ater form has been Maximized or Restored?



SilverWarior
30-11-2011, 01:00 PM
Hi guys!
How can I run some code just after form has been Maximized or Restored?
I have a program wich uses Andora2D for drawing some graphics on one of the panels in my program. The panel changes it size acouring to size of the form itself. So to avoid Andora2D streching graphics by panel size changing I need to call AdDraw.Restore.
Now using forms OnResize event doesn't comes into option becouse it causes rapid cals to AdDraw.Restore when user is resizing form by draging form border. This causes a lot off lag and creates my whole application unstable.
Currently for resizing and moving form I use
WMExitSizeMove(var Message: TMessage); message WM_EXITSIZEMOVE to handle WM_EXITSIZEMOVE wich is fired just after the moving or resizing has been compleeted. But this message isn't fired when the form has been resized by Maximizing or Restoring it.
I found this article: http://delphi.about.com/cs/adptips1999/a/bltip0999_4.htm wich describes of how to handle Maximizing or Restoring forms, but it fires before any resizing is done so it isn't useful for me.

Andru
30-11-2011, 05:02 PM
Use

WMSize(var Message: TMessage); message WM_SIZE
And check inside for Message.wParam = SIZE_MAXIMIZED or Message.wParam = SIZE_RESTORED

User137
30-11-2011, 07:11 PM
Not sure if these help, but...

In Lazarus there is a component TApplicationProperties on Additional tab. (In Delphi it's TApplicationEvents maybe)
Has event such as onRestore.

Alternatively you can manually assign a event to Application.OnRestore

SilverWarior
30-11-2011, 09:00 PM
@Andru
Your code works but it is fired before actual form resizing is done so code then executes before the form has been resized. I need to execute code after the resizing is done. Also this way my code fires multiple times while user is resizing form by draging form's border.

@User137
Tapplication's OnRestore event is fired when an application is restored from minimized state and not when MainForm is restored from MaximizedState. So it is of no use to me.

Andru
01-12-2011, 06:07 AM
Your code works but it is fired before actual form resizing is done so code then executes before the form has been resized.
Hmm, then Delphi sucks... :) Because with pure WinAPI this message fire after real resize.

SilverWarior
01-12-2011, 07:26 PM
After some more indeph testing I belive that I found the reason why the code doesn't work as it should. The message is realy fired just after the form has been resized but before other components wich are placed on the form has been resized. So this means that when the message is fired my panel still hasn't been resized so this causes AdDraw.Restore not working properly.
So I would probably need to handle Panel resizing, but there I don't have option of detecting whether the form has been maximized, restored or just simply resized. Also this would mean that my code would be executed multiple times when users will be resizing fowm by draging it's border. So I would have to make some sort of mechanizem wich will be preventing that (probably handling WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE to set some custom variable to tel Panel's OnResize handler when it should execute AdDraw.Restore and when not.
Anywhay after I implement and thest this idea I will post sourcecode here becouse it might come in handy for manny pepole.

Andru
01-12-2011, 10:05 PM
When user resizing something Windows sends WM_SIZING, when resizing is done - it will send WM_SIZE. So, try to use this messages instead of even OnResize for AdDraw.Restore.

User137
03-12-2011, 03:00 PM
Now using forms OnResize event doesn't comes into option becouse it causes rapid cals to AdDraw.Restore when user is resizing form by draging form border. This causes a lot off lag and creates my whole application unstable.

I don't really understand the issue you are having. Aren't all graphics drawn in their timer or onIdle event? You basically want to accelerate drawing while mouse is resizing window? Could you handle this by simply ignoring framerate control in the onResize event. Meaning that in onResize event there would be no commands to drawing or restoring, but just a variable that toggles framerate control off until a frame has been rendered.

Also, whole reason that the component automatically resizes itself is because of alClient alignment property. If you set it alNone you can completely customize it.

SilverWarior
05-12-2011, 02:04 AM
Problem solverd!

First I must admit that I was approaching this slightly wrong. I was eagerly trying to handle form resizing while I needed to handle Panel resizing since Andora uses it as a drawing surface in my program.. So now I call AdDraw.Restore in panels OnResize event. And for avoidance of multiple cals of AdDraw.Restore I check IsFormResizing variable of Boolean type to see if the form is in resizing state. I set this variable to True or False by handling WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE.

So my code looks like this:

procedure TMainForm.WMEnterSizeMove(var Message: TMessage);
begin
IsFormResizing := True;
end;

procedure TMainForm.WMExitSizeMove(var Message: TMessage);
begin
AdDraw.Restore;
IsFormResizing := False;
end;

procedure TMainForm.MainViewResize(Sender: TObject);
begin
if not IsFormResizing then
begin
AdDraw.Restore;
end;
end;

@User137
The reason why I need to call AdDraw.Restore is that Andora 2D can adjust it's drawing routine to the new surface size becouse othervise all of the graphics would get streched.