home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
pdlite.zip
/
PMCX.INF
(
.txt
)
< prev
next >
Wrap
OS/2 Help File
|
1995-07-11
|
62KB
|
2,188 lines
ΓòÉΓòÉΓòÉ 1. Trademarks ΓòÉΓòÉΓòÉ
The following are trademarks of the Prominare Inc.
Prominare
Prominare Designer
PM Control Extension
PMCX
The following are trademarks of the IBM Corporation.
CUA
Common User Access
IBM
Operating System/2
OS/2
Presentation Manager
Workplace Shell
ΓòÉΓòÉΓòÉ 2. Copyright ΓòÉΓòÉΓòÉ
Copyright Γòò 1989-1994 Prominare Inc. All Rights Reserved.
ΓòÉΓòÉΓòÉ 3. Introduction ΓòÉΓòÉΓòÉ
Prominare Designer's PM Control Extension (PMCX) allows you to design and
create custom controls, similar to those of OS/2 Presentation Manager, that can
be accessed from within your applications.
PMCX has been designed so the controls you create can be accessed through
Prominare Designer. As with normal OS/2 Presentation Manager controls, you can
view the final control as it would appear in your application. And as with
Prominare Designer's other controls, you can define a control in terms of its
style, text, and other related information.
OS/2 Presentation Manager is designed to allow custom or user-defined controls
to be included within dialogues. PMCX uses this feature to let you create
controls not found in the default OS/2 Presentation Manager environment. In
reality, a custom control is similar to any of the windows created for an
application.
OS/2 Presentation Manager also provides a mechanism for run-time binding of
libraries--namely, dynamic-link libraries. PMCX uses this mechanism to make the
custom control accessible to applications including Prominare Designer.
ΓòÉΓòÉΓòÉ 4. PMCX Architecture ΓòÉΓòÉΓòÉ
The PM Control Extension is based on a simple foundation that allows both your
application and Prominare Designer to interact with it. With the conventions
and methodology that follow, you will learn to create PMCX controls.
The architecture of a PMCX control, shown in the following diagram, can be
described as three publicly defined functions and a window procedure. The three
functions have to follow the naming and usage conventions of PMCX, whereas the
window procedure is similar to any other window procedure for a custom control.
PMCX architecture
The first convention deals with naming the control and the functions provided
in the PMCX control's DLL. For example, the definition of the initialization
routine is:
XxxxRegister(HAB hAB);
Xxxx is the formal name of the control, and also the name of the dynamic-link
library. Therefore, for a control called Ruler, the initialization routine
would be
RulerRegister(HAB hAB);
and the dynamic-link library name would be
RULER.DLL
This convention, the corner-stone for PMCX, allows Prominare Designer to
interact properly with the PMCX control DLL.
PMCX defines three required public functions:
Function Purpose
XxxxRegister Controls registration routine.
XxxxQuery Controls information query routine used by Prominare Designer
to determine capabilities of the control.
XxxxStyles Control's styles dialogue procedure, used by Prominare Designer
to allow styles, text, ID symbol and value. When included
within a design, controls specific information to be defined
and edited.
A PMCX control must also provide certain resources used by Prominare Designer.
The first resource is a dialogue template used for the XxxxStyles dialogue.
The second resource, although not absolutely required, makes reading resource
script files easier, is a set of entries within a string table. These entries
correspond to the style flags of the PMCX control and are used by Prominare
Designer during resource script generation, allowing the entry for the control
to look exactly like a normal PM control.
ΓòÉΓòÉΓòÉ 5. How it works ΓòÉΓòÉΓòÉ
Given the dual nature of a PMCX control, there is an easy part and a hard part
to the design process. The easy part is how your application interacts with the
control. You only need to use the XxxxRegister function in your application to
register the control with PM; let PM do the rest. If the control is part of a
dialogue template, PM will create the control as thought it were a normal PM
control. It is that simple.
The hard part is how the control interacts with Prominare Designer. This is a
little more complicated, as you have to fill in a structure describing the
control's capabilities to Prominare Designer, as well as create the styles
dialogue.
PMCX defines a set of structures that allow the custom control to pass
information between itself and Prominare Designer. The structures are at all
times controlled by Prominare Designer, which is responsible for allocating and
de-allocating necessary memory for the structures. Only through a callback
routine to Prominare Designer are you allowed to reallocate one area of these
structures--the area containing the variable sized control data. Some of the
structures are used only once, whereas others must be used many times, by both
Prominare Designer and the control. The methods of using the structures within
the control are defined to allow the control to access and update the elements
of the structure. The best place to start is with the header that defines the
structures you will use to interact with Prominare Designer.
ΓòÉΓòÉΓòÉ 6. PMCX Definitions Header - PMCX.H ΓòÉΓòÉΓòÉ
The PMCX definitions header include file, PMCX.H, is used to define constants,
structures, and macros, allowing information to be passed between Prominare
Designer and the custom control. The contents of PMCX.H are shown below.
/* pmcx.h Created: 1993-12-14 Revised: 1994-09-18 */
/* PM Control Extensions (PMCX) */
/* Definitions Header */
/* Consult User's Guide for complete description of PM Control */
/* Extensions */
/* Copyright Γòò 1989-1994 Prominare Inc. All Rights Reserved. */
/* -------------------------------------------------------------------- */
/* Function Prototypes (32-bit definition) */
/* ------------------- */
/* */
/* Control Initialization: */
/* */
/* BOOL EXPENTRY XxxxRegister(HAB hAB); */
/* */
/* Styles Dialogue Procedures: */
/* */
/* MRESULT EXPENTRY XxxxStyles(HWND hWnd, ULONG msg, */
/* MPARAM mp1, MPARAM mp2); */
/* */
/* Window Procedure: */
/* */
/* MRESULT EXPENTRY XxxxWndProc(HWND hWnd, ULONG msg, */
/* MPARAM mp1, MPARAM mp2); */
/* */
/* Control Information Procedure: */
/* */
/* BOOL EXPENTRY XxxxQuery(PUSERINFO pUserInfo); */
/* --- Constant Definitions ------------------------------------------- */
#define CTYPES 1 /* Maximum Number of User Types */
#define CCHCLASS 32 /* Maximum Classname Length */
#define CCHNAME 32 /* Maximum Name Length */
#define CCHAUTHOR 64 /* Maximum Author Name Length */
#define CCHDESC 32 /* Maximum Type Description Length */
#define CCHID 32 /* Maximum ID Symbol Length */
#define CCHTEXTMAX 512 /* Maximum Control Text Length */
#define UTYPE_PRIVATE 0x0002 /* Type: Private */
#define UTYPE_PUBLIC 0x0004 /* Type: Public */
#define USER_CWINDOWWORDS 8UL /* Control Reserved Memory Size */
#define QWW_USER (QWL_USER + 0UL) /* Pointer to User Data */
#define QWW_CDATA (QWL_USER + 4UL) /* Pointer to Private Data Pointer */
#define CUACHK_MNEMONIC 0 /* CUA Check: Mnemonic */
#define CUACHK_CAPS 1 /* CUA Check: Capitalization */
#define CUACHK_ELLIPSIS 2 /* CUA Check: Ellipsis */
#define STYLETYPE_BITFLAGS 0x0001 /* Style Type: Bit Flags */
#define STYLETYPE_SEQUENCE 0x0002 /* Style Type: Sequential */
#define PMCXOPT_NONE 0x00000000UL
#define PMCXOPT_REFRESH 0x00000001UL
#define PMCXOPT_VARICDATA 0x00000002UL
#define PMCXOPT_STYLECHG 0x00000004UL
#define PMCXOPT_TABABLE 0x00000008UL
#define PMCXOPT_HELP 0x00000010UL
/************************************************************************/
/************************************************************************/
/* */
/* PMCX 32-Bit Structure Definitions */
/* */
/************************************************************************/
/************************************************************************/
/* --- User Control Styles Structure ---------------------------------- */
typedef struct _STYLE /* st */
{ /* Size: 8 bytes */
ULONG flStyleMask; /* Style Flag Mask */
ULONG idStyle; /* Resource String ID */
} STYLE ;
/* --- User Control Type Structure ------------------------------------ */
typedef struct _USERTYPE /* ut */
{ /* Size: 348 bytes */
LONG cx; /* Suggested Width of Control */
LONG cy; /* Suggested Height of Control */
ULONG flStyle; /* Initial Style Flags */
ULONG flOptions; /* Options Flag */
ULONG cMaxText; /* Maximum Text Required */
ULONG idDlg; /* Dialog ID */
ULONG idReserved; /* Reserved */
ULONG flStyleType; /* Style Type */
ULONG cCtlData; /* Control Data Count */
ULONG ulType; /* Control Type */
ULONG cMasks; /* Style Masks Count */
CHAR szDescription[CCHDESC];/* Control Name */
STYLE stMasks[32]; /* Style Masks Array */
ULONG aulReserved[4]; /* Reserved */
} USERTYPE ;
/* --- User Control Information Structure ----------------------------- */
typedef struct _USERINFO /* ui */
{ /* Size: 512 bytes */
ULONG ulMajor; /* Control Version Number: Major */
ULONG ulMinor; /* Control Version Number: Minor */
CHAR szAuthor[CCHAUTHOR]; /* Control Author */
CHAR szClassname[CCHCLASS];/* Classname */
CHAR szName[CCHNAME]; /* Library Name */
ULONG aulReserved[6]; /* Reserved */
ULONG cTypes; /* Number of Control Types Supported */
USERTYPE utDefined[CTYPES]; /* Define User Types Array */
} USERINFO ;
typedef USERINFO *PUSERINFO;
/* --- User Control Style Structure ----------------------------------- */
typedef struct _USERSTYLE /* ust */
{ /* Size: 112 bytes */
PFN pfnSetSymbolID; /* Symbol/ID Set Function Address */
PFN pfnGetSymbolID; /* Symbol/ID Get Function Address */
PFN pfnGetFontClr; /* Font/Colours Function Address */
PFN pfnCUACheck; /* CUA Compliance Function Address */
PFN pfnRealloc; /* Reallocation Function Address */
ULONG flStyle; /* Style */
ULONG id; /* ID Value */
CHAR szid[CCHID]; /* ID Symbol */
PSZ pszText; /* Text Pointer */
ULONG cText; /* Text Count (Including NULL) */
PFN pfnGetBidi; /* Bidi Params Function Address */
ULONG aulReserved[8]; /* Reserved */
PBYTE pbCtlData; /* Variable Control Data Pointer */
ULONG cbCtlData; /* Control Data Size */
BYTE abCtlData[1]; /* Control Data */
} USERSTYLE ;
typedef USERSTYLE *PUSERSTYLE;
/* --- Macro Helpers for Setting or Retrieving User Style Pointer ------ */
#define PDATATODLG(hwndClient) ((WinSetWindowPtr(hwndClient, QWL_USER,\
(PVOID)mp2)))
#define PDATAFROMDLG(hwndClient) (((PUSERSTYLE)WinQueryWindowPtr(hwndClient,\
QWL_USER)))
There are a set of constant definitions, provided in the header, that you can
use in your implementation of the PMCX control. They are a mixture of limits,
options, flags, and service requests:
Constant Definition
CTYPES Defines the maximum length of the class name
definition, including null terminating byte.
CCHCLASS Defines the maximum length of the class name
definition, including null terminating byte.
CCHNAME Defines the maximum length of the control's name,
including the null terminating byte.
CCHAUTHOR Defines the maximum length of the author's name for
the control, including null terminating byte.
CCHDESC Defines the maximum length of the control's
description, including the null terminating byte.
CCHID Defines the maximum length of the ID symbol,
including the null terminating byte.
CCHTEXTMAX Defines the maximum length of text that can be
defined for the control, including the null
terminating byte.
UTYPE_PRIVATE Defines the control as a private class; it must be
registered specifically by the application before it
is used. This registration is provided the
XxxxRegister function within the DLL.
UTYPE_PUBLIC Defines the control as a public class that has been
registered with OS/2 Presentation Manager and does
not need to be registered by the application.
USER_CWINDOWWORDS Defines the minimum amount of reserved memory that
must be allocated for the control when it is
registered with OS/2 Presentation Manager. Additional
reserved memory can be allocated by adding the value
to the constant in the XxxxRegister function.
QWW_USER Used as an index into the control's reserved memory,
where the pointer to the user data is located.
QWW_CDATA Used as an index into the control's reserved memory,
where the pointer to the private control data memory
allocated for the control is located.
CUACHK_MNEMONIC Used as an option with the pfnCUACheck function to
check the text of the control for CUA compliance in
terms of mnemonic inclusion.
CUACHK_CAPS Used as an option with the pfnCUACheck function to
check the text of the control for CUA compliance in
terms of capitalization.
CUACHK_ELLIPSIS Used as an option with the pfnCUACheck function to
check the text of the control for CUA compliance in
terms of a space between the text and ellipsis.
STYLETYPE_BITFLAGS Indicates that the style masks are bitflags and that
the style generated in the resource script can be
multiple values when bitwise compared to the style
masks.
STYLETYPE_SEQUENCE Indicates that the style masks are sequential in
nature and that the styles generated within the
resource script should be based on a single value
that must match the style mask.
PMCXOPT_NONE Indicates that no special options are required.
PMCXOPT_REFRESH Indicates that the control should be refreshed
through Prominare Designer, where Prominare Designer
will delete the previous instance of the control and
create a new one to show the revised styles selected.
PMCXOPT_VARICDATA Indicates that the control supports variable length
control data.
PMCXOPT_STYLECHG Indicates that the control supports the changing of
the style flags using the WinSetWindowULong function
and the index of QWL_STYLE.
PMCXOPT_TABABLE Indicates that the control supports tabbing and
cursor movement selections.
PMCXOPT_HELP Indicates that the control allows the help to be
selected when it receives focus.
Four structures are defined within the header. Three are used to describe the
PMCX control to Prominare Designer; the fourth is used by Prominare Designer
to communicate with the styles dialogue:
Name Purpose
STYLE Defines a control style mask and the corresponding
resource file string table ID. Used by the USERTYPE
structure.
USERTYPE Defines the user control type. The information within
the structure is for the default characteristics of
the control, the ID of the dialogue template within
the control's DLL for the styles dialogue, the room
necessary for additional control data (i.e. picture
masks, ranges, limits, etc.), control type, styles
count, and style masks. Used by the USERINFO
structure.
USERINFO Defines information for the control initially queried
by Prominare Designer to determine the capabilities
of the control. The control's version number, author,
class, and types are defined. Used only by the
XxxxQuery function.
USERSTYLE Used by Prominare Designer and the XxxxStyles
functions to allow a method of communication
regarding data information entered or edited through
the dialogue procedure. The structure provides helper
function addresses that can be used to reference the
control's style, ID symbol and value, and text, and
to control specific data.
The STYLE structure is defined as:
Field Purpose
flStyleMask Contains a style flag mask for a possible style of
the control. Should be in the form of 0x0000UL. The
style mask must correspond with a resource string
indicated in the idStyle field.
idStyle Contains the ID of the resource string for the
corresponding style mask in the flStyleMask field.
The following is an example of how the structure is used:
/* Constants definitions within an include header file */
#define EC_NORMALBORDER 0x0001L
#define EC_THICKBORDER 0x0002L
#define EC_NOBORDER 0x0004L
#define IDS_NORMALBORDER 800
#define IDS_THICKBORDER 801
#define IDS_NOBORDER 802
/* Within source code file */
USERTYPE utExample;
utExample.flStyleType = STYLETYPE_BITFLAGS;
utExample.stMasks[0].flStyleMask = EC_NORMALBORDER;
utExample.stMasks[0].idStyle = IDS_NORMALBORDER;
utExample.stMasks[1].flStyleMask = EC_THICKBORDER;
utExample.stMasks[1].idStyle = IDS_THICKBORDER;
utExample.stMasks[2].flStyleMask = EC_NOBORDER;
utExample.stMasks[2].idStyle = IDS_NOBORDER;
/* Within resource script file */
STRINGTABLE
BEGIN
IDS_NORMALBORDER, "EC_NORMALBORDER"
IDS_THICKBORDER, "EC_THICKBORDER"
IDS_NOBORDER, "EC_NOBORDER"
END
The USERTYPE structure is defined as:
Field Purpose
cx Contains the suggested width of the control in
dialogue units. This value will be used by Prominare
Designer as the initial width of the control when it
is added to a window or dialogue.
cy Contains the suggested height of the control in
dialogue units. This value will be used by Prominare
Designer as the initial height of the control when it
is added to a window or dialogue.
flStyle Contains initial style flags of the control when it
is created by Prominare Designer.
flOptions Contains the options flag, which can be one of the
PMCXOPT_* flags.
cMaxText Contains the maximum number of characters that the
control is capable of handling. This value is used by
Prominare Designer to allocate space for the control
text addressed in the pszText field in the USERSTYLE
structure.
idDlg Contains the resource ID of the styles dialogue
displayed by Prominare Designer when the control is
first added to a window or dialogue or when the user
requests to edit the styles of the control.
idReserved Reserved.
flStyleType Contains the style type flag that indicates to
Prominare Designer how the style masks should be
interpreted when the resource script statement for
the control is generated. The current style types
defined are STYLETYPE_BITFLAGS for bitflag styles and
STYLETYPE_SEQUENCE for sequential styles.
cCtlData Contains the number of bytes that should be allocated
for private data used by the control. This data is
allocated by Prominare Designer and is addressed in
the abCtlData field in the USER_STYLE structure.
ulType Contains the control type, which may be either
UTYPE_PRIVATE or UTYPE_PUBLIC.
cMasks Contains the total count of style masks defined in
stMasks field.
szDescription[CCHDESC] Contains a short description that can be displayed by
Prominare Designer.
stMasks[32] Contains the control style flag masks and ID string
values.
aulReserved[4] Reserved.
The following is an example of how the structure is used:
USERTYPE utDefined;
utDefined.cx = 50L;
utDefined.cy = 12L;
utDefined.flStyle = 0UL;
utDefined.idDlg = Dialogue id;
utDefined.ulType = UTYPE_PRIVATE;
utDefined.cCtlData = 20UL;
utDefined.cMasks = 2UL;
utDefined.cMaxText = 5UL;
utdefined.flStyleType = STYLETYPE_BITFLAGS;
utDefined.stMasks[0].flStyleMask = 0x0001UL;
utDefined.stMasks[0].idStyle = String id;
utDefined.stMasks[1].flStyleMask = 0x0002UL;
utDefined.stMasks[1].idStyle = String id;
strcpy(utDefined.szDescription, "Description");
The USERINFO structure is defined as:
Field Purpose
ulMajor Contains the control's major version number.
ulMinor Contains the control's minor version number.
szAuthor[CCHAUTHOR] Contains the control's author name.
szClassname[CCHCLASS] Contains the classname of the control.
szName[CCHNAME] Contains the common name for the control. This name
should correspond to the Xxxx component of the
required functions as well as to the dynamic-link
library name.
aulReserved[6] Reserved.
cTypes Contains the number of types supported by the
control. In Version 1.0 of PMCX, only one type is
allowed and this field must be 1.
utDefined[CTYPES] Contains the type information of each of the controls
supported by the control. In Version 1.0 of PMCX,
only the first array element is used.
The following is an example of how the structure is used:
USERINFO uiControl;
uiControl.ulMajor = 1UL;
uiControl.ulMinor = 0UL;
uiControl.cTypes = 1UL;
strcpy(uiControl.szAuthor, "Author");
strcpy(uiControl.szClassname, "Classname");
strcpy(uiControl.szName, "Common Name");
uiControl.utDefined[0].cx = 50L;
uiControl.utDefined[0].cy = 12L;
uiControl.utDefined[0].flStyle = 0UL;
uiControl.utDefined[0].idDlg = Dialogue id;
uiControl.utDefined[0].ulType = UTYPE_PRIVATE;
uiControl.utDefined[0].cCtlData = 20UL;
uiControl.utDefined[0].cMasks = 2UL;
uiControl.utDefined[0].cMaxText = 5UL;
uiControl.utDefined[0].flStyleType = STYLETYPE_BITFLAGS;
uiControl.utDefined[0].stMasks[0].flStyleMask = 0x0001UL;
uiControl.utDefined[0].stMasks[0].idStyle = String id;
uiControl.utDefined[0].stMasks[1].flStyleMask = 0x0002UL;
uiControl.utDefined[0].stMasks[1].idStyle = String id;
strcpy(uiControl.utDefined[0].szDescription, "Description");
The USERSTYLE structure is defined as:
Field Purpose
pfnSetSymbol Contains the function address for the function in
Prominare Designer that sets the ID field symbol and
value.
pfnGetSymbol Contains the function address for the function in
Prominare Designer that causes the ID field symbol
and value to be validated and placed within the
USERSTYLE structure.
pfnGetFontClr Contains the function address for the Font & Colours
dialogue. Prominare Designer internally records the
font and colours selected by the user on behalf of
the control.
pfnCUACheck Contains the function address for the CUA Compliance
checking function. Compliance for mnemonics,
capitalization, and ellipsis can be checked via this
function if the control supports any of these
features. A value of TRUE is returned if
non-compliance is determined. A value of FALSE is
returned if the control is compliant.
pfnRealloc Contains the function address for the control data
reallocation function, which allows the control to
reallocate the necessary control data memory when it
supports variable control data.
flStyle Contains the current style flags set for the control.
id Contains the current ID value for the control.
szid[CCHID] Contains the current ID symbol for the control.
pszText Contains the address of the text for the control.
cText Contains the count of characters for the control.
pfnGetBidi Contains the function address for the Bidirectional
Support dialogue. Prominare Designer internally
records the bidirectional options selected by the
user on behalf of the control.
aulReserved[8] Reserved.
pbCtlData Contains the variable control data buffer pointer.
Used only when the control supports variable control
data; used in place of the abCtlData field.
cbCtlData Contains the size of the control data buffer
pbCtlData when the control supports variable control
data.
abCtlData[1] First element of the private control data. When
control data is used, the control should cast the
appropriate structure to the address of the array, so
it can easily address areas of the data.
Two helper macros are defined in the header:
Macro Purpose
PDATATODLG Places the passed address of the USERSTYLE pointer in
the dialogue's reserved memory. The passed address is
contained within the second message parameters
(MPARAM mp2) and must be placed in the dialogue's
reserved memory when it receives the WM_INITDLG
message.
PDATAFROMDLG References the memory location in the dialogue
procedure where the USERSTYLE pointer passed to the
dialogue is placed. A pointer returned by the macro
allows reference to the elements of the USERSTYLE
structure.
ΓòÉΓòÉΓòÉ 7. PMCX construction ΓòÉΓòÉΓòÉ
The first item of concern is the naming convention. The best way to illustrate
this is by considering the example below:
Functions
XxxxRegister
XxxxQuery
XxxxStyles
Dynamic-Link Library
Xxxx.DLL
Xxxx is the common name for the control. (The common name should be restricted
to eight letters to allow for FAT disk systems unless it is to be used
specifically with HPFS disk systems.) The common name is allowed to be a
maximum of 32 bytes long, including the NULL terminating character; the szName
field of the USERINFO structure will accept only that number of characters.
The second item of concern is who is responsible for allocating and
de-allocating memory for the structures. Prominare Designer allocates and
de-allocates the necessary memory for structures used to communicate with the
PMCX control. It provides a pointer to the memory address of the structure and
to the function when communication is required. It is the responsibility of
the PMCX control's style function to save the address of the structure. Any
pointers to memory elements within the structures are also allocated and
deallocated by Prominare Designer on behalf of the control.
The only exception is in the case of a control that allows for variable length
control data. In this case, the control can, through a callback function to
Prominare Designer, reallocate the control data memory.
Since the PMCX control's dialogue procedure is responsible for saving the
address of the USERSTYLE structure address passed to it by Prominare Designer,
you can use the two helper macros defined by the styles dialogue procedure to
save and retrieve the address. To save the USERSTYLE structure address in the
QWL_USER reserved memory location of the dialogue's reserved memory, use the
PDATATODLG macro. To retrieve the USERSTYLE structure address, use
PDATAFROMDLG macro.
To ensure the success of any PMCX control, you must encapsulate its use to
permit multiple usage, which means that the control must be totally
re-entrant. One way to do this is with dynamically allocated memory. Save
this memory address within the control's reserved memory. These addresses can
be referenced with the QWW_* indices. Prominare Designer provides a set of
helper functions for the control's style dialogue, which ensure that the
dialogue remains consistent with similar dialogues provided with Prominare
Designer. These helper functions must give the control's dialogue access to
the ID field, the Font & Colours dialogue, symbol verification, and CUA
compliance. Prominare Designer must provide the addresses of these routines
within the USERSTYLE structure in the following elements:
Callback Purpose
pfnSetSymbol ID field symbol and value set helper function
pfnGetSymbol Symbol ID and value validation and retrieval helper
function
pfnGetFontClr Font and colours helper function
pfnCUACheck CUA Compliance helper function
pfnRealloc Memory reallocation function similar to C library
function realloc( )
Prominare Designer constructs the necessary statements in the resource script
on behalf of the PMCX control. In turn, the control must provide style masks
and a string table containing the ASCII style definitions in its resources, if
styles are permitted for the control. The style masks and ID values for the
string that corresponds to the style masks are to be placed in the provided
structure elements of the USERINFO structure, along with the count of masks.
The control must also provide the number of control data bytes it requires
through the USERINFO structure. This structure must be completed in the
function XxxxQuery, through the structure address passed to the function when
it is called by Prominare Designer.
The functions defined for the control must be exported in the controls
definition file. The name of the function should be entered along with an
ordinal value. The following ordinals are required:
Function Ordinal
XxxxRegister 1
XxxxQuery 2
XxxxStyles 3
The following describes the use of each of the required functions of the PMCX
control.
ΓòÉΓòÉΓòÉ 7.1. XxxxRegister ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 7.1.1. Purpose ΓòÉΓòÉΓòÉ
The XxxxRegister function is used to register a private control with OS/2
Presentation Manager. It is also used to provide any control specific
initialization.
ΓòÉΓòÉΓòÉ 7.1.2. Prototype Definition ΓòÉΓòÉΓòÉ
BOOL EXPENTRY XxxxRegister(HAB hAB);
ΓòÉΓòÉΓòÉ 7.1.3. Upon entry ΓòÉΓòÉΓòÉ
hAB contains the calling application's anchor block handle. When the control is
a UTYPE_PRIVATE, the function must register the control with OS/2 Presentation
Manager using the WinRegisterClass function, as follows:
WinRegisterClass(hAB, pszClassname, XxxxWndProc,
CS_CLIPSIBLINGS | CS_SYNCPAINT | CS_SIZEREDRAW,
USER_CWINDOWWORDS);
Additional memory can be reserved for the control by adding the required value
to the USER_CWINDOWWORDS constant. Additional class styles can also be defined
for the control. The pszClassname must contain the classname of the control and
be consistent with the value placed in the USERINFO structure element
szClassname in the XxxxQuery function. The control can use other style flags
as is appropriate.
ΓòÉΓòÉΓòÉ 7.1.4. Upon exit ΓòÉΓòÉΓòÉ
XxxxRegister must return a value of TRUE, denoting successful registration of
the control with OS/2 Presentation Manager. A returned value of FALSE indicates
that the control could not be registered and therefore should not be used.
ΓòÉΓòÉΓòÉ 7.2. XxxxQuery ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 7.2.1. Purpose ΓòÉΓòÉΓòÉ
The XxxxQuery function is called by Prominare Designer to determine the
capabilities of the control and to receive information critical to its
successful use within Prominare Designer. The USERINFO structure is completed
through this function, in which Prominare Designer passes the function the
address of the structure.
ΓòÉΓòÉΓòÉ 7.2.2. Prototype Definition ΓòÉΓòÉΓòÉ
BOOL EXPENTRY XxxxQuery (PUSERINFO pUserInfo);
ΓòÉΓòÉΓòÉ 7.2.3. Upon entry ΓòÉΓòÉΓòÉ
pUserInfo contains the address of the USERINFO structure allocated within
Prominare Designer in which the XxxxQuery function can complete. The
information placed within the structure is done as follows:
pUserInfo->ulMajor = 1UL;
pUserInfo->ulMinor = 0UL;
pUserInfo->cTypes = 1UL;
strcpy(pUserInfo->szAuthor, "Author");
strcpy(pUserInfo->szClassname, "Classname");
strcpy(pUserInfo->szName, "Common Name");
pUserInfo->utDefined[0].cx = 50L;
pUserInfo->utDefined[0].cy = 12L;
pUserInfo->utDefined[0].flStyle = 0UL;
pUserInfo->utDefined[0].idDlg = Dialogue id;
pUserInfo->utDefined[0].ulType = UTYPE_PRIVATE;
pUserInfo->utDefined[0].cCtlData = 20UL;
pUserInfo->utDefined[0].cMasks = 2UL;
pUserInfo->utDefined[0].cMaxText = 5UL;
pUserInfo->utDefined[0].flStyleType = STYLETYPE_BITFLAGS;
pUserInfo->utDefined[0].stMasks[0].flStyleMask = 0x0001UL;
pUserInfo->utDefined[0].stMasks[0].idStyle = String id;
pUserInfo->utDefined[0].stMasks[1].flStyleMask = 0x0002UL;
pUserInfo->utDefined[0].stMasks[1].idStyle = String id;
strcpy(pUserInfo->utDefined[0].szDescription, "Description");
ΓòÉΓòÉΓòÉ 7.2.4. Upon exit ΓòÉΓòÉΓòÉ
XxxxQuery must return a value of TRUE, denoting successful completion of the
structure. A returned value of FALSE indicates that the structure was not
completed and the control therefore should not be used.
ΓòÉΓòÉΓòÉ 7.3. XxxxStyles ΓòÉΓòÉΓòÉ
ΓòÉΓòÉΓòÉ 7.3.1. Purpose ΓòÉΓòÉΓòÉ
The XxxxStyles function is the PMCX control's style dialogue used through
Prominare Designer.
ΓòÉΓòÉΓòÉ 7.3.2. Prototype Definition ΓòÉΓòÉΓòÉ
MRESULT EXPENTRY XxxxStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
ΓòÉΓòÉΓòÉ 7.3.3. Upon entry ΓòÉΓòÉΓòÉ
Normal dialogue procedure coding except as noted in Special Considerations.
below.
ΓòÉΓòÉΓòÉ 7.3.4. Upon exit ΓòÉΓòÉΓòÉ
XxxxStyles should return values consistent with normal dialogue procedures.
ΓòÉΓòÉΓòÉ 7.3.5. Special considerations ΓòÉΓòÉΓòÉ
During the processing of the WM_INITDLG message, the control should reference
message parameter 2 (MPARAM mp2) as follows: PDATATODLG(hWnd);
This causes the address of the USERSTYLE structure allocated within Prominare
Designer to be saved in the dialogue's reserved memory. The dialogue can then
reference the information in the USERSTYLE structure with the following method:
pust = PDATAFROMDLG(hWnd);
Also, the entry fields for the dialogue along with any styles should be
completed during processing of the WM_INITDLG message. For example, with a
control that supported text, the following could be used to fill in the Text
and ID fields:
if ( (pust = (PUSERSTYLE)mp2) != NULL )
{
WinSetDlgItemText(hWnd, ID_TEXT, pust->szText);
pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust);
}
When the dialogue is dismissed, the function must return either TRUE through
the WinDismissDlg function, to indicate to Prominare Designer changes have been
made to the USERSTYLE structure, or FALSE, to indicate that no changes were
made.
The USERSTYLE structure contains the addresses of the five Prominare Designer
helper routines, defined as follows:
VOID (EXPENTRY *pfnSetSymbolID)(HWND hWnd, ULONG idSymbol, PUSERSTYLE
pust);
BOOL (EXPENTRY *pfnGetSymbolID)(HWND hWnd, ULONG idSymbol, PUSERSTYLE
pust);
VOID (EXPENTRY *pfnGetFontClr)(HWND hWnd);
BOOL (EXPENTRY *pfnCUACheck)(HWND hWnd, ULONG idEntryField, LONG
iCUACompliance);
BOOL (EXPENTRY *pfnRealloc)(PVOID pv, INT cSize);
In this case, you would use the pfnSetSymbol in conjunction with the ID field.
The function is used to set the symbol and value of the control within the ID
field, as shown here:
if ( (pust = (PUSERSTYLE)mp2) != NULL )
pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust);
The pfnGetFontClr function allows the user to display the Font & Colours
dialogue when he or she clicks on the Font & colours... button. The function
allows the user to set the font and colours for the control, as shown here:
case WM_COMMAND :
switch ( SHORT1FROMMP(mp1) )
{
case ID_FONTCLR :
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
pust->pfnGetFontClr(hWnd);
break;
.
.
.
}
break;
The pfnGetBidi function allows the user to display the Bidirectional Support
dialogue when he or she clicks on the Bidi... button. The function allows the
user to set the bidirectional options as shown here:
case WM_COMMAND :
switch ( SHORT1FROMMP(mp1) )
{
case ID_BIDI :
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
pust->pfnGetBidi(hWnd);
break;
.
.
.
}
break;
Use the pfnGetSymbol function when the user tells the dialogue to accept the
changes made. The function checks the values in the ID field for validity and
displays any required error message boxes. If the function returns a value of
FALSE, the dialogue procedure should not retrieve any changes made but should
simply break the current processing, allowing the user to correct values
within the dialogue as he or she sees fit. A return value of TRUE indicates
that the dialogue should retrieve all changes made and save them in the
USERSTYLE structure before dismissing the dialogue. The function also
retrieves the ID symbol and value and places them in the USERSTYLE structure,
as shown here:
case WM_COMMAND :
switch ( SHORT1FROMMP(mp1) )
{
case DID_OK :
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
if ( !pust->pfnGetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust) )
{
.
. /* Continue processing */
.
WinDismissDlg(hWnd, TRUE);
}
break;
.
.
.
}
break;
Use the pfnCUACheck function when the user tells the dialogue to accept the
changes made. Depending on the option selected, the function checks the values
in the Text entry field for CUA compliance and displays any required error
message boxes. If the function returns a value of FALSE, the dialogue
procedure should not retrieve any changes made but should simply break the
current processing, allowing the user to correct values in the dialogue as he
or she sees fit. A return value of TRUE indicates that the dialogue should
retrieve all changes made, saving them in the USERSTYLE structure before
dismissing the , as shown here:
case WM_COMMAND :
switch ( SHORT1FROMMP(mp1) )
{
case DID_OK :
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
if ( pust->pfnCUACheck(hWnd, ID_TEXT, CUACHK_CAPS) )
break;
else
{
. /* Continue processing */
.
.
WinDismissDlg(hWnd, TRUE);
}
break;
.
.
}
break;
Finally, use the pfnRealloc function when the control allows variable-length
control data and the user has indicated a wish to save the information for the
control. You must use the function to reallocate the data buffer for the
control data, since Prominare Designer controls memory allocation for the
structures. The function utilizes the memory management routines of Prominare
Designer; care must therefore be exercised so the function is not misused.
Otherwise, Prominare Designer may develop a fatal unrecoverable error
condition. The function is exactly like the C library realloc( ) function in
usage. It is shown here:
case WM_COMMAND :
switch ( SHORT1FROMMP(mp1) )
{
case DID_OK :
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
{
if ( !(pust->pbCtlData =
(PBYTE)pust->pfnRealloc(pust->pbCtlData,
sizeof(COMBOBOXCDATA) - 1L)) )
{
WinMessageBox(HWND_DESKTOP, hWnd,
"Memory error on reallocating control data!",
"Super Combo Box Control", 0,
MB_OK | MB_ICONEXCLAMATION);
return(0L);
}
pust->cbCtlData = sizeof(COMBOBOXCDATA) - 1 + n;
pcbd = (PCOMBOBOXCDATA)pust->pbCtlData;
pcbd->cb = sizeof(COMBOBOXCDATA) - 1 + n;
pcbd->cItems = cItems;
memcpy(pcbd->abList, pchData, n);
}
break;
.
.
}
break;
ΓòÉΓòÉΓòÉ 8. DLL construction ΓòÉΓòÉΓòÉ
To correctly construct a custom control according to the PMCX, use the
following outline:
File Contents
PMCX.H PMCX constants, macros, and structure definitions.
This file is provided with the Prominare Designer
package and can be found in the PD\Include
sub-directory.
Xxxx.Lnk Contains the link response file needed by the linker.
Xxxx.C Contains source code for the custom code using PMCX.
Xxxx.Def Contains the definition statements required by the
linker to construct the final dynamic link library.
Xxxx.Mak Contains the MAKE file necessary to create the object
and resource files.
Xxxx.Rc Contains the resource script file with the control's
style dialogue template and styles string table.
ΓòÉΓòÉΓòÉ 9. Example control ΓòÉΓòÉΓòÉ
Following are listings of an example control provided with the Prominare
Designer package. It is shown here to help you understand the construction of a
PMCX control. A check mark control that allows the usage of a static control to
denote if an option is selected or available, it is similar to a check box
control except that the user does not interact with it. The final check mark
styles dialogue is shown here:
PMCX control Check Mark Styles dialogue
The check mark control created and managed by the PMCX control DLL appears as:
Check mark control appearance
The following example control code shows the necessary methods defined by PMCX
to successfully create a custom control that can be used within your own
applications and Prominare Designer.
#pragma title("Check Mark Control -- Version 1.00 -- (ChkMark.C)")
#pragma subtitle(" Check Mark Control Control DLL - Interface Definitions")
#pragma info(noext)
#define INCL_GPI /* Include OS/2 PM GPI Interface */
#define INCL_WIN /* Include OS/2 PM Windows Interface */
static char *MODID = "@(#)chkmark.c:1.02";
#include <os2.h>
#include <string.h>
#include <pmcx.h>
#include "chkmark.h"
/* This module contains an example installable control that can be used */
/* within applications where additional facilities are provided that */
/* are not found within the default controls of OS/2 PM. */
/* */
/* For complete details regarding the PM Control Extensions (PMCX) */
/* consult the User's Guide. */
/* */
/* The DLL is created using the following command line invocation: */
/* */
/* Icc -G3e- -O+ -Rn -W3 -C ChkMark.C */
/* Filename: ChkMark.C */
/* Version: 1.00 */
/* Created: 1993-12-21 */
/* Revised: 1994-09-18 */
/* Routines: BOOL EXPENTRY ChkMarkRegister(HAB hAB); */
/* BOOL EXPENTRY ChkMarkQuery(PUSERINFO pUserInfo); */
/* MRESULT EXPENTRY ChkMarkWndProc(HWND hWnd, ULONG msg, */
/* MPARAM mp1, MPARAM mp2); */
/* MRESULT EXPENTRY ChkMarkStyles(HWND hWnd, ULONG msg, */
/* MPARAM mp1, MPARAM mp2); */
/* Copyright Γòò 1989-1994 Prominare Inc. All Rights Reserved. */
/* -------------------------------------------------------------------- */
/************************************************************************/
/************************************************************************/
/* DISCLAIMER OF WARRANTIES. */
/************************************************************************/
/************************************************************************/
/* The following [enclosed] code is library code created by */
/* Prominare Inc. This library code is provided to you solely */
/* for the purpose of assisting you in the development of your */
/* applications. The code is provided "AS IS", without */
/* warranty of any kind. Prominare Inc. shall not be liable */
/* for any damages arising out of your use of the library code, */
/* even if they have been advised of the possibility of such */
/* damages. */
/************************************************************************/
/************************************************************************/
/* --- Control Data Structures ---------------------------------------- */
typedef struct _CHECKMARK /* cmrk */
{
HWND hwndOwner; /* Owner Window Handle */
CHAR szText[512]; /* Text Holder */
BOOL fChecked; /* Check Mark State Flag */
RECTL rclChecked; /* Bitmap Rectangle Checked */
RECTL rclUnChecked; /* Bitmap Rectangle UnChecked */
POINTL ptlChkMark; /* Bitmap Rectangle UnChecked */
POINTL ptlText; /* Text Display Point */
RECTL rclText; /* Text Display Rectangle */
RECTL rcl; /* Bitmap Display Rectangle */
HBITMAP hbm; /* Check Mark Bitmap Handle */
LONG aClr[7]; /* Presentation Colours Array */
} CHECKMARK ;
typedef CHECKMARK *PCHECKMARK;
/* --- Module Prototype Definitions ----------------------------------- */
static VOID SetDefaultColours(HWND hWnd, PCHECKMARK pcmrk);
static LONG lGetPresParam(HWND hWnd, ULONG ulID1, ULONG ulID2, LONG lDefault);
BOOL EXPENTRY ChkMarkRegister(HAB hAB);
BOOL EXPENTRY ChkMarkQuery(PUSERINFO pUserInfo);
MRESULT EXPENTRY ChkMarkWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
MRESULT EXPENTRY ChkMarkStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
#define CLENpszClassname 10
static PSZ pszClassname = "CheckMark";
static HMODULE hmodDLL;
#pragma subtitle(" Check Mark Control - DLL Initialization/Termination Procedure")
#pragma page( )
/* --- _Dll_InitTerm ----------------------------------- [ Public ] --- */
/* */
/* This function is used to provide the DLL initialization and */
/* termination. The function is called by the C startup code */
/* and allows the control to register itself and provide any */
/* necessary startup. */
/* */
/* This function is designed for IBM C Set/2 Version 1.0 and */
/* IBM C Set++ Version 2.x */
/* */
/* Upon Entry: */
/* */
/* ULONG hModule; = DLL Module Handle */
/* ULONG fl; = Startup / Termination Flag */
/* */
/* Upon Exit: */
/* */
/* _Dll_InitTerm = 0 : Error Return */
/* = 1 : Successful Startup / Termination */
/* */
/* -------------------------------------------------------------------- */
ULONG _System _Dll_InitTerm(ULONG hModule, ULONG fl)
{
/* Determine if in startup or termination mode */
if ( fl == 0 )
/* DLL being initialized, save the DLL module */
/* handle to allow the bitmap loading routines */
/* routines a means of loading the default */
/* bitmaps when required */
hmodDLL = hModule;
return(1UL);
}
#pragma subtitle(" Check Mark Control DLL - Control Initialization Function")
#pragma page ( )
/* --- ChkMarkInit ------------------------------------- [ Public ] --- */
/* */
/* This function is used to register the installable control class */
/* with OS/2 Presentation Manager. The registration must use the */
/* USER_CWINDOWWORDS to reserve memory for the control to allow for */
/* proper usage by Resource Editor and for use by the control */
/* dialog and window procedures. The information for the control */
/* containing the style, Font & Colours and control data */
/* is pointed to by a pointer that can be referenced by the */
/* control's dialog and window procedure as required. The memory */
/* for the structure is allocated and controlled through Resource */
/* Editor. The control can reserve more memory for its use */
/* by adding the memory required to that of the USER_CWINDOWWORDS */
/* constant. */
/* */
/* Upon Entry: */
/* */
/* HAB hAB; = Application Anchor Block Handle */
/* */
/* Upon Exit: */
/* */
/* ChkMarkInit = TRUE : Class Registration Successful */
/* = FALSE : Class Registration Failed */
/* */
/* -------------------------------------------------------------------- */
BOOL EXPENTRY ChkMarkRegister(HAB hAB)
{
/* Register the control class with OS/2 */
/* Presentation Manager and return registration */
/* result */
return(WinRegisterClass(hAB, pszClassname, ChkMarkWndProc,
CS_SYNCPAINT | CS_SIZEREDRAW, USER_CWINDOWWORDS));
}
#pragma subtitle(" Check Mark Control DLL - Query Control Information Function")
#pragma page ( )
/* --- ChkMarkQuery ------------------------------------ [ Public ] --- */
/* */
/* This function is used to return to the caller information */
/* regarding the installable control and its capabilities. The */
/* function should return a true value otherwise Resource */
/* Editor will not register the control as being usable. */
/* */
/* Upon Entry: */
/* */
/* PUSERINFO pUserInfo; = User Information Pointer */
/* */
/* Upon Exit: */
/* */
/* ChkMarkQuery = TRUE : User Information Being Returned */
/* = FALSE : No User Information Available */
/* */
/* -------------------------------------------------------------------- */
BOOL EXPENTRY ChkMarkQuery(PUSERINFO pUserInfo)
{
/* Complete the User Information structure */
/* passed to the function by Resource Editor */
/* Complete the version and number of control */
/* types. In Version 1.00 of CCRS, only one */
/* control type is used. */
pUserInfo->ulMajor = 2UL;
pUserInfo->ulMinor = 0UL;
/* Complete the author and control classname */
memcpy(pUserInfo->szAuthor, "Prominare Inc.", 15);
memcpy(pUserInfo->szClassname, pszClassname, CLENpszClassname);
memcpy(pUserInfo->szName, "ChkMark", 8);
/* Complete the default size and style of the */
/* first user control type */
pUserInfo->utDefined[0].cx = 25L;
pUserInfo->utDefined[0].cy = 10L;
pUserInfo->utDefined[0].flStyle = WS_VISIBLE;
/* Set the maximum amount of text control can */
/* accept including NULL termination byte */
pUserInfo->utDefined[0].cMaxText = CCHTEXTMAX;
/* Save the style's dialogue ID, type, control */
/* data size and count of style masks */
pUserInfo->utDefined[0].idDlg = DLG_CTRLUSER;
pUserInfo->utDefined[0].flOptions = PMCXOPT_REFRESH;
pUserInfo->utDefined[0].ulType = UTYPE_PRIVATE;
pUserInfo->utDefined[0].cCtlData = 0UL;
pUserInfo->utDefined[0].cMasks = 1UL;
pUserInfo->utDefined[0].flStyleType = STYLETYPE_BITFLAGS;
pUserInfo->utDefined[0].stMasks[0].flStyleMask = CMS_CHECKED;
pUserInfo->utDefined[0].stMasks[0].idStyle = IDS_CMS_CHECKED;
/* Save the description of the control */
memcpy(pUserInfo->utDefined[0].szDescription, "Check Mark", 11);
/* Return the success flag back to Resource */
/* Editor */
return(TRUE);
}
#pragma subtitle(" Check Mark Control DLL - Control Window Procedure")
#pragma page( )
/* --- lGetPresParam ---------------------------------- [ Private } --- */
/* */
/* This function is used to retrieve a Font & Colours */
/* that may be present. If the Font & Colours is not, */
/* the default colour passed to the function will be used. */
/* */
/* Upon Entry: */
/* */
/* HWND hWnd; = Window Handle */
/* ULONG ulID1; = Font & Colours 1 ID */
/* ULONG ulID2; = Font & Colours 2 ID */
/* LONG lDefault; = Default Colour */
/* */
/* Upon Exit: */
/* */
/* lGetPresParam = Colour to Use */
/* */
/* -------------------------------------------------------------------- */
LONG lGetPresParam(HWND hWnd, ULONG ulID1, ULONG ulID2, LONG lDefault)
{
HPS hPS; /* Presentation Space Handle */
LONG lClr; /* Font & Colours Colour */
ULONG ulID; /* Font & Colours ID */
if ( WinQueryPresParam(hWnd, ulID1, ulID2, &ulID, 4UL, (PVOID)&lClr,
QPF_NOINHERIT | QPF_ID2COLORINDEX | QPF_PURERGBCOLOR) )
return(lClr);
else
if ( (lDefault >= SYSCLR_SHADOWHILITEBGND) &&
(lDefault <= SYSCLR_HELPHILITE) )
return(WinQuerySysColor(HWND_DESKTOP, lDefault, 0L));
else
if ( (lClr = GpiQueryRGBColor(hPS = WinGetPS(hWnd),
LCOLOPT_REALIZED, lDefault)) == GPI_ALTERROR )
{
WinReleasePS(hPS);
return(lDefault);
}
else
{
WinReleasePS(hPS);
return(lClr);
}
}
#pragma subtitle(" Check Mark Control DLL - Default Colours Procedure")
#pragma page( )
/* --- SetDefaultColours ------------------------------ [ Private ] --- */
/* */
/* This function is used to set the default colours that the */
/* image button should use within the internal paint routines. */
/* The colour can either be a Font & Colours that has */
/* been set or it can be the default colour as defined within */
/* control. */
/* */
/* Upon Entry: */
/* */
/* HWND hWnd; = Window Handle */
/* PCHECKMARK pcmrk; = Check Mark Structure Pointer */
/* */
/* Upon Exit: */
/* */
/* Nothing */
/* */
/* -------------------------------------------------------------------- */
static VOID SetDefaultColours(HWND hWnd, PCHECKMARK pcmrk)
{
/* Set up the colours that will be used within */
/* the painting of the control. The colour */
/* indices are: */
/* */
/* 0 : Foreground (PP_FOREGROUND*) */
/* 1 : Background (PP_BACKGROUND*) */
/* 2 : Hilight Foreground (PP_HILITEFOREGROUND*) */
/* 3 : Hilight Background (PP_HILITEBACKGROUND*) */
/* 4 : Disabled Foreground (PP_DISABLEDFORE*) */
/* 5 : Disabled Foreground (PP_DISABLEDFORE*) */
/* 6 : Border (PP_BORDER*) */
pcmrk->aClr[0] = lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
PP_FOREGROUNDCOLORINDEX,
SYSCLR_OUTPUTTEXT);
pcmrk->aClr[1] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
PP_BACKGROUNDCOLORINDEX,
SYSCLR_FIELDBACKGROUND);
pcmrk->aClr[2] = lGetPresParam(hWnd, PP_HILITEFOREGROUNDCOLOR,
PP_HILITEFOREGROUNDCOLORINDEX,
SYSCLR_OUTPUTTEXT);
pcmrk->aClr[3] = lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
PP_HILITEBACKGROUNDCOLORINDEX,
SYSCLR_BACKGROUND);
pcmrk->aClr[4] = lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
PP_DISABLEDFOREGROUNDCOLORINDEX,
SYSCLR_OUTPUTTEXT);
pcmrk->aClr[5] = lGetPresParam(hWnd, PP_DISABLEDBACKGROUNDCOLOR,
PP_DISABLEDBACKGROUNDCOLORINDEX,
SYSCLR_BACKGROUND);
pcmrk->aClr[6] = lGetPresParam(hWnd, PP_BORDERCOLOR,
PP_BORDERCOLORINDEX,
SYSCLR_BUTTONDARK);
}
#pragma subtitle(" Check Mark Control DLL - Display Point Calculation Procedure")
#pragma page ( )
/* --- CalcDisplayPoints ------------------------------ [ Private ] --- */
/* */
/* This function is used to calculate the display points for the */
/* installed control. */
/* */
/* Upon Entry: */
/* */
/* PCHECKMARK pcmrk; = Control Data Structure Pointer */
/* LONG cx; = control Width */
/* LONG cy; = Control Height */
/* */
/* Upon Exit: */
/* */
/* Nothing */
/* */
/* -------------------------------------------------------------------- */
static VOID CalcDisplayPoints(HWND hWnd, PCHECKMARK pcmrk, LONG cx, LONG cy)
{
BITMAPINFOHEADER bmp; /* Bitmap Information Holder */
HPS hPS; /* Presentation Space Handle */
FONTMETRICS fm; /* Font Metrics */
GpiQueryBitmapParameters(pcmrk->hbm, &bmp);
GpiQueryFontMetrics(hPS = WinGetPS(hWnd), sizeof(FONTMETRICS), &fm);
WinReleasePS(hPS);
pcmrk->rclChecked.xRight = bmp.cx;
pcmrk->rclChecked.xLeft = (bmp.cx = (USHORT)(bmp.cx / 2));
pcmrk->rclUnChecked.xRight = bmp.cx;
pcmrk->rclChecked.yTop = pcmrk->rclUnChecked.yTop = bmp.cy;
pcmrk->ptlChkMark.y = cy / 2L - bmp.cy / 2L;
pcmrk->ptlText.x = bmp.cx + fm.lAveCharWidth / 2L;
pcmrk->ptlText.y = (cy / 2L) - (fm.lMaxBaselineExt / 2L) + fm.lMaxDescender;
pcmrk->rclText.xLeft = bmp.cx;
pcmrk->rclText.xRight = cx;
pcmrk->rclText.yTop = cy;
pcmrk->rcl.xRight = cx;
pcmrk->rcl.yTop = cy;
}
#pragma subtitle(" Check Mark Control DLL - 3D Text Window Procedure")
#pragma page ( )
/* --- ChkMarkWndProc --------------------------------- [ Private ] --- */
/* */
/* This function is used to handle the messages sent to the */
/* installed control. The window procedure is designed to */
/* allow for multiple instances and to be totally re-entrant. */
/* */
/* Upon Entry: */
/* */
/* HWND hWnd; = Window Handle */
/* ULONG msg; = PM Message */
/* MPARAM mp1; = Message Parameter 1 */
/* MPARAM mp2; = Message Parameter 2 */
/* */
/* Upon Exit: */
/* */
/* ChkMarkWndProc = Message Handling Result */
/* */
/* -------------------------------------------------------------------- */
MRESULT EXPENTRY ChkMarkWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
HPS hPS; /* Presentation Space Handle */
PCREATESTRUCT pcrst; /* Create Structure Pointer */
PCHECKMARK pcmrk; /* Check Mark Structure Pointer */
PWNDPARAMS pwprm; /* Window Parameters Pointer */
switch ( msg )
{
/* Perform control initialization when the */
/* control is created */
case WM_CREATE :
/* Create a heap for the control using a */
/* segment */
DosAllocMem((PPVOID)(PVOID)&pcmrk, 4096UL, PAG_READ | PAG_WRITE | PAG_COMMIT);
/* Save the address of the text string pointer */
/* in the control's reserved memory to allow it */
/* to be referenced as required by the control */
WinSetWindowPtr(hWnd, QWW_CDATA, (PVOID)pcmrk);
/* Get the control's creation structure address */
/* to copy the default text of the control to */
/* the memory in the heap */
pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);
pcmrk->hwndOwner = pcrst->hwndOwner;
if ( pcrst->flStyle & CMS_CHECKED )
pcmrk->fChecked = TRUE;
/* Set up the colours that will be used within */
/* the painting of the control. The colour */
/* indices are: */
/* */
/* 0 : Foreground (PP_FOREGROUND*) */
/* 1 : Background (PP_BACKGROUND*) */
/* 2 : Hilight Foreground (PP_HILITEFOREGROUND*) */
/* 3 : Hilight Background (PP_HILITEBACKGROUND*) */
/* 4 : Disabled Foreground (PP_DISABLEDFORE*) */
/* 5 : Disabled Foreground (PP_DISABLEDFORE*) */
/* 6 : Border (PP_BORDER*) */
SetDefaultColours(hWnd, pcmrk);
if ( pcrst->pszText )
strcpy(pcmrk->szText, pcrst->pszText);
pcmrk->hbm = GpiLoadBitmap(hPS = WinGetPS(hWnd), hmodDLL, IDB_CHECKMARKS,
0L, 0L);
WinReleasePS(hPS);
CalcDisplayPoints(hWnd, pcmrk, pcrst->cx, pcrst->cy);
break;
case WM_SIZE :
/* Text being set, get the address of the text */
/* string stored in the heap */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
CalcDisplayPoints(hWnd, pcmrk,
(LONG)(SHORT)SHORT1FROMMP(mp2),
(LONG)(SHORT)SHORT2FROMMP(mp2));
break;
/* Process window parameters setting */
case WM_SETWINDOWPARAMS :
/* Get the address for the windows parameters */
/* structure */
pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);
/* Check to see if the text for the control is */
/* being set */
if ( pwprm->fsStatus & WPM_TEXT )
{
/* Text being set, get the address of the text */
/* string stored in the heap */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
/* Check to see if any text is being set */
if ( pwprm->cchText )
/* Check to make sure that the text that is to */
/* be set is not greater than the memory */
/* allocated */
if ( pwprm->cchText > 511 )
{
strncpy(pcmrk->szText, pwprm->pszText, 511);
pcmrk->szText[511] = 0;
}
else
strcpy(pcmrk->szText, pwprm->pszText);
else
/* No text is being set, clear any existing text */
pcmrk->szText[0] = 0;
}
break;
/* Process window parameters query */
case WM_QUERYWINDOWPARAMS :
/* Get the address for the windows parameters */
/* structure */
pwprm = (PWNDPARAMS)PVOIDFROMMP(mp1);
/* Determine the type of query */
switch ( pwprm->fsStatus )
{
/* Query type: get text */
case WPM_TEXT :
/* Text being asked for, get the address of the */
/* text string stored in the heap */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
/* Copy the text from the string to the */
/* structure */
strcpy(pwprm->pszText, pcmrk->szText);
break;
/* Query type: get text length */
case WPM_CCHTEXT :
/* Text length being asked for, get the address */
/* of the text string stored in the heap */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
/* Place the length the string within the */
/* structure */
pwprm->cchText = (ULONG)strlen(pcmrk->szText);
break;
/* Query type: get control data length */
case WPM_CBCTLDATA :
/* Set the control data length to zero */
pwprm->cbCtlData = 0;
break;
default :
return(WinDefWindowProc(hWnd, msg, mp1, mp2));
}
break;
/* Font & Colours changed, record the */
/* change internally */
case WM_PRESPARAMCHANGED :
/* Check to see if an individual presentation */
/* parameter has changed if so, get the new */
/* colour value for use by the painting routines */
if ( LONGFROMMP(mp1) && (LONGFROMMP(mp1) < PP_FONTNAMESIZE) )
{
/* Get the address of the control info from the */
/* control's reserved memory */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
/* Get the new Font & Colours colour for */
/* the Font & Colours that has changed. */
/* Get the colour as a RGB value so as to be */
/* able to get an exact value and not an */
/* approximation which could happen if the */
/* Font & Colours was set as a RGB but */
/* queried as an index. When WinQueryPresParam */
/* returns a 0, it indicates that no */
/* Font & Colours set and the default */
/* colours should be used. */
switch ( LONGFROMMP(mp1) )
{
case PP_FOREGROUNDCOLOR :
case PP_FOREGROUNDCOLORINDEX :
pcmrk->aClr[0] = lGetPresParam(hWnd, PP_FOREGROUNDCOLOR,
PP_FOREGROUNDCOLORINDEX,
SYSCLR_OUTPUTTEXT);
break;
case PP_BACKGROUNDCOLOR :
case PP_BACKGROUNDCOLORINDEX :
pcmrk->aClr[1] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
PP_BACKGROUNDCOLORINDEX,
SYSCLR_DIALOGBACKGROUND);
break;
case PP_HILITEFOREGROUNDCOLOR :
case PP_HILITEFOREGROUNDCOLORINDEX :
pcmrk->aClr[2] = lGetPresParam(hWnd, PP_HILITEFOREGROUNDCOLOR,
PP_HILITEFOREGROUNDCOLORINDEX,
SYSCLR_OUTPUTTEXT);
break;
case PP_HILITEBACKGROUNDCOLOR :
case PP_HILITEBACKGROUNDCOLORINDEX :
pcmrk->aClr[3] = lGetPresParam(hWnd, PP_HILITEBACKGROUNDCOLOR,
PP_HILITEBACKGROUNDCOLORINDEX,
SYSCLR_DIALOGBACKGROUND);
break;
case PP_DISABLEDFOREGROUNDCOLOR :
case PP_DISABLEDFOREGROUNDCOLORINDEX :
pcmrk->aClr[4] = lGetPresParam(hWnd, PP_DISABLEDFOREGROUNDCOLOR,
PP_DISABLEDFOREGROUNDCOLORINDEX,
SYSCLR_OUTPUTTEXT);
break;
case PP_DISABLEDBACKGROUNDCOLOR :
case PP_DISABLEDBACKGROUNDCOLORINDEX :
pcmrk->aClr[5] = lGetPresParam(hWnd, PP_BACKGROUNDCOLOR,
PP_BACKGROUNDCOLORINDEX,
SYSCLR_DIALOGBACKGROUND);
break;
case PP_BORDERCOLOR :
case PP_BORDERCOLORINDEX :
pcmrk->aClr[6] = lGetPresParam(hWnd, PP_BORDERCOLOR,
PP_BORDERCOLORINDEX,
SYSCLR_BUTTONDARK);
break;
}
/* Invalidate the button to force to use the */
/* new colours just set or removed */
WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
}
else
/* Determine if the Scheme Palette has forced a */
/* global scheme update in which case, check all */
/* of the Font & Colours to see if they */
/* have been added or removed */
if ( LONGFROMMP(mp1) == 0L )
/* Set up the colours that will be used within */
/* the painting of the control. */
SetDefaultColours(hWnd,
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd,
QWW_CDATA));
break;
/* Mouse being passed over the control, imply */
/* that the control is transparent to the */
/* system */
case WM_HITTEST :
return(MRFROMLONG(HT_TRANSPARENT));
/* Erase control background */
case WM_ERASEBACKGROUND :
return(MRFROMLONG(TRUE));
case CKM_SETCHECK :
/* Get the address of the text from the */
/* control's reserved memory */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
pcmrk->fChecked = (BOOL)LONGFROMMP(mp1);
WinInvalidateRect(hWnd, (PRECTL)NULL, TRUE);
break;
/* Paint the Control */
case WM_PAINT :
/* Get the address of the text from the */
/* control's reserved memory */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
/* Get the presentation space for the control */
/* and set the colour table to RGB mode */
GpiCreateLogColorTable(hPS = WinBeginPaint(hWnd, (HPS)NULL, (PRECTL)NULL),
0L, LCOLF_RGB, 0L, 0L, (PLONG)NULL);
WinFillRect(hPS, &pcmrk->rcl, pcmrk->aClr[1]);
WinDrawBitmap(hPS, pcmrk->hbm, pcmrk->fChecked ? &pcmrk->rclChecked :
&pcmrk->rclUnChecked,
&pcmrk->ptlChkMark, 0L, 0L, DBM_IMAGEATTRS | DBM_NORMAL);
GpiCharStringPosAt(hPS, &pcmrk->ptlText, &pcmrk->rclText,
CHS_CLIP, (LONG)strlen(pcmrk->szText),
pcmrk->szText, NULL);
WinEndPaint(hPS);
break;
/* Control being destroyed */
case WM_DESTROY :
/* Get the address of the text from the */
/* control's reserved memory */
pcmrk = (PCHECKMARK)WinQueryWindowPtr(hWnd, QWW_CDATA);
GpiDeleteBitmap(pcmrk->hbm);
/* Release the heap allocated for use by the */
/* control */
DosFreeMem((PVOID)pcmrk);
break;
/* Default message processing */
default :
return(WinDefWindowProc(hWnd, msg, mp1, mp2));
}
return(0L);
}
#pragma subtitle(" Check Mark Control DLL - Control Styles Dialogue Procedure")
#pragma page ( )
/* --- ChkMarkStyles -------------------------------------------------- */
/* */
/* This function is used for the custom control's styles dialogue */
/* box procedure. */
/* */
/* When the dialogue is invoked from Resource Editor, the */
/* address of the user style information is contained in message */
/* parameter 2. The dialogue is responsible for saving the */
/* address. The best method to do this is to save the pointer */
/* in the dialogue's reserved memory where it can be retrieved as */
/* needed. */
/* */
/* Upon Entry: */
/* */
/* HWND hWnd; = Dialog Window Handle */
/* ULONG msg; = PM Message */
/* MPARAM mp1; = Message Parameter 1 */
/* MPARAM mp2; = Message Parameter 2 */
/* */
/* Upon Exit: */
/* */
/* ChkMarkStyles = Message Handling Result */
/* */
/* -------------------------------------------------------------------- */
MRESULT EXPENTRY ChkMarkStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
PUSERSTYLE pust; /* User Style Pointer */
SWP swp; /* Screen Window Position Holder */
switch ( msg )
{
/* Perform dialogue initialization */
case WM_INITDLG :
/* Save the pointer to user style information */
/* within the dialog's reserved memory */
WinSetWindowPtr(hWnd, QWL_USER, (PVOID)mp2);
/* Get the pointer to the user style information */
if ( (pust = (PUSERSTYLE)mp2) != NULL )
{
/* Set the text, ID symbol and value for the */
/* control */
WinSetDlgItemText(hWnd, EF_TEXT, pust->pszText);
pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust);
if ( pust->flStyle & CMS_CHECKED )
WinSendDlgItemMsg(hWnd, CB_CMS_CHECKED, BM_SETCHECK,
MPFROMSHORT(TRUE), 0L);
if ( pust->flStyle & WS_VISIBLE )
WinSendDlgItemMsg(hWnd, CB_VISIBLE, BM_SETCHECK,
MPFROMSHORT(TRUE), 0L);
if ( pust->flStyle & WS_GROUP )
WinSendDlgItemMsg(hWnd, CB_GROUP, BM_SETCHECK,
MPFROMSHORT(TRUE), 0L);
if ( pust->flStyle & WS_DISABLED )
WinSendDlgItemMsg(hWnd, CB_DISABLED, BM_SETCHECK,
MPFROMSHORT(TRUE), 0L);
if ( pust->flStyle & WS_TABSTOP )
WinSendDlgItemMsg(hWnd, CB_TABSTOP, BM_SETCHECK,
MPFROMSHORT(TRUE), 0L);
}
/* Centre dialog on the screen */
WinQueryWindowPos(hWnd, (PSWP)&swp);
WinSetWindowPos(hWnd, HWND_TOP,
(WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) - swp.cx) / 2L,
(WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - swp.cy) / 2L,
0L, 0L, SWP_MOVE);
break;
/* Process push button selections */
case WM_COMMAND :
switch ( SHORT1FROMMP(mp1) )
{
/* Font & Colours push button selected */
case DID_PRESPARAM :
/* Get the pointer to the user style information */
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
/* Get the address of the look up function from */
/* user style information structure and display */
/* the dialog. The value selected within the */
/* dialogue will be automatically placed within */
/* the required entry fields */
pust->pfnGetFontClr(hWnd);
break;
/* Bidi push button selected */
case DID_BIDI :
/* Get the pointer to the user style information */
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
/* Get the address of the look up function from */
/* user style information structure and display */
/* the dialog. The value selected within the */
/* dialogue will be automatically placed within */
/* the required entry fields */
pust->pfnGetBidi(hWnd);
break;
/* Enter push button selected get the */
/* definitions for the control */
case DID_OK :
/* Get the pointer to the user style information */
if ( (pust = PDATAFROMDLG(hWnd)) != NULL )
{
/* Get the address of the CUA compliance */
/* function from the user style information */
/* structure. The function will check the text */
/* for CUA compliance according to index value */
/* selected. A return value of TRUE from the */
/* compliance function indicates that the text */
/* entered is acceptable. Conversely, a FALSE */
/* return value indicates that text is non- */
/* compliant. In this case, the dialogue should */
/* not be exited from and the values within the */
/* the entry fields should not be saved. */
if ( !pust->pfnCUACheck(hWnd, EF_TEXT, CUACHK_CAPS) )
break;
/* Get the address of the symbol validation */
/* function from the user style information */
/* structure. The function will validate the */
/* symbol and will check for duplications of */
/* values. A return value of TRUE from the */
/* validation function indicates that the symbol */
/* and value are acceptable. Conversely, a */
/* FALSE return value indicates that symbol or */
/* value was not acceptable. In this case, */
/* the dialogue should not be exited from and */
/* the values within the entry fields should not */
/* be saved. */
if ( !pust->pfnGetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust) )
break;
else
{
/* Symbol and value validated, get the text of */
/* the control and save within the user style */
/* information structure for use by Resource */
/* Editor */
pust->cText = WinQueryDlgItemText(hWnd, EF_TEXT,
CCHTEXTMAX, pust->pszText);
/* Mask out current edit field styles clearing */
/* selectable styles and save new style */
pust->flStyle = 0UL;
/* Get raised/depressed style */
if ( SHORT1FROMMR(WinSendDlgItemMsg(hWnd, CB_CMS_CHECKED,
BM_QUERYCHECK,
0L, 0L)) )
pust->flStyle |= CMS_CHECKED;
/* Save completed edit field style in internal */
/* window information */
if ( WinSendDlgItemMsg(hWnd, CB_VISIBLE,
BM_QUERYCHECK, 0L, 0L) )
pust->flStyle |= WS_VISIBLE;
if ( WinSendDlgItemMsg(hWnd, CB_GROUP,
BM_QUERYCHECK, 0L, 0L) )
pust->flStyle |= WS_GROUP;
if ( WinSendDlgItemMsg(hWnd, CB_DISABLED,
BM_QUERYCHECK, 0L, 0L) )
pust->flStyle |= WS_DISABLED;
if ( WinSendDlgItemMsg(hWnd, CB_TABSTOP,
BM_QUERYCHECK, 0L, 0L) )
pust->flStyle |= WS_TABSTOP;
}
}
/* Exit the dialogue indicating changes made */
WinDismissDlg(hWnd, TRUE);
break;
/* Cancel selected, exit the dialogue without */
/* changing anything */
case DID_CANCEL :
WinDismissDlg(hWnd, FALSE);
break;
}
break;
/* Close received, exit dialog */
case WM_CLOSE :
WinDismissDlg(hWnd, FALSE);
break;
/* Pass through unhandled messages */
default :
return(WinDefDlgProc(hWnd, msg, mp1, mp2));
}
return(0L);
}
The constants header file is defined below. The constants used by Prominare
Designer, ChkMark.Rc and ChkMark.C, reference the controls in the styles
dialogue.
/* chkmark.h Created: 1993-12-21 Revised: 1994-09-18 */
/* PMCX Control Constants Header */
/* Copyright ╨╣ 1989-1994 Prominare Inc. All Rights Reserved. */
#define CMS_CHECKED 0x0001L
#define CKM_SETCHECK (WM_USER + 128UL)
/* --- Miscellaneous Constants ---------------------------------------- */
#define DID_HELP 3 /* Help Push Button ID */
#define DID_FONTCLR 11 /* Font & Colours Push Button ID */
#define DID_BIDI 12 /* Bidi Push Button ID */
#define CB_VISIBLE 256 /* Visible Check Box ID */
#define CB_GROUP 257 /* Group Check Box ID */
#define CB_DISABLED 258 /* Disabled Check Box ID */
#define CB_TABSTOP 259 /* Tab Stop Check Box ID */
/* --- Control Dialogue ----------------------------------------------- */
#define DLG_CTRLUSER 1000 /* User Defined Dialog */
#define CB_CMS_CHECKED 4042 /* Left Aligned Radio Button */
#define EF_TEXT 4051 /* Text Edit Field */
#define IDBX_SYMBOLVALUE 4053 /* ID Value Edit Field */
/* --- Styles String ID's --------------------------------------------- */
#define IDS_CMS_CHECKED 512
/* --- Bitmap ID's ---------------------------------------------------- */
#define IDB_CHECKMARKS 784
The resource file for the style dialogue is shown below.
/* PMCX Example Created: 1994-06-26 */
/* Resource File Revised: 1994-08-12 */
/* Copyright Γòò 1989-1994 Prominare Inc. All Rights Reserved. */
#define INCL_WINSYS
#define INCL_WINSTDDLGS
#define INCL_WINSTDSPIN
#define INCL_NLS
#define INCL_SW
#include <os2.h>
#include "chkmark.h"
/* --- Custom Control Styles Dialogue --------------------------------- */
BITMAP IDB_CHECKMARKS ChkMark.Bmp
DLGTEMPLATE DLG_CTRLUSER 850
BEGIN
DIALOG "Check Mark Styles", DLG_CTRLUSER, 22, 62, 220, 121, FS_NOBYTEALIGN |
FS_DLGBORDER | WS_CLIPSIBLINGS | WS_SAVEBITS | WS_VISIBLE,
FCF_TITLEBAR | FCF_SYSMENU
PRESPARAMS PP_FONTNAMESIZE, "8.Helv"
BEGIN
CONTROL "Select style and type text and ID symbol.", -1,
5, 110, 123, 8, WC_STATIC, SS_TEXT |
DT_VCENTER | WS_GROUP | WS_VISIBLE
PRESPARAMS PP_FOREGROUNDCOLORINDEX, CLR_BLACK
CONTROL "Text:", -1, 5, 99, 16, 8, WC_STATIC, SS_TEXT |
DT_RIGHT | DT_VCENTER | WS_VISIBLE
CONTROL "", EF_TEXT, 25, 70, 190, 36, WC_MLE,
MLS_BORDER | MLS_HSCROLL |
MLS_IGNORETAB | MLS_VSCROLL |
MLS_DISABLEUNDO | WS_TABSTOP |
WS_VISIBLE
CONTROL "ID:", -1, 5, 60, 16, 8, WC_STATIC, SS_TEXT |
DT_RIGHT | DT_VCENTER | WS_VISIBLE
CONTROL "", IDBX_SYMBOLVALUE, 25, 60, 190, 8, "ID.Box",
WS_TABSTOP | WS_VISIBLE
CONTROL "Check mark options", -1, 5, 40, 210, 18, WC_STATIC,
SS_GROUPBOX | WS_VISIBLE
CONTROL "~Checked", CB_CMS_CHECKED, 8, 42, 40, 8, WC_BUTTON,
BS_AUTOCHECKBOX | WS_TABSTOP |
WS_VISIBLE
CONTROL "Base styles", -1, 5, 20, 210, 18, WC_STATIC,
SS_GROUPBOX | WS_GROUP | WS_VISIBLE
CONTROL "~Visible", CB_VISIBLE, 8, 22, 32, 8, WC_BUTTON,
BS_AUTOCHECKBOX | WS_TABSTOP |
WS_VISIBLE
CONTROL "~Group", CB_GROUP, 110, 22, 31, 8, WC_BUTTON,
BS_AUTOCHECKBOX | WS_TABSTOP |
WS_VISIBLE
CONTROL "~Disabled", CB_DISABLED, 58, 22, 40, 8, WC_BUTTON,
BS_AUTOCHECKBOX | WS_TABSTOP |
WS_VISIBLE
CONTROL "~Tab stop", CB_TABSTOP, 165, 22, 39, 8, WC_BUTTON,
BS_AUTOCHECKBOX | WS_TABSTOP |
WS_VISIBLE
CONTROL "Enter", DID_OK, 5, 5, 50, 12, WC_BUTTON,
BS_PUSHBUTTON | BS_DEFAULT |
WS_GROUP | WS_TABSTOP | WS_VISIBLE
CONTROL "Cancel", DID_CANCEL, 58, 5, 50, 12, WC_BUTTON,
BS_PUSHBUTTON | WS_TABSTOP |
WS_VISIBLE
CONTROL "Help", DID_HELP, 110, 5, 50, 12, WC_BUTTON,
BS_PUSHBUTTON | BS_HELP |
BS_NOPOINTERFOCUS | WS_TABSTOP |
WS_VISIBLE
CONTROL "Font & Colours...", DID_PRESPARAM, 165, 5, 50, 12, WC_BUTTON,
BS_PUSHBUTTON | WS_TABSTOP |
WS_VISIBLE
END
END
CODEPAGE 850
STRINGTABLE MOVEABLE DISCARDABLE
BEGIN
IDS_CMS_CHECKED, "CMS_CHECKED"
END
The MAKE file is shown below.
# MAKE file for ChkMark Version 1.00.00
# Revised: 1994-08-12
# Copyright Γòò 1989-1994 Prominare Inc. All Rights Reserved.
ChkMark.Dll: ChkMark.Obj ChkMark.Res
Link386 /EXEPACK /BASE:0x1200000 @ChkMark.Lnk;
Rc ChkMark.Res ChkMark.Dll
ChkMark.Obj: ChkMark.C
Icc -G4e- -Ox -Rn -Fo$* ChkMark.C
ChkMark.Res: ChkMark.Rc
Rc -r $(@B).Rc $*.Res
The link response file is shown below.
ChkMark
ChkMark.Dll
ChkMark.Map
ChkMark.Def
The definitions file is shown below.
LIBRARY ChkMark INITINSTANCE TERMINSTANCE
DESCRIPTION 'Check Mark Control - 32-Bit Version'
CODE LOADONCALL EXECUTEREAD NOIOPL NONCONFORMING
DATA LOADONCALL READWRITE NOIOPL MULTIPLE NONSHARED
PROTMODE
EXETYPE OS2
EXPORTS ChkMarkRegister @ 1
ChkMarkQuery @ 2
ChkMarkStyles @ 3
Examples using PMCX (including full source code) are contained in the
Source\Designer subdirectories, if you allowed the source code to be installed
on your system during installation of Prominare Designer. Following are some of
the PMCX controls implemented.
Directory Purpose
3D Example of a PMCX control 3D text field.
ChkMark Example of a static control with check mark.
ComboBox Example of a variable control data usage PMCX control
using a combo box.
ComboMin Example of a variable control data usage PMCX control
using a combo box and also allowing for the combo box to
specify the depth of the drop down when used with tight
areas.
Control Example of a simple PMCX control.
DateFld Example of a PMCX control for a date entry field.
Frame Example of a PMCX control for a shadowed frame. This PMCX
example shows how to utilize font and colours within a
custom control.
ImageBtn Example of a PMCX control push button containing a graphic
bitmap image.
Line3D Example of a PMCX control 3D line.
ListBox Example of a variable control data usage PMCX control
using a list box.
Notebook Example of notebook usage in a design.
NotePage Example of a variable control data usage PMCX control
using a notebook.
Pattern Example of a PMCX control pattern field.
SpinBtn Example of a variable control data usage PMCX control
using a spin button.
TestBed Facility to test PMCX controls. The utility provides the
means to debug and test the control dialogues.
TimeFld Example of a PMCX control for a time entry field.