Author: Tomas Rutkauskas
I need a TTreeView with a checkbox next to each item, much like the way most backup
programs allow you to select files for backup (only I am not selecting files).
Answer:
Solve 1:
Checkboxes on TTreeView nodes. Use state images (2 and 3 for unchecked and checked
box in example below)
1 procedure TForm1.FormCreate(Sender: TObject);
2 var
3 bmp, temp: TBitmap;
4 i: Integer;
5 begin
6 bmp := TBitmap.create;
7 try
8 bmp.handle := LoadBitmap(0, PChar(OBM_CHECKBOXES));
9 {bmp now has a 4x3 bitmap of divers state images used by checkboxes
10 and radiobuttons}
11 temp := TBitmap.Create;
12 {image1.picture.bitmap := bmp;}
13 try
14 imagelist1.Width := bmp.width div 4;
15 imagelist1.Height := bmp.Height div 3;
16 with temp do
17 begin
18 width := bmp.width div 4;
19 height := bmp.height div 3;
20 for i := 0 to 3 do
21 begin
22 canvas.copyrect(canvas.cliprect, bmp.canvas, rect(i * width, 0, (i + 1) *
23 width, height));
24 imagelist1.AddMasked(temp, clSilver);
25 end;
26 end;
27 label1.Caption := IntToStr(imagelist1.Count);
28 finally
29 temp.free;
30 end;
31 finally
32 bmp.free
33 end;
34 end;
35
36 procedure TForm1.TreeView1Click(Sender: TObject);
37 var
38 pos: TPoint;
39 node: TTreeNode;
40 begin
41 pos := treeview1.screentoclient(mouse.CursorPos);
42 node := treeview1.GetNodeAt(pos.x, pos.y);
43 if assigned(node) then
44 if htOnStateIcon in treeview1.GetHitTestInfoAt(pos.x, pos.y) then
45 with node do
46 case StateIndex of
47 3: StateIndex := 2;
48 2: StateIndex := 3;
49 end;
50 end;
Solve 2:
Create an imagelist containing images of a checkbox checked and unchecked and put
the following code into your program. Notice the special update procedure. You need
to give an explicit update call since the treeview doesn't see you change the
images.
51
52 procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
53 Shift: TShiftState; X, Y: Integer);
54 var
55 myNode: TTreeNode;
56 begin
57 if htOnIcon in TreeView1.GetHitTestInfoAt(X, Y) then
58 begin
59 myNode := TreeView1.GetNodeAt(X, Y);
60 if myNode.ImageIndex = 0 then
61 begin
62 myNode.ImageIndex := 1;
63 myNode.StateIndex := 1;
64 myNode.SelectedIndex := 1;
65 end
66 else
67 begin
68 myNode.ImageIndex := 0;
69 myNode.StateIndex := 0;
70 myNode.SelectedIndex := 0;
71 end;
72 RefreshNode(myNode);
73 end;
74 end;
75
76 {Handles updating only a single node when a status image changes. This avoids
77 redrawing the entire tree, cutting down on flickering and speeding up the display.}
78
79 procedure TForm1.RefreshNode(Node: TTreeNode);
80 var
81 R: TRect;
82 begin
83 if Node <> nil then
84 begin
85 if not Node.IsVisible then
86 Exit;
87 R := Node.DisplayRect(False);
88 InvalidateRect(TreeView1.Handle, @R, False);
89 end;
90 end;
|