Delphi:如何在外部应用程序上正确使用ShowWindow
发布时间:2020-12-15 10:11:30 所属栏目:大数据 来源:网络整理
导读:参见英文答案 How can I make the second instance of my program pass control back to the first instance?1个 See also: 07001 我在启动应用程序之前使用以下代码,以检查是否有另一个实例 它已经开始了: var _PreviousHandle : THandle;begin _PreviousH
|
参见英文答案 >
How can I make the second instance of my program pass control back to the first instance?1个
我在启动应用程序之前使用以下代码,以检查是否有另一个实例 var _PreviousHandle : THandle;
begin
_PreviousHandle := FindWindow('TfrmMainForm',nil);
if _PreviousHandle <> 0 then
begin
ShowMessage('Application "" is already running!');
SetForegroundWindow(_PreviousHandle);
ShowWindow(_PreviousHandle,SW_SHOW);
Application.Terminate;
Exit;
end;
...
但是,如果它已经启动,我需要显示该应用程序.问题是以这种方式显示最小化按钮不再起作用,当我单击任务栏中的图标时,它“取消最小化”,并且显示的动画就像它被最小化一样.我错过了什么吗?是否有一种适当的方式来激活和显示外部应用程序,同时它被最小化? 解决方法
这是一个完整的项目,它只运行一个应用程序实例,并且应该将已运行的实例窗口带到前面.
您可以下载 Project1.dpr program Project1;
uses
Forms,Windows,Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
Mutex: THandle;
const
AppID = '{0AEEDBAF-2643-4576-83B1-8C9422726E98}';
begin
MessageID := RegisterWindowMessage(AppID);
Mutex := CreateMutex(nil,False,AppID);
if (Mutex <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) then
begin
PostMessage(HWND_BROADCAST,MessageID,0);
Exit;
end;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1,Form1);
Application.Run;
end.
Unit1.pas unit Unit1;
interface
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StrUtils,StdCtrls;
type
TForm1 = class(TForm)
private
function ForceForegroundWindow(WndHandle: HWND): Boolean;
function ForceRestoreWindow(WndHandle: HWND; Immediate: Boolean): Boolean;
protected
procedure WndProc(var AMessage: TMessage); override;
end;
var
Form1: TForm1;
MessageID: UINT;
implementation
{$R *.dfm}
{ TForm1 }
function TForm1.ForceForegroundWindow(WndHandle: HWND): Boolean;
var
CurrThreadID: DWORD;
ForeThreadID: DWORD;
begin
Result := True;
if (GetForegroundWindow <> WndHandle) then
begin
CurrThreadID := GetWindowThreadProcessId(WndHandle,nil);
ForeThreadID := GetWindowThreadProcessId(GetForegroundWindow,nil);
if (ForeThreadID <> CurrThreadID) then
begin
AttachThreadInput(ForeThreadID,CurrThreadID,True);
Result := SetForegroundWindow(WndHandle);
AttachThreadInput(ForeThreadID,False);
if Result then
Result := SetForegroundWindow(WndHandle);
end
else
Result := SetForegroundWindow(WndHandle);
end;
end;
function TForm1.ForceRestoreWindow(WndHandle: HWND;
Immediate: Boolean): Boolean;
var
WindowPlacement: TWindowPlacement;
begin
Result := False;
if Immediate then
begin
WindowPlacement.length := SizeOf(WindowPlacement);
if GetWindowPlacement(WndHandle,@WindowPlacement) then
begin
if (WindowPlacement.flags and WPF_RESTORETOMAXIMIZED) <> 0 then
WindowPlacement.showCmd := SW_MAXIMIZE
else
WindowPlacement.showCmd := SW_RESTORE;
Result := SetWindowPlacement(WndHandle,@WindowPlacement);
end;
end
else
Result := SendMessage(WndHandle,WM_SYSCOMMAND,SC_RESTORE,0) = 0;
end;
procedure TForm1.WndProc(var AMessage: TMessage);
begin
inherited;
if AMessage.Msg = MessageID then
begin
if IsIconic(Handle) then
ForceRestoreWindow(Handle,True);
ForceForegroundWindow(Application.Handle);
end;
end;
end.
在OS版本上测试: > Windows 8.1 64位 已知问题和限制: >根本没有考虑MainFormOnTaskbar;此时必须设置为True (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
