Figure 1   VIRTOP.CPP

 ////////////////////////////////////////////////////////////////
// VIRTOP Copyright 1995 Microsoft Systems Journal. 
// Simple program to demonstrate "virtual" operator<<.
// If this program works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
//
// To compile, type
//
//    cl virtop.cpp (Microsoft)
//    bcc virtop.cpp (Borland)
// at the DOS prompt.

#include <iostream.h>

//////////////////
// Base class has friend operator and virtual protected print function.
//
class Fruit {
protected:
   virtual void print(ostream& os) const = 0;
public:
   friend ostream& operator<< (ostream& os, const Fruit& fruit);
};

//////////////////
// Derived classes implement their own print functions
//
class Apple : public Fruit {
protected:
   virtual void print(ostream& os) const { os << "apple"; }
};
   
class Orange : public Fruit {
protected:
   virtual void print(ostream& os) const { os << "orange"; }
};

////////////////
// There's just one operator<<
// It calls the virtual print function to do the work.
//
inline ostream& operator<< (ostream& os, const Fruit& fruit)
{
   fruit.print(os);
   return os;
}

////////////////
// Main program entry
//
int main()
{
   Apple  a;
   Orange o;
   Fruit* array[2] = { &a, &o };

       // print the fruits using operator<<
   for (int i=0; i<2; i++)
      cout << "Fruit #" << i << " is a " << *array[i] << "\n";

   return 0;
}

Figure 3   DCLIKBAR

DCLIKBAR.DEF

 ; dclikbar.def : Declares the module parameters for the application.

NAME         DCLIKBAR
DESCRIPTION  'DCLIKBAR Windows Application'
EXETYPE      WINDOWS

CODE         PRELOAD MOVEABLE DISCARDABLE
DATA         PRELOAD MOVEABLE MULTIPLE

HEAPSIZE     1024   ; initial heap size
; Stack size is passed as argument to linker's /STACK option

DCLIKBAR.RC

 //Microsoft Developer Studio generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""afxres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#include ""res\\app.rc2""  // non-App Studio edited resources\r\n"
    "\r\n"
    "#include ""afxres.rc""  \011// Standard components\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

IDR_MAINFRAME           ICON    DISCARDABLE     "RES\\APP.ICO"
IDR_DOCTYPE             ICON    DISCARDABLE     "RES\\DOC.ICO"

/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

IDR_MAINFRAME           BITMAP  MOVEABLE PURE   "RES\\TOOLBAR.BMP"

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_MAINFRAME MENU PRELOAD DISCARDABLE 
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&New\tCtrl+N",                ID_FILE_NEW
        MENUITEM "E&xit",                       ID_APP_EXIT
    END
    POPUP "&View"
    BEGIN
        MENUITEM "&Toolbar",                    ID_VIEW_TOOLBAR
        MENUITEM "&Status Bar",                 ID_VIEW_STATUS_BAR
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About DCLIKBAR...",          ID_APP_ABOUT
    END
END

IDR_DOCTYPE MENU PRELOAD DISCARDABLE 
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&New\tCtrl+N",                ID_FILE_NEW
        MENUITEM "&Close",                      ID_FILE_CLOSE
        MENUITEM "E&xit",                       ID_APP_EXIT
    END
    POPUP "&View"
    BEGIN
        MENUITEM "&Toolbar",                    ID_VIEW_TOOLBAR
        MENUITEM "&Status Bar",                 ID_VIEW_STATUS_BAR
    END
    POPUP "&Window"
    BEGIN
        MENUITEM "&New Window",                 ID_WINDOW_NEW
        MENUITEM "&Cascade",                    ID_WINDOW_CASCADE
        MENUITEM "&Tile",                       ID_WINDOW_TILE_HORZ
        MENUITEM "&Arrange Icons",              ID_WINDOW_ARRANGE
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About DCLIKBAR...",          ID_APP_ABOUT
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE 
BEGIN
    "N",            ID_FILE_NEW,            VIRTKEY, CONTROL
    "O",            ID_FILE_OPEN,           VIRTKEY, CONTROL
    "S",            ID_FILE_SAVE,           VIRTKEY, CONTROL
    "Z",            ID_EDIT_UNDO,           VIRTKEY, CONTROL
    "X",            ID_EDIT_CUT,            VIRTKEY, CONTROL
    "C",            ID_EDIT_COPY,           VIRTKEY, CONTROL
    "V",            ID_EDIT_PASTE,          VIRTKEY, CONTROL
    VK_BACK,        ID_EDIT_UNDO,           VIRTKEY, ALT
    VK_DELETE,      ID_EDIT_CUT,            VIRTKEY, SHIFT
    VK_INSERT,      ID_EDIT_COPY,           VIRTKEY, CONTROL
    VK_INSERT,      ID_EDIT_PASTE,          VIRTKEY, SHIFT
    VK_F6,          ID_NEXT_PANE,           VIRTKEY 
    VK_F6,          ID_PREV_PANE,           VIRTKEY, SHIFT
END


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOG DISCARDABLE  34, 22, 165, 74
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About DCLIKBAR"
FONT 8, "MS Sans Serif"
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,11,10,18,20
    LTEXT           "DCLIKBAR Copyright 1995 Microsoft Systems Journal",
                    IDC_STATIC,45,10,93,18
    LTEXT           "Written by Paul DiLascia",IDC_STATIC,45,30,87,12
    DEFPUSHBUTTON   "OK",IDOK,45,49,32,14,WS_GROUP
END


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE PRELOAD DISCARDABLE 
BEGIN
    IDR_MAINFRAME           "DCLIKBAR Windows Application"
    IDR_DOCTYPE             "\nDCLIKBAR\n\n\n\n\n"
END

STRINGTABLE PRELOAD DISCARDABLE 
BEGIN
    AFX_IDS_APP_TITLE       "DCLIKBAR Windows Application"
    AFX_IDS_IDLEMESSAGE     "Ready"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_INDICATOR_EXT        "EXT"
    ID_INDICATOR_CAPS       "CAP"
    ID_INDICATOR_NUM        "NUM"
    ID_INDICATOR_SCRL       "SCRL"
    ID_INDICATOR_OVR        "OVR"
    ID_INDICATOR_REC        "REC"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_FILE_NEW             "Create a new document"
    ID_FILE_OPEN            "Open an existing document"
    ID_FILE_CLOSE           "Close the active document"
    ID_FILE_SAVE            "Save the active document"
    ID_FILE_SAVE_AS         "Save the active document with a new name"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_APP_ABOUT            "Display program information, version number and
                             copyright"
    ID_APP_EXIT             "Quit the application; prompts to save documents"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_FILE_MRU_FILE1       "Open this document"
    ID_FILE_MRU_FILE2       "Open this document"
    ID_FILE_MRU_FILE3       "Open this document"
    ID_FILE_MRU_FILE4       "Open this document"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_NEXT_PANE            "Switch to the next window pane"
    ID_PREV_PANE            "Switch back to the previous window pane"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_WINDOW_NEW           "Open another window for the active document"
    ID_WINDOW_ARRANGE       "Arrange icons at the bottom of the window"
    ID_WINDOW_CASCADE       "Arrange windows so they overlap"
    ID_WINDOW_TILE_HORZ     "Arrange windows as non-overlapping tiles"
    ID_WINDOW_TILE_VERT     "Arrange windows as non-overlapping tiles"
    ID_WINDOW_SPLIT         "Split the active window into panes"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_EDIT_CLEAR           "Erase the selection"
    ID_EDIT_CLEAR_ALL       "Erase everything"
    ID_EDIT_COPY            "Copy the selection and put it on the Clipboard"
    ID_EDIT_CUT             "Cut the selection and put it on the Clipboard"
    ID_EDIT_FIND            "Find the specified text"
    ID_EDIT_PASTE           "Insert Clipboard contents"
    ID_EDIT_REPEAT          "Repeat the last action"
    ID_EDIT_REPLACE         "Replace specific text with different text"
    ID_EDIT_SELECT_ALL      "Select the entire document"
    ID_EDIT_UNDO            "Undo the last action"
    ID_EDIT_REDO            "Redo the previously undone action"
END

STRINGTABLE DISCARDABLE 
BEGIN
    ID_VIEW_TOOLBAR         "Show or hide the toolbar"
    ID_VIEW_STATUS_BAR      "Show or hide the status bar"
END

STRINGTABLE DISCARDABLE 
BEGIN
    AFX_IDS_SCSIZE          "Change the window size"
    AFX_IDS_SCMOVE          "Change the window position"
    AFX_IDS_SCMINIMIZE      "Reduce the window to an icon"
    AFX_IDS_SCMAXIMIZE      "Enlarge the window to full size"
    AFX_IDS_SCNEXTWINDOW    "Switch to the next document window"
    AFX_IDS_SCPREVWINDOW    "Switch to the previous document window"
    AFX_IDS_SCCLOSE         "Close the active window and prompts to save the 
                             documents"
END

STRINGTABLE DISCARDABLE 
BEGIN
    AFX_IDS_SCRESTORE       "Restore the window to normal size"
    AFX_IDS_SCTASKLIST      "Activate Task List"
    AFX_IDS_MDICHILD        "Activate this window"
END


#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "res\app.rc2"  // non-App Studio edited resources

#include "afxres.rc"         // Standard components

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

DCLIKBAR.H

 ////////////////////////////////////////////////////////////////
// DCLIKBAR Copyright 1995 Microsoft Systems Journal. 
// If this program works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
//
// See DCLIKBAR.CPP for Description of program.

#include "resource.h"

class CDclikbarApp : public CWinApp {
public:
       CDclikbarApp();
       virtual BOOL InitInstance();

       //{{AFX_MSG(CDclikbarApp)
       afx_msg void OnAppAbout();
       //}}AFX_MSG
       DECLARE_MESSAGE_MAP()
};

DCLIKBAR.CPP

 ////////////////////////////////////////////////////////////////
// DCLIKBAR Copyright 1995 Microsoft Systems Journal. 
// If this program works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// DCLIKBAR shows how to change the window class name of your application's
// main windows, and also how to implement a control bar that allows 
// double-clicking.
//
// All the interesting code is in MAINFRM.CPP
// Makefiles: DCLIK152.MAK for VC++ 1.52
//            DCLIKB22.MAK for VC++ 2.2
//            DCLIKB40.MAK for VC++ 4.0

#include "stdafx.h"
#include "dclikbar.h"
#include "mainfrm.h"
#include "doc.h"
#include "view.h"

CDclikbarApp NEAR theApp;

BEGIN_MESSAGE_MAP(CDclikbarApp, CWinApp)
        //{{AFX_MSG_MAP(CDclikbarApp)
        ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
        //}}AFX_MSG_MAP
        ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
        ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

CDclikbarApp::CDclikbarApp()
{
}

BOOL CDclikbarApp::InitInstance()
{
        SetDialogBkColor();        // Set dialog background color to gray

        CMultiDocTemplate* pDocTemplate;
        pDocTemplate = new CMultiDocTemplate(
                IDR_DOCTYPE,
                RUNTIME_CLASS(CMyDoc),
                RUNTIME_CLASS(CMyChildFrame),
                RUNTIME_CLASS(CMyView));
        AddDocTemplate(pDocTemplate);

        // create main MDI Frame window
        CMainFrame* pMainFrame = new CMainFrame;
        if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
                return FALSE;
        m_pMainWnd = pMainFrame;

        pMainFrame->ShowWindow(m_nCmdShow);
        pMainFrame->UpdateWindow();

        OnFileNew();

        return TRUE;
}

class CAboutDlg : public CDialog {
public:
        CAboutDlg() : CDialog(IDD_ABOUTBOX) { }
};

void CDclikbarApp::OnAppAbout()
{
        CAboutDlg aboutDlg;
        aboutDlg.DoModal();
}

MAINFRM.H

 //////////////////
// Derived toolbar class to handle double-clicks.
//
class CMyToolBar : public CToolBar {
       static LPCSTR s_winClassName;
       DECLARE_DYNAMIC(CMyToolBar)
protected:
#if _MFC_VER < 0x0400
       virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
#endif
       //{{AFX_MSG(CMyToolBar)
       afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
       afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
       //}}AFX_MSG
       DECLARE_MESSAGE_MAP()
};

//////////////////
// Standard main frame. 
// Overrides PreCreateWindow to change window class name.
//
class CMainFrame : public CMDIFrameWnd {
       static LPCSTR s_winClassName;
       DECLARE_DYNAMIC(CMainFrame)
public:
       CMainFrame();
       virtual ~CMainFrame();
protected:

#if _MSC_VER < 0x0400
       // Not required for MFC 4.0 and later.
       virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
#endif

       CStatusBar  m_wndStatusBar;
       CMyToolBar  m_wndToolBar;

       //{{AFX_MSG(CMainFrame)
       afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
       //}}AFX_MSG
       DECLARE_MESSAGE_MAP()
};

//////////////////
// Derived child frame overrides PreCreateWindow
// to change the window class name.
//
class CMyChildFrame : public CMDIChildWnd {
       static LPCSTR s_winClassName;
       DECLARE_DYNCREATE(CMyChildFrame)
public:
       CMyChildFrame();
       virtual ~CMyChildFrame();
protected:
       virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
       //{{AFX_MSG(CMyChildFrame)
       //}}AFX_MSG
       DECLARE_MESSAGE_MAP()
};

MAINFRM.CPP

 #include "stdafx.h"
#include "dclikbar.h"
#include "mainfrm.h"

#ifndef AfxRegisterClass
// AfxRegisterClass is only defined in 32-bit versions of MFC
#define AfxRegisterClass ::RegisterClass
#endif

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
       //{{AFX_MSG_MAP(CMainFrame)
       ON_WM_CREATE()
       //}}AFX_MSG_MAP
END_MESSAGE_MAP()

// Static class member holds window class name
// (NULL if not registered yet).
// 
LPCSTR CMainFrame::s_winClassName = NULL;

static UINT BASED_CODE buttons[] = {
       ID_FILE_NEW, 
       ID_SEPARATOR, 
       ID_APP_ABOUT
};

static UINT BASED_CODE indicators[] = {
       ID_SEPARATOR,
       ID_INDICATOR_CAPS,
       ID_INDICATOR_NUM,
       ID_INDICATOR_SCRL,
};

CMainFrame::CMainFrame()
{
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
       if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
              return -1;

       if (!m_wndToolBar.Create(this) ||
              !m_wndToolBar.LoadBitmap(IDR_MAINFRAME) ||
              !m_wndToolBar.SetButtons(buttons,
                sizeof(buttons)/sizeof(UINT)) )
       {
              TRACE("Failed to create toolbar\n");
              return -1;      // fail to create
       }
       if (!m_wndStatusBar.Create(this) ||
              !m_wndStatusBar.SetIndicators(indicators,
                sizeof(indicators)/sizeof(UINT)))
       {
              TRACE("Failed to create status bar\n");
              return -1;      // fail to create
       }
       return 0;
}

//////////////////
// Helper function to register a new window class based on an already
// existing window class, but with a different name and icon. 
// Returns new name if successful; otherwise NULL.
//
static LPCSTR RegisterSimilarClass(LPCSTR lpszNewClassName,
       LPCSTR lpszOldClassName, UINT nIDResource)
{
       // Get class info for old class.
       //
       HINSTANCE hInst = AfxGetInstanceHandle();
       WNDCLASS wc;
       if (!::GetClassInfo(hInst, lpszOldClassName, &wc)) {
              TRACE("Can't find window class %s\n", lpszOldClassName);
              return NULL;
       }

       // Register new class with same info, but different name and icon.
       //
       wc.lpszClassName = lpszNewClassName;
       wc.hIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(nIDResource));
       if (!AfxRegisterClass(&wc)) {
              TRACE("Unable to register window class%s\n", lpszNewClassName);
              return NULL;
       }
       return lpszNewClassName;
}

//////////////////
// Override to register the different class and change window class name.
//
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
       if (!CFrameWnd::PreCreateWindow(cs))
              return FALSE;

       if (s_winClassName==NULL) {       
              // One-time initialization: register the class
              //
              s_winClassName = RegisterSimilarClass("MyMainFrame", 
                     cs.lpszClass, IDR_MAINFRAME);
              if (!s_winClassName)
                     return FALSE;
       }
       cs.lpszClass = s_winClassName;
       return TRUE;
}

////////////////////////////////////////////////////////////////
// CMyChildFrame implementation
//
IMPLEMENT_DYNCREATE(CMyChildFrame, CMDIChildWnd)

BEGIN_MESSAGE_MAP(CMyChildFrame, CMDIChildWnd)
       //{{AFX_MSG_MAP(CMyChildFrame)
       //}}AFX_MSG_MAP
END_MESSAGE_MAP()

// Static class member holds window class name
// (NULL if not registered yet).
// 
LPCSTR CMyChildFrame::s_winClassName = NULL;

CMyChildFrame::CMyChildFrame()
{
}

CMyChildFrame::~CMyChildFrame()
{
}

//////////////////
// Override to register the different class and change window class name.
//
BOOL CMyChildFrame::PreCreateWindow(CREATESTRUCT& cs)
{
       if (!CMDIChildWnd::PreCreateWindow(cs))
              return FALSE;

       if (s_winClassName==NULL) {
              // One-time initialization: register the class
              //
              s_winClassName = RegisterSimilarClass("MyChildFrame", 
                     cs.lpszClass, IDR_DOCTYPE);
              if (!s_winClassName)
                     return FALSE;
       }
       cs.lpszClass = s_winClassName;
       return TRUE;
}

////////////////////////////////////////////////////////////////
// CMyToolBar implementation. 
//

IMPLEMENT_DYNAMIC(CMyToolBar, CToolBar)

BEGIN_MESSAGE_MAP(CMyToolBar, CToolBar)
       //{{AFX_MSG_MAP(CMyToolBar)
       ON_WM_LBUTTONDBLCLK()
       //}}AFX_MSG_MAP
END_MESSAGE_MAP()

//////////////////
// Handle double-click
//
void CMyToolBar::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
       MessageBox("OK, I got the double-click. Now what?");
}

// Static class member holds window class name
// (NULL if not registered yet).
// 
LPCSTR CMyToolBar::s_winClassName = NULL;

//////////////////
// Override this function to register the different class
// Required for pre-4.0 MFC ONLY! MFC version 4.0 and later uses 
// real Win32 toolbar control, which accepts double-clicks, 
// so there's no need to register a new class.
//
#if _MFC_VER < 0x0400

BOOL CMyToolBar::PreCreateWindow(CREATESTRUCT& cs)
{
       if (!CToolBar::PreCreateWindow(cs))
              return FALSE;

       if (s_winClassName==NULL) {       

              // One-time initialization: register new class with same info, 
              // but different name and style.
              //
              WNDCLASS wc;
              HINSTANCE hInst = AfxGetInstanceHandle();

              // Get data for AfxControlBar
              if (!::GetClassInfo(hInst, cs.lpszClass, &wc)) {
                    TRACE("Can't find window class \"%s\"\n", cs.lpszClass);
                     return FALSE;
              }

              // Change name and style to allow double-clicks
              wc.lpszClassName = "MyControlBar";
              wc.style |= CS_DBLCLKS;
              if (!AfxRegisterClass(&wc)) {
                     TRACE("Unable to register window class MyControlBar\n");
                     return FALSE;
              }
              s_winClassName = wc.lpszClassName;
       }
       cs.lpszClass = s_winClassName;
       return TRUE;
}

#endif // _MFC_VER

Figure 6   Creating a Toolbar that Handles Double Clicks<

 LPCSTR CMyToolBar::s_winClassName = NULL;

BOOL CMyToolBar::PreCreateWindow(CREATESTRUCT& cs)
{
  if (!CToolBar::PreCreateWindow(cs))
    return FALSE;

  if (s_winClassName==NULL) {   
    // One-time initialization: register new class
    // with same info, but different name and style.

    // Get data for AfxControlBar
    WNDCLASS wc;
    VERIFY(::GetClassInfo(AfxGetInstanceHandle(), 
      cs.lpszClass, &wc));

    // Change name and style to allow double-clicks
    wc.lpszClassName = "MyControlBar";
    wc.style |= CS_DBLCLKS;
    VERIFY(AfxRegisterClass(&wc));
    s_winClassName = wc.lpszClassName;
  }
  cs.lpszClass = s_winClassName;
  return TRUE;
}

Figure 8   New Write Function for TRACEWIN

 // Modified Write function from TRACEWIN.H
//
void CMfxTrace::Write(const void* lpBuf, UINT nCount)
{
       if (!afxTraceEnabled)
              return;

       CWnd *pTraceWnd = CWnd::FindWindow(TRACEWND_CLASSNAME, NULL);
       if (pTraceWnd) {
              // Found Trace window: send string with WM_COPYDATA
              //
              COPYDATASTRUCT cds;
              cds.dwData = ID_COPYDATA_TRACEMSG;
              cds.cbData = nCount;
              cds.lpData = (void*)lpBuf;
              pTraceWnd->SendMessage(WM_COPYDATA, 
                     (WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(), 
                     (LPARAM)&cds);

       } else {
              // No trace window: do normal debug thing
              //
              ::OutputDebugString((LPCSTR)lpBuf);       
       }
}

Figure 9   Modified MAINFRM.CPP from TRACEWIN

 // (From modified TRACEWIN source, mainfrm.cpp)
//

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
       //{{AFX_MSG_MAP(CMainFrame)
       ON_MESSAGE(WM_COPYDATA, OnTraceMsg)
       .
       .
       .
       //}}AFX_MSG_MAP
END_MESSAGE_MAP()

//////////////////
// Someone sent me a WM_COPYDATA message: display it.
//
LRESULT CMainFrame::OnTraceMsg(WPARAM wParam, LPARAM lParam)
{
       COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;
       if (m_nOutputWhere==ID_OUTPUT_OFF || pcds->dwData!=ID_COPYDATA_TRACEMSG)
              return 0;

       const char* lpText = (const char*)pcds->lpData;
       DWORD len = pcds->cbData;

       if (m_nOutputWhere==ID_OUTPUT_TO_WINDOW) {
              // Convert \n to \n\r for Windows brain-damaged edit control
              // It's 1995, and I'm still writing code like this!
              //
              const char* src = lpText;
              const char* endsrc = lpText + len;

              char buf[1024];
              char* dst = buf;
              char* endbuf = buf + sizeof(buf) - 1;

              while (src < endsrc && dst < endbuf) {
                     if (*src == '\n')
                            *dst++ = '\r';
                     *dst++ = *src++;
              }
              *dst = 0;

              // Append string to contents of trace buffer
              m_wndBuffer.SetSel(-1, -1);               // end of edit text
              m_wndBuffer.ReplaceSel(buf);              // append string..
              m_wndBuffer.SendMessage(EM_SCROLLCARET);  // ..and show caret

       } else if (m_nOutputWhere==ID_OUTPUT_TO_FILE) {
              m_file.Write(lpText, len);

       }

       return 0;
}