Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

214 lines
7.7 KiB

//+---------------------------------------------------------------------
//
// 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));
}