Subversion Repositories userdetect2

Rev

Rev 72 | Rev 83 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit VTSCompat;
  2.  
  3. {$IF CompilerVersion >= 25.0}
  4. {$LEGACYIFEND ON}
  5. {$IFEND}
  6.  
  7. {$WARN UNSAFE_CODE OFF}
  8. {$WARN UNSAFE_TYPE OFF}
  9. {$WARN UNSAFE_CAST OFF}
  10.  
  11. interface
  12.  
  13. uses
  14.   Dialogs, Windows, Controls, Graphics, SysUtils, CommDlg, Classes;
  15.  
  16. function AddTransparentIconToImageList(ImageList: TImageList; Icon: TIcon): integer;
  17. function CompatOpenDialogExecute(OpenDialog: TOpenDialog): boolean;
  18. function CompatSaveDialogExecute(SaveDialog: TSaveDialog): boolean;
  19.  
  20. implementation
  21.  
  22. uses
  23.   PatchU, ShlObj, ShellAPI;
  24.  
  25. var
  26.   pp: TPatchMethod;
  27.  
  28. // --- CompatOpenDialogExecute
  29.  
  30. type
  31.   TExtOpenDialogAccessor = class(TOpenDialog);
  32.  
  33.   TExtOpenDialog = class(TOpenDialog)
  34.   protected
  35.     function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; override;
  36.   end;
  37.  
  38. function TExtOpenDialog.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
  39. begin
  40.   TOpenFileName(DialogData).Flags :=
  41.   TOpenFileName(DialogData).Flags and not OFN_ENABLETEMPLATE;
  42.  
  43.   TOpenFileName(DialogData).Flags :=
  44.   TOpenFileName(DialogData).Flags and not OFN_ENABLEHOOK;
  45.  
  46.   if pp.IsPatched then pp.Restore;
  47.  
  48.   result := inherited TaskModalDialog(DialogFunc, DialogData);
  49. end;
  50.  
  51. function CompatOpenDialogExecute(OpenDialog: TOpenDialog): boolean;
  52. {$IF CompilerVersion < 18.5} // prior to Delphi 2007
  53. var
  54.   x: TExtOpenDialog;
  55.   MethodPtr, MethodPtr2: function(DialogFunc: Pointer; var DialogData): Bool of object;
  56. begin
  57.   MethodPtr := TExtOpenDialogAccessor(OpenDialog).TaskModalDialog;
  58.  
  59.   x := TExtOpenDialog.Create(nil);
  60.   try
  61.     MethodPtr2 := x.TaskModalDialog;
  62.     pp := TPatchMethod.Create(@MethodPtr, @MethodPtr2);
  63.     try
  64.       result := OpenDialog.Execute;
  65.       if pp.IsPatched then pp.Restore;
  66.     finally
  67.       pp.Free;
  68.     end;
  69.   finally
  70.     x.Free;
  71.   end;
  72. {$ELSE}
  73. begin
  74.   result := OpenDialog.Execute;
  75. {$IFEND}
  76. end;
  77.  
  78. // --- CompatSaveDialogExecute
  79.  
  80. type
  81.   TExtSaveDialogAccessor = class(TSaveDialog);
  82.  
  83.   TExtSaveDialog = class(TSaveDialog)
  84.   protected
  85.     function TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool; override;
  86.   end;
  87.  
  88. function TExtSaveDialog.TaskModalDialog(DialogFunc: Pointer; var DialogData): Bool;
  89. begin
  90.   // Remove the two flags which let the File Dialog GUI fall back to the old design.
  91.   TOpenFileName(DialogData).Flags :=
  92.   TOpenFileName(DialogData).Flags and not OFN_ENABLETEMPLATE;
  93.  
  94.   TOpenFileName(DialogData).Flags :=
  95.   TOpenFileName(DialogData).Flags and not OFN_ENABLEHOOK;
  96.  
  97.   // It is important to restore TaskModalDialog, so we don't get a stack
  98.   // overflow when calling the inherited method.
  99.   if pp.IsPatched then pp.Restore;
  100.  
  101.   result := inherited TaskModalDialog(DialogFunc, DialogData);
  102. end;
  103.  
  104. function CompatSaveDialogExecute(SaveDialog: TSaveDialog): boolean;
  105. {$IF CompilerVersion < 18.5} // prior to Delphi 2007
  106. var
  107.   x: TExtSaveDialog;
  108.   MethodPtr, MethodPtr2: function(DialogFunc: Pointer; var DialogData): Bool of object;
  109. begin
  110.   MethodPtr := TExtSaveDialogAccessor(SaveDialog).TaskModalDialog;
  111.  
  112.   x := TExtSaveDialog.Create(nil);
  113.   try
  114.     MethodPtr2 := x.TaskModalDialog;
  115.     pp := TPatchMethod.Create(@MethodPtr, @MethodPtr2);
  116.     try
  117.       result := SaveDialog.Execute;
  118.     finally
  119.       pp.Free;
  120.     end;
  121.   finally
  122.     x.Free;
  123.   end;
  124. {$ELSE}
  125. begin
  126.   result := OpenDialog.Execute;
  127. {$IFEND}
  128. end;
  129.  
  130. // --- AddTransparentIconToImageList
  131.  
  132. function RealIconSize(H: HIcon): TPoint;
  133. // http://www.delphipages.com/forum/showthread.php?t=183999
  134. var
  135.   IconInfo: TIconInfo;
  136.   bmpmask: TBitmap;
  137. begin
  138.   result := Point(0, 0);
  139.  
  140.   if H <> 0 then
  141.   begin
  142.     bmpmask := TBitmap.Create;
  143.     try
  144.       IconInfo.fIcon := true;
  145.       try
  146.         GetIconInfo(H, IconInfo);
  147.         bmpmask.Handle := IconInfo.hbmMask;
  148.         bmpmask.Dormant; //lets us free the resource without 'losing' the bitmap
  149.       finally
  150.         DeleteObject(IconInfo.hbmMask);
  151.         DeleteObject(IconInfo.hbmColor)
  152.       end;
  153.       result := Point(bmpmask.Width, bmpmask.Height);
  154.     finally
  155.       bmpmask.Free;
  156.     end;
  157.   end;
  158. end;
  159.  
  160. function AddTransparentIconToImageList(ImageList: TImageList; Icon: TIcon): integer;
  161. // http://www.delphipages.com/forum/showthread.php?t=183999
  162. var
  163.   buffer, mask: TBitmap;
  164.   p: TPoint;
  165. begin
  166.   // result := ImageList.AddIcon(ico);
  167.   // --> In Delphi 6, Icons with half-transparency have a black border (e.g. in ListView)
  168.  
  169.   p := RealIconSize(icon.handle);
  170.  
  171.   buffer := TBitmap.Create;
  172.   mask := TBitmap.Create;
  173.   try
  174.     buffer.PixelFormat := pf24bit;
  175.     mask.PixelFormat := pf24bit;
  176.  
  177.     buffer.Width := p.X;
  178.     buffer.Height := p.Y;
  179.     buffer.Canvas.Draw(0, 0, icon);
  180.     buffer.Transparent := true;
  181.     buffer.TransparentColor := buffer.Canvas.Pixels[0,0];
  182.  
  183.     if (ImageList.Width <> p.X) or (ImageLIst.Height <> p.Y) then
  184.     begin
  185.       ImageList.Width := p.X;
  186.       ImageList.Height := p.Y;
  187.     end;
  188.  
  189.     // create a mask for the icon.
  190.     mask.Assign(buffer);
  191.     mask.Canvas.Brush.Color := buffer.Canvas.Pixels[0, buffer.Height -1];
  192.     mask.Monochrome := true;
  193.  
  194.     result := ImageList.Add(buffer, mask);
  195.   finally
  196.     mask.Free;
  197.     buffer.Free;
  198.   end;
  199. end;
  200.  
  201. end.
  202.