Walkthrough: Creating a C++ COM Server Usable within Microsoft Navision 3.6 and 4.0 Using Wizards

In this walkthrough, you will use the Visual Studio .NET integrated development environment (IDE) and the various wizards to create an ATL COM server.

To create a simple ATL COM server

1.       1.     On the File menu, click New, and then click Project.

The New Project dialog box appears.

2.       2.     In the Project Types pane, click Visual C++, and in the Templates pane, click the ATL Project icon.

3.       3.     In the Name box, enter MyServer.

4.       4.     Click OK.

The ATL Project Wizard appears.

5.       5.     Click Application Settings.

You will see the Attributed check box is selected by default. If you are not using attributes, unselect this option.

6.       6.     Click Finish to close the wizard and generate the project.

The result is an inproc ATL COM server without any server objects. There will be an additional project created called MyServerPS. This is a MyServer Proxy Server. You will not need to modify anything in the MyServerPS project.

7.       7.     On the Build menu, click Build Solution.

Building the project successfully registers the server with the operating system.

 

The COM Server now needs to implement a simple COM object.

 

To add a server object

1.     1.       In Solution Explorer, right-click the MyServer project.

2.       2.     On the shortcut menu, click Add, and then click Add Class.

The Add Class dialog box appears.

3.       3.     In the Templates pane, click the ATL Simple Object item and click Open.

The ATL Simple Object Wizard appears.

4.       4.     In the Short Name text box, enter Object1.

5.       5.     Click Options.

You will see that the Connection Points check box is deselected by default. Change this to be checked.

6.       6.     Click Finish to accept the remaining default values.

7.       In Class View, expand MyServer and MyServerLib to display the _IObject1Events interface.

8.       Right-click _IObject1Events. On the shortcut menu, click Add, and then click Add Method.

9.       Select a Return Type of void.

10.   Enter SomethingHappened in the Method name box.

11.   7.     Click Finish to accept the remaining default values.

 

Check the MyServer.idl file to see that the code was added to the _IObject1Events dispinterface.

 

The _IObject1Events dispinterface in your MyServer.idl file should now look like this:

 

dispinterface _IObject1Events

{

properties:

methods:

[id(1), helpstring("method SomethingHappened")] void SomethingHappened(void);

[id(2), helpstring("method ClickOut")] void ClickOut([in] LONG x, [in] LONG y);
};

 

Generating the Type Library

Generate the type library at this point, because the Connection Point Wizard will use it to obtain the information it needs to construct a connection point interface and a connection point container interface for your control.

 

To generate the type library

·          Rebuild your project.

 

-or-

 

·          Right-click the MyServer.idl file in Solution Explorer and click Compile on the shortcut menu.

 

This will create the MyServer.tlb file, which is your type library. The MyServer.tlb file is not visible from Solution Explorer because it is a binary file and cannot be viewed or edited directly.

 

Implementing the Connection Point Interfaces

Implement a connection point interface and a connection point container interface for your control. In COM, events are implemented through the mechanism of connection points. To receive events from a COM object, a container establishes an advisory connection to the connection point that the COM object implements. Because a COM object can have multiple connection points, the COM object also implements a connection point container interface. Through this interface, the container can determine which connection points are supported.

 

The interface that implements a connection point is called IConnectionPoint, and the interface that implements a connection point container is called IConnectionPointContrainer.

 

To use the Implement Connection Point Wizard

1.       1.     In Class View, right-click your control’s implementation class CObject1.

2.       2.     On the shortcut menu, click Add, and then click Add Connection Point.

3.       3.     Select _IObject1Events from the Source Interfaces list and double-click it to add it to the Implement connection points column.

      4.     Click Finish.

      A proxy class for the connection point will be generated, in this case, CProxy_IObject1Events.

 

If you look at the generated _IObjectEvents_CP.h file in Solution Explorer, you will see that it has a class called CProxy_IObject1Events that derives from IConnectionPointImpl. _IObject1Events_CP.h also defines the method, "SomethingHappened". You can call this method when you want to fire an event.

 

You are finished implementing the code to support events. Now, add some code to fire the events at the appropriate moment.

 

Creating Callable Methods

1.       1.     In Class View, expand MyServer to display the IObject1 interface.

2.       2.     On the shortcut menu, click Add, and then click Add Method.

3.       3.     Enter FireEvent in the Method name box.

4.       4.     Click Finish to accept the remaining default values.

5.       In the Solution Explorer, select the Object1.cpp file and change the FireEvent method code to look like the following:

 

STDMETHODIMP Cobject1::FireEvent(void)

{

Fire_SomethingHappened();

Return S_OK;
}

 

6.       5.     On the Build menu, click Build Solution.

 

Implementing your COM object in Navision

1.       1.     Create a codeunit that uses your COM object.

2.       2.     Add a global variable to the codeunit with a name of MyServer and a datatype of Automation.

3.       3.     For subtype, select the elipses, and then the Automation Server lookup. Select "MyServer 1.0 Type Library" and then click OK.

4.       4.     In the Classes listing, select Object1 and click OK.

5.       5.     Select the global variable’s line and click the properties button.

6.       6.     Change WithEvents to "Yes".

7.       7.     Add two functions to your codeunit’s globals. One called "Start" and one called "Stop".

8.       8.     In your Start method, create an instance of your COM object.

 

Your code in the Start method should look like this:

 

CREATE( MyServer );

9.       In your Stop method, dispose of the instance of your COM object.

 

Your code in the Stop function should look like this:

 

CLEAR( MyServer );

 

10.   9.     In your OnRun trigger, call your Start method.

11.   10.  Save and compile your Codeunit, naming your codeunit MyServer.

 

Your code in the OnRun trigger should look like this"

 

Start();

 

Adding your codeunit for use with Navision Application Server

1.       1.     In Codeunit 1, modify the function, "NAS Handler".

2.       2.     Add a local variable to the function with the Name of the codeunit that you created in step 1, a DataType of Codeunit, and a Subtype with the name of the Codeunit you created in step 1.

3.       3.     Copy the CASE section for ‘MAILLOG’ and paste is after the ‘ADCS’ section.

 

Your case statement should now look like this:

 

‘ADCS’ :

    BEGIN

       ADCSATASStartup.SetNASID(COPYSTR(ParamStr,SepPosition + 1));

       ADCASATASStartup.RUN;

       ATASStarted := TRUE;

    END;

‘MyServer’ :

    BEGIN

       MyServer.Run;

       ATASStarted := TRUE;

    END;

 

4.       4.     Save and compile Codeunit 1.

 

Testing What You Have Done

1.       1.     Create a Form that has a Start and Stop Button.

2.       2.     In the global variables for your form, create a global variable with a name of MyServer, a DataType of Codeunit, and a SubType of MyServer.

3.       3.     In the OnPush event for the Start button, run the codeunit you created.

 

Your OnPush event should now look like this:

 

MyServer.RUN();

 

4.       4.     In the OnPush event for the Stop button, run your codeunit’s Stop method.

 

Your OnPush even should now look like this:

 

MyServer.Stop();

 

5.       5.     Compile and save your test form.

6.       Currently, when the event is fired, nothing is going to happen. In the SomethingHappened event of the codeunit you created, enter a message.

 

Your SomethingHappened event should now look like this:

 

MESSAGE( ‘Event has been fired successfully’ );

 

7.       6.     Compile and save your codeunit.

8.       Run your form and click the start button. You should see a message box with the message "Event has been fired successfully".

 

The information on this page is provided "AS IS" with no warranties, and confers no rights.

Advertisements

4 thoughts on “Walkthrough: Creating a C++ COM Server Usable within Microsoft Navision 3.6 and 4.0 Using Wizards

  1. Nothing personal, but as a non-programmer that is a really dry read…Eric 😉

  2. Comment and Question:
     
    Comment: Visual Studio was frustrating on this example. When I first attempted to add a method to my_IObjectEvetns interface the program threw an Error saying Error line 1188:  ‘length’ was not an object and that this object did not support methods. Solution was to allow ActiveX controls to run (I guess the method dialog runs ActiveX controls) similar to when IE warns you that a website is attempting to run ActiveX content
     
    Question: What is the purpose of SomethingHappened() in this example? Why do we need this?

  3. It is the delegate that gets called when the event fires.

  4. automation events do not get fired under NAV 2013 even though the codeunit generates the event triggers

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s