LCL: New CanSetFocus function with whole parent tree check. Work better than CanFocus in many cases. Issue #21708, patch from Ondrej Pokorny.

git-svn-id: trunk@49526 -
This commit is contained in:
juha 2015-07-11 23:27:51 +00:00
parent 4f0f211f3c
commit 41ca5227fd
3 changed files with 68 additions and 6 deletions

View File

@ -11138,16 +11138,48 @@ End;
</element>
<!-- function Visibility: public -->
<element name="TWinControl.CanFocus">
<short>Is this control allowed to receive the focus?</short>
<descr>A control can get the focus only when all of its Parents except the form are Visible and Enabled.
While CanFocus checks all control parents it does not check whether a form control is placed on can have focus.</descr>
<short>Is this control allowed to receive the focus when parent form is visible?</short>
<descr>
<p>Checks if the control can get focus when parent form is visible, i.e. if all its parents except the form are visible and enabled.
</p>
<p>A possible usage:</p>
<pre>if FormFoo.EditFoo.CanFocus then
FormFoo.ActiveControl := FormFoo.EditFoo;
</pre>
<p>Please note that this function returns True also if the parent form isn't visible and therefore a consecutive SetFocus call could throw an exception. Use <var>CanSetFocus</var> in this case.
</p>
</descr>
<errors/>
<seealso/>
<seealso>
<link id="TWinControl.CanSetFocus"/>
</seealso>
</element>
<element name="TWinControl.CanFocus.Result">
<short/>
</element>
<!-- function Visibility: public -->
<element name="TWinControl.CanSetFocus">
<short>Is this control allowed to receive the focus?</short>
<descr>
<p>Checks if the control can get focus, i.e. if all its parents are visible and enabled.
</p>
<p>A possible usage:</p>
<pre>if MyControl.CanSetFocus then
MyControl.SetFocus;
</pre>
<p><var>CanSetFocus</var> should be prefered over <var>CanFocus</var> if used in CanSetFocus/SetFocus combination
because it checks also if the parent form can receive focus and thus prevents the "cannot focus an invisible window" LCL exception.
</p>
</descr>
<errors/>
<seealso>
<link id="TWinControl.CanFocus"/>
</seealso>
</element>
<element name="TWinControl.CanSetFocus.Result">
<short/>
</element>
<!-- function Visibility: public -->
<element name="TWinControl.GetControlIndex">
<short>Finds the index value for the given control,
in <link id="TWinControl.Controls">Controls[]</link>.

View File

@ -2164,6 +2164,7 @@ type
destructor Destroy; override;
procedure DockDrop(DragDockObject: TDragDockObject; X, Y: Integer); virtual;
function CanFocus: Boolean; virtual;
function CanSetFocus: Boolean; virtual;
function GetControlIndex(AControl: TControl): integer;
procedure SetControlIndex(AControl: TControl; NewIndex: integer);
function Focused: Boolean; virtual;

View File

@ -3604,8 +3604,8 @@ end;
{------------------------------------------------------------------------------
TWinControl CanFocus
------------------------------------------------------------------------------}
function TWinControl.CanFocus: Boolean;
var
@ -3628,6 +3628,35 @@ begin
end;
end;
{------------------------------------------------------------------------------
TWinControl CanSetFocus
CanSetFocus should be prefered over CanFocus if used in CanSetFocus/SetFocus
combination
if MyControl.CanSetFocus then
MyControl.SetFocus;
because it checks also if the parent form can receive focus and thus prevents
the "cannot focus an invisible window" LCL exception.
------------------------------------------------------------------------------}
function TWinControl.CanSetFocus: Boolean;
var
Control: TWinControl;
begin
Control := Self;
while True do
begin
// test if all are visible and enabled
if not (Control.IsControlVisible and Control.Enabled) then
Exit(False);
if not Assigned(Control.Parent) then
Break;
Control := Control.Parent;
end;
Result := Control is TCustomForm;//the very top parent must be a form
end;
{------------------------------------------------------------------------------
TWinControl CreateSubClass
------------------------------------------------------------------------------}