This forum is temporaily read-only. All existing discussions remain available for reference. For new questions, bug reports or support requests, please contact us at mail@lmdsupport.com.
ElTreeInplaceDateTimePicker on ElXTree raises Contol '' has no parent window. LMD ElPack 2018
If the DateTimePicker is editing, and you click outside it on the tree, it raises this error. I AM on the LMD ElPack 2018.0(22-01/2018).
On Rad Studio, Delphi, Tokyo 10.2, update 2.
An example with instructions is attached.
Best regards,
Louis Kriel

Comments
<Removed>
I have a TElXTree on a form with 7 sections. The 2nd section is a Text field that is marked Editable. I have a TElTreeInplaceEdit on the form associated with the TElXTree.
I use 3 events for the InplaceEdit:
procedure TOrganizePages.TagsDisplayInplaceEditEditorOnKeyUp(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
DoEditorOnKeyUp(TagsList, TDisplayAsCol, TCustomElEdit(Sender), Key, Shift);
end;
procedure DoEditorOnKeyUp(ElXTree: TElXTree; const EditColumn: integer; var ElEdit: TCustomElEdit;
var Key: word; Shift: TShiftState);
var
CurItem: TElXTreeItem;
INext: Integer;
begin
VK_F2:
ElXTree.EndEdit(false);
if ssCtrl in Shift then { Ctrl part of Ctrl-A }
ElEdit.SelectAll;
if ssCtrl in Shift then { Ctrl part of Ctrl-Z }
ElEdit.Undo;
ElXTree.Items.BeginUpdate;
{ Note: this isn't perfect from near the bottom of the tree, but it's close enough }
INext := ElXTree.TopIndex -(ElXTree.BottomIndex - ElXTree.ItemFocused.AbsoluteIndex);
if ElXTree.BottomIndex >= (ElXTree.Items.Count - 1) then
INext := INext - 1;
ElXTree.EndEdit(false);
ElXTree.Perform(WM_VSCROLL, SB_PAGEUP, 0);
ElXTree.ItemFocused := ElXTree.Items[INext];
ElXTree.Items.EndUpdate;
end;
ElXTree.Items.BeginUpdate;
INext := ElXTree.BottomIndex + ElXTree.ItemFocused.AbsoluteIndex - ElXTree.TopIndex;
if INext > ElXTree.Items.Count then INext := ElXTree.Items.Count - 1;
ElXTree.EndEdit(false);
ElXTree.Perform(WM_VSCROLL, SB_PAGEDOWN, 0);
ElXTree.ItemFocused := ElXTree.Items[INext];
ElXTree.Items.EndUpdate;
end;
if ssCtrl in Shift then { Ctrl part of Ctrl-Home } begin
ElXTree.Items.BeginUpdate;
ElXTree.EndEdit(false);
ElXTree.ItemFocused := ElXTree.Items[0];
ElXTree.Items.EndUpdate;
ElXTree.ItemFocused.MakeVisible;
end;
end;
if ssCtrl in Shift then { Ctrl part of Ctrl-End } begin
ElXTree.Items.BeginUpdate;
ElXTree.EndEdit(false);
ElXTree.ItemFocused := ElXTree.Items[ElXTree.Items.Count-1];
ElXTree.Items.EndUpdate;
ElXTree.ItemFocused.MakeVisible;
end;
end;
begin
ElXTree.Items.BeginUpdate;
CurItem := ElXTree.ItemFocused;
CurItem := CurItem.GetNext;
while CurItem <> nil do begin
ElXTree.ItemFocused := CurItem;
if CurItem.IsVisible and CurItem.AllowEdit then begin
ElXTree.EndEdit(false);
ElXTree.EditItem(CurItem, EditColumn);
break;
end;
CurItem := CurItem.GetNext;
end;
if CurItem = nil then { at the bottom }
ElXTree.EditItem(ElXTree.ItemFocused, EditColumn);
ElXTree.Items.EndUpdate;
ElXTree.ItemFocused.MakeVisible;
Key := 0;
end;
begin
ElXTree.Items.BeginUpdate;
CurItem := ElXTree.ItemFocused;
CurItem := CurItem.GetPrev;
while CurItem <> nil do begin
ElXTree.ItemFocused := CurItem;
if CurItem.IsVisible and CurItem.AllowEdit then begin
ElXTree.EndEdit(false);
ElXTree.EditItem(CurItem, EditColumn);
break;
end;
CurItem := CurItem.GetPrev;
end;
if CurItem = nil then { at the top }
ElXTree.EditItem(ElXTree.ItemFocused, EditColumn);
ElXTree.Items.EndUpdate;
ElXTree.ItemFocused.MakeVisible;
Key := 0;
end;
end;
end;
If I change text in the field and just hit Enter, or any of the keys in the above routine (e.g. arrow up, Home, etc) , there is no problem and it works as it should.
But if I change text in the field and then use the mouse to click on another field or any other window, when I'm in the Delphi debugger, it brings up a Debugger Exception Notification window that says: "Project raised exception class EInvalidOperation with message 'Control '' has no parent window' leading to the Windows exception "Control '' has no parent window."
If I break the debugger a that exception, the line in ElTreeStdEditors it was at was the last line of EditorWndProc:
SaveWndProc(Message);
This is the routine I use:
procedure TElTreeInplaceEdit.EditorWndProc(var Message : TMessage);
var
InputValid : boolean;
begin
if Message.Msg = WM_GETDLGCODE then
begin
inherited;
Message.Result := Message.Result or DLGC_WANTCHARS or DLGC_WANTARROWS or DLGC_WANTALLKEYS;
end
else
if Message.Msg = WM_KEYDOWN then
begin
TriggerKeyDown(TWMKey(Message));
with TWMKey(Message) do
begin
if KeyDataToShiftState(KeyData) = [] then
begin
if CharCode = VK_RETURN then
begin
InputValid := true;
FEditing := false;
TriggerValidateResult(InputValid);
FEditing := true;
if InputValid then
begin
CompleteOperation(true);
CharCode := 0;
exit;
end
else
Editor.SetFocus;
CharCode := 0;
end
else
// LK 31 May 2011 - End of Removed VK_RETURN so I can catch it myself *)
begin
CompleteOperation(false);
CharCode := 0;
exit;
end;
end;
end;
end
else
if (Message.Msg = WM_CANCELMODE) or
((Message.Msg = CM_CANCELMODE) and
(TObject(Pointer(Message.lParam)) <> Editor)) or
(Message.Msg = WM_KILLFOCUS) then
if FEditing then
begin
if THackElTree(Tree).FExplorerEditMode then
begin
EndEditWithInputChecked;
end
else
CompleteOperation(false);
SendMessage(THackElTree(Tree).View.Handle, CM_EXIT, 0, 0);
end;
SaveWndProc(Message);
end;
If you can see what might be causing this, or a possible patch for this, please let me know.
Also feel free to also give me any suggestions to capture keys like I'm doing if you think there's a better way.
If you need more screenshots or code than I can supply here, please email me: lkessler at lkessler dot com
Thanks.
Louis Kessler
Winnipeg, Manitoba, Canada
And just to make sure, I added back the code that I removed, and the issue still happens. So it does not appear to have anything to do with the handler I added or the changes I made.
ElXTree.TElXTreeView.WndProc - the last line: inherited
which calls a few vcl routines and then
((Message.Msg = CM_CANCELMODE) and
(TObject(Pointer(Message.lParam)) <> Editor)) or
(Message.Msg = WM_KILLFOCUS) then
if FEditing then
begin
if THackElTree(Tree).FExplorerEditMode then
begin
EndEditWithInputChecked;
end
else
CompleteOperation(false);
if Message.Msg <> CM_CANCELMODE then
SendMessage(THackElTree(Tree).View.Handle, CM_EXIT, 0, 0);
end;
SaveWndProc(Message);
CompleteOperation(false);
exit;
end;
So in
((Message.Msg = CM_CANCELMODE) and
(TObject(Pointer(Message.lParam)) <> Editor)) or
(Message.Msg = WM_KILLFOCUS) then
if FEditing then
begin
if THackElTree(Tree).FExplorerEditMode then
begin
EndEditWithInputChecked;
end
else
CompleteOperation(false);
if Message.Msg <> CM_CANCELMODE then
SendMessage(THackElTree(Tree).View.Handle, CM_EXIT, 0, 0);
end;
SaveWndProc(Message);