Figure 1 testdtor.cpp
 
////////////////////////////////////////////////////////////////
// MSDN Magazine ! December 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//
// This program illustrates what happens when you delete a managed object 
// in Managed C++: the compiler calls the object's dtor.
//
// To compile: cl /clr testdtor.cpp

#include <stdio.h>
#using <mscorlib.dll>

using namespace System;

//////////////////
// Managed class WITH dtor.
//
public __gc class ManagedClass {
public:
   ManagedClass() {
      printf(" ManagedClass(%p)::ctor\n", this);
   }
   ~ManagedClass() {
      printf(" ManagedClass(%p)::dtor\n", this);
   }
};

//////////////////
// Managed class WITHOUT dtor
//
public __gc class ManagedClassNoDtor {
public:
   ManagedClassNoDtor() {
      printf(" ManagedClassNoDtor(%p)::ctor\n", this);
   }
};

void main()
{
   printf("Begin main\n");

   ManagedClass *pmc = new ManagedClass();   // create instance
   delete pmc;                               // "destroy" (force-call 
                                             // dtor)
   pmc = new ManagedClass();                 // create another
// delete pmc;                               // don't destroy 
                                             // (cleaned up when pgm 
                                             // terminates)

   ManagedClassNoDtor *pmcnd = new ManagedClassNoDtor();
// delete pmcnd; // ERROR!: can't delete instance of class with no dtor!

   printf("End main\n");
}

Figure 3 ListWrap.cpp
 

////////////////////////////////////////////////////////////////
// MSDN Magazine ! December 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//
#using <mscorlib.dll>
#include "ListLib.h"

using namespace System;
using namespace System::Collections;

// Handy definition for human readability.
#define MANAGED __gc

namespace ListWrap {

//////////////////
// Managed wrapper for NativeNode mirrors definition.
//
public MANAGED class ManagedNode 
{
public:
   int a, b;      // same as NativeNode::a, NativeNode::b
   String* str;   // managed String, not char*

   // static
   static ArrayList* CreateList(int nelt) {
      NativeNode* nn = AllocateList(nelt);
      ArrayList*  ar = new ArrayList();      // create managed array list

      // Copy each NativeNode to managed ManagedNode
      while (nn) {
         ManagedNode* mn = new ManagedNode();
         mn->a = nn->a;
         mn->b = nn->b;
         mn->str = nn->str; // it just works!
         ar->Add(mn);       // append to list
         NativeNode* nnnext = nn->next; // save next ptr
         delete nn;                     // delete native node and..
         nn = nnnext;                   // ..move to next node
      }
      return ar;             // ..and return managed copy
   }
};

}

Figure 4 ConvertString.cpp
 

////////////////////////////////////////////////////////////////
// MSDN Magazine ! December 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//
#include < stdio.h >
#include < stdlib.h >
#include < vcclr.h >
#using < mscorlib.dll >
using namespace System;

//////////////////
// Shows how to convert managed String to char* or wchar_t
//
int main()
{
   // A managed string
   String* s = S"Hello, world";

   // Convert to wide char
   const wchar_t __pin* p = PtrToStringChars(s);
   printf("%S\n", (wchar_t*)p);

   // Convert to char:
   int len = wcstombs(NULL, p, 0)+1; // calculate required length..
   char* buf = (char*)malloc(len);   // ..allocate new string and..
   wcstombs(buf, p, len);            // ..convert
   printf("%s\n", buf);
}

Figure 5 ColorTab.cpp
 

////////////////////////////////////////////////////////////////
// MSDN Magazine ! December 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3.
//
// CColorTabCtrl implements a CTabCtrl with colored tabs.

#include "StdAfx.h"
#include "ColorTab.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNAMIC(CColorTabCtrl, CTabCtrl)
BEGIN_MESSAGE_MAP(CColorTabCtrl, CTabCtrl)
END_MESSAGE_MAP()

CColorTabCtrl::CColorTabCtrl()
{
   m_clrBackground = GetSysColor(COLOR_3DFACE);
   m_clrForeground = GetSysColor(COLOR_BTNTEXT);
}

CColorTabCtrl::~CColorTabCtrl()
{
}

//////////////////
// Set bg/gf colors
//
void CColorTabCtrl::SetColors(COLORREF bg, COLORREF fg)
{
   m_clrBackground = bg;
   m_clrForeground = fg;
}

//////////////////
// Subclass the tab control: also make owner-draw
// 
CColorTabCtrl::SubclassDlgItem(UINT nID, CWnd* pParent)
{
   if (!CTabCtrl::SubclassDlgItem(nID, pParent))
      return FALSE;
   ModifyStyle(0, TCS_OWNERDRAWFIXED);
   return TRUE;
}

//////////////////
// Draw the tab: use bg/fg colors.
//
void CColorTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
   DRAWITEMSTRUCT& ds = *lpDrawItemStruct;
   
   int iItem = ds.itemID;

   // Get tab item info
   char text[128];
   TCITEM tci;
   tci.mask = TCIF_TEXT;
   tci.pszText = text;
   tci.cchTextMax = sizeof(text);
   GetItem(iItem, &tci);

   // use draw item DC
   CDC dc;
   dc.Attach(ds.hDC);

   // calculate text rectangle and color
   CRect rc = ds.rcItem;
   rc += CPoint(1,4);                   // ?? by trial and error

   dc.FillSolidRect(rc, m_clrBackground);
   dc.SetBkColor(m_clrBackground);
   dc.SetTextColor(m_clrForeground);
   dc.DrawText(text, &rc, DT_CENTER|DT_VCENTER);

   dc.Detach();
}

IMPLEMENT_DYNAMIC(CColorPropertyPage, CPropertyPage)
BEGIN_MESSAGE_MAP(CColorPropertyPage, CPropertyPage)
   ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

CColorPropertyPage::CColorPropertyPage(UINT nID, COLORREF bg) : CPropertyPage(nID)
{
   SetBGColor(bg);
}

CColorPropertyPage::~CColorPropertyPage()
{

}

void CColorPropertyPage::SetBGColor(COLORREF bg)
{
   m_clrBackground = bg;
}

//////////////////
// Handle WM_ERASEBKGND: fill bg with bg color
//
BOOL CColorPropertyPage::OnEraseBkgnd(CDC* pDC)
{
   CRect rc;
   GetClientRect(&rc);
   pDC->FillSolidRect(rc, m_clrBackground);
   return TRUE;
}