Forms 像SendToBack这样的东西
大家好 我想在我的应用程序中将不同形式的工作模拟为不同的程序。Forms 像SendToBack这样的东西,forms,delphi,z-order,Forms,Delphi,Z Order,大家好 我想在我的应用程序中将不同形式的工作模拟为不同的程序。 所有表单在任务栏上都有自己的按钮,应用程序的mainform不可见,Application.ShowMainForm:=false。 但是如果我显示两个窗体,然后打开一些覆盖这两个窗体的程序,然后打开第一个窗体(第二个窗体在某些程序后面),然后关闭第一个窗体,第二个窗体在某些程序前面激活并恢复。 我知道它会恢复,因为在关闭第一个窗体后,我的应用程序会保持活动状态,这就是为什么会显示第一个可见窗体。如何防止恢复第二个表单?似乎我需要在
所有表单在任务栏上都有自己的按钮,应用程序的mainform不可见,Application.ShowMainForm:=false。
但是如果我显示两个窗体,然后打开一些覆盖这两个窗体的程序,然后打开第一个窗体(第二个窗体在某些程序后面),然后关闭第一个窗体,第二个窗体在某些程序前面激活并恢复。
我知道它会恢复,因为在关闭第一个窗体后,我的应用程序会保持活动状态,这就是为什么会显示第一个可见窗体。如何防止恢复第二个表单?似乎我需要在关闭后发送回我的应用程序,但我不知道如何发送 @大卫·赫弗南
这一切的背后其实是窗户。当你的一个朋友 窗体关闭时,Windows也必须决定将焦点移动到何处。 它选择将其移动到流程中的另一个顶级窗口, 因为有一个可见的存在。它通过发送窗口来实现这一点 它选择WM_SETFOCUS消息。毫无疑问,你能截获这个 阻止它发生 我曾试图在我的窗口上设置WM_SETFOCUS,但没有这样的消息
type
TfMyForm = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
FOldWindowProc: TWndMethod;
procedure NewWindowProc(var Message: TMessage);
end;
implementation
procedure TfMyForm.FormCreate(Sender: TObject);
begin
FOldWindowProc := WindowProc;
WindowProc := NewWindowProc;
end;
procedure TfMyForm.NewWindowProc(var Message: TMessage);
begin
if Message.Msg = WM_SETFOCUS then
Beep;
FOldWindowProc(Message);
end;
这是我自己找到的解决办法
procedure SwitchToPreviousWindow(AHandle: HWND);
var PrevWindow: HWND;
begin
PrevWindow := GetNextWindow(AHandle, GW_HWNDNEXT);
while PrevWindow <> NULL do
begin
if IsWindowVisible(PrevWindow) then
begin
SetForegroundWindow(PrevWindow);
Exit;
end;
PrevWindow := GetNextWindow(PrevWindow, GW_HWNDNEXT);
end;
end;
procedure TfMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SwitchToPreviousWindow(Self.Handle);
end;
过程切换到上一个窗口(AHandle:HWND);
var-PrevWindow:HWND;
开始
PrevWindow:=GetNextWindow(AHandle,GW\uHwnNext);
而PrevWindow NULL做什么
开始
如果IsWindowVisible(PrevWindow),则
开始
SetForegroundWindow(PrevWindow);
出口
终止
PrevWindow:=GetNextWindow(PrevWindow,GW\uHwnNext);
终止
终止
过程TfMyForm.FormClose(发送方:TObject;var操作:TCloseAction);
开始
切换到上一个窗口(自身手柄);
终止
这是我自己找到的解决方案
procedure SwitchToPreviousWindow(AHandle: HWND);
var PrevWindow: HWND;
begin
PrevWindow := GetNextWindow(AHandle, GW_HWNDNEXT);
while PrevWindow <> NULL do
begin
if IsWindowVisible(PrevWindow) then
begin
SetForegroundWindow(PrevWindow);
Exit;
end;
PrevWindow := GetNextWindow(PrevWindow, GW_HWNDNEXT);
end;
end;
procedure TfMyForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SwitchToPreviousWindow(Self.Handle);
end;
过程切换到上一个窗口(AHandle:HWND);
var-PrevWindow:HWND;
开始
PrevWindow:=GetNextWindow(AHandle,GW\uHwnNext);
而PrevWindow NULL做什么
开始
如果IsWindowVisible(PrevWindow),则
开始
SetForegroundWindow(PrevWindow);
出口
终止
PrevWindow:=GetNextWindow(PrevWindow,GW\uHwnNext);
终止
终止
过程TfMyForm.FormClose(发送方:TObject;var操作:TCloseAction);
开始
切换到上一个窗口(自身手柄);
终止
您是如何将任务栏按钮放在那里的?过程TfMyForm.CreateParams(var-Params:TCreateParams);开始继承CreateParams(参数);Params.ExStyle:=Params.ExStyle或WS_EX_APPWINDOW;Params.WndParent:=0;终止为什么要使用WS\u EX\u APPWINDOW
?当然,WndParent:=0
是这样做的。是的,我在前面的评论中回答了这个问题。抱歉,我不知道如何在注释中格式化代码。我将尝试SetWindowPos(…,HWND_BOTTOM…)
您是如何将任务栏按钮放在那里的?过程TfMyForm.CreateParams(var-Params:TCreateParams);开始继承CreateParams(参数);Params.ExStyle:=Params.ExStyle或WS_EX_APPWINDOW;Params.WndParent:=0;终止为什么要使用WS\u EX\u APPWINDOW
?当然,WndParent:=0
是这样做的。是的,我在前面的评论中回答了这个问题。对不起,我不知道如何在评论中格式化代码。我会尝试设置WindowPos(…,HWND_BOTTOM…)你是个天才。自问自答,你是个天才。自问自答。