Author: Tomas Rutkauskas
I tried many combinations of GW_STYLE with TVS_CHECKBOXES or BS_AUTO3STATE and I
can't get a three state checkbox. All I have is a plain 2 state box. Any ideas?
Answer:
Actually, you can have any number of checkbox states you like. The number of the
images in the state image list determines the number of the states. By default, the
image list has two bitmaps: checked and unchecked. But you are always able to add
yours for a third (forth ...) state. The code below shows a TTreeView with
checkboxes and a third state. I've tested it on D4 and it seemed to work alright.
You can set the third state to the tree node by setting 3 to the StateIndex
property in the form's OnCreate event or in any other suitable place:
1 MyTreeView1.Items[0].StateIndex := 3;
2 3 { ... }4 type5 TMyTreeView = class(TTreeView)
6 protected7 procedure CNNotify(varmessage: TWMNotify); message CN_NOTIFY;
8 procedure CreateParams(var Params: TCreateParams); override;
9 public10 procedure AddNewStateImage;
11 end;
12 13 { ... }14 15 procedure TMyTreeView.CreateParams(var Params: TCreateParams);
16 begin17 inherited CreateParams(Params);
18 Params.Style := Params.Style or TVS_CHECKBOXES;
19 end;
20 21 procedure TMyTreeView.CNNotify(varmessage: TWMNotify);
22 begin23 withmessagedo24 if NMHdr^.code = NM_CUSTOMDRAW then25 AddNewStateImage;
26 inherited;
27 end;
28 29 procedure TMyTreeView.AddNewStateImage;
30 var31 XImageList: TImageList;
32 XImage: HIMAGELIST;
33 XBitMap: TBitMap;
34 i: integer;
35 begin36 XImage := TreeView_GetImageList(Handle, TVSIL_STATE);
37 if (XImage <> 0) and (ImageList_GetImageCount(XImage) < 4) then38 begin39 XImageList := TImageList.Create(Self);
40 XBitMap := TBitMap.Create;
41 try42 XImageList.ShareImages := true;
43 XImageList.Handle := XImage;
44 XBitMap.Width := XImageList.Width;
45 XBitMap.Height := XImageList.Height;
46 XImageList.Draw(XBitMap.Canvas, 0, 0, 2, false);
47 XImageList.Add(XBitMap, nil);
48 finally49 XImageList.Free;
50 XBitMap.Free;
51 end;
52 for i := 0 to Items.Count - 1 do53 if Items[i].StateIndex > 0 then54 Items[i].StateIndex := Items[i].StateIndex;
55 end;
56 end;