lkovac
asked on
shortcut settings: start minimized
I'm trying to create Delphi 2.0 application which responds properly when started
with icons with Run: "Minimized" specified. And I just can't do it.
Borland's TI 2778 says about it this:
A: Delphi's Application object creates a hidden "application
window," and it is that window, rather than your main form,
that is being sent the command to show minimized. To fix this,
make your main form's OnCreate event handler look like this:
procedure TForm1.FormCreate(Sender: TObject);
{$IFDEF WIN32} { Delphi 2.0 (32 bit) }
var
MyInfo: TStartUpInfo;
{$ENDIF}
begin
{$IFDEF WIN32} { Delphi 2.0 (32 bit) }
GetStartUpInfo(MyInfo);
ShowWindow(Handle, MyInfo.wShowWindow);
{$ENDIF}
{$IFDEF WINDOWS} { Delphi 1.0 (16 bit) }
ShowWindow(Handle, cmdShow);
{$ENDIF}
end;
If I do this, TApplication and main form get out of sync. Application (i.e. the
icon in the toolbar) think the application is running restored (it has minimize
menu item enabled while restore is disabled). Main form is even worse. It is
"minimize-like" in the lower left corner of desktop, just over the toolbar, as
if it was MDI child of the desktop. I tried to put Application.Minimize call in
FormCreate or FormShow, but it doesn't make matters better.
I have an ugly "fix": at the end of FormCreate to post the message (minimize me)
if minimize flag is on in the shortcut. On response to the message I then
minimize the application. Result is that app starts normal and immediately after
minimizes. Looks ugly.
Does anyone know how to do it properly, or Borland guys just forgot about that
feature ?
Thank you in advance
with icons with Run: "Minimized" specified. And I just can't do it.
Borland's TI 2778 says about it this:
A: Delphi's Application object creates a hidden "application
window," and it is that window, rather than your main form,
that is being sent the command to show minimized. To fix this,
make your main form's OnCreate event handler look like this:
procedure TForm1.FormCreate(Sender: TObject);
{$IFDEF WIN32} { Delphi 2.0 (32 bit) }
var
MyInfo: TStartUpInfo;
{$ENDIF}
begin
{$IFDEF WIN32} { Delphi 2.0 (32 bit) }
GetStartUpInfo(MyInfo);
ShowWindow(Handle, MyInfo.wShowWindow);
{$ENDIF}
{$IFDEF WINDOWS} { Delphi 1.0 (16 bit) }
ShowWindow(Handle, cmdShow);
{$ENDIF}
end;
If I do this, TApplication and main form get out of sync. Application (i.e. the
icon in the toolbar) think the application is running restored (it has minimize
menu item enabled while restore is disabled). Main form is even worse. It is
"minimize-like" in the lower left corner of desktop, just over the toolbar, as
if it was MDI child of the desktop. I tried to put Application.Minimize call in
FormCreate or FormShow, but it doesn't make matters better.
I have an ugly "fix": at the end of FormCreate to post the message (minimize me)
if minimize flag is on in the shortcut. On response to the message I then
minimize the application. Result is that app starts normal and immediately after
minimizes. Looks ugly.
Does anyone know how to do it properly, or Borland guys just forgot about that
feature ?
Thank you in advance
ASKER
No, Eric, this doesn't work. I didn't try with Maximized, but that wsMinimized makes main form to create that ugly minimized window in lower left corner just over the taskbar (as if desktop was MDI parent for it) (at least on NT 4.0 it is doing that). My solution with posting user defined message is much better, I even improved it with Hiding (see following code), but there is still that ugly animation going first up then down... However, I still hope somebody has better solution (maybe even the hack to VCL source code) because with this problem how can one create commercial product with Delphi ?
Here is my code:
const
WM_MINIMIZE = WM_USER + 1;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
bMinimize: boolean;
procedure Minimize(var msg: TMessage); message WM_MINIMIZE;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
si: TStartupInfo;
begin
si.cb := SizeOf(TStartupInfo);
GetStartupInfo(si);
if ((SW_MINIMIZE = si.wShowWindow) or (SW_SHOWMINIMIZED = si.wShowWindow) or (SW_SHOWMINNOACTIVE = si.wShowWindow)) then
begin
bMinimize := True;
PostMessage(Handle, WM_MINIMIZE, 0, 0);
end
else
bMinimize := False;
end;
procedure TForm1.Minimize(var msg: TMessage);
begin
Application.Minimize;
bMinimize := False;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
if bMinimize then
Hide
else
if not Visible then
Show;
end;
Here is my code:
const
WM_MINIMIZE = WM_USER + 1;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
bMinimize: boolean;
procedure Minimize(var msg: TMessage); message WM_MINIMIZE;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
si: TStartupInfo;
begin
si.cb := SizeOf(TStartupInfo);
GetStartupInfo(si);
if ((SW_MINIMIZE = si.wShowWindow) or (SW_SHOWMINIMIZED = si.wShowWindow) or (SW_SHOWMINNOACTIVE = si.wShowWindow)) then
begin
bMinimize := True;
PostMessage(Handle, WM_MINIMIZE, 0, 0);
end
else
bMinimize := False;
end;
procedure TForm1.Minimize(var msg: TMessage);
begin
Application.Minimize;
bMinimize := False;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
if bMinimize then
Hide
else
if not Visible then
Show;
end;
This is how I did it successfully in Delphi 1.0. I haven't tried it in Delphi 2 yet, but I see no reason for it not to work
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowWindow(Handle, CmdShow);
{the rest of your program}
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowWindow(Handle, CmdShow);
{the rest of your program}
end;
ASKER
No, that doesn't work in Delphi 2.0 . Delphi 2.0 is completely different in this problem.
ASKER
Adjusted points to 200
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Great reply. Using your advice I was able to make it work. However, it
needed little bit more tweaking (regarding the animation when minimizing on
NT and making application aware of state (right click on icon on taskbar
should enable restore or minimize properly).
This is the solution for application which can be "normal" or minimized
(dialog main form). If it could be also maximized, solution would be much
more complicated. Here is the full solution:
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
const
WM_MINIMIZE = WM_USER + 1;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
bMinimize: boolean;
l, t: integer;
procedure Minimize(var msg: TMessage); message WM_MINIMIZE;
procedure WMMove(var Message: TWMMove); message WM_MOVE;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
si: TStartupInfo;
begin
l := Left;
t := Top;
si.cb := SizeOf(TStartupInfo);
GetStartupInfo(si);
if ((SW_MINIMIZE = si.wShowWindow) or (SW_SHOWMINIMIZED = si.wShowWindow) or (SW_SHOWMINNOACTIVE = si.wShowWindow)) then
begin
bMinimize := True;
MoveWindow(Handle, 3000, 3000, Width, Height, False);
PostMessage(Handle, WM_MINIMIZE, 0, 0);
end
else
bMinimize := False;
end;
procedure TForm1.Minimize(var msg: TMessage);
begin
if bMinimize then
ShowWindow(Application.Han dle, SW_HIDE);
Application.Minimize;
if bMinimize then
begin
bMinimize := False;
Left := l;
Top := t;
ShowWindow(Application.Han dle, SW_SHOWNA);
end;
end;
procedure TForm1.WMMove(var Message: TWMMove);
begin
if not bMinimize then
MoveWindow(Application.Han dle, Left, Top, Width, 0, False);
end;
end.
needed little bit more tweaking (regarding the animation when minimizing on
NT and making application aware of state (right click on icon on taskbar
should enable restore or minimize properly).
This is the solution for application which can be "normal" or minimized
(dialog main form). If it could be also maximized, solution would be much
more complicated. Here is the full solution:
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls;
const
WM_MINIMIZE = WM_USER + 1;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
bMinimize: boolean;
l, t: integer;
procedure Minimize(var msg: TMessage); message WM_MINIMIZE;
procedure WMMove(var Message: TWMMove); message WM_MOVE;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
si: TStartupInfo;
begin
l := Left;
t := Top;
si.cb := SizeOf(TStartupInfo);
GetStartupInfo(si);
if ((SW_MINIMIZE = si.wShowWindow) or (SW_SHOWMINIMIZED = si.wShowWindow) or (SW_SHOWMINNOACTIVE = si.wShowWindow)) then
begin
bMinimize := True;
MoveWindow(Handle, 3000, 3000, Width, Height, False);
PostMessage(Handle, WM_MINIMIZE, 0, 0);
end
else
bMinimize := False;
end;
procedure TForm1.Minimize(var msg: TMessage);
begin
if bMinimize then
ShowWindow(Application.Han
Application.Minimize;
if bMinimize then
begin
bMinimize := False;
Left := l;
Top := t;
ShowWindow(Application.Han
end;
end;
procedure TForm1.WMMove(var Message: TWMMove);
begin
if not bMinimize then
MoveWindow(Application.Han
end;
end.
Try a simple fix.... Set your FormStyle to wsMinimized, and then in OnCreate write something like this:
GetStartupInfo...
case MyInfo.wShowWindow of
SW_SHOW,
SW_SHOWNORMAL : Application.Restore;
SW_MAXMIMIZE : PostMessage(Application.Ha
SW_MINIMIZE : ; // Already minimized
end
You'll probably have to add some more of the warious SW_XXX constants in the case statement, but this would at least let you mimic proper startup behaviour.
Regards,
Erik.