This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com PUBLISHED BY Microsoft Press A Division of Microsoft Corporation One Microsoft Way Redmond, Washington 98052-6399 Copyright © 2003 by George Shepherd All rights reserved No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission of the publisher Library of Congress Cataloging-in-Publication Data Shepherd, George Programming with Microsoft Visual C++ NET, Sixth Edition (Core Reference) / Georg p cm Includes index ISBN 0-7356-1549-7 2002 Printed and bound in the United States of America QWT Distributed in Canada by H.B Fenn and Company Ltd A CIP catalogue record for this book is available from the British Library Microsoft Press books are available through booksellers and distributors worldwide For further informa-tion about international editions, contact your local Microsoft Corporation office or contact Microsoft Press International directly at fax (425) 936-7329 Visit our Web site at www.microsoft.com/mspress Send comments to mspinput@microsoft.com Active Directory, ActiveX, FrontPage, Links, Microsoft, Microsoft Press, MSDN, Outlook, PivotChart, PivotTable, PowerPoint, SharePoint, Visio, Visual Basic, Windows, and Windows NT are either regis-tered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries Other product and company names mentioned herein may be the trademarks of their respective owners The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred The example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious No association with any real company, organization, product, domain name, e-mail address, logo, person, place, or event is intended or should be inferred Acquisitions Editors: Juliana Aldous and Danielle Bird Project Editor: Denise Bankaitis Technical Editor: Julie Xiao This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Dedicated to Sandy Daston and Ted Shepherd This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Acknowledgments This part of book writing is always the best—everybody involved is nearly done with the manuscript and all that's left to is to thank everybody Because the author's name appears on the cover, it's sometimes easy to forget all the other folks involved in a project as large as this Many other folks gave their time and energy to this project, and I wish to thank you Thank you Sandy Daston and Ted Shepherd—my family, for your support while I wrote this book Thank you, Denise Bankaitis As the project editor, you kept me going by reminding me of the importance of this project (a key C++ reference for NET) and by coordinating the efforts of the rest of the team, which includes Julie Xiao, Ina Chang, Danielle Bird, Juliana Aldous, Joel Panchot, Carl Diltz, and Gina Cassill Thank you, Julie Xiao, for keeping the manuscript accurate Thank you, Ina Chang, for making my sentences readable Thank you, Danielle Bird and Juliana Aldous As acquisition editors, you got this project rolling and kept it on track Thank you, Joel Panchot, for making sure the art in this book looks good Thank you, Carl Diltz and Gina Cassill, for composing the manuscript and making it look great I would also like to thank the folks at DevelopMentor, for providing a wonderful environment and community for thinking and learning about modern computing You guys are wonderful This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Introduction The release of the Microsoft Visual Studio NET (and Visual C++ NET in particular) has underscored Microsoft’s increasing focus on Internet technologies, which are at the heart of the Microsoft NET architecture In addition to supporting the NET initiative, Visual C++ NET keeps all the productivity-boosting features you’re familiar with, such as Edit And Continue, IntelliSense, AutoComplete, and code tips Visual C++ NET also includes many new features such as managed code extensions for NET programming, support for attributed code, and a more consistent development environment These features take Visual C++ NET to a new level This book will get you up to speed on the latest technologies introduced into Visual C++ This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com NET, MFC, and ATL The technology churn we face these days is pretty impressive We went from no computers on our office desktops to nearly everyone having a computer running MS-DOS in the 1980s to nearly everyone running Microsoft Windows by the mid-1990s The technology wheel is about to turn again In the late 1990s, everyone was developing Web sites by hand using tools such as raw Hypertext Markup Language (HTML), Common Gateway Interface (CGI), Internet Server Application Programming Interface (ISAPI) DLLs, Java, and Active Server Pages (ASP) In July 2000, Microsoft announced to the world that it would change all that by betting the company on a new technology direction named NET The current thrust of Microsoft is indeed NET For a number of years, it’s been possible to build a Web site by setting up a server somewhere, getting an IP address, and putting up some content Anyone with the URL of your site can surf there and check it out Commercial enterprises have been taking advantage of the Web by posting information that’s useful to customers The Web has also become an invaluable research tool and efficient news broadcast medium The computing world of the near future will involve the Web heavily However, rather than just having human eyeballs look at Web sites, computers themselves will look at Web sites That is, Web sites will be programmable through Web services The NET vision also pushes the responsibility of providing a rich user interface out to the server With so much emphasis on Web services and server-based user interfaces, it might seem that standalone applications and client-side user interface scenarios—normally the realm of tools such as the Microsoft Foundation Class Library (MFC)—will be left in the dust But the need for rich client-side user interfaces is unlikely to go away Many thought that the advent of the PC and distribution technologies would spell the end of centralized processing on mainframes and minicomputers It turns out that PCs and distribution technologies only added to the available computing arsenal The NET vision of Web services and rich user interfaces provided by the server only adds to the options available to software developers Rich clientside user interfaces will continue to be viable for many types of applications, running alongside other applications that use other kinds of user interfaces (such as server-generated user interfaces) MFC is a mature and well-understood technology that’s accompanied by a host of third-party extensions For at least a little while longer, MFC represents the most effective way to write full-featured standalone applications A good portion of this book will focus on MFC-style development, but we’ll also cover Windows Forms—the NET way to write client-side user interfaces Of course, the next question is: Where does this leave COM? COM has solved many problems related to distributed processing, but it has some serious shortcomings—mostly centered around component versioning and type information Microsoft’s NET vision is based on the common language runtime The runtime takes the place of COM as the interoperability standard within NET We’ll cover NET and the common language runtime in depth in Part VI of this book This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com COM and the common language runtime represent different approaches to component architecture, but Microsoft has taken great care to ensure a seamless coexistence The interoperability path between COM and the runtime is smooth in most cases Within the NET world, you probably won’t find yourself using COM as a component architecture However, you might find yourself using Active Template Library (ATL) Server, which is a highperformance means of writing Web sites I’ve updated the coverage of ATL and MFC in this edition of the book because you’ll still find it very useful More important, I’ll show you how to leverage your heritage code (sounds better than “legacy code,” doesn’t it?) as you move into the NET world This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Managed C++ vs C# The NET platform has introduced a new C++-like language named C# C# is a curly-braceoriented language without all the headaches of C++ Much of C#’s appeal is due to the fact that it’s missing some of the more problematic elements of C++ (such as raw pointer management) while maintaining the useful features (such as virtual functions) The C# compiler eventually emits managed code—the kind that runs under the common language runtime However, the entire world isn’t going to switch over to C# overnight There’s just too much C++ code out there to convert Also, it will take a bit of time for developers to become fully comfortable with C# In the meantime, NET has introduced extensions to C++ for producing managed code (code that runs under the common language runtime) Managed Extensions for C++ will help ease the burden of developing software for the NET platform because they allow you to quickly update existing C++ code to work with NET Getting the managed code features in C++ means sprinkling your code with various keywords In the end, C# and managed C++ boil down to the same executable code once the compilers are done with it In the NET world, you’ll probably find yourself writing new components using C# while using managed C++ to add NET features to your existing code base This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com NET vs the Java Platform In recent years, we’ve seen a great deal of interest in the Java programming language and platform Java became a great boon for Internet developers by providing a useful means of distributing client user interfaces (through Java applets) and by providing enterprise solutions through Java Enterprise Edition Now, NET has become the best Internet development platform available today Unlike the Java platform, which requires that you write all your code using the Java syntax, NET often lets you use multiple syntaxes to arrive at the same machine instruction set You can use C++ (the main focus of this book) and its managed extensions, Visual Basic NET, C#, and even a host of third-party NET languages to write your programs Once you develop your source code, it is compiled to intermediate language and then eventually machine code before it runs Because NET code is managed by a runtime, you get benefits such as garbage collection and better code security This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Who This Book Is For Visual C++ NET, with its sophisticated application framework and support for NET, is for professional programmers, and so is this book I’ll assume that you’re proficient in the C language—you can write an if statement without consulting the manual And I’ll assume that you’ve been exposed to the C++ language—you’ve at least taken a course or read a book even if you haven’t written much code You might compare learning C++ to learning French You can study French in school, but you won’t be able to speak fluently unless you go to a Frenchspeaking country and start talking to people The Visual C++ wizards save you time and improve accuracy, but programmers must understand the code that the wizards generate and, ultimately, they must understand the structure of the MFC and ATL libraries, the inner workings of the Windows operating system, and how NET works I won’t assume, however, that you already know Windows and NET programming I’m sure that proficient C programmers can learn Windows the MFC way and the NET way It’s more important to know C++ than it is to know the Win32 application programming interface (API) You should, however, know how to run Windows and Windows-based applications If you’re already experienced with the Win32 API or with the MFC library, there’s something in this book for you, too You’ll learn about new features such as the Multiple Top-Level Interface (MTI) and the Visual C++ NET wizards If you haven’t already figured out the Component Object Model (COM), this book presents some important theory that will get you started on understanding ActiveX controls You’ll also learn about ATL Server and OLE DB templates And you’ll learn about C++ programming for the Internet (including Dynamic HTML) Finally, this book includes hard-to-find coverage of the new managed C++ extensions This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com ON_WM_DRAWITEM_REFLECT() afx_msg void DrawItem (LPDRAWITEMSTRUCT); ON_WM_DROPFILES() afx_msg void OnDropFiles(HDROP); ON_WM_ENABLE() afx_msg void OnEnable(BOOL); ON_WM_ENDSESSION() afx_msg void OnEndSession(BOOL); ON_WM_ENTERIDLE() afx_msg void OnEnterIdle(UINT, CWnd*); ON_WM_ENTERMENULOOP() afx_msg void OnEnterMenuLoop(BOOL); ON_WM_ERASEBKGND() afx_msg BOOL OnEraseBkgnd(CDC*); ON_WM_EXITMENULOOP() afx_msg void OnExitMenuLoop(BOOL); ON_WM_FONTCHANGE() afx_msg void OnFontChange(); ON_WM_GETDLGCODE() afx_msg UINT OnGetDlgCode(); ON_WM_GETMINMAXINFO() afx_msg void OnGetMinMaxInfo (MINMAXINFO*); ON_WM_HELPINFO() afx_msg BOOL OnHelpInfo(HELPINFO*); ON_WM_HSCROLL() afx_msg void OnHScroll(UINT, UINT, CScrollBar*); ON_WM_HSCROLL_REFLECT() afx_msg void HScroll(UINT, UINT); ON_WM_HSCROLLCLIPBOARD() afx_msg void OnHScrollClipboard(CWnd*, UINT, UINT); ON_WM_ICONERASEBKGND() afx_msg void OnIconEraseBkgnd(CDC*); ON_WM_INITMENU() afx_msg void OnInitMenu(CMenu*); ON_WM_INITMENUPOPUP() afx_msg void OnInitMenuPopup(CMenu*, UINT, BOOL); ON_WM_KEYDOWN() afx_msg void OnKeyDown(UINT, UINT, UINT); ON_WM_KEYUP() afx_msg void OnKeyUp(UINT, UINT, UINT); ON_WM_KILLFOCUS() afx_msg void OnKillFocus(CWnd*); ON_WM_LBUTTONDBLCLK() afx_msg void OnLButtonDblClk(UINT, CPoint); ON_WM_LBUTTONDOWN() afx_msg void OnLButtonDown(UINT, CPoint); ON_WM_LBUTTONUP() afx_msg void OnLButtonUp(UINT, CPoint); ON_WM_MBUTTONDBLCLK() afx_msg void OnMButtonDblClk(UINT, CPoint); ON_WM_MBUTTONDOWN() afx_msg void OnMButtonDown(UINT, CPoint); ON_WM_MBUTTONUP() afx_msg void OnMButtonUp(UINT, CPoint); This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com ON_WM_MDIACTIVATE() afx_msg void OnMDIActivate(BOOL, CWnd*, CWnd*); ON_WM_MEASUREITEM() afx_msg void OnMeasureItem(int, LPMEASUREITEMSTRUCT); ON_WM_MEASUREITEM_REFLECT() afx_msg void MeasureItem (LPMEASUREITEMSTRUCT); ON_WM_MENUCHAR() afx_msg LRESULT OnMenuChar(UINT, UINT, CMenu*); ON_WM_MENUSELECT() afx_msg void OnMenuSelect(UINT, UINT, HMENU); ON_WM_MOUSEACTIVATE() afx_msg int OnMouseActivate(CWnd*, UINT, UINT); ON_WM_MOUSEMOVE() afx_msg void OnMouseMove(UINT, CPoint); ON_WM_MOUSEWHEEL() afx_msg BOOL OnMouseWheel(UINT, short, CPoint); ON_WM_MOVE() afx_msg void OnMove(int, int); ON_WM_MOVING() afx_msg void OnMoving(UINT, LPRECT); ON_WM_NCACTIVATE() afx_msg BOOL OnNcActivate(BOOL); ON_WM_NCCALCSIZE() afx_msg void OnNcCalcSize(BOOL, NCCALCSIZE_PARAMS*); ON_WM_NCCREATE() afx_msg BOOL OnNcCreate (LPCREATESTRUCT); ON_WM_NCDESTROY() afx_msg void OnNcDestroy(); ON_WM_NCHITTEST() afx_msg UINT OnNcHitTest(CPoint); ON_WM_NCLBUTTONDBLCLK() afx_msg void OnNcLButtonDblClk(UINT, CPoint); ON_WM_NCLBUTTONDOWN() afx_msg void OnNcLButtonDown(UINT, CPoint); ON_WM_NCLBUTTONUP() afx_msg void OnNcLButtonUp(UINT, CPoint); ON_WM_NCMBUTTONDBLCLK() afx_msg void OnNcMButtonDblClk(UINT, CPoint); ON_WM_NCMBUTTONDOWN() afx_msg void OnNcMButtonDown(UINT, CPoint); ON_WM_NCMBUTTONUP() afx_msg void OnNcMButtonUp(UINT, CPoint); ON_WM_NCMOUSEMOVE() afx_msg void OnNcMouseMove(UINT, CPoint); ON_WM_NCPAINT() afx_msg void OnNcPaint(); This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com ON_WM_NCRBUTTONDBLCLK() afx_msg void OnNcRButtonDblClk(UINT, CPoint); ON_WM_NCRBUTTONDOWN() afx_msg void OnNcRButtonDown(UINT, CPoint); ON_WM_NCRBUTTONUP() afx_msg void OnNcRButtonUp(UINT, CPoint); ON_WM_PAINT() afx_msg void OnPaint(); ON_WM_PAINTCLIPBOARD() afx_msg void OnPaintClipboard(CWnd*, HGLOBAL); ON_WM_PALETTECHANGED() afx_msg void OnPaletteChanged(CWnd*); ON_WM_PALETTEISCHANGING() afx_msg void OnPaletteIsChanging(CWnd*); ON_WM_PARENTNOTIFY() afx_msg void OnParentNotify(UINT, LPARAM); ON_WM_PARENTNOTIFY_REFLECT() afx_msg void ParentNotify(UINT, LPARAM); ON_WM_QUERYDRAGICON() afx_msg HCURSOR OnQueryDragIcon(); ON_WM_QUERYENDSESSION() afx_msg BOOL OnQueryEndSession(); ON_WM_QUERYNEWPALETTE() afx_msg BOOL OnQueryNewPalette(); ON_WM_QUERYOPEN() afx_msg BOOL OnQueryOpen(); ON_WM_RBUTTONDBLCLK() afx_msg void OnRButtonDblClk(UINT, CPoint); ON_WM_RBUTTONDOWN() afx_msg void OnRButtonDown(UINT, CPoint); ON_WM_RBUTTONUP() afx_msg void OnRButtonUp(UINT, CPoint); ON_WM_RENDERALLFORMATS() afx_msg void OnRenderAllFormats(); ON_WM_RENDERFORMAT() afx_msg void OnRenderFormat(UINT); ON_WM_SETCURSOR() afx_msg BOOL OnSetCursor(CWnd*, UINT, UINT); ON_WM_SETFOCUS() afx_msg void OnSetFocus(CWnd*); ON_WM_SETTINGCHANGE() afx_msg void OnSettingChange(UINT, LPCTSTR); ON_WM_SHOWWINDOW() afx_msg void OnShowWindow(BOOL, UINT); ON_WM_SIZE() afx_msg void OnSize(UINT, int, int); ON_WM_SIZECLIPBOARD() afx_msg void OnSizeClipboard(CWnd*, HGLOBAL); ON_WM_SIZING() afx_msg void OnSizing(UINT, LPRECT); ON_WM_SPOOLERSTATUS() afx_msg void OnSpoolerStatus(UINT, UINT); ON_WM_STYLECHANGED() afx_msg void OnStyleChanged(int, This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com LPSTYLESTRUCT); ON_WM_STYLECHANGING() afx_msg void OnStyleChanging(int, LPSTYLESTRUCT); ON_WM_SYSCHAR() afx_msg void OnSysChar(UINT, UINT, UINT); ON_WM_SYSCOLORCHANGE() afx_msg void OnSysColorChange(); ON_WM_SYSCOMMAND() afx_msg void OnSysCommand(UINT, LPARAM); ON_WM_SYSDEADCHAR() afx_msg void OnSysDeadChar(UINT, UINT, UINT); ON_WM_SYSKEYDOWN() afx_msg void OnSysKeyDown(UINT, UINT, UINT); ON_WM_SYSKEYUP() afx_msg void OnSysKeyUp(UINT, UINT, UINT); ON_WM_TCARD() afx_msg void OnTCard(UINT, DWORD); ON_WM_TIMECHANGE() afx_msg void OnTimeChange(); ON_WM_TIMER() afx_msg void OnTimer(UINT); ON_WM_VKEYTOITEM() afx_msg int OnVKeyToItem(UINT, CListBox*, UINT); ON_WM_VKEYTOITEM_REFLECT() afx_msg int VKeyToItem(UINT, UINT); ON_WM_VSCROLL() afx_msg void OnVScroll(UINT, UINT, CScrollBar*); ON_WM_VSCROLL_REFLECT() afx_msg void VScroll(UINT, UINT); ON_WM_VSCROLLCLIPBOARD() afx_msg void OnVScrollClipboard(CWnd*, UINT, UINT); ON_WM_WINDOWPOSCHANGED() afx_msg void OnWindowPosChanged (WINDOWPOS*); ON_WM_WINDOWPOSCHANGING() afx_msg void OnWindowPosChanging (WINDOWPOS*); ON_WM_WININICHANGE() afx_msg void OnWinIniChange(LPCTSTR); Table 2-4 User-Defined Message Codes Map Entry Function Prototype ON_MESSAGE(,) afx_msg LRESULT memberFxn(WPARAM, LPARAM); ON_REGISTERED_MESSAGE (,) afx_msg LRESULT memberFxn(WPARAM, LPARAM); ON_REGISTERED_THREAD MESSAGE (, ) afx_msg void memberFxn(WPARAM, LPARAM); This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com ON_THREAD_MESSAGE (, ) afx_msg void memberFxn(WPARAM, LPARAM); This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Appendix B MFC Library Runtime Class Identification and Dynamic Object Creation Long before runtime type information (RTTI) was added to the C++ language specification, the MFC library designers realized that they needed runtime access to an object’s class name and to the position of the class in the hierarchy Also, the document-view architecture (and, later, COM class factories) demanded that objects be constructed from a class specified at run time So the MFC team created an integrated macro-based class identification and dynamic creation system that depends on the universal CObject base class And in spite of the fact that the Visual C++ NET compiler supports the ANSI RTTI syntax, the MFC library continues to use the original system, which actually has more features This appendix explains how the MFC library implements the class identification and dynamic creation features You’ll see how the DECLARE-_DYNAMIC, DECLARE_DYNCREATE, and associated macros work, and you’ll learn about the RUNTIME_CLASS macro and the CRuntimeClass structure This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Getting an Object’s Class Name at Run Time If you want only an object’s class name, you’ll have an easy time, assuming that all your classes are derived from a common base class, CObject (Note that this example does not use the real MFC CObject class.) Here’s how you get the class name: class CObject { public: virtual char* GetClassName() const { return NULL; } }; class CMyClass : public CObject { public: static char s_lpszClassName[]; virtual char* GetClassName() const { return s_lpszClassName; } }; char CMyClass::s_szClassName[] = "CMyClass"; Each derived class overrides the virtual GetClassName function, which returns a static string You get an object’s actual class name even if you use a CObject pointer to call GetClassName If you need the class name feature in many classes, you can save yourself some work by writing macros A DECLARE_CLASSNAME macro might insert the static data member and the GetClassName function in the class declaration, and an IMPLEMENT_CLASSNAME macro might define the class name string in the implementation file This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com The MFC CRuntimeClass Structure and the RUNTIME_CLASS Macro In a real MFC program, an instance of the CRuntimeClass structure replaces the static s_lpszClassName data member shown above This structure has data members for the class name and the object size; it also contains a pointer to a special static function, CreateObject, that’s supposed to be implemented in the target class Here’s a simplified version of CRuntimeClass: struct CRuntimeClass { // Attributes LPCSTR m_lpszClassName; int m_nObjectSize; UINT m_wSchema; // Schema number of the loaded class CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class #ifdef _AFXDLL CRuntimeClass* (PASCAL* m_pfnGetBaseClass)(); #else CRuntimeClass* m_pBaseClass; #endif // Operations CObject* CreateObject(); BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const; // Dynamic name lookup and creation static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName); static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName); static CObject* PASCAL CreateObject(LPCSTR lpszClassName); static CObject* PASCAL CreateObject(LPCWSTR lpszClassName); // Implementation void Store(CArchive& ar) const; static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum // CRuntimeClass objects linked together in simple list CRuntimeClass* m_pNextClass; // Linked list of registered class const AFX_CLASSINIT* m_pClassInit; }; NOTE The real MFC CRuntimeClass structure has additional data members and functions that navigate through the class’s hierarchy This navigation feature is not supported by the official C++ RTTI implementation This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com This structure supports not only class name retrieval but also dynamic creation Each class you derive from CObject has a static CRuntimeClass data member, provided you use the MFC DECLARE_DYNAMIC, DECLARE_DYNCREATE, or DECLARE_SERIAL macro in the declaration and the corresponding IMPLEMENT macro in the implementation file The name of the static data member is, by convention, class If your class were named CMyClass, the CRuntimeClass data member would be named classCMyClass If you want a pointer to a class’s static CRuntimeClass object, you use the MFC RUNTIME_CLASS macro, defined as follows: #define _RUNTIME_CLASS(class_name)\ ((CRuntimeClass*)(&class_name::class##class_name)) #ifdef _AFXDLL #define RUNTIME_CLASS(class_name) (class_name::GetThisClass()) #else #define RUNTIME_CLASS(class_name) _RUNTIME_CLASS(class_name) #endif Here’s how you use the macro to get the name string from a class name: ASSERT(RUNTIME_CLASS(CMyClass)->m_lpszClassName == "CMyClass"); If you want the class name string from an object, you call the virtual CObject::GetRuntimeClass function The function simply returns a pointer to the class’s static CRuntimeClass object, just as earlier the GetClassName function returned the name string Here’s the function for CMyClass: virtual CRuntimeClass* GetRuntimeClass() const { return &classCMyClass; } And here’s how you call it: ASSERT(pMyObject->GetRuntimeClass()->m_lpszClassName == "CMyClass"); This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com Dynamic Creation You’ve learned that the DECLARE and IMPLEMENT macros add a static CRuntimeClass object to a class If you use the DECLARE_DYNCREATE or DECLARE-_SERIAL macro (and the corresponding IMPLEMENT macro), you get an additional static member function CreateObject (which is distinct from CRuntimeClass::CreateObject) in your class Here’s an example: CObject* CMyClass::CreateObject() { return new CMyClass; } Obviously, CMyClass needs a default constructor This constructor is declared protected in wizard-generated classes that support dynamic creation Now look at the (slightly abbreviated) code for the CRuntime-Class::CreateObject function: CObject* CRuntimeClass::CreateObject() { return (*m_pfnCreateObject)(); } This function makes an indirect call to the CreateObject function in the target class Here’s how you dynamically construct an object of class CMyClass: CRuntimeClass* pRTC = RUNTIME_CLASS(CMyObject); CMyClass* pMyObject = (CMyClass*)pRTC->CreateObject(); Now you know how document templates work A document template object has three CRuntimeClass* data members initialized at construction to point to the static CRuntimeClass data members for the document, frame, and view classes When CWinApp::OnFileNew is called, the framework calls the CreateObject functions for the three stored pointers This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com A Sample Program Here’s the code for a command-line program that dynamically constructs objects of two classes This isn’t real MFC code—the CObject class is a simplified version of the MFC library CObject class You can find this code in the dyncreat.cpp file in the \vcppnet\appendb folder on the companion CD // dyncreat.cpp : Defines the entry point for the console application // #include "stdafx.h" #include #define RUNTIME_CLASS(class_name) (&class_name::class##class_name) class CObject; struct CRuntimeClass { char m_lpszClassName[21]; int m_nObjectSize; CObject* (*m_pfnCreateObject)(); CObject* CreateObject(); }; // Not a true abstract class because there are no pure // virtual functions, but user can't create CObject objects // because of the protected constructor class CObject { public: // not pure because derived classes don't necessarily // implement it virtual CRuntimeClass* GetRuntimeClass() const { return NULL; } // We never construct objects of class CObject, but in MFC we // use this to get class hierarchy information static CRuntimeClass classCObject; // DYNAMIC virtual ~CObject() {}; // gotta have it protected: CObject() { printf("CObject constructor\n"); } }; CRuntimeClass CObject::classCObject = { "CObject", sizeof(CObject), NULL }; CObject* CRuntimeClass::CreateObject() { return (*m_pfnCreateObject)(); // indirect function call } This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com } class CAlpha : public CObject { public: virtual CRuntimeClass* GetRuntimeClass() const { return &classCAlpha; } static CRuntimeClass classCAlpha; // DYNAMIC static CObject* CreateObject(); // DYNCREATE protected: CAlpha() { printf("CAlpha constructor\n"); } }; CRuntimeClass CAlpha::classCAlpha = { "CAlpha", sizeof(CAlpha), CAlpha::CreateObject }; CObject* CAlpha::CreateObject() // static function { return new CAlpha; } class CBeta : public CObject { public: virtual CRuntimeClass* GetRuntimeClass() const { return &classCBeta; } static CRuntimeClass classCBeta; // DYNAMIC static CObject* CreateObject(); // DYNCREATE protected: CBeta() { printf("CBeta constructor\n"); } }; CRuntimeClass CBeta::classCBeta = { "CBeta", sizeof(CBeta), CBeta::CreateObject }; CObject* CBeta::CreateObject() // static function { return new CBeta; } int main() { printf("Entering dyncreate main\n"); CRuntimeClass* pRTCAlpha = RUNTIME_CLASS(CAlpha); CObject* pObj1 = pRTCAlpha->CreateObject(); printf("class of pObj1 = %s\n", pObj1->GetRuntimeClass()->m_lpszClassName); CRuntimeClass* pRTCBeta = RUNTIME_CLASS(CBeta); CObject* pObj2 = pRTCBeta->CreateObject(); printf("class of pObj2 = %s\n", pObj2->GetRuntimeClass()->m_lpszClassName); delete pObj1; This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com delete pObj1; delete pObj2; return 0; } This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com About the Author When George Shepherd isn't writing NET components for Syncfusion (http://www.syncfusion.com), he teaches short courses with DevelopMentor (http://www.develop.com) George is a contributing editor for MSDN magazine, and the coauthor of several other books on working with Microsoft technologies George now prefers to play his Hamer Artist between compiles (although NET's new JIT compiling doesn't leave as much time for that) This document is created with a trial version of CHM2PDF Pilot http://www.colorpilot.com ... Figure 1-1 The Visual C++ MFC application build process Visual C++ NET and the Build Process Visual Studio NET is a suite of developer tools that includes Visual C++ NET The Visual Studio NET integrated... you tell Visual C++ NET to open the SLN file, and then you can edit and build the project Visual C++ NET creates some intermediate files too Table 1-1 lists the files that Visual C++ NET generates... this book, you’ll need to have Visual C++ NET or Visual Studio NET installed on your computer Any computer that satisfies the minimum requirements for Visual C++ NET will work effectively with