PngCheckListBox.pas 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. unit PngCheckListBox;
  2. interface
  3. uses
  4. Windows, Classes, CheckLst, pngimage, PngFunctions;
  5. type
  6. TPngCheckListBox = class(TCheckListBox)
  7. private
  8. FPngUnchecked: TPngImage;
  9. FPngChecked: TPngImage;
  10. FPngOptions: TPngOptions;
  11. FPngGrayed: TPngImage;
  12. procedure SetPngChecked(const Value: TPngImage);
  13. procedure SetPngUnchecked(const Value: TPngImage);
  14. procedure SetPngOptions(const Value: TPngOptions);
  15. procedure SetPngGrayed(const Value: TPngImage);
  16. protected
  17. procedure DrawItem(Index: Integer; ARect: TRect; State: TOwnerDrawState); override;
  18. function GetCheckWidth: Integer; reintroduce;
  19. public
  20. constructor Create(AOwner: TComponent); override;
  21. destructor Destroy; override;
  22. published
  23. property PngChecked: TPngImage read FPngChecked write SetPngChecked;
  24. property PngUnchecked: TPngImage read FPngUnchecked write SetPngUnchecked;
  25. property PngGrayed: TPngImage read FPngGrayed write SetPngGrayed;
  26. property PngOptions: TPngOptions read FPngOptions write SetPngOptions default [pngBlendOnDisabled];
  27. end;
  28. implementation
  29. uses
  30. Graphics, StdCtrls, Math;
  31. { TPngCheckListBox }
  32. constructor TPngCheckListBox.Create(AOwner: TComponent);
  33. begin
  34. inherited Create(AOwner);
  35. FPngChecked := TPngImage.Create;
  36. FPngUnchecked := TPngImage.Create;
  37. FPngGrayed := TPngImage.Create;
  38. end;
  39. destructor TPngCheckListBox.Destroy;
  40. begin
  41. FPngChecked.Free;
  42. FPngUnchecked.Free;
  43. FPngGrayed.Free;
  44. inherited Destroy;
  45. end;
  46. procedure TPngCheckListBox.DrawItem(Index: Integer; ARect: TRect; State:
  47. TOwnerDrawState);
  48. procedure DrawCheck(R: TRect; AState: TCheckBoxState; AEnabled: Boolean);
  49. var
  50. Png: TPngImage;
  51. OldColor: TColor;
  52. begin
  53. //Draws the check image, if it's a PNG, otherwise the inherited would have
  54. //been called
  55. OldColor := Canvas.Brush.Color;
  56. Canvas.Brush.Color := Color;
  57. Canvas.FillRect(R);
  58. Canvas.Brush.Color := OldColor;
  59. case AState of
  60. cbUnchecked: Png := FPngUnchecked;
  61. cbChecked: Png := FPngChecked;
  62. else
  63. Png := FPngGrayed;
  64. end;
  65. DrawPNG(Png, Canvas, Rect(R.Left, R.Top, R.Left + Png.Width, R.Top +
  66. Png.Height), FPngOptions);
  67. end;
  68. procedure DrawText;
  69. var
  70. Flags: Integer;
  71. Data: string;
  72. begin
  73. //Draws the text for an item
  74. if Assigned(OnDrawItem) then
  75. OnDrawItem(Self, Index, ARect, State)
  76. else begin
  77. Canvas.FillRect(ARect);
  78. if Index < Items.Count then begin
  79. Flags := DrawTextBiDiModeFlags(DT_SINGLELINE or DT_VCENTER or
  80. DT_NOPREFIX);
  81. if not UseRightToLeftAlignment then
  82. Inc(ARect.Left, 2)
  83. else
  84. Dec(ARect.Right, 2);
  85. Data := '';
  86. if (Style in [lbVirtual, lbVirtualOwnerDraw]) then
  87. Data := DoGetData(Index)
  88. else
  89. Data := Items[Index];
  90. Windows.DrawText(Canvas.Handle, PChar(Data), Length(Data), ARect, Flags);
  91. end;
  92. end;
  93. end;
  94. var
  95. R: TRect;
  96. SaveEvent: TDrawItemEvent;
  97. ACheckWidth: Integer;
  98. Enable: Boolean;
  99. begin
  100. if FPngChecked.Empty and FPngUnchecked.Empty and FPngGrayed.Empty then
  101. inherited DrawItem(Index, ARect, State)
  102. else begin
  103. ACheckWidth := GetCheckWidth;
  104. if Index < Items.Count then begin
  105. R := ARect;
  106. Enable := Self.Enabled and ItemEnabled[Index];
  107. if not Header[Index] then begin
  108. if not UseRightToLeftAlignment then begin
  109. R.Right := ARect.Left;
  110. R.Left := R.Right - ACheckWidth;
  111. end
  112. else begin
  113. R.Left := ARect.Right;
  114. R.Right := R.Left + ACheckWidth;
  115. end;
  116. DrawCheck(R, Self.State[Index], Enable);
  117. end
  118. else begin
  119. Canvas.Font.Color := HeaderColor;
  120. Canvas.Brush.Color := HeaderBackgroundColor;
  121. end;
  122. if not Enable then
  123. Canvas.Font.Color := clGrayText;
  124. end;
  125. if (Style = lbStandard) and Assigned(OnDrawItem) then begin
  126. //Force lbStandard list to ignore OnDrawItem event.
  127. SaveEvent := OnDrawItem;
  128. OnDrawItem := nil;
  129. try
  130. DrawText;
  131. finally
  132. OnDrawItem := SaveEvent;
  133. end;
  134. end
  135. else
  136. DrawText;
  137. end;
  138. end;
  139. function TPngCheckListBox.GetCheckWidth: Integer;
  140. begin
  141. //CheckWidth is equal to the widest PNG
  142. if not (FPngChecked.Empty and FPngUnchecked.Empty and FPngGrayed.Empty) then
  143. Result := Max(FPngChecked.Width, Max(FPngUnchecked.Width, FPngGrayed.Width))
  144. else
  145. Result := inherited GetCheckWidth;
  146. end;
  147. procedure TPngCheckListBox.SetPngChecked(const Value: TPngImage);
  148. begin
  149. //This is all neccesary, because you can't assign a nil to a TPngImage
  150. if Value = nil then begin
  151. FPngChecked.Free;
  152. FPngChecked := TPngImage.Create;
  153. end
  154. else
  155. FPngChecked.Assign(Value);
  156. Repaint;
  157. end;
  158. procedure TPngCheckListBox.SetPngUnchecked(const Value: TPngImage);
  159. begin
  160. //This is all neccesary, because you can't assign a nil to a TPngImage
  161. if Value = nil then begin
  162. FPngUnchecked.Free;
  163. FPngUnchecked := TPngImage.Create;
  164. end
  165. else
  166. FPngUnchecked.Assign(Value);
  167. Repaint;
  168. end;
  169. procedure TPngCheckListBox.SetPngGrayed(const Value: TPngImage);
  170. begin
  171. //This is all neccesary, because you can't assign a nil to a TPngImage
  172. if Value = nil then begin
  173. FPngGrayed.Free;
  174. FPngGrayed := TPngImage.Create;
  175. end
  176. else
  177. FPngGrayed.Assign(Value);
  178. Repaint;
  179. end;
  180. procedure TPngCheckListBox.SetPngOptions(const Value: TPngOptions);
  181. begin
  182. if FPngOptions <> Value then begin
  183. FPngOptions := Value;
  184. Repaint;
  185. end;
  186. end;
  187. end.