Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.20;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.058 c
14-1109446400
mordush
2005-02-26 22:33
2005.03.20
качалка


3-1108716191
msguns
2005-02-18 11:43
2005.03.20
Дата в IB


14-1109589900
1008
2005-02-28 14:25
2005.03.20
Или я чего-то не понял или что-то не работает.


14-1109863401
Dann
2005-03-03 18:23
2005.03.20
Forward declarations in Cpp


1-1109838806
mic_2000
2005-03-03 11:33
2005.03.20
Как в TreeView можно добавить CheckBox к элементам дерева





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский