Útržky kódu - focus

vložil Radek Červinka 13. prosince 2012 00:43

V současné době je ovládání programu čistě za pomoci klávesnice podceňované. Ale věřte, že existují uživatelé, kteří na tu krysu nebo touchpad (trackpoint) nešáhnou, jak je den dlouhý. Proto není vhodné podceňovat takové aspekty návrhu UI jako je i TabOrder.

Při zobrazení formuláře je vybrán (focus) prvek, který je povolený a má nejmenší TabOrder a povolený TabStop. Programově se dá focus změnit za pomoci volání metody SetFocus, kterou mají následníci TWinControl (což je předchůdce většiny vizuálních komponent).

  if edt.CanFocus then
    edt.SetFocus;

Pokud chcete ovšem něco podobného provést před zobrazením okna (nebo podle mne i nastavit focus prvku, který je např. na neaktivní záložce TPageControl) tak se dostane do problémů s vyjímkou Cannot focus a disabled or invisible window.

A tím se dostávám k jádru. V takovém případě stačí nastavit property ActiveControl dotyčného formuláře a změna bude po zobrazení aktivní.

procedure TForm4.Button1Click(Sender: TObject);
begin
  with TForm1.Create(nil) do
  begin
    try
//       Button1.SetFocus; // bug
      ActiveControl := Button1;
      ShowModal;
    finally
      Free;
    end;
  end;
end;

Tagy:

Začátečníci

Komentáře

13.12.2012 19:00:40 #

Zdeněk Vašků

Když už jsi narazil na TabOrder, tak by se hodilo i doplnit, jak to jde docela pohodlně pomocí GExperts.

Z

Zdeněk Vašků

13.12.2012 19:27:03 #

oxo

Já měl problém s CanFocus když byl formulář s komponentou neviditelný. Pak CanFocus chybně vracel True i když vlastně měl vracet False (viz implementaci TWinControl.CanFocus) - nevím, jestli to je záměr, nebo bug, ale podle mě bug (jestli se pletu, tak mě opravte).

Oprava:

  TOWinControlHelper = class helper for TWinControl
  public
    function RealCanFocus: Boolean;
  end;

function TOWinControlHelper.RealCanFocus: Boolean;
var xForm: TCustomForm;
begin
  xForm := GetParentForm(Self);
  Result := Assigned(xForm) and (xForm.Visible) and (xForm.Enabled) and Self.CanFocus;
end;

oxo

14.12.2012 11:16:46 #

radekc

Cílem článku mělo být spíše upozornění na ActiveControl , TabOrder bylo jen taková omáčka kolem :-).

oxo: to je pěkné použití ClassHelperu. Jinak v tomto případě to není jisté, zda se jedná o bug - ale podle mne asi ano.

radekc

14.12.2012 12:47:43 #

oxo

Asi to bude bug, zkouška:

procedure TForm1.Action1Execute(Sender: TObject);
var
  xMF: TForm;
begin
  xMF := TForm.CreateNew(nil);
  try
    with TMemo.Create(xMF) do begin
      Parent := xMF;
      if RealCanFocus then// = FALSE
        SetFocus;
      if CanFocus then// = TRUE
        SetFocus;//CHYBA
    end;

    xMF.ShowModal;

  finally
    xMF.Free;
  end;
end;

oxo

14.12.2012 12:54:55 #

oxo

ještě bych dodal, že ta moje zkouška je samozřejmě trochu mimo praktické použití (jde právě jen o demonstraci), ale pokud používáte formuláře, které se nějakým způsobem dají schovat, tak přesně na tento problém narazíte.

oxo

Komentování ukončeno

Naše nabídka

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy).

love Delphi

O Delphi.cz

Delphi je moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64, Mac OSX, Linux a na iPhone a Android.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Poslední komentáře

Comment RSS

Dle měsíců