Click to Rate and Give Feedback
Related Articles

Learn how you can set up every mobile device in your company with a few lines of code and some XML--thanks to the provisioning APIs in the Windows Mobile SDK.

Mike Calligaro

MSDN Magazine April 2008

...

Read more!

This month begins the design of the actual mouse class for EEK!

Stanley B. Lippman

MSDN Magazine December 2007

...

Read more!

The new Task Scheduler in Windows Vista can do so much more than previous versions. We introduce some basic concepts and building blocks you can put to use in your own scheduled task projects.

Kenny Kerr

MSDN Magazine October 2007

...

Read more!

In this article, author John Torjo presents a guide to his C++ GUI library called eGUI++ and explains how it makes user interface programming easier.

John Torjo

MSDN Magazine June 2008

...

Read more!

Understanding the ACLs that govern permissions and rights before an operation is allowed to proceed is critical to enhancing security.

John R. Michener

MSDN Magazine November 2008

...

Read more!

Also by this Author

Paul DiLascia

MSDN Magazine April 2006

...

Read more!

This month Paul DiLascia codes some Microsoft Office-style dialog box features.

Paul DiLascia

MSDN Magazine August 2006

...

Read more!

Last month I answered a question about implementing native events in C++ (see C++ At Work: Event Programming). I discussed events in general and showed how to use an interface to define event handlers for your class that clients must implement to handle events.

Paul DiLascia

MSDN Magazine March 2006

...

Read more!

Many of you are no doubt in the process of upgrading to Visual Studio® 2005, so I thought now would be a good time to relate some of my own experiences with the new compiler. What took me so long? Hey, I'm a retro kind of guy! Better late than never!.

Paul DiLascia

MSDN Magazine June 2006

...

Read more!

Paul DiLascia

MSDN Magazine June 2005

...

Read more!

Popular Articles

When incorporating the ASP.NET DataGrid control into your Web apps, common operations such as paging, sorting, editing, and deleting data require more effort than you might like to expend. But all that is about to change. The GridView control--the successor to the DataGrid-- extends the DataGrid's functionality it in a number of ways. First, it fully supports data source components and can automatically handle data operations, such as paging, sorting, and editing, as long as its bound data source object supports these capabilities. In addition, ...

Read more!

James Avery does it again with his popular list of developer tools. This time he covers the best Visual Studio add-ins available today that you can download for free.

James Avery

MSDN Magazine December 2005

...

Read more!

Here we present techniques for programmatic and declarative data binding and display with Windows Presentation Foundation.

Josh Smith

MSDN Magazine July 2008

...

Read more!

Jeff Prosise explains when it's better to use UpdatePanel and when it's better to use asynchronous calls to WebMethods or page methods instead.

Jeff Prosise

MSDN Magazine June 2007

...

Read more!

One-time passwords offer solutions to dictionary attacks, phishing, interception, and lots of other security breaches. Here's how it all works.

Dan Griffin

MSDN Magazine May 2008

...

Read more!

From the February 2002 issue of MSDN Magazine
MSDN Magazine
Getting a Class Name, ImgView Revisited, GetModuleFileName, and More
Paul DiLascia
Q I have two classes, Derived1 and Derived2, that are derived from a base class. In the constructor of the base class, I would like to get the name of the class for which this object is being created—that is, Derived1 or Derived2. Is it possible to get the name of the class as a string?
Nilesh Padbidri

A The short answer is: no. A base class doesn't know anything about what class it's derived from—and it's a good thing, too. You might think you could solve the problem by inventing a virtual function GetClassName
class Derived1 : public Base {
  virtual string GetClassName() {
    return "Derived1"; // or Derived2
  }
};
and call GetClassName from the Base constructor. But this won't work because in the constructor Base::Base, the vtable for Derived1 isn't established yet. That is, the object doesn't officially become an instance of Derived1 until the constructor Derived1::Derived1 begins. In pseudocode, the Derived1 constructor looks something like this:
Derived1::Derived1(...)
{
  // compiler-generated:
  Base::Base(...);      // call base ctor
  vtbl = Derived1_vtbl; // set up vtbl pointer
•••  
  // rest of your ctor
}
      When the Base class constructor runs, the vtbl is still the vtbl for the Base class. This issue comes up repeatedly in different ways and situations. Why does C++ do it this way? Because it isn't logical to let you call a Derived1 function—virtual or otherwise—until the Derived1 constructor has initialized the object. The object doesn't become a derived object until the derived constructor runs.
      So, what can you do? If you want the class name in the Base constructor, the only way to get it is to pass it as an argument.
class Base {
  Base(string sClassName,...);
  •••
 };
Derived1::Derived1(...) : Base("Derived1", ...) 
{
  •••
};
      In MFC, this sort of thing is handled a little more complicatedly (hey, am I allowed to coin a word here?) using CRuntimeClass. CRuntimeClass represents—what else?—a runtime class. For every class you or MFC declares with DECLARE_DYNAMIC, DECLARE_DYNCREATE or DECLARE_SERIAL, you get a static CRuntimeClass instance to represent the class. In fact, pretty much the only purpose of DECLARE/IMPLEMENT_DYNAMIC is to set this up.
class CDerived : public CBase {
  // DECLARE_DYNAMIC(CDerived) expands to:
protected:
  static CRuntimeClass* _GetBaseClass();
public: 
  static CRuntimeClass classCDerived;
  virtual CRuntimeClass* GetRuntimeClass() const;
}
      DECLARE_DYNAMIC declares three things: a static function to get the base class runtime class (CRuntimeClass for CBase), a static CRuntimeClass instance called classCDerived—the name of this object is the word "class" followed by the class name—and a virtual function, GetRuntimeClass, that returns a pointer to it. IMPLEMENT_DYNAMIC implements all this.
// IMPLEMENT_DYNAMIC(CDerived,CBase)
// expands to:
CRuntimeClass* CDerived::_GetBaseClass() { 
  return RUNTIME_CLASS(CBaseClass); 
}
const CRuntimeClass CDerived::classCDerived = {
  "CDerived", sizeof(class CDerived), ... 
};
CRuntimeClass* CDerived::GetRuntimeClass() const { 
  return RUNTIME_CLASS(CDerived); 
}
      RUNTIME_CLASS is yet another macro. It expands to &CWhatever::classCWhatever. So, for example, there's a classCWnd, classCDialog, classCListCtrl, and so on—the CRuntimeClass objects for these classes. There's exactly one CRuntimeClass for every MFC class (those that use DECLARE/IMPLEMENT_XXX). The CRuntimeClass holds the name of the class, its size, schema number (for serialization), and other meta class stuff. The way to get the CRuntimeClass for a given class is to hardcode RUNTIME_CLASS(CSomeClass), in which case you have to know the class name at compile time, or you can call the virtual GetRuntimeClass. But even that won't get you the runtime class for the derived class from within the base constructor, because, like I said earlier, the vtbl is still the base vtbl and GetRuntimeClass calls Base::GetRuntimeClass (see Figure 1).
      Once you have a pointer to the CRuntimeClass, you can get the class name from CRuntimeClass::m_lpszClassName. CRuntimeClass is a struct, not a class, so all its members are public.

Q I'm a newcomer to MFC and am working on a project to display photos. I've read through the code project ImgView from your October 2001 column and I find it is excellent and perfect as a foundation for my project. However, I couldn't find the class CArchiveStream or the file Afxpriv2.h on the MSDN® Web site. Would you please tell me the purpose and definition of the CArchiveStream?
Sam Ng

A Well, first of all I'm happy my code was "excellent and perfect" for your project—I guess that means there were no bugs and therefore I wrote it. (Hey, how much did we pay this guy?) As for afxpriv2.h, MFC has a number of private definitions and classes declared in afxpriv.h. afxpriv2.h is a secondary file included by afxpriv.h, so there's no need to include it directly. The classes in these files are neither documented nor officially supported; however, they're unlikely to change any time soon, so many programmers use them anyway. Just be advised that the Redmondtonians are free to change this stuff in future releases of MFC, if ever there are any. All of which is merely a longwinded way to say: go ahead and use whatever goodies you find in afxpriv.h, including CArchiveStream.
      And now to your question: what exactly does CArchiveStream do? Answer: it implements an IStream interface based on CArchive. In other words, suppose you want to use some COM interface that requires IStream, but you either don't have a clue what IStream is and/or you weep at the prospect of implementing QueryInterface, AddRef, Release, Read, Write, and nine other functions even if all they do is return E_NOT_IMPLEMENTED. Well, there's no need to weep; CArchiveStream will save your day. It provides the IStream you need, using your CArchive to supply the underlying data stream.
CArchive ar; // your archive
CArchiveStream arstm(ar);
HRESULT hr = 
  SomeCOMFunctionThatNeedsAStream(&arstm);
Pretty easy, eh? In most cases you don't have a CArchive, but a CFile. No problem, it's easy to create an archive from a file.
CFile file; // your file
CArchive ar(&file); // now it's a CArchive
Would that COM be always so easy.

Q I'm trying to find the FileVersion from the VersionInfo re-source of a bunch of DLLs that I'm putting together for an SDK. I don't want to hardcode the DLL file name into the call for ::GetModuleHandle since I want to reuse the common routine for all the DLLs I have. Is there a way to get the name of the current DLL where an exported function lives, from code in the exported function? Or can I get the instance handle of the DLL?
Vince Paragano

A GetModuleFileName is the function you want; it gets the name of a module—DLL or EXE. GetModuleFileName takes an HINSTANCE and a buffer in which to put the name. You can call GetModuleFileName with a NULL instance handle, but then it returns the name of the running process (EXE), not the DLL. To get the name of the DLL, you need its instance handle.
      If you're using MFC, you can get the instance handle from AfxGetApp()->m_hInstance. AfxGetApp returns a pointer to the current global application object (DLL object in the case of a DLL); m_hInstance is the instance handle.
char buf[MAXLEN];
::GetModuleFileName(AfxGetApp()->m_hInstance, buf, sizeof(buf);
      If you're not using MFC, you'll have to save the HINSTANCE yourself somewhere as a global, in DllMain, when your DLL first starts up.
// module instance handle—global variable
HINSTANCE h_hInstance;
BOOL DllMain(HINSTANCE hinst, DWORD dwReason, ...)
{
  if (dwReason == DLL_PROCESS_ATTACH) {
    g_hInstance = hinst; // save it
    •••
  } else if (dwReason == DLL_PROCESS_DETACH) {
    g_hInstance = NULL; // good idea
    •••
  }
}
Q I am using a class that contains a static member variable. Objects of this class are used in a multithreaded program. Would all the objects in this multithreaded program access the same static variable, or does each thread have its own copy?
Amit Wamburkar

A A static class member variable is just like a C static global. There's just one instance, in the module where it's defined.
class CSomeClass {
public:
  static long g_nObjects;
};
// the one-and-only
long CSomeClass::g_nObjects = 0;
      This is why in order to write thread-safe code, you have to protect static members with a lock or use thread-safe functions like InterlockedIncrement and InterlockedDecrement.
CSomeClass::CSomeClass()
{
  // increment object count
  InterlockedIncrement(&g_nObjects);
  •••
}
      If you want each thread to have its own copy of a variable, you can put the variable in an object that you pass as the startup parameter (LPVOID) when you call your favorite begin-thread function: AfxBeginThread, _beginthread, CreateThread, or whatever. You can then either pass the state object back and forth in all your thread functions, or, if that's too cumbersome, define a thread-local variable.
__declspec(thread) CThreadState foo;
      Now there's one foo variable per thread. The Microsoft compiler-specific "thread" attribute makes it easy to define thread-local storage using declspec, instead of allocating the storage through the thread local storage (TLS) API functions TlsAlloc, TlsFree, and so on. For more info about TLS, search the docs for "thread local storage" or TLS.

Q In your June 2000 column where you describe loading an AVI resource, this sequence loads a BYTE string resource:
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc); ASSERT(lpRsrc);
Is it necessary to delete lpRsrc once you're finished with it? The Microsoft documentation for LoadResource is vague: "The system automatically deletes these resources when the process that loaded them terminates, however, calling the appropriate function saves memory and decreases the size of the process's working set." I have not been able to successfully delete lpRsrc using any of the Delete or Destroy functions.
Teya Nikov

A There's never any need to free resources loaded with Load-Resource because LoadResource doesn't actually load anything. All LoadResource does is return a pointer to your resource in process address space, in the already loaded EXE or DLL. Nothing is allocated from the heap or anywhere else. If your program doesn't access the resource, its memory can be swapped out as per the normal Windows swapping algorithms. If your program accesses it again, it'll be swapped in again.
      The documentation is definitely cryptic. It says that in the case of accelerators, bitmaps, cursors, icons, or menus, you can use the appropriate Destroy/Delete function to destroy the object:
DestroyAcceleratorTable
DeleteObject // for a bitmap
DestroyCursor
DestroyIcon
DestroyMenu
But elsewhere the documentation says:
It is only necessary to call DestroyIcon for icons and cursors created with the CreateIconIndirect and the CopyIcon functions. Do not use this function to destroy a shared icon. A shared icon is valid as long as the module from which it was loaded remains in memory. The following functions obtain a shared icon: LoadIcon, LoadImage (if you use the LR_SHARED flag), and CopyImage (if you use the LR_COPYRETURNORG flag and the hImage parameter is a shared icon).
For DestroyAccelerator table, the documentation says you can call this function whether the accelerator table was created with CreateAcceleratorTable or LoadAccelerators.
      What should you make of all this mystification? The simple answer is that if the resource comes from your executable file (EXE or DLL), you don't need to free it. If you call some function to create the resource, you do—and you should use one of the Destroy/Delete functions just mentioned. Got it?

Send questions and comments for Paul to cppqa@microsoft.com.
Paul DiLascia is a freelance writer, consultant, and Web/UI designer-at-large. He is the author of Windows++: Writing Reusable Windows Code in C++(Addison-Wesley, 1992). Paul can be reached at askpd@pobox.com or http://www.dilascia.com.

Page view tracker