- improve RemoveStayOnTopFlags, RestoreStayOnTopFlags to prevent activation of window. Dont allow more than one remove without restore and vice versa.
- remove stay on top from application windows when application become inactive and restore them on activate (so stay on top windows are not on screen when application is inactive) (issue #0008471)

git-svn-id: trunk@12399 -
This commit is contained in:
paul 2007-10-10 00:46:31 +00:00
parent 286cd77dab
commit 892e6f172c
2 changed files with 35 additions and 19 deletions

View File

@ -1113,13 +1113,13 @@ begin
Assert(False, 'Trace:WindowProc - Checking Proc');
Assert(False, Format('Trace:WindowProc - Window Value: $%S-%d; Msg Value: %S; WParam: $%S; LParam: $%S', [IntToHex(Window, 4), Window, WM_To_String(Msg), IntToHex(WParam, sizeof(WParam)*4), IntToHex(LParam, sizeof(LParam)*4)]));
Case Msg Of
case Msg of
WM_ACTIVATE:
begin
Case LOWORD(WParam) Of
case LOWORD(WParam) Of
WA_ACTIVE, WA_CLICKACTIVE:
begin
LMessage.Msg := LM_ACTIVATE
LMessage.Msg := LM_ACTIVATE;
end;
WA_INACTIVE:
begin
@ -1131,17 +1131,22 @@ begin
begin
if Window = TWin32WidgetSet(WidgetSet).AppHandle then
begin
if WParam <> 0 then
if WParam <> 0 then // activated
begin
RestoreStayOnTopFlags(Window);
Windows.SetWindowPos(TWin32WidgetSet(WidgetSet).AppHandle, HWND_TOP,
0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
end
else
begin // deactivated
RemoveStayOnTopFlags(Window);
end;
// activate/deactivate main window
if (Application <> nil) and (Application.MainForm <> nil) and
Application.MainForm.HandleAllocated then
begin
CallDefaultWindowProc(Application.MainForm.Handle, WM_NCACTIVATE, WParam, 0);
CallDefaultWindowProc(Application.MainForm.Handle, WM_NCACTIVATE, WParam, LParam);
end;
end;
end;

View File

@ -172,6 +172,8 @@ uses
// {$DEFINE ASSERT_IS_ON}
{$ENDIF}
var
InRemoveStayOnTopFlags: Integer = 0;
{------------------------------------------------------------------------------
Function: WM_To_String
Params: WM_Message - a WinDows message
@ -1120,7 +1122,7 @@ begin
if (AStyle and WS_EX_TOPMOST) <> 0 then // if stay on top then
begin
StayOnTopWindowsInfo^.StayOnTopList.Add(Pointer(Handle));
SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
end;
end;
@ -1129,14 +1131,18 @@ var
StayOnTopWindowsInfo: PStayOnTopWindowsInfo;
WindowInfo: PWindowInfo;
begin
New(StayOnTopWindowsInfo);
StayOnTopWindowsInfo^.AppWindow := Window;
StayOnTopWindowsInfo^.StayOnTopList := TList.Create;
WindowInfo := GetWindowInfo(Window);
WindowInfo^.StayOnTopList := StayOnTopWindowsInfo^.StayOnTopList;
EnumThreadWindows(GetWindowThreadProcessId(Window, nil),
@EnumStayOnTopRemove, LPARAM(StayOnTopWindowsInfo));
Dispose(StayOnTopWindowsInfo);
if InRemoveStayOnTopFlags = 0 then
begin
New(StayOnTopWindowsInfo);
StayOnTopWindowsInfo^.AppWindow := Window;
StayOnTopWindowsInfo^.StayOnTopList := TList.Create;
WindowInfo := GetWindowInfo(Window);
WindowInfo^.StayOnTopList := StayOnTopWindowsInfo^.StayOnTopList;
EnumThreadWindows(GetWindowThreadProcessId(Window, nil),
@EnumStayOnTopRemove, LPARAM(StayOnTopWindowsInfo));
Dispose(StayOnTopWindowsInfo);
end;
inc(InRemoveStayOnTopFlags);
end;
procedure RestoreStayOnTopFlags(Window: HWND);
@ -1144,13 +1150,18 @@ var
WindowInfo: PWindowInfo;
I: integer;
begin
WindowInfo := GetWindowInfo(Window);
if WindowInfo^.StayOnTopList <> nil then
if InRemoveStayOnTopFlags = 1 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);
FreeAndNil(WindowInfo^.StayOnTopList);
WindowInfo := GetWindowInfo(Window);
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);
FreeAndNil(WindowInfo^.StayOnTopList);
end;
end;
if InRemoveStayOnTopFlags > 0 then
dec(InRemoveStayOnTopFlags);
end;