Getting Started With MDL (Microstation Development Language) Programming

In this article we will discuss the basic method of MDL programming.

First chapter, the basic methods MDL Programming

The MDL language is for the C programming language, therefore, we have a look at the C programming language; the basic methods and how to use them inside MDL Law. The iintent of this chapter is not to teach you how to use the C language programming, there are many books about that. We assume that the reader is already familiar with the C programming language, it only involves a number of necessary MDL C functions. Here we discuss the basic methods of MDL programming.

The basic concept

The MDL language is a structured programming language for building an application of the standard commands, functions and objectives. We would like to briefly describe the MDL as in the following.

MDL is a language that uses C structures, with its own run-time libraries, compiler, linker, library management process Sequence, and Micro Station environments.

This book will go beyond the programming language MDL. It is a foundation for developing Micro Station Application tools. Before we begin the preparation of MDL code, we should have some terminology, standards and conventions clear.

MDL program structure

The MDL procedure is a MDL language in accordance with the rules of combining a collection of statements. Program statements include the following:

  • ? Control structure or description (declaration) statements
  • ? Assignment Statements
  • ? function / procedure call statements
  • ? pre-processing directives
  • ? Notes

These statements are combined into the MDL program as a text file, using the extension ". Mc". We write an MDL program with a string to draw a box around the same time, extending from the box on a lead. We will see it as a typical MDL program
example. We will then use the new elements to make a unit. The program name is "" (see Figure 1.1). There are vmany ways to write this program. While you read this book you will note there are many changes in this program, complete the procedures listed in this chapter.
Finally, we will learn it step-by-step.


Note that the purpose is for the reader to understand the procedure, but also to enable programmers to modify the program to understand the procedure functions. The forward slash and asterisk (/ *) starts, and the opposite sign (* /) ends a comment. The The compiler will ignore the comments. MDL does not support nested comments.
In Micro Station V8, of course, it is also possible to use double slashes (/ /) on a single line for comments.

Contains the file

Contains the file is such a file that is included in the compile-time pre-processing program read into the program for use of the MDL source code. Sometimes also called the header include file documents, because they are at the beginning of the source.

We can put the common constants in a separate document, then various programs can include this file to ensure that these constants are consistent. There are two definitions of the include file method:

# include <mdl. h>

Figure 1.1 PLBOX the results of running

The convention is to use ". H" for the file extension. If you use angle brackets then the pre-processing program attempts MDL contains mesh Recorded.

Bentley \ Program \ Micro Station \ mdl \ include will find the <mdl. h> file.

Or, we can put the file name in quotation marks, that informs the preprocessing program to contain the file that contains the file description statements directory to find the package with the file.

# include "plbox.h" / * Generated by "rcomp-h plbox.r" * /

How do we know which one to use with documents? All the file names are listed in the <<MDL ??>. For example, when we use mdlText_extractShape, it must contain the <mselems. h> file. These documents can be included within Micro Station.

In the ... Bentley \ Program \ Micro Station \ mdl \ include directory to find.

In the Plbox. mc program, will use the following include files:


? Include Files ?


#include <mdl.h> /*system include files*/

#include <global.h>

#include <mselems.h>

#include <userfnc.h>

#include <rscdefs.h>

#include <tcb.h>

#include <plbox.h> /*Generated by rcomp:h plbox.r" */

Finally, an include file plbox.h should arouse attention because it consists of a resource file compiled betrayals. The second chapter has further explanation of the Resource file.

Micro Station V8 introduced the new file type ". Fdf", they are function definition files (Function Definition File). These documents contain certain category MDL function prototypes definitions, while another might include files references. Therefore, for V8 programming you will see we often simply procedures beginning contains these. Fdf documents do.

Variable Description

We use a variable before you must first define it. In most cases, at the beginning of program design we will not know which variables will be used. In this section we assume you already know what variables aree needed. Using MDL there are many approaches for definitions of variables, we wll see the basic concepts for explanation.

Definition of variables

The term "variable" means that names and memory addresses are linked. The amount of memory needed to store the variable depends on the variable type. The term "address" iindicates a variable storage address. For example, the value of an integer variable count is 20, its address is given by the & count. That is, the "&" symbol is the number back to count the address, rather than count the value of, this is a very important concept. Many programmers do not understand variables and that leads to errors. It addresses the meaning of the program generated many problems.
MDL is a language-sensitive pairs of uppercase and lowercase letters. When you define a variable or function name it should be firmly borne in mind. For example, the variables linePts and LinePts are different.

Variable Types

How variable the variable type definitions for storage and which operate it. The basic variable types are short, int, float,doublet, and char.

The following table defines the various MDL variable types.

Types of storage values:


short integer : 3 2, 678 ~ 3 2, 767
unsigned short integer 0 ~ 65,535
int integer - 3 2, 678 ~ 3 2, 767
long int integer -2,147,483,648 ~ 2, 147,483,647
unsigned int integer 0 ~ 65,535
unsigned long int integer 0 ~ 4,294,967,265
float by d o u b l e-type treatment
double with 6 or 7 significant digits of the floating-point
char ASCII character value, or integer:127 ~ 128
unsigned char integer 0 ~ 255

Variable scope

Variable description of the scope of the definition of variables for which part of the program. In order to determine the scope of variables, an MDL program source code according to the level Divided into many pieces.

A block can be a program or a function. The entire file can be considered as a block. Blocks can be nested in other blocks, so a block in the external variables are defined by all nested blocks recognition. An internal block defined in the variable name with an external block.

Variable the same name

In this case, the internal block variable will replace the external block variables, but this is only limited in-house within the scope of the block.

In this case, the internal block variable is considered local variables. Their values and their presence only by those who explain the function of the commitments that they Recognition. Global variable was MDL program for your recognition of all the functions.

Static variables and automatic variables

A variable has a storage type. Categories decide how to store a variable storage, how long it lives, as well as in the program where the variable names can be be referred to. If we describe the function of a variable to not do special treatment then it is an automatic variable. This means that when we call a function, the variable is automatically generated, when we leave this function it is abandoned. Sometimes, the need to retain the function is assigned to local variables. The final value of the static modifier static compiler directives are stored from a call to the next call to a local variable's value. A default variable is automatically a variable. Global variables may be static (in the MDL source module called by any recognized, but not by other source modules used).

If a global variable is not described as static then it can also be used by other source modules. In our example PLBOX, we need to define two functions for all of our global variables, we need to accommodate 128 to define a string variable textin, it is noteworthy because the "type" buffer is of 128 characters.

They define variables pntP to hold the data points.


¦ Private Global variables ¦


static char textin[128];

Dpoint3d pntP[2];

MDL internal variables

MDL provides global variable for our programs. Since they loaded in the compilation process, we need not go through the definition of a direct with these variables. Many internal variables are the structure or joint. For example, the variable * tcb is a design document that contains all the current information in a knot structure. If an internal variable with a simple type, such as int, contains the header files then it does not need to. However, if the internal type is a structure or union or a structure or union pointer points to, then it must include the appropriate header files. Details on the header files please refer to the appendix.


Type Variable Description
short dgnbuf [] containing the dgnbuf all the information in the current element. All Element or elements through the positioning operation commands into the buffer
MSStateData statedata Containing the current state of the function, all of the information, in the <global. h> is defined in
Tcb * tcb current DGN file that contains all the information in the <tcb. h> is defined in
Mgds_modes mgds_modes contains information on Micro Station current means of implementation, in the <global. h> in the definition of
byte cmplx-hdr []  If the element is a complex head, compared to TRUE. For example, The following is true: cmplx_ hdr [CELL_TYPE]
char mgdsPrompt [35] contains the prompt character, the default is "nStn>"
short element-drawn [s]  is an element of each type of office it is a bit mask, if the element is to display the bit is set
short hex msversion Micro Station current version number, 16
short database connected to the database, compared to true
int mdlErrno a variety of MDL function, the error message number
MSGraphConfig graphConfig contains graphics configuration, defined in<global.h>
Int error number  a variety of operating systems functions
Long mdlCommandNumber start MDL application that contains the most recent order number

MDL function

There are two kinds of function types, pre-defined functions and generated functions. In order to use a function, you can access it must be set before the Meaning it. In order to use the predefined function, must be the beginning of our consultation document have the correct include files. MDL offers two different sets of pre-defined functions, namely, the standard C function and MDL-specific functions (with prefix mdl).

This book does not include the interpretation of the standard C function. You can find them in many C language tutorials. MDL supports the following standard C functions.

File operations, input and output: fclose, leof, ferror, fflush, fSetc, fgets, fopen, fprintf, fputc,fputs, fread, freopen, fscanf, fwrite, fseek, ftell, getc, printf, putc, remove, rename, rewind,sscanf, setbuf, setvbuf, sprintf, tmpfile, tmpnam, ungetc, unlink, vfprintf, vprintf, vsprintf.

This book does not include the interpretation of the standard C function. You can, in many C language tutorial to find them. MDL supports the following character classification and conversion:

isalmum, isalpha, iscntrl, isdigit, isgraph, islowcr, isprint, ispuct, isspace, isupper, isxdigit, toascii, tolower. toupper.

String Manipulation: strcat, strchr, strcmp, strcmpi, strcpy, strcspn, strlen, strlwr, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, strok, strupr.

Cuncun allocation, buffer management and data conversion: atof, atoi, atol, calloc, exit, free, getenv,malloc, memchr, memcmp, memcpy, memmove, memset, rand, realloc, srand, strlod, strol, strloul.

Math: acos, asin, atan, atan2, ceil, cos, cosh, exp, labs, flooy, fmod, frexp, log, log1O, ldexp, ntodf, pow, sin, sinh, sqrt, tan, tanh.

Date and time: sctime, ctime, difftime, gmtime, localtime, strftime, time.

Variables: va_arg, va_end, va_start. MDL supports ANSI and K & R control variable approach.

main Function

Although not an MDL program must contain a main function, it is rare for there to be no main function. In MDL the main function serves three kinds of purposes.

Main is the initial entry. It is essentially an initial function. The main function returns to Micro Station when the MDL program is still resident (except for a program to uninstall MDL).

Main ()


RscFileltandle rfHandle;

/*load our command table */

if(mdlparse_loadCommandTable (NULL)= NULL)

mdloutput_error ("Unable to load command table.");

mdlResource_openFile (&rfHandle,NULL, FALSE);

mdloutput_prompt ("Key-in in place BOX to execute");


The main function will load the command table Micro Station. In the next chapter we will discuss the order form and resource file.

Display Information

The Micro Station command window can display the information divided into six areas. These six areas are, the wrong information domain (er-ror), prompted the domain (prompt), the command field (command); type the domain (keyin), information field (message), and the status field (status).

  • If the tcb-> control.inh_msg Set to a non-zero value, we can ban all the information sent to these domains.

  • If the tcb-> cont, such as rol.inh__err set to a non-zero value, letter Number of mdlOutput__error will not display information.

    Information function are summarized as follows:

  • mdlOutput_ error In the command window to display information within the designated areas

  • mdlOutput_ prompt

  • mdlOutput_ command

  • mdlOutput_ keyin

  • mdlOutput_ status

  • mdlOutput_ errorU In the command window to display information within the designated areas, these functions ignore the ban-bit

  • mdlOutput_ promptU

  • mdlOutput_ commandU

  • mdlOutput_ keyinU

  • mdlOutput_ messageU

  • mdlOutput_ statusU

  • mdlOutput_ printf According to parameters MSG_MESSAGE,MSG_ERROR,MSG_PROMPt,MSG_STATUS, MSG_COMMAND And MSG_KEYIN

    In any one field as specified in the command window to display information.

  • mdlOutput_ vprintf As above, but according to format string to display information

  • mdlOutput_ rscPrintf In the command window displays Messagelist within the Resource Information

  • mdlOutput_ rscvPrintf As above, but according to format string to display information

Structure and joint

Structure allows us to value various types of relevant combinations. As we will see MDL include file, due to ease of use, the structure has been widely used. In the The following examples, we have defined a structure called the elm_ hdr, and generated a type ELm_ hdr. Here the preprocessor directives # if, # else and # endif are in the following chapter.


¦ ELement Header structure-common to all Micro Station elements ¦

+ ---------------------------------------------------------------*/

typedef struct elm_hdr


UInt16 type; /* element type */


UInt16 reserved:6; /* reserved for future flags - always 0 */

UInt16 archive:3; /* modified or added and not yet committed to history; or conflict*/

UInt16 deletedCmplxHdr:1; /* deleted complex by header */

UInt16 nonModel:1; /* true if this element is file-specific and does not belong in any model */

UInt16 locked:1; /* element is locked */

UInt16 isGraphics:1; /* element is a graphics element, has Dsp_hdr */

UInt16 isComplexHeader:1; /* is a complex header, must have number of elements following its header */

UInt16 complex:1; /* this element is part of a complex element */

UInt16 deleted:1; /* this element is deleted */


UInt16 deleted:1; /* this element is deleted */

UInt16 complex:1; /* this element is part of a complex element */

UInt16 isComplexHeader:1; /* is a complex header, must have number of elements following its header */

UInt16 isGraphics:1; /* element is a graphics element, has Dsp_hdr */

UInt16 locked:1; /* element is locked */

UInt16 nonModel:1; /* true if this element is file-specific and does not belong in any model */

UInt16 deletedCmplxHdr:1; /* deleted complex by header */

UInt16 archive:3; /* modified or added and not yet committed to history; or conflict */

UInt16 reserved:6; /* reserved for future flags - always 0 */


UInt32 elementSize; /* number of words in element */

UInt32 attrOffset; /* offset (in words) from start of element to attributes */

UInt32 level; /* element level */

ElementID uniqueId; /* unique ID of element */

double lastModified; /* last time this element was changed */

} Elm_hdr;

In order to use this structure, we must define the variable type ELm_ hdr, and use the dot operator to access it.

For example, we define the type ELm_ hdr variable hdr:

ELm_ hdr hdr;

In order to change elements of the layer, we will use the statement:


Elements of the Joint

The joint is a special structure, that allows a variable to store multiple types of values. However, there is only one value at any time that can use this variable, that in the Fortran language, the equivalent of "equivalence." TCB variables UCBYT, UCWRD and UCASC are examples of the concept of a joint.

A Joint is a kind that allows us a relatively easy way to deal with a powerful means of data. Consider the following elements of the joint msELementUnion. In this joint, we might add DGNBUF written into every one within the Micro Station element. A fixed element of the first ELm_ hdr is also in the joint.


| name element_unio - union of all element types |


typedef union msELementUnion


Elm_hdr ehdr;

Header hdr; /* NOTE: hdr.dhdr is not valid unless ehdr.isGraphics is set */

Cell_2d cell_2d;

Cell_3d cell_3d;

Line_2d line_2d;

Line_3d line_3d;

Line_String_2d line_string_2d;

Line_String_3d line_string_3d;

Text_node_2d text_node_2d;

Text_node_3d text_node_3d;

Complex_string complex_string;

Ellipse_2d ellipse_2d;

Ellipse_3d ellipse_3d;

Arc_2d arc_2d;

Arc_3d arc_3d;

Text_2d text_2d;

Text_3d text_3d;

Point_string_2d point_string_2d;

Point_string_3d point_string_3d;

Cone_3d cone_3d;

Surface surf;

Bspline_pole_2d bspline_pole_2d;

Bspline_pole_3d bspline_pole_3d;

Bspline_curve bspline_curve;

Bspline_surface bspline_surface;

Bspline_weight bspline_weight;

Bspline_knot bspline_knot;

Bsurf_boundary bsurf_boundary;

Raster_hdr raster_hdr;

Raster _comp raster_comp;

ApplicationElm applicationElm;

ColorTable colorTable;

ReferenceFileElm referenceFileElm;



} MSELementUnion, MSELement;


In this way, we can define MSELementUnion types of variables el:

MSELementUnion el;

When we read one element, we cannot determine what elements. The use of elements of the joint, we can test the elements of a fixed head el.ehdr. In the example below, we can examine a line element, the use of joint that we can access el.line_2d in the same data.



el.Line_2d.start.x +=100;

el.Line_2d.start.y +=100;


Please note that we are a joint member how to use to extract data from the joint, and use another member to operate information. In this example, we have made a 2D line from the right move to move 100 units 100 units.


In the MDL pointer in the right understanding of many errors that may arise. And for the use of variables, we can use int, float, double and char to illustrate the pointer. Consider the MDL in the ordinary usage of the pointer.

Note: The parameter table * PString the definition of variables, in this book, we need to use the ANSI method parameter list defines the type of argument, this method has the advantages of checking the type argument.

private void parselnputstring(char * pString)






if((pResult = strtok(NULL""))! = NULL)




In the preceding example, we see two characters pointers * pString and * pResult. An asterisk (*) tell the program to store the pointer pString within the memory address to find the string value.

Passed by reference

There are two ways to pass parameters, namely, passed by value and passed by reference. When we come to passing parameters by reference, we give the address of variables to receive parameters. Therefore, the argument is called the program to change the call to any change in the value of program variables, because both share the same memory address. We need to pass a string by reference. We can address by using a pointer pointing to a string to do a string of passes, when a string is aAn array of characters when we do not need to use &, and MDL are used in all references to pass an array.

For example, the following note tells us that the string must be treated as a pointer to it passed to the parselnputstring.

Char string [20]; /*definition of string on main program*/

parseInputstring(string);/*pass the string into our function*/

Private void parselnputString(pstring) /*pass itby reference*/

char *pstring; /*define as a pointer*/

Back to looking at our main function, structure, rfHandle as a pointer to pass. Character (&) is the address operator. It is returned to the memory address of a variable, rather than the variable value.


Program mdlResouce_openFile is a predefined function. When we find it in the MDL manuals, we will see the first one variable must be
Shall be a pointer. By using the & symbol in front of rfHandle, we have provided the correct format to the function variables.

Passing by value

We can also pass variables by value. In other words, this variable has been assigned at the same time, this value is copied to the receiver parameters. Is called the program variables change is local. When the program is the end of its value will be lost. See the following examples, the process should be placed in view, a 2-arc. Which, viewNumber passed by value. Whether we have done right to receive parameters, when we complete the call, the variable is not changed.



Private void placeArcbyCenter (int view)


MSELementUnion arc;

Dpoint3d arcp[3];

double origin;

arcp[0].x=25.; /*start point*/


arcp[0].Z=fc_zero; /*floating point constant*/

arcp[1].X=55.; /*center point*/


arcp[1].Z=fc_zero; /*floating point constant*/

arcp[2].X=85.; /*end point*/


arcp[2].Z=fc_zero; /*floating point constant*/








Note: MDL arrays are consistent with C language conventions, from 0. For example, in the preceding definition of Dpoint3darcP [3], the array subscript is arcp [0], arcp [1], and arcp [2].

Function pointer

In the MDL, we can put the address of the function as an argument to pass. Therefore, the program can reference the value of a pointer to call this function.

Function pointers are widely used in MDL. For example, the function mdlState_startPrimitive asks the former two variables that are pointing to a function pointer.

mdlstate_ startPrimitive(placeBOX_ FirStPOint, placeBOX_ start,1,2):

Function PlaceBox_ firstPoint and placeBox_ Start appear to be references to their previous. We can start in the program where the definition of the function name to meet this requirement; or call the function it had previously appeared with complete (this is the usage throughout the book).

Micro Station: state machine

Micro Station is an event-driven machine. That is, at any point, an incident Micro Station into a given state, and a state of the handler to process its input. We can call to place online orders and PLACELINE the first demonstration of a point. When we move the cursor, the second point, like pulling a rubber band, like moving across the screen, we will choose WINDOWAREA the command and select the new window, rather than the second given data points. In the Windows update, this line has been eliminated. As a state machine, the Micro Station command state can be distinguished. View the command-line commands and put a different state. Therefore, we can assume that this line is still active, press the reset button so that we exit the view command and return to place the command line.

Figure 1.2 Micro Station input process

We can write an MDL program to deal with the establishment of a state function or type of information, such as data points such as input information. In this way we can enter the Micro Station basic (primitive) level. We write any of MDL applications, there will be more convenient, and does not require additional programming.

The other Micro Station programming tools, such as the UCM and MicroCSL, is to line up Micro Station commands. By Figure 1.3 we can see, UCM, and MicroCSL in the input queue, task distribution, and circulation among the external applications. Therefore, the state ordered the distribution layer applications will be out of control.


Resource is a group called the resource file being stored in the data. A typical data set is a string, an error message, raster icons and order form. The use of resources purpose of the paper is to separate the data and application source code. Using this method has many advantages.

  • To reduce the overall memory requirements, because only the data is required for the installation.

  • Multiple applications can share the same resource.

  • Easy maintenance. Tips and information on the changes without changes to the application. For example, you can integrate applications into other languages, such as French.

In later chapters, we will discuss the resources and the generation method.

Command Table

Bottom of the main program from the resource file to install the application command table. Command table defines a command language. For exercise, we assume that the main will command PLACEBOX into Micro Station. In later chapters, we would also like to discuss the order form.

main ()


RscFileHandle rfHandle;


mdloutput_error("Unable to load command table.");


mdloutput_prompt("key-in PLACE BOX to execute");


Here we tell Micro Station, our application order merely exists, we do not have enforcement procedures. This is the strength of the MDL. It allows application developers to enter the Micro Station "basic" level. We now define a group called PLACEBOX with the basic commands.

In order to activate our MDL process, we should get the uStn> prompt, type PLACE BOX. Microsration does a word-by-word analysis of our typing. Therefore, only type PLACE will have a vague command. Micro Station can not distinguish it from  PLACELINE. Generate a named PLACEBOX basic commands will not be able to use the command table, because the command is not level, so that the command can not be classified. Command category is very important, it allows Micro Station decisions or the allocation of the current state of the application. In our application to generate the command PLACEBOX table, we need to discuss this issue in detail.

When the Micro Station has successfully analyzed the user's typed message, it generates an order number. An application with the command the task of linking the ID and the command ID is used to determine the application of the implementation of this command and calls this function. In the following program, cmdNumber to function placeBox_start and a command number combination. When we type PLACEBOX time, MDL began PlaceBox_ start implementation.

cmdName placeBOX_start()

The program mdlState_startPrimitive state function will be established in order to use a data point to activate PLaceBOx_firstpoint, a rest will loop implementation placeBOx_start. At the same time, it will generate information form number from 0 to 1, information, and it appears in the command field, while the No. 2 information displayed in the prompt field. In the second chapter we will discuss the interest rate table and its generation method.

State Control Function

A Micro Station command sequence is composed of an application, another application in the implementation of its final prior to the end of a command. PLACELINE in the implementation of the command, the implementation of a user command to open the window, it should be clear tips: WINDOW AREA. Write an event-driven applications as the MDL procedure does not make this application to be suspended. Determine the number of functions to control the incident. In this section we will discuss the state of various control functions, these functions are the core of MDL programming. There are four Micro Station command states.

  1. Basic commands are used to generate, modify and delete elements. Start a basic command will terminate on the one basic commands, and the basic commands in another one to replace it until the order has been in active. Start a basic command must be called about the command:

    mdlstate_ startPrimitive: Start only the basic commands used to generate the elements.

    mdlstate_ startModifyCommand: Start one for the place and modify the elements of the basic commands.

    mdlstate_ startFenceCommand: The establishment of a basic command to operate a function of the fence.

  2. View Order Status

    The View command modifies or updates the view. We need to start calling the mdlState_startViewCommand view command. Start a view command will hang a basic command, when the view control at the end, hanging up the basic commands continues to work. If the user enters reset then the end of the view that we must mdlState_exitViewCommand life mdlState_startViewCommand command to start a view out of the view mdlState_exitViewCommand command.

  3. Direct order status

    A direct command modifies the settings (such as changing the capture state, or type WT =). Do not call the direct orders of the state function, it does not affect the basic order or view order status.

  4. Utility Command Status

    Practical non-interactive command execution functions such as COMPRESS. In the end we need to use a command called practical

    mdlState_ startDefaultCommand?

The rest of the state control function is as follows:

  • mdlState_clear: Reset command state, so that no command was activated

  • mdlState_checkSingleShot: Check whether a command operations (SingleShot) mode operation

  • mdlState_ dynamicUpdate: The function using a simple dynamic operation of the provisions of

  • mdlState_ registerStringIds: Provides a basic command to start using the tips of information

  • mdlState_ restartCurrentComman: The current basic commands to restart the

  • mdlState_ setFunction: According to the requirement to use a function of the incident

  • mdlState_ setKeyinPrompt: Provisions of the string for the type area, the default value is "nSTN>"

  • mdlState_ startDefaultCommand: After the end of the current command to start the default command

User-Defined Functions

When certain events occur in the Micro Station, MDL with the function pointer to specify the users to perform functions. Function pointer to make programming easy and effective. For example, when certain events occur, the function mdlState_ startModifyCommand the user to perform five functions. These events include user input reset, input data points, or dynamic display. The remaining two parameters display or cleared, is used to display in the DGNBUF been modified elements. Paired with the display and the regular use of clearance in order to clear the display can be restored to its previous function. We can deliver to these arguments are NULL.

The following is a list of user functions: Note: The function name in italics is not a function of the real name. Please use your program to use the function name you use to replace them.

  • userState_ clean: function to modify the function of

  • userState_ CommandCleanUp: in another command need to be cleared before the start of the function to use

  • userState_ complexDynamicUpdate: for complex dynamic display function

  • userState_ datapoint: in the input data points the function is called when the

  • userState_ dynamicUpdate: dynamic display function for simple

  • userState_ fenceContent: a function for processing the contents of the fence

  • userState_ fenceOutline: used to re-display function of the boundary fence

  • userState_ Keyin: Functions for handling the user typed

  • userState_ reset: for handling reset (reset) function

  • userState_ Show: When you modify the command used to display elements when the load DGNBUF a function of

Back to look at our PLBOX example, we need to build the basic commands to place the box. When the user sends data points, the first parameter placeBox-firstPoint is to perform the function pointer. The second parameter is called when a user enters the reset function. In this case, we start recycling and replace the box of the basic commands. The final two parameters define the information on the screen. We will discuss the information table in the second chapter.

cmdName placeBOx()

Event Type Let's look at the function placeBox-firstPoint, it needs to mdlState_startPrimitive coming from a data point. According to information received from the user, we will store the point and the establishment of the state function to be called. Function mdlState-setFunction needs two variables. The first is the type of event, and the second one is to perform the function pointer. Event types possible values are:

  • STATE_ DATAPOINT: When a user enters a data point

  • STATE_ RESET: when the user input when the reset

  • STATE_ KEYIN: When the user key person

  • STATE_ COMPLEX_ DYNAMICS: generate dynamic display, see below

  • STATE_ COMMAND_ CLEANUP: cleared in another order before the start of the current Command

MDL provides the elements to provide a dynamic operation. When the element generation, movement and change can be seen on the screen display of the same rubber band. We need a single element in the dynamic display using a simple dynamic. Complex dynamic is used to display more than one element. mdlState_dynamicUpdate is used for simple and dynamic functions.

For complex dynamic that we need to use mdlState_setFunction. Show a dynamic manner in order to determine, MDL implementation of the user function generatelmage, and to high-brightness display element. Therefore, only a display element, rather than Save. We will discuss the use of PLBOX dynamic display, you will see how this function works.

Private void placeBox_firstpoint


Dpoint3d *pt,

int view



/*save first point*/


/*set the datapoint state function for the second point.*/







As we have seen from the placeBox_firstpoint function, for every possible event that we have established the phaseShould be a state function. Program KeylnText characters were obtained from the input queue and put it in there is a variable textin.

Private void keyin Text()


if (!*statedata.cmdstring)




Should pay special attention to the function generatelmage, because it is every time we move the cursor when the procedure is called. In the downlink, we tell the MDL in a dynamic operation, use this function.


generate lmage will be placed on this string and a box, and to build the line and the box in a corner alignment.

Elements Function

Here's how a single element of the common elements of function, we will discuss in subsequent chapters of the operation of a complex element.

  1. mdl Element _ add add an element of the document

  2. mdl Element _ append an element attached to the file

  3. mdlElement_appendAttributes of an existing element of additional attribute data

  4. mdl Element _ display in all views display elements

  5. mdlElement_displaylnSelectedView appear within the specified elements in the view

  6. mdlElement_extractAttributes extract elements from existing attribute data

  7. mdlElement_getFilepos Returns the element file location

  8. mdlElement_getProperties Returns the element attribute information

  9. mdlElement_getSymbology Returns the element's display line breaks

  10. mdlElement_getType Returns the type of element number

  11. If the element is filled mdlElement_isFilled returns TRUE

  12. mdlElement_offset to move some distance away from elements

  13. mdlElement_read to an element of the buffer read from the design document

  14. mdlElement_rewrite rewrite an existing element

  15. mdlElement_setFilePos file location to establish the elements

  16. mdl Element _ set Properties to establish the element attribute information

  17. mdl Element _ set Sympology to establish elements of the display line breaks

  18. mdl Element _ size number of bytes returned element size

  19. mdl Element _ strip Attributes remove an existing element in all of the attribute information

  20. mdlElement_stroke By an element into a series of vectors to deal with an element of

  21. mdlElement_transform through the transformation matrix to transform an element of

  22. mdlElement_undoableDelete delete a With the UNDO command to restore elements of

Elements generating function

MDL provides some generating function of Micro Station elements can be displayed. These elements are generated in memory. Therefore, the use of the function mdlELement_add The elements written in the document is very important. Elements of the structure <mselems. h> is defined.

To use these functions generate the elements, the encoding and the subsequent separation of the elements of the format change is a good work habits. For the two Micro Station New - size and multi-line, that is clear, <mselems. h> elements of the structure is not detailed.

Generating function of the elements listed below:

  • mdlArc_ create an arc element is generated

  • mdlArc_ createByCenter through the center and two endpoints generate an arc

  • mdlArc_ createByPoint generate an arc by 3 points

  • mdlCell_ create the first element of generating units

  • mdlCircle_ createBy3Pts generated using 3-point circle, oval

  • mdlCone_create generate a cone element

  • mdlCone_createRightCylinder generate a positive cylindrical element

  • mdlCone_create generate a curve element

  • mdlEllipse_create generate an elliptical element

  • mdlLine_create generate a line element

  • mdlLineString_create generate a line string, outline or curve elements

  • mdlPointString_create generate a point string element

  • mdlText_create generate a text element

  • mdlTextNode_create generates a text node elements

We will use mdlText_create generated string. Our approach is not generating any specific string, but is displayed, the need to consider the use of dynamic display.


When we use mdlELement_display displayed on the screen one element may be drawing method is:

Graphical implications

  • NORMALDRAW: using ordinary color picture elements

  • ERASE: erased from the screen

  • HILITE: with high-brightness color painting element in

Provisional elements of painting TEMPDRAW

  • TEMPERASE: wipe temporary graphics

  • TEMPROTATE: use "different" operation or semi-color

  • XORDRAW: use "different" operation

This dynamic program temporary plotted on the screen of our images, and when we move the cursor when you erase it. When we use Closed the second location of the point, the function placeBox-secondpoint be activated, because this state has been established previously State

privatevoid placeBox_secondpoint



int view





Function placeBox_ Secondpoint direct calls generatelmage, and passes to it a ORMALDRAW option. We will use PLBOX elements generates an isolated unit. Call Mdlcell_begin will generate the type 2 unit head. Since then placed on each element will be a part of this module. In generate mage, we will see that NORMALDRAW elements will be added to DGN document.


/*createText in dgnBuffor Micro Station Dynamicsto display*/



if (drawMode==NORMALDRAW)


CellFilepos=mdlCell_ begin(" plbox",&origin,NULL,NULL,O);

mdlELement_ add(&el);


Element extraction function

When we generate a string, it is still in the DGNBUF. Only when we call mdlELement_add, it was only added to the DGN file. Next, we place a rectangle around the string; we can use an element capture function to remove the element of information. These functions allow programmers to retrieve the elements of the information without having to understand the elements of the storage format. The best programmers use these functions, in order to protect their proceedings are not to because the elements of the format is changed.

The following is a list element extraction function:

  • mdlArc_ extract: extract arc or elliptical elements

  • mdlCell_ extract: header information extraction unit

  • mdlCone_extract: cone element information extracted

  • mdlLinear_extract: from a line, line string, contour-shaped, cone-shaped, curve, Polyline or curve to extract coordinate array B

  • mdlLinear_getClosestSegment: from a point close to a linear element to find a line segment near the point

  • mdl Shared Cell _ extract: extract the shared cell instance or its definition of information

  • mdl T ext _ extract: extract text element information

  • mdlText_ extractShape: extract the smallest element of the border around the text

  • mdlText_ extractString: element extracted from the text string

  • mdlTextNode_ extract: extract the text node elements

  • mdlTextNode_ extractShape: returns a text node around the smallest border

We should mdlText_ extractShape be rectangular 5-point (the first point and last point coincide). The fourth variable is set to TRUE, in accordance with the current precision to enable the border to capture a greater extent (and SETLOCATE of typing the same). We do not read from the DGN file string because it's an operation to make DGNBUF already have this string.

mdlText_ extractshape(Shapep.NULL, &el,TRUE,view)


mdlElement_disPlay(&el, drawMode);



The next step in our program is to lead targeting box of the iceberg. Figure 1.3 The point underlined that if we get two points entered by the user will need to draw the line. With this simple geometric method, according to the first quadrant of a point where it is easy to determine the endpoint this line in the rectangular of a suitable corner.

leads to place

The following is to calculate a new endpoint:

if (pntP[0].x < origin.x)


if (pntP[0].y < origin.y)


pntm[1].x=shapep [0].x;

pntP[1].y=shapep [0].y;





pntP[1].x=shapep [3].x;

pntm[1].y=shapep [3].y;





if (pntP[0].y < origin.y)


pntm[1].x=shapep [1].x;

pntP[1].y=shapep [1].y;




pntP[1].x=shapep [2].x;




Once the calculation of a new endpoint, we can use mdlLine_create to place this line. By calling mdlCell_end to close the unit, it uses descriptors to form the elements of number and the correct file pointer changes to unit head

/ * place the modified leader line * /

mdlLine_Create(&el, NULL, pnpt);


if (drawMode = NORMALDRAW)



mdlCell_end (cellFilePos):

We learn from the first MDL program full is as follows:



| Example MDL function to place a box around |

| a text string with a leader line. |



| Include Files |


#include <cmdlist.h>

#include <toolsubs.h>

#include <string.h>

#include <msrsrc.fdf>

#include <msparse.fdf>

#include <msoutput.fdf>

#include <mselemen.fdf>

#include <msvar.fdf>

#include <msstate.fdf>

#include <mssystem.fdf>

#include <msdialog.fdf>

#include <mscell.fdf>

#include <mselmdsc.fdf>

#include "PlaceBox.h"

#include "PlaceBoxcmd.h"

static char textin [128];

Dpoint3d pntP[2];


| name generateImage – dynamic function for box. |


Private int generateImage



int view,

int drawMode



MSElementUnion el;

Dpoint3d origin;

Dpoint3d shapeP[5];

MSElementDescr * pDescr = NULL;


mdlCell_create (&el, "BOX", &pntP[0], FALSE);

mdlElmdscr_new (&pDescr,NULL,&el);

/*create Text in dgnBuf for Micro Station Dymamics to display */

mdlText_create (&el,NULL,textin,&pntP[1],NULL,NULL,NULL,NULL);




mdlShape_create(&el, NULL, shapeP, 5, -1);

mdlElement_display(&el, drawMode);


if (pntP[0].x < origin.x)


if (pntP[0].y < origin.y)


pntP [1] .x=shapeP [0] .x;

pntP[ 1] .y=shapeP[0] .y;

} else {

pntP[1] .x=shapeP [3].x;

pntP [1] .y=shapeP [3].y;


}else {

if (pntP[0].y < origin.y)


pntP[1] .x=shapeP[1] .x;


} else {

pntP[1] .x=shapeP[2] .x;

pntP [1] .y=shapeP[2] .y;



/* Place the modified leader line */

mdlLine_create(&el, NULL, pntP);

mdlElement_display (&el, drawMode);


if (drawMode==NORMALDRAW)





return SUCCESS;



| name keyinText |


Private void keyinText(char *cmdStringP)





| name placeBox_done |


Private void placeBox_done()






| name placeBox_seconPoint |


Private void placeBox_secondpoint


Dpoint3d *pt,

int view






| name placeBox_firstPoint |


Private void placeBox_firstpoint



int view




/*Set the datapoint state function for the second point.*/

mdlState_setKeyinPrompt ("KEY IN TEXT:");

mdlState_setFunction (STATE_KEYIN,keyinText);

mdlState_setFunction (STATE_DATAPOINT,placeBox_secondpoint);

mdlState_setFunction (STATE_RESET,placeBox_done);

mdlOutput_rscPrintf (MSG_PROMPT,NULL,0,3);

/*Setup Rubber Banding function*/

mdlState_setFunction (STATE_COMPLEX_DYNAMICS,generateImage);



| name placeBox_start |


void placeBox_start()






* @description PlaceBox_unloadFunction

* @param unloadType Reason for the unload of the app

* @return SUCCESS to allow the unload; ERROR to disallow the unload

* @bsimethod BSI 06/03


Private int PlaceBox_unloadFunction


int unloadType



BoolInt disallow = FALSE;


| If the value of unloadType is negative, then Micro Station ignores

| the return value of this function. In this case, we can assume

| that Micro Station is shutting down or was terminated so this

| function should not attempt to abort the unload.


if (unloadType < 0)


return FALSE;



** Your processing, which may include setting the disallow flag to TRUE


return (disallow ? ERROR : SUCCESS);



* Dialog/Item Hooks; Command Numbers and Command Names



typedef void (*Handler)(char *);

typedef void (*Hook)();


* @description MdlMain

* @param argc Count of arguments into the function

* @param argv Array of arguments

* @return Return code from the application

* @bsimethod BSI 06/03


Public int main


int argc,

char *argv[]



RscFileHandle rscFileH;



This function opens a resource file, thus making its contents

available to the application. In this case, we need to open as a resource file so that we have access to the the

string lists for our messages.


if (SUCCESS != mdlResource_openFile (&rscFileH, NULL, 0))


mdlOutput_rscPrintf (MSG_ERROR, 0l, MESSAGELISTID_Messages,


/* unload the application */

mdlDialog_cmdNumberQueue (FALSE, CMD_MDL_UNLOAD,

mdlSystem_getCurrTaskID (), TRUE);


/* --- Set up function to get called at unload time --- */

mdlSystem_setFunction (SYSTEM_UNLOAD_PROGRAM, PlaceBox_unloadFunction);

mdlState_registerStringIds(MESSAGELISTID_Commands, MESSAGELISTID_Commands);

mdlParse_loadCommandTable (NULL);

mdlOutput_prompt("Key-in PLACE BOX to execute");

return 0;


Chapter Summary

To learn a new programming language is often very difficult. We believe that the best way is to look at an example. If you find it difficult at this stage, do not despair; just remember the following points:

  1. MDL is based on the C language.

  2. Micro Station is a state machine. Take advantage of this, MDL can enter the basic layer of Micro Station to use it.

  3. State machine means that the command is not necessarily carried out sequentially, but according to the events within the active part of the Micro Station commands.

  4. The user commands and MicroCSL procedures Micro Station commands in sequence. MDL can also do so, but its real power is that it can change according to the state to provide a function call.