kasprogressbar.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. {
  2. Double Commander Components
  3. -------------------------------------------------------------------------
  4. Extended ProgressBar class
  5. Copyright (C) 2010 Przemyslaw Nagay ([email protected])
  6. Copyright (C) 2011-2018 Alexander Koblov ([email protected])
  7. Windows 7 implementation based on "Windows 7 Component Library"
  8. by Daniel Wischnewski (http://www.gumpi.com/blog)
  9. This program is free software; you can redistribute it and/or
  10. modify it under the terms of the GNU General Public License as
  11. published by the Free Software Foundation; either version 2 of the
  12. License, or (at your option) any later version.
  13. This program is distributed in the hope that it will be useful, but
  14. WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. }
  20. unit KASProgressBar;
  21. {$mode objfpc}{$H+}
  22. interface
  23. uses
  24. LCLType, Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ComCtrls
  25. {$IFDEF LCLWIN32}
  26. , InterfaceBase, ComObj, LMessages, Windows, Themes, dwTaskbarList
  27. {$ENDIF}
  28. {$IFDEF LCLGTK2}
  29. , Gtk2
  30. {$ENDIF}
  31. {$IFDEF LCLQT}
  32. , qt4, qtwidgets
  33. {$ENDIF}
  34. {$IFDEF LCLQT5}
  35. , qt5, qtwidgets
  36. {$ENDIF}
  37. {$IFDEF LCLQT6}
  38. , qt6, qtwidgets
  39. {$ENDIF}
  40. ;
  41. type
  42. { TKASProgressBar }
  43. TKASProgressBar = class(TProgressBar)
  44. private
  45. FShowInTaskbar: Boolean;
  46. {$IFDEF LCLWIN32}
  47. FBarText: String;
  48. FTaskBarEntryHandle: HWND;
  49. FTaskbarList: ITaskbarList;
  50. FTaskbarList3: ITaskbarList3;
  51. {$ENDIF}
  52. protected
  53. {$IFDEF LCLWIN32}
  54. procedure InitializeWnd; override;
  55. procedure WMPaint(var Msg: TLMPaint); message LM_PAINT;
  56. {$ENDIF}
  57. procedure DoOnResize; override;
  58. public
  59. constructor Create(AOwner: TComponent); override;
  60. procedure SetProgress(CurrentValue: Int64; MaxValue: Int64; BarText: String = '');
  61. published
  62. property ShowInTaskbar: Boolean read FShowInTaskbar write FShowInTaskbar default False;
  63. end;
  64. procedure Register;
  65. implementation
  66. procedure Register;
  67. begin
  68. RegisterComponents('KASComponents',[TKASProgressBar]);
  69. end;
  70. { TKASProgressBar }
  71. {$IFDEF LCLWIN32}
  72. procedure TKASProgressBar.InitializeWnd;
  73. var
  74. aOwnerForm: TWinControl;
  75. begin
  76. inherited InitializeWnd;
  77. if CheckWin32Version(6, 1) then
  78. begin
  79. aOwnerForm:= GetParentForm(Self);
  80. if Assigned(aOwnerForm) and (aOwnerForm <> Application.MainForm) then
  81. FTaskBarEntryHandle := aOwnerForm.Handle
  82. else
  83. FTaskBarEntryHandle := Widgetset.AppHandle;
  84. end;
  85. BarShowText:= BarShowText and CheckWin32Version(8);
  86. end;
  87. procedure TKASProgressBar.WMPaint(var Msg: TLMPaint);
  88. var
  89. OldFont: HFONT;
  90. OldBkMode: Integer;
  91. Details: TThemedElementDetails;
  92. begin
  93. inherited WMPaint(Msg);
  94. if BarShowText and ThemeServices.ThemesEnabled then
  95. begin
  96. OldBkMode:= SetBkMode(Msg.DC, TRANSPARENT);
  97. Details:= ThemeServices.GetElementDetails(tpBar);
  98. OldFont:= SelectObject(Msg.DC, Font.Reference.Handle);
  99. ThemeServices.DrawText(Msg.DC, Details, FBarText, Msg.PaintStruct^.rcPaint, DT_SINGLELINE or DT_CENTER or DT_VCENTER, 0);
  100. SelectObject(Msg.DC, OldFont);
  101. SetBkMode(Msg.DC, OldBkMode);
  102. end;
  103. end;
  104. {$ENDIF}
  105. procedure TKASProgressBar.DoOnResize;
  106. begin
  107. inherited;
  108. Max := Width;
  109. end;
  110. constructor TKASProgressBar.Create(AOwner: TComponent);
  111. begin
  112. inherited Create(AOwner);
  113. {$IFDEF LCLWIN32}
  114. FTaskbarList3 := nil;
  115. FTaskBarEntryHandle := INVALID_HANDLE_VALUE;
  116. // Works only under Windows 7 and higher
  117. if CheckWin32Version(6, 1) then
  118. try
  119. FTaskbarList := ITaskbarList(CreateComObject(CLSID_TaskbarList));
  120. FTaskbarList.HrInit;
  121. FTaskbarList.QueryInterface(CLSID_TaskbarList3, FTaskbarList3);
  122. except
  123. FTaskbarList3 := nil;
  124. end;
  125. {$ENDIF}
  126. {$IFDEF LCLGTK2}
  127. // Have to disable LCLGTK2 default progress bar text
  128. // set in TGtk2WSProgressBar.UpdateProgressBarText.
  129. BarShowText := False;
  130. {$ENDIF}
  131. end;
  132. procedure TKASProgressBar.SetProgress(CurrentValue: Int64; MaxValue: Int64;
  133. BarText: String);
  134. {$IFDEF LCLGTK2}
  135. var
  136. wText: String;
  137. {$ENDIF}
  138. {$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)}
  139. var
  140. wText: WideString;
  141. {$ENDIF}
  142. begin
  143. if MaxValue <> 0 then
  144. Position := Round(CurrentValue * Max / MaxValue)
  145. else
  146. Position := 0;
  147. {$IFDEF LCLWIN32}
  148. if BarShowText then
  149. begin
  150. if MaxValue = 0 then
  151. FBarText := BarText
  152. else if BarText = '' then
  153. FBarText := FloatToStrF((CurrentValue / MaxValue) * 100, ffFixed, 0, 0) + '%'
  154. else
  155. FBarText := BarText + ' (' + FloatToStrF((CurrentValue / MaxValue) * 100, ffFixed, 0, 0) + '%)';
  156. end;
  157. if FShowInTaskbar and (FTaskBarEntryHandle <> INVALID_HANDLE_VALUE) and Assigned(FTaskbarList3) then
  158. begin
  159. FTaskbarList3.SetProgressValue(FTaskBarEntryHandle, Position, Max);
  160. end;
  161. {$ENDIF}
  162. {$IFDEF LCLGTK2}
  163. {
  164. %v - the current progress value.
  165. %l - the lower bound for the progress value.
  166. %u - the upper bound for the progress value.
  167. %p - the current progress percentage.
  168. }
  169. if BarText <> '' then
  170. wText := BarText + ' (%p%%)'
  171. else
  172. wText := '%p%%';
  173. gtk_progress_set_format_string(PGtkProgress(Self.Handle), PChar(wText));
  174. // Have to reset 'show_text' every time because LCLGTK2 will set it according to BarShowText.
  175. gtk_progress_set_show_text(PGtkProgress(Self.Handle), True);
  176. {$ENDIF}
  177. {$IF DEFINED(LCLQT) OR DEFINED(LCLQT5) OR DEFINED(LCLQT6)}
  178. {
  179. %p - is replaced by the percentage completed.
  180. %v - is replaced by the current value.
  181. %m - is replaced by the total number of steps.
  182. }
  183. if BarText <> '' then
  184. wText := WideString(BarText) + ' (%p%)'
  185. else
  186. wText := '%p%';
  187. QProgressBar_setFormat(QProgressBarH(TQtProgressBar(Self.Handle).Widget), @wText);
  188. //QProgressBar_setTextVisible(QProgressBarH(TQtProgressBar(Self.Handle).Widget), True);
  189. {$ENDIF}
  190. end;
  191. end.