home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / CTRLDES.ZIP / CONTROLS.C next >
C/C++ Source or Header  |  1993-04-27  |  55KB  |  1,518 lines

  1.  
  2. /* Program name:   Controls.C  Title: Designing    Custom Controls        */
  3. /* OS/2    Developer Magazine, Issue:  Spring '93, page 72                 */
  4. /* Author:  Mark Benge     IBM Corp.                    */
  5. /*        Matt Smith     Prominare Inc.                    */
  6. /* Description:     Custom    controls demystified.  Sample custom controls.    */
  7. /*         Can be    used as    the basis for other custom controls.    */
  8. /* Program Requirements:  OS/2 2.0, IBM    C Set/2    or WATCOM C 386/9.0    */
  9. /*              OS/2 Toolkit                    */
  10.  
  11. /* DISCLAIMER OF WARRANTIES:                        */
  12. /* -------------------------                        */
  13. /* The following [enclosed] code is sample code    created    by IBM        */
  14. /* Corporation and Prominare Inc.  This    sample code is not part    of any    */
  15. /* standard IBM    product    and is provided    to you solely for the purpose    */
  16. /* of assisting    you in the development of your applications.  The code    */
  17. /* is provided "AS IS",    without    warranty of any    kind.  Neither IBM nor    */
  18. /* Prominare shall be liable for any damages arising out of your    */
  19. /* use of the sample code, even    if they    have been advised of the    */
  20. /* possibility of such damages.                        */
  21.  
  22. #define    INCL_DOS           /* Include OS/2 DOS Kernal        */
  23. #define    INCL_GPI           /* Include OS/2 PM GPI Interface    */
  24. #define    INCL_WIN           /* Include OS/2 PM Windows Interface    */
  25.  
  26. #include <os2.h>
  27. #include <string.h>
  28.  
  29. #include "controls.h"
  30.  
  31. /* This    module contains    an example installable control that can    be used    */
  32. /* by any OS/2 2.x Presentation    Manager    application.  The control    */
  33. /* demonstrates    the principles of creating a custom control such    */
  34. /* that    new custom controls can    be created using this as a model.    */
  35. /*                                    */
  36. /* The control can be compiled using the IBM C Set/2 Version 1.0 with    */
  37. /* the following:                            */
  38. /*                                    */
  39. /*   Icc -G3e- -O+ -Rn -W3 -C -FoControls.Obj Controls.C        */
  40. /*                                    */
  41. /* The control can be compiled using the WATCOM    C 386 Version 9.0 with    */
  42. /* the following:                            */
  43. /*                                    */
  44. /*   Wcl386 -ms    -3s -bd    -s -ox -zp4 -w3    -c -fo=Controls.Obj Controls.C    */
  45.  
  46. /* Filename:   Controls.C                        */
  47.  
  48. /*  Version:   1.00                            */
  49. /*  Created:   1992-09-02                        */
  50. /*  Revised:   1992-12-30                        */
  51. /* Released:   1993-04-22                        */
  52.  
  53. /* Routines:   ULONG EXPENTRY InitControls(HAB hAB);            */
  54. /*           static VOID CalcFrameSize(PRECTL    prcl, PSFRAME psframe);    */
  55. /*           static VOID CalcLineSize(HWND hWnd, PRECTL prcl,        */
  56. /*                    PLINEFIELD plf);        */
  57. /*           static VOID CalcTextSize(PRECTL prcl, PTEXTFIELD    ptf);    */
  58. /*           static LONG lGetPresParam(HWND hWnd, ULONG ulID1,    */
  59. /*                     ULONG ulID2, LONG lDefault);    */
  60. /*           static VOID SetDefaultTextColours(HWND hWnd,        */
  61. /*                         PTEXTFIELD ptf);    */
  62. /*           MRESULT EXPENTRY    FrameWndProc(HWND hWnd,    ULONG msg,    */
  63. /*                         MPARAM mp1, MPARAM    mp2);    */
  64. /*           MRESULT EXPENTRY    Line3DWndProc(HWND hWnd, ULONG msg,    */
  65. /*                          MPARAM mp1, MPARAM mp2);    */
  66. /*           MRESULT EXPENTRY    PatternWndProc(HWND hWnd, ULONG    msg,    */
  67. /*                           MPARAM mp1, MPARAM mp2);    */
  68. /*           MRESULT EXPENTRY    Text3DWndProc(HWND hWnd, ULONG msg,    */
  69. /*                          MPARAM mp1, MPARAM mp2);    */
  70.  
  71. /* Copyright ╕ International Business Machines Corp., 1991,1992,1993.    */
  72. /* Copyright ╕ 1989-1993  Prominare Inc.  All Rights Reserved.        */
  73.  
  74. /* --------------------------------------------------------------------    */
  75.  
  76.  
  77. #define    USER_RESERVED       16       /* Control Reserved Memory Size    */
  78.  
  79. #define    QUCWP_STYLE (QWL_USER +     4)/* Pointer to Styles    Flag        */
  80. #define    QUCWP_HEAP  (QWL_USER +     8)/* Pointer to Heap Handle        */
  81. #define    QUCWP_WNDP  (QWL_USER +    12)/* Pointer to Heap Pointer        */
  82.  
  83.  
  84. /************************************************************************/
  85. /*                                    */
  86. /*     Private Control Data used by each different control type        */
  87. /*                                    */
  88. /************************************************************************/
  89.  
  90. typedef    struct _TEXTFIELD       /* tf */
  91.    {
  92.    HWND      hwndText;           /* Static Text Handle        */
  93.    HWND      hwndOwner;           /* Owner Window Handle        */
  94.    POINTL aptl[5];           /* Entry Field Outline Points    */
  95.    ULONG  lClrLeftTop;           /* Left and Top Edge    Colour        */
  96.    ULONG  lClrBottomRight;       /* Right and    Bottom Edge Colour    */
  97.    BOOL      fRaised;           /* Raised Field Flag            */
  98.    ULONG  aClr[7];           /* Presentation Colours Array    */
  99.    } TEXTFIELD ;
  100.  
  101. typedef    TEXTFIELD *PTEXTFIELD;
  102.  
  103. typedef    struct _LINEFIELD       /* lf */
  104.    {
  105.    HWND      hwndOwner;           /* Owner Window Handle        */
  106.    POINTL aptl[4];           /* Entry Field Outline Points    */
  107.    } LINEFIELD ;
  108.  
  109. typedef    LINEFIELD *PLINEFIELD;
  110.  
  111. typedef    struct _SFRAME           /* sframe */
  112.    {
  113.    POINTL aptl[2];           /* Shadowed Frame Outline Points    */
  114.    POINTL aptlShadow[2];       /* Shadowed Frame Outline Points    */
  115.    RECTL  rcl;               /* Frame Rectangle            */
  116.    } SFRAME ;
  117.  
  118. typedef    SFRAME *PSFRAME;
  119.  
  120. typedef    struct _PATTERN           /* pat */
  121.    {
  122.    RECTL    rcl;           /* Frame Rectangle            */
  123.    HPOINTER hptrArrow;           /* Arrow Pointer            */
  124.    ULONG    flStyle;           /* Control Style            */
  125.    ULONG    aClr[7];           /* Presentation Colours Array    */
  126.    } PATTERN ;
  127.  
  128. typedef    PATTERN    *PPATTERN;
  129.  
  130. /* --- Local Function Definitions -------------------------------------    */
  131.  
  132. static VOID CalcFrameSize(PRECTL prcl, PSFRAME psframe);
  133. static VOID CalcLineSize(HWND hWnd, PRECTL prcl, PLINEFIELD plf);
  134. static VOID CalcTextSize(PRECTL    prcl, PTEXTFIELD ptf);
  135. static LONG lGetPresParam(HWND hWnd, ULONG ulID1, ULONG    ulID2, LONG lDefault);
  136. static VOID SetDefaultTextColours(HWND hWnd, PTEXTFIELD    ptf);
  137.  
  138. MRESULT    EXPENTRY FrameWndProc(HWND hWnd, ULONG msg, MPARAM mp1,    MPARAM mp2);
  139. MRESULT    EXPENTRY Line3DWndProc(HWND hWnd, ULONG    msg, MPARAM mp1, MPARAM    mp2);
  140. MRESULT    EXPENTRY PatternWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  141. MRESULT    EXPENTRY Text3DWndProc(HWND hWnd, ULONG    msg, MPARAM mp1, MPARAM    mp2);
  142.  
  143. /* --- Public Function Definitions ------------------------------------    */
  144.  
  145. ULONG EXPENTRY InitControls(HAB    hAB);
  146.  
  147. #pragma    subtitle("   Image Button Control - DLL Initialization/Termination Procedure")
  148. #pragma    page( )
  149.  
  150. /* --- InitControls ------------------------------------ [ Public ] ---    */
  151. /*                                    */
  152. /*     This function is    used to    provide    the control initialization    */
  153. /*     by registering the custom controls with OS/2 PM.            */
  154. /*                                    */
  155. /*     Upon Entry:                            */
  156. /*                                    */
  157. /*     HAB hAB;    = Anchor Block Handle                    */
  158. /*                                    */
  159. /*     Upon Exit:                            */
  160. /*                                    */
  161. /*     InitControls =  0 : Error Return                    */
  162. /*            =  1 : Successful Initialization            */
  163. /*                                    */
  164. /* --------------------------------------------------------------------    */
  165.  
  166. ULONG EXPENTRY InitControls(HAB    hAB)
  167.  
  168. {
  169.                /* Register the control class with OS/2        */
  170.                /* Presentation Manager and return registration    */
  171.                /* result                    */
  172.  
  173. if ( !WinRegisterClass(hAB, "3DFrame", (PFNWP)FrameWndProc,
  174.                CS_SYNCPAINT | CS_HITTEST | CS_PARENTCLIP | CS_SIZEREDRAW,
  175.                USER_RESERVED) )
  176.    return(0UL);
  177.                /* Register the control class with OS/2        */
  178.                /* Presentation Manager and return registration    */
  179.                /* result                    */
  180.  
  181. if ( !WinRegisterClass(hAB, "Patterns",    (PFNWP)PatternWndProc,
  182.                CS_SYNCPAINT | CS_HITTEST | CS_PARENTCLIP | CS_SIZEREDRAW,
  183.                USER_RESERVED) )
  184.    return(0UL);
  185.                /* Register the control class with OS/2        */
  186.                /* Presentation Manager and return registration    */
  187.                /* result                    */
  188.  
  189. if ( !WinRegisterClass(hAB, "3DLine", (PFNWP)Line3DWndProc,
  190.                CS_SYNCPAINT | CS_HITTEST | CS_PARENTCLIP | CS_SIZEREDRAW,
  191.                USER_RESERVED) )
  192.    return(0UL);
  193.                /* Register the control class with OS/2        */
  194.                /* Presentation Manager and return registration    */
  195.                /* result                    */
  196.  
  197. if ( !WinRegisterClass(hAB, "3DText", (PFNWP)Text3DWndProc,
  198.                CS_SYNCPAINT | CS_HITTEST | CS_PARENTCLIP | CS_SIZEREDRAW,
  199.                USER_RESERVED) )    
  200.    return(0UL);
  201.                /* Retrun successful registration value        */
  202. return(1UL);
  203. }
  204. #pragma    subtitle("   Custom Controls - Window Size Calculation Procedure")
  205. #pragma    page ( )
  206.  
  207. /* --- CalcFrameSize ----------------------------------    [ Private ] ---    */
  208. /*                                    */
  209. /*     This function is    used to    calculate the sizes and    positions    */
  210. /*     of the various elements that are    used to    make up    a shadowed    */
  211. /*     frame.                                */
  212. /*                                    */
  213. /*     Upon Entry:                            */
  214. /*                                    */
  215. /*     PRECTL  prcl;    = Control Rectangle Pointer            */
  216. /*     PSFRAME psframe;    = Frame    Private    Data Pointer            */
  217. /*                                    */
  218. /*     Upon Exit:                            */
  219. /*                                    */
  220. /*     Nothing                                */
  221. /*                                    */
  222. /* --------------------------------------------------------------------    */
  223.  
  224. static VOID CalcFrameSize(PRECTL prcl, PSFRAME psframe)
  225.  
  226. {
  227.            /* Display points:                    */
  228.            /*                            */
  229.            /*      1                  2            */
  230.            /*       +-------------------------+            */
  231.            /*       |                 |            */
  232.            /*       |                 |            */
  233.            /*       |                 |            */
  234.            /*       |                 |            */
  235.            /*       +-------------------------+            */
  236.            /*      0 4                  3            */
  237.  
  238. psframe->rcl = *prcl;
  239.  
  240. psframe->aptl[0].x = prcl->xLeft + 1L;
  241. psframe->aptl[0].y = prcl->yBottom;
  242. psframe->aptl[1].x = prcl->xRight - 1L;
  243. psframe->aptl[1].y = prcl->yTop    - 2L;
  244.  
  245. psframe->aptlShadow[0].x = prcl->xLeft;
  246. psframe->aptlShadow[0].y = prcl->yBottom + 1L;
  247. psframe->aptlShadow[1].x = prcl->xRight    - 2L;
  248. psframe->aptlShadow[1].y = prcl->yTop -    1L;
  249. }
  250. #pragma    subtitle("   Custom Controls - Control Window Procedure")
  251. #pragma    page ( )
  252.  
  253. /* --- CalcLineSize -----------------------------------    [ Private ] ---    */
  254. /*                                    */
  255. /*     This function is    used to    calculate the sizes and    positions    */
  256. /*     of the various elements that are    used to    make up    a 3D line    */
  257. /*     field.                                */
  258. /*                                    */
  259. /*     Upon Entry:                            */
  260. /*                                    */
  261. /*     HWND      hWnd;    = Window Handle                    */
  262. /*     PRECTL      prcl;    = Control Rectangle Pointer            */
  263. /*     PLINEFIELD ptf;    = Private Line Data Pointer            */
  264. /*                                    */
  265. /*     Upon Exit:                            */
  266. /*                                    */
  267. /*     Nothing                                */
  268. /*                                    */
  269. /* --------------------------------------------------------------------    */
  270.  
  271. static VOID CalcLineSize(HWND hWnd, PRECTL prcl, PLINEFIELD plf)
  272.  
  273. {
  274.            /*  Line    display    points                    */
  275.            /*                            */
  276.            /*      0                  1            */
  277.            /*       ===========================            */
  278.            /*      2                  3            */
  279.  
  280. if ( WinQueryWindowULong(hWnd, QWL_STYLE) & LNS_VERTICAL )
  281.    {
  282.    plf->aptl[0].x = plf->aptl[1].x = (prcl->xRight - prcl->xLeft) / 2L +
  283.                       prcl->xLeft;
  284.    plf->aptl[2].x = plf->aptl[3].x = plf->aptl[0].x + 1L;
  285.    plf->aptl[0].y = plf->aptl[2].y = prcl->yBottom;
  286.    plf->aptl[1].y = plf->aptl[3].y = prcl->yTop      - 1L;
  287.    }
  288. else
  289.    {
  290.    plf->aptl[0].x = plf->aptl[2].x = prcl->xLeft;
  291.    plf->aptl[1].x = plf->aptl[3].x = prcl->xRight;
  292.    plf->aptl[0].y = plf->aptl[1].y = (prcl->yTop - prcl->yBottom) / 2L +
  293.                       prcl->yBottom;
  294.    plf->aptl[2].y = plf->aptl[3].y = plf->aptl[0].y - 1L;
  295.    }
  296. }
  297. #pragma    subtitle("   Custom Controls - Control Window Sizing Procedure")
  298. #pragma    page ( )
  299.  
  300. /* --- CalcTextSize -----------------------------------    [ Private ] ---    */
  301. /*                                    */
  302. /*     This function is    used to    calculate the sizes and    positions    */
  303. /*     of the various elements that are    used to    make up    a shadowed    */
  304. /*     text field.                            */
  305. /*                                    */
  306. /*     Upon Entry:                            */
  307. /*                                    */
  308. /*     PRECTL      prcl;    = Control Rectangle Pointer            */
  309. /*     PTEXTFIELD ptf;    = Private Text Data Pointer            */
  310. /*                                    */
  311. /*     Upon Exit:                            */
  312. /*                                    */
  313. /*     Nothing                                */
  314. /*                                    */
  315. /* --------------------------------------------------------------------    */
  316.  
  317. static VOID CalcTextSize(PRECTL    prcl, PTEXTFIELD ptf)
  318.  
  319. {
  320.            /*  Text    display    points                    */
  321.            /*                            */
  322.            /*      1                  2            */
  323.            /*       +-------------------------+            */
  324.            /*       |                 |            */
  325.            /*       |                 |            */
  326.            /*       |                 |            */
  327.            /*       |                 |            */
  328.            /*       +-------------------------+            */
  329.            /*      0 4                  3            */
  330.  
  331. ptf->aptl[0].x = prcl->xLeft;
  332. ptf->aptl[0].y = prcl->yBottom;
  333. ptf->aptl[1].x = prcl->xLeft;
  334. ptf->aptl[1].y = prcl->yTop   -    1L;
  335. ptf->aptl[2].x = prcl->xRight -    1L;
  336. ptf->aptl[2].y = prcl->yTop   -    1L;
  337. ptf->aptl[3].x = prcl->xRight -    1L;
  338. ptf->aptl[3].y = prcl->yBottom;
  339. ptf->aptl[4].x = prcl->xLeft;
  340. ptf->aptl[4].y = prcl->yBottom;
  341.  
  342. WinSetWindowPos(ptf->hwndText, HWND_BOTTOM,
  343.         (prcl->xLeft + 2L), (prcl->yBottom + 1L),
  344.         (prcl->xRight -    prcl->xLeft - 4L),
  345.         (prcl->yTop - prcl->yBottom - 2L),
  346.         SWP_MOVE | SWP_SIZE | SWP_SHOW);
  347. }
  348. #pragma    subtitle("   Custom Controls - Control Window Procedure")
  349. #pragma    page( )
  350.  
  351. /* --- lGetPresParam ----------------------------------    [ Private } ---    */
  352. /*                                    */
  353. /*     This function is    used to    retrieve a presentation    parameter    */
  354. /*     that may    be present.  If    the presentation parameter is not,    */
  355. /*     the default colour passed to the    function will be used.        */
  356. /*                                    */
  357. /*     Upon Entry:                            */
  358. /*                                    */
  359. /*     HWND  hWnd;     = Window    Handle                    */
  360. /*     ULONG ulID1;    = Presentation Parameter    1 ID            */
  361. /*     ULONG ulID2;    = Presentation Parameter    2 ID            */
  362. /*     LONG  lDefault; = Default Colour                    */
  363. /*                                    */
  364. /*     Upon Exit:                            */
  365. /*                                    */
  366. /*     lGetPresParam = Colour to Use                    */
  367. /*                                    */
  368. /* --------------------------------------------------------------------    */
  369.  
  370. static LONG lGetPresParam(HWND hWnd, ULONG ulID1, ULONG    ulID2, LONG lDefault)
  371.  
  372. {
  373. HPS   hPS;               /* Presentation Space Handle        */
  374. LONG  lClr;               /* Presentation Parameter Colour    */
  375. ULONG ulID;               /* Presentation Parameter ID        */
  376.  
  377. if ( WinQueryPresParam(hWnd, ulID1, ulID2, &ulID, 4, (PVOID)&lClr,
  378.                QPF_NOINHERIT | QPF_ID1COLORINDEX | QPF_ID2COLORINDEX | QPF_PURERGBCOLOR) )
  379.    return(lClr);
  380. else
  381.    if (    (lDefault >= SYSCLR_SHADOWHILITEBGND) &&
  382.     (lDefault <= SYSCLR_HELPHILITE)    )
  383.        return(WinQuerySysColor(HWND_DESKTOP, lDefault, 0L));
  384.    else
  385.        if ( (lClr = GpiQueryRGBColor(hPS = WinGetPS(hWnd),
  386.                      LCOLOPT_REALIZED, lDefault)) == GPI_ALTERROR )
  387.        {
  388.        WinReleasePS(hPS);
  389.        return(lDefault);
  390.        }
  391.        else
  392.        {
  393.        WinReleasePS(hPS);
  394.        return(lClr);
  395.        }
  396. }
  397. #pragma    subtitle("   Custom Controls - Default Colours Procedure")
  398. #pragma    page( )
  399.  
  400. /* --- SetDefaultTextColours --------------------------    [ Private ] ---    */
  401. /*                                    */
  402. /*     This function is    used to    set the    default    colours    that the    */
  403. /*     image button should use within the internal paint routines.    */
  404. /*     The colour can either be    a presentation parameter that has    */
  405. /*     been set    or it can be the default colour    as defined within    */
  406. /*     control.                                */
  407. /*                                    */
  408. /*     Upon Entry:                            */
  409. /*                                    */
  410. /*     HWND      hWnd;    = Window Handle                    */
  411. /*     PTEXTFIELD ptf;    = Text Control Structure Pointer        */
  412. /*                                    */
  413. /*     Upon Exit:                            */
  414. /*                                    */
  415. /*     Nothing                                */
  416. /*                                    */
  417. /* --------------------------------------------------------------------    */
  418.  
  419. static VOID SetDefaultTextColours(HWND hWnd, PTEXTFIELD    ptf)
  420.  
  421. {
  422.                /* Set up the colours that will be used within    */
  423.                /* the painting of the control.    The colour    */
  424.                /* indices are:                    */
  425.                /*                        */
  426.                /* 0 : Foreground (PP_FOREGROUND*)        */
  427.                /* 1 : Background (PP_BACKGROUND*)        */
  428.                /* 2 : Hilight Foreground (PP_HILITEFOREGROUND*)    */
  429.                /* 3 : Hilight Background (PP_HILITEBACKGROUND*)    */
  430.                /* 4 : Disabled Foreground (PP_DISABLEDFORE*)    */
  431.                /* 5 : Disabled Foreground (PP_DISABLEDFORE*)    */
  432.                /* 6 : Border (PP_BORDER*)            */
  433.  
  434. ptf->aClr[0] = lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
  435.                  PP_FOREGROUNDCOLORINDEX,
  436.                  SYSCLR_OUTPUTTEXT);
  437. ptf->aClr[1] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
  438.                  PP_BACKGROUNDCOLORINDEX,
  439.                  SYSCLR_FIELDBACKGROUND);
  440. ptf->aClr[2] = lGetPresParam(hWnd, PP_HILITEFOREGROUNDCOLOR,
  441.                  PP_HILITEFOREGROUNDCOLORINDEX,
  442.                  SYSCLR_OUTPUTTEXT);
  443. ptf->aClr[3] = lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
  444.                  PP_HILITEBACKGROUNDCOLORINDEX,
  445.                  SYSCLR_BACKGROUND);
  446. ptf->aClr[4] = lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
  447.                  PP_DISABLEDFOREGROUNDCOLORINDEX,
  448.                  SYSCLR_OUTPUTTEXT);
  449. ptf->aClr[5] = lGetPresParam(hWnd, PP_DISABLEDBACKGROUNDCOLOR,
  450.                  PP_DISABLEDBACKGROUNDCOLORINDEX,
  451.                  SYSCLR_BACKGROUND);
  452. ptf->aClr[6] = lGetPresParam(hWnd, PP_BORDERCOLOR,
  453.                  PP_BORDERCOLORINDEX,
  454.                  SYSCLR_BUTTONDARK);
  455. }
  456. #pragma    subtitle("   Custom Controls - Control Window Procedure")
  457. #pragma    page ( )
  458.  
  459. /* --- FrameWndProc ---------------------------------------------------    */
  460. /*                                    */
  461. /*     This function is    used to    handle the messages sent to the        */
  462. /*     installed control.  The window procedure    is designed to        */
  463. /*     allow for multiple instances and    to be totally re-entrant.    */
  464. /*                                    */
  465. /*     Upon Entry:                            */
  466. /*                                    */
  467. /*     HWND   hWnd; = Window Handle                    */
  468. /*     ULONG  msg;  = PM Message                    */
  469. /*     MPARAM mp1;  = Message Parameter    1                */
  470. /*     MPARAM mp2;  = Message Parameter    2                */
  471. /*                                    */
  472. /*     Upon Exit:                            */
  473. /*                                    */
  474. /*     FrameWndProc = Message Handling Result                */
  475. /*                                    */
  476. /* --------------------------------------------------------------------    */
  477.  
  478. MRESULT    EXPENTRY FrameWndProc(HWND hWnd, ULONG msg, MPARAM mp1,    MPARAM mp2)
  479.  
  480. {
  481. HPS          hPS;           /* Presentation Space Handle        */
  482. PCREATESTRUCT pcrst;           /* Create Structure Pointer        */
  483. PSFRAME          psframe;           /* Frame Private Data Pointer    */
  484. PWNDPARAMS    pwprm;           /* Window Parameters    Pointer        */
  485. RECTL          rcl;           /* Rectangle    Holder            */
  486.  
  487. switch ( msg )
  488.    {
  489.  
  490. /************************************************************************/
  491. /************************************************************************/
  492. /*                                    */
  493. /* Part    1: Control creation coding                    */
  494. /*                                    */
  495. /************************************************************************/
  496. /************************************************************************/
  497.  
  498.    /*********************************************************************/
  499.    /*  Control creation                            */
  500.    /*********************************************************************/
  501.  
  502.    case    WM_CREATE :
  503.                /* Allocate memory for the private control data    */
  504.  
  505.        DosAllocMem((PPVOID)&psframe, 4096UL, PAG_READ |    PAG_WRITE | PAG_COMMIT);
  506.  
  507.                /* Save the private control data    pointer    within    */
  508.                /* the controls reserved    memory            */
  509.  
  510.        WinSetWindowPtr(hWnd, QUCWP_WNDP, (PVOID)psframe);
  511.  
  512.                /* Get the control's creation structure address  */
  513.                /* to save the size of the control        */
  514.  
  515.        pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);
  516.        psframe->rcl.xLeft  = psframe->rcl.yBottom = 0L;
  517.        psframe->rcl.xRight = pcrst->cx;
  518.        psframe->rcl.yTop   = pcrst->cy;
  519.  
  520.                /* Determine the    display    points for the shadow    */
  521.  
  522.        CalcFrameSize(&psframe->rcl, psframe);
  523.        break;
  524.  
  525. /************************************************************************/
  526. /************************************************************************/
  527. /*                                    */
  528. /* Part    2: Control text    and colour support coding            */
  529. /*                                    */
  530. /************************************************************************/
  531. /************************************************************************/
  532.  
  533.    /*********************************************************************/
  534.    /*  Process window parameters query                    */
  535.    /*********************************************************************/
  536.  
  537.    case    WM_QUERYWINDOWPARAMS :
  538.  
  539.                /* Get the address for the windows parameters    */
  540.                /* structure                    */
  541.  
  542.        pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);
  543.  
  544.                /* Determine the    type of    query            */
  545.  
  546.        switch (    pwprm->fsStatus    )
  547.        {
  548.                /* Query    type:  get text    length            */
  549.  
  550.        case    WPM_CCHTEXT :
  551.  
  552.                /* Place    the length the string within the    */
  553.                /* structure                    */
  554.  
  555.            pwprm->cchText =    0;
  556.            break;
  557.                /* Query    type:  get control data    length        */
  558.  
  559.        case    WPM_CBCTLDATA :
  560.  
  561.                /* Set the control data length to zero        */
  562.  
  563.            pwprm->cbCtlData    = 0;
  564.            break;
  565.  
  566.        default :
  567.            return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  568.        }
  569.        break;
  570.  
  571. /************************************************************************/
  572. /************************************************************************/
  573. /*                                    */
  574. /* Part    3: Control size    and position coding                */
  575. /*                                    */
  576. /************************************************************************/
  577. /************************************************************************/
  578.  
  579.    /*********************************************************************/
  580.    /*  Size of the control changing                    */
  581.    /*********************************************************************/
  582.  
  583.    case    WM_SIZE    :
  584.        WinQueryWindowRect(hWnd,    &rcl);
  585.        CalcFrameSize(&rcl,
  586.              (PSFRAME)WinQueryWindowPtr(hWnd, QUCWP_WNDP));
  587.        break;
  588.  
  589. /************************************************************************/
  590. /************************************************************************/
  591. /*                                    */
  592. /* Part    4: User    interaction coding for keyboard    and mouse        */
  593. /*                                    */
  594. /************************************************************************/
  595. /************************************************************************/
  596.  
  597.    /*********************************************************************/
  598.    /*  Process mouse hit testing                    */
  599.    /*********************************************************************/
  600.  
  601.    case    WM_HITTEST :
  602.        return(MRFROMLONG(HT_TRANSPARENT));
  603.  
  604. /************************************************************************/
  605. /************************************************************************/
  606. /*                                    */
  607. /* Part    5: Control painting and    appearance coding            */
  608. /*                                    */
  609. /************************************************************************/
  610. /************************************************************************/
  611.  
  612.    /*********************************************************************/
  613.    /*  Erase background                            */
  614.    /*********************************************************************/
  615.  
  616.    case    WM_ERASEBACKGROUND :
  617.  
  618.                /* Have OS/2 Presentation Manager perform the    */
  619.                /* background erase on behalf of    the button    */
  620.  
  621.        return(MRFROMLONG(TRUE));
  622.  
  623.    /*********************************************************************/
  624.    /*  Paint the button                            */
  625.    /*********************************************************************/
  626.  
  627.    case    WM_PAINT :
  628.                /* Get the address of the private data from the    */
  629.                /* control's reserved memory                     */
  630.  
  631.        psframe = (PSFRAME)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  632.  
  633.                /* Get the presentation space for the control    */
  634.                /* and set the colour table to RGB mode        */
  635.  
  636.        GpiCreateLogColorTable(hPS = WinBeginPaint(hWnd,    (HPS)NULL, (PRECTL)NULL),
  637.                   0L, LCOLF_RGB, 0L, 0L, (PLONG)NULL);
  638.  
  639.                /* Set the colour of the    highlight edge to white    */
  640.  
  641.        GpiSetColor(hPS,    0x00FFFFFF);
  642.  
  643.                /* Draw the highlighted part of the frame    */
  644.  
  645.        GpiMove(hPS, psframe->aptl);
  646.        GpiBox(hPS, DRO_OUTLINE,    &psframe->aptl[1], 0L, 0L);
  647.  
  648.                /* Set the colour for the shadow    component    */
  649.  
  650.        GpiSetColor(hPS,    (LONG)WinQuerySysColor(HWND_DESKTOP, SYSCLR_SHADOW, 0L));
  651.  
  652.                /* Draw the shadow part of the frame        */
  653.  
  654.        GpiMove(hPS, psframe->aptlShadow);
  655.        GpiBox(hPS, DRO_OUTLINE,    &psframe->aptlShadow[1], 0L, 0L);
  656.  
  657.        WinEndPaint(hPS);
  658.        break;
  659.  
  660. /************************************************************************/
  661. /************************************************************************/
  662. /*                                    */
  663. /* Part    6: Control destruction coding                    */
  664. /*                                    */
  665. /************************************************************************/
  666. /************************************************************************/
  667.  
  668.    /*********************************************************************/
  669.    /*  Window being destroyed, perform clean-up                */
  670.    /*********************************************************************/
  671.  
  672.    case    WM_DESTROY :
  673.                /* Get the address of the private data from the    */
  674.                /* control's reserved memory and release the     */
  675.                /* allocated memory                */
  676.  
  677.        DosFreeMem((PVOID)WinQueryWindowPtr(hWnd, QUCWP_WNDP));
  678.        break;
  679.                /* Default message processing            */
  680.    default :
  681.        return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  682.    }
  683.  
  684. return(0L);
  685. }
  686. #pragma    subtitle("   Custom Controls - Control Window Procedure")
  687. #pragma    page ( )
  688.  
  689. /* --- Line3DWndProc --------------------------------------------------    */
  690. /*                                    */
  691. /*     This function is    used to    handle the messages sent to the        */
  692. /*     installed control.  The window procedure    is designed to        */
  693. /*     allow for multiple instances and    to be totally re-entrant.    */
  694. /*                                    */
  695. /*     The styles supported for    the control are:            */
  696. /*                                    */
  697. /*     LNS_HORZ
  698. /*                                    */
  699. /*     Upon Entry:                            */
  700. /*                                    */
  701. /*     HWND   hWnd; = Window Handle                    */
  702. /*     ULONG  msg;  = PM Message                    */
  703. /*     MPARAM mp1;  = Message Parameter    1                */
  704. /*     MPARAM mp2;  = Message Parameter    2                */
  705. /*                                    */
  706. /*     Upon Exit:                            */
  707. /*                                    */
  708. /*     Line3DWndProc = Message Handling    Result                */
  709. /*                                    */
  710. /* --------------------------------------------------------------------    */
  711.  
  712. MRESULT    EXPENTRY Line3DWndProc(HWND hWnd, ULONG    msg, MPARAM mp1, MPARAM    mp2)
  713.  
  714. {
  715. HPS          hPS;           /* Presentation Space Handle        */
  716. PCREATESTRUCT pcrst;           /* Create Structure Pointer        */
  717. PLINEFIELD    plf;           /* Text Field Structure Pointer    */
  718. RECTL          rcl;           /* Rectangle    Holder            */
  719. PWNDPARAMS    pwprm;           /* Window Parameters    Pointer        */
  720.  
  721. switch ( msg )
  722.    {
  723.  
  724. /************************************************************************/
  725. /************************************************************************/
  726. /*                                    */
  727. /* Part    1: Control creation coding                    */
  728. /*                                    */
  729. /************************************************************************/
  730. /************************************************************************/
  731.  
  732.    /*********************************************************************/
  733.    /*  Control creation                            */
  734.    /*********************************************************************/
  735.  
  736.    case    WM_CREATE :
  737.                /* Allocate memory for the private control data    */
  738.  
  739.        DosAllocMem((PPVOID)&plf, 4096UL, PAG_COMMIT | PAG_READ | PAG_WRITE);
  740.  
  741.                /* Save the private control data    pointer    within    */
  742.                /* the controls reserved    memory            */
  743.  
  744.        WinSetWindowPtr(hWnd, QUCWP_WNDP, (PVOID)plf);
  745.  
  746.                /* Get the control's creation structure address  */
  747.                /* to save the size of the control  and the    */
  748.                /* control owner                    */
  749.  
  750.        pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);
  751.  
  752.        plf->hwndOwner =    pcrst->hwndOwner;
  753.  
  754.        rcl.xLeft   =\
  755.        rcl.yBottom = 0L;
  756.        rcl.xRight  = pcrst->cx;
  757.        rcl.yTop       = pcrst->cy;
  758.        CalcLineSize(hWnd, &rcl,    plf);
  759.        break;
  760.  
  761. /************************************************************************/
  762. /************************************************************************/
  763. /*                                    */
  764. /* Part    2: Control text    and colour support coding            */
  765. /*                                    */
  766. /************************************************************************/
  767. /************************************************************************/
  768.  
  769.    /*********************************************************************/
  770.    /*  Process window parameters query                    */
  771.    /*********************************************************************/
  772.  
  773.    case    WM_QUERYWINDOWPARAMS :
  774.  
  775.                /* Get the address for the windows parameters    */
  776.                /* structure                    */
  777.  
  778.        pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);
  779.  
  780.                /* Determine the    type of    query            */
  781.  
  782.        switch (    pwprm->fsStatus    )
  783.        {
  784.                /* Query    type:  get text    length            */
  785.  
  786.        case    WPM_CCHTEXT :
  787.  
  788.                /* Place    the length the string within the    */
  789.                /* structure                    */
  790.  
  791.            pwprm->cchText =    0;
  792.            break;
  793.                /* Query    type:  get control data    length        */
  794.  
  795.        case    WPM_CBCTLDATA :
  796.  
  797.                /* Set the control data length to zero        */
  798.  
  799.            pwprm->cbCtlData    = 0;
  800.            break;
  801.  
  802.        default :
  803.            return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  804.        }
  805.        break;
  806.  
  807. /************************************************************************/
  808. /************************************************************************/
  809. /*                                    */
  810. /* Part    3: Control size    and position coding                */
  811. /*                                    */
  812. /************************************************************************/
  813. /************************************************************************/
  814.  
  815.    /*********************************************************************/
  816.    /*  Size of the control changing                    */
  817.    /*********************************************************************/
  818.  
  819.    case    WM_SIZE    :
  820.        WinQueryWindowRect(hWnd,    &rcl);
  821.        CalcLineSize(hWnd, &rcl,
  822.         plf = (PLINEFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP));
  823.        break;
  824.  
  825. /************************************************************************/
  826. /************************************************************************/
  827. /*                                    */
  828. /* Part    4: User    interaction coding for keyboard    and mouse        */
  829. /*                                    */
  830. /************************************************************************/
  831. /************************************************************************/
  832.  
  833.    /*********************************************************************/
  834.    /*  Process mouse hit testing                    */
  835.    /*********************************************************************/
  836.  
  837.    case    WM_HITTEST :
  838.        return(MRFROMLONG(HT_TRANSPARENT));
  839.  
  840. /************************************************************************/
  841. /************************************************************************/
  842. /*                                    */
  843. /* Part    5: Control painting and    appearance coding            */
  844. /*                                    */
  845. /************************************************************************/
  846. /************************************************************************/
  847.  
  848.    /*********************************************************************/
  849.    /*  Erase background                            */
  850.    /*********************************************************************/
  851.  
  852.    case    WM_ERASEBACKGROUND :
  853.  
  854.                /* Have OS/2 Presentation Manager perform the    */
  855.                /* background erase on behalf of    the button    */
  856.  
  857.        return(MRFROMLONG(TRUE));
  858.  
  859.    /*********************************************************************/
  860.    /*  Paint the button                            */
  861.    /*********************************************************************/
  862.  
  863.    case    WM_PAINT :
  864.                /* Get the address of the private data from the    */
  865.                /* control's reserved memory                     */
  866.  
  867.        plf = (PLINEFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  868.  
  869.                /* Get the presentation space for the control    */
  870.                /* and set the colour table to RGB mode        */
  871.  
  872.        GpiCreateLogColorTable(hPS = WinBeginPaint(hWnd,    (HPS)NULL, (PRECTL)NULL),
  873.                   0L, LCOLF_RGB, 0L, 0L, (PLONG)NULL);
  874.  
  875.                /* Set the shadow colour    for the    line to    dark    */
  876.                /* gray                        */
  877.  
  878.        GpiSetColor(hPS,    (LONG)WinQuerySysColor(HWND_DESKTOP, SYSCLR_SHADOW, 0L));
  879.  
  880.                /* Display the shadow portion            */
  881.  
  882.        GpiMove(hPS, plf->aptl);
  883.        GpiLine(hPS, &plf->aptl[1]);
  884.  
  885.                /* Set the highlight colour for the line    to    */
  886.                /* white                        */
  887.  
  888.        GpiSetColor(hPS,    0x00ffffff);
  889.  
  890.                /* Display the highlight    portion            */
  891.  
  892.        GpiMove(hPS, &plf->aptl[2]);
  893.        GpiLine(hPS, &plf->aptl[3]);
  894.  
  895.        WinEndPaint(hPS);
  896.        break;
  897.  
  898. /************************************************************************/
  899. /************************************************************************/
  900. /*                                    */
  901. /* Part    6: Control destruction coding                    */
  902. /*                                    */
  903. /************************************************************************/
  904. /************************************************************************/
  905.  
  906.    /*********************************************************************/
  907.    /*  Window being destroyed, perform clean-up                */
  908.    /*********************************************************************/
  909.  
  910.    case    WM_DESTROY :
  911.                /* Get the address of the private data from the    */
  912.                /* control's reserved memory and release the     */
  913.                /* memory allocated for the use of the control    */
  914.  
  915.        DosFreeMem((PVOID)WinQueryWindowPtr(hWnd, QUCWP_WNDP));
  916.        break;
  917.                /* Default message processing            */
  918.    default :
  919.        return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  920.    }
  921.  
  922. return(0L);
  923. }
  924. #pragma    subtitle("   Custom Controls - Control Window Procedure")
  925. #pragma    page( )
  926.  
  927. /* --- PatternWndProc -------------------------------------------------    */
  928. /*                                    */
  929. /*     This function is    used to    process    the messages for the image    */
  930. /*     button control.                            */
  931. /*                                    */
  932. /*     Upon Entry:                            */
  933. /*                                    */
  934. /*     HWND   hWnd; = Window Handle                    */
  935. /*     ULONG  msg;  = PM Message                    */
  936. /*     MPARAM mp1;  = Message Parameter    1                */
  937. /*     MPARAM mp2;  = Message Parameter    2                */
  938. /*                                    */
  939. /*     Upon Exit:                            */
  940. /*                                    */
  941. /*     PatternWndProc =    Message    Handling Result                */
  942. /*                                    */
  943. /* --------------------------------------------------------------------    */
  944.  
  945. MRESULT    EXPENTRY PatternWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  946.  
  947. {
  948. HPS          hPS;           /* Presentation Space Handle        */
  949. PCREATESTRUCT pcrst;           /* Create Structure Pointer        */
  950. POINTL          ptl;           /* Drawing Point            */
  951. PPATTERN      ppat;           /* Image Button Structure Pointer    */
  952. PWNDPARAMS    pwprm;           /* Window Parameters    Pointer        */
  953.  
  954. switch ( msg )
  955.    {
  956.  
  957. /************************************************************************/
  958. /************************************************************************/
  959. /*                                    */
  960. /* Part    1: Control creation coding                    */
  961. /*                                    */
  962. /************************************************************************/
  963. /************************************************************************/
  964.  
  965.    /*********************************************************************/
  966.    /*  Control creation                            */
  967.    /*********************************************************************/
  968.  
  969.    case    WM_CREATE :
  970.                /* Allocate memory for the private control data    */
  971.  
  972.        DosAllocMem((PVOID)&ppat, 4096UL, PAG_READ | PAG_WRITE |    PAG_COMMIT);
  973.  
  974.                /* Save the private control data    pointer    within    */
  975.                /* the controls reserved    memory            */
  976.  
  977.        WinSetWindowPtr(hWnd, QUCWP_WNDP, (PVOID)ppat);
  978.  
  979.                /* Get the control's creation structure address  */
  980.                /* to save the size of the control        */
  981.  
  982.        pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);
  983.  
  984.        ppat->rcl.xLeft    = ppat->rcl.yBottom = 0L;
  985.        ppat->rcl.xRight    = pcrst->cx;
  986.        ppat->rcl.yTop    = pcrst->cy;
  987.        break;
  988.  
  989. /************************************************************************/
  990. /************************************************************************/
  991. /*                                    */
  992. /* Part    2: Control text    and colour support coding            */
  993. /*                                    */
  994. /************************************************************************/
  995. /************************************************************************/
  996.  
  997.    /*********************************************************************/
  998.    /*  Process window parameters query                    */
  999.    /*********************************************************************/
  1000.  
  1001.    case    WM_QUERYWINDOWPARAMS :
  1002.  
  1003.                /* Get the address for the windows parameters    */
  1004.                /* structure                    */
  1005.  
  1006.        pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);
  1007.  
  1008.                /* Determine the    type of    query            */
  1009.  
  1010.        switch (    pwprm->fsStatus    )
  1011.        {
  1012.                /* Query    type:  get text    length            */
  1013.  
  1014.        case    WPM_CCHTEXT :
  1015.  
  1016.                /* Place    the length the string within the    */
  1017.                /* structure                    */
  1018.  
  1019.            pwprm->cchText =    0;
  1020.            break;
  1021.                /* Query    type:  get control data    length        */
  1022.  
  1023.        case    WPM_CBCTLDATA :
  1024.  
  1025.                /* Set the control data length to zero        */
  1026.  
  1027.            pwprm->cbCtlData    = 0;
  1028.            break;
  1029.  
  1030.        default :
  1031.            return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  1032.        }
  1033.        break;
  1034.  
  1035. /************************************************************************/
  1036. /************************************************************************/
  1037. /*                                    */
  1038. /* Part    3: Control size    and position coding                */
  1039. /*                                    */
  1040. /************************************************************************/
  1041. /************************************************************************/
  1042.  
  1043.    /*********************************************************************/
  1044.    /*  Size of the control changing                    */
  1045.    /*********************************************************************/
  1046.  
  1047.    case    WM_SIZE    :
  1048.        ppat = (PPATTERN)WinQueryWindowPtr(hWnd,    QUCWP_WNDP);
  1049.        WinQueryWindowRect(hWnd,    &ppat->rcl);
  1050.        break;
  1051.  
  1052. /************************************************************************/
  1053. /************************************************************************/
  1054. /*                                    */
  1055. /* Part    4: User    interaction coding for keyboard    and mouse        */
  1056. /*                                    */
  1057. /************************************************************************/
  1058. /************************************************************************/
  1059.  
  1060.    /*********************************************************************/
  1061.    /*  Process mouse hit testing                    */
  1062.    /*********************************************************************/
  1063.  
  1064.    case    WM_HITTEST :
  1065.        return(MRFROMLONG(HT_TRANSPARENT));
  1066.  
  1067. /************************************************************************/
  1068. /************************************************************************/
  1069. /*                                    */
  1070. /* Part    5: Control painting and    appearance coding            */
  1071. /*                                    */
  1072. /************************************************************************/
  1073. /************************************************************************/
  1074.  
  1075.    /*********************************************************************/
  1076.    /*  Erase background                            */
  1077.    /*********************************************************************/
  1078.  
  1079.    case    WM_ERASEBACKGROUND :
  1080.  
  1081.                /* Have OS/2 Presentation Manager perform the    */
  1082.                /* background erase on behalf of    the button    */
  1083.  
  1084.        return(MRFROMLONG(TRUE));
  1085.  
  1086.    /*********************************************************************/
  1087.    /*  Paint the button                            */
  1088.    /*********************************************************************/
  1089.  
  1090.    case    WM_PAINT :
  1091.                /* Get the address of the private data from the    */
  1092.                /* control's reserved memory                     */
  1093.  
  1094.        ppat = (PPATTERN)WinQueryWindowPtr(hWnd,    QUCWP_WNDP);
  1095.  
  1096.                /* Get the presentation space for the window    */
  1097.                /* and draw the grid which the buttons are    */
  1098.                /* placed                    */
  1099.  
  1100.        GpiSetPattern(hPS = WinBeginPaint(hWnd, (HPS)NULL, (PRECTL)NULL),
  1101.              (LONG)WinQueryWindowULong(hWnd, QWL_STYLE)    & 0x5f);
  1102.  
  1103.        ptl.x = ptl.y = 0L;
  1104.        GpiMove(hPS, &ptl);
  1105.        ptl.x = ppat->rcl.xRight;
  1106.        ptl.y = ppat->rcl.yTop;
  1107.        GpiBox(hPS, DRO_FILL, &ptl, 0L, 0L);
  1108.  
  1109.                /* Release the presentation space        */
  1110.        WinEndPaint(hPS);
  1111.        break;
  1112.  
  1113. /************************************************************************/
  1114. /************************************************************************/
  1115. /*                                    */
  1116. /* Part    6: Control destruction coding                    */
  1117. /*                                    */
  1118. /************************************************************************/
  1119. /************************************************************************/
  1120.  
  1121.    /*********************************************************************/
  1122.    /*  Window being destroyed, perform clean-up                */
  1123.    /*********************************************************************/
  1124.  
  1125.    case    WM_DESTROY :
  1126.                /* Release the heap allocated for use by    the    */
  1127.                /* control                    */
  1128.  
  1129.        DosFreeMem((PVOID)WinQueryWindowPtr(hWnd, QUCWP_WNDP));
  1130.        break;
  1131.                /* Default message processing            */
  1132.    default :
  1133.        return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  1134.    }
  1135. return(0L);
  1136. }
  1137. #pragma    subtitle("   Custom Controls - 3D Text Window Procedure")
  1138. #pragma    page ( )
  1139.  
  1140. /* --- Text3DWndProc ----------------------------------    [ Private ] ---    */
  1141. /*                                    */
  1142. /*     This function is    used to    handle the messages sent to the        */
  1143. /*     installed control.  The window procedure    is designed to        */
  1144. /*     allow for multiple instances and    to be totally re-entrant.    */
  1145. /*                                    */
  1146. /*     Upon Entry:                            */
  1147. /*                                    */
  1148. /*     HWND   hWnd; = Window Handle                    */
  1149. /*     ULONG  msg;  = PM Message                    */
  1150. /*     MPARAM mp1;  = Message Parameter    1                */
  1151. /*     MPARAM mp2;  = Message Parameter    2                */
  1152. /*                                    */
  1153. /*     Upon Exit:                            */
  1154. /*                                    */
  1155. /*     Text3DWndProc = Message Handling    Result                */
  1156. /*                                    */
  1157. /* --------------------------------------------------------------------    */
  1158.  
  1159. MRESULT    EXPENTRY Text3DWndProc(HWND hWnd, ULONG    msg, MPARAM mp1, MPARAM    mp2)
  1160.  
  1161. {
  1162. HPS           hPS;           /* Presentation Space Handle        */
  1163. LONG           lClr;           /* Presentation Parameter Colour    */
  1164. PCREATESTRUCT  pcrst;           /* Create Structure Pointer        */
  1165. PTEXTFIELD     ptf;           /* Text Field Structure Pointer    */
  1166. RECTL           rcl;           /* Rectangle    Holder            */
  1167. ULONG           ulID;           /* Presentation Parameter ID        */
  1168.  
  1169. switch ( msg )
  1170.    {
  1171.  
  1172. /************************************************************************/
  1173. /************************************************************************/
  1174. /*                                    */
  1175. /* Part    1: Control creation coding                    */
  1176. /*                                    */
  1177. /************************************************************************/
  1178. /************************************************************************/
  1179.  
  1180.    /*********************************************************************/
  1181.    /*  Control creation                            */
  1182.    /*********************************************************************/
  1183.  
  1184.    case    WM_CREATE :
  1185.                /* Allocate memory for the private control data    */
  1186.  
  1187.        DosAllocMem((PVOID)&ptf,    4096UL,    PAG_READ | PAG_WRITE | PAG_COMMIT);
  1188.  
  1189.                /* Save the private control data    pointer    within    */
  1190.                /* the controls reserved    memory            */
  1191.  
  1192.        WinSetWindowPtr(hWnd, QUCWP_WNDP, (PVOID)ptf);
  1193.  
  1194.                /* Get the control's creation structure address  */
  1195.                /* to save the size of the control        */
  1196.  
  1197.        pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);
  1198.  
  1199.        ptf->hwndOwner =    pcrst->hwndOwner;
  1200.        ptf->hwndText  =    WinCreateWindow(hWnd, WC_STATIC, pcrst->pszText,
  1201.                     (pcrst->flStyle    & ~DS_RAISED) |    WS_VISIBLE | SS_TEXT,
  1202.                     0, 0, 0, 0,
  1203.                     hWnd, HWND_BOTTOM, 0x4321,
  1204.                     pcrst->pCtlData, pcrst->pPresParams);
  1205.  
  1206.                /* Set up the colours that will be used within    */
  1207.                /* the painting of the control.    The colour    */
  1208.                /* indices are:                    */
  1209.                /*                        */
  1210.                /* 0 : Foreground (PP_FOREGROUND*)        */
  1211.                /* 1 : Background (PP_BACKGROUND*)        */
  1212.                /* 2 : Hilight Foreground (PP_HILITEFOREGROUND*)    */
  1213.                /* 3 : Hilight Background (PP_HILITEBACKGROUND*)    */
  1214.                /* 4 : Disabled Foreground (PP_DISABLEDFORE*)    */
  1215.                /* 5 : Disabled Foreground (PP_DISABLEDFORE*)    */
  1216.                /* 6 : Border (PP_BORDER*)            */
  1217.  
  1218.        SetDefaultTextColours(hWnd, ptf);
  1219.        WinSetPresParam(ptf->hwndText, PP_FOREGROUNDCOLOR, 4L, (PVOID)ptf->aClr);
  1220.        WinSetPresParam(ptf->hwndText, PP_BACKGROUNDCOLOR, 4L, (PVOID)&ptf->aClr[1]);
  1221.  
  1222.                /* Check    to see if the user provided font that    */
  1223.                /* should override the default font that    would    */
  1224.                /* be set                    */
  1225.  
  1226.        if ( !WinQueryPresParam(hWnd, PP_FONTNAMESIZE, 0L, &ulID, 4L,
  1227.                    (PVOID)&lClr, QPF_NOINHERIT) )
  1228.  
  1229.                /* System indicates not set since not data was    */
  1230.                /* returned, therefore set default font for the    */
  1231.                /* control                    */
  1232.  
  1233.        WinSetPresParam(hWnd, PP_FONTNAMESIZE, 8L, (PVOID)"10.Helv");
  1234.  
  1235.        if ( pcrst->flStyle & DS_RAISED )
  1236.        {
  1237.        ptf->fRaised    = TRUE;
  1238.        ptf->lClrLeftTop    = 0x00ffffff;
  1239.        ptf->lClrBottomRight    = ptf->aClr[6];
  1240.        }
  1241.        else
  1242.        {
  1243.        ptf->fRaised    = FALSE;
  1244.        ptf->lClrLeftTop    = ptf->aClr[6];
  1245.        ptf->lClrBottomRight    = 0x00ffffff;
  1246.        }
  1247.  
  1248.        rcl.xLeft   =\
  1249.        rcl.yBottom = 0L;
  1250.        rcl.xRight  = pcrst->cx;
  1251.        rcl.yTop       = pcrst->cy;
  1252.        CalcTextSize(&rcl, ptf);
  1253.        break;
  1254.  
  1255. /************************************************************************/
  1256. /************************************************************************/
  1257. /*                                    */
  1258. /* Part    2: Control text    and colour support coding            */
  1259. /*                                    */
  1260. /************************************************************************/
  1261. /************************************************************************/
  1262.  
  1263.    /*********************************************************************/
  1264.    /*  Process window parameters query                    */
  1265.    /*********************************************************************/
  1266.  
  1267.    case    WM_QUERYWINDOWPARAMS :
  1268.    case    WM_SETWINDOWPARAMS :
  1269.        ptf = (PTEXTFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  1270.        return(MRFROMLONG(WinSendMsg(ptf->hwndText, msg,    mp1, mp2)));
  1271.  
  1272.    /*********************************************************************/
  1273.    /*  Process window presentation parameters change            */
  1274.    /*********************************************************************/
  1275.  
  1276.    case    WM_PRESPARAMCHANGED :
  1277.        if ( LONGFROMMP(mp1) < PP_FONTNAMESIZE )
  1278.        {
  1279.        ptf = (PTEXTFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  1280.        if (    WinQueryPresParam(hWnd,    LONGFROMMP(mp1),
  1281.                   (LONGFROMMP(mp1) % 2)    ? LONGFROMMP(mp1) + 1L : 0L,
  1282.                   &ulID, 4, (PVOID)&lClr,
  1283.                   QPF_NOINHERIT    | QPF_ID1COLORINDEX | QPF_ID2COLORINDEX) )
  1284.            ptf->aClr[(LONGFROMMP(mp1) - 1L)    / 2L] =    lClr;
  1285.        if (    ptf->fRaised )
  1286.            ptf->lClrBottomRight = ptf->aClr[6];
  1287.        else
  1288.            ptf->lClrLeftTop        = ptf->aClr[6];
  1289.        WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
  1290.        }
  1291.                /* Check    to see if an individual    presentation    */
  1292.                /* parameter has    changed    if so, get the new    */
  1293.                /* colour value for use by the painting routines    */
  1294.  
  1295.        if ( LONGFROMMP(mp1) && (LONGFROMMP(mp1)    < PP_FONTNAMESIZE) )
  1296.        {
  1297.                /* Get the address of the private data from the    */
  1298.                /* control's reserved memory                     */
  1299.  
  1300.        ptf = (PTEXTFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  1301.  
  1302.                /* Get the new presentation parameter colour for    */
  1303.                /* the presentation parameter that has changed.    */
  1304.                /* Get the colour as a RGB value    so as to be    */
  1305.                /* able to get an exact value and not an        */
  1306.                /* approximation    which could happen if the    */
  1307.                /* presentation parameter was set as a RGB but    */
  1308.                /* queried as an    index.    When WinQueryPresParam    */
  1309.                /* returns a 0, it indicates that no        */
  1310.                /* presentation parameter set and the default    */
  1311.                /* colours should be used.            */
  1312.  
  1313.        switch ( LONGFROMMP(mp1) )
  1314.            {
  1315.            case PP_FOREGROUNDCOLOR :
  1316.            case PP_FOREGROUNDCOLORINDEX :
  1317.            ptf->aClr[0]    = lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
  1318.                         PP_FOREGROUNDCOLORINDEX,
  1319.                         SYSCLR_OUTPUTTEXT);
  1320.            WinSetPresParam(ptf->hwndText,
  1321.                    PP_FOREGROUNDCOLOR,
  1322.                    4L, (PVOID)&ptf->aClr[0]);
  1323.            break;
  1324.  
  1325.            case PP_BACKGROUNDCOLOR :
  1326.            case PP_BACKGROUNDCOLORINDEX :
  1327.            ptf->aClr[1]    = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
  1328.                         PP_BACKGROUNDCOLORINDEX,
  1329.                         SYSCLR_BACKGROUND);
  1330.            WinSetPresParam(ptf->hwndText,
  1331.                    PP_BACKGROUNDCOLOR,
  1332.                    4L, (PVOID)&ptf->aClr[1]);
  1333.            break;
  1334.  
  1335.            case PP_HILITEFOREGROUNDCOLOR :
  1336.            case PP_HILITEFOREGROUNDCOLORINDEX :
  1337.            ptf->aClr[2]    = lGetPresParam(hWnd, PP_HILITEFOREGROUNDCOLOR,
  1338.                         PP_HILITEFOREGROUNDCOLORINDEX,
  1339.                         SYSCLR_OUTPUTTEXT);
  1340.            break;
  1341.  
  1342.            case PP_HILITEBACKGROUNDCOLOR :
  1343.            case PP_HILITEBACKGROUNDCOLORINDEX :
  1344.            ptf->aClr[3]    = lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
  1345.                         PP_HILITEBACKGROUNDCOLORINDEX,
  1346.                         SYSCLR_BACKGROUND);
  1347.            break;
  1348.  
  1349.            case PP_DISABLEDFOREGROUNDCOLOR :
  1350.            case PP_DISABLEDFOREGROUNDCOLORINDEX :
  1351.            ptf->aClr[4]    = lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
  1352.                         PP_DISABLEDFOREGROUNDCOLORINDEX,
  1353.                         SYSCLR_OUTPUTTEXT);
  1354.            break;
  1355.  
  1356.            case PP_DISABLEDBACKGROUNDCOLOR :
  1357.            case PP_DISABLEDBACKGROUNDCOLORINDEX :
  1358.            ptf->aClr[5]    = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
  1359.                         PP_BACKGROUNDCOLORINDEX,
  1360.                         SYSCLR_BACKGROUND);
  1361.            break;
  1362.  
  1363.            case PP_BORDERCOLOR :
  1364.            case PP_BORDERCOLORINDEX    :
  1365.            ptf->aClr[6]    = lGetPresParam(hWnd, PP_BORDERCOLOR,
  1366.                         PP_BORDERCOLORINDEX,
  1367.                         SYSCLR_BUTTONDARK);
  1368.            break;
  1369.            }
  1370.        if (    ptf->fRaised )
  1371.            ptf->lClrBottomRight = ptf->aClr[6];
  1372.        else
  1373.            ptf->lClrLeftTop        = ptf->aClr[6];
  1374.  
  1375.                /* Invalidate the button    to force to use    the    */
  1376.                /* new colours just set or removed        */
  1377.  
  1378.        WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
  1379.        }
  1380.        else
  1381.                /* Determine if the Scheme Palette has forced a    */
  1382.                /* global scheme    update in which    case, check all    */
  1383.                /* of the presentation parameters to see    if they    */
  1384.                /* have been added or removed            */
  1385.  
  1386.        if (    LONGFROMMP(mp1)    == 0L )
  1387.  
  1388.                /* Set up the colours that will be used within    */
  1389.                /* the painting of the control.            */
  1390.  
  1391.            SetDefaultTextColours(hWnd,
  1392.                  (PTEXTFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP));
  1393.        break;
  1394.  
  1395. /************************************************************************/
  1396. /************************************************************************/
  1397. /*                                    */
  1398. /* Part    3: Control size    and position coding                */
  1399. /*                                    */
  1400. /************************************************************************/
  1401. /************************************************************************/
  1402.  
  1403.    /*********************************************************************/
  1404.    /*  Size of the control changing                    */
  1405.    /*********************************************************************/
  1406.  
  1407.    case    WM_SIZE    :
  1408.        WinQueryWindowRect(hWnd,    &rcl);
  1409.        CalcTextSize(&rcl,
  1410.             (PTEXTFIELD)WinQueryWindowPtr(hWnd,    QUCWP_WNDP));
  1411.        break;
  1412.  
  1413. /************************************************************************/
  1414. /************************************************************************/
  1415. /*                                    */
  1416. /* Part    4: User    interaction coding for keyboard    and mouse        */
  1417. /*                                    */
  1418. /************************************************************************/
  1419. /************************************************************************/
  1420.  
  1421.    /*********************************************************************/
  1422.    /*  Process control notification                    */
  1423.    /*********************************************************************/
  1424.  
  1425.    case    WM_CONTROL :
  1426.             /* Since the control is    really a composite,    */
  1427.             /* pass    the message to the text    control        */
  1428.  
  1429.        ptf = (PTEXTFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  1430.        return(MRFROMLONG(WinSendMsg(ptf->hwndOwner, msg, mp1, mp2)));
  1431.  
  1432.    /*********************************************************************/
  1433.    /*  Process mouse hit testing                    */
  1434.    /*********************************************************************/
  1435.  
  1436.    case    WM_HITTEST :
  1437.        return(MRFROMLONG(HT_TRANSPARENT));
  1438.  
  1439. /************************************************************************/
  1440. /************************************************************************/
  1441. /*                                    */
  1442. /* Part    5: Control painting and    appearance coding            */
  1443. /*                                    */
  1444. /************************************************************************/
  1445. /************************************************************************/
  1446.  
  1447.    /*********************************************************************/
  1448.    /*  Erase background                            */
  1449.    /*********************************************************************/
  1450.  
  1451.    case    WM_ERASEBACKGROUND :
  1452.  
  1453.                /* Have OS/2 Presentation Manager perform the    */
  1454.                /* background erase on behalf of    the button    */
  1455.  
  1456.        return(MRFROMLONG(TRUE));
  1457.  
  1458.    /*********************************************************************/
  1459.    /*  Paint the button                            */
  1460.    /*********************************************************************/
  1461.  
  1462.    case    WM_PAINT :
  1463.                /* Get the address of the private data from the    */
  1464.                /* control's reserved memory                     */
  1465.  
  1466.        ptf = (PTEXTFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  1467.  
  1468.                /* Get the presentation space for the control    */
  1469.                /* and set the colour table to RGB mode        */
  1470.  
  1471.        GpiCreateLogColorTable(hPS = WinBeginPaint(hWnd,    (HPS)NULL, (PRECTL)NULL),
  1472.                   0L, LCOLF_RGB, 0L, 0L, (PLONG)NULL);
  1473.  
  1474.        GpiSetColor(hPS,    ptf->lClrLeftTop);
  1475.  
  1476.        GpiMove(hPS, ptf->aptl);
  1477.        GpiPolyLine(hPS,    2L, &ptf->aptl[1]);
  1478.  
  1479.        GpiSetColor(hPS,    ptf->lClrBottomRight);
  1480.  
  1481.        GpiMove(hPS, &ptf->aptl[2]);
  1482.        GpiPolyLine(hPS,    2L, &ptf->aptl[3]);
  1483.  
  1484.        WinEndPaint(hPS);
  1485.        break;
  1486.  
  1487. /************************************************************************/
  1488. /************************************************************************/
  1489. /*                                    */
  1490. /* Part    6: Control destruction coding                    */
  1491. /*                                    */
  1492. /************************************************************************/
  1493. /************************************************************************/
  1494.  
  1495.    /*********************************************************************/
  1496.    /*  Window being destroyed, perform clean-up                */
  1497.    /*********************************************************************/
  1498.  
  1499.    case    WM_DESTROY :
  1500.                /* Get the address of the private data from the    */
  1501.                /* control's reserved memory                     */
  1502.  
  1503.        ptf = (PTEXTFIELD)WinQueryWindowPtr(hWnd, QUCWP_WNDP);
  1504.        WinDestroyWindow(ptf->hwndText);
  1505.  
  1506.                /* Release the heap allocated for use by    the    */
  1507.                /* control                    */
  1508.  
  1509.        DosFreeMem((PVOID)ptf);
  1510.        break;
  1511.                /* Default message processing            */
  1512.    default :
  1513.        return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  1514.    }
  1515.  
  1516. return(0L);
  1517. }
  1518.