-------------------------------------------------------------------------------- ÁÖ Á¦ ActiveX ÄÁÆ®·Ñ¿¡¼­ÀÇ IObjectSafety ÀÎÅÍÆäÀ̽º ±¸Çö -------------------------------------------------------------------------------- ¿Å±äÀÌ ÁÖ (¹ÌÄ£º´¾Æ¸® ¿Ð~) Á¦°¡ ¾Ö¿ëÇÏ´Â ¹æ¹ýÀº ¾µµ¥¾øÀÌ ·¹Áö½ºÆ®¸®¸¦ ´õ·´È÷´Â ¹æ¹ýº¸´Ù´Â IObjectSafety ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÏ´Â ¹æ¹ýÀÔ´Ï´Ù.. ¸»ÀÌ ±¸ÇöÀÌÁö.. ½ÇÁ¦·Î.. ¾Æ·¡ ³ª¿Â ¼Ò½º¸¦ ±×´ë·Î ³Ö°í ÀÚ½ÅÀÌ °³¹ßÇÑ ActiveX ÄÁÆ®·Ñ Ŭ·¡½º¸í¸¸ ¼öÁ¤ÇØÁÖ¸é µË´Ï´Ù.. ¾Æ·¡ ¿¹¿¡¼­´Â COcxPuzCtrl À̶õ ¹®ÀÚ¿­À» ÀÚ½ÅÀÇ Å¬·¡½º¸íÀ¸·Î ¹Ù²ãÁÖ¸é µÇÁÒ.. ------------------------------------------------------------------------ Active-X ÄÁÆ®·Ñ¿¡ Safe ¿É¼ÇÀ» Ãß°¡ÇÏ´Â ¹æ¹ýÀº ÄÁÆ®·ÑÀÌ ÀνºÅç µÇ°Å³ª ±× ÈÄ¿¡ Certains functionÀ» ÄÁÆ®·ÑÀÌ Á÷Á¢ È£ÃâÇÏ´Â ¹æ¹ý°ú ±× ÄÁÆ®·Ñ¿¡ Á÷Á¢ IobjectSafety ÀÎÅÍÆäÀ̽º¸¦ Á÷Á¢±¸ÇöÇÏ´Â ¹æ¹ý µÎ°¡Áö°¡ ÀÖ½À´Ï´Ù. << ·¹Áö½ºÅÍ¿¡ µî·ÏÇÏ´Â µ¿¾È ÄÁÆ®·ÑÀ» ¸¶Å©ÇÏ´Â ¹æ¹ý >> ¿ì¼± ·¹Áö½ºÆ®¸®¿¡ µî·ÏÇÏ´Â ÇïÆÛ Æã¼ÇÀ» Æ÷ÇÔÇÑ helpers.h¿Í helpers.cpp¸¦ ÀÛ¼ºÇØ¾ß Çϴµ¥, ÀÌ ÆÄÀÏÀº MSDNÀÇ ActiveX SDK¿¡¼­ Ä«ÇÇÇÒ ¼ö Àִٴµ¥ Àú µµ ã¾Æº¸Áø ¾Ê¾Æ¼­ À߸𸣰ڱ¸¿ä.. ¹°·Ð ÀúÇÑÅ×µµ ÀÖ½À´Ï´Ù. (helpers.h - ´Ù¿î·Îµå, helpers.cpp - ´Ù¿î·Îµå) ±× ´ÙÀ½ [CONTROL NAME]CTRL.CPP¿¡ HELPERS.H¿Í OBJSAFE.H¸¦ IncludeÇÑ ´ÙÀ½ {ControlClass}::{ControlClass}Factory::UpdateRegistry¿¡ ´ÙÀ½ Äڵ带 »ðÀÔ ÇÏ¸é µË´Ï´Ù. // Mark as safe for scripting-failure OK. HRESULT hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls that are safely scriptable"); if (SUCCEEDED(hr)) // Only register if category exists. RegisterCLSIDInCategory(m_clsid, CATID_SafeForScripting); // Don't care if this call fails. // Mark as safe for data initialization. hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data"); if (SUCCEEDED(hr)) // Only register if category exists. RegisterCLSIDInCategory(m_clsid, CATID_SafeForInitializing); // Don't care if this call fails. << IobjectSafety ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÏ´Â ¹æ¹ý >> ÀÌ ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇϱâÀ§Çؼ­´Â GetInterfaceSafetyOptions¿Í SetInterfaceSafetyOptions µÎ°³ÀÇ ÇÔ¼ö°¡ ÇÊ¿äÇÕ´Ï´Ù. ÀÌ°ÍÀº ÆÛÁñocx¸¦ ¿¹ ¸¦ µé¾î ¼³¸íÇÏ°Ú½À´Ï´Ù. ¿ì¼± [Controlname]Ctrl.h ÆÄÀÏ¿¡ ObjSafe.h¸¦ IncludeÇÏ°í Ŭ·¡½º¿¡ ´ÙÀ½°ú °°Àº Äڵ带 »ðÀÔÇÕ´Ï´Ù. class COcxPuzCtrl : public COleControl { DECLARE_DYNCREATE(COcxPuzCtrl) DECLARE_INTERFACE_MAP() BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety) STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) ( /* [in] */ REFIID riid, /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions ); STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) ( /* [in] */ REFIID riid, /* [in] */ DWORD dwOptionSetMask, /* [in] */ DWORD dwEnabledOptions ); END_INTERFACE_PART(ObjSafe); ±×¸®°í cpp ÆÄÀÏ¿¡ ´ÙÀ½°ú °°Àº Äڵ带 »ðÀÔÇØ ÁÖ¸é µË´Ï´Ù. //////////////////////////////////////////////////////////////////////// // Interface map for IObjectSafety BEGIN_INTERFACE_MAP( COcxPuzCtrl, COleControl ) INTERFACE_PART(COcxPuzCtrl, IID_IObjectSafety, ObjSafe) END_INTERFACE_MAP() //////////////////////////////////////////////////////////////////////// // IObjectSafety member functions // Delegate AddRef, Release, QueryInterface ULONG FAR EXPORT COcxPuzCtrl::XObjSafe::AddRef() { METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe) return pThis->ExternalAddRef(); } ULONG FAR EXPORT COcxPuzCtrl::XObjSafe::Release() { METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe) return pThis->ExternalRelease(); } HRESULT FAR EXPORT COcxPuzCtrl::XObjSafe::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe) return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA; const DWORD dwNotSupportedBits = ~ dwSupportedBits; //////////////////////////////////////////////////////////////////////// // COcxPuzCtrl::XObjSafe::GetInterfaceSafetyOptions // Allows container to query what interfaces are safe for what. We're // optimizing significantly by ignoring which interface the caller is // asking for. HRESULT STDMETHODCALLTYPE COcxPuzCtrl::XObjSafe::GetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions) { METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe) HRESULT retval = ResultFromScode(S_OK); // does interface exist? IUnknown FAR* punkInterface; retval = pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface); if (retval != E_NOINTERFACE) { // interface exists punkInterface->Release(); // release it--just checking! } // we support both kinds of safety and have always both set, // regardless of interface *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits; return retval; // E_NOINTERFACE if QI failed } //////////////////////////////////////////////////////////////////////// // COcxPuzCtrl::XObjSafe::SetInterfaceSafetyOptions // Since we're always safe, this is a no-brainer--but we do check to make // sure the interface requested exists and that the options we're asked to // set exist and are set on (we don't support unsafe mode). HRESULT STDMETHODCALLTYPE COcxPuzCtrl::XObjSafe::SetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [in] */ DWORD dwOptionSetMask, /* [in] */ DWORD dwEnabledOptions) { METHOD_PROLOGUE(COcxPuzCtrl, ObjSafe) // does interface exist? IUnknown FAR* punkInterface; pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface); if (punkInterface) { // interface exists punkInterface->Release(); // release it--just checking! } else { // interface doesn't exist return ResultFromScode(E_NOINTERFACE); } // can't set bits we don't support if (dwOptionSetMask & dwNotSupportedBits) { return ResultFromScode(E_FAIL); } // can't set bits we do support to zero dwEnabledOptions &= dwSupportedBits; // (we already know there are no extra bits in mask ) if ((dwOptionSetMask & dwEnabledOptions) != dwOptionSetMask) { return ResultFromScode(E_FAIL); } // don't need to change anything since we're always safe return ResultFromScode(S_OK); } ±×¸®°í ÀÚ¼¼ÇÑ »çÇ×Àº http://premium.microsoft.com/msdn/library/techart/msdn_signmark.htm ¿¡ »ó¼¼È÷ ¼³¸íµÇ¾î ÀÖÀ¸´Ï ÂüÁ¶ÇØ º¸¼¼¿ä..