Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.03.20;
Скачать: CL | DM;

Вниз

TVS_CHECKBOXES & TreeView. Как сделать с тремя состояниями ?   Найти похожие ветки 

 
Andriy Tysh ©   (2005-03-07 13:17) [0]

Есть TreeView, в котором с помощью TVS_CHECKBOXES добавляю CheckBox"ы.
Но у них только два состояния: Check & UnCheck.

Как мне сделать третье состояние, напр. Grayed как в TCheckBox при AllowGrayed ?


 
Andriy Tysh ©   (2005-03-07 16:53) [1]

А что, у ГУРУ сегодня выходной ?


 
GuAV ©   (2005-03-07 19:33) [2]

Из MSDN

TVS_CHECKBOXES
Version 4.70. Enables check boxes for items in a tree-view control. A check box is displayed only if an image is associated with the item. When set to this style, the control effectively uses DrawFrameControl to create and set a state image list containing two images. State image 1 is the unchecked box and state image 2 is the checked box. Setting the state image to zero removes the check box altogether. For more information, see Working with state image indexes.

Из этого следует два вывода
1. стандартных средств от MS нет, только checked и unchecked.
2. можно пойти тем же путём самому и создать свой TImageList, заполнить его изображениями checkboxов (unchecked, checked, grayed) и поставить его в св-во StateImages.
Пример рисования чекбоксов можно найти в TCheckListBox.DrawCheck (модуль CheckLst, компонент TCheckListBox на закладке additional)


 
Andriy Tysh ©   (2005-03-07 20:53) [3]

//Из MSDN
Мда, там я тоже такое читал. Значит правда.
//TCheckListBox.DrawCheck
Я пробовал это, но рисует "снизу", "наверх" никак не удаётся поставить.
//StateImages
Придётся так и сделать.


 
GuAV ©   (2005-03-07 22:00) [4]

2 Andriy Tysh ©  

enjoy...

Класс ImageList"а

unit CheckImg;

interface

{ использовать темы ХР, если есть.
 в D6 AFAIR не пойдёт, поэтому т.к. сабж [D6, D7] сделал DEFINE - убрать в D6}
{$DEFINE USE_THEMES_D7}

uses
 Windows, SysUtils, Variants, Classes, Graphics, StdCtrls,
 ImgList {$IFDEF USE_THEMES_D7} , Themes {$ENDIF} ;

type
 TCheckBoxesImageList = class(TCustomImageList)
 private
   FCheckWidth, FCheckHeight: Integer;
   FFlat: Boolean;
   procedure DrawCheck(R: TRect; AState: TCheckBoxState;
      Canvas: TCanvas; AEnabled: Boolean);
   procedure GetCheckSize;
 public
   constructor Create(AOwner: TComponent); override;
   property Flat: Boolean read FFlat write FFlat default True;
 end;

implementation

procedure TCheckBoxesImageList.GetCheckSize;
begin
 with TBitmap.Create do
   try
     Handle := LoadBitmap(0, PChar(OBM_CHECKBOXES));
     FCheckWidth := Width div 4;
     FCheckHeight := Height div 3;
   finally
     Free;
   end;
end;

{ TCheckBoxesImageList }

constructor TCheckBoxesImageList.Create(AOwner: TComponent);
var B: TBitmap; State: TCheckBoxState; R: TRect;
begin
 inherited;
 Flat := True;
 GetCheckSize;
 B := TBitmap.Create;
 try
   B.Width := Width;
   B.Height := Height;
   {Почему-то ImageState = 0 не работает...
    запишем тогда туда пустой bitmap}
   AddMasked(B, clWhite);
   R.Left := (Width - FCheckWidth + 1) div 2;
   R.Top := (Height - FCheckHeight + 1) div 2;
   R.Right := R.Left + FCheckWidth;
   R.Bottom := R.Top + FCheckHeight;

   for State := Low(State) to High(State) do
   begin
     DrawCheck(R, State, B.Canvas, True);
     AddMasked(B, clWhite);
   end;
 finally
   B.Free;
 end;
end;

procedure TCheckBoxesImageList.DrawCheck(R: TRect;
 AState: TCheckBoxState; Canvas: TCanvas; AEnabled: Boolean);
var
 DrawState: Integer;
 {$IFDEF USE_THEMES_D7}
 ElementDetails: TThemedElementDetails;
 {$ENDIF}
begin
 with Canvas do
 begin
  {$IFDEF USE_THEMES_D7}
  if ThemeServices.ThemesEnabled then
  begin
     case AState of
       cbChecked:
         if AEnabled then
           ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal)
         else
           ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxCheckedDisabled);
       cbUnchecked:
         if AEnabled then
           ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxUncheckedNormal)
         else
           ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxUncheckedDisabled)
       else // cbGrayed
         if AEnabled then
           ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxMixedNormal)
         else
           ElementDetails := ThemeServices.GetElementDetails(tbCheckBoxMixedDisabled);
     end;
     ThemeServices.DrawElement(Handle, ElementDetails, R);
   end
   else
   {$ENDIF}
   begin
     case AState of
       cbChecked:
         DrawState := DFCS_BUTTONCHECK or DFCS_CHECKED;
       cbUnchecked:
         DrawState := DFCS_BUTTONCHECK;
       else // cbGrayed
         DrawState := DFCS_BUTTON3STATE or DFCS_CHECKED;
     end;
     if Flat then
       DrawState := DrawState or DFCS_FLAT;
     if not AEnabled then
       DrawState := DrawState or DFCS_INACTIVE;
     DrawFrameControl(Handle, R, DFC_BUTTON, DrawState);
   end;
 end;
end;

end.



type
 TForm1 = class(TForm)
   TreeView1: TTreeView;
   procedure FormCreate(Sender: TObject);
   procedure TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure TreeView1KeyPress(Sender: TObject; var Key: Char);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

uses CheckImg;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 TreeView1.StateImages := TCheckBoxesImageList.Create(Self);
end;

procedure ChangeState(Item: TTreeNode);
begin
 if Item = nil then Exit;
 with Item do
   case StateIndex of
     1: StateIndex := 2;
     2: StateIndex := 3;
     3: StateIndex := 1;
   end;
end;

procedure TForm1.TreeView1MouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
var TVInfo: TTVHitTestInfo;
begin
 {реакция на клик по чекбоксу}
 TVInfo.pt := Point(X, Y);
 if TControl(Sender).Perform(TVM_HITTEST, 0, LPARAM(@TVInfo)) <> 0 then
 if TVinfo.flags and TVHT_ONITEMSTATEICON <> 0 then
   ChangeState(TreeView1.Items.GetNode(TVInfo.hItem));
end;

procedure TForm1.TreeView1KeyPress(Sender: TObject; var Key: Char);
begin
 {реакция на пробел}
 if Key = " " then
 begin
   Key := #0;
   ChangeState(TreeView1.Selected);
 end;
end;

end.



PS: у меня работает - D7 Win98.


 
GuAV ©   (2005-03-07 22:04) [5]

Ставить в ItemState 1 для Unchecked, 2 для Checked, 3 для Grayed.


 
Andriy Tysh ©   (2005-03-08 10:16) [6]

Спасибо, буду пробовать!

PS: Всегда приятно, когда человек делится не только соображениями, но и кодом. Тогда уж понятнее всё становится.


 
Andriy Tysh ©   (2005-03-08 11:13) [7]

Заработало!



Страницы: 1 вся ветка

Текущий архив: 2005.03.20;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.028 c
3-1108621132
Denmin
2005-02-17 09:18
2005.03.20
Как запретить Append в таблице?


3-1108785324
DelphiN!
2005-02-19 06:55
2005.03.20
Отправка SQL запроса на сервер Interbase через IbDataSet


1-1109677618
Kolokoltsov
2005-03-01 14:46
2005.03.20
ToolBar


9-1104128352
Макс
2004-12-27 09:19
2005.03.20
glscene dynamic collision.


14-1109313879
Cosinus
2005-02-25 09:44
2005.03.20
Не загружается Windows2000. После ввода пароля,просто синий экран