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

Popular posts from this blog

java - Intellij Synchronizing output directories .. -

git - Initial Commit: "fatal: could not create leading directories of ..." -