delphi - No scrollbars appear in an autoscrollable form -




------------------------- original question -------------------------

greetings delphi developers! in delphi 2006 non mdi application, create non-sizeable, autoscrollable, autosizeable form. excerpt form's unit:

uses grid;  tgridfrm = class(tform)     public         grid : tgrid;         constructor create(aowner : tcomponent; asize : tpoint); end;  implementation  constructor tgridfrm.create(aowner: tcomponent; asize : tpoint); begin     inherited create(aowner);     borderstyle := bssingle; // users not allowed resize form     windowstate := wsnormal;     borderwidth := 0;     autosize := true;     autoscroll := true;     constraints.maxwidth := screen.width - 1;     constraints.maxheight := screen.height - 1;     grid := tgrid.create(asize.x, asize.y, self); end; 

now, tgrid custom control own canvas of course. excerpt unit:

tgrid = class (tcustomcontrol)     public         noofcellsx,         noofcellsy,         cellsize : integer;         procedure setzoom(z : integer);         constructor create(awidth, aheight : integer; aparent : tform = nil); end;  implementation  constructor tgrid.create(awidth, aheight : integer; aparent : tform = nil); begin     inherited create(aparent);     parent := aparent;     align := alcustom;     left := 0;     top := 0; end;  procedure tgrid.setzoom(zoom : integer); begin     cellsize := zoom * 10 div 100;     width := noofcellsx * cellsize;     height := noofcellsy * cellsize; end; 

in form's unit have arranged things (through applicationevents object) setzoom called zoom value, whenever numeric +/- keys pressed. idea behind have custom control snap upper left corner of form (with predefined margin/borderwidth), , have entire form automatically adjust size whenever zoom in or out of custom control, never extending beyond screen limits. it's working, point scrollbars must become visible: never show up. since autoscrollable form, aren't supposed show whenever control inside form (grid in case) gets larger constrained form , out of way when gets smaller? tried refactoring moving setzoom form's class, no avail. missing here?

----------------- compilable code added afterwards ------------------

the project file:

program myapp;  uses     forms,     grid in 'source\grid.pas',     gridform in 'source\gridform.pas' {gridfrm},     main in 'source\main.pas' {mainfrm};  {$r *.res}  begin     application.initialize;     application.createform(tmainfrm, mainfrm);     application.run; end. 

the main.pas:

unit main;  interface  uses     windows, messages, sysutils, variants, classes, graphics, controls,     forms, dialogs, stdctrls;  type     tmainfrm = class(tform)         createnewformbutton: tbutton;         procedure formclose(sender: tobject; var action: tcloseaction);         procedure createnewformbuttonclick(sender: tobject);     end;  var     mainfrm: tmainfrm;  implementation  {$r *.dfm}  uses     gridform;  procedure tmainfrm.createnewformbuttonclick(sender: tobject); var aform : tform; begin     aform := tgridfrm.create(self, point(15, 15));     aform.show;     tgridfrm(aform).grid.setzoom(100); end;  procedure tmainfrm.formclose(sender: tobject; var action: tcloseaction); begin     action := cafree; end;  end. 

the gridform.pas:

unit gridform;  interface  uses     windows, messages, sysutils, variants, classes, graphics, controls, forms,     dialogs, grid, appevnts;  type     tgridfrm = class(tform)         applicationevents1: tapplicationevents;         procedure formclose(sender: tobject; var action: tcloseaction);         procedure applicationevents1message(var msg: tagmsg; var handled: boolean);     private         thegrid : tgrid;     public         property grid : tgrid read thegrid write thegrid;         constructor create(aowner : tcomponent; asize : tpoint);     end;  var     gridfrm: tgridfrm;  implementation  {$r *.dfm}  procedure tgridfrm.applicationevents1message(var msg: tagmsg; var handled: boolean); var keystate : tkeyboardstate; begin     if not active begin exit; end;     if msg.message = wm_keydown     begin         getkeyboardstate(keystate);         case msg.wparam of              vk_add : begin // zoom in                 grid.setzoom(grid.zoom + 10);                 handled := true;             end;              vk_subtract : begin // zoom out                 grid.setzoom(grid.zoom - 10);                 handled := true;             end;              // other keys down here...          end;     end; end;  constructor tgridfrm.create(aowner : tcomponent; asize : tpoint); begin     inherited create(aowner);     borderstyle := bssingle;     borderwidth := 2;     autosize := true;     autoscroll := true;     constraints.maxwidth := screen.width - 1;     constraints.maxheight := screen.height - 1;     visible := false;     grid := tgrid.create(asize.x, asize.y, random(800) + 500, self); end;  procedure tgridfrm.formclose(sender: tobject; var action: tcloseaction); begin                     action := cafree; end;  end. 

and grid.pas:

unit grid;  interface  uses     stdctrls, sysutils, controls, forms, graphics, dialogs;  type     tgrid = class (tcustomcontrol)         lbl1, lbl2,         gridsizeinfolbl,         formsizeinfolbl,         warninglbl : tlabel;          public             noofcellsx,             noofcellsy,             squaresize, // in 1/1000ths of centimeter             cellsize, // in pixels             zoom : integer;             procedure setzoom(z : integer);             constructor create(x, y, asquaresize : integer; aparent : tform = nil);     end;  implementation  uses     gridform;  constructor tgrid.create(x, y, asquaresize : integer; aparent : tform = nil); begin     inherited create(aparent);     parent := aparent;     color := clteal;     align := alcustom;     left := 0;     top := 0;     noofcellsx := x;     noofcellsy := y;     squaresize := asquaresize;     lbl1 := tlabel.create(self);     lbl2 := tlabel.create(self);     gridsizeinfolbl := tlabel.create(self);     formsizeinfolbl := tlabel.create(self);     warninglbl := tlabel.create(self);     lbl1     begin         parent := self;         caption := 'size of grid: ';         width := 55;         height := 18;         left := 2;         top := 1;     end;     lbl2     begin         parent := self;         caption := 'size of form: ';         width := 75;         height := 18;         left := 2;         top := 19;     end;     gridsizeinfolbl     begin         parent := self;         width := 100;         height := 18;         left := 65;         top := 1;     end;     formsizeinfolbl     begin         parent := self;         width := 100;         height := 18;         left := 65;         top := 19;     end;     warninglbl     begin         parent := self;         width := 150;         height := 18;         left := 2;         top := 39;     end; end;  procedure tgrid.setzoom(z : integer); begin     zoom := z;     cellsize := (screen.pixelsperinch * squaresize * zoom) div (1000 * 254);     width := noofcellsx * cellsize;     height := noofcellsy * cellsize;      gridsizeinfolbl.caption := inttostr(width) +         'x' + inttostr(height) +         ' (zoom: ' + inttostr(zoom) +         ', cellsize zoomed: ' + inttostr(cellsize) +         ', squaresize: ' + inttostr(squaresize) +         'mm, squares: ' + inttostr(noofcellsx) + 'x' + inttostr(noofcellsy) + ')';     tgridfrm(parent)     begin         left := (screen.width - width) div 2;         top := (screen.height - height) div 2;         formsizeinfolbl.caption := inttostr(width) + 'x' + inttostr(height) +         ' (clientarea: ' + inttostr(clientwidth) + 'x' + inttostr(clientheight) + ')';         if self.width > clientwidth             if self.height > clientheight                 warninglbl.caption := 'both scrollbars should appear!'             else                 warninglbl.caption := 'horizontal scrollbar should appear!'         else if self.height > clientheight             warninglbl.caption := 'vertical scrollbar should appear!'         else             warninglbl.caption := 'no scrollbars needed';     end; end;  end. 

code synopsis: click on main form' s button creates autosizeable form, in turn creates child grid of random initial size. numeric +/- keys make grid larger or smaller , form autosized accordingly, no scrollbars ever show up, no matter how large grid becomes (the labels added provide visual feedback).

your problem twofold.

the first is, jerry commented question, autosize. purpose of autosize resize form such content visible. there can no scrollbars when content visible, 2 properties contradictory.

as such vcl developers have took precaution. below d2007 source:

function tscrollingwincontrol.autoscrollenabled: boolean; begin   result := not autosize , not (docksite , usedockmanager); end; 

as can see setting autoscroll has no effect when autosize set.

you override behavior, virtual method, if wouldn't interfere second fold.


you've decided leave autosize off , calculate , set required size of form depending on workarea size, meet second problem: alignment of grid control.

the below d2007 code when vertical scroll bar wants see if needs adjust:

  procedure processvert(control: tcontrol);   begin     if control.visible       case control.align of         altop, alnone:           if (control.align = altop) or (control.anchors * [aktop, akbottom] = [aktop])             newrange := max(newrange, position + control.top + control.height);         albottom: inc(alignmargin, control.height);       end;   end; 

as can see control not have effect on automatic vertical scroll bar if doesn't have either altop, albottom or alnone alignment. yours have alcustom.

this why overriding autosizing behavior won't help, autosize depends on controls having "left", "right", "top", "bottom" or "none" aligned controls.


have redesign control taking consideration how vcl internally works. not of internal dependency aspects can documented, have use source kind of enhanced development.





wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

python - Read npy file directly from S3 StreamingBody -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -