Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Как найти размеры "галочки"


Автор: Тутанхамец 21.1.2007, 11:20
Здравствуйте. Есть TreeView с TVS_CHECKBOXES. Мне нужно обрабатывать снятие/установку "галочки". Ничего кроме вот этого в голову не пришло:
Код

procedure TForm1.tvWindowsMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  node:Ttreenode;
  i,h:DWORD;
begin
  node:=tvwindows.GetNodeAt(x,y);
  if node<>nil then begin
    if ((node.DisplayRect(true).left-x<15) and  (node.DisplayRect(true).left-x>0)) then begin
    {Тут выполняется код, который надо выполнять, если юзер поставил/снял галочку} 
     end;
  end;
end;


Это плохой код. Потому что длина чекбокса без особых причин принимается за 15. Но вдруг она по каким-то причинам станет другой? В общем, как узнать длину этого квадратика с галочкой?

Автор: Sunvas 21.1.2007, 11:36
Тутанхамец, да. Твой вариант неверен хотя бы потому, что можно же еще и клавиатурой ставить галочки.

Цитата(Тутанхамец @  21.1.2007,  11:20 Найти цитируемый пост)
 TreeView с TVS_CHECKBOXES

А куда это свойсво пихать - что-то не найду. У тебя стандартный компонент? Если ответишь на это попробую тебе набросать код.

Автор: Тутанхамец 21.1.2007, 11:37
Некоторое облегчение дает такой вариант:
Код

procedure TForm1.tvWindowsMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  node:Ttreenode;
  i,h:DWORD;
begin
  node:=tvwindows.GetNodeAt(x,y);
  if node<>nil then begin


    if ((tvwindows.Indent+2<x) and  (node.DisplayRect(true).left>x)) then begin  //измененная строка

      i:=node.absoluteindex;
      h:=strtoint(handles[i]);
      if ischeckednode(node) then
        SetWindowPos (h, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE)
      else
        SetWindowPos (h, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE);
          end;
  end;
end;


Но это всё равно не совсем то, что хотелось бы. Лучше было бы узнавать размер чекбокса.

Добавлено @ 11:38 
Блин, про клаву я и не подумал...

ЧТоб у treeview появились чекбоксы я делаю так:
Код

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetWindowLong(TvWindows.Handle, GWL_STYLE, GetWindowLong(TvWindows.Handle, GWL_STYLE) or TVS_CHECKBOXES);
end;


Добавлено @ 11:38 
В смысле, компонент стандартный. TTreeView.

Автор: Sunvas 21.1.2007, 11:52
Цитата(Тутанхамец @  21.1.2007,  11:37 Найти цитируемый пост)
TVS_CHECKBOXES

А откуда эта константа?

Автор: Тутанхамец 21.1.2007, 15:20
Модуль CommCtrl. 

Автор: Sunvas 21.1.2007, 17:24
Общем поэкспериментировал я над твоим кодом. Довольно интересно было, но ничего лучше твоего не получилось.
Вот только тебе код как узнать ширину Check-a
Код

var
  b:Bitmap;
  CheckWidth: word;
begin
GetObject(LoadBitmap(0, PChar(OBM_CHECKBOXES)),SizeOf(BITMAP),@b);
CheckWidth := b.bmWidth div 4;


Следовательно тебе надо проверять. Область нажатия мыши. Думаю сам справишься.
И не забываей о пробеле.

Автор: Тутанхамец 21.1.2007, 17:41
Спасибо, Sunvas. smile

Мой код с indent'ом не будет работать с любым Node, который находитcя HE в корневухе TreeView. У нодов-потомков отступ от левого края будет не один indent, а несколько, но неизвестно сколько именно. К счастью, у меня все ноды именно в корневухе. 

Я правильно понял, что твой код выдает ширину ЛЮБОГО стандартного чекбокса в системе? Или только чекбокса в моей проге?




Автор: Sunvas 21.1.2007, 17:49
Цитата(Тутанхамец @  21.1.2007,  17:41 Найти цитируемый пост)
код выдает ширину ЛЮБОГО стандартного чекбокса в системе

По идее так.
Цитата(Тутанхамец @  21.1.2007,  17:41 Найти цитируемый пост)
К счастью, у меня все ноды именно в корневухе. 

Тогда зачем тебе дерево, если ты используешь только корневые ноды?

Автор: Тутанхамец 21.1.2007, 17:51
Цитата

Тогда зачем тебе дерево, если ты используешь только корневые ноды? 


Потому что сначала предполагал, что эти ноды будут не только корневые. А еще потому, что в дереве можно к ноду добавлять маленькую картинку, а как это сделать с CheckListBox я не нашел. 

Автор: aktuba 21.1.2007, 17:55
Тутанхамец, а не лучше вместо стандартного дерева использовать VirtualTreeView?
И с отображением изображений проблем нет, и с checkbox-ами тоже, да и на будущее, если вдруг понадобиться использовать древовидную структуру, полезно...

Автор: Тутанхамец 21.1.2007, 17:58
Наверное проще, но неохота юзать нестандартные компоненты. Работать приходится на том компе, который в данный момент не занят. Дельфа-то на них на всех стоит, а вот каждый раз устанавливать доп. компоненты неудобно. 

Автор: Sunvas 21.1.2007, 18:01
Тутанхамец, а тогда чем тебя CheckListBox не устаивает?

Автор: Тутанхамец 21.1.2007, 18:07
Тем, что я не нашел у CheckListBox свойства Images и решил, что туда нельзя впихнуть картинку. Хотя именно сейчас читаю про owner-draw и потихоньку понимаю, как ее туда впихнуть. 

Ребята, большое спасибо. Похоже, я выбрал не тот путь решения задачи. Вопрос закрыт. 


Автор: ~FoX~ 15.2.2007, 08:25
Цитата(Тутанхамец @  21.1.2007,  19:07 Найти цитируемый пост)
ем, что я не нашел у CheckListBox свойства Images и решил, что туда нельзя впихнуть картинку.

Может уже и поздно, однако:
Код

procedure TForm1.CheckListBox1DrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  Bitmap: TBitmap;
  Offset: Integer;
  BMPRect: TRect;
begin
  with (Control as TCheckListBox).Canvas do
  begin
    FillRect(Rect);
    Bitmap := TBitmap.Create;

   ImageList1.GetBitmap(0, Bitmap);
    Offset := 0;
    if Bitmap <> nil then

    begin
      BMPRect := Bounds(Rect.Left+2, Rect.Top+2, (Rect.Bottom-Rect.Top-2), Rect.Bottom-Rect.Top-2);
      BrushCopy(BMPRect,Bitmap, Bounds(0, 0, Bitmap.Width, Bitmap.Height),
      Bitmap.Canvas.Pixels[0, Bitmap.Height-1]);
      Offset := (Rect.Bottom-Rect.Top+1)+3;
    end;
    TextOut(Rect.Left+Offset, Rect.Top, CheckListBox1.Items[index]);
    Bitmap.Free;
  end;

end;

Автор: Тутанхамец 15.2.2007, 17:30
Вообще-то поздно, но все равно спасибо. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)