L
laozhongcheng
Unregistered / Unconfirmed
GUEST, unregistred user!
关于Delphi Application Normalization(Delphi程序标准化) 熟悉VCL和Win32的朋友,请帮忙改进一下代码。多谢! (200分)<br />下面的代码是将Delphi程序中Application在任务栏上面的按钮去除,同时用Form的按钮
替代。我把这个成为Delphi Application Normalization(Delphi程序标准化)
但是,在测试过程中碰到一个问题难以解决,就是如果当时显示了Modal Dialog,
那么点击任务栏上面的按钮将会短暂激活Form,并且Modal Dialog将会失去焦点。
这个问题看起来关系不大,但是如果使用Delphi提供的Win32通用对话框组件,
在对话框弹出的时候,也同样会使当前在Main Form之前的对话框消失,要用Alt+Tab切换
才会重新出现。熟悉VCL和Win32的朋友,请帮忙改进一下代码。多谢!
大家测试的时候将Delphi生成的Form从TForm改成从这个类派生就可以了。
unit CompXPForm;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms;
type
TCompXPForm = class (TForm)
private
{ Private declarations }
FPreventToolWindowToBeMainForm : Boolean;
// Events
FOnMinimize : TNotifyEvent;
FOnRestore : TNotifyEvent;
procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
protected
{ Protected declarations }
procedure CreateParams(var Params: TCreateParams); override;
property PreventToolWindowToBeMainForm : Boolean
read FPreventToolWindowToBeMainForm write FPreventToolWindowToBeMainForm
stored True default True;
// Events
property OnMinimize : TNotifyEvent read FOnMinimize write FOnMinimize
stored True;
property OnRestore : TNotifyEvent read FOnRestore write FOnRestore
stored True;
public
constructor Create(AOwner: TComponent); override;
{ Public declarations }
published
{ Published declarations }
end;
implementation
constructor TCompXPForm.Create(AOwner: TComponent);
begin
inherited;
if ( Application.MainForm <> nil) and ( Self <> Application.MainForm) and
(Self.FormStyle <> fsMDIChild) then
SetParent ( Application.MainForm);
end;
procedure TCompXPForm.CreateParams(var Params: TCreateParams);
begin
inherited;
if ( Application.MainForm = nil) or ( Self = Application.MainForm) then
begin
SetWindowLong ( Application.Handle, GWL_EXSTYLE,
GetWindowLong (Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
if FPreventToolWindowToBeMainForm then
Params.ExStyle := Params.ExStyle and (not WS_EX_TOOLWINDOW);
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;
Params.Style := Params.Style and (not WS_CHILDWINDOW);
end;
procedure TCompXPForm.WMSysCommand(var Message: TWMSysCommand);
begin
if (Message.CmdType and $FFF0 = SC_MINIMIZE) and
(Application.MainForm = Self) then
begin
if not IsIconic ( Handle) then
begin
Application.NormalizeTopMosts;
SetActiveWindow(Handle);
if (Application.MainForm <> nil) and (Application.ShowMainForm or
Application.MainForm.Visible) and IsWindowEnabled ( Handle) then
begin
SetWindowPos( Handle, Application.MainForm.Handle,
Application.MainForm.Left, Application.MainForm.Top,
Application.MainForm.Width, 0, SWP_SHOWWINDOW);
DefWindowProc( Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;
end;
if Assigned ( FOnMinimize) and ( not (csDesigning in ComponentState)) then
FOnMinimize (Self);
end
else if (Message.CmdType and $FFF0 <> SC_MOVE) or
(csDesigning in ComponentState) or (Align = alNone) or
(WindowState = wsMinimized) then
inherited;
if ((Message.CmdType and $FFF0 = SC_MINIMIZE) or
(Message.CmdType and $FFF0 = SC_RESTORE)) and
not (csDesigning in ComponentState) and (Align <> alNone) then
RequestAlign;
if ( Message.CmdType and $FFF0 = SC_RESTORE) and Assigned ( FOnRestore)
and ( not (csDesigning in ComponentState)) then
FOnRestore (Self);
end;
end.
替代。我把这个成为Delphi Application Normalization(Delphi程序标准化)
但是,在测试过程中碰到一个问题难以解决,就是如果当时显示了Modal Dialog,
那么点击任务栏上面的按钮将会短暂激活Form,并且Modal Dialog将会失去焦点。
这个问题看起来关系不大,但是如果使用Delphi提供的Win32通用对话框组件,
在对话框弹出的时候,也同样会使当前在Main Form之前的对话框消失,要用Alt+Tab切换
才会重新出现。熟悉VCL和Win32的朋友,请帮忙改进一下代码。多谢!
大家测试的时候将Delphi生成的Form从TForm改成从这个类派生就可以了。
unit CompXPForm;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Forms;
type
TCompXPForm = class (TForm)
private
{ Private declarations }
FPreventToolWindowToBeMainForm : Boolean;
// Events
FOnMinimize : TNotifyEvent;
FOnRestore : TNotifyEvent;
procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
protected
{ Protected declarations }
procedure CreateParams(var Params: TCreateParams); override;
property PreventToolWindowToBeMainForm : Boolean
read FPreventToolWindowToBeMainForm write FPreventToolWindowToBeMainForm
stored True default True;
// Events
property OnMinimize : TNotifyEvent read FOnMinimize write FOnMinimize
stored True;
property OnRestore : TNotifyEvent read FOnRestore write FOnRestore
stored True;
public
constructor Create(AOwner: TComponent); override;
{ Public declarations }
published
{ Published declarations }
end;
implementation
constructor TCompXPForm.Create(AOwner: TComponent);
begin
inherited;
if ( Application.MainForm <> nil) and ( Self <> Application.MainForm) and
(Self.FormStyle <> fsMDIChild) then
SetParent ( Application.MainForm);
end;
procedure TCompXPForm.CreateParams(var Params: TCreateParams);
begin
inherited;
if ( Application.MainForm = nil) or ( Self = Application.MainForm) then
begin
SetWindowLong ( Application.Handle, GWL_EXSTYLE,
GetWindowLong (Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
if FPreventToolWindowToBeMainForm then
Params.ExStyle := Params.ExStyle and (not WS_EX_TOOLWINDOW);
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;
Params.Style := Params.Style and (not WS_CHILDWINDOW);
end;
procedure TCompXPForm.WMSysCommand(var Message: TWMSysCommand);
begin
if (Message.CmdType and $FFF0 = SC_MINIMIZE) and
(Application.MainForm = Self) then
begin
if not IsIconic ( Handle) then
begin
Application.NormalizeTopMosts;
SetActiveWindow(Handle);
if (Application.MainForm <> nil) and (Application.ShowMainForm or
Application.MainForm.Visible) and IsWindowEnabled ( Handle) then
begin
SetWindowPos( Handle, Application.MainForm.Handle,
Application.MainForm.Left, Application.MainForm.Top,
Application.MainForm.Width, 0, SWP_SHOWWINDOW);
DefWindowProc( Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;
end;
if Assigned ( FOnMinimize) and ( not (csDesigning in ComponentState)) then
FOnMinimize (Self);
end
else if (Message.CmdType and $FFF0 <> SC_MOVE) or
(csDesigning in ComponentState) or (Align = alNone) or
(WindowState = wsMinimized) then
inherited;
if ((Message.CmdType and $FFF0 = SC_MINIMIZE) or
(Message.CmdType and $FFF0 = SC_RESTORE)) and
not (csDesigning in ComponentState) and (Align <> alNone) then
RequestAlign;
if ( Message.CmdType and $FFF0 = SC_RESTORE) and Assigned ( FOnRestore)
and ( not (csDesigning in ComponentState)) then
FOnRestore (Self);
end;
end.