Возникновение фокуса у компонента в приложении 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 выполняется дважды.
Решение:
Для определения способа получения фокуса компонентом можно воспользоваться следующим подходом:
Переопределить обработчик события WMKeyUp в компоненте TVirtualStringTree, чтобы отслеживать нажатие клавиши Tab:
В обработчике события 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
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.