home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pdlite.zip / PMCX.INF (.txt) < prev    next >
OS/2 Help File  |  1995-07-11  |  62KB  |  2,188 lines

  1.  
  2. ΓòÉΓòÉΓòÉ 1. Trademarks ΓòÉΓòÉΓòÉ
  3.  
  4. The following are trademarks of the Prominare Inc. 
  5.  
  6.       Prominare 
  7.       Prominare Designer 
  8.       PM Control Extension 
  9.       PMCX 
  10.  
  11.  The following are trademarks of the IBM Corporation. 
  12.  
  13.       CUA 
  14.       Common User Access 
  15.       IBM 
  16.       Operating System/2 
  17.       OS/2 
  18.       Presentation Manager 
  19.       Workplace Shell 
  20.  
  21.  
  22. ΓòÉΓòÉΓòÉ 2. Copyright ΓòÉΓòÉΓòÉ
  23.  
  24. Copyright Γòò 1989-1994  Prominare Inc.  All Rights Reserved. 
  25.  
  26.  
  27. ΓòÉΓòÉΓòÉ 3. Introduction ΓòÉΓòÉΓòÉ
  28.  
  29. Prominare Designer's PM Control Extension (PMCX) allows you to design and 
  30. create custom controls, similar to those of OS/2 Presentation Manager, that can 
  31. be accessed from within your applications. 
  32.  
  33. PMCX has been designed so the controls you create can be accessed through 
  34. Prominare Designer. As with normal OS/2 Presentation Manager controls, you can 
  35. view the final control as it would appear in your application. And as with 
  36. Prominare Designer's other controls, you can define a control in terms of its 
  37. style, text, and other related information. 
  38.  
  39. OS/2 Presentation Manager is designed to allow custom or user-defined controls 
  40. to be included within dialogues. PMCX uses this feature to let you create 
  41. controls not found in the default OS/2 Presentation Manager environment. In 
  42. reality, a custom control is similar to any of the windows created for an 
  43. application. 
  44.  
  45. OS/2 Presentation Manager also provides a mechanism for run-time binding of 
  46. libraries--namely, dynamic-link libraries. PMCX uses this mechanism to make the 
  47. custom control accessible to applications including Prominare Designer. 
  48.  
  49.  
  50. ΓòÉΓòÉΓòÉ 4. PMCX Architecture ΓòÉΓòÉΓòÉ
  51.  
  52. The PM Control Extension is based on a simple foundation that allows both your 
  53. application and Prominare Designer to interact with it. With the conventions 
  54. and methodology that follow, you will learn to create PMCX controls. 
  55.  
  56. The architecture of a PMCX control, shown in the following diagram, can be 
  57. described as three publicly defined functions and a window procedure. The three 
  58. functions have to follow the naming and usage conventions of PMCX, whereas the 
  59. window procedure is similar to any other window procedure for a custom control. 
  60.  
  61. PMCX architecture 
  62.  
  63. The first convention deals with naming the control and the functions provided 
  64. in the PMCX control's DLL. For example, the definition of the initialization 
  65. routine is: 
  66.  
  67.       XxxxRegister(HAB hAB); 
  68.  
  69.  Xxxx is the formal name of the control, and also the name of the dynamic-link 
  70.  library. Therefore, for a control called Ruler, the initialization routine 
  71.  would be 
  72.  
  73.       RulerRegister(HAB hAB); 
  74.  and the dynamic-link library name would be 
  75.  
  76.       RULER.DLL 
  77.  
  78.  This convention, the corner-stone for PMCX, allows Prominare Designer to 
  79.  interact properly with the PMCX control DLL. 
  80.  
  81.  PMCX defines three required public functions: 
  82.  
  83.  Function       Purpose 
  84.  XxxxRegister   Controls registration routine. 
  85.  XxxxQuery      Controls information query routine used by Prominare Designer 
  86.                 to determine capabilities of the control. 
  87.  XxxxStyles     Control's styles dialogue procedure, used by Prominare Designer 
  88.                 to allow styles, text, ID symbol and value. When included 
  89.                 within a design, controls specific information to be defined 
  90.                 and edited. 
  91.  
  92.  A PMCX control must also provide certain resources used by Prominare Designer. 
  93.  The first resource is a dialogue template used for the XxxxStyles dialogue. 
  94.  The second resource, although not absolutely required, makes reading resource 
  95.  script files easier, is a set of entries within a string table. These entries 
  96.  correspond to the style flags of the PMCX control and are used by Prominare 
  97.  Designer during resource script generation, allowing the entry for the control 
  98.  to look exactly like a normal PM control. 
  99.  
  100.  
  101. ΓòÉΓòÉΓòÉ 5. How it works ΓòÉΓòÉΓòÉ
  102.  
  103. Given the dual nature of a PMCX control, there is an easy part and a hard part 
  104. to the design process. The easy part is how your application interacts with the 
  105. control. You only need to use the XxxxRegister function in your application to 
  106. register the control with PM; let PM do the rest. If the control is part of a 
  107. dialogue template, PM will create the control as thought it were a normal PM 
  108. control. It is that simple. 
  109.  
  110. The hard part is how the control interacts with Prominare Designer. This is a 
  111. little more complicated, as you have to fill in a structure describing the 
  112. control's capabilities to Prominare Designer, as well as create the styles 
  113. dialogue. 
  114.  
  115. PMCX defines a set of structures that allow the custom control to pass 
  116. information between itself and Prominare Designer. The structures are at all 
  117. times controlled by Prominare Designer, which is responsible for allocating and 
  118. de-allocating necessary memory for the structures. Only through a callback 
  119. routine to Prominare Designer are you allowed to reallocate one area of these 
  120. structures--the area containing the variable sized control data. Some of the 
  121. structures are used only once, whereas others must be used many times, by both 
  122. Prominare Designer and the control. The methods of using the structures within 
  123. the control are defined to allow the control to access and update the elements 
  124. of the structure. The best place to start is with the header that defines the 
  125. structures you will use to interact with Prominare Designer. 
  126.  
  127.  
  128. ΓòÉΓòÉΓòÉ 6. PMCX Definitions Header - PMCX.H ΓòÉΓòÉΓòÉ
  129.  
  130. The PMCX definitions header include file, PMCX.H, is used to define constants, 
  131. structures, and macros, allowing information to be passed between Prominare 
  132. Designer and the custom control. The contents of PMCX.H are shown below. 
  133.  
  134. /* pmcx.h          Created:    1993-12-14  Revised:    1994-09-18       */
  135.  
  136. /* PM Control Extensions (PMCX)                                         */
  137. /* Definitions Header                                                   */
  138.  
  139. /* Consult User's Guide for complete description of PM Control          */
  140. /* Extensions                                                           */
  141.  
  142. /* Copyright Γòò 1989-1994  Prominare Inc.  All Rights Reserved.          */
  143.  
  144. /* -------------------------------------------------------------------- */
  145.  
  146. /* Function Prototypes (32-bit definition)                              */
  147. /* -------------------                                                  */
  148. /*                                                                      */
  149. /*     Control Initialization:                                          */
  150. /*                                                                      */
  151. /*         BOOL EXPENTRY XxxxRegister(HAB hAB);                         */
  152. /*                                                                      */
  153. /*     Styles Dialogue Procedures:                                      */
  154. /*                                                                      */
  155. /*         MRESULT EXPENTRY XxxxStyles(HWND hWnd, ULONG msg,            */
  156. /*                                     MPARAM mp1, MPARAM mp2);         */
  157. /*                                                                      */
  158. /*     Window Procedure:                                                */
  159. /*                                                                      */
  160. /*         MRESULT EXPENTRY XxxxWndProc(HWND hWnd, ULONG msg,           */
  161. /*                                      MPARAM mp1, MPARAM mp2);        */
  162. /*                                                                      */
  163. /*     Control Information Procedure:                                   */
  164. /*                                                                      */
  165. /*         BOOL EXPENTRY XxxxQuery(PUSERINFO pUserInfo);                */
  166.  
  167. /* --- Constant Definitions ------------------------------------------- */
  168.  
  169. #define CTYPES              1      /* Maximum Number of User Types      */
  170. #define CCHCLASS           32      /* Maximum Classname Length          */
  171. #define CCHNAME            32      /* Maximum Name Length               */
  172. #define CCHAUTHOR          64      /* Maximum Author Name Length        */
  173. #define CCHDESC            32      /* Maximum Type Description Length   */
  174. #define CCHID              32      /* Maximum ID Symbol Length          */
  175. #define CCHTEXTMAX        512      /* Maximum Control Text Length       */
  176.  
  177. #define UTYPE_PRIVATE  0x0002      /* Type:  Private                    */
  178. #define UTYPE_PUBLIC   0x0004      /* Type:  Public                     */
  179.  
  180. #define USER_CWINDOWWORDS   8UL    /* Control Reserved Memory Size      */
  181.  
  182. #define QWW_USER  (QWL_USER + 0UL) /* Pointer to User Data              */
  183. #define QWW_CDATA (QWL_USER + 4UL) /* Pointer to Private Data Pointer   */
  184.  
  185. #define CUACHK_MNEMONIC    0       /* CUA Check:  Mnemonic              */
  186. #define CUACHK_CAPS        1       /* CUA Check:  Capitalization        */
  187. #define CUACHK_ELLIPSIS    2       /* CUA Check:  Ellipsis              */
  188.  
  189. #define STYLETYPE_BITFLAGS 0x0001  /* Style Type:  Bit Flags            */
  190. #define STYLETYPE_SEQUENCE 0x0002  /* Style Type:  Sequential           */
  191.  
  192. #define PMCXOPT_NONE      0x00000000UL
  193. #define PMCXOPT_REFRESH   0x00000001UL
  194. #define PMCXOPT_VARICDATA 0x00000002UL
  195. #define PMCXOPT_STYLECHG  0x00000004UL
  196. #define PMCXOPT_TABABLE   0x00000008UL
  197. #define PMCXOPT_HELP      0x00000010UL
  198.  
  199. /************************************************************************/
  200. /************************************************************************/
  201. /*                                                                      */
  202. /*     PMCX 32-Bit Structure Definitions                                */
  203. /*                                                                      */
  204. /************************************************************************/
  205. /************************************************************************/
  206.  
  207. /* --- User Control Styles Structure ---------------------------------- */
  208.  
  209. typedef struct _STYLE              /* st */
  210.    {                               /* Size:    8 bytes                  */
  211.    ULONG    flStyleMask;           /* Style Flag Mask                   */
  212.    ULONG    idStyle;               /* Resource String ID                */
  213.    } STYLE ;
  214.  
  215. /* --- User Control Type Structure ------------------------------------ */
  216.  
  217. typedef struct _USERTYPE           /* ut */
  218.    {                               /* Size:  348 bytes                  */
  219.    LONG     cx;                    /* Suggested Width of Control        */
  220.    LONG     cy;                    /* Suggested Height of Control       */
  221.    ULONG    flStyle;               /* Initial Style Flags               */
  222.    ULONG    flOptions;             /* Options Flag                      */
  223.    ULONG    cMaxText;              /* Maximum Text Required             */
  224.    ULONG    idDlg;                 /* Dialog ID                         */
  225.    ULONG    idReserved;            /* Reserved                          */
  226.    ULONG    flStyleType;           /* Style Type                        */
  227.    ULONG    cCtlData;              /* Control Data Count                */
  228.    ULONG    ulType;                /* Control Type                      */
  229.    ULONG    cMasks;                /* Style Masks Count                 */
  230.    CHAR     szDescription[CCHDESC];/* Control Name                      */
  231.    STYLE    stMasks[32];           /* Style Masks Array                 */
  232.    ULONG    aulReserved[4];        /* Reserved                          */
  233.    } USERTYPE ;
  234.  
  235. /* --- User Control Information Structure ----------------------------- */
  236.  
  237. typedef struct _USERINFO           /* ui */
  238.    {                               /* Size:  512 bytes                  */
  239.    ULONG     ulMajor;              /* Control Version Number:  Major    */
  240.    ULONG     ulMinor;              /* Control Version Number:  Minor    */
  241.    CHAR      szAuthor[CCHAUTHOR];  /* Control Author                    */
  242.    CHAR      szClassname[CCHCLASS];/* Classname                         */
  243.    CHAR      szName[CCHNAME];      /* Library Name                      */
  244.    ULONG     aulReserved[6];       /* Reserved                          */
  245.    ULONG     cTypes;               /* Number of Control Types Supported */
  246.    USERTYPE  utDefined[CTYPES];    /* Define User Types Array           */
  247.    } USERINFO ;
  248.  
  249. typedef USERINFO *PUSERINFO;
  250.  
  251. /* --- User Control Style Structure ----------------------------------- */
  252.  
  253. typedef struct _USERSTYLE          /* ust */
  254.    {                               /* Size:  112 bytes                  */
  255.    PFN      pfnSetSymbolID;        /* Symbol/ID Set Function Address    */
  256.    PFN      pfnGetSymbolID;        /* Symbol/ID Get Function Address    */
  257.    PFN      pfnGetFontClr;         /* Font/Colours Function Address     */
  258.    PFN      pfnCUACheck;           /* CUA Compliance Function Address   */
  259.    PFN      pfnRealloc;            /* Reallocation Function Address     */
  260.    ULONG    flStyle;               /* Style                             */
  261.    ULONG    id;                    /* ID Value                          */
  262.    CHAR     szid[CCHID];           /* ID Symbol                         */
  263.    PSZ      pszText;               /* Text Pointer                      */
  264.    ULONG    cText;                 /* Text Count (Including NULL)       */
  265.    PFN      pfnGetBidi;            /* Bidi Params Function Address      */
  266.    ULONG    aulReserved[8];        /* Reserved                          */
  267.    PBYTE    pbCtlData;             /* Variable Control Data Pointer     */
  268.    ULONG    cbCtlData;             /* Control Data Size                 */
  269.    BYTE     abCtlData[1];          /* Control Data                      */
  270.    } USERSTYLE ;
  271.  
  272. typedef USERSTYLE *PUSERSTYLE;
  273.  
  274. /* --- Macro Helpers for Setting or Retrieving User Style Pointer ------ */
  275.  
  276. #define PDATATODLG(hwndClient) ((WinSetWindowPtr(hwndClient, QWL_USER,\
  277.         (PVOID)mp2)))
  278.  
  279. #define PDATAFROMDLG(hwndClient) (((PUSERSTYLE)WinQueryWindowPtr(hwndClient,\
  280.         QWL_USER)))
  281.  
  282. There are a set of constant definitions, provided in the header, that you can 
  283. use in your implementation of the PMCX control. They are a mixture of limits, 
  284. options, flags, and service requests: 
  285.  
  286.  Constant                 Definition 
  287.  CTYPES                   Defines the maximum length of the class name 
  288.                           definition, including null terminating byte. 
  289.  CCHCLASS                 Defines the maximum length of the class name 
  290.                           definition, including null terminating byte. 
  291.  CCHNAME                  Defines the maximum length of the control's name, 
  292.                           including the null terminating byte. 
  293.  CCHAUTHOR                Defines the maximum length of the author's name for 
  294.                           the control, including null terminating byte. 
  295.  CCHDESC                  Defines the maximum length of the control's 
  296.                           description, including the null terminating byte. 
  297.  CCHID                    Defines the maximum length of the ID symbol, 
  298.                           including the null terminating byte. 
  299.  CCHTEXTMAX               Defines the maximum length of text that can be 
  300.                           defined for the control, including the null 
  301.                           terminating byte. 
  302.  UTYPE_PRIVATE            Defines the control as a private class; it must be 
  303.                           registered specifically by the application before it 
  304.                           is used. This registration is provided the 
  305.                           XxxxRegister function within the DLL. 
  306.  UTYPE_PUBLIC             Defines the control as a public class that has been 
  307.                           registered with OS/2 Presentation Manager and does 
  308.                           not need to be registered by the application. 
  309.  USER_CWINDOWWORDS        Defines the minimum amount of reserved memory that 
  310.                           must be allocated for the control when it is 
  311.                           registered with OS/2 Presentation Manager. Additional 
  312.                           reserved memory can be allocated by adding the value 
  313.                           to the constant in the XxxxRegister function. 
  314.  QWW_USER                 Used as an index into the control's reserved memory, 
  315.                           where the pointer to the user data is located. 
  316.  QWW_CDATA                Used as an index into the control's reserved memory, 
  317.                           where the pointer to the private control data memory 
  318.                           allocated for the control is located. 
  319.  CUACHK_MNEMONIC          Used as an option with the pfnCUACheck function to 
  320.                           check the text of the control for CUA compliance in 
  321.                           terms of mnemonic inclusion. 
  322.  CUACHK_CAPS              Used as an option with the pfnCUACheck function to 
  323.                           check the text of the control for CUA compliance in 
  324.                           terms of capitalization. 
  325.  CUACHK_ELLIPSIS          Used as an option with the pfnCUACheck function to 
  326.                           check the text of the control for CUA compliance in 
  327.                           terms of a space between the text and ellipsis. 
  328.  STYLETYPE_BITFLAGS       Indicates that the style masks are bitflags and that 
  329.                           the style generated in the resource script can be 
  330.                           multiple values when bitwise compared to the style 
  331.                           masks. 
  332.  STYLETYPE_SEQUENCE       Indicates that the style masks are sequential in 
  333.                           nature and that the styles generated within the 
  334.                           resource script should be based on a single value 
  335.                           that must match the style mask. 
  336.  PMCXOPT_NONE             Indicates that no special options are required. 
  337.  PMCXOPT_REFRESH          Indicates that the control should be refreshed 
  338.                           through Prominare Designer, where Prominare Designer 
  339.                           will delete the previous instance of the control and 
  340.                           create a new one to show the revised styles selected. 
  341.  PMCXOPT_VARICDATA        Indicates that the control supports variable length 
  342.                           control data. 
  343.  PMCXOPT_STYLECHG         Indicates that the control supports the changing of 
  344.                           the style flags using the WinSetWindowULong function 
  345.                           and the index of QWL_STYLE. 
  346.  PMCXOPT_TABABLE          Indicates that the control supports tabbing and 
  347.                           cursor movement selections. 
  348.  PMCXOPT_HELP             Indicates that the control allows the help to be 
  349.                           selected when it receives focus. 
  350.  
  351.  Four structures are defined within the header. Three are used to describe the 
  352.  PMCX control to Prominare Designer; the fourth is used by Prominare Designer 
  353.  to communicate with the styles dialogue: 
  354.  
  355.  Name                     Purpose 
  356.  STYLE                    Defines a control style mask and the corresponding 
  357.                           resource file string table ID. Used by the USERTYPE 
  358.                           structure. 
  359.  USERTYPE                 Defines the user control type. The information within 
  360.                           the structure is for the default characteristics of 
  361.                           the control, the ID of the dialogue template within 
  362.                           the control's DLL for the styles dialogue, the room 
  363.                           necessary for additional control data (i.e. picture 
  364.                           masks, ranges, limits, etc.), control type, styles 
  365.                           count, and style masks. Used by the USERINFO 
  366.                           structure. 
  367.  USERINFO                 Defines information for the control initially queried 
  368.                           by Prominare Designer to determine the capabilities 
  369.                           of the control. The control's version number, author, 
  370.                           class, and types are defined. Used only by the 
  371.                           XxxxQuery function. 
  372.  USERSTYLE                Used by Prominare Designer and the XxxxStyles 
  373.                           functions to allow a method of communication 
  374.                           regarding data information entered or edited through 
  375.                           the dialogue procedure. The structure provides helper 
  376.                           function addresses that can be used to reference the 
  377.                           control's style, ID symbol and value, and text, and 
  378.                           to control specific data. 
  379.  
  380.  The STYLE structure is defined as: 
  381.  
  382.  Field                    Purpose 
  383.  flStyleMask              Contains a style flag mask for a possible style of 
  384.                           the control. Should be in the form of 0x0000UL. The 
  385.                           style mask must correspond with a resource string 
  386.                           indicated in the idStyle field. 
  387.  idStyle                  Contains the ID of the resource string for the 
  388.                           corresponding style mask in the flStyleMask field. 
  389.  
  390.  The following is an example of how the structure is used: 
  391.  
  392.   /* Constants definitions within an include header file */
  393.  
  394.   #define EC_NORMALBORDER  0x0001L
  395.   #define EC_THICKBORDER   0x0002L
  396.   #define EC_NOBORDER      0x0004L
  397.  
  398.   #define IDS_NORMALBORDER 800
  399.   #define IDS_THICKBORDER  801
  400.   #define IDS_NOBORDER     802
  401.  
  402.   /* Within source code file */
  403.   USERTYPE utExample;
  404.  
  405.   utExample.flStyleType         = STYLETYPE_BITFLAGS;
  406.   utExample.stMasks[0].flStyleMask   = EC_NORMALBORDER;
  407.   utExample.stMasks[0].idStyle       = IDS_NORMALBORDER;
  408.   utExample.stMasks[1].flStyleMask   = EC_THICKBORDER;
  409.   utExample.stMasks[1].idStyle       = IDS_THICKBORDER;
  410.   utExample.stMasks[2].flStyleMask   = EC_NOBORDER;
  411.   utExample.stMasks[2].idStyle       = IDS_NOBORDER;
  412.  
  413.   /* Within resource script file */
  414.  
  415.   STRINGTABLE
  416.   BEGIN
  417.        IDS_NORMALBORDER,   "EC_NORMALBORDER"
  418.        IDS_THICKBORDER,    "EC_THICKBORDER"
  419.        IDS_NOBORDER,       "EC_NOBORDER"
  420.   END
  421.  
  422.  The USERTYPE structure is defined as: 
  423.  
  424.  Field                    Purpose 
  425.  cx                       Contains the suggested width of the control in 
  426.                           dialogue units. This value will be used by Prominare 
  427.                           Designer as the initial width of the control when it 
  428.                           is added to a window or dialogue. 
  429.  cy                       Contains the suggested height of the control in 
  430.                           dialogue units. This value will be used by Prominare 
  431.                           Designer as the initial height of the control when it 
  432.                           is added to a window or dialogue. 
  433.  flStyle                  Contains initial style flags of the control when it 
  434.                           is created by Prominare Designer. 
  435.  flOptions                Contains the options flag, which can be one of the 
  436.                           PMCXOPT_* flags. 
  437.  cMaxText                 Contains the maximum number of characters that the 
  438.                           control is capable of handling. This value is used by 
  439.                           Prominare Designer to allocate space for the control 
  440.                           text addressed in the pszText field in the USERSTYLE 
  441.                           structure. 
  442.  idDlg                    Contains the resource ID of the styles dialogue 
  443.                           displayed by Prominare Designer when the control is 
  444.                           first added to a window or dialogue or when the user 
  445.                           requests to edit the styles of the control. 
  446.  idReserved               Reserved. 
  447.  flStyleType              Contains the style type flag that indicates to 
  448.                           Prominare Designer how the style masks should be 
  449.                           interpreted when the resource script statement for 
  450.                           the control is generated. The current style types 
  451.                           defined are STYLETYPE_BITFLAGS for bitflag styles and 
  452.                           STYLETYPE_SEQUENCE for sequential styles. 
  453.  cCtlData                 Contains the number of bytes that should be allocated 
  454.                           for private data used by the control. This data is 
  455.                           allocated by Prominare Designer and is addressed in 
  456.                           the abCtlData field in the USER_STYLE structure. 
  457.  ulType                   Contains the control type, which may be either 
  458.                           UTYPE_PRIVATE or UTYPE_PUBLIC. 
  459.  cMasks                   Contains the total count of style masks defined in 
  460.                           stMasks field. 
  461.  szDescription[CCHDESC]   Contains a short description that can be displayed by 
  462.                           Prominare Designer. 
  463.  stMasks[32]              Contains the control style flag masks and ID string 
  464.                           values. 
  465.  aulReserved[4]           Reserved. 
  466.  
  467.  The following is an example of how the structure is used: 
  468.  
  469.   USERTYPE utDefined;
  470.  
  471.   utDefined.cx           = 50L;
  472.   utDefined.cy           = 12L;
  473.   utDefined.flStyle      = 0UL;
  474.   utDefined.idDlg        = Dialogue id;
  475.   utDefined.ulType       = UTYPE_PRIVATE;
  476.   utDefined.cCtlData     = 20UL;
  477.   utDefined.cMasks       = 2UL;
  478.   utDefined.cMaxText     = 5UL;
  479.   utdefined.flStyleType  = STYLETYPE_BITFLAGS;
  480.   utDefined.stMasks[0].flStyleMask = 0x0001UL;
  481.   utDefined.stMasks[0].idStyle     = String id;
  482.   utDefined.stMasks[1].flStyleMask = 0x0002UL;
  483.   utDefined.stMasks[1].idStyle     = String id;
  484.   strcpy(utDefined.szDescription, "Description");
  485.  
  486.  The USERINFO structure is defined as: 
  487.  
  488.  Field                    Purpose 
  489.  ulMajor                  Contains the control's major version number. 
  490.  ulMinor                  Contains the control's minor version number. 
  491.  szAuthor[CCHAUTHOR]      Contains the control's author name. 
  492.  szClassname[CCHCLASS]    Contains the classname of the control. 
  493.  szName[CCHNAME]          Contains the common name for the control. This name 
  494.                           should correspond to the Xxxx component of the 
  495.                           required functions as well as to the dynamic-link 
  496.                           library name. 
  497.  aulReserved[6]           Reserved. 
  498.  cTypes                   Contains the number of types supported by the 
  499.                           control. In Version 1.0 of PMCX, only one type is 
  500.                           allowed and this field must be 1. 
  501.  utDefined[CTYPES]        Contains the type information of each of the controls 
  502.                           supported by the control. In Version 1.0 of PMCX, 
  503.                           only the first array element is used. 
  504.  
  505.  The following is an example of how the structure is used: 
  506.  
  507.   USERINFO uiControl;
  508.  
  509.   uiControl.ulMajor = 1UL;
  510.   uiControl.ulMinor = 0UL;
  511.   uiControl.cTypes = 1UL;
  512.   strcpy(uiControl.szAuthor, "Author");
  513.   strcpy(uiControl.szClassname, "Classname");
  514.   strcpy(uiControl.szName, "Common Name");
  515.   uiControl.utDefined[0].cx           = 50L;
  516.   uiControl.utDefined[0].cy           = 12L;
  517.   uiControl.utDefined[0].flStyle      = 0UL;
  518.   uiControl.utDefined[0].idDlg        = Dialogue id;
  519.   uiControl.utDefined[0].ulType       = UTYPE_PRIVATE;
  520.   uiControl.utDefined[0].cCtlData     = 20UL;
  521.   uiControl.utDefined[0].cMasks       = 2UL;
  522.   uiControl.utDefined[0].cMaxText     = 5UL;
  523.   uiControl.utDefined[0].flStyleType  = STYLETYPE_BITFLAGS;
  524.   uiControl.utDefined[0].stMasks[0].flStyleMask = 0x0001UL;
  525.   uiControl.utDefined[0].stMasks[0].idStyle     = String id;
  526.   uiControl.utDefined[0].stMasks[1].flStyleMask = 0x0002UL;
  527.   uiControl.utDefined[0].stMasks[1].idStyle     = String id;
  528.   strcpy(uiControl.utDefined[0].szDescription, "Description");
  529.  
  530.  The USERSTYLE structure is defined as: 
  531.  
  532.  Field                    Purpose 
  533.  pfnSetSymbol             Contains the function address for the function in 
  534.                           Prominare Designer that sets the ID field symbol and 
  535.                           value. 
  536.  pfnGetSymbol             Contains the function address for the function in 
  537.                           Prominare Designer that causes the ID field symbol 
  538.                           and value to be validated and placed within the 
  539.                           USERSTYLE structure. 
  540.  pfnGetFontClr            Contains the function address for the Font & Colours 
  541.                           dialogue. Prominare Designer internally records the 
  542.                           font and colours selected by the user on behalf of 
  543.                           the control. 
  544.  pfnCUACheck              Contains the function address for the CUA Compliance 
  545.                           checking function. Compliance for mnemonics, 
  546.                           capitalization, and ellipsis can be checked via this 
  547.                           function if the control supports any of these 
  548.                           features. A value of TRUE is returned if 
  549.                           non-compliance is determined. A value of FALSE is 
  550.                           returned if the control is compliant. 
  551.  pfnRealloc               Contains the function address for the control data 
  552.                           reallocation function, which allows the control to 
  553.                           reallocate the necessary control data memory when it 
  554.                           supports variable control data. 
  555.  flStyle                  Contains the current style flags set for the control. 
  556.  id                       Contains the current ID value for the control. 
  557.  szid[CCHID]              Contains the current ID symbol for the control. 
  558.  pszText                  Contains the address of the text for the control. 
  559.  cText                    Contains the count of characters for the control. 
  560.  pfnGetBidi               Contains the function address for the Bidirectional 
  561.                           Support dialogue. Prominare Designer internally 
  562.                           records the bidirectional options selected by the 
  563.                           user on behalf of the control. 
  564.  aulReserved[8]           Reserved. 
  565.  pbCtlData                Contains the variable control data buffer pointer. 
  566.                           Used only when the control supports variable control 
  567.                           data; used in place of the abCtlData field. 
  568.  cbCtlData                Contains the size of the control data buffer 
  569.                           pbCtlData when the control supports variable control 
  570.                           data. 
  571.  abCtlData[1]             First element of the private control data. When 
  572.                           control data is used, the control should cast the 
  573.                           appropriate structure to the address of the array, so 
  574.                           it can easily address areas of the data. 
  575.  
  576.  Two helper macros are defined in the header: 
  577.  
  578.  Macro                    Purpose 
  579.  PDATATODLG               Places the passed address of the USERSTYLE pointer in 
  580.                           the dialogue's reserved memory. The passed address is 
  581.                           contained within the second message parameters 
  582.                           (MPARAM mp2) and must be placed in the dialogue's 
  583.                           reserved memory when it receives the WM_INITDLG 
  584.                           message. 
  585.  PDATAFROMDLG             References the memory location in the dialogue 
  586.                           procedure where the USERSTYLE pointer passed to the 
  587.                           dialogue is placed. A pointer returned by the macro 
  588.                           allows reference to the elements of the USERSTYLE 
  589.                           structure. 
  590.  
  591.  
  592. ΓòÉΓòÉΓòÉ 7. PMCX construction ΓòÉΓòÉΓòÉ
  593.  
  594. The first item of concern is the naming convention. The best way to illustrate 
  595. this is by considering the example below: 
  596.  
  597. Functions 
  598.  
  599.       XxxxRegister 
  600.  
  601.       XxxxQuery 
  602.  
  603.       XxxxStyles 
  604.  
  605.  Dynamic-Link Library 
  606.  
  607.       Xxxx.DLL 
  608.  
  609.  Xxxx is the common name for the control. (The common name should be restricted 
  610.  to eight letters to allow for FAT disk systems unless it is to be used 
  611.  specifically with HPFS disk systems.) The common name is allowed to be a 
  612.  maximum of 32 bytes long, including the NULL terminating character; the szName 
  613.  field of the USERINFO structure will accept only that number of characters. 
  614.  
  615.  The second item of concern is who is responsible for allocating and 
  616.  de-allocating memory for the structures. Prominare Designer allocates and 
  617.  de-allocates the necessary memory for structures used to communicate with the 
  618.  PMCX control. It provides a pointer to the memory address of the structure and 
  619.  to the function when communication is required. It is the responsibility of 
  620.  the PMCX control's style function to save the address of the structure. Any 
  621.  pointers to memory elements within the structures are also allocated and 
  622.  deallocated by Prominare Designer on behalf of the control. 
  623.  
  624.  The only exception is in the case of a control that allows for variable length 
  625.  control data. In this case, the control can, through a callback function to 
  626.  Prominare Designer, reallocate the control data memory. 
  627.  
  628.  Since the PMCX control's dialogue procedure is responsible for saving the 
  629.  address of the USERSTYLE structure address passed to it by Prominare Designer, 
  630.  you can use the two helper macros defined by the styles dialogue procedure to 
  631.  save and retrieve the address. To save the USERSTYLE structure address in the 
  632.  QWL_USER reserved memory location of the dialogue's reserved memory, use the 
  633.  PDATATODLG macro. To retrieve the USERSTYLE structure address, use 
  634.  PDATAFROMDLG macro. 
  635.  
  636.  To ensure  the success of any PMCX control, you must encapsulate its use to 
  637.  permit multiple usage, which means that the control must be totally 
  638.  re-entrant.  One way to do this is with dynamically allocated memory. Save 
  639.  this memory address within the control's reserved memory. These addresses can 
  640.  be referenced with the QWW_* indices. Prominare Designer provides a set of 
  641.  helper functions for the control's style dialogue, which ensure that the 
  642.  dialogue remains consistent with similar dialogues provided with Prominare 
  643.  Designer. These helper functions must give the control's dialogue access to 
  644.  the ID field, the Font & Colours dialogue, symbol verification, and CUA 
  645.  compliance. Prominare Designer must provide the addresses of these routines 
  646.  within the USERSTYLE structure in the following elements: 
  647.  
  648.  Callback                 Purpose 
  649.  pfnSetSymbol             ID field symbol and value set helper function 
  650.  pfnGetSymbol             Symbol ID and value validation and retrieval helper 
  651.                           function 
  652.  pfnGetFontClr            Font and colours helper function 
  653.  pfnCUACheck              CUA Compliance helper function 
  654.  pfnRealloc               Memory reallocation function similar to C library 
  655.                           function realloc( ) 
  656.  
  657.  Prominare Designer constructs the necessary statements in the resource script 
  658.  on behalf of the PMCX control. In turn, the control must provide style masks 
  659.  and a string table containing the ASCII style definitions in its resources, if 
  660.  styles are permitted for the control. The style masks and ID values for the 
  661.  string that corresponds to the style masks are to be placed in the provided 
  662.  structure elements of the USERINFO structure, along with the count of masks. 
  663.  The control must also provide the number of control data bytes it requires 
  664.  through the USERINFO structure. This structure must be completed in the 
  665.  function XxxxQuery, through the structure address passed to the function when 
  666.  it is called by Prominare Designer. 
  667.  
  668.  The functions defined for the control must be exported in the controls 
  669.  definition file. The name of the function should be entered along with an 
  670.  ordinal value. The following ordinals are required: 
  671.  
  672.  Function                 Ordinal 
  673.  XxxxRegister             1 
  674.  XxxxQuery                2 
  675.  XxxxStyles               3 
  676.  
  677.  The following describes the use of each of the required functions of the PMCX 
  678.  control. 
  679.  
  680.  
  681. ΓòÉΓòÉΓòÉ 7.1. XxxxRegister ΓòÉΓòÉΓòÉ
  682.  
  683.  
  684. ΓòÉΓòÉΓòÉ 7.1.1. Purpose ΓòÉΓòÉΓòÉ
  685.  
  686. The XxxxRegister function is used to register a private control with OS/2 
  687. Presentation Manager. It is also used to provide any control specific 
  688. initialization. 
  689.  
  690.  
  691. ΓòÉΓòÉΓòÉ 7.1.2. Prototype Definition ΓòÉΓòÉΓòÉ
  692.  
  693. BOOL EXPENTRY XxxxRegister(HAB hAB); 
  694.  
  695.  
  696. ΓòÉΓòÉΓòÉ 7.1.3. Upon entry ΓòÉΓòÉΓòÉ
  697.  
  698. hAB contains the calling application's anchor block handle. When the control is 
  699. a UTYPE_PRIVATE, the function must register the control with OS/2 Presentation 
  700. Manager using the WinRegisterClass function, as follows: 
  701.  
  702. WinRegisterClass(hAB, pszClassname, XxxxWndProc,
  703.                  CS_CLIPSIBLINGS | CS_SYNCPAINT | CS_SIZEREDRAW,
  704.                  USER_CWINDOWWORDS);
  705.  
  706. Additional memory can be reserved for the control by adding the required value 
  707. to the USER_CWINDOWWORDS constant. Additional class styles can also be defined 
  708. for the control. The pszClassname must contain the classname of the control and 
  709. be consistent with the value placed in the USERINFO structure element 
  710. szClassname in the XxxxQuery function.  The control can use other style flags 
  711. as is appropriate. 
  712.  
  713.  
  714. ΓòÉΓòÉΓòÉ 7.1.4. Upon exit ΓòÉΓòÉΓòÉ
  715.  
  716. XxxxRegister must return a value of TRUE, denoting successful registration of 
  717. the control with OS/2 Presentation Manager. A returned value of FALSE indicates 
  718. that the control could not be registered and therefore should not be used. 
  719.  
  720.  
  721. ΓòÉΓòÉΓòÉ 7.2. XxxxQuery ΓòÉΓòÉΓòÉ
  722.  
  723.  
  724. ΓòÉΓòÉΓòÉ 7.2.1. Purpose ΓòÉΓòÉΓòÉ
  725.  
  726. The XxxxQuery function is called by Prominare Designer to determine the 
  727. capabilities of the control and to receive information critical to its 
  728. successful use within Prominare Designer. The USERINFO structure is completed 
  729. through this function, in which Prominare Designer passes the function the 
  730. address of the structure. 
  731.  
  732.  
  733. ΓòÉΓòÉΓòÉ 7.2.2. Prototype Definition ΓòÉΓòÉΓòÉ
  734.  
  735. BOOL EXPENTRY XxxxQuery (PUSERINFO pUserInfo); 
  736.  
  737.  
  738. ΓòÉΓòÉΓòÉ 7.2.3. Upon entry ΓòÉΓòÉΓòÉ
  739.  
  740. pUserInfo contains the address of the USERINFO structure allocated within 
  741. Prominare Designer in which the XxxxQuery function can complete. The 
  742. information placed within the structure is done as follows: 
  743.  
  744. pUserInfo->ulMajor = 1UL;
  745. pUserInfo->ulMinor = 0UL;
  746. pUserInfo->cTypes = 1UL;
  747. strcpy(pUserInfo->szAuthor, "Author");
  748. strcpy(pUserInfo->szClassname, "Classname");
  749. strcpy(pUserInfo->szName, "Common Name");
  750. pUserInfo->utDefined[0].cx           = 50L;
  751. pUserInfo->utDefined[0].cy           = 12L;
  752. pUserInfo->utDefined[0].flStyle      = 0UL;
  753. pUserInfo->utDefined[0].idDlg        = Dialogue id;
  754. pUserInfo->utDefined[0].ulType       = UTYPE_PRIVATE;
  755. pUserInfo->utDefined[0].cCtlData     = 20UL;
  756. pUserInfo->utDefined[0].cMasks       = 2UL;
  757. pUserInfo->utDefined[0].cMaxText     = 5UL;
  758. pUserInfo->utDefined[0].flStyleType  = STYLETYPE_BITFLAGS;
  759. pUserInfo->utDefined[0].stMasks[0].flStyleMask = 0x0001UL;
  760. pUserInfo->utDefined[0].stMasks[0].idStyle     = String id;
  761. pUserInfo->utDefined[0].stMasks[1].flStyleMask = 0x0002UL;
  762. pUserInfo->utDefined[0].stMasks[1].idStyle     = String id;
  763. strcpy(pUserInfo->utDefined[0].szDescription, "Description");
  764.  
  765.  
  766. ΓòÉΓòÉΓòÉ 7.2.4. Upon exit ΓòÉΓòÉΓòÉ
  767.  
  768. XxxxQuery must return a value of TRUE, denoting successful completion of the 
  769. structure. A returned value of FALSE indicates that the structure was not 
  770. completed and the control therefore should not be used. 
  771.  
  772.  
  773. ΓòÉΓòÉΓòÉ 7.3. XxxxStyles ΓòÉΓòÉΓòÉ
  774.  
  775.  
  776. ΓòÉΓòÉΓòÉ 7.3.1. Purpose ΓòÉΓòÉΓòÉ
  777.  
  778. The XxxxStyles function is the PMCX control's style dialogue used through 
  779. Prominare Designer. 
  780.  
  781.  
  782. ΓòÉΓòÉΓòÉ 7.3.2. Prototype Definition ΓòÉΓòÉΓòÉ
  783.  
  784. MRESULT EXPENTRY XxxxStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2); 
  785.  
  786.  
  787. ΓòÉΓòÉΓòÉ 7.3.3. Upon entry ΓòÉΓòÉΓòÉ
  788.  
  789. Normal dialogue procedure coding except as noted in Special Considerations. 
  790. below. 
  791.  
  792.  
  793. ΓòÉΓòÉΓòÉ 7.3.4. Upon exit ΓòÉΓòÉΓòÉ
  794.  
  795. XxxxStyles should return values consistent with normal dialogue procedures. 
  796.  
  797.  
  798. ΓòÉΓòÉΓòÉ 7.3.5. Special considerations ΓòÉΓòÉΓòÉ
  799.  
  800. During the processing of the WM_INITDLG message, the control should reference 
  801. message parameter 2 (MPARAM mp2) as follows: PDATATODLG(hWnd); 
  802.  
  803. This causes the address of the USERSTYLE structure allocated within Prominare 
  804. Designer to be saved in the dialogue's reserved memory. The dialogue can then 
  805. reference the information in the USERSTYLE structure with the following method: 
  806.  
  807. pust = PDATAFROMDLG(hWnd);
  808.  
  809. Also, the entry fields for the dialogue along with any styles should be 
  810. completed during processing of the WM_INITDLG message. For example, with a 
  811. control that supported text, the following could be used to fill in the Text 
  812. and ID fields: 
  813.  
  814. if ( (pust = (PUSERSTYLE)mp2) != NULL )
  815.      {
  816.      WinSetDlgItemText(hWnd, ID_TEXT, pust->szText);
  817.      pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust);
  818.      }
  819.  
  820. When the dialogue is dismissed, the function must return either TRUE through 
  821. the WinDismissDlg function, to indicate to Prominare Designer changes have been 
  822. made to the USERSTYLE structure, or FALSE, to indicate that no changes were 
  823. made. 
  824.  
  825. The USERSTYLE structure contains the addresses of the five Prominare Designer 
  826. helper routines, defined as follows: 
  827.  
  828.       VOID (EXPENTRY *pfnSetSymbolID)(HWND hWnd, ULONG idSymbol, PUSERSTYLE 
  829.       pust); 
  830.  
  831.       BOOL (EXPENTRY *pfnGetSymbolID)(HWND hWnd, ULONG idSymbol, PUSERSTYLE 
  832.       pust); 
  833.  
  834.       VOID (EXPENTRY *pfnGetFontClr)(HWND hWnd); 
  835.  
  836.       BOOL (EXPENTRY *pfnCUACheck)(HWND hWnd, ULONG idEntryField, LONG 
  837.       iCUACompliance); 
  838.  
  839.       BOOL (EXPENTRY *pfnRealloc)(PVOID pv, INT cSize); 
  840.  
  841.  In this case, you would use the pfnSetSymbol in conjunction with the ID field. 
  842.  The function is used to set the symbol and value of the control within the ID 
  843.  field, as shown here: 
  844.  
  845.   if ( (pust = (PUSERSTYLE)mp2) != NULL )
  846.        pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust);
  847.  
  848.  The pfnGetFontClr function allows the user to display the Font & Colours 
  849.  dialogue when he or she clicks on the Font & colours... button. The function 
  850.  allows the user to set the font and colours for the control, as shown here: 
  851.  
  852.   case WM_COMMAND :
  853.        switch ( SHORT1FROMMP(mp1) )
  854.             {
  855.             case ID_FONTCLR :
  856.                  if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  857.                       pust->pfnGetFontClr(hWnd);
  858.                  break;
  859.             .
  860.             .
  861.             .
  862.             }
  863.        break;
  864.  
  865.  The pfnGetBidi function allows the user to display the Bidirectional Support 
  866.  dialogue when he or she clicks on the Bidi... button. The function allows the 
  867.  user to set the bidirectional options as shown here: 
  868.  
  869.   case WM_COMMAND :
  870.        switch ( SHORT1FROMMP(mp1) )
  871.             {
  872.             case ID_BIDI :
  873.                  if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  874.                       pust->pfnGetBidi(hWnd);
  875.                  break;
  876.             .
  877.             .
  878.             .
  879.             }
  880.        break;
  881.  
  882.  Use the pfnGetSymbol function when the user tells the dialogue to accept the 
  883.  changes made. The function checks the values in the ID field for validity and 
  884.  displays any required error message boxes. If the function returns a value of 
  885.  FALSE, the dialogue procedure should not retrieve any changes made but should 
  886.  simply break the current processing, allowing the user to correct values 
  887.  within the dialogue as he or she sees fit. A return value of TRUE indicates 
  888.  that the dialogue should retrieve all changes made and save them in the 
  889.  USERSTYLE structure before dismissing the dialogue. The function also 
  890.  retrieves the ID symbol and value and places them in the USERSTYLE structure, 
  891.  as shown here: 
  892.  
  893.   case WM_COMMAND :
  894.        switch ( SHORT1FROMMP(mp1) )
  895.             {
  896.             case DID_OK :
  897.                  if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  898.                       if ( !pust->pfnGetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust) )
  899.                            {
  900.                            .
  901.                            .    /* Continue processing */
  902.                            .
  903.                            WinDismissDlg(hWnd, TRUE);
  904.                            }
  905.                  break;
  906.             .
  907.             .
  908.             .
  909.             }
  910.        break;
  911.  
  912.  Use the pfnCUACheck function when the user tells the dialogue to accept the 
  913.  changes made. Depending on the option selected, the function checks the values 
  914.  in the Text entry field for CUA compliance and displays any required error 
  915.  message boxes. If the function returns a value of FALSE, the dialogue 
  916.  procedure should not retrieve any changes made but should simply break the 
  917.  current processing, allowing the user to correct values in the dialogue as he 
  918.  or she sees fit. A return value of TRUE indicates that the dialogue should 
  919.  retrieve all changes made, saving them in the USERSTYLE structure before 
  920.  dismissing the , as shown here: 
  921.  
  922.   case WM_COMMAND :
  923.        switch ( SHORT1FROMMP(mp1) )
  924.             {
  925.             case DID_OK :
  926.                  if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  927.                       if ( pust->pfnCUACheck(hWnd, ID_TEXT, CUACHK_CAPS) )
  928.                            break;
  929.                       else
  930.                            {
  931.                            .    /* Continue processing */
  932.                            .
  933.                            .
  934.                            WinDismissDlg(hWnd, TRUE);
  935.                            }
  936.                  break;
  937.             .
  938.             .
  939.             }
  940.        break;
  941.  
  942.  Finally, use the pfnRealloc function when the control allows variable-length 
  943.  control data and the user has indicated a wish to save the information for the 
  944.  control. You must use the function to reallocate the data buffer for the 
  945.  control data, since Prominare Designer controls memory allocation for the 
  946.  structures. The function utilizes the memory management routines of Prominare 
  947.  Designer; care must therefore be exercised so the function is not misused. 
  948.  Otherwise, Prominare Designer may develop a fatal unrecoverable error 
  949.  condition. The function is exactly like the C library realloc( ) function in 
  950.  usage. It is shown here: 
  951.  
  952.   case WM_COMMAND :
  953.        switch ( SHORT1FROMMP(mp1) )
  954.             {
  955.             case DID_OK :
  956.                  if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  957.                       {
  958.                       if ( !(pust->pbCtlData =
  959.                            (PBYTE)pust->pfnRealloc(pust->pbCtlData,
  960.                                                sizeof(COMBOBOXCDATA) - 1L)) )
  961.                            {
  962.                            WinMessageBox(HWND_DESKTOP, hWnd,
  963.                                           "Memory error on reallocating control data!",
  964.                                           "Super Combo Box Control", 0,
  965.                                           MB_OK | MB_ICONEXCLAMATION);
  966.                            return(0L);
  967.                            }
  968.  
  969.                       pust->cbCtlData = sizeof(COMBOBOXCDATA) - 1 + n;
  970.  
  971.                       pcbd = (PCOMBOBOXCDATA)pust->pbCtlData;
  972.                       pcbd->cb = sizeof(COMBOBOXCDATA) - 1 + n;
  973.                       pcbd->cItems = cItems;
  974.                       memcpy(pcbd->abList, pchData, n);
  975.                       }
  976.                  break;
  977.             .
  978.             .
  979.             }
  980.        break;
  981.  
  982.  
  983. ΓòÉΓòÉΓòÉ 8. DLL construction ΓòÉΓòÉΓòÉ
  984.  
  985. To correctly construct a custom control according to the PMCX, use the 
  986. following outline: 
  987.  
  988.  File                     Contents 
  989.  PMCX.H                   PMCX constants, macros, and structure definitions. 
  990.                           This file is provided with the Prominare Designer 
  991.                           package and can be found in the PD\Include 
  992.                           sub-directory. 
  993.  Xxxx.Lnk                 Contains the link response file needed by the linker. 
  994.  Xxxx.C                   Contains source code for the custom code using PMCX. 
  995.  Xxxx.Def                 Contains the definition statements required by the 
  996.                           linker to construct the final dynamic link library. 
  997.  Xxxx.Mak                 Contains the MAKE file necessary to create the object 
  998.                           and resource files. 
  999.  Xxxx.Rc                  Contains the resource script file with the control's 
  1000.                           style dialogue template and styles string table. 
  1001.  
  1002.  
  1003. ΓòÉΓòÉΓòÉ 9. Example control ΓòÉΓòÉΓòÉ
  1004.  
  1005. Following are listings of an example control provided with the Prominare 
  1006. Designer package. It is shown here to help you understand the construction of a 
  1007. PMCX control. A check mark control that allows the usage of a static control to 
  1008. denote if an option is selected or available, it is similar to a check box 
  1009. control except that the user does not interact with it. The final check mark 
  1010. styles dialogue is shown here: 
  1011.  
  1012. PMCX control Check Mark Styles dialogue 
  1013.  
  1014. The check mark control created and managed by the PMCX control DLL appears as: 
  1015.  
  1016. Check mark control appearance 
  1017.  
  1018. The following example control code shows the necessary methods defined by PMCX 
  1019. to successfully create a custom control that can be used within your own 
  1020. applications and Prominare Designer. 
  1021.  
  1022. #pragma title("Check Mark Control  --  Version 1.00 -- (ChkMark.C)")
  1023. #pragma subtitle("  Check Mark Control Control DLL - Interface Definitions")
  1024.  
  1025. #pragma info(noext)
  1026.  
  1027. #define INCL_GPI                   /* Include OS/2 PM GPI Interface     */
  1028. #define INCL_WIN                   /* Include OS/2 PM Windows Interface */
  1029.  
  1030. static char *MODID = "@(#)chkmark.c:1.02";
  1031.  
  1032. #include <os2.h>
  1033. #include <string.h>
  1034.  
  1035. #include <pmcx.h>
  1036.  
  1037. #include "chkmark.h"
  1038.  
  1039. /* This module contains an example installable control that can be used */
  1040. /* within applications where additional facilities are provided that    */
  1041. /* are not found within the default controls of OS/2 PM.                */
  1042. /*                                                                      */
  1043. /* For complete details regarding the PM Control Extensions (PMCX)      */
  1044. /* consult the User's Guide.                                            */
  1045. /*                                                                      */
  1046. /* The DLL is created using the following command line invocation:      */
  1047. /*                                                                      */
  1048. /*     Icc -G3e- -O+ -Rn -W3 -C ChkMark.C                               */
  1049.  
  1050. /* Filename:   ChkMark.C                                                */
  1051.  
  1052. /*  Version:   1.00                                                     */
  1053. /*  Created:   1993-12-21                                               */
  1054. /*  Revised:   1994-09-18                                               */
  1055.  
  1056. /* Routines:   BOOL EXPENTRY ChkMarkRegister(HAB hAB);                  */
  1057. /*             BOOL EXPENTRY ChkMarkQuery(PUSERINFO pUserInfo);         */
  1058. /*             MRESULT EXPENTRY ChkMarkWndProc(HWND hWnd, ULONG msg,    */
  1059. /*                                             MPARAM mp1, MPARAM mp2); */
  1060. /*             MRESULT EXPENTRY ChkMarkStyles(HWND hWnd, ULONG msg,     */
  1061. /*                                            MPARAM mp1, MPARAM mp2);  */
  1062.  
  1063.  
  1064. /* Copyright Γòò 1989-1994  Prominare Inc.  All Rights Reserved.          */
  1065.  
  1066. /* -------------------------------------------------------------------- */
  1067.  
  1068. /************************************************************************/
  1069. /************************************************************************/
  1070. /*                     DISCLAIMER OF WARRANTIES.                        */
  1071. /************************************************************************/
  1072. /************************************************************************/
  1073. /*     The following [enclosed] code is library code created by         */
  1074. /*     Prominare Inc.  This library code is  provided to you solely     */
  1075. /*     for the purpose of assisting you in the development of your      */
  1076. /*     applications.  The code is provided "AS IS", without             */
  1077. /*     warranty of any kind.  Prominare Inc. shall not be liable        */
  1078. /*     for any damages arising out of your use of the library code,     */
  1079. /*     even if they have been advised of the possibility of such        */
  1080. /*     damages.                                                         */
  1081. /************************************************************************/
  1082. /************************************************************************/
  1083.  
  1084. /* --- Control Data Structures ---------------------------------------- */
  1085.  
  1086. typedef struct _CHECKMARK          /* cmrk */
  1087.    {
  1088.    HWND    hwndOwner;              /* Owner Window Handle               */
  1089.    CHAR    szText[512];            /* Text Holder                       */
  1090.    BOOL    fChecked;               /* Check Mark State Flag             */
  1091.    RECTL   rclChecked;             /* Bitmap Rectangle Checked          */
  1092.    RECTL   rclUnChecked;           /* Bitmap Rectangle UnChecked        */
  1093.    POINTL  ptlChkMark;             /* Bitmap Rectangle UnChecked        */
  1094.    POINTL  ptlText;                /* Text Display Point                */
  1095.    RECTL   rclText;                /* Text Display Rectangle            */
  1096.    RECTL   rcl;                    /* Bitmap Display Rectangle          */
  1097.    HBITMAP hbm;                    /* Check Mark Bitmap Handle          */
  1098.    LONG    aClr[7];                /* Presentation Colours Array        */
  1099.    } CHECKMARK ;
  1100.  
  1101. typedef CHECKMARK *PCHECKMARK;
  1102.  
  1103. /* --- Module Prototype Definitions ----------------------------------- */
  1104.  
  1105. static VOID SetDefaultColours(HWND hWnd, PCHECKMARK pcmrk);
  1106. static LONG lGetPresParam(HWND hWnd, ULONG ulID1, ULONG ulID2, LONG lDefault);
  1107.  
  1108. BOOL    EXPENTRY ChkMarkRegister(HAB hAB);
  1109. BOOL    EXPENTRY ChkMarkQuery(PUSERINFO pUserInfo);
  1110. MRESULT EXPENTRY ChkMarkWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  1111. MRESULT EXPENTRY ChkMarkStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  1112.  
  1113. #define CLENpszClassname 10
  1114. static PSZ pszClassname = "CheckMark";
  1115. static HMODULE hmodDLL;
  1116.  
  1117. #pragma subtitle("   Check Mark Control - DLL Initialization/Termination Procedure")
  1118. #pragma page( )
  1119.  
  1120. /* --- _Dll_InitTerm ----------------------------------- [ Public ] --- */
  1121. /*                                                                      */
  1122. /*     This function is used to provide the DLL initialization and      */
  1123. /*     termination.  The function is called by the C startup code       */
  1124. /*     and allows the control to register itself and provide any        */
  1125. /*     necessary startup.                                               */
  1126. /*                                                                      */
  1127. /*     This function is designed for IBM C Set/2 Version 1.0 and        */
  1128. /*     IBM C Set++ Version 2.x                                          */
  1129. /*                                                                      */
  1130. /*     Upon Entry:                                                      */
  1131. /*                                                                      */
  1132. /*     ULONG hModule; = DLL Module Handle                               */
  1133. /*     ULONG fl;      = Startup / Termination Flag                      */
  1134. /*                                                                      */
  1135. /*     Upon Exit:                                                       */
  1136. /*                                                                      */
  1137. /*     _Dll_InitTerm =  0 : Error Return                                */
  1138. /*                   =  1 : Successful Startup / Termination            */
  1139. /*                                                                      */
  1140. /* -------------------------------------------------------------------- */
  1141.  
  1142. ULONG _System _Dll_InitTerm(ULONG hModule, ULONG fl)
  1143.  
  1144. {
  1145.                        /* Determine if in startup or termination mode   */
  1146. if ( fl == 0 )
  1147.                        /* DLL being initialized, save the DLL module    */
  1148.                        /* handle to allow the bitmap loading routines   */
  1149.                        /* routines a means of loading the default       */
  1150.                        /* bitmaps when required                         */
  1151.    hmodDLL = hModule;
  1152.  
  1153. return(1UL);
  1154. }
  1155. #pragma subtitle("   Check Mark Control DLL - Control Initialization Function")
  1156. #pragma page ( )
  1157.  
  1158. /* --- ChkMarkInit ------------------------------------- [ Public ] --- */
  1159. /*                                                                      */
  1160. /*     This function is used to register the installable control class  */
  1161. /*     with OS/2 Presentation Manager.  The registration must use the   */
  1162. /*     USER_CWINDOWWORDS to reserve memory for the control to allow for */
  1163. /*     proper usage by Resource Editor and for use by the control       */
  1164. /*     dialog and window procedures.  The information for the control   */
  1165. /*     containing the style, Font & Colours and control data   */
  1166. /*     is pointed to by a pointer that can be referenced by the         */
  1167. /*     control's dialog and window procedure as required.  The memory   */
  1168. /*     for the structure is allocated and controlled through Resource   */
  1169. /*     Editor.   The control can reserve more memory for its use        */
  1170. /*     by adding the memory required to that of the USER_CWINDOWWORDS   */
  1171. /*     constant.                                                        */
  1172. /*                                                                      */
  1173. /*     Upon Entry:                                                      */
  1174. /*                                                                      */
  1175. /*     HAB hAB; = Application Anchor Block Handle                       */
  1176. /*                                                                      */
  1177. /*     Upon Exit:                                                       */
  1178. /*                                                                      */
  1179. /*     ChkMarkInit =  TRUE : Class Registration Successful              */
  1180. /*                 = FALSE : Class Registration Failed                  */
  1181. /*                                                                      */
  1182. /* -------------------------------------------------------------------- */
  1183.  
  1184. BOOL EXPENTRY ChkMarkRegister(HAB hAB)
  1185.  
  1186. {
  1187.                        /* Register the control class with OS/2          */
  1188.                        /* Presentation Manager and return registration  */
  1189.                        /* result                                        */
  1190.  
  1191. return(WinRegisterClass(hAB, pszClassname, ChkMarkWndProc,
  1192.                         CS_SYNCPAINT | CS_SIZEREDRAW, USER_CWINDOWWORDS));
  1193.  
  1194. }
  1195. #pragma subtitle("   Check Mark Control DLL - Query Control Information Function")
  1196. #pragma page ( )
  1197.  
  1198. /* --- ChkMarkQuery ------------------------------------ [ Public ] --- */
  1199. /*                                                                      */
  1200. /*     This function is used to return to the caller information        */
  1201. /*     regarding the installable control and its capabilities.  The     */
  1202. /*     function should return a true value otherwise Resource           */
  1203. /*     Editor will not register the control as being usable.            */
  1204. /*                                                                      */
  1205. /*     Upon Entry:                                                      */
  1206. /*                                                                      */
  1207. /*     PUSERINFO pUserInfo; = User Information Pointer                  */
  1208. /*                                                                      */
  1209. /*     Upon Exit:                                                       */
  1210. /*                                                                      */
  1211. /*     ChkMarkQuery =  TRUE : User Information Being Returned           */
  1212. /*                  = FALSE : No User Information Available             */
  1213. /*                                                                      */
  1214. /* -------------------------------------------------------------------- */
  1215.  
  1216. BOOL EXPENTRY ChkMarkQuery(PUSERINFO pUserInfo)
  1217.  
  1218. {
  1219.                        /* Complete the User Information structure       */
  1220.                        /* passed to the function by Resource Editor     */
  1221.  
  1222.                        /* Complete the version and number of control    */
  1223.                        /* types.  In Version 1.00 of CCRS, only one     */
  1224.                        /* control type is used.                         */
  1225. pUserInfo->ulMajor = 2UL;
  1226. pUserInfo->ulMinor = 0UL;
  1227.                        /* Complete the author and control classname     */
  1228.  
  1229. memcpy(pUserInfo->szAuthor,    "Prominare Inc.", 15);
  1230. memcpy(pUserInfo->szClassname, pszClassname, CLENpszClassname);
  1231. memcpy(pUserInfo->szName,      "ChkMark", 8);
  1232.  
  1233.                        /* Complete the default size and style of the    */
  1234.                        /* first user control type                       */
  1235.  
  1236. pUserInfo->utDefined[0].cx           = 25L;
  1237. pUserInfo->utDefined[0].cy           = 10L;
  1238. pUserInfo->utDefined[0].flStyle      = WS_VISIBLE;
  1239.  
  1240.                        /* Set the maximum amount of text control can    */
  1241.                        /* accept including NULL termination byte        */
  1242.  
  1243. pUserInfo->utDefined[0].cMaxText     = CCHTEXTMAX;
  1244.  
  1245.                        /* Save the style's dialogue ID, type, control   */
  1246.                        /* data size and count of style masks            */
  1247.  
  1248. pUserInfo->utDefined[0].idDlg        = DLG_CTRLUSER;
  1249. pUserInfo->utDefined[0].flOptions    = PMCXOPT_REFRESH;
  1250. pUserInfo->utDefined[0].ulType       = UTYPE_PRIVATE;
  1251. pUserInfo->utDefined[0].cCtlData     = 0UL;
  1252. pUserInfo->utDefined[0].cMasks       = 1UL;
  1253. pUserInfo->utDefined[0].flStyleType  = STYLETYPE_BITFLAGS;
  1254. pUserInfo->utDefined[0].stMasks[0].flStyleMask = CMS_CHECKED;
  1255. pUserInfo->utDefined[0].stMasks[0].idStyle     = IDS_CMS_CHECKED;
  1256.  
  1257.                        /* Save the description of the control           */
  1258.  
  1259. memcpy(pUserInfo->utDefined[0].szDescription, "Check Mark", 11);
  1260.  
  1261.                        /* Return the success flag back to Resource      */
  1262.                        /* Editor                                        */
  1263. return(TRUE);
  1264. }
  1265. #pragma subtitle("   Check Mark Control DLL - Control Window Procedure")
  1266. #pragma page( )
  1267.  
  1268. /* --- lGetPresParam ---------------------------------- [ Private } --- */
  1269. /*                                                                      */
  1270. /*     This function is used to retrieve a Font & Colours                */
  1271. /*     that may be present.  If the Font & Colours is not,               */
  1272. /*     the default colour passed to the function will be used.          */
  1273. /*                                                                      */
  1274. /*     Upon Entry:                                                      */
  1275. /*                                                                      */
  1276. /*     HWND  hWnd;     = Window Handle                                  */
  1277. /*     ULONG ulID1;    = Font & Colours 1 ID                             */
  1278. /*     ULONG ulID2;    = Font & Colours 2 ID                             */
  1279. /*     LONG  lDefault; = Default Colour                                 */
  1280. /*                                                                      */
  1281. /*     Upon Exit:                                                       */
  1282. /*                                                                      */
  1283. /*     lGetPresParam = Colour to Use                                    */
  1284. /*                                                                      */
  1285. /* -------------------------------------------------------------------- */
  1286.  
  1287. LONG lGetPresParam(HWND hWnd, ULONG ulID1, ULONG ulID2, LONG lDefault)
  1288.  
  1289. {
  1290. HPS   hPS;                         /* Presentation Space Handle         */
  1291. LONG  lClr;                        /* Font & Colours Colour     */
  1292. ULONG ulID;                        /* Font & Colours ID         */
  1293.  
  1294. if ( WinQueryPresParam(hWnd, ulID1, ulID2, &ulID, 4UL, (PVOID)&lClr,
  1295.                        QPF_NOINHERIT | QPF_ID2COLORINDEX | QPF_PURERGBCOLOR) )
  1296.    return(lClr);
  1297. else
  1298.    if ( (lDefault >= SYSCLR_SHADOWHILITEBGND) &&
  1299.         (lDefault <= SYSCLR_HELPHILITE) )
  1300.        return(WinQuerySysColor(HWND_DESKTOP, lDefault, 0L));
  1301.    else
  1302.        if ( (lClr = GpiQueryRGBColor(hPS = WinGetPS(hWnd),
  1303.                                      LCOLOPT_REALIZED, lDefault)) == GPI_ALTERROR )
  1304.            {
  1305.            WinReleasePS(hPS);
  1306.            return(lDefault);
  1307.            }
  1308.        else
  1309.            {
  1310.            WinReleasePS(hPS);
  1311.            return(lClr);
  1312.            }
  1313. }
  1314. #pragma subtitle("   Check Mark Control DLL - Default Colours Procedure")
  1315. #pragma page( )
  1316.  
  1317. /* --- SetDefaultColours ------------------------------ [ Private ] --- */
  1318. /*                                                                      */
  1319. /*     This function is used to set the default colours that the        */
  1320. /*     image button should use within the internal paint routines.      */
  1321. /*     The colour can either be a Font & Colours that has                */
  1322. /*     been set or it can be the default colour as defined within       */
  1323. /*     control.                                                         */
  1324. /*                                                                      */
  1325. /*     Upon Entry:                                                      */
  1326. /*                                                                      */
  1327. /*     HWND       hWnd;  = Window Handle                                */
  1328. /*     PCHECKMARK pcmrk; = Check Mark Structure Pointer                 */
  1329. /*                                                                      */
  1330. /*     Upon Exit:                                                       */
  1331. /*                                                                      */
  1332. /*     Nothing                                                          */
  1333. /*                                                                      */
  1334. /* -------------------------------------------------------------------- */
  1335.  
  1336. static VOID SetDefaultColours(HWND hWnd, PCHECKMARK pcmrk)
  1337.  
  1338. {
  1339.                        /* Set up the colours that will be used within   */
  1340.                        /* the painting of the control.  The colour      */
  1341.                        /* indices are:                                  */
  1342.                        /*                                               */
  1343.                        /* 0 : Foreground (PP_FOREGROUND*)               */
  1344.                        /* 1 : Background (PP_BACKGROUND*)               */
  1345.                        /* 2 : Hilight Foreground (PP_HILITEFOREGROUND*) */
  1346.                        /* 3 : Hilight Background (PP_HILITEBACKGROUND*) */
  1347.                        /* 4 : Disabled Foreground (PP_DISABLEDFORE*)    */
  1348.                        /* 5 : Disabled Foreground (PP_DISABLEDFORE*)    */
  1349.                        /* 6 : Border (PP_BORDER*)                       */
  1350.  
  1351. pcmrk->aClr[0] = lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
  1352.                              PP_FOREGROUNDCOLORINDEX,
  1353.                              SYSCLR_OUTPUTTEXT);
  1354. pcmrk->aClr[1] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
  1355.                              PP_BACKGROUNDCOLORINDEX,
  1356.                              SYSCLR_FIELDBACKGROUND);
  1357. pcmrk->aClr[2] = lGetPresParam(hWnd, PP_HILITEFOREGROUNDCOLOR,
  1358.                              PP_HILITEFOREGROUNDCOLORINDEX,
  1359.                              SYSCLR_OUTPUTTEXT);
  1360. pcmrk->aClr[3] = lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
  1361.                              PP_HILITEBACKGROUNDCOLORINDEX,
  1362.                              SYSCLR_BACKGROUND);
  1363. pcmrk->aClr[4] = lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
  1364.                              PP_DISABLEDFOREGROUNDCOLORINDEX,
  1365.                              SYSCLR_OUTPUTTEXT);
  1366. pcmrk->aClr[5] = lGetPresParam(hWnd, PP_DISABLEDBACKGROUNDCOLOR,
  1367.                              PP_DISABLEDBACKGROUNDCOLORINDEX,
  1368.                              SYSCLR_BACKGROUND);
  1369. pcmrk->aClr[6] = lGetPresParam(hWnd, PP_BORDERCOLOR,
  1370.                              PP_BORDERCOLORINDEX,
  1371.                              SYSCLR_BUTTONDARK);
  1372. }
  1373. #pragma subtitle("   Check Mark Control DLL - Display Point Calculation Procedure")
  1374. #pragma page ( )
  1375.  
  1376. /* --- CalcDisplayPoints ------------------------------ [ Private ] --- */
  1377. /*                                                                      */
  1378. /*     This function is used to calculate the display points for the    */
  1379. /*     installed control.                                               */
  1380. /*                                                                      */
  1381. /*     Upon Entry:                                                      */
  1382. /*                                                                      */
  1383. /*     PCHECKMARK pcmrk; = Control Data Structure Pointer               */
  1384. /*     LONG       cx;    = control Width                                */
  1385. /*     LONG       cy;    = Control Height                               */
  1386. /*                                                                      */
  1387. /*     Upon Exit:                                                       */
  1388. /*                                                                      */
  1389. /*     Nothing                                                          */
  1390. /*                                                                      */
  1391. /* -------------------------------------------------------------------- */
  1392.  
  1393. static VOID CalcDisplayPoints(HWND hWnd, PCHECKMARK pcmrk, LONG cx, LONG cy)
  1394.  
  1395. {
  1396. BITMAPINFOHEADER bmp;              /* Bitmap Information Holder         */
  1397. HPS              hPS;              /* Presentation Space Handle         */
  1398. FONTMETRICS      fm;               /* Font Metrics                      */
  1399.  
  1400. GpiQueryBitmapParameters(pcmrk->hbm, &bmp);
  1401.  
  1402. GpiQueryFontMetrics(hPS = WinGetPS(hWnd), sizeof(FONTMETRICS), &fm);
  1403.  
  1404. WinReleasePS(hPS);
  1405. pcmrk->rclChecked.xRight = bmp.cx;
  1406. pcmrk->rclChecked.xLeft = (bmp.cx = (USHORT)(bmp.cx / 2));
  1407.  
  1408. pcmrk->rclUnChecked.xRight = bmp.cx;
  1409. pcmrk->rclChecked.yTop = pcmrk->rclUnChecked.yTop = bmp.cy;
  1410.  
  1411. pcmrk->ptlChkMark.y = cy / 2L - bmp.cy / 2L;
  1412.  
  1413. pcmrk->ptlText.x = bmp.cx + fm.lAveCharWidth / 2L;
  1414. pcmrk->ptlText.y = (cy / 2L) - (fm.lMaxBaselineExt / 2L) + fm.lMaxDescender;
  1415.  
  1416. pcmrk->rclText.xLeft  = bmp.cx;
  1417. pcmrk->rclText.xRight = cx;
  1418. pcmrk->rclText.yTop   = cy;
  1419.  
  1420. pcmrk->rcl.xRight = cx;
  1421. pcmrk->rcl.yTop   = cy;
  1422.  
  1423. }
  1424. #pragma subtitle("   Check Mark Control DLL - 3D Text Window Procedure")
  1425. #pragma page ( )
  1426.  
  1427. /* --- ChkMarkWndProc --------------------------------- [ Private ] --- */
  1428. /*                                                                      */
  1429. /*     This function is used to handle the messages sent to the         */
  1430. /*     installed control.  The window procedure is designed to          */
  1431. /*     allow for multiple instances and to be totally re-entrant.       */
  1432. /*                                                                      */
  1433. /*     Upon Entry:                                                      */
  1434. /*                                                                      */
  1435. /*     HWND   hWnd; = Window Handle                                     */
  1436. /*     ULONG  msg;  = PM Message                                        */
  1437. /*     MPARAM mp1;  = Message Parameter 1                               */
  1438. /*     MPARAM mp2;  = Message Parameter 2                               */
  1439. /*                                                                      */
  1440. /*     Upon Exit:                                                       */
  1441. /*                                                                      */
  1442. /*     ChkMarkWndProc = Message Handling Result                         */
  1443. /*                                                                      */
  1444. /* -------------------------------------------------------------------- */
  1445.  
  1446. MRESULT EXPENTRY ChkMarkWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1447.  
  1448. {
  1449. HPS              hPS;              /* Presentation Space Handle         */
  1450. PCREATESTRUCT    pcrst;            /* Create Structure Pointer          */
  1451. PCHECKMARK       pcmrk;            /* Check Mark Structure Pointer      */
  1452. PWNDPARAMS       pwprm;            /* Window Parameters Pointer         */
  1453.  
  1454. switch ( msg )
  1455.    {
  1456.                        /* Perform control initialization when the       */
  1457.                        /* control is created                            */
  1458.    case WM_CREATE :
  1459.                        /* Create a heap for the control using a         */
  1460.                        /* segment                                       */
  1461.  
  1462.        DosAllocMem((PPVOID)(PVOID)&pcmrk, 4096UL, PAG_READ | PAG_WRITE | PAG_COMMIT);
  1463.  
  1464.                        /* Save the address of the text string pointer   */
  1465.                        /* in the control's reserved memory to allow it  */
  1466.                        /* to be referenced as required by the control   */
  1467.  
  1468.        WinSetWindowPtr(hWnd, QWW_CDATA, (PVOID)pcmrk);
  1469.  
  1470.                        /* Get the control's creation structure address  */
  1471.                        /* to copy the default text of the control to    */
  1472.                        /* the memory in the heap                        */
  1473.  
  1474.        pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);
  1475.  
  1476.        pcmrk->hwndOwner = pcrst->hwndOwner;
  1477.  
  1478.        if ( pcrst->flStyle & CMS_CHECKED )
  1479.            pcmrk->fChecked = TRUE;
  1480.  
  1481.                        /* Set up the colours that will be used within   */
  1482.                        /* the painting of the control.  The colour      */
  1483.                        /* indices are:                                  */
  1484.                        /*                                               */
  1485.                        /* 0 : Foreground (PP_FOREGROUND*)               */
  1486.                        /* 1 : Background (PP_BACKGROUND*)               */
  1487.                        /* 2 : Hilight Foreground (PP_HILITEFOREGROUND*) */
  1488.                        /* 3 : Hilight Background (PP_HILITEBACKGROUND*) */
  1489.                        /* 4 : Disabled Foreground (PP_DISABLEDFORE*)    */
  1490.                        /* 5 : Disabled Foreground (PP_DISABLEDFORE*)    */
  1491.                        /* 6 : Border (PP_BORDER*)                       */
  1492.  
  1493.        SetDefaultColours(hWnd, pcmrk);
  1494.  
  1495.        if ( pcrst->pszText )
  1496.            strcpy(pcmrk->szText, pcrst->pszText);
  1497.        pcmrk->hbm = GpiLoadBitmap(hPS = WinGetPS(hWnd), hmodDLL, IDB_CHECKMARKS,
  1498.                                   0L, 0L);
  1499.  
  1500.        WinReleasePS(hPS);
  1501.  
  1502.        CalcDisplayPoints(hWnd, pcmrk, pcrst->cx, pcrst->cy);
  1503.        break;
  1504.  
  1505.    case WM_SIZE :
  1506.                        /* Text being set, get the address of the text   */
  1507.                        /* string stored in the heap                     */
  1508.  
  1509.        pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1510.        CalcDisplayPoints(hWnd, pcmrk,
  1511.                          (LONG)(SHORT)SHORT1FROMMP(mp2),
  1512.                          (LONG)(SHORT)SHORT2FROMMP(mp2));
  1513.        break;
  1514.                        /* Process window parameters setting             */
  1515.  
  1516.    case WM_SETWINDOWPARAMS :
  1517.  
  1518.                        /* Get the address for the windows parameters    */
  1519.                        /* structure                                     */
  1520.  
  1521.        pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);
  1522.  
  1523.                        /* Check to see if the text for the control is   */
  1524.                        /* being set                                     */
  1525.  
  1526.        if ( pwprm->fsStatus & WPM_TEXT )
  1527.            {
  1528.                        /* Text being set, get the address of the text   */
  1529.                        /* string stored in the heap                     */
  1530.  
  1531.            pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1532.  
  1533.                        /* Check to see if any text is being set         */
  1534.  
  1535.            if ( pwprm->cchText )
  1536.  
  1537.                        /* Check to make sure that the text that is to   */
  1538.                        /* be set is not greater than the memory         */
  1539.                        /* allocated                                     */
  1540.  
  1541.                if ( pwprm->cchText > 511 )
  1542.                    {
  1543.                    strncpy(pcmrk->szText, pwprm->pszText, 511);
  1544.                    pcmrk->szText[511] = 0;
  1545.                    }
  1546.                else
  1547.                    strcpy(pcmrk->szText, pwprm->pszText);
  1548.            else
  1549.                        /* No text is being set, clear any existing text */
  1550.  
  1551.                pcmrk->szText[0] = 0;
  1552.            }
  1553.        break;
  1554.                        /* Process window parameters query               */
  1555.  
  1556.    case WM_QUERYWINDOWPARAMS :
  1557.  
  1558.                        /* Get the address for the windows parameters    */
  1559.                        /* structure                                     */
  1560.  
  1561.        pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);
  1562.  
  1563.                        /* Determine the type of query                   */
  1564.  
  1565.        switch ( pwprm->fsStatus )
  1566.            {
  1567.                        /* Query type:  get text                         */
  1568.  
  1569.            case WPM_TEXT :
  1570.  
  1571.                        /* Text being asked for, get the address of the  */
  1572.                        /* text string stored in the heap                */
  1573.  
  1574.                pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1575.  
  1576.                        /* Copy the text from the string to the          */
  1577.                        /* structure                                     */
  1578.  
  1579.                strcpy(pwprm->pszText, pcmrk->szText);
  1580.                break;
  1581.                        /* Query type:  get text length                  */
  1582.  
  1583.            case WPM_CCHTEXT :
  1584.  
  1585.                        /* Text length being asked for, get the address  */
  1586.                        /* of the text string stored in the heap         */
  1587.  
  1588.                pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1589.  
  1590.                        /* Place the length the string within the        */
  1591.                        /* structure                                     */
  1592.  
  1593.                pwprm->cchText = (ULONG)strlen(pcmrk->szText);
  1594.                break;
  1595.                        /* Query type:  get control data length          */
  1596.  
  1597.            case WPM_CBCTLDATA :
  1598.  
  1599.                        /* Set the control data length to zero           */
  1600.  
  1601.                pwprm->cbCtlData = 0;
  1602.                break;
  1603.  
  1604.            default :
  1605.                return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  1606.            }
  1607.        break;
  1608.                        /* Font & Colours changed, record the            */
  1609.                        /* change internally                             */
  1610.  
  1611.    case WM_PRESPARAMCHANGED :
  1612.  
  1613.                        /* Check to see if an individual presentation    */
  1614.                        /* parameter has changed if so, get the new      */
  1615.                        /* colour value for use by the painting routines */
  1616.  
  1617.        if ( LONGFROMMP(mp1) && (LONGFROMMP(mp1) < PP_FONTNAMESIZE) )
  1618.            {
  1619.                        /* Get the address of the control info from the  */
  1620.                        /* control's reserved memory                     */
  1621.  
  1622.            pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1623.  
  1624.                        /* Get the new Font & Colours colour for          */
  1625.                        /* the Font & Colours that has changed.           */
  1626.                        /* Get the colour as a RGB value so as to be     */
  1627.                        /* able to get an exact value and not an         */
  1628.                        /* approximation which could happen if the       */
  1629.                        /* Font & Colours was set as a RGB but            */
  1630.                        /* queried as an index.  When WinQueryPresParam  */
  1631.                        /* returns a 0, it indicates that no             */
  1632.                        /* Font & Colours set and the default             */
  1633.                        /* colours should be used.                       */
  1634.  
  1635.            switch ( LONGFROMMP(mp1) )
  1636.                {
  1637.                case PP_FOREGROUNDCOLOR :
  1638.                case PP_FOREGROUNDCOLORINDEX :
  1639.                    pcmrk->aClr[0] = lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
  1640.                                                   PP_FOREGROUNDCOLORINDEX,
  1641.                                                   SYSCLR_OUTPUTTEXT);
  1642.                    break;
  1643.  
  1644.                case PP_BACKGROUNDCOLOR :
  1645.                case PP_BACKGROUNDCOLORINDEX :
  1646.                    pcmrk->aClr[1] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
  1647.                                                   PP_BACKGROUNDCOLORINDEX,
  1648.                                                   SYSCLR_DIALOGBACKGROUND);
  1649.                    break;
  1650.  
  1651.                case PP_HILITEFOREGROUNDCOLOR :
  1652.                case PP_HILITEFOREGROUNDCOLORINDEX :
  1653.                    pcmrk->aClr[2] = lGetPresParam(hWnd, PP_HILITEFOREGROUNDCOLOR,
  1654.                                                   PP_HILITEFOREGROUNDCOLORINDEX,
  1655.                                                   SYSCLR_OUTPUTTEXT);
  1656.                    break;
  1657.  
  1658.                case PP_HILITEBACKGROUNDCOLOR :
  1659.                case PP_HILITEBACKGROUNDCOLORINDEX :
  1660.                    pcmrk->aClr[3] = lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
  1661.                                                   PP_HILITEBACKGROUNDCOLORINDEX,
  1662.                                                   SYSCLR_DIALOGBACKGROUND);
  1663.                    break;
  1664.  
  1665.                case PP_DISABLEDFOREGROUNDCOLOR :
  1666.                case PP_DISABLEDFOREGROUNDCOLORINDEX :
  1667.                    pcmrk->aClr[4] = lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
  1668.                                                   PP_DISABLEDFOREGROUNDCOLORINDEX,
  1669.                                                   SYSCLR_OUTPUTTEXT);
  1670.                    break;
  1671.  
  1672.                case PP_DISABLEDBACKGROUNDCOLOR :
  1673.                case PP_DISABLEDBACKGROUNDCOLORINDEX :
  1674.                    pcmrk->aClr[5] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
  1675.                                                   PP_BACKGROUNDCOLORINDEX,
  1676.                                                   SYSCLR_DIALOGBACKGROUND);
  1677.                    break;
  1678.  
  1679.                case PP_BORDERCOLOR :
  1680.                case PP_BORDERCOLORINDEX :
  1681.                    pcmrk->aClr[6] = lGetPresParam(hWnd, PP_BORDERCOLOR,
  1682.                                                   PP_BORDERCOLORINDEX,
  1683.                                                   SYSCLR_BUTTONDARK);
  1684.                    break;
  1685.                }
  1686.                        /* Invalidate the button to force to use the     */
  1687.                        /* new colours just set or removed               */
  1688.  
  1689.            WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
  1690.            }
  1691.        else
  1692.                        /* Determine if the Scheme Palette has forced a  */
  1693.                        /* global scheme update in which case, check all */
  1694.                        /* of the Font & Colours to see if they          */
  1695.                        /* have been added or removed                    */
  1696.  
  1697.            if ( LONGFROMMP(mp1) == 0L )
  1698.  
  1699.                        /* Set up the colours that will be used within   */
  1700.                        /* the painting of the control.                  */
  1701.  
  1702.                SetDefaultColours(hWnd,
  1703.                                  pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd,
  1704.                                                                        QWW_CDATA));
  1705.        break;
  1706.                        /* Mouse being passed over the control, imply    */
  1707.                        /* that the control is transparent to the        */
  1708.                        /* system                                        */
  1709.    case WM_HITTEST :
  1710.        return(MRFROMLONG(HT_TRANSPARENT));
  1711.  
  1712.                        /* Erase control background                      */
  1713.  
  1714.    case WM_ERASEBACKGROUND :
  1715.        return(MRFROMLONG(TRUE));
  1716.  
  1717.    case CKM_SETCHECK :
  1718.                        /* Get the address of the text from the          */
  1719.                        /* control's reserved memory                     */
  1720.  
  1721.        pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1722.        pcmrk->fChecked = (BOOL)LONGFROMMP(mp1);
  1723.        WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
  1724.        break;
  1725.                        /* Paint the Control                             */
  1726.    case WM_PAINT :
  1727.                        /* Get the address of the text from the          */
  1728.                        /* control's reserved memory                     */
  1729.  
  1730.        pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1731.  
  1732.                        /* Get the presentation space for the control    */
  1733.                        /* and set the colour table to RGB mode          */
  1734.  
  1735.        GpiCreateLogColorTable(hPS = WinBeginPaint(hWnd, (HPS)NULL, (PRECTL)NULL),
  1736.                               0L, LCOLF_RGB, 0L, 0L, (PLONG)NULL);
  1737.  
  1738.        WinFillRect(hPS, &pcmrk->rcl, pcmrk->aClr[1]);
  1739.  
  1740.        WinDrawBitmap(hPS, pcmrk->hbm, pcmrk->fChecked ? &pcmrk->rclChecked :
  1741.                                                         &pcmrk->rclUnChecked,
  1742.                      &pcmrk->ptlChkMark, 0L, 0L, DBM_IMAGEATTRS | DBM_NORMAL);
  1743.  
  1744.        GpiCharStringPosAt(hPS, &pcmrk->ptlText, &pcmrk->rclText,
  1745.                           CHS_CLIP, (LONG)strlen(pcmrk->szText),
  1746.                           pcmrk->szText, NULL);
  1747.  
  1748.        WinEndPaint(hPS);
  1749.        break;
  1750.                        /* Control being destroyed                       */
  1751.    case WM_DESTROY :
  1752.                        /* Get the address of the text from the          */
  1753.                        /* control's reserved memory                     */
  1754.  
  1755.        pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
  1756.        GpiDeleteBitmap(pcmrk->hbm);
  1757.  
  1758.                        /* Release the heap allocated for use by the     */
  1759.                        /* control                                       */
  1760.  
  1761.        DosFreeMem((PVOID)pcmrk);
  1762.        break;
  1763.                        /* Default message processing                    */
  1764.    default :
  1765.        return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  1766.    }
  1767.  
  1768. return(0L);
  1769. }
  1770. #pragma subtitle("   Check Mark Control DLL - Control Styles Dialogue Procedure")
  1771. #pragma page ( )
  1772.  
  1773. /* --- ChkMarkStyles -------------------------------------------------- */
  1774. /*                                                                      */
  1775. /*     This function is used for the custom control's styles dialogue   */
  1776. /*     box procedure.                                                   */
  1777. /*                                                                      */
  1778. /*     When the dialogue is invoked from Resource Editor, the           */
  1779. /*     address of the user style information is contained in message    */
  1780. /*     parameter 2.  The dialogue is responsible for saving the         */
  1781. /*     address.  The best method to do this is to save the pointer      */
  1782. /*     in the dialogue's reserved memory where it can be retrieved as   */
  1783. /*     needed.                                                          */
  1784. /*                                                                      */
  1785. /*     Upon Entry:                                                      */
  1786. /*                                                                      */
  1787. /*     HWND   hWnd; = Dialog Window Handle                              */
  1788. /*     ULONG  msg;  = PM Message                                        */
  1789. /*     MPARAM mp1;  = Message Parameter 1                               */
  1790. /*     MPARAM mp2;  = Message Parameter 2                               */
  1791. /*                                                                      */
  1792. /*     Upon Exit:                                                       */
  1793. /*                                                                      */
  1794. /*     ChkMarkStyles = Message Handling Result                          */
  1795. /*                                                                      */
  1796. /* -------------------------------------------------------------------- */
  1797.  
  1798. MRESULT EXPENTRY ChkMarkStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1799.  
  1800. {
  1801. PUSERSTYLE   pust;                 /* User Style Pointer                */
  1802. SWP          swp;                  /* Screen Window Position Holder     */
  1803.  
  1804. switch ( msg )
  1805.    {
  1806.                        /* Perform dialogue initialization               */
  1807.    case WM_INITDLG :
  1808.                        /* Save the pointer to user style information    */
  1809.                        /* within the dialog's reserved memory           */
  1810.  
  1811.        WinSetWindowPtr(hWnd, QWL_USER, (PVOID)mp2);
  1812.  
  1813.                        /* Get the pointer to the user style information */
  1814.  
  1815.        if ( (pust = (PUSERSTYLE)mp2) != NULL )
  1816.            {
  1817.                        /* Set the text, ID symbol and value for the     */
  1818.                        /* control                                       */
  1819.  
  1820.            WinSetDlgItemText(hWnd, EF_TEXT, pust->pszText);
  1821.            pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust);
  1822.  
  1823.            if ( pust->flStyle & CMS_CHECKED )
  1824.                WinSendDlgItemMsg(hWnd, CB_CMS_CHECKED, BM_SETCHECK,
  1825.                                  MPFROMSHORT(TRUE), 0L);
  1826.  
  1827.            if ( pust->flStyle & WS_VISIBLE )
  1828.                WinSendDlgItemMsg(hWnd, CB_VISIBLE, BM_SETCHECK,
  1829.                                  MPFROMSHORT(TRUE), 0L);
  1830.  
  1831.            if ( pust->flStyle & WS_GROUP )
  1832.                WinSendDlgItemMsg(hWnd, CB_GROUP, BM_SETCHECK,
  1833.                                  MPFROMSHORT(TRUE), 0L);
  1834.  
  1835.            if ( pust->flStyle & WS_DISABLED )
  1836.                WinSendDlgItemMsg(hWnd, CB_DISABLED, BM_SETCHECK,
  1837.                                  MPFROMSHORT(TRUE), 0L);
  1838.  
  1839.            if ( pust->flStyle & WS_TABSTOP )
  1840.                WinSendDlgItemMsg(hWnd, CB_TABSTOP, BM_SETCHECK,
  1841.                                  MPFROMSHORT(TRUE), 0L);
  1842.            }
  1843.                        /* Centre dialog on the screen                   */
  1844.  
  1845.        WinQueryWindowPos(hWnd, (PSWP)&swp);
  1846.        WinSetWindowPos(hWnd, HWND_TOP,
  1847.                        (WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) - swp.cx) / 2L,
  1848.                        (WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - swp.cy) / 2L,
  1849.                        0L, 0L, SWP_MOVE);
  1850.        break;
  1851.                        /* Process push button selections                */
  1852.    case WM_COMMAND :
  1853.        switch ( SHORT1FROMMP(mp1) )
  1854.            {
  1855.                        /* Font & Colours push button selected           */
  1856.  
  1857.            case DID_PRESPARAM :
  1858.  
  1859.                        /* Get the pointer to the user style information */
  1860.  
  1861.                if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  1862.  
  1863.                        /* Get the address of the look up function from  */
  1864.                        /* user style information structure and display  */
  1865.                        /* the dialog.  The value selected within the    */
  1866.                        /* dialogue will be automatically placed within  */
  1867.                        /* the required entry fields                     */
  1868.  
  1869.                    pust->pfnGetFontClr(hWnd);
  1870.                break;
  1871.                        /* Bidi push button selected                     */
  1872.  
  1873.            case DID_BIDI :
  1874.  
  1875.                        /* Get the pointer to the user style information */
  1876.  
  1877.                if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  1878.  
  1879.                        /* Get the address of the look up function from  */
  1880.                        /* user style information structure and display  */
  1881.                        /* the dialog.  The value selected within the    */
  1882.                        /* dialogue will be automatically placed within  */
  1883.                        /* the required entry fields                     */
  1884.  
  1885.                    pust->pfnGetBidi(hWnd);
  1886.                break;
  1887.                        /* Enter push button selected get the            */
  1888.                        /* definitions for the control                   */
  1889.            case DID_OK :
  1890.  
  1891.                        /* Get the pointer to the user style information */
  1892.  
  1893.                if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
  1894.                    {
  1895.                        /* Get the address of the CUA compliance         */
  1896.                        /* function from the user style information      */
  1897.                        /* structure.  The function will check the text  */
  1898.                        /* for CUA compliance according to index value   */
  1899.                        /* selected.  A return value of TRUE from the    */
  1900.                        /* compliance function indicates that the text   */
  1901.                        /* entered is acceptable.  Conversely, a FALSE   */
  1902.                        /* return value indicates that text is non-      */
  1903.                        /* compliant.  In this case, the dialogue should */
  1904.                        /* not be exited from and the values within the  */
  1905.                        /* the entry fields should not be saved.         */
  1906.  
  1907.                    if ( !pust->pfnCUACheck(hWnd, EF_TEXT, CUACHK_CAPS) )
  1908.                        break;
  1909.  
  1910.                        /* Get the address of the symbol validation      */
  1911.                        /* function from the user style information      */
  1912.                        /* structure.  The function will validate the    */
  1913.                        /* symbol and will check for duplications of     */
  1914.                        /* values.  A return value of TRUE from the      */
  1915.                        /* validation function indicates that the symbol */
  1916.                        /* and value are acceptable.  Conversely, a      */
  1917.                        /* FALSE return value indicates that symbol or   */
  1918.                        /* value was not acceptable.  In this case,      */
  1919.                        /* the dialogue should not be exited from and    */
  1920.                        /* the values within the entry fields should not */
  1921.                        /* be saved.                                     */
  1922.  
  1923.                    if ( !pust->pfnGetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust) )
  1924.                        break;
  1925.                    else
  1926.                        {
  1927.                        /* Symbol and value validated, get the text of   */
  1928.                        /* the control and save within the user style    */
  1929.                        /* information structure for use by Resource     */
  1930.                        /* Editor                                        */
  1931.  
  1932.                        pust->cText = WinQueryDlgItemText(hWnd, EF_TEXT,
  1933.                                                          CCHTEXTMAX, pust->pszText);
  1934.  
  1935.                        /* Mask out current edit field styles clearing   */
  1936.                        /* selectable styles and save new style          */
  1937.  
  1938.                        pust->flStyle = 0UL;
  1939.  
  1940.                        /* Get raised/depressed style                    */
  1941.  
  1942.                        if ( SHORT1FROMMR(WinSendDlgItemMsg(hWnd, CB_CMS_CHECKED,
  1943.                                                            BM_QUERYCHECK,
  1944.                                                            0L, 0L)) )
  1945.                            pust->flStyle |= CMS_CHECKED;
  1946.  
  1947.                        /* Save completed edit field style in internal   */
  1948.                        /* window information                            */
  1949.  
  1950.                        if ( WinSendDlgItemMsg(hWnd, CB_VISIBLE,
  1951.                                               BM_QUERYCHECK, 0L, 0L) )
  1952.                            pust->flStyle |= WS_VISIBLE;
  1953.  
  1954.                        if ( WinSendDlgItemMsg(hWnd, CB_GROUP,
  1955.                                               BM_QUERYCHECK, 0L, 0L) )
  1956.                            pust->flStyle |= WS_GROUP;
  1957.  
  1958.                        if ( WinSendDlgItemMsg(hWnd, CB_DISABLED,
  1959.                                               BM_QUERYCHECK, 0L, 0L) )
  1960.                            pust->flStyle |= WS_DISABLED;
  1961.  
  1962.                        if ( WinSendDlgItemMsg(hWnd, CB_TABSTOP,
  1963.                                               BM_QUERYCHECK, 0L, 0L) )
  1964.                            pust->flStyle |= WS_TABSTOP;
  1965.                        }
  1966.                    }
  1967.                        /* Exit the dialogue indicating changes made     */
  1968.  
  1969.                WinDismissDlg(hWnd, TRUE);
  1970.                break;
  1971.                        /* Cancel selected, exit the dialogue without    */
  1972.                        /* changing anything                             */
  1973.  
  1974.            case DID_CANCEL :
  1975.                WinDismissDlg(hWnd, FALSE);
  1976.                break;
  1977.            }
  1978.        break;
  1979.                        /* Close received, exit dialog                   */
  1980.    case WM_CLOSE :
  1981.        WinDismissDlg(hWnd, FALSE);
  1982.        break;
  1983.                        /* Pass through unhandled messages               */
  1984.    default :
  1985.        return(WinDefDlgProc(hWnd, msg, mp1, mp2));
  1986.    }
  1987. return(0L);
  1988.  
  1989. }
  1990.  
  1991. The constants header file is defined below. The constants used by Prominare 
  1992. Designer, ChkMark.Rc and ChkMark.C, reference the controls in the styles 
  1993. dialogue. 
  1994.  
  1995. /* chkmark.h       Created:    1993-12-21  Revised:    1994-09-18       */
  1996.  
  1997. /* PMCX Control Constants Header                                        */
  1998.  
  1999. /* Copyright ╨╣ 1989-1994  Prominare Inc.  All Rights Reserved.          */
  2000.  
  2001.  
  2002. #define CMS_CHECKED       0x0001L
  2003.  
  2004. #define CKM_SETCHECK      (WM_USER + 128UL)
  2005.  
  2006. /* --- Miscellaneous Constants ---------------------------------------- */
  2007.  
  2008. #define DID_HELP              3    /* Help Push Button ID               */
  2009. #define DID_FONTCLR          11    /* Font & Colours Push Button ID     */
  2010. #define DID_BIDI             12    /* Bidi Push Button ID               */
  2011.  
  2012. #define CB_VISIBLE          256    /* Visible Check Box ID              */
  2013. #define CB_GROUP            257    /* Group Check Box ID                */
  2014. #define CB_DISABLED         258    /* Disabled Check Box ID             */
  2015. #define CB_TABSTOP          259    /* Tab Stop Check Box ID             */
  2016.  
  2017. /* --- Control Dialogue ----------------------------------------------- */
  2018.  
  2019. #define DLG_CTRLUSER       1000    /* User Defined Dialog               */
  2020. #define CB_CMS_CHECKED     4042    /* Left Aligned Radio Button         */
  2021. #define EF_TEXT            4051    /* Text Edit Field                   */
  2022. #define IDBX_SYMBOLVALUE   4053    /* ID Value Edit Field               */
  2023.  
  2024. /* --- Styles String ID's --------------------------------------------- */
  2025.  
  2026. #define IDS_CMS_CHECKED         512
  2027.  
  2028. /* --- Bitmap ID's ---------------------------------------------------- */
  2029.  
  2030. #define IDB_CHECKMARKS     784
  2031.  
  2032. The resource file for the style dialogue is shown below. 
  2033.  
  2034. /* PMCX Example                        Created:  1994-06-26             */
  2035. /* Resource File                       Revised:  1994-08-12             */
  2036.  
  2037. /* Copyright Γòò 1989-1994  Prominare Inc.  All Rights Reserved.          */
  2038.  
  2039. #define   INCL_WINSYS
  2040. #define INCL_WINSTDDLGS
  2041. #define INCL_WINSTDSPIN
  2042. #define INCL_NLS
  2043. #define INCL_SW
  2044.  
  2045. #include <os2.h>
  2046. #include "chkmark.h"
  2047.  
  2048. /* --- Custom Control Styles Dialogue --------------------------------- */
  2049.  
  2050. BITMAP      IDB_CHECKMARKS ChkMark.Bmp
  2051.  
  2052. DLGTEMPLATE DLG_CTRLUSER 850
  2053. BEGIN
  2054.     DIALOG "Check Mark Styles", DLG_CTRLUSER, 22, 62, 220, 121, FS_NOBYTEALIGN |
  2055.                 FS_DLGBORDER | WS_CLIPSIBLINGS | WS_SAVEBITS | WS_VISIBLE,
  2056.                 FCF_TITLEBAR | FCF_SYSMENU
  2057.     PRESPARAMS PP_FONTNAMESIZE, "8.Helv"
  2058.     BEGIN
  2059.         CONTROL "Select style and type text and ID symbol.", -1,
  2060.                                         5, 110, 123, 8, WC_STATIC, SS_TEXT |
  2061.                                             DT_VCENTER | WS_GROUP | WS_VISIBLE
  2062.                 PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_BLACK
  2063.         CONTROL "Text:",               -1, 5, 99, 16, 8, WC_STATIC, SS_TEXT |
  2064.                                             DT_RIGHT | DT_VCENTER | WS_VISIBLE
  2065.         CONTROL "",                    EF_TEXT, 25, 70, 190, 36, WC_MLE,
  2066.                                             MLS_BORDER | MLS_HSCROLL |
  2067.                                             MLS_IGNORETAB | MLS_VSCROLL |
  2068.                                             MLS_DISABLEUNDO | WS_TABSTOP |
  2069.                                             WS_VISIBLE
  2070.         CONTROL "ID:",                 -1, 5, 60, 16, 8, WC_STATIC, SS_TEXT |
  2071.                                             DT_RIGHT | DT_VCENTER | WS_VISIBLE
  2072.         CONTROL "",                    IDBX_SYMBOLVALUE, 25, 60, 190, 8, "ID.Box",
  2073.                                             WS_TABSTOP | WS_VISIBLE
  2074.         CONTROL "Check mark options",  -1, 5, 40, 210, 18, WC_STATIC,
  2075.                                             SS_GROUPBOX | WS_VISIBLE
  2076.         CONTROL "~Checked",            CB_CMS_CHECKED, 8, 42, 40, 8, WC_BUTTON,
  2077.                                             BS_AUTOCHECKBOX | WS_TABSTOP |
  2078.                                             WS_VISIBLE
  2079.         CONTROL "Base styles",         -1, 5, 20, 210, 18, WC_STATIC,
  2080.                                             SS_GROUPBOX | WS_GROUP | WS_VISIBLE
  2081.         CONTROL "~Visible",            CB_VISIBLE, 8, 22, 32, 8, WC_BUTTON,
  2082.                                             BS_AUTOCHECKBOX | WS_TABSTOP |
  2083.                                             WS_VISIBLE
  2084.         CONTROL "~Group",              CB_GROUP, 110, 22, 31, 8, WC_BUTTON,
  2085.                                             BS_AUTOCHECKBOX | WS_TABSTOP |
  2086.                                             WS_VISIBLE
  2087.         CONTROL "~Disabled",           CB_DISABLED, 58, 22, 40, 8, WC_BUTTON,
  2088.                                             BS_AUTOCHECKBOX | WS_TABSTOP |
  2089.                                             WS_VISIBLE
  2090.         CONTROL "~Tab stop",           CB_TABSTOP, 165, 22, 39, 8, WC_BUTTON,
  2091.                                             BS_AUTOCHECKBOX | WS_TABSTOP |
  2092.                                             WS_VISIBLE
  2093.         CONTROL "Enter",               DID_OK, 5, 5, 50, 12, WC_BUTTON,
  2094.                                             BS_PUSHBUTTON | BS_DEFAULT |
  2095.                                             WS_GROUP | WS_TABSTOP | WS_VISIBLE
  2096.         CONTROL "Cancel",              DID_CANCEL, 58, 5, 50, 12, WC_BUTTON,
  2097.                                             BS_PUSHBUTTON | WS_TABSTOP |
  2098.                                             WS_VISIBLE
  2099.         CONTROL "Help",                DID_HELP, 110, 5, 50, 12, WC_BUTTON,
  2100.                                             BS_PUSHBUTTON | BS_HELP |
  2101.                                             BS_NOPOINTERFOCUS | WS_TABSTOP |
  2102.                                             WS_VISIBLE
  2103.         CONTROL "Font & Colours...",     DID_PRESPARAM, 165, 5, 50, 12, WC_BUTTON,
  2104.                                             BS_PUSHBUTTON | WS_TABSTOP |
  2105.                                             WS_VISIBLE
  2106.     END
  2107. END
  2108.  
  2109. CODEPAGE 850
  2110. STRINGTABLE MOVEABLE DISCARDABLE
  2111. BEGIN
  2112.     IDS_CMS_CHECKED,                    "CMS_CHECKED"
  2113. END
  2114. The MAKE file is shown below. 
  2115.  
  2116. # MAKE file for ChkMark     Version 1.00.00
  2117.  
  2118. # Revised:  1994-08-12
  2119.  
  2120. # Copyright Γòò 1989-1994  Prominare Inc.  All Rights Reserved.
  2121.  
  2122. ChkMark.Dll: ChkMark.Obj ChkMark.Res
  2123.  Link386 /EXEPACK /BASE:0x1200000 @ChkMark.Lnk;
  2124.  Rc ChkMark.Res ChkMark.Dll
  2125.  
  2126. ChkMark.Obj: ChkMark.C
  2127.   Icc -G4e- -Ox -Rn -Fo$* ChkMark.C
  2128.  
  2129. ChkMark.Res: ChkMark.Rc
  2130.  Rc -r $(@B).Rc $*.Res
  2131. The link response file is shown below. 
  2132.  
  2133. ChkMark
  2134. ChkMark.Dll
  2135. ChkMark.Map
  2136.  
  2137. ChkMark.Def
  2138. The definitions file is shown below. 
  2139.  
  2140. LIBRARY         ChkMark INITINSTANCE TERMINSTANCE
  2141.  
  2142. DESCRIPTION     'Check Mark Control - 32-Bit Version'
  2143.  
  2144. CODE            LOADONCALL EXECUTEREAD NOIOPL NONCONFORMING
  2145. DATA            LOADONCALL READWRITE NOIOPL MULTIPLE NONSHARED
  2146.  
  2147. PROTMODE
  2148.  
  2149. EXETYPE         OS2
  2150.  
  2151. EXPORTS         ChkMarkRegister @ 1
  2152.                 ChkMarkQuery @ 2
  2153.                 ChkMarkStyles @ 3
  2154.  
  2155. Examples using PMCX (including full source code) are contained in the 
  2156. Source\Designer subdirectories, if you allowed the source code to be installed 
  2157. on your system during installation of Prominare Designer. Following are some of 
  2158. the PMCX controls implemented. 
  2159.  
  2160.  Directory           Purpose 
  2161.  3D  Example of a PMCX control 3D text field. 
  2162.  ChkMark             Example of a static control with check mark. 
  2163.  ComboBox            Example of a variable control data usage PMCX control 
  2164.                      using a combo box. 
  2165.  ComboMin            Example of a variable control data usage PMCX control 
  2166.                      using a combo box and also allowing for the combo box to 
  2167.                      specify the depth of the drop down when used with tight 
  2168.                      areas. 
  2169.  Control             Example of a simple PMCX control. 
  2170.  DateFld             Example of a PMCX control for a date entry field. 
  2171.  Frame               Example of a PMCX control for a shadowed frame. This PMCX 
  2172.                      example shows how to utilize font and colours within a 
  2173.                      custom control. 
  2174.  ImageBtn            Example of a PMCX control push button containing a graphic 
  2175.                      bitmap image. 
  2176.  Line3D              Example of a PMCX control 3D line. 
  2177.  ListBox             Example of a variable control data usage PMCX control 
  2178.                      using a list box. 
  2179.  Notebook            Example of notebook usage in a design. 
  2180.  NotePage            Example of a variable control data usage PMCX control 
  2181.                      using a notebook. 
  2182.  Pattern             Example of a PMCX control pattern field. 
  2183.  SpinBtn             Example of a variable control data usage PMCX control 
  2184.                      using a spin button. 
  2185.  TestBed             Facility to test PMCX controls. The utility provides the 
  2186.                      means to debug and test the control dialogues. 
  2187.  TimeFld             Example of a PMCX control for a time entry field. 
  2188.