home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / contro.zip / CONTROL.SAM next >
INI File  |  1994-12-28  |  24KB  |  539 lines

  1. [ver]
  2.     4
  3. [sty]
  4.     _DEFAULT.STY
  5. [files]
  6. [charset]
  7.     82
  8.     ANSI (Windows, IBM CP 1252)
  9. [revisions]
  10.     0
  11. [prn]
  12.     IBM Laser Printer 4019
  13. [port]
  14.     LPT1.OS2
  15. [lang]
  16.     1
  17. [desc]
  18.     
  19.     
  20.     
  21.     
  22.     
  23.     788647808
  24.     6
  25.     787701971
  26.     357
  27.     7
  28.     0
  29.     0
  30.     0
  31.     0
  32.     
  33.     
  34.     
  35.     
  36.     
  37.     
  38.     1
  39. [fopts]
  40.     0
  41.     1
  42.     0
  43.     0
  44. [lnopts]
  45.     2
  46.     Body Text
  47.     1
  48. [docopts]
  49.     5
  50.     2
  51. [GramStyle]
  52.     
  53. [l1]
  54.     0
  55. [pg]
  56.     7
  57.     35 0 32 0 0 1 0 65535 65535 Standard    65535 0 0    0 0 0 0 0 0 0 65535 0 0 65535 0 0 0 0 0
  58.     70 98 84 0 0 0 0 65535 65535 Standard    65535 0 0    0 0 0 0 0 0 0 65535 0 0 65535 0 0 0 0 0
  59.     100 0 77 32 0 1 0 65535 65535 Standard    65535 0 0    0 0 0 0 0 0 0 65535 0 0 65535 0 0 0 0 0
  60.     144 0 44 0 0 1 0 65535 2 Standard    65535 0 0    0 0 0 0 0 0 0 65535 0 0 65535 0 0 0 0 0
  61.     179 114 94 0 0 0 0 65535 2 Standard    65535 0 0    0 0 0 0 0 0 0 65535 0 0 65535 0 0 0 0 0
  62.     212 265 96 0 0 0 0 65535 65535 Standard    65535 0 0    0 0 0 0 0 0 0 65535 0 0 65535 0 0 0 0 0
  63.     222 0 34 1025 0 0 0 65535 2 Standard    65535 0 0    0 0 0 0 0 0 0 65535 0 0 65535 0 0 0 0 0
  64. [edoc]
  65. <:s><:#284,9360>Creating user controls- not for the faint of heart
  66.  
  67. <:s><:#284,9360>
  68.  
  69. <:s><:#1136,9360>There are two basic types of user controls, simple and complex. The simple type does not require one to create any screens, as Gpf supplies a default. The tougher one has the "extended" feature of the default screen turned on, and one must create the entire
  70.  infrastructure to display and make use of such a dialogue. 
  71.  
  72. <:s><:#284,9360>
  73.  
  74. In both cases the developer is responsible for the entire behavior of the user control, which can be very simple for static-like entities, or a real pain for interactive objects (for example, building a genuine multi-column list box, or formatted data entry
  75.  fields, or SQL-wise controls, etc.)
  76.  
  77. <:s><:#284,9360>
  78.  
  79. <:s><:#284,9360>This package contains:
  80.  
  81. <:s><:#568,9360>    a. a minimal user control, similar to STATIC TEXT controls, but auto sizing and with fancy shadowing. No extended dialog is required.
  82.  
  83. <:s><:#568,9360>    b. the same control with an extended dialog, permitting the Gpf developer to specify some extra properties.
  84.  
  85. <:s><:#284,9360>
  86.  
  87. <:s><:#284,9360>A. The Minimal Control
  88.  
  89. <:s><:#289,9360>We will call this control<+!> "SHADOW"<-!>. You will need the following files:
  90.  
  91. <:#284,9360>    GPFUC.H        do not write, included with the Gpf product
  92.  
  93. <:#284,9360>    SHADOW.H        you write this, though not strictly required
  94.  
  95. <:#852,9360>    SHADOW.C        includes GPFUC.H, SHADOW.H, and is the driver code. It must contain  at least (2) entry points expected by Gpf, and an entire window procedure for the control. This window procedure will be fairly simple.
  96.  
  97. <:#284,9360>    SHADOW.DEF    linker information, and exports the required entry points
  98.  
  99. <:#284,9360>    SHADOW.MAK    a makefile, necessary if you hate to type a lot
  100.  
  101. <:s><:#284,9360>
  102.  
  103. <:s><:#284,9360>When all is said and done you will have created:
  104.  
  105. <:#284,9360>    SHADOW.DLL    this will need to be moved to one of your LIBPATH locations
  106.  
  107. <:#284,9360>    SHADOW.LIB    IMPLIBed, nice to make, but again not strictly necessary
  108.  
  109. <:#284,9360>    SHADOW.OBJ    which can be discarded after the DLL is generated
  110.  
  111. <:s><:#284,9360>
  112.  
  113. <:s><:#568,9360>For this simple example we will not use a SHADOW.H, all source will be in SHADOW.C. What is required in this file?
  114.  
  115. <:s><:#284,9360>For the purposes of Gpf, two and only two exported functions
  116.  
  117. <:#284,9360>    PUCC APIENTRY RegisterXXXXXX (VOID)
  118.  
  119. <:#284,9360>    FNWP       fnwpXXXXXX(HWND,ULONG,MPARAM,MPARAM)
  120.  
  121. <:#568,9360>where XXXXXX is replaced with your control name. In this example we would therefore create these two functions:
  122.  
  123. <:#284,9360>    RegisterShadow
  124.  
  125. <:#284,9360>    fnwpShadow
  126.  
  127. <:s><:#284,9360>and can now write the entire SHADOW.DEF file as follows
  128.  
  129. <:#240,9360><:f,QCourier,>LIBRARY SHADOW INITINSTANCE TERMINSTANCE
  130.  
  131. <:s><:#240,9360><:f,QCourier,>DESCRIPTION 'any text you want'
  132.  
  133. <:#240,9360><:f,QCourier,>PROTMODE<:f>
  134.  
  135. <:#284,9360>DATA        PRELOAD MULTIPLE NONSHARED
  136.  
  137. <:s><:#240,9360><:f,QCourier,>CODE         PRELOAD
  138.  
  139. <:s><:#240,9360><:f,QCourier,>EXPORTS
  140.  
  141. <:s><:#240,9360><:f,QCourier,>    RegisterShadow    @1
  142.  
  143. <:s><:#240,9360><:f,QCourier,>    fnwpShadow    @2<:f>
  144.  
  145. <:s><:#284,9360>
  146.  
  147. <:#568,9360>SHADOW.DEF is now complete, so now  let's write and file away SHADOW.MAK. <[>In this example we are using IBM C\SET 2 in "c" mode]. The entire text follows
  148.  
  149. <:s><:#284,9360>
  150.  
  151. <:s><:#284,9360>---------------------------------------------
  152.  
  153. <:#240,9360><:f,QCourier,>Lib    =    Os2386
  154.  
  155. <:#240,9360><:f,QCourier,>Objects    =    shadow.obj
  156.  
  157. <:#240,9360><:f,QCourier,>LinkOpt    =    /A:4 /BASE:0x12000000
  158.  
  159. <:#240,9360><:f,QCourier,>Options    =    /W3 /c /Gd- /Ge- /Gm+ /Re
  160.  
  161. <:s><:#240,9360><:f,QCourier,>
  162.  
  163. <:#240,9360><:f,QCourier,>Shadow.dll: $(Objects) Shadow.def
  164.  
  165. <:#480,9360><:f,QCourier,>    Link386 $(Objects), Shadow.dll $(LinkOpt), ,$(Lib), Shadow.def
  166.  
  167. <:s><:#240,9360><:f,QCourier,>    
  168.  
  169. <:#240,9360><:f,QCourier,>Shadow.obj: Shadow.c
  170.  
  171. <:#240,9360><:f,QCourier,>    ICC $(Options) Shadow.C<:f>
  172.  
  173. <:s><:#284,9360>
  174.  
  175. <:s><:#284,9360>----------------------------------------------
  176.  
  177. <:s><:#284,9360>    
  178.  
  179. <:s><:#284,9360>Nothing left to do except the "C" file. 
  180.  
  181. <:s><:#284,9360>Notes about the two exported functions:
  182.  
  183. <:s><:#284,9360>1. RegisterShadow()
  184.  
  185. <:s><:#284,9360>Three major things are done here:
  186.  
  187. <:#284,9360>    - get a HAB
  188.  
  189. <:s><:#568,9360>    - register this class, including its name and window procedure (fnwpShadow). The last parameter reserves some extra storage which is to be tacked on to each instance.
  190.  
  191.     - fill in the fields in struct "Ucc", typedef'd in GPFUC.H. In this file there are several 'defines' of the form GPF_CAPS_wxzy. These are used to control the capabilities which are enabled during the presentation of the default User Control dialog. Since w
  192. e want the developer to define text, we enable the text entry field this way: 
  193.  
  194. <:#240,9360>    <:f,QCourier,>Ucc.Capabilities= GPF_CAPS_TEXT;    
  195.  
  196. <:#240,9360><:f,QCourier,>    /* more stuff could be ORed in */<:f>
  197.  
  198. <:s><:#284,9360>
  199.  
  200. <:s><:#284,9360>2. fnwpShadow()
  201.  
  202. <:#1988,9360>Each instance of this control will need some storage in which we can store, as a minimum, the text defined by the developer during control creation. In this case it will be of type PSZ, for which memory will be allocated during the WM_CREATE message. <[>Not
  203. e that the call to WM_CREATE will be made from Gpf, after the CREATESTRUCT fields have been filled in. The text specified by the developer will be pointed to by the "pszText" field of this structure.] Once allocated we will place a pointer to this area into
  204.  the first slot of the EXTRAWORDS asked for during class registration.
  205.  
  206. <:#284,9360>This storage will be free(d) during the WM_DESTROY message.
  207.  
  208. <:s><:#1136,9360>Now jump back to the start of fnwpShadow and notice that we initially try to retrieve the pointer stored with the instance. If it is NULL we know the WM_CREATE function has not been processed (or invoked) as of yet, hence we immediately return unless the me
  209. ssage is WM_CREATE! It is usually safe to ignore any messages flying around before WM_CREATE.
  210.  
  211. <:s><:#284,9360>
  212.  
  213. <:#1988,9360>The other message of real interest is WM_PAINT. The pointer to the instance text has already been retrieved, so an HPS is opened, and along with the PSZ and HWND, is passed to a helper function called Paint(). The details of what Paint() does will not be ex
  214. plained here, kindly look at the source code. In fact, modify it to your heart's content.... but don't call me if it blows up after your 'improvements' are installed.  Many optimizations are possible, such as re-sizing the control to exactly fit the passed-
  215. in text. But that would obscure the point of this AppNote. The next control, having an extended dialog, will indeed have some obfuscating code.
  216.  
  217. <:s><:#284,9360>
  218.  
  219. <:s><:#284,9360>How does one use this control?
  220.  
  221. <:s><:#284,9360>1. From Gpf click on menu "Objects- User Controls"
  222.  
  223. <:s><:#284,9360>2. In new dialog, press "Add"
  224.  
  225. <:s><:#284,9360>3. In new dialog
  226.  
  227. <:s><:#284,9360>    enter "shadow" in name field
  228.  
  229. <:s><:#284,9360>    enter "shadow" in DLL name field
  230.  
  231. <:s><:#284,9360>     the link via should be left at "import"
  232.  
  233. <:#568,9360>4. press Ok. If Gpf is unable to find it, move SHADOW.DLL to a directory seen by the LIBPATH variable in CONFIG.SYS, then repeat the above
  234.  
  235. <:s><:#284,9360>5. exit to top level
  236.  
  237. <:s><:#284,9360>6. open or create a window
  238.  
  239. <:s><:#284,9360>7. click on the "Create- User Control" menu
  240.  
  241. <:s><:#284,9360>8. drop the tracking rectangle anywhere on the client area.
  242.  
  243. <:s><:#568,9360>9. the User Control default dialog should come up (if you have this turned off, simply double click anywhere within the tracking rectangle for this control)
  244.  
  245. <:#284,9360>10. enter the desired text and return with OK
  246.  
  247. <:s><:#284,9360>11. drag/drop or re-size as desired
  248.  
  249. <:s><:#284,9360>12. if you want to modify the SHADOW.DLL sources, close Gpf so that it releases the DLL!
  250.  
  251. <:s><:#284,9360>
  252.  
  253. <:s><:#284,9360>
  254.  
  255. <:s><:#284,9360>Al Charov, November 1994
  256.  
  257. <:s><:#284,9360>*****************************************************************
  258.  
  259. <:s><:#284,9360>
  260.  
  261. <:s><:#284,9360>B. A more complex example
  262.  
  263. <:s><:#284,9360>
  264.  
  265. <:#852,9360>Examining file "Gpfuc.h" reveals a definition of GPF_CAPS_EXTENDED.  Including this bit during the registration phase enables the "Extended..." pushbutton in the User Control default dialog. Simple enough, but a bunch of extra baggage must be generated to s
  266. upport this capability:
  267.  
  268. <:#568,9360>    - one or more dialog templates must be made, using the toolkit dialog editor, and (resource) compiled.
  269.  
  270. <:s><:#568,9360>    - an extra registration procedure must be written, with a specific format, for the extended dialog
  271.  
  272. <:s><:#284,9360>    - a complete window procedure must be written for each and every new  dialog
  273.  
  274. <:#568,9360>    - a parameter/data collection and passing stategy must be implemented within the new procedures, and made known to the two original procedures (made in the simple case).
  275.  
  276. <:#289,9360>    - the .<+!>DEF<-!> and <+!>MAK<-!> files need to be expanded a bit.
  277.  
  278. <:#573,9360>    - for general ease, an .<+!>RC<-!> file is made; its only function is to pull in the .<+!>DLG<-!> file created for the extended dialogs.
  279.  
  280. <:s><:#284,9360>
  281.  
  282. <:#857,9360>Sounds a bit messy, but it all becomes perfectly clear after making a few dozen of these beasts. In this example we will create a User Control with the name 
  283. <+!>"SHADOWX"<-!>, since it is derived from the previous control but with a few bells and whistles thrown in.
  284.  
  285. <:s><:#284,9360>
  286.  
  287. <:s><:#284,9360>As before, let's talk about the bare minimums:
  288.  
  289. <:s><:#284,9360>    - you must create source code for these functions
  290.  
  291. <:s><:#284,9360>        <:f200,QCourier,>/* the next two are just as in the simple example */
  292.  
  293. <:#202,9360><:f200,QCourier,>        PUCC RegisterShadowx(VOID);
  294.  
  295. <:#202,9360><:f200,QCourier,>        MRESULT EXPENTRY fnwpShawdowx(HWND,ULONG,MPARAM,MPARAM)
  296.  
  297. <:s><:#202,9360><:f200,QCourier,>        /* the next two are new,<:f><:f200,QCourier,> when using the EXTENDED feature */
  298.  
  299. <:#202,9360><:f200,QCourier,>        LONG APIENTRY ExtendedShadowx(LONG, PVOID);
  300.  
  301. <:#202,9360><:f200,QCourier,>        MRESULT EXPENTRY fnwpExtShadowx(HWND,ULONG,MPARAM,MPARAM);<:f>
  302.  
  303. <:#284,9360>    /* the new prefixes, 'Extended' and 'fnwpExt' must be exact, even their case !! */
  304.  
  305. <:#284,9360>    /* and the suffix for all (4) functions must be the name of this control: Shadowx */
  306.  
  307. <:#852,9360>    - invoke the dialog editor (not Gpf!!) and create a .DLG and .H file. In this example I created SHADEXT.DLG and SHADEXT.H.  No instructions for using this particular editor will be provided here, except an admonition to specify useful ID names.
  308.  
  309. <:s><:#284,9360>
  310.  
  311. <:#568,9360>As before we can immediately write the complete .DEF file, and we'll call it SHADOWX.DEF. The entire source follows:
  312.  
  313. <:s><:#284,9360>
  314.  
  315. <:s><:#240,9360><:f,QCourier,>LIBRARY SHADOWX INITINSTANCE TERMINSTANCE
  316.  
  317. <:s><:#240,9360><:f,QCourier,>DESCRIPTION 'any text you want'
  318.  
  319. <:s><:#240,9360><:f,QCourier,>PROTMODE<:f>
  320.  
  321. <:s><:#284,9360>DATA        PRELOAD MULTIPLE NONSHARED
  322.  
  323. <:s><:#240,9360><:f,QCourier,>CODE     PRELOAD
  324.  
  325. <:s><:#240,9360><:f,QCourier,>EXPORTS
  326.  
  327. <:#240,9360><:f,QCourier,>    RegisterShadowx    @1
  328.  
  329. <:#240,9360><:f,QCourier,>    ExtendedShadowx    @2
  330.  
  331. <:#288,9360><:f,QCourier,>    fnwpShadow<:f>x
  332.  
  333. <:#240,9360><:f,QCourier,>    fnwpExtShadowx
  334.  
  335. <:s><:#240,9360><:f,QCourier,>
  336.  
  337. <:s><:#284,9360>
  338.  
  339. <:#284,9360><:f,2Times New Roman,>and now the entire MAK file, which I've named SHADOWX.MAK
  340.  
  341. <:s><:#284,9360><:f,2Times New Roman,>
  342.  
  343. <:s><:#284,9360><:f,2Times New Roman,>-------------------------------------------
  344.  
  345. <:s><:#202,9360><:f200,QCourier,>Lib    = Os2386 
  346.  
  347. <:#202,9360><:f200,QCourier,>Objects =    shadowx.obj shadext.obj 
  348.  
  349. <:s><:#202,9360><:f200,QCourier,>LinkOpt = /A:4 /BASE:0x12000000
  350.  
  351. <:s><:#202,9360><:f200,QCourier,>Options = /W3 /c /Gd- /Ge- /Gm+ /Re
  352.  
  353. <:s><:#202,9360><:f200,QCourier,>
  354.  
  355. <:#202,9360><:f200,QCourier,>Shadowx.Dll:  $(Objects) shadext.res Shadowx.Def
  356.  
  357. <:#202,9360><:f200,QCourier,>    Link386 $(Objects) , Shadowx.Dll $(LinkOpt),,$(Lib) , Shadowx.Def;
  358.  
  359. <:#202,9360><:f200,QCourier,>    rc shadext.res shadowx.dll
  360.  
  361. <:#202,9360><:f200,QCourier,>    copy shadowx.dll c:\os2\dll
  362.  
  363. <:#202,9360><:f200,QCourier,><:f><:f200,QCourier,>Shadowx.Obj:    shadowx.c shadowx.h shadext.h
  364.  
  365. <:#202,9360><:f200,QCourier,>    ICC $(Options) shadowx.C
  366.  
  367. <:s><:#202,9360><:f200,QCourier,>
  368.  
  369. <:#202,9360><:f200,QCourier,>Shadext.obj: shadext.c shadowx.h shadext.h
  370.  
  371. <:s><:#202,9360><:f200,QCourier,>    ICC $(Options) shadext.c
  372.  
  373. <:s><:#202,9360><:f200,QCourier,>
  374.  
  375. <:#202,9360><:f200,QCourier,>shadext.res: shadext.rc shadext.dlg shadext.h
  376.  
  377. <:#202,9360><:f200,QCourier,>    rc -r shadext.rc <:f200,,><:f>
  378.  
  379. <:s><:#284,9360><:f,QCourier,><:f,2Times New Roman,>
  380.  
  381. <:#2272,9360><:f,2Times New Roman,>For no particular reason, except perhaps to keep all source files on the small side, I chose to split my code into two "C" files. SHADOWX.C contains the same functions as in the simple example, and SHADEXT.C contains the required new f
  382. unctions which support the extended dialog. Aside from ensuring the compile/link of two source files, the only real addition to the .MAK file is some extra processing for the resource compiler. SHADEXT.DLG and SHADEXT.H files were generated by the Dialog Ed
  383. itor, and then a simple .RC file was created which simply does an 'RCINCLUDE' of these two. With the production details out of the way it is time to discuss the source changes and additions.
  384.  
  385. <:s><:#284,9360><:f,2Times New Roman,>
  386.  
  387. <:s><:#284,9360><:f,2Times New Roman,>What are the new features of this control?
  388.  
  389. <:s><:#852,9360><:f,2Times New Roman,>    - Presentation Parameters, familiar to most Gpf users, can now be specified for this control in the same fashion. Note: only foreground/background colors have any effect. Font specifications are ignored, as the source code is hard-wir
  390. ed to 'Times New Roman".
  391.  
  392. <:s><:#284,9360><:f,2Times New Roman,>    - the "Extended..." pushbutton is enabled, leading to a dialog in which we can
  393.  
  394. <:s><:#284,9360><:f,2Times New Roman,>    a. specify a left or right tilt to our text, 0-30 degrees from vertical.
  395.  
  396. <:s><:#284,9360><:f,2Times New Roman,>    b. specify the left shadow color
  397.  
  398. <:s><:#284,9360><:f,2Times New Roman,>    c. specify the right shadow color
  399.  
  400. <:s><:#284,9360><:f,2Times New Roman,>    d. override the background color
  401.  
  402. <:s><:#284,9360><:f,2Times New Roman,>    e. override the foreground color
  403.  
  404. <:s><:#284,9360><:f,2Times New Roman,>
  405.  
  406. <:#1704,9360><:f,2Times New Roman,>The only change to the registration procedure was the addition of two bits to 'Ucc.capability', turning ON the PresParams and Extended pushbutton in the default User Control dialog. The changes to the window procedure are a bit more in
  407. volved, and depend on what happens in the extended dialog (if anything; the user should not be required to invoke it). The key to understanding this code is knowing what, and when, gets passed between our four required functions. 
  408.  
  409. <:#284,9360><:f,2Times New Roman,>All Gpf User Controls make use of a structure of type UCC, contained in GPFUC.H:
  410.  
  411. <:s><:#284,9360><:f,2Times New Roman,>
  412.  
  413. <:#202,9360><:f200,QCourier,>#pragma pack(1) /* force structure alignment packing */
  414.  
  415. <:#202,9360><:f200,QCourier,>typedef struct
  416.  
  417. <:s><:#202,9360><:f200,QCourier,>  {
  418.  
  419. <:#202,9360><:f200,QCourier,>    ULONG        Capability;        /* Caps Style        */
  420.  
  421. <:#202,9360><:f200,QCourier,>    ULONG        WsStyle;        /* Initial Ws Style */
  422.  
  423. <:#202,9360><:f200,QCourier,>    USHORT    Cx;            /* Initial Cx        */
  424.  
  425. <:s><:#202,9360><:f200,QCourier,>    USHORT    Cy;            /* Initial Cy        */
  426.  
  427. <:#202,9360><:f200,QCourier,>    LONG        Reserved<[>60];     /* Reserved     */
  428.  
  429. <:s><:#202,9360><:f200,QCourier,>  } UCC; 
  430.  
  431. <:#202,9360><:f200,QCourier,>typedef UCC FAR *PUCC;             /* Far Pointer        */<:f200,,><:f>
  432.  
  433. <:s><:#284,9360><:f,2Times New Roman,>
  434.  
  435. <:#1420,9360><:f,2Times New Roman,>Previously we used the first four members of this structure and now we will use the fifth in addition. We can define any structure we wish, provided it is 'packed' and does not exceed 60 bytes in length. Gpf will be providing us with a
  436.  pointer to the 'Reserved' member at appropriate times, and we can type cast it to suit our needs. So I created a structure to hold the information this control will be interested in retaining. In file SHADOWX.H:
  437.  
  438. <:s><:#284,9360><:f,2Times New Roman,>
  439.  
  440. <:#202,9360><:f200,QCourier,>#define MAX_SHADOW_TEXT    26
  441.  
  442. <:s><:#202,9360><:f200,QCourier,>/* due to Gpf definitions this <:f><:f200,QCourier,> structure must be <<= 60 bytes */ 
  443.  
  444. <:s><:#202,9360><:f200,QCourier,>#pragma pack(1)
  445.  
  446. <:s><:#202,9360><:f200,QCourier,>typedef struct{
  447.  
  448. <:#202,9360><:f200,QCourier,>    USHORT    cBytes;
  449.  
  450. <:#202,9360><:f200,QCourier,>    CHAR    chText<[>MAX_SHADOW_TEXT];
  451.  
  452. <:#202,9360><:f200,QCourier,>    ULONG    BgColor;
  453.  
  454. <:#202,9360><:f200,QCourier,>    SHORT    BgIndex;
  455.  
  456. <:#202,9360><:f200,QCourier,>    ULONG    FgColor;
  457.  
  458. <:#202,9360><:f200,QCourier,>    SHORT    FgIndex;
  459.  
  460. <:#202,9360><:f200,QCourier,>    ULONG    LeftColor;
  461.  
  462. <:#202,9360><:f200,QCourier,>    SHORT    LeftIndex;
  463.  
  464. <:#202,9360><:f200,QCourier,>    ULONG    RightColor;
  465.  
  466. <:#202,9360><:f200,QCourier,>    SHORT    RightIndex;
  467.  
  468. <:#202,9360><:f200,QCourier,>    SHORT    sAngle;
  469.  
  470. <:#202,9360><:f200,QCourier,>    BOOL    fOverride;
  471.  
  472. <:#202,9360><:f200,QCourier,>    } UCPARAMS;
  473.  
  474. <:#202,9360><:f200,QCourier,>typedef UCPARAMS * PUCPARAMS;
  475.  
  476. <:s><:#202,9360><:f200,QCourier,>#pragma pack()<:f200,,><:f>
  477.  
  478. <:s><:#284,9360>
  479.  
  480. <:#568,9360>Member 'cBytes' will be used as a test of whether or not the structure has been initialized. After initialization the sizeof(UCPARAMS) number will be placed here. 
  481.  
  482. <:#852,9360>All members suffixed with 'Color' will contain the OS/2 PM definition for a color, such as CLR_BLACK. All colors known to this control are in structure 'Colors', found at the top of file SHADEXT.C. 
  483.  
  484. <:s><:#852,9360>All members suffixed with 'Index' are used to hold the offset into the 'Colors' structure for the related 'Color' member. This is for convenience only, and comes in handy when communicating with the combo boxes which display the current and the available ch
  485. oices.
  486.  
  487. <:#284,9360>Member 'sAngle' will contain the tilt angle, read from a spin button having a range of +/- 30.
  488.  
  489. <:#852,9360>Member 'fOverride' will follow a check button in the extended dialog, and when true will cause the WM_PAINT procedure to ignore Presentation Parameters and use the colors specified by the user from the extended dialog.
  490.  
  491. <:s><:#284,9360>
  492.  
  493. <:#1420,9360>It is important to understand that Gpf itself will know nothing about this structure, and will care even less. But it will maintain a pointer, set to NULL or to the enclosing area (UCC.Reserved). A NULL value is the initial value and will stay that way unle
  494. ss and until the extended dialog is invoked at least once. Then it will be fixed to point to the reserved block. This pointer is available at these times:
  495.  
  496. <:#284,9360>    - for Gpf's default User Control dialog functions
  497.  
  498. <:#284,9360>        In RegisterShadowx one can, if one really desires, derive &Ucc.Reserved
  499.  
  500. <:#568,9360>        In fnwpShadowx, message WM_CREATE, it is passed in as 'mp1'. It may or may not be NULL, subject to the explanation above.
  501.  
  502. <:s><:#284,9360>    - for the extended dialog functions
  503.  
  504. <:#1704,9360>        In fnwpExtShadowx, message WM_INITDLG, it is passed in as 'mp2'. Here it is never NULL and we will immediately capture it into a static variable, available then to all other messages including any further WM_INITDLG. Keep in mind that the entire UCC struc
  505. ture is primarily for the use of Gpf, and we will keep a local copy of the reserved area in the 'window words' of each control instance. How? Let's examine the modifications to WM_CREATE in fnwpShadowx(). 
  506.  
  507. <:#3124,9360>As in the simple case, 'mp2' is a pointer to a CREATESTRUCT defined by OS/2 PM header files. The member of interest to us is 'pszText', into which Gpf will stuff any text entered by the Gpf user during the default dialog. The pointer to the reserved block w
  508. ill be in 'mp1', providing that the extended dialog has been invoked at least once. The first time that WM_CREATE is called there is no possibility of having gone through the extended dialog, hence Gpf will have set this to NULL. Meanwhile, we allocate stor
  509. age for a UCPARAMS structure and initialize a pointer to this block. Next we check 'mp1', here type cast to a PUCPARAMS. If it is NULL we init two of the color fields in our local structure; if it is non-NULL, we copy the entire contents into our local inst
  510. ance. The text is then copied, in both cases, to the newly allocated structure. It is then tucked away for future use with the WinSetWindowPtr() function. WM_PAINT will have access to this pointer, and will modify itself according to the information. Now to
  511.  the extended dialog...
  512.  
  513. <:s><:#284,9360><:f,2Times New Roman,>
  514.  
  515. <:f,2Times New Roman,>The window procedure, fnwpExtShadowx, will always be given a true and valid<:f><:f,2Times New Roman,> pointer to the reserved, 60-byte area (via 'mp2'). As this window is constantly<:f><:f,2Times New Roman,> being created and destroyed
  516. , we must implement a mechanism to determine the validity of the structure contents. It would be nice, for example, to set all the controls to their last-invoked state. But testing for a NULL pointer will not work, as it is never NULL. Hence we do something
  517.  else, we set member 'cBytes' to a certain value at the first opportunity. Now we can test the contents of 'cBytes' for this value. If it is incorrect we know this is the first time it is seen by our window procedure, and we initialize ALL relevant members 
  518. to desired values. <:f><:f,2Times New Roman,>The remaining controls can then be initialized with respect to the structure contents, new or existing, and this completes our WM_INITDLG phase.
  519.  
  520. <:s><:#284,9360><:f,2Times New Roman,>
  521.  
  522. <:#1420,9360><:f,2Times New Roman,>The only remaining job is to catch user interactions with the extended dialog controls. Since they will all generate a WM_COMMAND message, that is where we lump them. Parameter 'mp1' tells us the control ID and the nature of the messag
  523. e. A big switch statement is built to take care of all possibilities of interest to us. Those of no interest should not be ignored, but rather passed to WinDefDlgProc(). Bizarre things can happen if you forget to do this.
  524.  
  525. <:s><:#284,9360><:f,2Times New Roman,>
  526.  
  527. <:f,2Times New Roman,>Using this control is similar to the simple example, except that you must change the name to 'shadowx'. Obviously nothing prevents you from using both types of control, in the same application.
  528.  
  529. <:s><:#284,9360><:f,2Times New Roman,>
  530.  
  531. <:s><:#284,9360><:f,2Times New Roman,>Alexander Charov, 
  532.  
  533. <:#284,9360><:f,2Times New Roman,>December 1994
  534.  
  535. >
  536.  
  537. [Embedded]
  538. 00023914
  539.