Create a TTreeView with checkboxes (Views: 27)
Problem/Question/Abstract: 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) procedure TForm1.FormCreate(Sender: TObject); var bmp, temp: TBitmap; i: Integer; begin bmp := TBitmap.create; try bmp.handle := LoadBitmap(0, PChar(OBM_CHECKBOXES)); {bmp now has a 4x3 bitmap of divers state images used by checkboxes and radiobuttons} temp := TBitmap.Create; {image1.picture.bitmap := bmp;} try imagelist1.Width := bmp.width div 4; imagelist1.Height := bmp.Height div 3; with temp do begin width := bmp.width div 4; height := bmp.height div 3; for i := 0 to 3 do begin canvas.copyrect(canvas.cliprect, bmp.canvas, rect(i * width, 0, (i + 1) * width, height)); imagelist1.AddMasked(temp, clSilver); end; end; label1.Caption := IntToStr(imagelist1.Count); finally temp.free; end; finally bmp.free end; end; procedure TForm1.TreeView1Click(Sender: TObject); var pos: TPoint; node: TTreeNode; begin pos := treeview1.screentoclient(mouse.CursorPos); node := treeview1.GetNodeAt(pos.x, pos.y); if assigned(node) then if htOnStateIcon in treeview1.GetHitTestInfoAt(pos.x, pos.y) then with node do case StateIndex of 3: StateIndex := 2; 2: StateIndex := 3; end; 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. procedure TForm1.TreeView1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var myNode: TTreeNode; begin if htOnIcon in TreeView1.GetHitTestInfoAt(X, Y) then begin myNode := TreeView1.GetNodeAt(X, Y); if myNode.ImageIndex = 0 then begin myNode.ImageIndex := 1; myNode.StateIndex := 1; myNode.SelectedIndex := 1; end else begin myNode.ImageIndex := 0; myNode.StateIndex := 0; myNode.SelectedIndex := 0; end; RefreshNode(myNode); end; end; {Handles updating only a single node when a status image changes. This avoids redrawing the entire tree, cutting down on flickering and speeding up the display.} procedure TForm1.RefreshNode(Node: TTreeNode); var R: TRect; begin if Node <> nil then begin if not Node.IsVisible then Exit; R := Node.DisplayRect(False); InvalidateRect(TreeView1.Handle, @R, False); end; end; |