Introduction

In this third tutorial we will create our first .Net CC2 XP.  This is where all the fun begins!

Setting up your project

Lets start by loading our previous project, 'MyFirstXP'.  We must prepare this project to use the CLR (Common Language Runtime) that is the heart of .Net.

To alter a projects properties first bring up the Solution Explorer (By default a tab on the lest side of the screen).  Right click on the project and then select Properties. 

The projects 'Property Pages' dialog box will now appear.

The setting we will set is the 'Common Language Runtime Support' under 'Configuation Properties' > 'General'.  Choose 'Common Language Runtime Support (/clr)' from the dropdown.

We are now ready to convert 'MyFirstXP' to use the .Net Framework.

 

Coding and Running Your Project

Now we will replace the existing code with the code for our first .Net Framework XP.  Open the C++ file and replace all the code with the code below.

///////////////////////MyFirstTest (.Net Framework)////////////////////
//  Writen By: L. Lee Saunders
///////////////////////////////////////////////////////////////////////
#include <windows.h>

extern "C" 
{  
	#include <XP.H>
}

#using <mscorlib.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>

using namespace System::Windows::Forms;

#define XPID 0xF000 

void XPCALL About(void);
void XPCALL ShowInfoBox(void);

char CList[]="SHOWINFO\0";
PCMDPROC PList[]={About, ShowInfoBox};

XP MyXP = {0, CList, PList, 0, 0, 0, XPID, 0, 500, 0, 0, 500};
///////////////////////////////////////////////////////////////////////


/////////////////////////// About information /////////////////////////
void XPCALL About(void)
{
	MessageBox::Show("CC2 XP\n\n\tSHOWINFO - Show a .Net Messagebox\n");
}
///////////////////////////////////////////////////////////////////////


/////////////////////////// MTEST1 XP command /////////////////////////
void XPCALL ShowInfoBox(void)
{
	MessageBox::Show("Your new .Net XP is working!");
	CmdEnd();
}
///////////////////////////////////////////////////////////////////////


/////////////  DllMain - XP initialization & Unload code //////////////
#pragma unmanaged
BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
{
	switch (dwReason)
	{
		case DLL_PROCESS_ATTACH:
		{
			MyXP.ModHdl=hDLL;
			XPRegCmd(&MyXP);
			break;
		}
		case DLL_PROCESS_DETACH:
		{
			XPUnregCmd(&MyXP);
			break;
		}
	}
	return TRUE;
}
///////////////////////////////////////////////////////////////////////

A simple Build > Build Solution will now create your first XP dll. 

If it builds without errors, (as it should) then you need to move your XP dll into the CC2 directory.  If you did not change the default output directory, the dll should be in your 'My Documents' > 'Visual Studio 2005' > 'Projects' > THE NAME OF YOUR PROJECT > 'Debug'.

Now start CC2 and type in on the command line 'SHOWINFO'.  Your new XP will now run and display:

 

The Code Explained

#include <windows.h>

extern "C" 
{  
	#include <XP.H>
}

#using <mscorlib.dll>
#using <System.dll>
#using <System.Windows.Forms.dll>

using namespace System::Windows::Forms;
#define XPID 0xF000 

This section has grown from the previous tutorial. The '#using' statements connect our code with the .Net Framework dlls.  The 'using namespace' statement is a shortcut statement. It allows us to use the commands in this namespace without having to fully reference them. 

The next set of code connects your code with the CC2 XP libraries, but since these libraries are C code instead of C++ code, we need to wrap the include call in an 'extern "C"' statement.  This lets the compiler know that it is dealing with C code instead of C++ code.

void XPCALL About(void);
void XPCALL ShowInfoBox(void);

char CList[]= "SHOWINFO\0";
PCMDPROC PList[]= {About, ShowInfoBox};

These are the same as the previous tutorial.

void XPCALL About(void)
{
	MessageBox::Show("CC2 XP\n\n\tSHOWINFO - Show a .Net Messagebox\n");
}

Here, I've altered the 'About' function by removing the complicated to 'FormSt' and replaced it with a simple call to 'MessageBox'.  I could have referenced it by its fully qualified name: 'System::Windows::Forms::MessageBox' but that is a lot of code, so this is why we have the 'using namespace' statement in the first code block.

void XPCALL ShowInfoBox(void)
{
	MessageBox::Show("Your new .Net XP is working!");
	CmdEnd();
}

The 'ShowInfoBox' has also been altered to use the .Net framework way of evoking a Message Box.

XP MyXP = { 0, CList, PList, 0, 0, 0, XPID, 0, 603, 0, 0};

/////////////  DllMain - XP initialization & Unload code //////////////
#pragma unmanaged
BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
{
	switch (dwReason)
	{
		case DLL_PROCESS_ATTACH:
		{
			MyXP.ModHdl=hDLL;
			XPRegCmd(&MyXP);
			break;
		}
		case DLL_PROCESS_DETACH:
		{
			XPUnregCmd(&MyXP);
			break;
		}
	}
	return TRUE;
}
///////////////////////////////////////////////////////////////////////

Our boilerplate code has one small addition and it is what makes all the diference. We now have a '#pragma unmanaged' statement right before the 'DllMain' function  You may have also  noticed that this code has moved to the bottom of the file.  The reason is that once we turned on the (/clr) property, the compiler thinks that all code not marked with '#pragma unmanaged' will run under the .Net Framework. 

If 'DllMain' could run under the .Net Framework, we would gladly let it, but it cannot.  CC2 expects a Win32 dll to connect to, so we must compile the 'DllMain' function under the unmanaged pragma flag.

If anyone has any problems with this tutorial, please contact the CC2 Developers List on Yahoo at:

http://groups.yahoo.com/group/cc2-dev-l/

And as I compile the solutions I'll add them to the 'What went wrong' section below.

What went wrong.

Nothing yet, lets keep our fingers crossed!