home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / Atl / atlvcl.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-01  |  15.5 KB  |  464 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // ATLVCL.CPP - Provides the connective tissue between
  3. //              the ATL framework and VCL components.
  4. //
  5. // $Revision:   1.29.2.6  $
  6. //
  7. // Copyright (c) 1997, 2000 Borland International
  8. ///////////////////////////////////////////////////////////////////////////////
  9. #include <vcl.h>
  10. #pragma hdrstop
  11.  
  12. #if !defined(__ATLVCL_H_)
  13. #include <atl\atlvcl.h>
  14. #endif
  15. #include <comconst.hpp>
  16. #include <axctrls.hpp>
  17. #include <tchar.h>
  18.  
  19. namespace TInternalRegistrationHelpers {
  20. // Contains functions needed internally to this module for the purpose
  21. // of manipulating data into more pleasant forms and/or talking to the
  22. // Registry. These functions are not available externally.
  23.  
  24. HRESULT CreateRegKey(const TCHAR* Key, const TCHAR* ValueName, const TCHAR* Value)
  25. {
  26.    HKEY tempKey;
  27.    HRESULT Status = RegCreateKeyEx(HKEY_CLASSES_ROOT, Key, 0, _T(""),
  28.                     REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, 0, &tempKey, 0);
  29.    if SUCCEEDED(Status)
  30.    {
  31.      Status = RegSetValueEx(tempKey, ValueName, 0, REG_SZ, (BYTE*)Value,
  32.                             _tcslen(Value) + 1);
  33.      RegCloseKey(tempKey);
  34.    }
  35.    return Status;
  36. }
  37.  
  38. HRESULT DeleteRegValue(TCHAR* Key, TCHAR* ValueName)
  39. {
  40.   HKEY tempKey;
  41.   HRESULT Status = RegOpenKey(HKEY_CLASSES_ROOT, Key, &tempKey);
  42.   if SUCCEEDED(Status)
  43.   {
  44.     Status = RegDeleteValue(tempKey, ValueName);
  45.     RegCloseKey(tempKey);
  46.   }
  47.   return Status;
  48. }
  49.  
  50. /* must be freed by caller. */
  51. TCHAR* CreateKeyOfClass(TCHAR* CLSID)
  52. {
  53.    TCHAR* retval = new TCHAR[_tcslen(CLSID)+_tcslen(_T("CLSID\\"))+1]; // length of "CLSID\"+ null terminator
  54.    _tcscpy(retval, _T("CLSID\\"));
  55.    _tcscat(retval, CLSID);
  56.    return retval;
  57. }
  58.  
  59. /* must be freed by caller */
  60. TCHAR* CreateAppIDOfClass(TCHAR* CLSID)
  61. {
  62.    TCHAR* retval = new TCHAR[_tcslen(CLSID)+_tcslen(_T("AppID\\"))+1]; // length of "AppID\" + null terminator
  63.    _tcscpy(retval, _T("AppID\\"));
  64.    _tcscat(retval, CLSID);
  65.    return retval;
  66. }
  67.  
  68. /* must be freed by caller */
  69. TCHAR* CreateImplementedCategoriesOfClass(TCHAR* CLSID)
  70. {
  71.  TCHAR* retval = new TCHAR[_tcslen(_T("CLSID\\"))+_tcslen(CLSID)+_tcslen(_T("\\Implemented Categories\\"))+1];
  72.   _tcscpy(retval, _T("CLSID\\"));
  73.   _tcscat(retval, CLSID);
  74.   _tcscat(retval, _T("\\Implemented Categories\\"));
  75.   return retval;
  76. }
  77.  
  78. /* must be freed by caller */
  79. TCHAR* CreateImplementedMIDASOfClass(TCHAR* CLSID)
  80. {
  81.   TCHAR* retval = new TCHAR[_tcslen(CLSID)+_tcslen(_T("CLSID\\"))+
  82.                             _tcslen(_T("\\Implemented Categories\\"))+
  83.                             _tcslen(_T("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}\\"))+1];
  84.   _tcscpy(retval, _T("CLSID\\"));
  85.   _tcscat(retval, CLSID);
  86.   _tcscat(retval, _T("\\Implemented Categories\\"));
  87.   _tcscat(retval, _T("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}\\"));
  88.   return retval;
  89. }
  90.  
  91. /* must be freed by caller. Since the caller won't have a clue how
  92.    to free it if it's not of type REG_SZ, free it manually and return
  93.    an error in that case. */
  94. char* GetRegStringValue(const TCHAR* Key, const TCHAR* ValueName)
  95. {
  96.    char* retval = new char[256];
  97.    DWORD Length = 256*sizeof(char);
  98.    HKEY tempKey;
  99.    DWORD TypeCode;
  100.    HRESULT hr = RegOpenKey(HKEY_CLASSES_ROOT, Key, &tempKey);
  101.    if SUCCEEDED(hr)
  102.    {
  103.       hr = RegQueryValueEx(tempKey, ValueName, 0, &TypeCode, (Byte*)retval, &Length);
  104.    }
  105.    if (TypeCode != REG_SZ)
  106.    {
  107.       delete[] retval;
  108.       retval = NULL;
  109.    }
  110.    return retval;
  111. }
  112.  
  113. }   // END namespace
  114. //-----------------------------------------------------------------------------//
  115.  
  116. // Externs
  117. // Pointer to save Initialization Procedure when using VCL
  118. // (CBuilder3 backward compatibility)
  119. //
  120. void* SaveInitProc = 0;
  121.  
  122. // Helper used by IPersistStreamInit implementation to save component
  123. //
  124. void __fastcall SaveVCLComponentToStream(TComponent *vclInstance, LPSTREAM pStrm)
  125. {
  126.   TPtr<TStream> pStream = new TOleStream(_di_IStream(pStrm));
  127.   TPtr<TWriter> pWriter = new TWriter(pStream, 4096);
  128.   pWriter->IgnoreChildren = true;
  129.   pWriter->WriteDescendent(vclInstance, 0);
  130. }
  131.  
  132.  
  133. // Helper used by IPersistStreamInit implementation to load component
  134. //
  135. void __fastcall LoadVCLComponentFromStream(TComponent *vclInstance, LPSTREAM pStrm)
  136. {
  137.   TPtr<TStream> pStream = new TOleStream(_di_IStream(pStrm));
  138.   TPtr<TReader> pReader = new TReader(pStream, 4096);
  139.   pReader->ReadRootComponent(vclInstance);
  140. }
  141.  
  142.  
  143. // Helper used by framework to create a reflector object
  144. //
  145. TWinControl* CreateReflectorWindow(HWND parent, Controls::TControl* Control)
  146. {
  147.   return new TReflectorWindow(parent, Control);
  148. }
  149.  
  150. //----------------------------------------------------------------------------//
  151.  
  152. // Register (or unregisters) Remote data module
  153. //
  154. HRESULT TRemoteDataModuleRegistrar::UpdateRegistry(bool bRegister)
  155. {
  156.    HRESULT hr = TTypedComServerRegistrar::UpdateRegistry(bRegister);
  157. #if!defined UNICODE && !defined(_UNICODE)
  158.    LPCSTR pClassID = m_ClassIDstr;
  159.    LPCSTR pProgID  = m_ProgID;
  160. #else
  161.    TAPtr<CHAR> pClassID = WideToAnsi(m_ClassIDstr);
  162.    TAPtr<CHAR> pProgID  = WideToAnsi(m_ProgID);
  163. #endif
  164.    if (bRegister ) hr = doRegister();
  165.    else hr=doUnRegister();
  166.  
  167.    return hr;
  168. }
  169.  
  170. /* Unregister the keys added if the data module supported pooling. */
  171. HRESULT TRemoteDataModuleRegistrar::doUnRegisterPooled()
  172. {
  173.   TCHAR* pClassID = m_ClassIDstr;
  174.   TCHAR* tempKey = TInternalRegistrationHelpers::CreateKeyOfClass(pClassID);
  175.   try
  176.   {
  177.     OLECHECK(TInternalRegistrationHelpers::DeleteRegValue(tempKey, _T("Pooled")));
  178.     OLECHECK(TInternalRegistrationHelpers::DeleteRegValue(tempKey, _T("MaxObjects")));
  179.     OLECHECK(TInternalRegistrationHelpers::DeleteRegValue(tempKey, _T("Timeout")));
  180.     OLECHECK(TInternalRegistrationHelpers::DeleteRegValue(tempKey, _T("Singleton")));
  181.     delete[] tempKey;
  182.   }
  183.   catch (...)
  184.   {
  185.     if (tempKey) delete[] tempKey;
  186.     return E_FAIL;
  187.   }
  188.   return S_OK;
  189. }
  190.  
  191. /* Register the data module to support pooling */
  192. HRESULT TRemoteDataModuleRegistrar::doRegisterPooled()
  193. {
  194.   TCHAR* pClassID = m_ClassIDstr;
  195.   TCHAR* tempKey = TInternalRegistrationHelpers::CreateKeyOfClass(pClassID);
  196.   char* tempNumber = 0;
  197.  try
  198.   {
  199.     OLECHECK(TInternalRegistrationHelpers::CreateRegKey(tempKey, _T("Pooled"), _T("1")));
  200.     tempNumber = new char[33];
  201.     itoa(MaxObjects, tempNumber, 10);
  202. #if !defined(UNICODE) && !defined(_UNICODE)
  203.     OLECHECK(TInternalRegistrationHelpers::CreateRegKey(tempKey, "MaxObjects", tempNumber));
  204. #else
  205.     OLECHECK(TInternalRegistrationHelpers::CreateRegKey(tempKey, TStringConverter<char>::AnsiToWide("MaxObjects"),
  206.                                                         TStringConverter<char>::AnsiToWide(tempNumber)));
  207. #endif
  208.     memset(tempNumber, '\0', 33);
  209.     itoa(Timeout, tempNumber, 10);
  210. #if !defined(UNICODE) && !defined(_UNICODE)
  211.     OLECHECK(TInternalRegistrationHelpers::CreateRegKey(tempKey, "Timeout", tempNumber));
  212. #else
  213.     OLECHECK(TInternalRegistrationHelpers::CreateRegKey(tempKey, TStringConverter<char>::AnsiToWide("Timeout"),
  214.                                                         TStringConverter<char>::AnsiToWide(tempNumber)));
  215. #endif
  216.     if (Singleton) OLECHECK(TInternalRegistrationHelpers::CreateRegKey(tempKey, _T("Singleton"), _T("1")));
  217.     else OLECHECK(TInternalRegistrationHelpers::CreateRegKey(tempKey, _T("Singleton"), _T("0")));
  218.     delete[] tempKey;
  219.     delete[] tempNumber;
  220.   }
  221.   catch (...)
  222.   {
  223.     if (tempKey) delete[] tempKey;
  224.     if (tempNumber) delete[] tempNumber;
  225.     return E_FAIL;
  226.   }
  227.   return S_OK;
  228. }
  229.  
  230. HRESULT TRemoteDataModuleRegistrar::doUnRegister()
  231. {
  232.   TCHAR* pClassID = m_ClassIDstr;
  233.   ICatRegister* CatReg = 0;
  234.   TCHAR* RegKeyTemp = 0;
  235.   CLSID MIDASTemp;
  236.   GUID RemovalTemp;
  237.  
  238.   // Get a component category manager. */
  239.   HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoryMgr, 0,
  240.                                 CLSCTX_INPROC_SERVER, IID_ICatRegister,
  241.                                 (void**)&CatReg);
  242.  
  243.   try {
  244.     if SUCCEEDED(hr)
  245.     {
  246. #if !defined(UNICODE) && !defined(_UNICODE)
  247.       MIDASTemp = TStringConverter<char>::AnsiToGUID("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}");
  248.       RemovalTemp = TStringConverter<char>::AnsiToGUID(pClassID);
  249. #else
  250.       MIDASTemp = TStringConverter<char>::WideToGUID(_T("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}"));
  251.       RemovalTemp = TStringConverter<char>::WideToGUID(pClassID);
  252. #endif
  253.       hr  = CatReg->UnRegisterClassImplCategories(MIDASTemp, 1, &RemovalTemp);
  254.  
  255.       RegKeyTemp = TInternalRegistrationHelpers::CreateImplementedCategoriesOfClass(pClassID);
  256.       RegDeleteKey(HKEY_CLASSES_ROOT, RegKeyTemp);
  257.       delete[] RegKeyTemp;
  258.     }
  259.     else
  260.     {
  261.       RegKeyTemp = TInternalRegistrationHelpers::CreateImplementedMIDASOfClass(pClassID);
  262.       RegDeleteKey(HKEY_CLASSES_ROOT, RegKeyTemp);
  263.       delete[] RegKeyTemp;
  264.     }
  265.     RegKeyTemp = TInternalRegistrationHelpers::CreateAppIDOfClass(pClassID);
  266.     RegDeleteKey(HKEY_CLASSES_ROOT, RegKeyTemp);
  267.     delete[] RegKeyTemp;
  268.     if (EnableSocket)
  269.     {
  270.       RegKeyTemp = TInternalRegistrationHelpers::CreateKeyOfClass(pClassID);
  271.       TInternalRegistrationHelpers::DeleteRegValue(RegKeyTemp, _T("Sockets"));
  272.       delete[] RegKeyTemp;
  273.     }
  274.     if (EnableWeb)
  275.     {
  276.       RegKeyTemp = TInternalRegistrationHelpers::CreateKeyOfClass(pClassID);
  277.       TInternalRegistrationHelpers::DeleteRegValue(RegKeyTemp, _T("Web"));
  278.       delete[] RegKeyTemp;
  279.     }
  280.   }
  281.   catch (...) {
  282.     // OLECHECK throws on failure
  283.     if (CatReg)  CatReg->Release();
  284.     if (RegKeyTemp)  delete[] RegKeyTemp;
  285.     return E_FAIL;
  286.   }
  287.   if (RegisterPooled)
  288.   {
  289.     hr = doUnRegisterPooled();
  290.     return hr;
  291.   }
  292.   else return S_OK;
  293. }
  294.  
  295. HRESULT TRemoteDataModuleRegistrar::doRegister()
  296. {
  297.  TCHAR* pClassID = m_ClassIDstr;
  298.  
  299.   // Initialize these so they can be checked for deletion if someone throws
  300.   ICatRegister* CatReg = 0;
  301.   TCHAR* RegKeyTemp = 0;
  302.   TCHAR* DescriptTemp = 0;
  303.   TCHAR* AppTemp = 0;
  304.   LPWSTR MidasStrTemp = 0;
  305.   GUID tempGUID;
  306.  
  307.   // Get a component category manager. */
  308.   HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoryMgr, 0,
  309.                                 CLSCTX_INPROC_SERVER, IID_ICatRegister,
  310.                                 (void**)&CatReg);
  311.   try {
  312.     if SUCCEEDED(hr)
  313.     {
  314.       /* Build a Category Information structure for the MIDAS category */
  315.       CATEGORYINFO CatInfo;
  316. #if !defined(UNICODE) && !defined(_UNICODE)
  317.       CatInfo.catid = TStringConverter<char>::AnsiToGUID("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}"); /* do not localize */
  318. #else
  319.       CatInfo.catid = TStringConverter<char>::WideToGUID(_T("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}")); /* do not localize */
  320. #endif
  321.       MidasStrTemp = TStringConverter<char>::AnsiToWide("Borland MIDAS Application Servers"); /* Do not localize */
  322.       CatInfo.lcid = 0x409;
  323.  
  324.       wcscpy((wchar_t*)&CatInfo.szDescription, MidasStrTemp);
  325.       delete[] MidasStrTemp;
  326.       MidasStrTemp - 0;
  327.  
  328.       /* Register the category */
  329.       OLECHECK(CatReg->RegisterCategories(1, &CatInfo));
  330. #if !defined(UNICODE) && !defined(_UNICODE)
  331.       tempGUID =TStringConverter<char>::AnsiToGUID("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}");
  332.       OLECHECK(CatReg->RegisterClassImplCategories( TStringConverter<char>::AnsiToGUID(pClassID), 1, &tempGUID));
  333. #else
  334.       tempGUID =TStringConverter<char>::WideToGUID(_T("{13E85B3C-9508-11D2-AB63-00C04FA35CFA}"));
  335.       OLECHECK(CatReg->RegisterClassImplCategories( TStringConverter<char>::WideToGUID(pClassID), 1, &tempGUID));
  336. #endif
  337.       CatReg->Release();
  338.     } else {
  339.       /* For some reason there's no component categories manager available. oops,
  340.          we'll have to do the equivalent */
  341.       OLECHECK(TInternalRegistrationHelpers::CreateRegKey(_T("Component Categories\\{13E85B3C-9508-11D2-AB63-00C04FA35CFA}"), /* do not localize */
  342.                             _T("409"), _T("Borland MIDAS Application Servers"))); /* do not localize */
  343.       RegKeyTemp = TInternalRegistrationHelpers::CreateImplementedMIDASOfClass(pClassID);
  344.       OLECHECK(TInternalRegistrationHelpers::CreateRegKey(RegKeyTemp, _T(""), _T("")));
  345.       delete[] RegKeyTemp;
  346.     }
  347.  
  348.     // Register the AppID and the ClassID
  349.     RegKeyTemp = TInternalRegistrationHelpers::CreateKeyOfClass(pClassID);
  350. #if !defined(UNICODE) && !defined(_UNICODE)
  351.     DescriptTemp = TInternalRegistrationHelpers::GetRegStringValue(RegKeyTemp, _T(""));
  352. #else
  353.     DescriptTemp = TStringConverter<char>::AnsiToWide(TInternalRegistrationHelpers::GetRegStringValue(RegKeyTemp, _T("")));
  354. #endif
  355.     TInternalRegistrationHelpers::CreateRegKey(RegKeyTemp, _T("AppID"), pClassID);
  356.     AppTemp = TInternalRegistrationHelpers::CreateAppIDOfClass(pClassID);
  357.     TInternalRegistrationHelpers::CreateRegKey(AppTemp, _T(""), DescriptTemp);
  358.     delete[] AppTemp;
  359.     delete[] DescriptTemp;
  360.  
  361.     if (EnableSocket)
  362.     {
  363.       /* Add a special key just for sockets. */
  364.       OLECHECK(TInternalRegistrationHelpers::CreateRegKey(RegKeyTemp, _T("Sockets"), _T("1")));
  365.     }
  366.     if (EnableWeb)
  367.     {
  368.       /* Add a special key just for web support. */
  369.       OLECHECK(TInternalRegistrationHelpers::CreateRegKey(RegKeyTemp, _T("Web"), _T("1")));
  370.     }
  371.     delete[] RegKeyTemp;
  372.   }
  373.   catch (...)
  374.   {
  375.     /* OLECHECK throws on failure. */
  376.     if (CatReg) CatReg->Release();
  377.     if (RegKeyTemp) delete[] RegKeyTemp;
  378.     if (DescriptTemp) delete[] DescriptTemp;
  379.     if (AppTemp) delete[] AppTemp;
  380.     if (MidasStrTemp) delete[] MidasStrTemp;
  381.     return E_FAIL;
  382.   }
  383.   if (RegisterPooled)
  384.   {
  385.     hr = doRegisterPooled();
  386.     return hr;
  387.   }
  388.   else return S_OK;
  389. }
  390.  
  391. //----------------------------------------------------------------------------//
  392. // Registers (or Unregisters) ActiveX Control
  393. //
  394. HRESULT TAxControlRegistrar::UpdateRegistry(bool Register)
  395. {
  396.   HRESULT hres;
  397.   if (Register)
  398.   {
  399.     // Call base first when registering
  400.     //
  401.     hres = TTypedComServerRegistrar::UpdateRegistry(Register);
  402.    
  403.     // Make registry entries
  404.     //
  405.     TCHAR key[_MAX_PATH];
  406.     lstrcpy(key, m_ClassKey);
  407.     LPTSTR pinsert = key + lstrlen(key);
  408.  
  409.     lstrcpy(pinsert, _T("\\MiscStatus"));
  410.     CreateRegKey(key, _T(""), _T("0"));
  411.  
  412.     TCHAR misc[16];
  413.     wsprintf(misc, _T("%d"), m_MiscFlags);
  414.     lstrcpy(pinsert, _T("\\MiscStatus\\1"));
  415.     CreateRegKey(key, _T(""), misc);
  416.  
  417.     lstrcpy(pinsert, _T("\\ToolboxBitmap32"));
  418.     TCHAR mod[_MAX_PATH + 8];
  419.     wsprintf(mod, _T("%s,%d"), LPCTSTR(m_ModuleName), m_BitmapID);
  420.     CreateRegKey(key, _T(""),  mod);
  421.  
  422.     lstrcpy(pinsert, _T("\\Control"));
  423.     CreateRegKey(key,   _T(""), _T(""));
  424.  
  425.     lstrcpy(pinsert, _T("\\Verb"));
  426.     CreateRegKey(key,   _T(""), _T(""));
  427.    
  428.     // Register Verbs
  429.     //
  430.     const OLEVERB *pVerb = m_Verbs;
  431.     while (pVerb->lpszVerbName && *pVerb->lpszVerbName)
  432.     {
  433.       TCHAR szKey[_MAX_PATH];
  434.       wsprintf(szKey, _T("%s\\Verb\\%d"), LPCTSTR(m_ClassKey), pVerb->lVerb);
  435.  
  436.       TCHAR szVerb[_MAX_PATH];
  437.       wsprintf(szVerb, _T("%ls,%d,%d"), pVerb->lpszVerbName, pVerb->fuFlags, pVerb->grfAttribs);
  438.     
  439.       CreateRegKey(szKey, _T(""), szVerb);
  440.  
  441.       pVerb++;
  442.     }
  443.   }
  444.   else
  445.   {
  446.     // Call base class to unregister
  447.     // NOTE: Base class removes everything underneath \\CLSID\\<clsid> && \\<progid>\\
  448.     //
  449.     hres = TTypedComServerRegistrar::UpdateRegistry(Register);
  450.   }
  451.   return hres;
  452. }
  453.  
  454. //-----------------------------------------------------------------------------//
  455. #if defined(USING_VCL)
  456. // AutomationTerminateProc (Backward compatiblity)
  457. //
  458. bool __fastcall AutomationTerminateProc()
  459. {
  460.   return TComModule::AutomationTerminateProc();
  461. }
  462. #endif
  463.  
  464.