I have my own Treeview control derived from TCustomTreeView
.
I have added some of my own procedures to the class such as adding nodes. When this procedure is called at runtime I wanted the newly added node to be selected and for the Treeview to be focused so the new node is highlighted.
Here is a extract:
procedure TMyTreeView.AddGroup(AName: string);
var
Node: TTreeNode;
Obj: TGroup;
procedure AddToTree;
begin
Obj := TGroup.Create(AName);
FGroups.Add(Obj);
Node := Items.AddObject(Node, AName, Obj);
with Node do
begin
ImageIndex := 0;
SelectedIndex := 0;
end;
Selected := Node;
SetFocus;
end;
begin
Node := nil;
AddToTree;
end;
The above works but I am facing the common error message when calling from the Forms OnCreate
event:
Cannot focus a disabled or invisible window
I know you can use the OnActivate
event or just don't use OnCreate
at all which will not result in the error, but anyone else who may use the component may not realise this.
So I wanted to know if there is a way to determine if my Treeview (or any control) is able to receive the focus, then I could add a little checking of my own, something like:
if ControlIsFocusable then
begin
Selected := Node;
SetFocus;
end;
I know there is the Loaded
procedure you can override which tells us when the control is loaded but then that would only work on first run. If the control became hidden by the user at runtime (or was not visible to begin with) the Cannot focus a disabled or invisible window
error is still going to show up.
The dirty way to do it when not run in the debugger is:
try
Selected := Node;
SetFocus;
except
end;
But that defeats the purpose and I hate handling errors in this way.
So basically I wanted to know if there was a way to determine if a control can receive focus, so that we can set the focus to it?
I'm not going to answer the question that you asked, because I think you are doing this wrong.
The control should not call SetFocus
on itself. I can imagine no scenario where that is the correct behaviour. The form or application or framework should determine focus. Not the control.
Imagine what happens when you have a form with two such controls? Imagine using the keyboard to focus a button, which you then press with the SPACE bar. If the action attached to the button calls your control's method which then changes the focus, you've just gone against the platform UI guidelines. You control now places a severe burden on any application that attempts to consume it.