浏览代码

Bug 1527: Windows logo key is not working in toolbar input boxes

https://winscp.net/tracker/1527

Source commit: 440d20a270839f6369f68a30bad674340f73b9f1
Martin Prikryl 8 年之前
父节点
当前提交
3dc4f19c0a
共有 2 个文件被更改,包括 36 次插入14 次删除
  1. 4 0
      source/packages/tb2k/TB2ExtItems.pas
  2. 32 14
      source/packages/tb2k/TB2Item.pas

+ 4 - 0
source/packages/tb2k/TB2ExtItems.pas

@@ -881,8 +881,12 @@ begin
       ActiveWnd := 0;
 
     FEditControlStatus := [ecsContinueLoop];
+    // During modal state of the toolbar, Windows logo key is not working.
+    // It should be fixed more generically, but here we fix it at least for the most obvious case (= while in edit box)
+    TTBModalHandler.UnlockForegroundWindow;
     ControlMessageLoop;
   finally
+    TTBModalHandler.LockForegroundWindow;
     S := FEditControl.Text;
     FreeAndNil(FEditControl);
   end;

+ 32 - 14
source/packages/tb2k/TB2Item.pas

@@ -882,6 +882,10 @@ type
       AFromMSAA, TrackRightButton: Boolean);
     property RootPopup: TTBPopupWindow read FRootPopup write FRootPopup;
     property Wnd: HWND read FWnd;
+
+    class procedure DoLockForegroundWindow(LockCode: Cardinal);
+    class procedure LockForegroundWindow;
+    class procedure UnlockForegroundWindow;
   end;
 
 function ProcessDoneAction(const DoneActionData: TTBDoneActionData;
@@ -5915,11 +5919,6 @@ var
 constructor TTBModalHandler.Create(AExistingWnd: HWND);
 begin
   inherited Create;
-  if not LockSetForegroundWindowInited then begin
-    LockSetForegroundWindow := GetProcAddress(GetModuleHandle(user32),
-      'LockSetForegroundWindow');
-    InterlockedExchange(Integer(LockSetForegroundWindowInited), Ord(True));
-  end;
   LastPos := SmallPointToPoint(TSmallPoint(GetMessagePos()));
   if AExistingWnd <> 0 then
     FWnd := AExistingWnd
@@ -5927,23 +5926,42 @@ begin
     FWnd := {$IFDEF JR_D6}Classes.{$ENDIF} AllocateHWnd(WndProc);
     FCreatedWnd := True;
   end;
-  if Assigned(LockSetForegroundWindow) then begin
-    { Like standard menus, don't allow other apps to steal the focus during
-      our modal loop. This also prevents us from losing activation when
-      "active window tracking" is enabled and the user moves the mouse over
-      another application's window. }
-    LockSetForegroundWindow(LSFW_LOCK);
-  end;
+  { Like standard menus, don't allow other apps to steal the focus during
+    our modal loop. This also prevents us from losing activation when
+    "active window tracking" is enabled and the user moves the mouse over
+    another application's window. }
+  LockForegroundWindow;
   SetCapture(FWnd);
   SetCursor(LoadCursor(0, IDC_ARROW));
   NotifyWinEvent(EVENT_SYSTEM_MENUSTART, FWnd, OBJID_CLIENT, CHILDID_SELF);
   FInited := True;
 end;
 
-destructor TTBModalHandler.Destroy;
+class procedure TTBModalHandler.DoLockForegroundWindow(LockCode: Cardinal);
 begin
+  if not LockSetForegroundWindowInited then begin
+    LockSetForegroundWindow := GetProcAddress(GetModuleHandle(user32),
+      'LockSetForegroundWindow');
+    InterlockedExchange(Integer(LockSetForegroundWindowInited), Ord(True));
+  end;
+  { Should always, as supported since Windows 2000 }
   if Assigned(LockSetForegroundWindow) then
-    LockSetForegroundWindow(LSFW_UNLOCK);
+    LockSetForegroundWindow(LockCode);
+end;
+
+class procedure TTBModalHandler.LockForegroundWindow;
+begin
+  DoLockForegroundWindow(LSFW_LOCK);
+end;
+
+class procedure TTBModalHandler.UnlockForegroundWindow;
+begin
+  DoLockForegroundWindow(LSFW_UNLOCK);
+end;
+
+destructor TTBModalHandler.Destroy;
+begin
+  UnlockForegroundWindow;
   if FWnd <> 0 then begin
     if GetCapture = FWnd then
       ReleaseCapture;