瀏覽代碼

Bug 1727: Failure when starting GUI

https://winscp.net/tracker/1727

Source commit: f3096a73ba80657f7bce396c5e1fc7553970c6a9
Martin Prikryl 6 年之前
父節點
當前提交
c08a3e7c02
共有 3 個文件被更改,包括 24 次插入7 次删除
  1. 7 2
      source/packages/filemng/CustomDirView.pas
  2. 13 5
      source/packages/my/PasTools.pas
  3. 4 0
      source/windows/WinMain.cpp

+ 7 - 2
source/packages/filemng/CustomDirView.pas

@@ -520,6 +520,8 @@ function CompareLogicalTextPas(const S1, S2: string; NaturalOrderNumericalSortin
 
 function OverlayImageList(Size: Integer): TImageList;
 
+procedure InitFileControls;
+
 var
   StdDirIcon: Integer;
   StdDirSelIcon: Integer;
@@ -569,12 +571,15 @@ begin
   end;
 end; {GetshFileInfo}
 
-procedure InitGlobals;
+procedure InitFileControls;
 begin
   if not GlobalsInitialized then
   begin
     GlobalsInitialized := True;
 
+    // See the comment in the call from Execute()
+    NeedShellImageLists;
+
     // Calling GetshFileInfo in Windows Session 0 sometime cause crash
     // (not immediately, but very shortly afterwards [few ms]).
     // So this code was moved from initialization section to avoid it
@@ -786,7 +791,7 @@ end;
 
 constructor TCustomDirView.Create(AOwner: TComponent);
 begin
-  InitGlobals;
+  InitFileControls;
 
   inherited;
 

+ 13 - 5
source/packages/my/PasTools.pas

@@ -66,6 +66,7 @@ function GetSystemMetricsForControl(Control: TControl; nIndex: Integer): Integer
 type
   TImageListSize = (ilsSmall, ilsLarge);
 
+procedure NeedShellImageLists;
 function ShellImageListForControl(Control: TControl; Size: TImageListSize): TImageList;
 
 function ControlHasRecreationPersistenceData(Control: TControl): Boolean;
@@ -486,6 +487,7 @@ var
   Height, Width: Integer;
   ShellImageList: TImageList;
   SHGetImageList: TSHGetImageList;
+  HR: HRESULT;
 begin
   Lib := LoadLibrary('shell32');
   SHGetImageList := GetProcAddress(Lib, 'SHGetImageList');
@@ -493,7 +495,8 @@ begin
   for ImageList := 0 to SHIL_LAST do
   begin
     // VCL have declaration for SHGetImageList in ShellAPI, but it does not link
-    if (SHGetImageList(ImageList, IID_IImageList, Pointer(Handle)) = S_OK) and
+    HR := SHGetImageList(ImageList, IID_IImageList, Pointer(Handle));
+    if (HR = S_OK) and
        ImageList_GetIconSize(Handle, Width, Height) then
     begin
 
@@ -511,6 +514,14 @@ begin
   end;
 end;
 
+procedure NeedShellImageLists;
+begin
+  if ShellImageLists = nil then
+  begin
+    InitializeShellImageLists;
+  end;
+end;
+
 function ShellImageListForControl(Control: TControl; Size: TImageListSize): TImageList;
 var
   ImageListPair: TPair<Integer, TImageList>;
@@ -518,10 +529,7 @@ var
   Diff, BestDiff: Integer;
 begin
   // Delay load image lists, not to waste resources in console/scripting mode
-  if ShellImageLists = nil then
-  begin
-    InitializeShellImageLists;
-  end;
+  NeedShellImageLists;
 
   case Size of
     ilsSmall: Width := 16;

+ 4 - 0
source/windows/WinMain.cpp

@@ -964,6 +964,10 @@ int __fastcall Execute()
       }
 
       WinConfiguration->CheckDefaultTranslation();
+      // Loading shell image lists here (rather than only on demand when file controls are being created)
+      // reduces risk of an occasional crash.
+      // It seems that the point is to load the lists before any call to SHGetFileInfoWithTimeout.
+      InitFileControls();
 
       if (!Params->Empty)
       {