不用MDI方式,如何能让背景主窗体总是在本程序最底?
用SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_NOACTIVATE + SWP_NOSENDCHANGING); 会变成所有程序最底,效果不好。
也不能把其他窗体设为总在最前来解决,还有其他办法吗?
用SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_NOACTIVATE + SWP_NOSENDCHANGING); 会变成所有程序最底,效果不好。
也不能把其他窗体设为总在最前来解决,还有其他办法吗?
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
CommFrm, ActnList, ImgList, ResChange;type
TfrmStayOnTop = class(TForm)
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FMoved: boolean;
newProc: pointer;
oldProc: pointer;
procedure OwnerWndProc(var Message: TMessage);
//procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
//procedure WMMove(var Message: TMessage); message WM_MOVE;
protected
class function CanMultiInstance: boolean; virtual;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
end;const
MM_CUSTOMMESSAGE = WM_USER+1076;implementationconst
MM_PROCCHANGE = WM_USER + 127;{$R *.DFM}{ TfrmStayOnTop }constructor TfrmStayOnTop.Create(AOwner: TComponent);
var
a: integer;
begin
if not (AOwner is TForm) then Raise Exception.Create('The Owner Must Be a Form');
a := Integer(ClassInfo);
if SendMessage(TWinControl(AOwner).handle, MM_CUSTOMMESSAGE, -$FF, a)=1 then
if not CanMultiInstance then
begin
abort;
end; inherited;
newProc := MakeObjectInstance(OwnerWndProc);
oldProc := Pointer(SetWindowLong(TWinControl(aOwner).handle, GWL_WNDPROC, integer(newProc)));
end;procedure TfrmStayOnTop.OwnerWndProc(var Message: TMessage);
begin
message.Result := CallWindowProc(oldProc, TWinControl(Owner).handle, message.Msg, message.WParam, message.LParam);
case message.Msg of
WM_WINDOWPOSCHANGED:
SetWindowPos(handle, PWINDOWPOS(message.lParam).hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_NOACTIVATE + SWP_NOSENDCHANGING);
WM_DESTROY:
//SendMessage(self.handle, WM_CLOSE, 0, 0);
Self.free;
MM_PROCCHANGE:
if oldProc = Pointer(Message.wParam) then
begin
oldProc := Pointer(Message.lParam);
Message.Result := 1;
end;
MM_CUSTOMMESSAGE:
if Message.WParam = -$FF then
if Message.LParam = Integer(ClassInfo) then
begin
SetWindowPos(handle, PWINDOWPOS(message.lParam).hwndInsertAfter, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_NOACTIVATE + SWP_NOSENDCHANGING);
Message.Result := 1;
end;
end;
end;procedure TfrmStayOnTop.FormDestroy(Sender: TObject);
begin
if SendMessage(TWinControl(Owner).handle, MM_PROCCHANGE, integer(newProc), integer(oldProc)) = 0 then
SetWindowLong(TWinControl(Owner).handle, GWL_WNDPROC, integer(oldProc));
inherited;
end;
{
procedure TfrmStayOnTop.CMShowingChanged(var Message: TMessage);
var
r, r1: TRect;
begin
if Showing then
begin
if not FMoved and (WindowState=wsNormal) then
begin
Windows.GetWindowRect(TWinControl(Owner).handle, r);
Windows.GetWindowRect(handle, r1);
Left := r.Right-(r1.Right-r1.left);
Top := r.bottom-(r1.bottom-r1.top);
end;
PubYSBZ.AnimateShowWindow(self);
ShowWindow(handle, SW_HIDE);
end
else
PubYSBZ.AnimateShowWindow(self, false);
FMoved := true;
inherited;
end;procedure TfrmStayOnTop.WMMove(var Message: TMessage);
begin
inherited;
end;
}
class function TfrmStayOnTop.CanMultiInstance: boolean;
begin
result := true;
end;end.