CMac Documentation/Tutorial

Home Forums Multi-Edit Suggestions CMac Documentation/Tutorial

Viewing 15 posts - 16 through 30 (of 38 total)
  • Author
  • #3217

    You’ve probably already discovered this via experimentation, but yes, you can use either syntax for a function with parameters declared as:

    [code:32hb5ez5]void testsub(int iVal = Parse_Int("/I=", MParm_Str))[/code:32hb5ez5]

    You can use any of the following:



    rm("TestSub /I=4");


    TestSub /I=4 on the command map entry[/code:32hb5ez5]

    Those are off the top of my head, so I suspect I’ve screwed something up, but that’s the general idea. :D

    Michal Vodicka


    sorry but your second example is incorrect. You can’t use testsub(“/I=4”) because it passes string value instead of int.

    Command line syntax is just for RM command which is internally used by command map, Run macro dialog box etc. It is documented for sure, how else I’d know about it? ;-)


    First the purpose of the macro_file statement is documented in the “Creating a macro source file” topic in the CMac Help file.

    The “Macro command line parameter compatibility & default parameters” topic in the CMac Help file covers your other point.

    The CMac Help file was written to be read from the beginning to get a overview of the CMac language any many topics that have been asked about is covered in the introductory material. The help file also serves as a “Reference” manual for the built-in functions, which is how most use it.

    I agree that the CMac information is in bad need of being updated and that is why we are working on it :)


    The documentation should have an example of a case statement with multiple matches executing the same code. Example:

    case 1:
    case 2:
    case 3:
    case 4:
    make_message(‘three or four’);

    It’s the regular C way of doing it (matching both 3 and 4), but I wasn’t sure until I searched Multi-Edit9/src for an example, since not everything about CMAC is identical to C (for example, operator precedence).

    Also, the ‘right’ function doesn’t pay attention to the “Restrict Cursor” setting under TOOLS->CUSTOMINZE…->Editing. It moves the cursor beyond the end of line even if that box is checked. However, the ‘down’ function does pay attention to the “Restrict Cursor” setting, refusing to move the cursor below the EOF (End Of File) if “Restrict Cursor” is checked, but moving cursor below EOF if “Restrict Cusor” is not checked. This needs to be documented.

    Clay Martin

    On a less technical note, some of the descriptions of features and tools available in MEW could be improved. As it stands many are overly breif and some make a feature sound like it is too much trouble to learn/setup for the perceived value.

    Check out the following post:

    Just a thought,


    Add a chapter on how a Multi-Edit macro can call a user written external dll function written in whatever language is currently popular (C, C++, C#?) I was unaware until recently that this was possible.

    Include an example of passing every type of parameter, and how to code the dll function to properly receive the parameter, and then possibly modify it. Example:

    int i = 12;
    real q;
    real r = 3.14;
    str s;

    q = mydllfunc(7,i,r,s);

    give an example of some C++ code that would receive these parameters, change i to 13, change r to 2.17, and do something with string s.

    The string s is the biggest unknown. Is it an ASCIZ zero-terminated string, where the end of the string is marked by a 0x00 byte? Or is it an ASCIC string, where the first word, or byte (which is it?), gives the length of the string? Can our C++ code allocate memory for a string to return as s? Or do we need to create a string array s of sufficient length in the CMAC code, and pass that along with the length as an extra parameter? So many questions that could be quickly answered by an example. How to return a value for q? What if q were defined above to be a string instead of a real, how would you code the C++ to return a string?

    A simple example of calling a system dll I was given a few weeks ago:

    import void Sleep( DWord dwMilliseconds ) Kernel32 ‘Sleep’;
    void Test( )
    Multi-Edit Macro
    05-Sep-03 11:56

    Function: Test the Sleep Window API
    Entry : None
    Exit : None
    Author : Dan Hughes

    Copyright (C) 2003 by Multi Edit Software, Inc
    *******************************************************************( ldh )***/
    Make_Message( ‘Sleeping now…’ );
    Sleep( 1000 );
    Make_Message( ‘Finished Sleeping’ );

    } // TstSleep


    The CMAC help file documentation for function ‘Goto_Line’ gives an example of calling macro ‘GoToLine’ which doesn’t work.


    As far as I can tell macro GoToLine does not accept any parameters. CMAC gets unhappy and reports “Macro or Macro file “GOTOLINE(5″ NOT found in C:Program Files\Multi-Edit 9\ nor C:Program Files\Multi-Edit 9\MAC\” when the above line is executed.

    The function ‘Goto_Line’ apparently has a bug, or the screen updating has a bug, in that a call to Goto_Line moves the editing point but not the cursor. Example:

    void test()
    Make_Message(‘Current line=’ + str(C_Line));

    Bind this to a key, turn on line numbers, press that key, the message says “Current Line=22” but the cursor does not move. Clicking on the “Save File” icon causes the window to be properly updated and places the cursor on line 22, or switching back and forth between windows also fixes things up, or adding a ‘Redraw;’ statement after ‘Goto_Line(22)’ seems to fix things. I suggest either fix the bug or document that a ‘Redraw’ statement is necessary to get the cursor back on top of the editing point.

    Ken Walker

    Now this is the kind of information I was hoping to get from users. Thanks to everyone for posting and keep up the good information!

    Every topic that’s been posted will be covered. And rest assured, I intend to expand the current documentation by providing lots of actual code samples. I know for me, when learning a new language, sometimes example code is all I need for the concept to sink in. I will be providing in depth descriptions of procedures and functions also.

    Thanks again!


    I need more information about function ‘Read_Key’. The current example in CMAC help appears to be wrong (possibly this example was once correct for DOS CMAC and no longer correct for CMAC for Windows?):


    Read_Key; /* Get keycode */
    /* If Key1 == 0, then extended key was pressed */
    if ( Key1 == 0 && Key2 == 59 )
    Make_Message(‘You pressed F1!’);

    When I press F1 I get Key1=112 and Key2=1

    In we have:

    #define VK_F1 112

    so Key1 for F1 key is 112.

    I’m not sure how to get the character corresponding to the key pressed.

    Sometimes c = char(Key1); works, but

    If I press the MINUS key – (above the letter “P” key on the keyboard), I get Key1=0xBD and Key2=1. It would make sense if Key1=0x2D (hex) since that’s the ASCII code, but I’m not sure how we get Key1=0xBD instead.

    So I’m not sure how to do a simple “read a keystroke from the keyboard and if it’s a printable character key give me that character as a local string variable.”


    There is no mention of how to create and handle an integer array under topic “Data Types”.

    Arrays are mentioned under index topic “Arrays” and “Arrays in Structures”. Apparently you can have an integer array, but you must place it inside a structure. However, if inside a structure you dimension an array as:

    struct ts
    int tarray[100];

    it is not explained if this array is from [0]-[99] or [1]-[100] or [0]-[100].

    Currently, experimentation is required to determine that the array is [0]-[99].

    It is also not mentioned if you can or can not create multi-dimensional arrays.

    Clay Martin

    One of the features we are planning on adding in a patch release of Multi-Edit 9.10 is a settings export feature which will allow a user to export any configuration data to later be imported. The idea is to try to write “update” scripts on the export and then allow them to be put into packages which will use the normal Add-On installation routines to reinstall.

    Once this is done, a user could export all of their custom setting and when a new release of Multi-Edit comes out, they would install the default version, getting all of the new feature, and then run the Add-On install of their personal packages and all of their custom setting would be added in.


    That sounds like a great idea!


    I’m confused as to whether a macro with no parameters still requires a “()” in the definition or in the call. Example:

    void mynoparam()
    text(“hello world”);


    void mynoparam
    text(“hello world”);

    and calling:

    void test

    So far CMACW seems to accept both. I assume I could infer this from a careful reading of “Macro elements”. It is a question I wondered, so perhaps other new programmers to CMACW will also ask the same question.

    Another broader question is how and when to use old-style parameter passing vs. new more standard parameter passing. i.e. when should I use the lengthy:

    void FindFile( str fn = parse_str(“/F=”, mparm_str) )

    instead of the shorter

    void FindFile( str fn)

    Does it slow down Multi-Edit to use the longer version above?

    There’s a pretty good description under “Macro command line parameter compatibility & default parameters”. This, or a reference to this, should probably be added to the “Caveats” section since it’s a digression from standard C.


    Many languages define a MIN and MAX function.
    In C it’s common for a programmer to define one for himself as:
    #define MIN(a,b) ( ((a) > (b)) ? (b) : (a) )
    #define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
    How to achieve a MIN & MAX function in CMAC could be discussed. Whether or not CMAC supports a C-like conditional expression operator “?” could be discussed. (Perhaps MIN & MAX functions could be added to a future release of Multi-Edit.)

Viewing 15 posts - 16 through 30 (of 38 total)
  • You must be logged in to reply to this topic.