|
|
//+---------------------------------------------------------------------
//
// File: clsdesc.cxx
//
// Contents: ClassDescriptor implementation
//
//------------------------------------------------------------------------
//[ classdescriptor_overview
/*
ClassDescriptor Overview
A ClassDescriptor is a structure the contains global, static information about an OLE Compound Document class. Having a ClassDescriptor allows the base classes to do a lot of work on behalf of the derived class because it can get information it needs from the ClassDescriptor instead of resorting to virtual method calls. A single ClassDescriptor is shared by all object instances of that Compound Document class.
A ClassDescriptor has three conceptual parts. The first part is a collection of information loaded from resources. This includes strings, menus, accelerators, and an icon. The second part is a pair of verb tables that are used to implement IOleObject::DoVerb. The third part is two pairs of format tables that are used to implement many of the Get/Set/Query methods on IDataObject. Each of these parts has its own initialization method to prepare that part of the class descriptor.
The ClassDescriptor is usually associated with the ClassFactory.
*/ //]
#include "headers.hxx"
#pragma hdrstop
#define MAX_USERTYPE_LEN 64
//+---------------------------------------------------------------
//
// Member: ClassDescriptor::ClassDescriptor
//
// Synopsis: Constructor for ClassDescriptor structure
//
// Notes: A DLL (in-process) server should allocate the class
// descriptor at library initialization time and allocate
// it in shared memory (GMEM_SHARE flag with GlobalAlloc, or
// the OLE shared allocator, MEMCTX_SHARED).
//
// The constructor ensures all members of the structure
// are initialized to NULL
//
//----------------------------------------------------------------
ClassDescriptor::ClassDescriptor(void) { // initialize everything to NULL
// ZeroMemory(this, sizeof(ClassDescriptor));
memset(this, 0, sizeof(ClassDescriptor)); }
//+---------------------------------------------------------------
//
// Member: ClassDescriptor::Init
//
// Synopsis: Initializes a class descriptor structure from resources
//
// Arguments: [hinst] -- instance handle of module with resources used
// to initialize the class descriptor
//
// Returns: TRUE iff the class descriptor was successfully initialized
//
// Notes: This method only fills in the part of the class descriptor
// that can be initialized from resources. The other part
// that requires initialization are the verb and format tables.
//
// Objects that are concerned about resource load times could
// not use this initialization method and fill in fields of the
// class descriptor directly.
//
//----------------------------------------------------------------
BOOL ClassDescriptor::Init(HINSTANCE hinst, WORD wBaseID) { //REVIEW: Currently, information loaded from resources is duplicated
//REVIEW: in the registration database. We could
//REVIEW: (1) load this stuff from the reg db instead (except CLSID), or
//REVIEW: (2) do an autoregistration feature where the reg db is filled
//REVIEW: in from the class descriptor information loaded from resources
//REVIEW: We could also support loading the verb and format tables
//REVIEW: from resources/regdb as well.
_hinst = hinst; _wBaseResID = wBaseID;
// load our class id string and convert it into our real class id
TCHAR szClsId[40]; ZeroMemory (szClsId, sizeof (szClsId));
LoadString(hinst, wBaseID+IDOFF_CLASSID, szClsId, ARRAY_SIZE(szClsId)); #if !defined(UNICODE) && !defined(OLE2ANSI)
LPOLESTR lpostr = ConvertMBToOLESTR(szClsId,-1); BOOL fRet = OK(CLSIDFromString(lpostr, &_clsid)); TaskFreeMem(lpostr); #else
BOOL fRet = OK(CLSIDFromString(szClsId, &_clsid)); #endif
// load our in-place menus and accelerators
_hicon = LoadIcon(hinst, MAKEINTRESOURCE(wBaseID+IDOFF_ICON));
_haccel = (HACCEL)LoadAccelerators(hinst, MAKEINTRESOURCE(wBaseID+IDOFF_ACCELS));
LoadResourceData(hinst, MAKEINTRESOURCE(wBaseID+IDOFF_MGW), &_mgw, sizeof(_mgw)); LoadResourceData(hinst, MAKEINTRESOURCE(wBaseID+IDOFF_MISCSTATUS), &_dwMiscStatus, sizeof(_dwMiscStatus));
#if !defined(UNICODE) && !defined(OLE2ANSI)
CHAR szUserClassType[MAX_USERTYPE_LEN]; #define SetWideClassType(y,x) \
MultiByteToWideChar(CP_ACP \ , 0 \ , (y) \ , -1 \ , _szUserClassType[(x)] \ , ARRAY_SIZE(_szUserClassType[(x)])) LoadString(hinst , wBaseID+IDOFF_USERTYPEFULL , szUserClassType , MAX_USERTYPE_LEN); SetWideClassType(szUserClassType,USERCLASSTYPE_FULL);
LoadString(hinst , wBaseID+IDOFF_USERTYPESHORT , szUserClassType , MAX_USERTYPE_LEN); SetWideClassType(szUserClassType,USERCLASSTYPE_SHORT); LoadString(hinst , wBaseID+IDOFF_USERTYPEAPP , szUserClassType , MAX_USERTYPE_LEN); SetWideClassType(szUserClassType,USERCLASSTYPE_APPNAME); LoadString(hinst , wBaseID+IDOFF_DOCFEXT , szUserClassType , MAX_USERTYPE_LEN);
MultiByteToWideChar(CP_ACP , 0 , szUserClassType , -1 , _szDocfileExt , ARRAY_SIZE(_szDocfileExt)); #else
LoadString(hinst , wBaseID+IDOFF_USERTYPEFULL , _szUserClassType[USERCLASSTYPE_FULL] , ARRAY_SIZE(_szUserClassType[USERCLASSTYPE_FULL])); LoadString(hinst , wBaseID+IDOFF_USERTYPESHORT , _szUserClassType[USERCLASSTYPE_SHORT] , ARRAY_SIZE(_szUserClassType[USERCLASSTYPE_SHORT])); LoadString(hinst , wBaseID+IDOFF_USERTYPEAPP , _szUserClassType[USERCLASSTYPE_APPNAME] , ARRAY_SIZE(_szUserClassType[USERCLASSTYPE_APPNAME])); LoadString(hinst , wBaseID+IDOFF_DOCFEXT , _szDocfileExt , ARRAY_SIZE(_szDocfileExt));
#endif
return fRet; }
//+---------------------------------------------------------------
//
// Member: ClassDescriptor::LoadMenu, public
//
// Synopsis: Loads a copy of the menus for the server
//
// Notes: A single copy of the menu cannot be shared by all
// instances of the class, like an accelerator table can.
// This is because the menu is not a read-only resource
// (e.g. you can "check" a menu item and merge in verb
// menu items). Therefore each class instance must load
// its own copy of the menu. This LoadMenu call is used
// for that purpose.
//
//---------------------------------------------------------------
HMENU ClassDescriptor::LoadMenu(void) { return ::LoadMenu(_hinst, MAKEINTRESOURCE(_wBaseResID+IDOFF_MENU)); }
|