This chapter describes an MDL application called basic.ma that opens a simple, modeless dialog box. While the application is basic, as the name implies, it does illustrate all of the steps necessary to create an MDL application that uses the dialog box manager.
It is assumed that the reader is familiar with the contents of the preceding three chapters. However, this section can also be read to capture the flavor of MDL dialog box applications.
- The basic MDL application is also featured in "Building Applications", which you may want to review concurrently with this one. All the source files needed to create the application are here along with detailed explanations. These files are also found in the basic example directory. To run this example, first make the basic application by going to the basic directory and entering: BMAKE BASIC.
To load the application, start MicroStation and select the "MDL Applications" menu item from MicroStation's "User" pull-down menu. Then select the basic application using the dialog box that appears. If the basic application does not appear in the list of "Available Applications", make sure that the MS_MDL MicroStation environment includes the ..\mdlapps directory.
When the basic.ma application is loaded, a modeless dialog box entitled "Basic Dialog Box" appears on the screen. This modeless dialog box contains three items: a text item, an option button item and a push button item.
Both the text and option button item controls let the user view the same application variable parameter1. Using a synonym resource, whenever either of these items changes the variable parameter1, the other item's appearance also changes to match parameter1's new value.
When the user clicks on the push button item labeled "Open Modal," a modal dialog box is displayed. Its title is "Basic Modal Dialog Box". As long as this modal dialog box is present on the screen, the user cannot interact with any other window's contents.
The "Basic Modal Dialog Box" also contains three items: a toggle button, a push button labeled "OK," and a push button labeled "Cancel." This modal dialog box lets the user increment the application variable parameter1.
If the user clicks the OK button after turning the toggle button "on," the modal dialog box will be dismissed and parameter1 will be incremented. The appearance of the text and option button items in the "Basic Dialog Box" is also changed to reflect the new value of parameter1. If the toggle button is "off" when the OK button is clicked or the Cancel button is clicked, the modal dialog box is simply dismissed and parameter1 remains unchanged.
When the user closes the initial "Basic Dialog Box," the basic.ma application is automatically unloaded.
The basic application consists of the following files:
basic.h Defines the constants and data structures used by the application. basic.r Contains the definition of the application's resources. basic.mc Contains the application's source code. basiccmd.r Contains the definition of the application's command table resources. basiccmd.h Contains the application's command numbers (generated by rcomp when basiccmd.r is compiled). basictyp.mt Used to generate type declaration resources for the application. basicmsg.r Contains language-specific messages (located in the english subdirectory). basictxt.h Contains language-specific text strings (located in the english subdirectory). basic.mke Contains information used by the bmake utility to create the basic.ma application from the above files. basicrsc.mki Contains rules and dependencies used by basic.mke.
The application header file: basic.h 23 /*-----------------------------------------------------------------+ 24 | | 25 | Function - | 26 | | 27 | Constants & types used in basic dialog example | 28 | | 29 +-----------------------------------------------------------------*/ 30 #ifndef __basicH__ 31 #define __basicH__ 32 /*-----------------------------------------------------------------+ 33 | | 34 | Resource ID's | 35 | | 36 +-----------------------------------------------------------------*/ 37 #define DIALOGID_Basic 1 /* dialog id for Basic Dialog */ 38 #define DIALOGID_BasicModal 2 /* dialog id for Basic Modal Dialog */ 39 #define OPTIONBUTTONID_Basic 1 /* id for parameter 1 option button */ 40 #define PUSHBUTTONID_OModal 1 /* id for "Open Modal" push button */ 41 #define TEXTID_Basic 1 /* id for "parameter 1" text item */ 42 #define TOGGLEID_Basic 1 /* id for "Inc parameter 1?" toggle */ 43 #define SYNONYMID_Basic 1 /* id for synonym resource */ 44 #define MESSAGELISTID_BasicErrors 1 /* id for error message list */ 45 /*-----------------------------------------------------------------+ 46 | | 47 | Error Message ID Definitions | 48 | | 49 +-----------------------------------------------------------------*/ 50 #define ERRID_CommandTable 1 51 #define ERRID_BasicDialog 2 52 #define ERRID_ModalDialog 3 53 /*-----------------------------------------------------------------+ 54 | | 55 | Hook Function ID's | 56 | | 57 +-----------------------------------------------------------------*/ 58 #define HOOKITEMID_ToggleButton_Basic 1 /* toggle for item hook id */ 59 #define HOOKDIALOGID_Basic 2 /* id for dialog hook func */ 60 /*-----------------------------------------------------------------+ 61 | | 62 | Typedefs | 63 | | 64 +-----------------------------------------------------------------*/ 65 typedef struct basicglobals 66 { 67 int parameter1; /* used by text & option button item */ 68 int parameter2; /* used by toggle button item */ 69 } BasicGlobals; 70 #endif
The header file basic.h is included in basic.r, basic.mc and basictyp.mt.
Lines 37-44 define symbolic constants that are used as resource ID numbers. Remember that each instance of a particular resource type needs to have its own unique, positive resource ID number. That is why DIALOGID_BasicModal is defined to be 2 and not 1, which is already assigned to DIALOGID_Basic. Both of these resource IDs are used to create a DialogBoxRsc resource (with a resource type of RTYPE_DialogBox) and therefore must be different numbers. As a further illustration, if another DItem_OptionButtonRsc resource was needed for this application its resource ID could not be 1. That number is already used by OPTIONBUTTONID_Basic.
See the "Resources" section in the "MicroStation Dialog Box Manager Overview" chapter for more information on creating resource IDs.
Lines 50-52 define symbolic constants which are used to reference entries in the Message List resource defined by MESSAGELISTID_BasicErrors.
Lines 58-59 define symbolic constants used as hook function ID numbers. Remember that each hook function in an application requires its own unique, positive ID number. This is true whether the hook function is a dialog hook function or a dialog item hook function. Dialog hook functions and item hook functions share the same number space. This is why HOOKDIALOGID_Basic is 2 and not 1, which is already used by HOOKITEMID_ToggleButton_Basic.
See the "Hook function IDs" section in the "MicroStation Dialog Box Manager Overview" chapter for more information on creating hook function IDs.
Finally, lines 65-69 declare the structure BasicGlobals. The dialog items in the basic application's dialog boxes control members of a variable of this type (see lines 104, 115 and 143 in basic.r).
The BasicGlobals structure is created to hold the variables that these dialog box items modify. This was done because any application variable that a dialog box item refers to in a C expression string resource must be published in a symbol set for use by the C expression handling functions. When the variables are part of a structure, only one mdlDialog_publishComplexVariable or mdlDialog_publishComplexPtr function call must be done for that structure. Otherwise, an mdlDialog_publishÉ function call is required for each referenced variable.
See "Referencing Application Variables from Resource Files" for more information on variable references within C expression strings.
23 /*-----------------------------------------------------------------+ 24 | | 25 | Function - | 26 | | 27 | Basic Dialog Example Resources | 28 | | 29 +-----------------------------------------------------------------*/ 30 /*-----------------------------------------------------------------+ 31 | | 32 | Include Files | 33 | | 34 +-----------------------------------------------------------------*/ 35 #include /* dlog box manager resource consts & structs */ 36 #include /* MicroStation resource IDs */ 37 #include "basic.h" /* basic dialog box example consts & structs */ 38 #include "basiccmd.h" /* basic dialog box command numbers */ 39 #include "basictxt.h" /* basic dialog box static text defines */ 40 /*-----------------------------------------------------------------+ 41 | | 42 | Basic Dialog Box | 43 | | 44 +-----------------------------------------------------------------*/ 45 #define X1 (14*XC) /* text & option button x position */ 46 #define X2 (7*XC) /* push button x position */ 47 #define XW (9*XC) /* text & option button width */ 48 #define BTN_WIDTH (12*XC) /* push button width */ 49 DialogBoxRsc DIALOGID_Basic= 50 { 51 DIALOGATTR_DEFAULT | DIALOGATTR_SINKABLE, 52 25*XC, 7*YC, 53 NOHELP, MHELP, HOOKDIALOGID_Basic, NOPARENTID, 54 TXT_BasicDialogBox, 55 { 56 {{X1,GENY(1),XW,0}, Text, TEXTID_Basic, ON, 0, "", ""}, 57 {{X1,GENY(2),XW,0}, OptionButton,OPTIONBUTTONID_Basic, ON, 0,"",""}, 58 {{X2,GENY(4),BTN_WIDTH,0},PushButton,PUSHBUTTONID_OModal,ON,0,"",""} 59 } 60 }; 61 #undef X1 /* undef symbols so they can be reused */ 62 #undef X2 63 #undef XW 64 #undef BTN_WIDTH 65 /*-----------------------------------------------------------------+ 66 | | 67 | Modal Sub-Dialog Box | 68 | (opened when PUSHBUTTONID_OModal is activated) | 69 | | 70 +-----------------------------------------------------------------*/ 71 #define X1 (1*XC) /* toggle button x position */ 72 #define X2 (3*XC) /* OK button x position */ 73 #define X3 (14*XC) /* Cancel button x position */ 74 DialogBoxRsc DIALOGID_BasicModal= 75 { 76 DIALOGATTR_DEFAULT | DIALOGATTR_MODAL, 77 25*XC, 6*YC, 78 NOHELP, MHELP, HOOKDIALOGID_Basic, NOPARENTID, 79 TXT_BasicModalDialogBox, 80 { 81 {{X1,GENY(1),0,0}, ToggleButton, TOGGLEID_Basic, ON, 0, "", ""}, 82{{X2,GENY(3),BUTTON_STDWIDTH,0},PushButton,PUSHBUTTONID_OK,ON,0,"","" }, 83 {{X3,GENY(3),BUTTON_STDWIDTH,0},PushButton,PUSHBUTTONID_Cancel,ON, 0,"",""}, 84 } 85 }; 86 #undef X1 /* undef symbols so they can be reused */ 87 #undef X2 88 #undef X3 89 /*-----------------------------------------------------------------+ 90 | | 91 | Item Resource Specifications | 92 | | 93 +-----------------------------------------------------------------*/ 94 /*-----------------------------------------------------------------+ 95 | | 96 | Text Item Resources | 97 | | 98 +-----------------------------------------------------------------*/ 99 DItem_TextRsc TEXTID_Basic= 100 { 101 NOCMD, LCMD, SYNONYMID_Basic, NOHELP, MHELP, NOHOOK, NOARG, 102 4, "%ld", "%ld", "1", "3", NOMASK, NOCONCAT, 103 TXT_Parameter1, 104 "basicGlobals.parameter1" 105 }; 106 /*-----------------------------------------------------------------+ 107 | | 108 | Option Button Item Resources | 109 | | 110 +-----------------------------------------------------------------*/ 111 DItem_OptionButtonRsc OPTIONBUTTONID_Basic= 112 { 113 SYNONYMID_Basic, NOHELP, MHELP, NOHOOK, NOARG, 114 TXT_Parameter1, 115 "basicGlobals.parameter1", 116 { 117 {NOTYPE, NOICON, NOCMD, LCMD, 1, NOMASK, ON, TXT_Value1}, 118 {NOTYPE, NOICON, NOCMD, LCMD, 2, NOMASK, ON, TXT_Value2}, 119 {NOTYPE, NOICON, NOCMD, LCMD, 3, NOMASK, ON, TXT_Value3}, 120 } 121 }; 122 /*-----------------------------------------------------------------+ 123 | | 124 | PushButton Item Resources | 125 | | 126 +-----------------------------------------------------------------*/ 127 DItem_PushButtonRsc PUSHBUTTONID_OModal= 128 { 129 NOT_DEFAULT_BUTTON, NOHELP, MHELP, NOHOOK, 0, 130 CMD_OPENMODAL, LCMD, "", 131 TXT_OpenModal 132 }; 133 /*-----------------------------------------------------------------+ 134 | | 135 | Toggle Button Item Resources | 136 | | 137 +-----------------------------------------------------------------*/ 138 DItem_ToggleButtonRsc TOGGLEID_Basic= 139 { 140 NOCMD, LCMD, NOSYNONYM, NOHELP, MHELP, 141 HOOKITEMID_ToggleButton_Basic, NOARG, NOMASK, NOINVERT, 142 TXT_IncrementParameter1, 143 "basicGlobals.parameter2" 144 }; 145 /*-----------------------------------------------------------------+ 146 | | 147 | Synonym List Resources | 148 | | 149 +-----------------------------------------------------------------*/ 150 DItem_SynonymsRsc SYNONYMID_Basic= 151 { 152 { 153 {Text, TEXTID_Basic}, 154 {OptionButton, OPTIONBUTTONID_Basic}, 155 } 156 };
The resource source file basic.r contains all of the dialog and item resources for the basic application.
The header file dlogbox.h is included on line 35. dlogbox.h contains all of the MicroStation dialog box manager resource related constants and structures. It must be included in any resource source file that defines dialog box manager related resources.
The header file dlogids.h is included on line 36. dlogids.h contains the resource IDs of all of the dialog box manager related resources present in the MicroStation resource file. This file is needed because the "Basic Modal Dialog Box" uses the standard MicroStation "OK" and "Cancel" push button item resources.
The header file basic.h is included on line 37; it contains the application's resource ID and hook function ID numbers.
The header file basiccmd.h is included on line 38; it contains the command number for the basic application's Openmodal command. This is used in the definition of the push button whose resource ID is PUSHBUTTONID_OModal (see line 130).
The header file basictxt.h is included on line 39; it contains the static text label definitions referenced by the dialog resources contained in the basic application dialog boxes as shown in lines 54, 79, 103, 114, 131 and 142.
The modeless dialog box entitled "Basic Dialog Box" is defined on lines 45-64. This dialog box is 7 characters tall and approximately 25 characters wide. It will have a "sink" icon on the right side of its title bar. It has a dialog hook function, which in this case is the basic_dialogHook function (see line 71 in basic.mc). The dialog box has three entries in its dialog item list: a text item, an option button item, and a push button. The x position, width of the text and option button items are the same and are defined by the symbolic constant X1 and XW respectively. This ensures that if it is necessary to change their X position or size, their horizontal relationship will remain correct. The GENY macro is used to position the text item on "row" 1, and the option button on "row" 2. Since push buttons are taller than the other items, it is placed on "row" 4 to allow more space between it and the option button item. The height of all three items is specified to be 0. This indicates that the associated item handlers should calculate an appropriate default height.
The modal dialog box entitled, "Basic Modal Dialog Box" is defined on lines 71-88. This dialog box is 6 characters tall and approximately 25 characters wide. Since it is modal, the DIALOGATTR_MODAL bit is set in its attributes member. It has a dialog hook function, which is the same basic_dialogHook function that the "Basic Dialog Box" uses (see line 71 in basic.mc). This hook function looks at the dialogId member of any dialog messages received to determine which dialog box the message is for. The dialog box has three entries in its dialog box item list: a toggle button item, and two push button items. Note that the resources for the two push button items are not defined in basic.r; instead, these standard resources will be loaded from MicroStation's resource file. This ensures that the "OK" and "Cancel" modal dialog box behavior is correctly implemented.
See "DialogBoxRsc Structure" and + for more information on creating dialog box resources.
The next section in basic.r defines the actual dialog item resources that were referenced in the above dialog boxes. See the "Standard Dialog Box Items" chapter for more information on creating dialog item resources.
Lines 99-105 define the text item referred to in line 56. The text item can contain up to 4 characters, is displayed as an integer, and must be between 1 and 3. It's label is "Parameter 1": and it controls the basicGlobals.parameter1 application variable.
This text item has a synonym resource associated with it whose ID is SYNONYMID_Basic. Therefore, whenever the user modifies the text item to change basicGlobals.parameter1, the appearance of all of the other items that are listed in the SYNONYMID_Basic synonym resource will be forced to match the state of their application variables. In this example, the appearance of the OPTIONBUTTONID_Basic option button item will change to reflect the new value of basicGlobals.parameter1.
Lines 111-121 define the option button item referred to in line 57. Its hook function is the basic_dummyItemHook function. It displays the text strings "Value 1," "Value 2" or "Value 3" depending on the value of the basicGlobals.parameter1 application variable. The option button item also has the SYNONYMID_Basic synonym resource associated with it. This means that when the user modifies basicGlobals.parameter1 with the option button item, the appearance of the TEXTID_Basic text item will also be changed.
Lines 127-132 define the "Open Modal" push button item referred to in line 58. Its hook function is the basic_dummyItemHook function. The basic application's Openmodal command will be placed in the input queue when the user clicks on this button.
Lines 138-144 define the toggle button item referred to in line 81. Its hook function is the basic_toggleButtonHook function (see line 50 in basic.mc). It controls the basicGlobals.parameter2 application variable.
Lines 150-156 define the synonym resource that is associated with both the TEXTID_Basic text item and the OPTIONBUTTONID_Basic option button item. See the "Synonym resources" section in the "MicroStation Dialog Box Manager Overview" chapter for more information on synonym resources.
23 /*-----------------------------------------------------------------+ 24 | | 25 | Function - | 26 | | 27 | MDL example to show creation & use of basic dialog box | 28 | | 29 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 30 | | 31 | Public Routine Summary - | 32 | | 33 | main - Main entry point and initialization logic | 34 | basic_dialogHook - Dialog box hook function | 35 | basic_toggleButtonHook - Toggle button item hook function | 36 | basic_openModal - Application command function to open modal | 37 | dialog box | 38 | basic_errorPrint - Function to display an error message in | 39 | messages dialog box | 40 | | 41 +-----------------------------------------------------------------*/ 42 /*-----------------------------------------------------------------+ 43 | | 44 | Include Files | 45 | | 46 +-----------------------------------------------------------------*/ 47 #include /* MDL Library funcs structures & constants */ 48 #include /* Dialog Box Manager structures & constants */ 49 #include /* C Expression structures & constants */ 50 #include /* MicroStation command numbers */ 51 #include /* dialog box manager function prototypes */ 52 #include "basic.h" /* basic dialog box example constants & structs */ 53 #include "basiccmd.h" /* basic dialog box command nums */ 54 /*-----------------------------------------------------------------+ 55 | | 56 | Private Global variables | 57 | | 58 +-----------------------------------------------------------------*/ 59 /* The following variable is referenced in C expression strings used 60 by the text, option button, and toggle button items defined in 61 basic.r. The initial external state of the text item and the option 62 button (they are both looking at the same application variable) is 1. 63 The initial external state of the toggle button in the modal dialog 64 box is 0 (the toggle is "out" or OFF) */ 65 Private BasicGlobals basicGlobals={1, 0}; 66 void basic_toggleButtonHook(); 67 void basic_dialogHook(); 68 Private DialogHookInfo uHooks[]= 69 { 70 {HOOKITEMID_ToggleButton_Basic, basic_toggleButtonHook}, 71 {HOOKDIALOGID_Basic, basic_dialogHook}, 72 }; 73 /*-----------------------------------------------------------------+ 74 | | 75 | name main | 76 | | 77 | author BSI 12/90 | 78 | | 79 +-----------------------------------------------------------------*/ 80 Public main 81 ( 82 int argc, /* => number of args in next array */ 83 char *argv[] /* => array of cmd line arguments */ 84 ) 85 { 86 char *setP; /* a ptr to a "C expression symbol set" */ 87 RscFileHandle rscFileH; /* a resource file handle */ 88 DialogBox *dbP; /* a ptr to a dialog box */ 89 /* open the resource file that we came out of */ 90 mdlResource_openFile (&rscFileH, NULL, 0); 91 /* load the command table */ 92 if (mdlParse_loadCommandTable(NULL) == NULL) 93 basic_errorPrint(ERRID_CommandTable); 94 /* set up variables to be evaluated w/i C expression strings */ 95 setP=mdlCExpression_initializeSet(VISIBILITY_DIALOG_BOX,0,FALSE); 96 mdlDialog_publishComplexVariable(setP, "basicglobals", 97 "basicGlobals", &basicGlobals); 98 /* publish our hook functions */ 99 mdlDialog_hookPublish(sizeof(uHooks)/sizeof(DialogHookInfo),uHooks); 100 /* open the "Basic" dialog box */ 101 if ((dbP = mdlDialog_open(NULL, DIALOGID_Basic)) == NULL) 102 basic_errorPrint(ERRID_BasicDialog); 103 } 104 /*----------------------------------------------------------------+ 105 | | 106 | Hook Functions | 107 | | 108 +-----------------------------------------------------------------*/ 109 /*----------------------------------------------------------------+ 110 | | 111 | name basic_dialogHook | 112 | | 113 | author BSI 12/90 | 114 | | 115 +-----------------------------------------------------------------*/ 116 Private void basic_dialogHook 117 ( 118 DialogMessage *dmP /* => a ptr to a dialog message */ 119 ) 120 { 121 /* ignore any messages being sent to modal dialog hook */ 122 if (dmP->dialogId != DIALOGID_Basic) 123 return; 124 dmP->msgUnderstood = TRUE; 125 switch (dmP->messageType) 126 { 127 case DIALOG_MESSAGE_DESTROY: 128 { 129 /* unload this mdl task when Basic Dialog is closed */ 130 mdlDialog_cmdNumberQueue(FALSE, CMD_MDL_UNLOAD, 131 mdlSystem_getCurrTaskID(), TRUE); 132 /* mdlSystem_getCurrTaskID was erroneously omitted 133 from the MDL documentation. It returns a character 134 pointer pointing to the current task's task ID. */ 135 break; 136 }; 137 default: 138 dmP->msgUnderstood = FALSE; 139 break; 140 } 141 } 142 /*-----------------------------------------------------------------+ 143 | | 144 | name basic_toggleButtonHook | 145 | | 146 | author BSI 12/90 | 147 | | 148 +-----------------------------------------------------------------*/ 149 Private void basic_toggleButtonHook 150 ( 151 DialogItemMessage *dimP /* => a ptr to a dialog item message */ 152 ) 153 { 154 dimP->msgUnderstood = TRUE; 155 switch (dimP->messageType) 156 { 157 case DITEM_MESSAGE_CREATE: 158 { 159 basicGlobals.parameter2 = 0; 160 break; 161 } 162 default: 163 dimP->msgUnderstood = FALSE; 164 break; 165 } 166 } 167 /*-----------------------------------------------------------------+ 168 | | 169 | Command Handling routines | 170 | | 171 +-----------------------------------------------------------------*/ 172 /*-----------------------------------------------------------------+ 173 | | 174 | name basic_openModal | 175 | | 176 | author BSI 12/90 | 177 | | 178 +-----------------------------------------------------------------*/ 179 Public cmdName void basic_openModal 180 ( 181 char *unparsedP /* => unparsed part of command */ 182 ) 183 cmdNumber CMD_OPENMODAL 184 { 185 int lastAction; 186 /* open child modal dialog box */ 187 if (mdlDialog_openModal(&lastAction, NULL, DIALOGID_BasicModal)) 188 { 189 basic_errorPrint (ERRID_ModalDialog); 190 return; 191 } 192 /* if the user clicked in OK push button, and the toggle button 193 is currently "in", then increment parameter1 and update the 194 appearance of both the text item and the option button item 195 in the Basic dialog box */ 196 if (lastAction == ACTIONBUTTON_OK && basicGlobals.parameter2) 197 { 198 basicGlobals.parameter1++; 199 if (basicGlobals.parameter1 > 3) 200 basicGlobals.parameter1 = 1; 201 mdlDialog_synonymsSynch(NULL, SYNONYMID_Basic, NULL); 202 } 203 } 204 /*-----------------------------------------------------------------+ 205 | | 206 | Utility routines | 207 | | 208 +-----------------------------------------------------------------*/ 209 /*----------------------------------------------------------------+ 210 | | 211 | name basic_errorPrint -- print an error message into Dialog | 212 | Box Manager Messages dialog box | 213 | | 214 | author BSI 12/90 | 215 | | 216 +-----------------------------------------------------------------*/ 217 Private void basic_errorPrint 218 ( 219 int errorNumber /* => number of error to print */ 220 ) 221 { 222 char errorMsg[80]; 223 if (mdlResource_loadFromStringList(errorMsg, NULL, 224 MESSAGELISTID_BasicErrors, errorNumber)) 225 return; /* unable to find msg. w/ num. "errorNumber" */ 226 mdlDialog_dmsgsPrint(errorMsg); 227 }
The main function is defined on lines 80-103. It starts by opening the resource file from which its application was loaded by calling mdlResource_openFile with NULL as its second argument. In this case, the resource file basic.ma is opened in read-only mode. This resource file needs to be opened before any resources that reside in it can be accessed.
The mdlParse_loadCommandTable function call on line 92 makes the contents of the command table present in basic.ma available as MicroStation key-ins. In this case, the user can key in OPENMODAL to display the "Basic Modal Dialog Box", instead of clicking on the "Open Modal" push button.
The text, option button and toggle button item resources defined in basic.r refer to the basicGlobals variable that is defined on line 65. Lines 96 and 97 publish this variable and its structure declaration to the C expression handling functions. The dialog box manager can then evaluate the strings in the item resources that refer to the basicGlobals variable (see lines 104, 115 and 143 in basic.r). See "Referencing application variables from resource files" in the "MicroStation Dialog Box Manager Overview" chapter for more information.
The DialogHookInfo array defined on lines 68-72 establishes the connection between hook function ID numbers and MDL function addresses. The mdlDialog_hookPublish function call on line 99 informs the dialog box manager of these connections.
Line 101 opens the Basic Dialog Box.
There are two hook functions used in this application: basic_dialogHook and basic_toggleButtonHook.
The basic_dialogHook function is attached to the "Basic Dialog Box." When it receives the DIALOG_MESSAGE_DESTROY message for this dialog box, it forces the basic application to be unloaded by queueing up the MicroStation MDL Unload command (see line 130).
The basic_toggleButtonHook function is the item hook function that is attached to the toggle button item in the "Basic Modal Dialog Box." Every time that a modal dialog box is opened, all of its items are sent DITEM_MESSAGE_CREATE messages. When the basic_toggleButtonHook function receives this message, it sets the application variable that the toggle button controls to 0, basicGlobals.parameter2 (see line 159). This ensures that the toggle button will always be "off" when the "Basic Modal Dialog Box" is opened. Note that this only works for the Create message - the DITEM_MESSAGE_INIT message cannot be used. The Init message is sent after the toggle button has already been initialized from the value of its underlying application variable; setting basicGlobals.parameter2 to 0 at this time would thus be incorrect.
The dialog box manager can be told to print out information on all messages sent to dialog boxes and dialog box items that have hook functions attached to them. The basic_dummyItemHook function is attached to items that normally would not require an item hook function so that the dialog box manager will print out information on the messages sent to those items. The item hook function does not however perform any useful action. The basic_dialogHook function is attached to the "Basic Modal Dialog Box" so that the dialog box manager will print out messages sent to the dialog box. The dialog hook function returns immediately if it receives any messages for that dialog box.
To see the flow of the dialog and item messages that the dialog box manager sends, enter the following commands before starting the basic application:
DMSG DIALOGDEBUG ON DMSG ITEMDEBUG ON DMSG VERBOSEDEBUG ON
See the "Tracking hook function messages" section in this chapter for more information on debugging dialog box manager messages.
The basic_openModal function is called whenever the user keys in the basic application's Openmodal command or clicks the "Open Modal" push button. basic_openModal calls mdlDialog_openModal with a dialog box resource ID of DIALOGID_BasicModal to open the "Basic Modal Dialog Box" (see line 187). mdlDialog_openModal doesn't return to its caller until the user has dismissed the open modal dialog box. At that time, the lastAction variable is set to indicate which of the two standard push buttons the user clicked on to dismiss the modal dialog box.
basic_openModal checks to make sure that the user has clicked the "OK" push button and that the toggle button has been turned on. If both of these tests are passed, it increments basicGlobals.parameter1 (setting it back to 1 if it becomes greater than 3). It then forces the text and option button items to be redrawn to reflect the new value of basicGlobals.parameter1 by calling mdlDialog_synonymsSynch. This function "synchronizes" all of the items listed in the specified synonym resource. In other words, the items' appearances are forced to match the value of their underlying application variables.
The basic_errorPrint function loads a string from the MESSAGELISTID_BasicErrors message list and displays it in the "Dialog Box Manager Messages" dialog box. The errorNumber parameter indicates which string to display.
23 /*----------------------------------------------------------------+ 24 | | 25 | Function - | 26 | | 27 | "Basic Dialog Example" Command Table Resources | 28 | | 29 +----------------------------------------------------------------*/ 30 /*----------------------------------------------------------------+ 31 | | 32 | Include Files | 33 | | 34 +----------------------------------------------------------------*/ 35 #include 36 #include 37 /*----------------------------------------------------------------+ 38 | | 39 | Local Defines | 40 | | 41 +----------------------------------------------------------------*/ 42 #define CT_NONE 0 43 #define CT_BASIC 1 44 /*----------------------------------------------------------------+ 45 | | 46 | "Basic dialog example" commands | 47 | | 48 +----------------------------------------------------------------*/ 49 Table CT_BASIC= 50 { 51 {1, CT_NONE, INPUT, NONE, "OPENMODAL"}, 52 };
The basiccmd.r file is a resource source file that contains the command tables for the basic application. In this case there is only the main command table, which is identified by the constant CT_BASIC. Within the main table there is only one command: Openmodal. The Openmodal command has only one command word, "OPENMODAL," has no subtables or options, and is of the INPUT command class.
The MicroStation resource compiler, rcomp, is used to generate the header file basiccmd.h and the resource file basiccmd.rsc from basiccmd.r (see lines 42 and 43 of the makefile basic.mke). The header file basiccmd.h, which is shown in the next section, defines the command number CMD_OPENMODAL that is associated with the Openmodal command.
The Openmodal command is automatically placed in MicroStation's input queue when user clicks on the push button labeled "Open Modal" (see line 130 of basic.r). When MicroStation processes the Openmodal command it will call the basic_openModal function to perform whatever actions are required (see lines 179-183 of basic.mc).
See "Compiling an Application Command Table" for more information about command tables.
1 #define CMD_OPENMODAL 0x01000000 /* INPUT */
The basiccmd.h file is created from the basiccmd.r file by the rcomp resource compiler. It contains the command number associated with the basic application command Openmodal.
The basiccmd.h header file is included in the files basic.r and basic.mc. The push button resource defined in lines 127-132 of basic.r uses the symbolic constant CMD_OPENMODAL to specify the command to place in the input queue when the user clicks on the push button. The basic_openModal function definition on lines 179-183 in basic.mc uses CMD_OPENMODAL to indicate that basic_openModal should be called whenever the Openmodal command is seen on the input queue.
30 #include "basic.h" 31 publishStructures(basicglobals);
This type of definition file is used to generate type declaration resources for the BasicGlobals structure. This is necessary because a variable of type BasicGlobals is referenced by C expression strings in the resource file basic.r (lines 104, 115 and 143).
The header file basic.h contains the declaration of the BasicGlobals structure and thus must be included in basictyp.mt. The publishStructures statement indicates that type declaration resources should be built for the structure whose tag is basicGlobals. The rsctype utility program, under the direction of line 48 of the makefile basic.mke, generates these resources and places them in the resource source file basictyp.r.
See "Generating Resource Files from C Type Definitions" and "Referencing Application Variables from Resource Files" for more information on type definition files.
The message file is located in the english directory, and contains the messages used by the application. It is separated from the other files so that it can easily be customized for any language the developer wishes.
23 /*----------------------------------------------------------------+ 24 | | 25 | Function - | 26 | | 27 | Basic application message string resources | 28 | | 29 +----------------------------------------------------------------*/ 30 #include /* dlog box manager resource consts & structs */ 31 #include /* MicroStation resource IDs */ 32 #include "basic.h" /* basic dialog box example consts & structs */ 33 /*----------------------------------------------------------------+ 34 | | 35 | Error Messages | 36 | | 37 +----------------------------------------------------------------*/ 38 MessageList MESSAGELISTID_BasicErrors= 39 { 40 { 41 {ERRID_CommandTable, "Unable to load command table."}, 42 {ERRID_BasicDialog, "Unable to open Basic dialog box."}, 43 {ERRID_ModalDialog, "Unable to open modal dialog box."}, 44 } 45 };
Lines 38-45 define a message list resource that contains error messages. If all of the text strings of an application are defined in a resource file, those strings will be much easier to translate into a different language. In fact, internationalization of this example can be done without access to the basic.mc source file. The steps required to internationalize basic are as follows:
1. Create the intermediate file basic.mi by combining the program file (basic.mp) with the command table and type resources (basiccmd.rsc and basictyp.rsc). 2. Give copies of basictxt.h and basicmsg.r to the translators for internationalization. In addition, give them basic.r in case they need to resize any dialog items to accomodate longer strings, and give them the basic.mi file. 3. When the translators have finished their internationalization, they compile basicmsg.r into basicmsg.rsc and then compile basic.r into basic.rsc. Note that basic.r must be compiled whether it was changed or not because it includes basictxt.h. 4. Once basic.rsc and basicmsg.rsc are ready, they can be combined with basic.mi to create an internationalized version of basic.ma.
The text file is located in the english directory, and contains the text strings referenced by dialog boxes as labels for the dialog box, dialog items and items subentities. It is separated from the other files so that it can easily be customized for any language the developer wishes.
23 /*-----------------------------------------------------------------+ 24 | | 25 | Function - | 26 | | 27 | Static text defines for the basic application | 28 | dialog resources | 29 +-----------------------------------------------------------------*/ 30 #if !defined (__basictxtH__) 31 #define __basictxtH__ 32 #define TXT_BasicDialogBox "Basic Dialog Box" 33 #define TXT_BasicModalDialogBox "Basic Modal Dialog Box" 34 #define TXT_Parameter1 "Parameter 1:" 35 #define TXT_OpenModal "Open Modal" 36 #define TXT_IncrementParameter1 "Increment parameter 1?" 37 #define TXT_Value1 "Value 1" 38 #define TXT_Value2 "Value 2" 39 #define TXT_Value3 "Value 3" 40 #endif
18 #--------------------------------------------- 19 # Define macros specific to this example 20 #--------------------------------------------- 21 %if defined (_MakeFilePath) 22 BaseDir = $(_MakeFilePath) 23 %else 24 BaseDir = $(MS)/mdl/examples/basic/ 25 %endif 26 27 privateInc = $(BaseDir) 28 29 #--------------------------------------------- 30 # mdl.mki contains the default rules for creating .rsc, .mo, etc files 31 # mdlexmpl.mki contains the output directory overrides used by examples 32 #--------------------------------------------- 33 %include mdl.mki 34 35 #------------------------------------------------------------------- --- 36 # Create needed output directories if they don't exist 37 #------------------------------------------------------------------- --- 38 $(o)$(tstdir) : $(o)$(tstdir) 39 40 $(rscObjects)$(tstdir) : $(rscObjects)$(tstdir) 41 42 $(reqdObjs)$(tstdir) : $(reqdObjs)$(tstdir) 43 44 #------------------------------------------------------------------- --- 45 # Define macros for files included in our link and resource merge 46 #------------------------------------------------------------------- --- 47 basicObjs = \ 48 $(o)basic.mo \ 49 $(mdlLibs)ditemlib.dlo 50 51 basicRscs = \ 52 $(o)basic.mp \ 53 $(o)basiccmd.rsc \ 54 $(o)basictyp.rsc 55 56 #--------------------------------------------- 57 # Generate command table include & resource file using rcomp 58 #--------------------------------------------- 59 $(genSrc)basiccmd.h : $(BaseDir)basiccmd.r 60 61 $(o)basiccmd.rsc : $(BaseDir)basiccmd.r 62 63 #--------------------------------------------- 64 # Create & compile the application's type resource file using rsctype 65 # and rcomp 66 #--------------------------------------------- 67 $(o)basictyp.r : $(BaseDir)basictyp.mt $(BaseDir)basic.h 68 69 $(o)basictyp.rsc : $(o)basictyp.r $(BaseDir)basic.h 70 71 #--------------------------------------------- 72 # Compile the MDL source file using mcomp 73 #--------------------------------------------- 74 $(o)basic.mo : $(BaseDir)basic.mc $(BaseDir)basic.h 75 76 #--------------------------------------------- 77 # Link MDL program file from basic.mo & ditemlib.dlo using rlink 78 #--------------------------------------------- 79 $(o)basic.mp : $(basicObjs) 80 $(msg) 81 > $(o)make.opt 82 $(linkOpts) 83 -a$@ 84 $(basicObjs) 85 < 86 $(MLinkCmd) @$(o)make.opt 87 ~time 88 89 #--------------------------------------------- 90 # Merge the dialog resources & MDL program file using rlib 91 #--------------------------------------------- 92 $(reqdObjs)basic.mi : $(basicRscs) 93 $(msg) 94 > $(o)make.opt 95 -o$@ 96 $(basicRscs) 97 < 98 $(RLibCmd) @$(o)make.opt 99 ~time 100 101 # complete construction of the .ma by getting the last resource. 102 103 %include $(BaseDir)basicrsc.mki 104
The bmake utility uses the makefile basic.mke to automatically build the basic.ma application file from its component parts.
Lines 21 through 27 define some macros to specify directories where various files can be found or placed. In particular, BaseDir is set to be the directory where the source files for the basic application will be found.
Line 33 includes the file mdl.mki (the .mki extension indicates that the file is a makefile header file). mdl.mki is a handy header file that defines the most useful rules to use when creating a file with one extension from a file of another extension. Most of the dependency lines in basic.mke use the rules from mdl.mki and do not have to specify any explicit build commands.
Lines 47-49 define the macro basicObjs as the two files basic.mo and ditemlib.dlo. This macro is used when creating the MDL program file basic.mp.
Lines 51-54 define the macro basicRscs to be the files basic.mp, basiccmd.rsc and basictyp.rsc. This macro is used when creating the MDL intermediate file basic.mi.
Line 59 specifies that the command number header file basiccmd.h should be generated from the command table file basiccmd.r. A rule from mdl.mki indicates that the rcomp resource compiler performs this operation.
Line 61 specifies that the resource file basiccmd.rsc should be generated from the command table file basiccmd.r. A rule from mdl.mki indicates that the rcomp resource compiler performs this operation.
Line 67 specifies that the resource source file basictyp.r should be generated from the type definition file basictyp.mt. A rule from mdl.mki indicates that the rsctype utility performs this operation.
Line 69 specifies that the resource file basictyp.rsc should be generated from the resource source file basictyp.r, which was itself generated in line 41. A rule from mdl.mki indicates that the rcomp resource compiler performs this operation.
Line 74 specifies that the MDL object file basic.mo should be generated from the MDL source code file basic.mc. A rule from mdl.mki indicates that the mcomp MDL compiler performs this operation.
In lines 79-87, the MDL linker mlink is used to link the MDL object file basic.mo with the dialog box manager library file ditemlib.dlo. The output of this linkage is the MDL program file basic.mp. Lines 81-85 create the temporary response file make.opt that is then read by the MDL linker on line 86. This avoids exceeding DOS command line length limits. Notice that the basicObjs macro is used to specify both the dependency list and the list of files that need to be linked.
In lines 92-99, the separate resource files basic.mp, basiccmd.rsc and basictyp.rsc are combined by the rlib resource librarian into the intermediate file basic.mi. Lines 94-97 create the temporary response file make.opt that is then read by the resource librarian on line 98. This also avoids exceeding the limits on the length of a DOS command line. Notice that the basicRscs macro specifies both the dependency list and the list of files that need to be merged.
At this point, all the language generic components of the basic application have been built.
Finally, in line 103, the basicrsc.mki file is included (the .mki extension indicates that the file is a makefile header file). basicrsc.mki is a header file which defines the final steps necessary for building the languaging specific portions of the basic application.
18 basicRscs = \ 19 $(reqdObjs)basic.mi \ 20 $(rscObjects)basic.rsc \ 21 $(rscObjects)basicmsg.rsc 22 $(rscObjects)basic.rsc : $(BaseDir)basic.r $(langSpec)basictxt.h \ 23 $(privateInc)basic.h \ 24 $(genSrc)basiccmd.h 25 $(rscObjects)basicmsg.rsc:$(langSpec)basicmsg.r $(privateInc)basic.h 26 $(mdlapps)basic.ma : $(basicRscs) 27 $(msg) 28 > $(rscObjects)make.opt 29 -o$@ 30 $(basicRscs) 31 < 32 $(RLibCmd) @$(rscObjects)make.opt 33 ~time
Lines 18-21 define the macro basicRscs to be the files basic.mi, basic.rsc and basicmsg.rsc. This macro is used when creating the MDL application file basic.ma.
Lines 22-24 specify that the resource file basic.rsc should be generated from the main application resource source file basic.r. Notice that this file is dependent upon the basictxt.h header file which contains the dialog label definitions for all dialog box related resources. As described earlier, the rule from mdl.mki indicates that the rcomp resource compiler performs this operation.
Line 25 specifies that the resource file basicmsg.rsc should be generated from the main application resource source file basicmsg.r. As before, the rule from mdl.mki indicates that the rcomp resource compiler performs this operation.
Finally, in lines 26-33, the separate resource files basic.mi, basic.rsc and basicmsg.rsc are combined by the rlib resource librarian into the application file basic.ma. Lines 28-31 create the temporary response file make.opt that is then read by the resource librarian on line 32. This also avoids exceeding the limits on the length of a DOS command line. Notice that the basicRscs macro specifies both the dependency list and the list of files that need to be merged.