delphi xe - TObjectList re-order -


i need re-order tobjectlist, according rules. how can achieve this?

so add panels scrollbox dinamically. when add them, add them objectlist in order added @ runtime, future use. can re-organize panels in scrollbox drag/drop. want objectlist mirror same order set @ runtime drag/drop.

here code:

var   mainform: tmainform;   panellist,panellisttmp:tobjectlist;  implementation ...  procedure tmainform.formcreate(sender: tobject); begin   panellist:=tobjectlist.create;   panellisttmp:=tobjectlist.create; end;  procedure tmainform.button1click(sender: tobject); begin   addpanel('0');   addpanel('1');   addpanel('2');   addpanel('3');   addpanel('4'); end;  procedure tmainform.addpanel(what:string); var   pan:tpanel;   bv:tshape; begin   pan:=tpanel.create(self);   pan.parent:=thecontainer;   pan.height:=50;   pan.bevelouter:=bvnone;   pan.borderstyle:=bsnone;   pan.ctl3d:=false;   pan.name:='layerpan'+what;   pan.caption:=what;   pan.align:=albottom;   pan.onmousedown:=panmousedown; end;  procedure tmainform.panmousedown(sender: tobject; button: tmousebutton;shift: tshiftstate; x, y: integer); var   i:integer;   idu:string;   panui:tpanel; begin   panui:=sender tpanel;   panui.parentcolor:=false;   panui.bringtofront;   // drag drop stuff   releasecapture;   panui.perform(wm_nclbuttondown,htcaption,0);    := 0 mainform.componentcount - 1     begin       if mainform.components[i] twincontrol         if twincontrol(mainform.components[i]) tpanel         if (twincontrol(mainform.components[i]) tpanel).parent=mainform.thecontainer           begin             (twincontrol(mainform.components[i]) tpanel).align:=albottom;           end;     end;   thecontainer.scrollinview(panui);   reorderpanels; end;   procedure tmainform.reorderpanels; begin  end; 

what should in reorderpanels procedure? thinking feeding panels of scrollbox bottom top new tobjectlist (panellisttmp), clear panellist , re-add them panellisttmp, when that, error: access violation, , einvalidpointer - invalid pointer operation

so thought:

procedure tmainform.reorderpanels; var   ctrl:tcontrol;   pos:tpoint;   pan:tpanel;   bad:boolean;   ord,i:integer; begin   memo2.lines.add('*** new order start');   panellisttmp.clear;  // scroll top   thecontainer.vertscrollbar.position := 0;   // scroll down   thecontainer.vertscrollbar.position := thecontainer.vertscrollbar.range;   // panel   pos:=thecontainer.clientorigin;   pos.y:=pos.y+thecontainer.height-5;   ctrl := findvclwindow(pos) ;   if ctrl tpanel     if tpanel(ctrl).parent = thecontainer     begin       pan:=(ctrl tpanel);       panellisttmp.add(pan);     end;    ord:=1;   bad:=false;   repeat    repeat        pos.y:=pos.y-1;    until (findvclwindow(pos) tpanel)and(findvclwindow(pos)<>pan);    if (findvclwindow(pos) tpanel)and(findvclwindow(pos).name<>'layerpan')    begin        pan:=findvclwindow(pos) tpanel;        containeru.vertscrollbar.position := 0;        containeru.scrollinview(pan);        ord:=ord+1;        panellisttmp.add(pan);    end    else      bad:=true;   until bad=true;    // , swap between objectlists...   panellist.clear;   i:=0 panellisttmp.count-1      begin       (panellisttmp.items[i] tpanel).parent:=containeru;       panellist.add(panellisttmp.items[i]);     end; end; 

so assume because objectlist storing pointers actual objects, when clear initial objectlist, actual objects freed, second objectlist contains list of pointers no longer viable... how can achieve want?

so on buttonclick, objectlist contains panels in following order:

panellist[0] - panel0 panellist[1] - panel1 panellist[2] - panel2 panellist[3] - panel3 panellist[4] - panel4 

after drag - drop panels inside scrollbox, can end order (in scrollbox)

panel3 panel1 panel4 panel2 panel0 

but in objectlist, order same before...

again, want able have objectlist ordered according order of panels scrollbox. in re-order procedure panels in desired order. need have them in same order in objectlist.

is there other way of doing this? other me creating new class hold index beside tpanel , use in objectlist maintain order?

tobjectlist has ownsobjects property true default. make sure set false since don't want list auto-free objects owned form.

as actual sorting of tobjectlist, consider using sort() or sortlist() method that. after have repositioned panels desired within container, call sort() or sortlist(). sorting callback provide given 2 object pointers @ time while sorting iterating list. use current positions of objects relative each other tell list order should appear in.

try this:

var   mainform: tmainform;   panellist: tobjectlist;  implementation  ...  procedure tmainform.formcreate(sender: tobject); begin   panellist := tobjectlist.create(false); end;  procedure tmainform.formdestroy(sender: tobject); begin   panellist.free; end;  procedure tmainform.button1click(sender: tobject); begin   addpanel('0');   addpanel('1');   addpanel('2');   addpanel('3');   addpanel('4'); end;  procedure tmainform.addpanel(what: string); var   pan: tpanel;   bv: tshape; begin   pan := tpanel.create(self);   try     pan.parent := thecontainer;     pan.height := 50;     pan.bevelouter := bvnone;     pan.borderstyle := bsnone;     pan.ctl3d := false;     pan.name := 'layerpan'+what;     pan.caption := what;     pan.align := albottom;     pan.onmousedown := panmousedown;     panellist.add(pan);   except     pan.free;     raise;   end; end;  procedure tmainform.panmousedown(sender: tobject; button: tmousebutton; shift: tshiftstate; x, y: integer); var   i: integer;   idu: string;   panui, pan: tpanel;   tmplist: tobjectlist; begin   panui := sender tpanel;   panui.parentcolor := false;   panui.bringtofront;    // drag drop stuff   releasecapture;   panui.perform(wm_nclbuttondown, htcaption, 0);    tmplist := tobjectlist.create(false);   try     := 0 thecontainer.controlcount - 1     begin       if thecontainer.controls[i] tpanel         tmplist.add(tpanel(thecontainer.controls[i]));     end;     := 0 tmplist.count - 1       tpanel(tmplist[i]).align := albottom;       tmplist.free;   end;    thecontainer.scrollinview(panui);   reorderpanels; end;  function sortpanels(item1, item2: pointer): integer; begin   result := tpanel(item2).top - tpanel(item1).top; end;  procedure tmainform.reorderpanels; begin   panellist.sort(sortpanels);    // alternatively:   {   panellist.sortlist(     function(item1, item2: pointer): integer;     begin       result := tpanel(item2).top - tpanel(item1).top;     end   );   } end; 

Comments

Popular posts from this blog

c - Bitwise operation with (signed) enum value -

xslt - Unnest parent nodes by child node -

YouTubePlayerFragment cannot be cast to android.support.v4.app.Fragment -