#delphi #winapi #controls #caret #delphi-6
#delphi #winapi #элементы управления #курсор #delphi-6
Вопрос:
Следующая _isEdit
функция определяет, можно ли применить ввод к текущему сфокусированному элементу управления:
class function TSpeedInput._getFocusedControlClassName(): WideString;
var
lpClassName: array[0..1000] of WideChar;
begin
FillChar(lpClassName, SizeOf(lpClassName), 0);
Windows.GetClassNameW(GetFocus(), PWideChar(@lpClassName), 999);
Result := lpClassName;
end;
class function TSpeedInput._isEdit(): Boolean;
const
CNAMES: array[0..3] of string = ('TEdit', 'TMemo', 'TTntMemo.UnicodeClass',
'TTntEdit.UnicodeClass');
var
cn: WideString;
i: Integer;
begin
Result := False;
cn := _getFocusedControlClassName();
for i := Low(CNAMES) to High(CNAMES) do
if cn = CNAMES[i] then begin
Result := True;
Exit;
end;
//MessageBoxW(0, PWideChar(cn), nil, 0);
end;
Что мне в этом не нравится, так это жесткое кодирование списка имен классов. Можно ли обнаружить, что текущее сфокусированное окно принадлежит к семейству редакторов или, лучше сказать, что оно имеет активную каретку? (в порядке, который _isEdit
возвращает False
для WhateverItIsControl, который находится в режиме только для чтения).
Комментарии:
1. Посмотрите на: codeproject.com/Articles/34520 /…
2. Элемент управления, доступный только для чтения, может отображать курсор. Действительно, обычно это так, чтобы вы могли копировать текст.
3. В любом случае, вы можете попробовать скрыть курсор. Если это удастся, покажите его снова и обратите внимание, что отображался курсор.
Ответ №1:
Если Handle
элемент управления выделен, вы можете использовать этот хак:
function IsEdit(AControl: TWinControl): boolean;
begin
if AControl.HandleAllocated then
begin
Result := SendMessage(AControl.Handle, EM_SETREADONLY,
WPARAM(Ord(AControl.Enabled)), 0) <> 0;
end
else
begin
Result := AControl is TCustomEdit;
end;
end;
Ответ №2:
Если интересующие вас элементы управления находятся в определенной форме и принадлежат этой форме (и являются стандартными элементами управления Delphi), вы можете использовать следующее:
function TFormML2.FocusIsEdit: boolean;
var
i : integer;
begin
Result := FALSE;
for i := 0 to ComponentCount - 1 do
begin
if Components[ i ] is TCustomEdit then
begin
if (Components[ i ] as TCustomEdit).Focused and not (Components[ i ] as TCustomEdit).ReadOnly then
begin
Result := TRUE;
break;
end;
end;
end;
end;
Если вы знаете форму и можете передать ее в качестве параметра, вы могли бы сделать что-то подобное.
TCustomEdit является предком всех полей редактирования, заметок и т. Д.
Комментарии:
1. Несколько замечаний: (1) При этом будут найдены только элементы управления, принадлежащие
TFormML2
. Эта форма вполне может содержать элементы управления, не принадлежащие ей. (2) Не проще ли использоватьFindControl
функцию? (3) Не все элементы управления редактированием являются производными отTCustomEdit
. Например, мой собственныйTTextEditor
происходит отTCustomControl
.2. @AndreasRejbrand Спасибо за ваши комментарии. Я знал, что это может быть не совсем то, чего хочет OP, но опять же это может быть. Он, например, специально запрашивает, доступно ли оно только для чтения. Но я согласен, это только все собственные элементы управления Delphi VCL, которые являются производными от TCustomEdit. Я думал, что упоминал, что форма должна владеть элементами управления, но при чтении назад я вижу, что я этого не сделал. Я отредактирую..
3. OP использует
Application.OnMessage
, чтобы элемент управления редактированием мог быть в любой форме. Все, что у меня есть, это дескриптор.