www.pudn.com > COM技术内幕配书源码.rar > CATEGORY.CPP
// // Category.cpp - // Component category demonstration program // // This program is not designed to be compiled for UNICODE. #include#include #include #include ///////////////////////////////////////////////// // // 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 pointers ICatInformation* 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 categories CATEGORYINFO 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 Library OleUninitialize() ; 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)) ; // 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. char szCLSID[40] ; wcstombs(szCLSID, wszCLSID, 40) ; // Open the Registry key. HKEY key = NULL ; long l = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_ALL_ACCESS, &key) ; assert(l == ERROR_SUCCESS) ; // Get the friendly name. char 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) ; }