Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Определение способа получения фокуса компонентом в Delphi

Delphi , Синтаксис , Деревья

Заголовок:

Возникновение фокуса у компонента в приложении Delphi может происходить разными способами: при нажатии клавиши Tab, при щелчке мышью или другими способами. В некоторых случаях может потребоваться определить, каким именно способом компонент получил фокус. В этой статье мы рассмотрим, как это можно сделать.

Обновление 1: Действительно, речь идет о компоненте TVirtualStringTree, который должен открывать кастомный редактор, фокусируясь на определенной колонке в зависимости от того, как он получил фокус.

Обновление 2: Давайте рассмотрим приведенный ниже код, который пытается решить эту задачу:

procedure TForm1.Tree1Click(Sender: TObject);
var
  Tree: TVirtualStringTree;
  Click: THitInfo;
  HitNode: PVirtualNode;
  HitColumn: TColumnIndex;
  col: Integer;
begin
  Tree:= Sender as TVirtualStringTree;
  Tree.GetHitTestInfoAt(Mouse.CursorPos.X-Tree.ClientOrigin.X, Mouse.CursorPos.Y-Tree.ClientOrigin.Y, True, Click);

  HitNode:= Click.HitNode;
  if not Assigned(Click.HitNode) and Assigned(Tree.FocusedNode) then
    HitNode:= Tree.FocusedNode;

  HitColumn:= Click.HitColumn;

  //get first visible and editable column
  if (HitColumn <= NoColumn) or
     ((HitColumn > NoColumn) and
      (not (coVisible in Tree.Header.Columns.Items[HitColumn].Options) or
       not (coEditable in Tree.Header.Columns.Items[HitColumn].Options))) then
    if Tree.Header.Columns.Count > 0 then
      for col := 0 to Tree.Header.Columns.Count - 1 do
        if (coVisible in Tree.Header.Columns.Items[col].Options) and
           (coEditable in Tree.Header.Columns.Items[col].Options) then
        begin
          HitColumn:= col;
          Break;
        end;

  if Assigned(HitNode) and (HitColumn > NoColumn) then
    Tree.EditNode(HitNode,HitColumn);
end;

procedure TForm1.Tree1Enter(Sender: TObject);
var
  Tree: TVirtualStringTree;
  Click: THitInfo;
  HitNode: PVirtualNode;
  HitColumn: TColumnIndex;
  col: Integer;
begin
  Tree:= Sender as TVirtualStringTree;

  HitNode:= Tree.FocusedNode;

  if not Assigned(Tree.FocusedNode) then
    HitNode:= Tree.GetFirstVisible;

  HitColumn:= NoColumn;

  //get first visible and editable column
  if Tree.Header.Columns.Count > 0 then
    for col := 0 to Tree.Header.Columns.Count - 1 do
      if (coVisible in Tree.Header.Columns.Items[col].Options) and
         (coEditable in Tree.Header.Columns.Items[col].Options) then
      begin
        HitColumn:= col;
        Break;
      end;

  if Assigned(HitNode) and (HitColumn > NoColumn) then
    Tree.EditNode(HitNode,HitColumn);
end;

Задача автора кода состоит в том, чтобы редактировать первую колонку фокусируемого узла, если фокус получен при нажатии клавиши Tab, или редактировать колонку, на которой был щелчок мыши, если фокус получен таким образом. Однако, при щелчке на компоненте сначала срабатывает событие OnEnter, а затем OnClick, что приводит к тому, что команда EditNode выполняется дважды.

Решение: Для определения способа получения фокуса компонентом можно воспользоваться следующим подходом:

  1. Переопределить обработчик события WMKeyUp в компоненте TVirtualStringTree, чтобы отслеживать нажатие клавиши Tab:
type
  TCustomVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
  private
    FTabPressed: Boolean;
  protected
    procedure WMMouseDown(var Message: TWMMouse); message WM_LBUTTONDOWN;
    procedure WMMouseUp(var Message: TWMMouse); message WM_LBUTTONUP;
    procedure WMKeyUp(var Message: TWMKeyUp); message WM_KEYUP;
    property TabPressed: Boolean read FTabPressed;
  end;

procedure TCustomVirtualStringTree.WMKeyUp(var Message: TWMKeyUp);
begin
  if Message.CharCode = VK_TAB then
    FTabPressed := True;
  inherited;
  FTabPressed := False;
end;
  1. В обработчике события OnEnter компонента TVirtualStringTree проверить значение свойства TabPressed. Если оно равно True, значит фокус получен при нажатии клавиши Tab, иначе - при щелчке мышью:
procedure TForm1.Tree1Enter(Sender: TObject);
begin
  if TCustomVirtualStringTree(Sender).TabPressed then
    // фокус получен при нажатии клавиши Tab
  else
    // фокус получен при щелчке мышью
end;

При таком подходе можно определить способ получения фокуса компонентом в зависимости от того, как он был получен: при нажатии клавиши Tab или при щелчке мышью.

Создано по материалам из источника по ссылке.

Вопрос о определении способа получения фокуса компонентом в Delphi, с акцентом на компоненте `TVirtualStringTree` и использовании кастомного редактора в зависимости от того, как компонент получил фокус.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Деревья ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-15 22:34:42/0.0054547786712646/1