home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 April A / Pcwk4a98.iso / PROGRAM / DELPHI16 / Calmira / Src / VCL / CHKLIST.PAS < prev    next >
Pascal/Delphi Source File  |  1997-02-15  |  6KB  |  246 lines

  1. {*********************************************************}
  2. {                                                         }
  3. {    Calmira Visual Component Library 1.0                 }
  4. {    by Li-Hsin Huang,                                    }
  5. {    released into the public domain January 1997         }
  6. {                                                         }
  7. {*********************************************************}
  8.  
  9. unit Chklist;
  10.  
  11. { TCheckList control }
  12.  
  13. { TCheckList is a listbox that acts as an array of checkboxes.  It
  14.   draws each item like a 3D check box, using the Selected property
  15.   to determine if an item is checked.  At design time, use the Items
  16.   property to set the contents.
  17.  
  18.   This has many advantages over a large array or group of standard
  19.   TCheckbox controls:
  20.  
  21.   1.  Less resources -- a listbox only uses one window handle.
  22.   2.  Fast -- only one control is created and drawn.
  23.   3.  Practically unlimited capacity, without using more resources.
  24.   4.  Scrollable -- pack a large number of options into a small
  25.       space in a dialog box.
  26.  
  27.   The check list was originally designed so that many Boolean variables
  28.   can be set without the need to map each var to one TCheckbox, which is
  29.   error prone and slow, so there are two additional methods to allow
  30.   efficient data transfer.
  31.  
  32.   SetData - accepts an open array of Booleans which is used to set
  33.     the Selected property.
  34.   GetData - accepts an open array of Boolean pointers, which is
  35.     assigned the values from the Selected property.
  36.   RangeCheck - if True, a call to GetData or SetData will check that
  37.     the size of the open array matches the size of the list.  This
  38.     often catches out ommissions and inconsistencies.
  39.  
  40.   For long lists, you can use just paste a copy the SetData call,
  41.   change the "Set" to a "Get" and add @ symbols in front of each
  42.   boolean identifier.
  43.  
  44.   Example :
  45.  
  46.   var
  47.     DebugInfo, LocalSymbols, SymbolInfo : Boolean;
  48.  
  49.   CheckList1.SetData([DebugInfo, LocalSymbols, SymbolInfo]);
  50.   if ShowModal = mrOK then
  51.   CheckList1.GetData([@DebugInfo, @LocalSymbols, @SymbolInfo]);
  52.  
  53.   Don't forget to distribute CHKLIST.RES, which contains the
  54.   fake checkbox bitmaps.
  55. }
  56.  
  57.  
  58. interface
  59.  
  60. uses
  61.   SysUtils, WinTypes, WinProcs, Classes, Graphics, Controls,
  62.   Forms, StdCtrls, Menus;
  63.  
  64. type
  65.   PBoolean = ^Boolean;
  66.  
  67.   TCheckList = class(TCustomListbox)
  68.   private
  69.     { Private declarations }
  70.     FRangeCheck : Boolean;
  71.     FHints : TStrings;
  72.     procedure Validate(n : Integer);
  73.     procedure SetHints(value : TStrings);
  74.   protected
  75.     { Protected declarations }
  76.     procedure DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState); override;
  77.   public
  78.     { Public declarations }
  79.     constructor Create(AOwner: TComponent); override;
  80.     destructor Destroy; override;
  81.     procedure SetData(const b: array of Boolean);
  82.     procedure GetData(const p: array of PBoolean);
  83.   published
  84.     { Published declarations }
  85.     property RangeCheck : Boolean read FRangeCheck write FRangeCheck default True;
  86.     property Hints : TStrings read FHints write SetHints;
  87.     property Align;
  88.     property BorderStyle;
  89.     property Color;
  90.     property Columns;
  91.     property Ctl3D;
  92.     property DragCursor;
  93.     property DragMode;
  94.     property Enabled;
  95.     property Font;
  96.     property IntegralHeight;
  97.     property ItemHeight;
  98.     property Items;
  99.     property ParentColor;
  100.     property ParentCtl3D;
  101.     property ParentFont;
  102.     property ParentShowHint;
  103.     property PopupMenu;
  104.     property ShowHint;
  105.     property Sorted;
  106.     property TabOrder;
  107.     property TabStop;
  108.     property Visible;
  109.     property OnClick;
  110.     property OnDblClick;
  111.     property OnDragDrop;
  112.     property OnDragOver;
  113.     property OnEndDrag;
  114.     property OnEnter;
  115.     property OnExit;
  116.     property OnKeyDown;
  117.     property OnKeyPress;
  118.     property OnKeyUp;
  119.     property OnMouseDown;
  120.     property OnMouseMove;
  121.     property OnMouseUp;
  122.   end;
  123.  
  124.   ECheckListError = class(Exception);
  125.  
  126. procedure Register;
  127.  
  128. implementation
  129.  
  130. {$R *.RES}
  131.  
  132. var
  133.   CheckedBmp, UncheckedBmp : TBitmap;
  134.  
  135.  
  136. procedure LoadCheckboxBitmaps;
  137. begin
  138.   CheckedBmp := TBitmap.Create;
  139.   CheckedBmp.Handle := LoadBitmap(HInstance, 'CHECKLISTCHECKED');
  140.   UncheckedBmp := TBitmap.Create;
  141.   UncheckedBmp.Handle := LoadBitmap(HInstance, 'CHECKLISTUNCHECKED');
  142. end;
  143.  
  144. constructor TCheckList.Create(AOwner: TComponent);
  145. begin
  146.   inherited Create(AOwner);
  147.   Color := clBtnFace;
  148.   IntegralHeight := True;
  149.   Style := lbOwnerDrawFixed;
  150.   MultiSelect := True;
  151.   ExtendedSelect := False;
  152.   ItemHeight := 20;
  153.   FRangeCheck := True;
  154.   FHints := TStringList.Create;
  155.   if CheckedBmp = nil then LoadCheckboxBitmaps;
  156. end;
  157.  
  158.  
  159. destructor TCheckList.Destroy;
  160. begin
  161.   FHints.Free;
  162.   inherited Destroy;
  163. end;
  164.  
  165. procedure TCheckList.SetHints(value: TStrings);
  166. begin
  167.   FHints.Assign(value);
  168. end;
  169.  
  170.  
  171. procedure TCheckList.DrawItem(Index: Integer; Rect: TRect; State: TOwnerDrawState);
  172. var
  173.   bmp : TBitmap;
  174.   h : Integer;
  175. begin
  176.   h := Rect.Bottom - Rect.Top;
  177.  
  178.   Canvas.Brush.Color := Color;
  179.   Canvas.FillRect(Rect);
  180.  
  181.   if Selected[Index] then
  182.     bmp := CheckedBmp else bmp := UncheckedBmp;
  183.  
  184.   Canvas.Draw(4, Rect.Top + (h - bmp.Height) div 2, bmp);
  185.   Canvas.TextOut(Rect.Left + 22,
  186.     Rect.Top + (h - Abs(Font.Height)) div 2 - 1, Items[Index]);
  187. end;
  188.  
  189.  
  190. procedure TCheckList.Validate(n : Integer);
  191. begin
  192.   if FRangeCheck then
  193.     if n < Items.Count then
  194.       raise ECheckListError.Create('Not enough elements in data array')
  195.     else if n > Items.Count then
  196.       raise ECheckListError.Create('Too many elements in data array')
  197. end;
  198.  
  199.  
  200. procedure TCheckList.SetData(const b: array of Boolean);
  201. var
  202.   i: Integer;
  203. begin
  204.   Validate(High(b)+1);
  205.   i := 0;
  206.  
  207.   while (i <= High(b)) and (i < Items.Count) do begin
  208.     Selected[i] := b[i];
  209.     Inc(i);
  210.   end;
  211.  
  212.   TopIndex := 0;
  213.   Invalidate;
  214. end;
  215.  
  216.  
  217. procedure TCheckList.GetData(const p: array of PBoolean);
  218. var
  219.   i: Integer;
  220. begin
  221.   Validate(High(p)+1);
  222.   i := 0;
  223.  
  224.   while (i <= High(p)) and (i < Items.Count) do begin
  225.     p[i]^ := Selected[i];
  226.     Inc(i);
  227.   end;
  228. end;
  229.  
  230.  
  231. procedure DoneCheckList; far;
  232. begin
  233.   CheckedBmp.Free;
  234.   UncheckedBmp.Free;
  235. end;
  236.  
  237. procedure Register;
  238. begin
  239.   RegisterComponents('Samples', [TCheckList]);
  240. end;
  241.  
  242.  
  243. initialization
  244.   AddExitProc(DoneCheckList);
  245. end.
  246.