Paul
Paul

Reputation: 26690

Determine whether a focused window has an active caret

Following _isEdit function detects whether input could be applied to the currently focused control:

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;

What I don't like about it is the hard coding of the class name list. Could it be detected that a currently focused window belongs to the editors family or, better to say, that it has an active caret? (in order that _isEdit returns False for a WhateverItIsControl that is in read-only mode).

Upvotes: 1

Views: 154

Answers (2)

Dsm
Dsm

Reputation: 6013

If the controls you are interested in are on a specific form and are owned by that form (and are standard Delphi controls) you could use the following:

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;

If you know the form and can pass it as a parameter, you could do something similar.

TCustomEdit is the ancestor of all edit boxes, memos, etc.

Upvotes: 2

dwrbudr
dwrbudr

Reputation: 817

If the Handle of the control is allocated, you can use this hack:

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;

Upvotes: 2

Related Questions