It does the following:
Creates the necessary keys to register as an ActiveX control.
Adds in the codebase keys so there is no need to pass the /codebase flag to regasm.exe.
Please note, if you're not including oleidl.h as part of your include hierarchy (which I am as I'm using the Windows SDK), then you'll need to define the following constants:
// Ref: http://msdn.microsoft.com/en-us/library/ms678497.aspx const int OLEMISC_RECOMPOSEONRESIZE = 1; const int OLEMISC_CANTLINKINSIDE = 16; const int OLEMISC_INSIDEOUT = 128; const int OLEMISC_ACTIVATEWHENVISIBLE = 256; const int OLEMISC_SETCLIENTSITEFIRST = 131072;Credit is given to the authors of the CSActiveX control upon which this code was originally based.
// // we need to add some extra registry keys on top of the regasm.exe generated // keys. this is because we are an ActiveX control (not just a plain COM control) // and as such require certain keys and values to be present. // // we also add in the codebase entries (instead of passing /codebase to regasm.exe) // this is so we avoid the overkill warnings that regasm.exe generates. // // as such to register this .NET assembly as a fully fledged ActiveX control // we need to run: // // regasm.exe /tlb // void FTEngine::Register( Type^ t ) { try { // Open the CLSID key of the control RegistryKey^ keyCLSID = Registry::ClassesRoot->OpenSubKey( "CLSID\\" + t->GUID.ToString("B"), true ); ////////////////////////////////////////////////////////////////////////// // Set "InprocServer32" to register a 32-bit in-process server. // InprocServer32 = // Ref: http://msdn.microsoft.com/en-us/library/ms683844.aspx // RegistryKey^ subkey = keyCLSID->OpenSubKey( "InprocServer32", true ); if( subkey ) { // .NET runtime engine (mscoree.dll) for .NET assemblies subkey->SetValue( nullptr, Environment::SystemDirectory + "\\mscoree.dll" ); // setup codebase flag as we're not in the GAC subkey->SetValue( "CodeBase", Assembly::GetExecutingAssembly()->CodeBase ); // setup the version specific codebase flag Version^ ver = Assembly::GetExecutingAssembly()->GetName()->Version; subkey = subkey->OpenSubKey( String::Format( "{0}.{1}.{2}.{3}", ver->Major, ver->Minor, ver->Build, ver->Revision ), true ); if( subkey ) { // setup codebase flag as we're not in the GAC subkey->SetValue( "CodeBase", Assembly::GetExecutingAssembly()->CodeBase ); } } ////////////////////////////////////////////////////////////////////////// // Create "Control" to identify it as an ActiveX Control. // Ref: http://msdn.microsoft.com/en-us/library/ms680056.aspx // keyCLSID->CreateSubKey( "Control" ); ////////////////////////////////////////////////////////////////////////// // Create "MiscStatus" to specify how to create/display an object. // MiscStatus = // Ref: http://msdn.microsoft.com/en-us/library/ms683733.aspx // subkey = keyCLSID->CreateSubKey( "MiscStatus" ); int nMiscStatus = OLEMISC_RECOMPOSEONRESIZE + OLEMISC_CANTLINKINSIDE + OLEMISC_INSIDEOUT + OLEMISC_ACTIVATEWHENVISIBLE + OLEMISC_SETCLIENTSITEFIRST; subkey->SetValue( "", nMiscStatus.ToString(), RegistryValueKind::String ); ////////////////////////////////////////////////////////////////////////// // Create "ToolBoxBitmap32" to identify the module name and the resource // ID for a 16 x 16 bitmap as the toolbar button face. // ToolBoxBitmap32 = ., // Ref: http://msdn.microsoft.com/en-us/library/ms687316.aspx // subkey = keyCLSID->CreateSubKey( "ToolBoxBitmap32" ); // If you want different icons for each control in the assembly you // can modify this section to specify a different icon each time. // Each specified icon must be embedded as a win32 resource in the // assembly; the default one is at the index 101, but you can use // additional ones. subkey->SetValue( "", Assembly::GetExecutingAssembly()->Location + ", 101", RegistryValueKind::String ); ////////////////////////////////////////////////////////////////////////// // Create "TypeLib" to specify the typelib GUID associated with the class. // subkey = keyCLSID->CreateSubKey("TypeLib"); Guid libId = Marshal::GetTypeLibGuidForAssembly( t->Assembly ); subkey->SetValue( "", libId.ToString("B"), RegistryValueKind::String ); ////////////////////////////////////////////////////////////////////////// // Create "Version" to specify the version of the control. // Ref: http://msdn.microsoft.com/en-us/library/ms686568.aspx // subkey = keyCLSID->CreateSubKey( "Version" ); int nMajor, nMinor; Marshal::GetTypeLibVersionForAssembly( t->Assembly, nMajor, nMinor); subkey->SetValue( "", String::Format( "{0}.{1}", nMajor, nMinor ) ); } catch( Exception^ ex ) { LogException( ex ); throw; } }
No comments:
Post a Comment