count - Delphi: TreeView elements vs. Form position changing -
we have found seems bug(?), , cause bug in our code.
delphi xe3, win32. 2 forms, main have button:
procedure tform4.button1click(sender: tobject); begin tform1.create(application) begin showmodal; release; end; end;
the form1 doing this:
procedure tform1.formcreate(sender: tobject); var i, j: integer; mn: ttreenode; begin := 1 10 begin mn := treeview1.items.add(nil, 'm' + inttostr(i)); j := 1 10 begin treeview1.items.addchild(mn, 'c' + inttostr(j)); end; end; position := podesigned; beep; caption := inttostr(treeview1.items.count); end;
after 0 elements in caption.
but when have button in form code...
procedure tform1.button1click(sender: tobject); begin caption := inttostr(treeview1.items.count); end;
...
then can see number (110 elements).
if write treeview1.handleneeded after position changing, count good.
the problem based on recreatewnd, calls destroyhandles. repaired in show (in activate event can see result too).
treeview special control, because tree elements children, , count calculated on them, no matter have real sub-object list.
the main problem recreatewnd called methods to, can cause problems in sections too, , cannot put handleneeded before .count calculation.
(we have special base form correct position podesigned if poscreencenter can positionable later. happens after formcreate call, in inner method. found problem these kind of forms, later reproduce in simple code too)
so question - global solution problem?
(did experience in xe5 too?)
thank help, info, doc.
the form's hwnd
getting destroyed when set position
. destroys child hwnds. treeview's hwnd
has not been re-created yet when read count
, why reports 0. calling treeview.handleneeded
after setting position
forces treeview re-create hwnd
immediately, re-load treenodes had beencached internally when treeview's hwnd
destroyed (but if treeview.createwndrestores
property true, default).
a treeview stores child nodes inside of hwnd
. reading items.count
merely asks hwnd
how many nodes has, if there no hwnd
count
0. ttreeview
not keep own list of ttreenode
objects, merely assigns them user-defined data in physical nodes themselves. when nodes removed tree, ttreeview
frees associated ttreenode
objects. in case of hwnd
recreation, ttreeview
caches ttreenode
data , re-assigns new nodes when hwnd
re-created. again, not keep track of ttreenode
objects.
what ttreeview
have done store current number of nodes during hwnd
destruction, , have items.count
return value if hwnd
has not been re-created yet. alas, ttreeview
not that. implement manually subclassing ttreeview
intercept createwnd()
, destroywnd()
methods, , write own function returns actual items.count
when handleallocated
true , returns cached value if false.
if form visible user hwnd
(and hwnd
of children) available, since control not visible without hwnd
, items.count
available if ttreeview
visible user. if hwnd
ever destroyed while visible, vcl re-create hwnd
user not see missing control. however, if form (or treeview) not visible user when hwnd
destroyed, hwnd
not re-created until needed when form/treeview made visible again.
since forcing position
podesigned
@ time of form creation, why not set position
podesigned
@ design-time? otherwise, can set position
before populating treeview instead of afterwards, @ least:
procedure tform1.formcreate(sender: tobject); var i, j: integer; mn: ttreenode; begin position := podesigned; // <-- here := 1 10 begin mn := treeview1.items.add(nil, 'm' + inttostr(i)); // <-- first call add() forces hwnd recreation if needed j := 1 10 begin treeview1.items.addchild(mn, 'c' + inttostr(j)); end; end; beep; caption := inttostr(treeview1.items.count); // <-- correct value reported end;
this happens in versions of delphi. how things work in vcl.
on side note, should use free()
instead of release()
. release()
meant used when form needs free()
itself, such in event handler, delaying free()
until form becomes idle. since form closed , idle time showmodal()
exits, safe free()
form immediately.
Comments
Post a Comment