COM technology insider Reading Notes-Chapter 2

Source: Internet
Author: User
Tags ole

The use of hresult values is a little more troublesome than a typical Boolean value. Of course, it also provides some additional information: there are multiple successful codes and multiple failed codes; the failure code may change.

Direct transfer of error code may cause some customers to not recognize the error code. The example has a strong description on the 85 pages of the book, which can be referred.

General rules for custom hrsult: Do not use values in the range of 0x0000 and 0x01ff as the return code, because these values are reserved for the facility_itf defined by com; do not spread the facility_itf error code; use the common com Success and Failure Code as much as possible; avoid defining your own hresult, but use an output function in the function.

The GUID structure is not important. You only need to know that the guid creation function has enough reason to create a unique string value guid, which is related to the time space.

The key-value structure of the Windows registry is easy to understand. Note that the sub-Keyword inprocserver32 of CLSID indicates the full path of the DLL. progid corresponds to CLSID, and uses CLSID to correspond to the name principle of progid and functions obtained in two directions: clsidfromprogid and progidfromclsid.

 

The registration process requires two interface functions: dllregisterserver () and dllunregisterserver (). These two functions mainly deal with the creation and correspondence between the CLSID key and the progid key mentioned above. Of course, it is not difficult to use the registry operation API.

 

Component category implementation: there is only one small segment to describe: the most attractive part of the component category may be that developers do not need to complete registry processing themselves. These tasks can be completed by a component category manager attached to Windows. There are two examples of interface classes in the program code: icatregister and icatinformation. In my personal understanding, you can use these functions to complete registration before you can fully understand the registration process.

Oleview provides users with a more advanced view about the registry information. In the examples of programs that come with vs, I have tracked and debugged the page and sent it for reference.

 

Com library function. I think these so-called initialization functions are very weak descriptions. They tell you to initialize them at the beginning and release them at the end. Why don't you understand the principle? Is it because of the memory to be allocated? Or load some system resources? I didn't say it in the book. Of course, I think this section is nonsense.

 

Add component category implementation code (details of the original book code version that need to be modified in the new development environment are currently compiled on vs2008)

//// Category.cpp -//   Component category demonstration program//// This program is not designed to be compiled for UNICODE.#include <stdlib.h>#include <iostream>#include <assert.h>#include <tchar.h>#include <comcat.h>using namespace std;///////////////////////////////////////////////////// Function declarations//// Worker functions// List the registered component categories.BOOL ListCategories() ;// Register our sample component category.BOOL RegisterCategory() ;// Unregister our sample component category.void UnregisterCategory() ;// Add component to our sample component category.void AddComponent() ;// Remove component from our sample component category.void RemoveComponent() ;// List all of the components which are members of our sample category.void ListCategoryMembers() ;// Helper functions// Print out the COM/OLE error string for an HRESULT.void ErrorMessage(const char* str, HRESULT hr) ;// Get friendly name for a CLSID from the Registry and display.void OutputFriendlyName(const CLSID& clsid) ;///////////////////////////////////////////////////// Global Data and constants//// Global interface pointersICatInformation*  g_pICatInformation = NULL ;ICatRegister*     g_pICatRegister = NULL ;// Array of category IDs// {f2484d60-e8d0-11cf-a6bb-0080c7b2d682}static GUID CATID_SampleCategories[1] = {0xf2484d60, 0xe8d0, 0x11cf,{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;// Category Information structure used to register categoriesCATEGORYINFO g_SampleCategoryInfo ={    {0xf2484d60, 0xe8d0, 0x11cf,{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}},  // CATID catid ;LOCALE_SYSTEM_DEFAULT,                       // LCID lcid ;L"This is the sample category"               // OLECHAR szDescription[128] ;} ;// Component to add to the sample category defined above// {0c092c20-882c-11cf-a6bb-0080c7b2d682}extern "C" const CLSID CLSID_Component1 ={0x0c092c20, 0x882c, 0x11cf,{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;///////////////////////////////////////////////////// main //int main(){// Initialize COM Library.OleInitialize(NULL) ;// Create the standard COM Category manager.HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr,NULL, CLSCTX_ALL,IID_ICatInformation, (void**)&g_pICatInformation) ;if (FAILED(hr)){ErrorMessage("main: Could not create component category manager.", hr) ;goto Uninitialize ;}// List the categories.if (!ListCategories()){goto Release ;}// Get the Category Registration interface.hr = g_pICatInformation->QueryInterface(IID_ICatRegister,(void**)&g_pICatRegister) ;if (FAILED(hr)){ErrorMessage("Attempt to query for ICatRegister failed.", hr) ;goto Release ;}//// Register our sample component category.//cout << "--------Register---------------" << endl ;if (!RegisterCategory()){goto Release ;}// List the categories again to show the newly registered category.ListCategories() ;// Add component to our sample category.cout << "--------Add Component----------" << endl ;AddComponent() ;// List all components implementing our sample category.cout << "--------List Category----------" << endl ;ListCategoryMembers();// Remove class from our sample category.cout << "--------Remove Component-------" << endl ;RemoveComponent();// List all components implementing our sample category. // Should be empty.cout << "--------List Category----------" << endl ;ListCategoryMembers() ;// Unregister our sample component category.cout << "--------Unregister-------------" << endl ;UnregisterCategory() ;// List the categories to show that the component category// has been removed.ListCategories() ;Release:// Release the interface pointers.if (g_pICatInformation != NULL){g_pICatInformation->Release() ;}if (g_pICatRegister != NULL){g_pICatRegister->Release() ;}Uninitialize:// Unintialize COM LibraryOleUninitialize() ;return 0 ;}///////////////////////////////////////////////////// Worker functions////// List the registered component categories.//BOOL ListCategories(){BOOL bReturn = TRUE ;// Get an enumerator for the categories.IEnumCATEGORYINFO* pIEnumCATEGORYINFO = NULL ; HRESULT hr = g_pICatInformation->EnumCategories(::GetUserDefaultLCID(),&pIEnumCATEGORYINFO) ;if (FAILED(hr)){ErrorMessage("ListCategories: ICatInformation::EnumCategories failed.", hr) ;return FALSE ;}// Prepare for loop.char szDescription[128] ;CATEGORYINFO CategoryInfo ;// Enumerate the categories.while ((hr = pIEnumCATEGORYINFO->Next(1, &CategoryInfo, NULL)) == S_OK){// Convert from wchar_t to char.::wcstombs(szDescription, CategoryInfo.szDescription,sizeof(szDescription)) ;//_tcscpy(szDescription,CategoryInfo.szDescription);// Print out description.cout << szDescription << "\r\n" ;} // Did Next fail or finish?if (FAILED(hr)){ErrorMessage("ListCategories: IEnumCATEGORYINFO::Next failed.", hr) ;bReturn = FALSE ;}// Release Interfaces.if (pIEnumCATEGORYINFO != NULL){pIEnumCATEGORYINFO->Release() ;}return bReturn ;}//// Register the component category.//BOOL RegisterCategory(){HRESULT hr = g_pICatRegister->RegisterCategories(1, &g_SampleCategoryInfo) ;if (FAILED(hr)){ErrorMessage("RegisterCategory: Registering the component category failed.",hr) ;return FALSE ;}return TRUE ;}//// Unregister the component category.//void UnregisterCategory(){HRESULT hr = g_pICatRegister->UnRegisterCategories(1, CATID_SampleCategories) ; if (FAILED(hr)){ErrorMessage("UnregisterCategory: Unregistering component category failed.",hr) ;}}//// Add component to component category.//void AddComponent(){HRESULT hr = g_pICatRegister->RegisterClassImplCategories(CLSID_Component1,1, CATID_SampleCategories) ; if (FAILED(hr)){ErrorMessage("AddComponent: Adding component to category failed.", hr) ;}}//// Remove component from component category.//void RemoveComponent(){HRESULT hr = g_pICatRegister->UnRegisterClassImplCategories(CLSID_Component1,1, CATID_SampleCategories) ; if (FAILED(hr)){ErrorMessage("RemoveComponent: Removing component to category failed.",hr) ;}}//// List all of the components which are members of a particular category.//void ListCategoryMembers(){// Get an enumerator for the categories.IEnumCLSID* pIEnumCLSID = NULL; HRESULT hr = g_pICatInformation->EnumClassesOfCategories(1,CATID_SampleCategories,0,NULL,&pIEnumCLSID) ;if (FAILED(hr)){ErrorMessage("ListCategoryMembers: EnumClassesOfCategories  failed.", hr) ;}// Prepare for loop.char szDescription[128] ;CLSID clsid ;// Enumerate the categories.while (TRUE){// Get the next category.hr = pIEnumCLSID->Next(1, &clsid, NULL) ;if (hr != S_OK){// Did Next fail or finish?if (FAILED(hr)){ErrorMessage("ListCategoryMembers: IEnumCLSID::Next failed.",hr) ;}break ;}// Print the friendly name.OutputFriendlyName(clsid) ;} // Release interfaces.if (pIEnumCLSID != NULL){pIEnumCLSID->Release() ;}}///////////////////////////////////////////////////// Helper function declarations////// Print out the COM/OLE error string for an HRESULT.//void ErrorMessage(const char* str, HRESULT hr){void* pMsgBuf ;::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,hr,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language(LPTSTR) &pMsgBuf,0,NULL ) ;// Display the string.cout << str << "\r\n" ;cout << "Error (" << hex << hr << "):  " << (char*)pMsgBuf << endl ;// Free the buffer.LocalFree( pMsgBuf ) ;}//// Get friendly name for a CLSID from the Registry and display.//void OutputFriendlyName(const CLSID& clsid){// Convert clsid to a string.wchar_t wszCLSID[80] ;int r = ::StringFromGUID2(clsid, wszCLSID, 80) ;assert(r != 0) ;// Convert to single byte char.TCHAR szCLSID[40] ;//wcstombs(szCLSID, wszCLSID, 40) ;_tcscpy(szCLSID,wszCLSID);// Open the Registry key.HKEY key = NULL ;long l = ::RegOpenKeyEx(HKEY_CLASSES_ROOT,_T("CLSID"),0,KEY_ALL_ACCESS,&key) ;assert(l == ERROR_SUCCESS) ;// Get the friendly name.TCHAR szFriendly[256] ;long size = sizeof(szFriendly) ;l = ::RegQueryValue(key,szCLSID,szFriendly,&size) ;assert(l == ERROR_SUCCESS) ;// Output the friendly name.cout << szFriendly << endl ;// Clean up.::RegCloseKey(key) ;}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.