Summary: Paper describes how to customize Microsoft Visual Studio IDE with MDL development, how to build up your knowledge base and introduces MDL project wizard for Visual Studio 6.
Date: August 2002 Published in : CAD I/2003 Authors: Stanislav Sumbera download MSDNIntegrator by codejock download sample MSDNfiles (dat,col)
Integrated development environment - IDE Step 1. MDL language syntax highlighting Step 2. MDL built-in functions highlighting Step 5. Integrating MDL help with MSDN Step 6. Advanced customization |
MicroStation Development Environment (MDE) presented on installation of MicroStation unfortunately doesn’t contain any Integrated Development Environment for developing MDL programs. Although you may write MDL code in any text editor, I guess MDL programmers in 21.century deserve more, at least :
· File management
· Syntax highlighting
· Automatically Completing Statements - Intellisense
· Context help
· Comprehensive visual debugger
· Optionally version management for large projects
Using these features will certainly help you in developing process and will positively affect the quality of your MDL application. Although you may use any IDE I would recommend to use Visual Studio v.6 or Visual Studio.NET respectively. The main reason is that you will get with Visual Studio a native compiler used by MicroStation bmake utility to compile MDL into native code (DLL).
Make sure you have installed Visual C++ v.6 with service pack 5 and Microsoft Development Library (MSDN). To set up IDE for MDL several steps need to be done. We will go through them. step by step.
MDL code is C code. We need that Visual Studio recognize file extensions of MDL related files as C-based files. This extensions are primary : .mc; .fdf;.r;.mt;. The information of file extension is stored in registry key:
[HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0\
Text Editor\Tabs/Language Settings\C/C++]
"FileExtensions"="cpp;cxx;c;h;hxx;hpp;inl;tlh;tli;rc;rc2;mc;fdf;mt;r"
Run file VC_MDL_HIGHLIT.reg from folder IDE to update registry entries or extend registry manually by running regedit.exe. Now run Visual Studio, open any .mc file via File/Open menu and see highlighting syntax of code. Go to Tools/Options... menu and select Format tab page. In the Category list select Source Windows; in Font option list choose Courier New font with size 10pt. Then select in Colors option list type of code text and use Foreground and Background items to set its corresponding colors as you wish. Check the Keyword type to be colored.
Wouldn’t be nice to have highlighted all MDL built-in functions as keyword ? We may do this by populating file usertype.dat with all keyword names – in this case all mdl functions. The file must be subsequently copied into the same directory where msdev.exe resides. By default this will be C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin. The file you may download form folder... it contains all mdl functions (even undocumented). Optionally you may add there MDL types or constants. Restart Visual Studio, open arbitrary mc file and see keyword-color of all mdl functions.
Select New... from the File menu to bring up the list shown in Figure. Select Project tab page. From the available projects choose Makefile. On the right side of the dialog, in the Location edit item select parent folder of you project. Type your project name into the Project name edit item. Visual Studio will make the folder according to the Project name (or will use the existing one if the folder with this name already exists). Toggle on option Create new workspace.
Press OK. Next wizard dialog asks for Command line for DEBUG configuration. Visual Studio has basically two configuration for running compilation process: Debug used for debug compilation, and Release, used for final release code. Despite you may use them for compilation, I would recommend to use only one configuration and directly edit batch and make file for any necessary changes in build process.
Delete any content there and type there your project name plus .bat extension, for instance treexmpl.bat. This will be a batch file for running MicroStation compilation. Then type into the Output your final application name, e.g. treexmpl.ma, and you may leave Rebuild All Switch as it is. Press Finish button.
Wizard creates workspace and project with three virtual folders :Source Files, Header Files and Resource Files. Now you may add source files to appropriate folders by clicking right mouse on item and selecting Add Files to Folder.
After adding all files you should be able to see Class View with all structures and functions used in your project. This is very useful for navigation through the code. If Wizard Bar tool box is presented on upper pane (see menu Tools/Customize/ Toolbars ) you may then quickly access function from option list there.
Visual Studio also helps with statement completition features (intellisense) of declared functions and types. If you have checked in Tools/Options dialog in Editor tab options for statement completition you may see parameter list when typing a function, for instance :
Or trying to access members of data structure:
Unfortunately intellisense doesn’t work implicitly for built-in mdl functions. Wouldn’t be this a nice feature when programming with MDL ? Fortunately there is a trick how to force Visual Studio to show parameter info and data members of mdl functions. For each workspace Visual Studio stores browse information in binary .ncb file. Browse information hold records for each entity and where it’s used in our project files. This data are used by intellisense to offer parameter info when typing a function. Intellisense works fine for function definition. MDL built in function are declared in fdf files. So we need to change declaration to definition and include them into Visual Studio project so intellisense would catch them. Of course we cannot and may not overwrite standard mdl function, so this would be only temporary. All files needed are presented in folder ..../intellisense. Here are steps to turn on intellisense for mdl functions:
1. Make new virtual folder in project. Right click on project name in FileView pane, select New Folder and type intellisense. A new folder is created.
2. Right click on the just created folder and choose Add Files to Folder. Insert Files into Project dialog appears. Browse to folder with intellisense mdl files, switch Files of Type on *.* and select all 284 files. Click OK and wait until Visual Studio is ready. it may take few minutes for updating all browse information.Important : I was not allowed to distribute fdf files so you will find them already included in .ncb file inside MDLWizard tool, actually MDLWizard will copy this file for you, or you may copy it manually. if you want however, please mekae copy of all fdf and header files into arbitrary folder and replace fr each function declaracion ";" to definition "{}" please refer to FAQ
3. Delete folder previously created –intellisense in this case.
4. Choose Save All from File menu and close project.
5. Reopen project and the intellisense should work for mdl files and structures.
The intellisense should now work . Note when you delete .ncb file you nee to repeat these steps since new ncb file is created by Visual Studio.
Very often we need to search particular keyword or function definition in help documentation. or in any other supplied help files. Visual Studio provides MSDN help containing all necessary information for developers under Windows platform. Since MDL is C based language we may find there for example a useful C code reference. But I guess you would like to have there a MDL help reference and mdl programmer's guide help files too. Then we need to integrate supplied Bentley help files with MSDN help files.
MSDN stores content information about the help files in XML formatted file called collection. Actually collection uses two files : msdnxxx.col (actual collection) and hhcolreg.dat (collection registry) .We need to find and update these two files to force MSDN to count with Bentley help files. To find these file you may use this VBScrip stored in IDE/Macros.
'1. get Windows Scripting Host and File System objects
Set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
'2. reading registry entry to locate collection file
COLfile = WshShell.RegRead(_
"HKLM\SOFTWARE\Microsoft\HTML Help Collections\" +_
"Developer Collections\0x0409\0x035900940\Filename")
'3.location of dat file in system or setting dirs
DATfile98 = fso.GetSpecialFolder(WindowsFolder)+"\Help\hhcolreg.dat"
DATfile = Replace(WshShell.SpecialFolders("AllUsersDesktop"),_
"Desktop","Application Data\Microsoft\HTML Help\hhcolreg.dat")
'4. print if files exists and open them in notepad
if (fso.FileExists(COLfile)) then WScript.Echo (COLfile):_
WshShell.Run ("notepad " & COLfile)
if (fso.FileExists(DATfile98)) then DATfile = DATfile98
if (fso.FileExists(DATfile)) then WScript.Echo (DATfile) :_
WshShell.Run ("notepad " & DATfile)
the console output of this script could be like this :
C:\Program Files\Microsoft Visual Studio\MSDN98\98VSa\1033\msdnvs6a.col
C:\WINDOWS\Help\hhcolreg.dat
Let’s update collection file msdnvs6a.col. At the end of the file you will find ending tag for collection folders </Folders> . Put before this tag following XML and save file:
<
Folder><TitleString value="MDL api reference"/> <FolderOrder value=2/> <TitleString value="=bentley_mdl_reference"/> <FolderOrder value=1/> <LangId value=1033/>
</
Folder>Updating file hhcolreg.dat require similarly to put before tag </DocCompilations> following XML:
<DocCompilation>
<DocCompId value="bentley_msv8_mdl_ref" />
<DocCompLanguage value="1033" />
<LocationHistory>
<ColNum value="3" />
<TitleLocation value="C:\HELP\MDL_API.chm" />
<IndexLocation value="C:\HELP\MDL_API.chi" />
<QueryLocation value=""/>
<LocationRef value="" />
<Version value="1" />
<LastPromptedVersion value="0" />
<TitleSampleLocation value="" />
<TitleQueryLocation value="" />
<SupportsMerge value="0" />
</LocationHistory>
</ DocCompilation>
Change the value for the tag TitleLocation according your help file location. The key value DocCompId must be unique, best would be GUID identifier and must correspond to the value in key TitleString in previous file. The help index file (.chi) is not in standard help file installation, so in folder IDE/MDLhelp you will find it. Alternatively to this manual setting you may use for help integration utility called MSDNIntegrator which is stored in folder IDE/HelpIntegration. Run this tool and specify chm and chi mdl help files located in IDE/MDLHelp.
After integration run Visual Studio, enter any mdl function and while standing on the function with cursor pres F1. MSDN help will be displayed, after re-indexing its content a description for the function should be displayed. You may add other resources for rich knowledge base as is shown on figure bellow.
Look on sample files: msdnvs6a.col and hhcolreg.dat
|
Macros are pretty cool in Visual Studio. Actually you may write your own VBScript macros to automate tasks when writing MDL code. Macros can reduce boring “copy-paste-rename” workflow in development process. Moreover you may create for your development team code templates and wizards to automate common steps. An example of simple macro for creating mc file based on template is shown bellow .
On Error resume Next
Sub CreateNewMC()
Set fso = CreateObject("Scripting.FileSystemObject")
MCtemplate = fso.GetParentFolderName(Application.Path)+ _
"\template\MDLproj.mc"
'-- prompt for input mc file
fileName = InputBox("Enter name","Add mc file", _
ActiveProject.Name+".mc")
'-- build target mc full name
MCtarget = fso.GetParentFolderName(ActiveProject.Fullname)+ _
"\"+fileName
'-- open template and make selection
Documents.Open MCtemplate
Set doc =
ActiveDocument
doc.Selection.SelectAll
'-- replace template variables with
doc.Selection.ReplaceText "##FILE", fileName, dsMatchRegExp
doc.Selection.ReplaceText "##TIME", Now, dsMatchRegExp
doc.Selection.Cancel
'-- save file and add it to active project
doc.Save MCtarget,true
ActiveProject.AddFile fileName
Set fso = Nothing
End Sub
You will find in folder IDE/MDLtool utility for creating different types of MDL code. Copy the MDLtool.dll into the directory Common\MSDev98\AddIns and copy templates to the Common\MSDev98\template directory respectively founded under Visual Studio base directory (by default it will be C:\Program Files\Microsoft Visual Studio). Restart you Visual Studio and go to Tools/Customize menu. A dialog box Customize will appear. Go to tab page Add-ins and Macro files and check in MDL tools in list item Add-ins and macro files. An MDL toolbar will be displayed. Now you may create MDL application on 2 clicks !
Project name: enter the name of you MDL project
Project location: Chose parent location for you project
Add to workspace : Check this option if you need to add newly created project into the workspace. If not checked a new workspace will be created for your project
MicroStation version : Select from combo box target MicroStation version for your MDL application.
Template location: Only If you have different templates change the folder to the desired one
Perform build : Check-in this option if you request build after wizard is finished
Project Type: Select the MDL project type you are going to generate
Generate files : Check-in any files you want to be generated.
Example of generated project with name MDLVS:
echo off
cls
echo +-----------------MDL BUILD BATCH ------------------------------+
cd
echo MDLVS.bat
date /t
time /t
SET MS=D:\BentleyV8\Program\MicroStation
SET MS
call vcvars32.bat
SET INCLUDE=%MS%\mdl\include;%INCLUDE%
SET LIB=%MS%\mdl\library;%MS%\jmdl\lib;%LIB%
set BMAKE_OPT=-I%MS%\mdl\include -I%MS%\jmdl\include
set PATH=;%MS%;%MS%\mdl\bin;%MS%\jmdl\bin;%PATH%
set MLINK_STDLIB=%MS%\mdl\library\builtin.dlo %MS%\mdl\library\dgnfileio.dlo
%MS%\mdl\library\toolsubs.dlo
echo +---------------------------------------------------------------+
bmake -a MDLVS.mke
appName = MDLVS
%if defined (_MakeFilePath)
baseDir = $(_MakeFilePath)
%else
baseDir = ./
%endif
privateInc = $(baseDir)
langSpec = $(baseDir)english/
%include mdl.mki
appObjects = $(o)$(appName).mo $(mdlLibs)ditemlib.dlo
appRscs = $(o)$(appName).mp
#----------------------------------------------------------------------
# The following section builds any necessary CODE modules for the
# application.
#----------------------------------------------------------------------
$(o)$(appName).mo : $(baseDir)$(appName).mc
#----------------------------------------------------------------------
# The following section generates the MDL Program module. This
# module should contain ALL CODE resources and/or libraries used
# by the application.
#----------------------------------------------------------------------
$(o)$(appName).mp : $(appObjects)
$(msg)
> $(o)make.opt
$(linkOpts)
-a$@
$(appObjects)
<
$(MLinkCmd) @$(o)make.opt
~time
$(mdlApps)$(appName).ma : $(appRscs)
$(msg)
> $(o)make.opt
-o$@
$(appRscs)
<
$(RLibCmd) @$(o)make.opt
~time
/*----------------------------------------------------------------------+
|
| Copyright 2002,
| All rights reserved.
| File :
| Purpose :
| Revision :
| Date :11/12/2002 12:43:59 PM
|
/*----------------------------------------------------------------------*/
/* ----------- INCLUDE FILES ---------------------------------------*/
#if
defined winNT#define MAIN MdlMain
#include <windows.h>
#define __NORECTANGLE__ 1#else
#define MAIN main#endif
/* ANSI C includes */
#include
<stdlib.h>#include
<stdio.h>#include
<string.h>/* MDL H includes */
#include
<mdl.h>#include
<cmdlist.h>#include
<dlogids.h>#include
<dlogitem.h>#include
<mdlerrs.h>/* MDL FDF includes */
#include
<ditemlib.fdf>#include
<dlogman.fdf>#include
<mscexpr.fdf>#include
<mscnv.fdf>#include
<msdialog.fdf>#include
<msoutput.fdf>#include
<msritem.fdf>#include
<msrsrc.fdf>#include
<msstate.fdf>#include
<mssystem.fdf>#include
<listmodel.fdf>#include
<treemodel.fdf>/* ----------- PRIVATE GLOBAL VARIABLES ----------------------------*/
/* ----------- FUNCTIONS --------------------------------------*/
#if
defined winNTBOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
return 1;}
#endif
/* ----------- ENTRY POINT --------------------------------------*/
DLLEXPORT
int MAIN(
int argc,char *argv[]
)
/*----------------------------------------------------------------------*/
{
printf(
" Hello Word from MDL app\n");mdlSystem_getStringFromConsole(NULL,
"press Enter to exit",0,TRUE);return
0;}
/* Finish main function */