diff --git a/lcl/interfaces/win32/win32callback.inc b/lcl/interfaces/win32/win32callback.inc index a53d1190db..49b670453e 100644 --- a/lcl/interfaces/win32/win32callback.inc +++ b/lcl/interfaces/win32/win32callback.inc @@ -1006,6 +1006,8 @@ begin WinProcess := True; NotifyUserInput := False; + // WriteLn('Msg: ', WM_To_String(Msg)); + WindowInfo := GetWin32WindowInfo(Window); if WindowInfo^.isChildEdit then begin @@ -2207,15 +2209,15 @@ begin begin //WriteLn('Restore'); RestoreStayOnTopFlags(Window); - if assigned(Application) then - Application.IntfAppActivate; + if Assigned(Application) then + Application.IntfAppActivate; end else begin // deactivated //WriteLn('Remove'); RemoveStayOnTopFlags(Window); - if assigned(Application) then - Application.IntfAppDeactivate; + if Assigned(Application) then + Application.IntfAppDeactivate; end; end; end; diff --git a/lcl/interfaces/win32/win32proc.pp b/lcl/interfaces/win32/win32proc.pp index d2913dfca3..c82cc6daa0 100644 --- a/lcl/interfaces/win32/win32proc.pp +++ b/lcl/interfaces/win32/win32proc.pp @@ -99,8 +99,8 @@ function AllocWindowInfo(Window: HWND): PWin32WindowInfo; function DisposeWindowInfo(Window: HWND): boolean; function GetWin32WindowInfo(Window: HWND): PWin32WindowInfo; -procedure RemoveStayOnTopFlags(Window: HWND; ASystemTopAlso: Boolean = False); -procedure RestoreStayOnTopFlags(Window: HWND); +procedure RemoveStayOnTopFlags(AppHandle: HWND; ASystemTopAlso: Boolean = False); +procedure RestoreStayOnTopFlags(AppHandle: HWND); procedure HidePopups(AppHandle: HWND); procedure RestorePopups; @@ -132,6 +132,7 @@ procedure UpdateWindowsVersion; type PStayOnTopWindowsInfo = ^TStayOnTopWindowsInfo; TStayOnTopWindowsInfo = record + AppHandle: HWND; SystemTopAlso: Boolean; StayOnTopList: TList; end; @@ -903,7 +904,7 @@ var WindowInfo: PWin32WindowInfo; begin WindowInfo := PWin32WindowInfo(Windows.GetProp(Window, PChar(PtrUInt(WindowInfoAtom)))); - Result := Windows.RemoveProp(Window, PChar(PtrUInt(WindowInfoAtom)))<>0; + Result := Windows.RemoveProp(Window, PChar(PtrUInt(WindowInfoAtom))) <> 0; if Result then begin WindowInfo^.StayOnTopList.Free; @@ -920,76 +921,76 @@ end; function EnumStayOnTopRemove(Handle: HWND; Param: LPARAM): WINBOOL; stdcall; var - AStyle: DWord; StayOnTopWindowsInfo: PStayOnTopWindowsInfo absolute Param; lWindowInfo: PWin32WindowInfo; lWinControl: TWinControl; begin Result := True; - AStyle := GetWindowLong(Handle, GWL_EXSTYLE); - if (AStyle and WS_EX_TOPMOST) <> 0 then // if stay on top then + if ((GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_TOPMOST) <> 0) then begin // Don't remove system-wide stay on top, unless desired if not StayOnTopWindowsInfo^.SystemTopAlso then begin lWindowInfo := GetWin32WindowInfo(Handle); - if (lWindowInfo <> nil) then + if Assigned(lWindowInfo) then begin lWinControl := lWindowInfo^.WinControl; - if (lWinControl <> nil) and (lWinControl is TCustomForm) - and (TCustomForm(lWinControl).FormStyle = fsSystemStayOnTop) then + if Assigned(lWinControl) and + (lWinControl is TCustomForm) and + (TCustomForm(lWinControl).FormStyle = fsSystemStayOnTop) then Exit; end; end; StayOnTopWindowsInfo^.StayOnTopList.Add(Pointer(Handle)); - SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER or SWP_NOSENDCHANGING); end; end; -procedure RemoveStayOnTopFlags(Window: HWND; ASystemTopAlso: Boolean = False); +procedure RemoveStayOnTopFlags(AppHandle: HWND; ASystemTopAlso: Boolean = False); var StayOnTopWindowsInfo: PStayOnTopWindowsInfo; WindowInfo: PWin32WindowInfo; + I: Integer; begin - // WriteLn('RemoveStayOnTopFlags 1'); + //WriteLn('RemoveStayOnTopFlags ', InRemoveStayOnTopFlags); if InRemoveStayOnTopFlags = 0 then begin New(StayOnTopWindowsInfo); + StayOnTopWindowsInfo^.AppHandle := AppHandle; StayOnTopWindowsInfo^.SystemTopAlso := ASystemTopAlso; StayOnTopWindowsInfo^.StayOnTopList := TList.Create; - WindowInfo := GetWin32WindowInfo(Window); + WindowInfo := GetWin32WindowInfo(AppHandle); WindowInfo^.StayOnTopList := StayOnTopWindowsInfo^.StayOnTopList; - EnumThreadWindows(GetWindowThreadProcessId(Window, nil), + EnumThreadWindows(GetWindowThreadProcessId(AppHandle, nil), @EnumStayOnTopRemove, LPARAM(StayOnTopWindowsInfo)); + for I := 0 to WindowInfo^.StayOnTopList.Count - 1 do + SetWindowPos(HWND(WindowInfo^.StayOnTopList[I]), HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER or SWP_DRAWFRAME); Dispose(StayOnTopWindowsInfo); end; inc(InRemoveStayOnTopFlags); - // WriteLn('RemoveStayOnTopFlags 2'); end; -procedure RestoreStayOnTopFlags(Window: HWND); +procedure RestoreStayOnTopFlags(AppHandle: HWND); var WindowInfo: PWin32WindowInfo; I: integer; begin - // WriteLn('RestoreStayOnTopFlags 1'); + //WriteLn('RestoreStayOnTopFlags ', InRemoveStayOnTopFlags); if InRemoveStayOnTopFlags = 1 then begin - WindowInfo := GetWin32WindowInfo(Window); + WindowInfo := GetWin32WindowInfo(AppHandle); if WindowInfo^.StayOnTopList <> nil then begin for I := 0 to WindowInfo^.StayOnTopList.Count - 1 do SetWindowPos(HWND(WindowInfo^.StayOnTopList.Items[I]), HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER or SWP_NOSENDCHANGING); + SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER or SWP_DRAWFRAME); FreeAndNil(WindowInfo^.StayOnTopList); end; end; if InRemoveStayOnTopFlags > 0 then dec(InRemoveStayOnTopFlags); - // WriteLn('RestoreStayOnTopFlags 2'); end; function EnumHidePopups(Handle: HWND; Param: LPARAM): WINBOOL; stdcall; diff --git a/lcl/interfaces/win32/win32wsforms.pp b/lcl/interfaces/win32/win32wsforms.pp index b9ed85a37d..63e7a1821b 100644 --- a/lcl/interfaces/win32/win32wsforms.pp +++ b/lcl/interfaces/win32/win32wsforms.pp @@ -493,14 +493,15 @@ begin if (lWindowInfo <> nil) then begin lWinControl := lWindowInfo^.WinControl; - if (lWinControl <> nil) and (lWinControl is TCustomForm) - and (TCustomForm(lWinControl).FormStyle in fsAllStayOnTop) - and not (csDesigning in TCustomForm(lWinControl).ComponentState) then + if Assigned(lWinControl) and + (lWinControl is TCustomForm) and + (TCustomForm(lWinControl).FormStyle in fsAllStayOnTop) and + not (csDesigning in lWinControl.ComponentState) then list.Add(Pointer(Handle)); end; end; -procedure EnumStayOnTop(window: THandle; dstlist: TList); +procedure EnumStayOnTop(Window: THandle; dstlist: TList); begin EnumThreadWindows(GetWindowThreadProcessId(Window, nil), @EnumStayOnTopProc, LPARAM(dstlist)); @@ -508,9 +509,11 @@ end; class procedure TWin32WSCustomForm.SetFormStyle(const AForm: TCustomform; const AFormStyle, AOldFormStyle: TFormStyle); +const + WindowPosFlags = SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_NOOWNERZORDER; var - toplist : TList; - i : Integer; + toplist: TList; + i: Integer; begin // Some changes don't require RecreateWnd @@ -518,7 +521,7 @@ begin if (AOldFormStyle = fsNormal) and (AFormStyle in fsAllStayOnTop) then begin if not (csDesigning in AForm.ComponentState) then - SetWindowPos(AForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE) + SetWindowPos(AForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, WindowPosFlags) // From StayOnTop to normal end else @@ -546,12 +549,10 @@ begin toplist := TList.Create; try EnumStayOnTop(AForm.Handle, toplist); - SetWindowPos(AForm.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); + SetWindowPos(AForm.Handle, HWND_NOTOPMOST, 0, 0, 0, 0, WindowPosFlags); for i := 0 to toplist.Count - 1 do - begin if HWND(toplist[i]) <> AForm.Handle then - SetWindowPos(HWND(toplist[i]), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); - end; + SetWindowPos(HWND(toplist[i]), HWND_TOPMOST, 0, 0, 0, 0, WindowPosFlags); finally toplist.Free; end;