AddIns

Programming AddIns

Using the EPLAN 21 API, you can both write your own programs and integrate so-called AddIns to be run within EPLAN 21. EPLAN 21 AddIns are DLLs which are registered in EPLAN and are called up when starting EPLAN. You can use C++ DLLs as well as ActiveX DLLs generated with Visual Basic. However, the ActiveX DLLs must be registered as COM server with REGSVR.32.EXE ...*.DLL before being entered in the Default settings dialog of EPLAN 21.

Using the functions of the API, the AddIns can access the EPLAN database. Each AddIn must export the two functions EplanInitialize and EplanDeinitialize. These functions are called up by EPLAN whenever the AddIn is loaded or before EPLAN is terminated. Via the EplanInitialize function, the AddIn can carry out general initializations and register its own commands as well as integrate menu items into EPLAN 21.

The registration of menu items is carried out via the EPLAN.EPLAN21.ADDIN.REGISTER command. Menu items can be integrated into the main window of EPLAN 21 as well as into the Browser and the graphical editor. For each menu item, a command is registered which is called up whenever the user selects a menu item.

The AddIn can register its own commands (for example, as callback for a menu item) by using the eplRegisterCommandHandler API function. It can also access the current selection in the Browser or graphical editor. To this purpose, the EPLAN.EPLAN21.SELECTION command is used.

Example

#include "stdafx.h"

#define DLL_EXPORT __declspec(dllexport)


//  Command handler for the user-defined "TEST.COMMAND01" command.
//  The "TEST.COMMAND01" is executed when the "TestCommand01" menu item is selected.
//  Each command used as menu callback is parameterized with the HWND of the parent window 
//  and the index of the function set. It can be used to register only one callback
//  for various menu items.
//
//  The first parameter assigned to the command handler function is the session in which the command
//  was called up. The second parameter gives the name of the command that is called up.
//  In this case this is "TEST.COMMAND01". The third parameter is used to access the 
//  parameters of the command that is implemented in this handler function.
//  (==> eplSetParam, eplSetHandleParam,eplGetParam, eplGetHandleParam).

external "C" DLL_EXPORT
void _stdcall ItestCommandHandler(EplSession session, const EplChar* commandName, EplHandle hParam)
{
        wchar_t buf[256];

        // Get the handle of the parent window
        eplGetParam(session, hParam, EPL_PARAM_COMMAND_PARENTWINDOW, 0, buf, 256);

        HWND parentWindow = (HWND)wcstol(buf, NULL, 10);

        eplGetParam(session, hParam, EPL_PARAM_COMMAND_INDEX, 0, buf, 256);

        std::wstring title;

        if(wcscmp(buf, L"1") == 0)
                title = L"TestCommand01";
        else
                title = L"TestCommand02";

        // Then make sure which object is selected in the Browser 
        EplHandle hSelectionCmd = eplCreateCommand(session, L"EPLAN.EPLAN21.SELECTION");
        eplExecuteCommand(session, hSelectionCmd);

        // Get the number of selected elements
        eplGetParam(session, hSelectionCmd, EPL_PARAM_SELECTION_COUNT, 0, buf, 256);

        if(wcstol(buf, NULL, 10) > 0)
        {
                // By means of the EPL_PARAM_SELECTION_RESULT parameter
                // you can get a handle of an iterator for all selected elements
                EplHandle hSelectionIter  = eplGetHandleParam(session, hSelectionCmd, EPL_PARAM_SELECTION_RESULT, 0);

                //  Get the first selected element
                EplHandle hObject = eplFirst(session, hSelectionIter);


                // Get the (object) type of the element, and display it in a message box
                int type = eplGetType(session, hObject);
                std::wstring s;

                switch(type)
                {
                case OBJTYPE_PROJECT:                        //...is it a project?
                        s = L"Projects: ";
                        s.append(buf);
                        MessageBoxW(parentWindow, s.c_str(), title.c_str(), MB_OK | MB_ICONEXCLAMATION);
                        break;
                case OBJTYPE_PAGE:                                //...or a page?
                        s = L"Pages: ";
                        s.append(buf);
                        MessageBoxW(parentWindow, s.c_str(), title.c_str(), MB_OK | MB_ICONEXCLAMATION);
                        break;
                case OBJTYPE_INSTANCE:                        //...or an instance?
                        s = L"Instances: ";
                        s.append(buf);
                        MessageBoxW(parentWindow, s.c_str(), title.c_str(), MB_OK | MB_ICONEXCLAMATION);
                        break;
                default:                                                //...or maybe nothing :-(...
                        MessageBoxW(parentWindow, L"Kein Projekt, keine Seite, keine Instanz...", title.c_str(), MB_OK | MB_ICONEXCLAMATION);
                        break;
                }

                // Close the selection iterator
                eplCloseObject(session, hSelectionIter);
        }
}

//
//  As already explained in the basics of the Addin programming, each Addin DLL must export the
//  functions EplanInitialize() and EplanDeinitialize(). These functions will then be executed
//  -- if the AddIn was correctly entered in the default dialog box --
//  when the AddIn is loaded (during the starting process of EPLAN 21) or when EPLAN 21 is 
//  terminated.

extern "C" DLL_EXPORT
int EplanInitialize(void)
{
        EplSession session = eplCreateSession();

        //The new command under the name "Test.Command01" is registered here.
        // It was previously implemented by the function "testCommandHandler" (see above).
        // If a special command was registered with eplRegisterCommandHandler,
        // it can be used as an usual EPLAN 21 command.
        // Example:
        // EplHandle testCommand = eplCreateCommand(s, L"TEST.COMMAND1");
        // eplExecuteCommand(s, testCommand);
        //
        eplRegisterCommandHandler(session, L"TEST.COMMAND01", ItestCommandHandler);

        // Append menu items
        EplHandle hRegisterCmd = eplCreateCommand(session, L"EPLAN.EPLAN21.ADDIN.REGISTER");
        if(hRegisterCmd != EPL_ERROR)
        {
                // Menu name:
                eplSetParam(session, hRegisterCmd, EPL_PARAM_ADDIN_REGISTER_MENUNAME, L"TestCommand01", 1);

                // Now we use "TEST.COMMAND01" as the callback for the menu item.
                // Every time the user selects this new menu item, the command is executed.
                eplSetParam(session, hRegisterCmd, EPL_PARAM_ADDIN_REGISTER_MENUHANDLER, L"TEST.COMMAND01", 1);

                // Another menu item in the graphics editor:
                eplSetParam(session, hRegisterCmd, EPL_PARAM_ADDIN_REGISTER_MENUNAME, L"TestCommand02", 2);
                eplSetParam(session, hRegisterCmd, EPL_PARAM_ADDIN_REGISTER_MENUHANDLER, L"TEST.COMMAND01", 2); // The same command is executed.

                wchar_t buf[20];
                // Here you can find in which menu the (second) new menu item is to be appended.
                eplSetParam(session, hRegisterCmd, EPL_PARAM_ADDIN_REGISTER_PARENTMENU, _ltow(EPL_ADDIN_MENU_GED, buf, 10), 2);

                // Execute the command
                eplExecuteCommand(session, hRegisterCmd);
                eplCloseObject(session, hRegisterCmd);
        }

        eplDestroySession(session);
        return 0;

}

extern "C" DLL_EXPORT
int EplanDeinitialize(void)
{
        // In this example we don't have to do anything more. Here, it would be possible to
        // insert functionalities that automate the procedures before EPLAN 21 is terminated. 
        // (e.g. archiving a current project at the end)

        return 0;
}