home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / vrac / dyndlgp.zip / ODYNDLG.PAS < prev   
Pascal/Delphi Source File  |  1994-07-31  |  7KB  |  226 lines

  1. { Unit: odyndlg
  2.   By: Ping-sheun LEE (LPS)
  3.  
  4.  ( translation + modification from
  5.    (1) DynDlg.zip(BC4++ OWL2 Excample)
  6.        by
  7.        University of California, Davis
  8.    and
  9.    (2) MSJ vol9 No.3
  10.        by
  11.        Mr Atig Aziz
  12.        Source code: DynDlg.exe (Microsoft)
  13.   Other information ,please refer to 'dyndlg.txt'
  14.   
  15.   Any bug and Suggestion please send to:
  16.   Ping Shuen Lee
  17.   Compuserve: 100426,21
  18.   Internet: Ping.shuen.Lee@hk.super.net
  19.   
  20.    mod: Use Pcollection instead of array to store dialogs information.
  21. }
  22.  
  23. Unit odyndlg;
  24. Interface
  25. Uses
  26.     wintypes,winprocs,objects,owindows,odialogs,win31;
  27.  
  28. {Following infomation is written by Rory Jaffe:
  29. the code for functions: GetDlgCtlRect and MoveSet are adapted (with changes) 
  30. from the code by Atif Aziz in the article: "Simplify and Enhance Your 
  31. Application's User Interface with Dynamic Dialog Boxes" in MSJ vol. 9 no. 3, 
  32. Mar, 1994.  Both functions are changed to to replace a few function calls 
  33. which appear to be either erroneous or are calls to functions he has defined
  34. but not printed in the article. There are at least two things you can do to 
  35. create dangerous situations with this code: 1) use non-existent ID's for 
  36. homespot or refbox, and 2) add more than maxsets sets. I've added debug 
  37. macros for number 1--it should be unnecessary for your finished code. }
  38.  
  39.  
  40. {constructor--rarely need to alter default arguments--make hideatstart TRUE }
  41. {if you did not remove visible attribute from the controls which are not }
  42. {to be initially visible--make firstactive nonzero if you want a different }
  43. {set (than 0) initially active--increase maxsets if you are crazy enough }
  44. {to have more than 20 "looks" for the dialog box }
  45.  
  46. {Setup--this function is called in SetupWindow method of dialog box--first }
  47. {argument is resource ID of the frame that is correctly positioned in the }
  48. {dialog box, as a reference for moving the sets of controls--second }
  49. {argument should be the HWND of the dialog box owning the controls, which }
  50. {is almost always HWindow }
  51.  
  52. {AddSet--adds in sequence each set of dynamic controls (sets numbered from 0) and
  53. returns the sequence number for the added set--each set consists of a
  54. group of sequentially numbered controls (gaps are OK but wasteful) and a
  55. refence frame.  The controls are placed in the reference frame so that
  56.  they are in the same relation to their reference frame as you wish them
  57. to be with the correctly positioned frame (set in Setup method).
  58.  The AddSet method should also be called in the dialog class's SetupWindow
  59.  method. }
  60.  
  61. {Activate--argument is the set number of the group to activate (show).  This }
  62. {function returns the set number of the previously active group. }
  63.  
  64. type
  65.  
  66. PDynamicDialogControls=^tdynamicdialogcontrols;
  67. tdynamicdialogcontrols=object
  68.         dlginfo:pcollection;
  69.     constructor init(hideatstart:bool;firstactive:integer) ;
  70.     destructor done;virtual;
  71.     procedure Setup(homespot:integer;hdlgwindow:hwnd) ;virtual;
  72.     function AddSet(firstitem,lastitem,refbox:integer):integer;virtual;
  73.     function Activate(which:integer):integer;virtual;
  74. private
  75.     _HDlgWindow:hwnd;
  76.     _HomeSpot:integer ;
  77.     _Active:integer ;
  78.     _HideAtStart:bool ;
  79.     procedure ShowSet(setnumber,cmdshow:integer) ;
  80.     procedure MoveSet(setnumber,refbox:integer) ;
  81.     procedure GetDlgCtlRect(nID:integer;var rc:trect) ;
  82. end;
  83.  
  84. Implementation
  85.  
  86. type
  87.     pdlglistelem=^tdlglistelem;
  88.      tdlglistelem=object(tobject)
  89.       start:integer;
  90.       ends:integer;
  91.      constructor init(_start,_ends:integer);
  92.      destructor done;virtual;
  93. end;
  94.  
  95. constructor tdlglistelem.init(_start,_ends:integer);
  96. begin
  97.    start:=_start;
  98.    ends:=_ends;
  99. end;
  100.  
  101. destructor tdlglistelem.done;
  102. begin
  103.   inherited done;
  104. end;
  105. (* wptr is pointer to dialog box that contains this class
  106.  homespot is ID of the frame that is correctly positioned
  107.  hideatstart tells the class to send SW_HIDE to all inactive controls on
  108.  startup--but it's faster to unset VISIBLE attribute in dialog editor
  109.  firstactive is the number of the set to be initially shown
  110.  maxsets means no more than that many can be saved
  111.  typical call is--
  112.   TMyDialog::TMyDialog(...) : TDialog(...), mydyncontrols(this,HomeFrameID){}
  113.  
  114.   where mydyncontrols is a data member of TMyDialog*)
  115.  
  116.  
  117.  
  118. constructor tDynamicDialogControls.init(hideatstart:bool;firstactive:integer);
  119. begin
  120.     _HideAtStart:=hideatstart;
  121.     _Active:=firstactive;
  122.         dlginfo:=new(pcollection,init(5,5));
  123. end;
  124.  
  125. destructor tDynamicDialogControls.done;
  126. begin
  127.     dispose(dlginfo,done);
  128. end;
  129.  
  130. procedure tDynamicDialogControls.Setup(homespot:integer;hdlgwindow:hwnd);
  131. begin
  132.     _HomeSpot:= homespot ;
  133.     _HDlgWindow:= hdlgwindow ;
  134. end;
  135.  
  136. {add a set of sequentially numbered controls to dynamic box--they will be
  137. moved to the same relative position in the HomeSpot frame as they were in the
  138. refbox frame
  139. Returns the set number}
  140.  
  141. function TDynamicDialogControls.AddSet(firstitem, lastitem, refbox:integer):integer;
  142.  
  143. begin
  144.     dlginfo^.insert(new(pdlglistelem,init(firstitem,lastitem))) ;
  145.     if refbox <> _HomeSpot then
  146.         MoveSet(dlginfo^.count, refbox) ;
  147.     if (_HideAtStart=false) and (dlginfo^.count<>_Active) then
  148.         ShowSet(dlginfo^.count, SW_HIDE) ;
  149.     addset:=dlginfo^.count ;
  150. end;
  151.  
  152. procedure tDynamicDialogControls.GetDlgCtlRect( nID:integer; var rc:tRECT);
  153. begin
  154.  
  155.     GetWindowRect(GetDlgItem(_HDlgWindow,nID),rc) ;
  156.     MapWindowPoints(0, _HDlgWindow, rc, 2) ;
  157. end;
  158.  
  159. { activate a set--returns the number of the prior active set}
  160.  
  161. function tDynamicDialogControls.Activate(which:integer):integer;
  162. var lastactive:integer;
  163. begin
  164.     lastactive:= _Active ;
  165.     if _Active=which then
  166.         activate:=_Active ;
  167.  
  168.     ShowSet(_Active,SW_HIDE) ;
  169.     ShowSet(which, SW_SHOW) ;
  170.     _Active:= which ;
  171.     activate:=lastactive ;
  172. end;
  173.  
  174. procedure tDynamicDialogControls.MoveSet(setnumber, refbox:integer);
  175. var
  176.        rcSrc, rcDest, rcCtl:trect ;
  177.        nDeltaX, nDeltaY:integer ;
  178.        hwndCtl:hwnd ;
  179.        i,first,last:integer;
  180.  
  181. begin
  182.     (*PRECONDITIONX(::GetDlgItem(HDlgWindow,refbox), "refbox in call to MoveSet is"
  183.         "invalid") ;
  184.     PRECONDITIONX(::GetDlgItem(HDlgWindow,HomeSpot), "HomeSpot in call to MoveSet is"
  185.         "invalid") ;
  186.           *)
  187.     GetDlgCtlRect(refbox, rcSrc) ;
  188.     GetDlgCtlRect(_HomeSpot, rcDest) ;
  189.  
  190.     nDeltaX:= rcDest.left - rcSrc.left ;
  191.     nDeltaY:= rcDest.top - rcSrc.top ;
  192.  
  193.         first:=pdlglistelem(dlginfo^.at(setnumber-1))^.start;
  194.         last:=pdlglistelem(dlginfo^.at(setnumber-1))^.ends;
  195.     for i := first to last do
  196.     begin
  197.         hwndCtl := GetDlgItem(_HDlgWindow,i) ;
  198.         if hwndCtl>0 then
  199.         begin
  200.             GetDlgCtlRect(i, rcCtl) ;
  201.             SetWindowPos(hwndCtl, 0, rcCtl.left + nDeltaX,
  202.                 rcCtl.top + nDeltaY, 0, 0,
  203.                 SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE) ;
  204.         end;
  205.     end;
  206. end;
  207.  
  208. procedure tDynamicDialogControls.ShowSet( setnumber:integer; cmdShow:integer);
  209. var  first,last:integer;
  210.      hwndCtl:hwnd ;
  211.      i:integer;
  212. begin
  213.         first:=pdlglistelem(dlginfo^.at(setnumber-1))^.start;
  214.         last:=pdlglistelem(dlginfo^.at(setnumber-1))^.ends;
  215.  
  216.     for i:=first to last do
  217.     begin
  218.         hwndCtl:=GetDlgItem(_HDlgWindow,i) ;
  219.         if hwndCtl>0  then
  220.         ShowWindow(hwndCtl, cmdShow) ;
  221.     end;
  222. end;
  223.  
  224. End.
  225.  
  226.