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
2 procedure TForm1.FormCreate(Sender: TObject);
3 var
4 bmp, temp: TBitmap;
5 i: Integer;
6 begin
7 bmp := TBitmap.create;
8 try
9 bmp.handle := LoadBitmap(0, PChar(OBM_CHECKBOXES));
10 {bmp now has a 4x3 bitmap of divers state images used by checkboxes
11 and radiobuttons}
12 temp := TBitmap.Create;
13 {image1.picture.bitmap := bmp;}
14 try
15 imagelist1.Width := bmp.width div 4;
16 imagelist1.Height := bmp.Height div 3;
17 with temp do
18 begin
19 width := bmp.width div 4;
20 height := bmp.height div 3;
21 for i := 0 to 3 do
22 begin
23 canvas.copyrect(canvas.cliprect, bmp.canvas, rect(i * width, 0, (i + 1) *
24 width, height));
25 imagelist1.AddMasked(temp, clSilver);
26 end;
27 end;
28 label1.Caption := IntToStr(imagelist1.Count);
29 finally
30 temp.free;
31 end;
32 finally
33 bmp.free
34 end;
35 end;
36
37 procedure TForm1.TreeView1Click(Sender: TObject);
38 var
39 pos: TPoint;
40 node: TTreeNode;
41 begin
42 pos := treeview1.screentoclient(mouse.CursorPos);
43 node := treeview1.GetNodeAt(pos.x, pos.y);
44 if assigned(node) then
45 if htOnStateIcon in treeview1.GetHitTestInfoAt(pos.x, pos.y) then
46 with node do
47 case StateIndex of
48 3: StateIndex := 2;
49 2: StateIndex := 3;
50 end;
51 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.
52
53 procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton;
54 Shift: TShiftState; X, Y: Integer);
55 var
56 myNode: TTreeNode;
57 begin
58 if htOnIcon in TreeView1.GetHitTestInfoAt(X, Y) then
59 begin
60 myNode := TreeView1.GetNodeAt(X, Y);
61 if myNode.ImageIndex = 0 then
62 begin
63 myNode.ImageIndex := 1;
64 myNode.StateIndex := 1;
65 myNode.SelectedIndex := 1;
66 end
67 else
68 begin
69 myNode.ImageIndex := 0;
70 myNode.StateIndex := 0;
71 myNode.SelectedIndex := 0;
72 end;
73 RefreshNode(myNode);
74 end;
75 end;
76
77 {Handles updating only a single node when a status image changes. This avoids
78 redrawing the entire tree, cutting down on flickering and speeding up the display.}
79
80 procedure TForm1.RefreshNode(Node: TTreeNode);
81 var
82 R: TRect;
83 begin
84 if Node <> nil then
85 begin
86 if not Node.IsVisible then
87 Exit;
88 R := Node.DisplayRect(False);
89 InvalidateRect(TreeView1.Handle, @R, False);
90 end;
91 end;
|