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 https://www.dilascia.com.