win32: replace the code which moved the focus to the last focused window on application activate with the search of the top window (active stay on top windows always win), move code which restored the last active window on application activation to LCL

git-svn-id: trunk@35504 -
This commit is contained in:
paul 2012-02-20 09:24:42 +00:00
parent 2f4158711d
commit 8fc49926d2
4 changed files with 54 additions and 6 deletions

View File

@ -1424,6 +1424,7 @@ procedure TApplication.Activate;
begin
if AppActive in FFlags then exit;
Include(FFlags, AppActive);
Screen.RestoreLastActive;
NotifyActivateHandler;
end;

View File

@ -2012,8 +2012,14 @@ begin
begin
if (Window = Win32WidgetSet.AppHandle) then
begin
if not IsIconic(Window) and IsWindow(WindowLastFocused) then
SetFocus(WindowLastFocused);
// if application window is still focused then move the focus
// to the next top window
if not IsIconic(Window) and (GetFocus = Window) then
begin
TargetWindow := LookupTopWindow(Window);
if TargetWindow <> Window then
SetFocus(TargetWindow);
end;
Result := 0;
Exit;
end;
@ -2026,9 +2032,7 @@ begin
{$endif}
// move focus to another application window but process event first
if (Window = Win32WidgetSet.AppHandle) then
PostMessage(Window, CM_ACTIVATE, 0, 0)
else
WindowLastFocused := Window;
PostMessage(Window, CM_ACTIVATE, 0, 0);
// handle feature mouse-click, setfocus, mouse-click -> double-click
if (Window <> MouseDownWindow) and (MouseDownFocusStatus <> mfNone) then
begin

View File

@ -274,7 +274,6 @@ var
MouseDownWindow: HWND = 0;
MouseDownFocusWindow: HWND;
MouseDownFocusStatus: TMouseDownFocusStatus = mfNone;
WindowLastFocused: HWND = 0;
ComboBoxHandleSizeWindow: HWND = 0;
IgnoreNextCharWindow: HWND = 0; // ignore next WM_(SYS)CHAR message
// set to true, if we are redirecting a WM_MOUSEWHEEL message, to prevent recursion

View File

@ -94,6 +94,7 @@ procedure RemoveStayOnTopFlags(AppHandle: HWND; ASystemTopAlso: Boolean = False)
procedure RestoreStayOnTopFlags(AppHandle: HWND);
procedure HidePopups(AppHandle: HWND);
procedure RestorePopups;
function LookupTopWindow(AppHandle: HWND): HWND;
procedure AddToChangedMenus(Window: HWnd);
procedure RedrawMenus;
@ -133,6 +134,12 @@ type
AppHandle: HWND;
OwnersList: TFPList;
end;
PLookupTopWindowInfo = ^TLookupTopWindowInfo;
TLookupTopWindowInfo = record
AppHandle: HWND;
TopWindow: HWND;
end;
TWindowsVersion = (
wvUnknown,
@ -909,6 +916,43 @@ begin
end;
end;
function EnumLookupTopWindow(Handle: HWND; Param: LPARAM): WINBOOL; stdcall;
begin
Result := True;
if IsWindowVisible(Handle) and IsWindowEnabled(Handle) then
begin
with PLookupTopWindowInfo(Param)^ do
begin
if (Handle = AppHandle) or (Handle = TopWindow) then
Exit;
if GetWindowLong(Handle, GWL_EXSTYLE) and WS_EX_TOPMOST <> 0 then
begin
// we've found the top most window => stop
TopWindow := Handle;
Result := False;
end
else
if TopWindow = 0 then
TopWindow := Handle;
end;
end;
end;
function LookupTopWindow(AppHandle: HWND): HWND;
var
Info: PLookupTopWindowInfo;
begin
New(Info);
Info^.AppHandle := AppHandle;
Info^.TopWindow := 0;
EnumThreadWindows(GetWindowThreadProcessId(AppHandle, nil),
@EnumLookupTopWindow, LPARAM(Info));
Result := Info^.TopWindow;
if Result = 0 then
Result := AppHandle;
Dispose(Info);
end;
{-------------------------------------------------------------------------------
procedure AddToChangedMenus(Window: HWnd);