Консультация № 63845
23.11.2006, 12:16
0.00 руб.
0 2 2
Уважаемые эксперты! Помогите, пожалуйста в следующем:
Задача: создать дерево с Chekbox‘ами (примерно как в инсталляторах). Галочки в чекбоксах будут расставлять пользователи и нужно также их ставить программно. При этом необходимо, чтобы при выборе родительской ветви отмечались галочками и все дочерние узлы этой ветви и соответственно наоборот - при снятии галочки снимались и все дочерние. Мои попытки реализовать это (см. код) успехом не увенчались.

Приложение:
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, CommCtrl;type TForm1 = class(TForm) TreeView1: TTreeView; Label1: TLabel; Label2: TLabel; Label3: TLabel; procedure FormCreate(Sender: TObject); procedure TreeView1Change(Sender: TObject; Node: TTreeNode); procedure TreeView1Click(Sender: TObject); procedure TreeView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end;var Form1: TForm1; MouseX, MouseY: Integer;implementation{$R *.dfm}Function TVGetCheck(TV: TTreeView; Node: TTreeNode): Boolean;Var Item: TTVItem;Begin With Item Do Begin hItem:=Node.ItemId; mask:=TVIF_STATE; TV.Perform(TVM_GETITEM,0,Integer(@Item)); Result:=Bool((State and $2000) shr 13); End;End;Procedure TVSetCheck(TV: TTreeView; Node: TTreeNode);Var Item: TTVItem;BeginWith Item Do Begin hItem:=Node.ItemId; mask:=TVIF_STATE; State:=$2000; TV.Perform(TVM_SETITEM,0,Integer(@Item)); End;End;procedure TForm1.FormCreate(Sender: TObject);var CurrNode : TTreeNode;begin SetWindowLong(TreeView1.Handle,GWL_STYLE,GetWindowLong(TreeView1.Handle,GWL_STYLE) or TVS_CHECKBOXES); CurrNode := TreeView1.Items.AddChild(nil,‘Офис 1‘); CurrNode := TreeView1.Items.AddChild(CurrNode,‘Департамент 1.1‘); CurrNode := TreeView1.Items.AddChild(CurrNode,‘Работник 1.1.1‘); CurrNode := TreeView1.Items.Add(CurrNode,‘Работник 1.1.2‘); CurrNode := TreeView1.Items.AddChild(nil,‘Офис 2‘); CurrNode := TreeView1.Items.AddChild(CurrNode,‘Департамент 2.1‘); CurrNode := TreeView1.Items.AddChild(CurrNode,‘Работник 2.1.1‘);end;procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);var a,a1,b,c:integer;beginb:=TreeView1.Selected.Level; c:=0;for a:=TreeView1.Selected.AbsoluteIndex+1 to TreeView1.Items.Count-1 do if TreeView1.Items.Item[a].Level>b then Inc(c) else Break;a1:=TreeView1.Selected.AbsoluteIndex; for a:=a1+1 to a1+c do TVSetCheck (TreeView1,TreeView1.Items.Item[a]);end;procedure TForm1.TreeView1Click(Sender: TObject);beginTreeView1.Select(TreeView1.GetNodeAt(MouseX,MouseY));TreeView1Change(Sender,TreeView1.Selected);end;procedure TForm1.TreeView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);begin MouseX:=X; MouseY:=Y;end;end.

Обсуждение

Неизвестный
23.11.2006, 12:46
общий
это ответ
Здравствуйте, Alexius1979!
Воспользуйся компонентом TJvgCheckTreeView из библиотеки Jedi VCL. Сама библиотека имееет более 400 компонент. Скачать ее можно с http://sourceforge.net/projects/jvcl/
Неизвестный
23.11.2006, 12:52
общий
это ответ
Здравствуйте, Alexius1979!

можно попробовать все сделать еще проще, через images
отрисовать 3 чекбокса нажатый, пустой и затемненный нажатый и при нажатии на ветвь просто менять imageindex на нужный !!!

если ветка не имеет Child объектов то только нажатый или отпущеный !!!
если имеет то делать проверку всех child-ов на предмет нажатия (по imageindex) определять !!!

мне кажется так будет проще !!!
Форма ответа