The DataCAD Developer Network (DDN) is an online resource for information and support for DCAL® (DataCAD Applications Language) developers as well as anyone interested in creating fonts, toolbars, hatch patterns, or linetypes for use in DataCAD.
#71992 by Jsosnowski
Thu Aug 03, 2017 11:01 am
PART TWO - A DCAL FOR DELPHI PRIMER - THE MAIN FUNCTION
Every D4D macro starts at the same place. A macro file is simply a windows 'dll' (dynamic linked library) file with a '.dmx' file extension. When Datacad opens a macro file the only function it knows to look for is called Main. You begin writing your macro by creating a new ddl/dmx file. To create the file in Delphi (as of v10.2) select the menu tree 'project/add new project' and then choose the DLL option in the pop-up form. Delphi will generate a blank 'library' unit. Begin work on your macro by inserting the code shown below:


Code: Select alllibrary D4Dtemplate;{1}

//Delphi compiler instructions {2}
{$E dmx}  //dmx is the extension for DCAL Dll's
{$R *.res}


Uses {3}
{Add any units required by Delphi. Many units are added directly by the Delphi IDE, but some must be added manually
system.sysutils, 
System.Classes, // Required if Class/Objects are used in the code.
}
//DCAL for Delphi (D4D) environment units
UConstants,  //constants declarations
Uvariables, //all variables available in DCAl
URecords,  //all record structures available in DCAL
UInterfaces, //DCAL for Delphi methods used for interfacing directly with user
UinterfacesRecords; //record structures used to pass arguments to interface methods
UDCLibrary; //loose end interface declarations not included in Uinterfaces

//Add other units used in the macro to identify all methods used in this unit.

const {4}
//dcalstate constants
   XMain = XDcalStateBegin;  {Currently set as 8100 by uconstants.pas}
//add an incremented dcalstate constant for each Name _doMenu or Datacad menu call function included inthe 'Main' function below.
//   XName = XMain +1;   


{5}
Function Main(dcalstate: asint; act: action; p_LR, p_DR: Pointer) : wantType; stdcall;
begin
 case dcalstate of
    XMain: Result := DCALMacro_doMenu(act, p_LR, p_DR); //XMain is the intital Datacad dcalstate call
    //list additional dcalstate cases for each Name_doMenu or Datacad interface menu function directly called in your macro.
    else  result := XDone;
   end;
end;

exports {6}
   Main;

begin
end.


Code Instructions (refer to bracket numbers {}for code location):
{1} - Save the project using your chosen macro name. In this example the project is named 'D4Dtemplate' and Delphi will rename the library title (first line) to match.
{2} - Make certain that these two Delphi compiler instructions are present. The ($E dmx) line instructs the compiler to save the library using the '.dmx' file extension that Datacad will look for to find macros. The $R *.res directive instruct the compiler to place any resource files in a .res file with a name to match the project. These files include information for graphics other information associated with advanced Delphi capabilities included in Delphi 'forms' which will be linked in the DLL when the macro is 'built'.
{3} Include the five D4D unit files listed in the uses section of the macro file. These units contain all of the relevant Datacad information needed for Delphi to compile the macros. Not every macro will require all of them, but listing them does not increase the size of the macro if they are not needed. So if your not sure if the unit applies, include it anyway. You must also list any other units that contain constants, types, or methods needed by your macro.
{4} - You must create a constant to use as the identifying label in the Main function's case dcalstate of statement. You will create additional dcalstate constants for each menu loop created for your macro as explained in PART FOUR - _DoMenu FUNCTIONS.
{5} Add the function Main to your macro file. This function serves as Grand Central for your D4D macro.
{6} Declare the 'Main' function as exported from this library/macro

Implementing the Main Function

When you start a D4D macro in Datacad, the library file above is opened by Datacad which follows the coded instructions contained in the Main function. Main is then responsible for directing the operations of the macro to the desired methods to execute your macro. Focus is redirected to various portions of the macro using the choices in the case statement in Main. To see how it does this look at the function arguments.

Code: Select allFunction Main(dcalstate: asint; act: action; p_LR, p_DR: Pointer) : wantType; stdcall;


1. The first argument, dcalstate is the message from the last iteration of the macro loop telling the Main function which dcalstate to execute in the current iteration of the menu loop. When the macro is first started Datacad will include the value XDcalstateBegin (which is assigned to Xmain in the const declarations at the top of the file) instructing Main to go to your the first dcalstate option 'XMain'. In the example, 'XMain' calls the function DCALMacro_doMenu.
2. Act is a variable argument of type 'action' which is declared in the file unit Uconstants.pas as an enumerated set with four values Afirst, Alast, Aagain, & AlSize. In PART ONE we viewed a traditional DCAL macro code example. In it initialization and finalization operations occur outside of the menu loop (repeat...until). This act variable allows Datacad to handle those one-off operations separate from the looped operations including the display/input/execution steps. PART FOUR will demonstrate how these activities are handled in more detail.
3. The argument p_LR is a pointer to a t<name>LoopRecord record variable that you structure and include as a 'type' in your macro (see PART THREE). (Note: Datacad sample macros name this argument as 'pl'. The name is changed here to be more descriptive.) It includes all necessary data passed between your <name>_doMenu functions and various D4D interface methods supplied and operated by Datacad. A complete listing of these methods is included in the file unit UInterfaces.pas.
4. Similarly, the p_DR pointer argument is used to link to an t<name>DataRecord record variable,defined in your macro that includes the persistent data your various macro methods need to perform their operations. (Note: Datacad sample macros name this argument as 'pargs'. The name is changed here to be more descriptive). We will discuss creating these record structures in PART THREE. Also, as you will see in PART FOUR, we will create local pointers linked to the arguments contained in this function call to read, insert and manipulate data both in Datacad and the macro.
5. The Main function returns a result value of the type wantType. This result value is defined by D4D a type asint, which in turn is simply an integer. All <name>_doMenu functions identified in the case statement will return this value indicating which case of dcalstate
statement choices to pick in the next iteration of the macro loop which is then returned as the value for Main.

Moving beyond the Main function declaration to the actual code, it declares a case dcalstate of structure that lists all of the <name>_doMenu functions created and used in your macro. You will create a separate dcalState and function <name>_doMenu necessary for your macro. To add a new <name>_domenu function first define the XName constant value as described in step 5 above and then create a new <name>_doMenu function using the template discussed in the PART FOUR post. Whenever the current <name>_doMenu function must change to a new <name>_doMenu option it does so by returning a new 'wanttype' result such as 'Xmain' or another dcalstate case defined in Main option. (See PART FOUR).

In the next posting, PART THREE, we will see how the p_LR & p_DR arguments are structured and used in more detail.
Last edited by Jsosnowski on Sun Sep 17, 2017 9:40 am, edited 3 times in total.

Who is online

Users browsing this forum: No registered users and 9 guests

About DataCAD Forum

The DataCAD Forum is a FREE online community we provide to enhance your experience with DataCAD.

We hope you'll visit often to get answers, share ideas, and interact with other DataCAD users around the world.

DataCAD

Software for Architects Since 1984