////////////////////////////////////////////////////////////////
// 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;
}