[ATL COM AppWizard ½ºÅÜ 1/1] ¿¡¼ , ¼¹ö ŸÀÔÀ» ´ÙÀ̳ª¹Í ¸µÅ© ¶óÀ̺귯¸® (DLL) ·Î ÇØ ,MFC ÀÇ ¼Æ÷Æ®¿¡ üũ¸¦ ³Ö°í (MFC ¸¦ »ç¿ëÇÏÁö ¾Ê´Â °æ¿ì´Â , ´ç¿¬È÷ üũÀÇ ÇÊ¿ä´Â ¾ø½À´Ï´Ù),[Á¾·á] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
È®ÀÎÀ» À§ÇÑ [½Å±Ô ÇÁ·ÎÁ§Æ® Á¤º¸] ·Î [OK] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
´ÙÀ½¿¡ ÀÛ¼ºÇÏ´Â ÄÁÆ®·Ñ·ÎºÎÅÍ , Á¢¼Ó Æ÷ÀÎÆ®¸¦ »ç¿ëÇØ À̺¥Æ® ÅëÁöÇÒ ¶§¿¡ »ç¿ëÇÏ´Â ATL ¿ÀºêÁ§Æ®¸¦ ÀÛ¼ºÇÕ´Ï´Ù.
Ç¥½ÃµÇ´Â [ATL ¿ÀºêÁ§Æ® À§ÀúµåÀÇ ÇÁ·ÓÆÛƼ] ÀÇ [À̸§] ÅÇÀ¸·Î [¼îÆ® ³×ÀÓ] À» Àû´çÇÏ°Ô (¿©±â¿¡¼´Â SampleParam À¸·Î Çß´ø) ÀÔ·ÂÇØ ,[¾ÖÆ®¸®ºäÆ®(attribute)] ÅÇÀ¸·Î [thread ¸ðµ¨] À» ¾ÆÆÄÆ®¸ÕÆ®¿¡ ,[ÀÎÅÍÆäÀ̽º] ¸¦ µà¾ó , [¾Æ±×¸®°ÔÀ̼Ç] À» ³× ·Î ÇØ ,[OK] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
´ÙÀ½¿¡ ÄÁÆ®·ÑÀ» ÀÛ¼ºÇÕ´Ï´Ù.
Ç¥½ÃµÇ´Â [ATL ¿ÀºêÁ§Æ® À§ÀúµåÀÇ ÇÁ·ÓÆÛƼ] ÀÇ [À̸§] ÅÇÀ¸·Î [¼îÆ® ³×ÀÓ] À» Àû´çÇÏ°Ô (¿©±â¿¡¼´Â SampleCtrl À¸·Î Çß´ø) ÀÔ·ÂÇØ ,[¾ÖÆ®¸®ºäÆ®(attribute)] ÅÇÀ¸·Î [thread ¸ðµ¨] À» ¾ÆÆÄÆ®¸ÕÆ®¿¡ ,[ÀÎÅÍÆäÀ̽º] ¸¦ µà¾ó , [¾Æ±×¸®°ÔÀ̼Ç] À» ³×¿¡ ,[ISupportErrorInfo ¼Æ÷Æ®] ¿Í [connection Æ÷ÀÎÆ®ÀÇ ¼Æ÷Æ®] ¿¡ üũ¸¦ ³Ö¾î [OK] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
[ClassView] ¿¡ ÀÛ¼ºµÈ Ŭ·¡½º°¡ Ç¥½ÃµÇ°í ÀÖ´Â °ÍÀ» È®ÀÎÇØ ÁÖ¼¼¿ä.
¿ì¼± , ¸Þ´º·ÎºÎÅÍ [ºôµå] - [ºôµå] ¸¦ ¼±ÅÃÇØ , ºôµå ÇØ ÁÖ¼¼¿ä. ¶óÀ̺귯¸®¿¡ ÃÖ½ÅÀÇ °Í SDK À» »ç¿ëÇÏ°í ÀÖ´Â °æ¿ì ,
c:\documents and settings\bono\my documents\visual studio projects\atlctrlsample\samplectrl.h(97) : error C2668: 'InlineIsEqualGUID' : µ°ÊÞ°Û°ÄÞÇÔ¼öÀ� È£ÃâÀ» ÇØ°áÇÒ ¼ö°¡ ¾ø½À´Ï´Ù. (½Å±â´É ; ÍÙÌßÀ» ÂüÁ¶)¿Í °°Àº ¿¡·¯°¡ µÇ´Â °æ¿ì°¡ ÀÖ½À´Ï´Ù. ¿øÀÎÀº ¸¶ÀÌÅ©·Î¼ÒÇÁÆ® ¼Æ÷Æ® ±â¼ú Á¤º¸ 243298 - [VC60] C2668 ¿¡·¯°¡ InlineIsEqualGUID ÀÇ Á¤ÀÇ ºÎºÐ¿¡¼ ¹ß»ý À¸·Î ¸®Æ÷Æ® µÇ°í ÀÖ½À´Ï´Ù.
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid) { static const IID* arr[] = { &IID_ISampleCtrl, }; for (int i=0; i<sizeof(arr)/sizeof(arr[0]); i++) { if (ATL::InlineIsEqualGUID(*arr[i], riid)) return S_OK; } return S_FALSE; }ÆíÁýÀÌ »ì¸é(ÀÚ) , ÀçÂ÷ ºôµå ÇØ ÁÖ¼¼¿ä.
[ÀÎÅÍÆäÀ̽º¿¡ ÇÁ·ÓÆÛƼ¸¦ Ãß°¡] ´ÙÀ̾ó·Î±×°¡ Ç¥½ÃµÇ±â ¶§¹®¿¡ ,[ÇÁ·ÓÆÛƼÀÇ Á¾·ù] ¿¡ BSTR,[ÇÁ·ÓÆÛƼ¸í] ¿¡ DisplayString ¸¦ ¼³Á¤ÇØ ,[OK] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
´ÙÀ½¿¡ , ÇÁ·ÓÆÛƼġ¸¦ º¸Á¸Çϱâ À§ÇÑ º¯¼ö ¸â¹ö¸¦ Ãß°¡ÇÕ´Ï´Ù. SampleCtrl.h (À»)¸¦ ¿¾î , Ŭ·¡½º Á¤ÀÇ¿¡ CString ÀÇ º¯¼ö m_DisplayString ¸¦ Ãß°¡ÇÕ´Ï´Ù.
(rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2, pszText, lstrlen(pszText)); return S_OK; } private: // ÇÁ·ÓÆÛƼ DisplayString ÀÇ °ªÀ» º¸°ü À¯ÁöÇÑ´Ù. CString m_DisplayString; }; #endif //__SAMPLECTRL_H_´ÙÀ½¿¡ , ÇÁ·ÓÆÛƼġ¸¦ m_DisplayString ·Î ¼³Á¤/ÃëµæÇÏ´Â Äڵ带 ¾¹´Ï´Ù.
¿©±â¿¡¼´Â ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇß½À´Ï´Ù.
STDMETHODIMP CSampleCtrl::get_DisplayString(BSTR *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) *pVal = m_DisplayString.AllocSysString(); return S_OK; } STDMETHODIMP CSampleCtrl::put_DisplayString(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) m_DisplayString = newVal; // ÄÁÆ®·ÑÀÌ º¯°æµÈ °ÍÀ» ¼³Á¤ÇÑ´Ù. SetDirty(TRUE); // Àç¹¦È ÇÏ°í ½ÍÀº °ÍÀ» ÄÁÅ×À̳ʿ¡ ÅëÁöÇÑ´Ù. FireViewChange(); return S_OK; }´ÙÀ½¿¡ m_DisplayString ¸¦ Ç¥½ÃÇϵµ·Ï(µíÀÌ) µðÆúÆ®ÀÇ ¹¦È Äڵ带 º¯°æÇÕ´Ï´Ù.
HRESULT OnDraw(ATL_DRAWINFO& di) { RECT& rc = *(RECT*)di.prcBounds; Rectangle(di.hdcDraw, rc.left, rc.top, rc.right, rc.bottom); SetTextAlign(di.hdcDraw, TA_CENTER|TA_BASELINE); // ÇÁ·ÓÆÛƼġ¸¦ Ç¥½ÃÇϵµ·Ï(µíÀÌ) º¯°æÇÑ´Ù. //LPCTSTR pszText = _T("ATL 3.0 : SampleCtrl"); LPCTSTR pszText = m_DisplayString; TextOut(di.hdcDraw, (rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2, pszText, lstrlen(pszText)); return S_OK; }ÀÌ°ÍÀ¸·Î , ÇÁ·ÓÆÛƼ¸¦ Ç¥½ÃÇÒ ¼ö ÀÖ°Ô µË´Ï´Ù. ¶ó°í ÁÁÀº ½ÍÀº °÷ÀÔ´Ï´Ù¸¸ , ¾ÆÁ÷ÀÔ´Ï´Ù. IE µî¿¡¼ ÇÁ·ÓÆÛƼ¸¦ ¼³Á¤ÇÏ°í ½ÍÀº °æ¿ì ,IPersistPropertyBag ¸¦ ½ÇÀåÇÒ ÇÊ¿ä°¡ ÀÖ½À´Ï´Ù. ±×·¸´Ù°í Çصµ ,ATL ±×·³ IPersistPropertyBagImpl À̶ó°í ÇÏ´Â µðÆúÆ®ÀÇ ½ÇÀåÀÌ Á¦°øµÇ°í Àֱ⠶§¹®¿¡ , ÀÚ½ÅÀÇ ÄÁÆ®·Ñ Ŭ·¡½º¿¡¼ ÀÌ°ÍÀ» °è½ÂÇÏ´Â °Í¸¸À¸·Î ³¡³³´Ï´Ù.
public IPersistPropertyBagImpl<CSampleCtrl> // ÇÁ·ÓÆÛƼ¸¦ Ãë±ÞÇÏ´ÂÀ» Ãß°¡ÇÕ´Ï´Ù.
class ATL_NO_VTABLE CSampleCtrl : public CComObjectRootEx<CComSingleThreadModel>, public IDispatchImpl<ISampleCtrl, &IID_ISampleCtrl, &LIBID_ATLCTRLSAMPLELib>, public CComControl<CSampleCtrl>, public IPersistStreamInitImpl<CSampleCtrl>, public IOleControlImpl<CSampleCtrl>, public IOleObjectImpl<CSampleCtrl>, public IOleInPlaceActiveObjectImpl<CSampleCtrl>, public IViewObjectExImpl<CSampleCtrl>, public IOleInPlaceObjectWindowlessImpl<CSampleCtrl>, public ISupportErrorInfo, public IConnectionPointContainerImpl<CSampleCtrl>, public IPersistStorageImpl<CSampleCtrl>, public ISpecifyPropertyPagesImpl<CSampleCtrl>, public IQuickActivateImpl<CSampleCtrl>, public IDataObjectImpl<CSampleCtrl>, public IProvideClassInfo2Impl<&CLSID_SampleCtrl, &DIID__ISampleCtrlEvents, &LIBID_ATLCTRLSAMPLELib>, public IPropertyNotifySinkCP<CSampleCtrl>, public CComCoClass<CSampleCtrl, &CLSID_SampleCtrl>, public IPersistPropertyBagImpl<CSampleCtrl> // ÇÁ·ÓÆÛƼ¸¦ Ãë±ÞÇÏ´Â { public: CSampleCtrl() {°Ô´Ù°¡ Ŭ·¡½º Á¤ÀÇÁßÀÇ °Í BEGIN_COM_MAP(CSampleCtrl) À¸·ÎºÎÅÍ END_COM_MAP() ÀÇ »çÀÌ¿¡
COM_INTERFACE_ENTRY(IPersistPropertyBag)¸¦ Ãß°¡ÇÕ´Ï´Ù.
COM_INTERFACE_ENTRY(IConnectionPointContainer) COM_INTERFACE_ENTRY(ISpecifyPropertyPages) COM_INTERFACE_ENTRY(IQuickActivate) COM_INTERFACE_ENTRY(IPersistStorage) COM_INTERFACE_ENTRY(IDataObject) COM_INTERFACE_ENTRY(IProvideClassInfo) COM_INTERFACE_ENTRY(IProvideClassInfo2) COM_INTERFACE_ENTRY(IPersistPropertyBag) END_COM_MAP()¸¶Áö¸·À¸·Î , ÇÁ·ÓÆÛƼÀÇ ¸íĪÀ» Á¤ÀÇÇϱâ À§ÇØ(¶§¹®¿¡) ,BEGIN_PROP_MAP(CSampleCtrl) ·ÎºÎÅÍ END_PROP_MAP() ÀÇ »çÀÌ¿¡
PROP_ENTRY("DisplayString", 1, GetObjectCLSID())¸¦ Ãß°¡ÇÕ´Ï´Ù. µ¡ºÙ¿© Á¦ 2 ÀμöÀÇ °Í 1 Àº , À§Àúµå¿¡ ÀÇÇØ IDL ¿¡ Ãß°¡µÈ ÇÁ·ÓÆÛƼ DisplayString ÀÇ ÇÁ·ÓÆÛƼ ID ÀÔ´Ï´Ù.
BEGIN_PROP_MAP(CSampleCtrl) PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4) PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4) PROP_ENTRY("DisplayString", 1, GetObjectCLSID()) // Example entries // PROP_ENTRY("Property Description", dispid, clsid) // PROP_PAGE(CLSID_StockColorPage) END_PROP_MAP()ºôµå°¡ ³¡³ª¸é(ÀÚ) , ÇÁ·ÓÆÛƼġ¸¦ ¼³Á¤Çϵµ·Ï(µíÀÌ) ÄÁÆ®·Ñ Å×½ºÆ®¿ëÀÇ °Í HTML (SampleCtrl.htm) À» ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
<HTML> <HEAD> <TITLE>¿ÀºêÁ§Æ® SampleCtrl ¿ë ATL 3.0 Å×½ºÆ® ÆäÀÌÁö</TITLE> </HEAD> <BODY> <OBJECT ID="SampleCtrl" CLASSID="CLSID:B94F2CEA-B317-4CEC-8448-B9E733BE663A"> <PARAM NAME="DisplayString" VALUE="¾È³çÇϼ¼¿ä"> </OBJECT> </BODY> </HTML>ÆíÁýÀÌ ³¡³ª¸é(ÀÚ) , Å×½ºÆ® ÆäÀÌÁö¸¦ IE ·Î ¿·Á ÁÖ¼¼¿ä. ÀÌÇÏ¿Í °°ÀÌ Ç¥½ÃµÇ¸é OK ÀÔ´Ï´Ù.
µ¡ºÙ¿© ÇÁ·ÓÆÛƼ¸¦ ½ÇÀåÇϸé(ÀÚ) , ÀÌÇÏ¿Í °°Àº ´ÙÀ̾ó·Î±×°¡ ³ª¿À±â ½ÃÀÛÇÏ°Ô µË´Ï´Ù.
ÀÌ°ÍÀº , ÄÁÆ®·ÑÀÌ ¾ÈÀüÀ̶ó°í ¸¶Å·µÇ¾î ÀÖÁö ¾Ê±â ¶§¹®ÀÔ´Ï´Ù. ÀÌ°ÍÀ» ¸¶Å© Çϱâ À§Çؼ IObjectSafety ¸¦ ½ÇÀåÇÕ´Ï´Ù. ATL ¿¡´Â IObjectSafetyImpl ÀÌ Á¦°øµÇ°í Àֱ⠶§¹®¿¡ , Åë»óÀº , ÀÌ°ÍÀ» ÄÁÆ®·Ñ Ŭ·¡½º¿¡¼ °è½ÂÇÒ »ÓÀÔ´Ï´Ù.
public IObjectSafetyImpl<CSampleCtrl, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>¸¦ Ãß°¡ÇÕ´Ï´Ù. ¿©±â¿¡¼´Â , ½ºÅ©¸³Æ®ÀÇ ¾ÈÀü¼º°ú ÃʱâȽÃÀÇ µ¥ÀÌÅÍÀÇ ¾ÈÀü¼ºÀ» º¸ÁõÇÏ°í ÀÖ½À´Ï´Ù.
class ATL_NO_VTABLE CSampleCtrl : public CComObjectRootEx<CComSingleThreadModel>, public IDispatchImpl<ISampleCtrl, &IID_ISampleCtrl, &LIBID_ATLCTRLSAMPLELib>, public CComControl<CSampleCtrl>, public IPersistStreamInitImpl<CSampleCtrl>, public IOleControlImpl<CSampleCtrl>, public IOleObjectImpl<CSampleCtrl>, public IOleInPlaceActiveObjectImpl<CSampleCtrl>, public IViewObjectExImpl<CSampleCtrl>, public IOleInPlaceObjectWindowlessImpl<CSampleCtrl>, public ISupportErrorInfo, public IConnectionPointContainerImpl<CSampleCtrl>, public IPersistStorageImpl<CSampleCtrl>, public ISpecifyPropertyPagesImpl<CSampleCtrl>, public IQuickActivateImpl<CSampleCtrl>, public IDataObjectImpl<CSampleCtrl>, public IProvideClassInfo2Impl<&CLSID_SampleCtrl, &DIID__ISampleCtrlEvents, &LIBID_ATLCTRLSAMPLELib>, public IPropertyNotifySinkCP<CSampleCtrl>, public CComCoClass<CSampleCtrl, &CLSID_SampleCtrl>, public IPersistPropertyBagImpl<CSampleCtrl>, // ÇÁ·ÓÆÛƼ¸¦ Ãë±ÞÇÏ´Â public IObjectSafetyImpl<CSampleCtrl, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA> { public: CSampleCtrl() {°Ô´Ù°¡ Ŭ·¡½º Á¤ÀÇÁßÀÇ °Í BEGIN_COM_MAP(CSampleCtrl) À¸·ÎºÎÅÍ END_COM_MAP() ÀÇ »çÀÌ¿¡
COM_INTERFACE_ENTRY(IObjectSafety)¸¦ Ãß°¡ÇÕ´Ï´Ù.
COM_INTERFACE_ENTRY(IConnectionPointContainer) COM_INTERFACE_ENTRY(ISpecifyPropertyPages) COM_INTERFACE_ENTRY(IQuickActivate) COM_INTERFACE_ENTRY(IPersistStorage) COM_INTERFACE_ENTRY(IDataObject) COM_INTERFACE_ENTRY(IProvideClassInfo) COM_INTERFACE_ENTRY(IProvideClassInfo2) COM_INTERFACE_ENTRY(IPersistPropertyBag) COM_INTERFACE_ENTRY(IObjectSafety) END_COM_MAP()
¸Þ´º·ÎºÎÅÍ [»ðÀÔ] - [ATL ¿ÀºêÁ§Æ®ÀÇ ½Å±Ô ÀÛ¼º] À» ¼±ÅÃÇØ [ATL ¿ÀºêÁ§Æ® À§Àúµå] ¸¦ Ç¥½ÃÇÕ´Ï´Ù.
Ç¥½ÃµÇ´Â [ATL ¿ÀºêÁ§Æ® À§ÀúµåÀÇ ÇÁ·ÓÆÛƼ] ÀÇ [À̸§] ÅÇÀ¸·Î [¼îÆ® ³×ÀÓ] À» Àû´çÇÏ°Ô (¿©±â¿¡¼´Â SampleCtrlPropPage À¸·Î Çß´ø) ÀÔ·ÂÇØ ,[string] ÅÇÀ¸·Î [ŸÀÌƲ] ¿¡ »ùÇà ÇÁ·ÓÆÛƼ ,[¹®¼ÀÇ ¹®ÀÚ] ¿¡ »ùÇÃÀÇ ÇÁ·ÓÆÛƼ ÆäÀÌÁö , [ÇïÇÁ ÆÄÀÏ] À» Çϴ÷Π¼³Á¤ÇØ ,[OK] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
ÇÁ·ÎÁ§Æ®¿¡ ÇÁ·ÓÆÛƼ ÆäÀÌÁö¿ëÀÇ ´ÙÀ̾ó·Î±×¿Í Ŭ·¡½º°¡ »ðÀԵ˴ϴÙ.
ÀÌ°ÍÀ» ÆíÁýÇØ ,DisplayString ¿ë¹«ÀÇ ÅؽºÆ® ¹Ú½º¸¦ ÀÛ¼ºÇÕ´Ï´Ù.
´ÙÀ½¿¡ ÇÁ·ÓÆÛƼ DisplayString ÀÇ ³»¿ëÀ» ´ÙÀ̾ó·Î±×·ÎºÎÅÍ ÆíÁýÇÒ ¼ö ÀÖµµ·Ï(µíÀÌ) Äڵ带 ¾¹´Ï´Ù.
Ç¥½ÃµÈ [CSampleCtrlPropPage Ŭ·¡½º¿¡ ½Å±Ô À©µµ¿ì ¸Þ¼¼Áö¿Í À̺¥Æ® Çڵ鷯¸¦ Ãß°¡] ´ÙÀ̾ó·Î±×·Î , [Ŭ·¡½º¿¡¼ »ç¿ë °¡´ÉÇÏ°Ô ÇÏ´Â ¸Þ¼¼ÁöÀÇ ÇÊÅÍ] ¿¡ ´ÙÀ̾ó·Î±× ¸¦ ¼±ÅÃÇØ ,[½Å±Ô À©µµ¿ì ¸Þ¼¼Áö/À̺¥Æ®] ·Î WM_INITDIALOG ¸¦ ´õºí Ŭ¸¯ ÇØ [±âÁ¸ÀÇ ¸Þ¼¼Áö/À̺¥Æ® Çڵ鷯] ¿¡ À̵¿½ÃÄÑ,[OK] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
Ãß°¡µÇ¾ú´Ù OnInitDialog() ¸¦ ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (m_nObjects <= 0) { // ´ç ÇÁ·ÓÆÛƼ ÆäÀÌÁö¿¡ °ü·ÃÁþ°í µÇ°í ÀÖ´Â ¿ÀºêÁ§Æ®°¡ ¾ø´Â °æ¿ì , return 0; } // ÇÁ·ÓÆÛƼÀÇ °ªÀ» CSampleCtrl ·ÎºÎÅÍ ÃëµæÇØ , // ´ÙÀ̾ó·Î±×»óÀÇ ÄÁÆ®·Ñ¿¡ ¹Ý¿µÇÑ´Ù. CComQIPtr<ISampleCtrl, &IID_ISampleCtrl> pSampleCtrl(m_ppUnk[0]); CComBSTR displayString; if (SUCCEEDED(pSampleCtrl->get_DisplayString(&displayString.m_str))) { SetDlgItemText(IDC_DISPLAY_STRING, CString(displayString)); } // º¯°æ Ç÷¡±×¸¦ ÃʱâÈÇØ µÐ´Ù. SetDirty(FALSE); return 0; }´ÙÀ½¿¡ ÇÁ·ÓÆÛƼ ÆäÀÌÁö·Î [Àû¿ë] ¶Ç´Â [OK] ÀÌ Å¬¸¯µÇ¾úÀ» ¶§ÀÇ Çڵ鷯 Apply() ¸¦ ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
STDMETHOD(Apply)(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // ´ÙÀ̾ó·Î±× ÄÁÆ®·ÑÀÇ °ªÀ» , ´ç ÇÁ·ÓÆÛƼ ÆäÀÌÁö¿¡ // °ü·ÃÁöÀ» ¼ö ÀÖ°í ÀÖ´Â CSampleCtrl ¿ÀºêÁ§Æ® ¸ðµÎ¿¡°Ô ¹Ý¿µÇÑ´Ù. BOOL bFailure = FALSE; for (UINT i = 0; i < m_nObjects; i++) { CComQIPtr<ISampleCtrl, &IID_ISampleCtrl> pSampleCtrl(m_ppUnk[i]); CComBSTR displayString; GetDlgItemText(IDC_DISPLAY_STRING, displayString.m_str); if (FAILED(pSampleCtrl->put_DisplayString(displayString))) { bFailure = TRUE; } } if (bFailure) { // ½ÇÆа¡ ÀÖ¾úÀ» ¶§´Â , ¿¡·¯ Á¤º¸¸¦ ÃëµæÇØ Ç¥½ÃÇÑ´Ù. CComPtr<IErrorInfo> pError; CComBSTR strError; GetErrorInfo(0, &pError); pError->GetDescription(&strError); MessageBox(CString(strError), _T("ÇÁ·ÓÆÛƼÀÇ º¸Á¸¿¡ ½ÇÆÐÇß½À´Ï´Ù. "), MB_OK | MB_ICONEXCLAMATION); return E_FAIL; } m_bDirty = FALSE; return S_OK; }ÅؽºÆ® ¹Ú½º°¡ º¯°æµÇ¾úÀ» ¶§¿¡ º¯°æ Ç÷¡±×¸¦ ¼³Á¤Çϵµ·Ï(µíÀÌ) Äڵ带 Ãß°¡ÇÕ´Ï´Ù.
[±âÁ¸ÀÇ ¸Þ¼¼Áö/À̺¥Æ® Çڵ鷯] ¿¡ EN_CHANGE °¡ À̵¿ÇϹǷΠ, ±×´ë·Î [OK] ¸¦ Ŭ¸¯ÇÕ´Ï´Ù.
Ãß°¡µÇ¾ú´Ù OnChangeDisplayString() ¸¦ ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
LRESULT OnChangeDisplayString(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); SetDirty(TRUE); return 0; }CSampleCtrl ÀÇ ÇÁ·ÓÆÛƼ¿Í ÀÌ ÇÁ·ÓÆÛƼ ÆäÀÌÁö¸¦ °ü·ÃÁþ±â À§Çؼ(¶§¹®¿¡) ,CSampleCtrl ÀÇ Å¬·¡½º Á¤ÀÇÀÇ °Í BEGIN_PROP_MAP() À¸·ÎºÎÅÍ END_PROP_MAP ÀÇ »çÀÌÀÇ °Í
PROP_ENTRY("DisplayString", 1, GetObjectCLSID())À» ,
PROP_ENTRY("DisplayString", 1, CLSID_SampleCtrlPropPage)°ú °°ÀÌ °íÃÄ ¾¹´Ï´Ù. °íÃÄ ¾²°í°¡ ³¡³ª¸é(ÀÚ) ºôµå ÇØ ÁÖ¼¼¿ä.
CSampleParam ÀÇ Å¬·¡½º Á¤ÀÇ¿¡ ÇÁ·ÓÆÛƼ Msg ÀÇ ³»¿ëÀ» º¸°ü À¯ÁöÇÏ´Â ¸â¹ö m_Msg ¸¦ Á¤ÀÇÇÕ´Ï´Ù.
// ÇÁ·ÓÆÛƼ Msg ÀÇ ³»¿ëÀ» º¸°ü À¯ÁöÇÑ´Ù. CString m_Msg; }; #endif //__SAMPLEPARAM_H_À§Àúµå¿¡ ÀÇÇØ Ãß°¡µÈ get_Msg,put_Msg ÀÇ ³»¿ëÀ» ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
STDMETHODIMP CSampleParam::get_Msg(BSTR *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) *pVal = m_Msg.AllocSysString(); return S_OK; } STDMETHODIMP CSampleParam::put_Msg(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) m_Msg = newVal; return S_OK; }ÀÌ°ÍÀ¸·Î ,SampleParam ´Â ¿Ï¼ºÀÔ´Ï´Ù.
Ãß°¡Çϸé(ÀÚ) , ºôµå ÇØ ÁÖ¼¼¿ä. ¿¡·¯°¡ ¾øÀ¸¸é ,[ClassView] ±×¸®°í CSampleCtrl ¸¦ ¿À¸¥ÂÊ Å¬¸¯ÇØ , Ç¥½ÃµÇ´Â pop-up menu·ÎºÎÅÍ [Á¢¼Ó Æ÷ÀÎÆ®ÀÇ ÀÎÇø®¸ÇÆ®] ¸¦ ¼±ÅÃÇÕ´Ï´Ù.
Ãß°¡°¡ ³¡³ª¸é(ÀÚ) , ÀçÂ÷ ºôµå ÇØ ÁÖ¼¼¿ä. ȯ°æ¿¡ ÀÇÇÑÀÏÁöµµ ¸ð¸¨´Ï´Ù¸¸ , ¿©±â¼
c:\documents and settings\bono\my documents\visual studio projects\atlctrlsample\samplectrl.h(83) : error C2065: 'IID__ISampleCtrlEvents' : Á¤ÀǵǾî ÀÖÁö ¾ÊÀº ½Äº°ÀÚÀÔ´Ï´Ù. c:\documents and settings\bono\my documents\visual studio projects\atlctrlsample\samplectrl.h(83) : error C2440: 'static_cast' : 'class CSampleCtrl *' (À¸)·ÎºÎÅÍ 'class ATL::_ICPLocator *' ·Î º¯È¯ÇÒ ¼ö ¾ø½À´Ï´Ù. (»õ·Î¿î µ¿ÀÛ ; ÍÙÌßÀ» ÂüÁ¶) Áö½Ã¹ÞÀº ÇüÅ´ °ü·ÃÀÌ ¾ø½À´Ï´Ù; º¯È¯¿¡´Â reinterpret_cast, C ½À²Ù ·¬½Ä¶Ç´Â ÇÔ¼ö½À²ÙÀÇ °Í·¬½ÄÀÌ ÇÊ¿äÇÕ´Ï´Ù. c:\documents and settings\bono\my documents\visual studio projects\atlctrlsample\samplectrl.h(83) : fatal error C1903: Á÷ÀüÀÇ °Í´×°À� ¼öº¹ÇÒ ¼ö ¾ø½À´Ï´Ù; ºÝÊß²Ù¸¦ ÁßÁöÇÕ´Ï´Ù.(¿Í)°ú °°Àº ¿¡·¯°¡ ³ª¿À´Â °æ¿ì ,CSampleCtrl Ŭ·¡½ºÀÇ Á¤Àdz»ÀÇ °Í
BEGIN_CONNECTION_POINT_MAP(CSampleCtrl) CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink) CONNECTION_POINT_ENTRY(IID__ISampleCtrlEvents) END_CONNECTION_POINT_MAP()À»
BEGIN_CONNECTION_POINT_MAP(CSampleCtrl) CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink) CONNECTION_POINT_ENTRY(DIID__ISampleCtrlEvents) END_CONNECTION_POINT_MAP()°ú °°ÀÌ (IID__ISampleCtrlEvents ÀÇ ¸Ó¸®¿¡ D ¸¦ ºÎ°¡ÇÏ´Â) ÆíÁýÇØ ÁÖ¼¼¿ä. ºôµå ÇÒ ¼ö ÀÖ°Ô µË´Ï´Ù.
´ÙÀ½¿¡ , À̺¥Æ® ÅëÁöÇÒ ¶§¿¡ »ç¿ëÇÏ´Â ISampleParam ÀÎÅÍÆäÀ̽º Æ÷ÀÎÅ͸¦ »ý¼º/ÆıâÇÏ´Â Äڵ带 Ãß°¡ÇÕ´Ï´Ù.
ISampleParam* m_pSampleParam;¸¦ Ãß°¡ÇÕ´Ï´Ù.
// ISampleParam (À»)¸¦ º¸°ü À¯ÁöÇÑ´Ù. ISampleParam* m_pSampleParam; }; #endif //__SAMPLECTRL_H_CSampleCtrl ÀÇ constructor¡¡ ¡¡ À» ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
CSampleCtrl() : m_pSampleParam(0) { }CComObjectRootEx::FinalConstruct() (À»)¸¦ ¿À¹ö¶óÀ̵å(override) ÇØ , ÀÌÇÏ¿Í °°ÀÌ Ãß°¡ÇÕ´Ï´Ù.
HRESULT FinalConstruct() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // À̺¥Æ® ÅëÁö¿¡ »ç¿ëÇÏ´Â ÀÎÅÍÆäÀ̽º¸¦ ÀÛ¼ºÇÑ´Ù. HRESULT hr; hr = CoCreateInstance(CLSID_SampleParam, 0, CLSCTX_INPROC_SERVER, IID_ISampleParam, (void **) &m_pSampleParam); if (FAILED(hr)) { TRACE("FAILURE: FinalConstruct() - CoCreateInstance(): IID_ISampleParam\n"); } return hr; }CComObjectRootEx::FinalRelease() (À»)¸¦ ¿À¹ö¶óÀ̵å(override) ÇØ , ÀÌÇÏ¿Í °°ÀÌ Ãß°¡ÇÕ´Ï´Ù.
void FinalRelease() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // À̺¥Æ® ÅëÁö¿¡ »ç¿ëÇÏ´Â ÀÎÅÍÆäÀ̽º¸¦ ÇعæÇÑ´Ù. if (m_pSampleParam) { m_pSampleParam->Release(); } }À§Àúµå¿¡ ÀÇÇØ CSampleCtrl ¿¡ Ãß°¡µÇ¾ú´Ù MyCallMethod ¸¦ ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
STDMETHODIMP CSampleCtrl::MyCallMethod() { AFX_MANAGE_STATE(AfxGetStaticModuleState()) CString msg = _T("¡ª"); if (m_pSampleParam) { m_pSampleParam->put_Msg(msg.AllocSysString()); Fire_SampleMethod(m_pSampleParam); } return S_OK; }ÆíÁýÀÌ ³¡³ª¸é(ÀÚ) , ºôµå ÇØ ÁÖ¼¼¿ä.
Private Sub Command1_Click() SampleCtrl1.MyCallMethod End Sub Private Sub SampleCtrl1_SampleMethod(ByVal sampParam As ATLCTRLSAMPLELibCtl.ISampleParam) MsgBox sampParam.Msg End Sub½ÇÇàÇØ Command1 ¸¦ Ŭ¸¯ÇØ ,"¡ª" (¿Í)°ú ¸Þ½ÃÁö ¹Ú½º¿¡ Ç¥½ÃµÇ¸é OK ÀÔ´Ï´Ù.
UINT MyControllingFunction(LPVOID pParam);°ú °°ÀÌ µË´Ï´Ù.
´ÙÀ½¿¡ , thread Ãø¿¡ °Ç³×ÁÖ´Â ÀÎÅÍÆäÀ̽º¸¦ ¸¶¼£¸µ Çϴµ¥ »ç¿ëÇÏ´Â IStream ¿¡ÀÇ Æ÷ÀÎÅÍ º¯¼ö¸¦ CSampleCtrl ÀÇ ¸â¹ö º¯¼ö·Î¼ Ãß°¡ÇÕ´Ï´Ù.
// ISampleParam ¸¶¼£¸µ¿ë IStream* m_IStreamSampleParam; // Á¢¼Ó Æ÷ÀÎÆ® ¸¶¼£¸µ¿ë CArray<IStream*, IStream*> m_IStreamDispatchArray; }; #endif //__SAMPLECTRL_H_±×¸®°í ,CArray ¸¦ »ç¿ëÇϱâ À§Çؼ StdAfx.h ¿¡
#include <afxtempl.h>¸¦ Ãß°¡ÇÕ´Ï´Ù.
#include <atlcom.h> #include <atlctl.h> #include <afxtempl.h> //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ (Àº)´Â ÀüÇàÀÇ Á÷Àü¿¡ Ãß°¡ÀÇ ¼±¾ðÀ» »ðÀÔÇÕ´Ï´Ù. #endif // !defined(AFX_STDAFX_H__55503BB6_11A0_4AE2_ABC9_C341A38E43F7__INCLUDED)´ÙÀ½¿¡ , ÄÁÅ×ÀÌ³Ê Á¾·á½Ã¿¡ thread°¡ ¾ÆÁ÷ µ¿ÀÛÇÏ°í ÀÖ¾úÀ» °æ¿ì , threadÀÇ Á¾·á¸¦ Áö½ÃÇÏ´Â Ç÷¡±×¿Í threadÀÇ Á¾·á¸¦ ¸¸³ª°í Çϱâ À§Çؼ , thread ÇÚµéÀ» ÅðÇÇÇØ µÎ´Â º¯¼ö¸¦ CSampleCtrl ÀÇ ¸â¹ö º¯¼ö·Î¼ Ãß°¡ÇÏ´Â
// Á¾·á Ç÷¡±× BOOL m_bAbort; // thread Á¾·á ¸¸³ª°í °¨½Ã¿ë HANDLE m_hThread; }; #endif //__SAMPLECTRL_H_»ó±â·Î Ãß°¡ÇÑ ¸â¹ö º¯¼öÀÇ Ãʱâȸ¦ CSampleCtrl ÀÇ constructor¡¡ ¡¡ ¿¡ Ãß°¡ÇÕ´Ï´Ù.
CSampleCtrl() : m_pSampleParam(0), m_IStreamSampleParam(0), m_bAbort(FALSE), m_hThread(0) {MyCallMethod (À»)¸¦ ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
STDMETHODIMP CSampleCtrl::MyCallMethod() { AFX_MANAGE_STATE(AfxGetStaticModuleState()) HRESULT hr; IStream* pStream; try { if (m_hThread) { // ÀÌÀü¿¡ ÅðÇÇÇÑ thread ÇÚµéÀÌ ³²¾Æ ÀÖÀ¸¸é »èÁ¦ÇÑ´Ù. CloseHandle(m_hThread); m_hThread = 0; } // // Á¢¼Ó ÀÎÅÍÆäÀ̽º¸¦ ¸¶¼£¸µ ÇØ ,m_IStreamDispatchArray ¿¡ °Ý³³ÇÑ´Ù. // m_IStreamDispatchArray.RemoveAll(); CProxy_ISampleCtrlEvents<CSampleCtrl>* pT = static_cast<CProxy_ISampleCtrlEvents<CSampleCtrl>*>(this); int nConnectionIndex; int nConnections = pT->m_vec.GetSize(); // Á¢¼Ó ÀÎÅÍÆäÀ̽º¸¦ ¸ðµÎ ÃëµæÇØ , ¸¶¼£¸µ ÈÄ , ¹è¿¿¡ °Ý³³ÇÑ´Ù. for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) { Lock(); CComPtr<IUnknown> sp = pT->m_vec.GetAt(nConnectionIndex); Unlock(); IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p); if (pDispatch != NULL) { // ÃëµæÇß´Ù IDispatch ¸¦ IStream ¿¡ º¯È¯ÇØ °Ý³³ÇÑ´Ù. pStream = 0; hr = CoMarshalInterThreadInterfaceInStream(IID_IDispatch, pDispatch, (IStream**) &pStream); if (FAILED(hr)) { TRACE("FAILURE: CSampleCtrl::MyCallMethod() - CoMarshalInterThreadInterfaceInStream(): IID_IDispatch\n"); } else { ASSERT(pStream); m_IStreamDispatchArray.Add(pStream); } } } // // ISampleParam ÀÎÅÍÆäÀ̽º¸¦ ¸¶¼£¸µ ÇØ , °Ý³³ÇÑ´Ù. // m_IStreamSampleParam = 0; if (m_pSampleParam) { // ¸¶¼£¸µ ÇØ °Ý³³ÇÑ´Ù. pStream = 0; hr = CoMarshalInterThreadInterfaceInStream(IID_ISampleParam, m_pSampleParam, (IStream**) &pStream); if (FAILED(hr)) { TRACE("FAILURE: CSampleCtrl::MyCallMethod() - CoMarshalInterThreadInterfaceInStream(): IID_ISampleParam\n"); } else { ASSERT(pStream); m_IStreamSampleParam = pStream; } } // // thread¸¦ ÀÛ¼ºÇØ , °³½ÃÇÑ´Ù. // // thread¸¦ ÀÛ¼ºÇÑ´Ù. CWinThread* pThread = AfxBeginThread( TestThread, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, 0); if (!pThread) { return Error(_T("thread¸¦ ÀÛ¼ºÇÒ ¼ö ¾ø¾ú½À´Ï´Ù. ")); } // thread Á¾·á ¸¸³ °Í , thread ÇÚµéÀ» º¹Á¦ÇÑ´Ù. DuplicateHandle( GetCurrentProcess(), // ¿ø ÇÁ·Î¼¼½º pThread->m_hThread, // ¿À¸®Áö³¯ ÇÚµé GetCurrentProcess(), // ó ÇÁ·Î¼¼½º &m_hThread, // º¹Á¦ÇÑ ÇÚµéÀÌ Ä«ÇǵǴ 0, // ¾×¼¼½º±Ç(¹«½ÃµÇ´Â) FALSE, // °è½ÂÇÏÁö ¾Ê´Â DUPLICATE_SAME_ACCESS // º¹Á¦Ã³ ÇÚµéÀº , º¹Á¦¿ø ÇÚµé°ú °°Àº ¾×¼¼½º±ÇÀ» °¡Áø´Ù ); m_bAbort = FALSE; // thread¸¦ °³½ÃÇÑ´Ù. pThread->ResumeThread(); } catch (CException* e) { e->Delete(); return Error(_T("Ä¡¸íÀûÀÎ ¿¡·¯°¡ ¹ß»ýÇß½À´Ï´Ù. ")); } return S_OK; }¿À¹ö¶óÀ̵å(override) ÇÑ FinalRelease() ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
void FinalRelease() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // threadÀÇ Á¾·á »óÅ ¸¸³ª°í ¿ë¹«ÀÇ // º¹Á¦µÈ thread ÇÚµéÀÌ ÀÖÀ¸¸é , // ¸¸³ª°í¸¦ ½Ç½ÃÇÑ µÚ , »èÁ¦ÇÑ´Ù. try { m_bAbort = TRUE; if (m_hThread) { // NOTE: ŸÀÓ ¾Æ¿ôÀ» INFINITE ·Î ÇÏ´Â ¿ë±â°¡ ¾ø±â ¶§¹®¿¡ , // Àû´çÇÑ ½Ã°£À» ¼³Á¤ÇØ ÀÖ´Ù. WaitForSingleObject(m_hThread, 10000); CloseHandle(m_hThread); } } catch (CException* e) { e->Delete(); } // À̺¥Æ® ÅëÁö¿¡ »ç¿ëÇÏ´Â ÀÎÅÍÆäÀ̽º¸¦ ÇعæÇÑ´Ù. if (m_pSampleParam) { m_pSampleParam->Release(); } }¸¶Áö¸·¿¡ TestThread() ¸¦ ÀÌÇÏ¿Í °°ÀÌ ÆíÁýÇÕ´Ï´Ù.
UINT CSampleCtrl::TestThread(VOID *pParam) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // COM ¶óÀ̺귯¸®¸¦ ÃʱâÈÇØ , »õ·Î¿î ¾ÆÆÄÆ®¸ÕÆ®½º·¿µå¿¡ µé¾î°£´Ù. if (FAILED(CoInitialize(0))) { return 1; } // Ŭ·¡½º ÀνºÅϽº¿¡ÀÇ Æ÷ÀÎÅ͸¦ ²¨³½´Ù. CSampleCtrl* pSampleCtrl = (CSampleCtrl*) pParam; if (!pSampleCtrl) { return 1; } // ½Ã°£ÀÌ °É¸®´Â 󸮸¦ ÇÑ´Ù. for (int i = 0; i < 10; ++i) { if (pSampleCtrl->m_bAbort) { break; } Sleep(1000); } if (!pSampleCtrl->m_bAbort) { // ÄÁÅ×ÀÌ³Ê Á¾·á½Ã ÀÌ¿Ü´Â ÅëÁöÇÑ´Ù. HRESULT hr; IStream* pStream; int i; // // ÄÁÅ×À̳ʿ¡ À̺¥Æ® ÅëÁöÇÑ´Ù. // // ¾È ¸¶¼£¸µ ÈÄÀÇ Á¢¼Ó Æ÷ÀÎÆ®¸¦ °Ý³³ÇÑ´Ù. CArray<IDispatch*, IDispatch*> dispatchArray; // ¾È ¸¶¼£¸µ ÈÄÀÇ ISampleParam ÀÎÅÍÆäÀ̽º¸¦ °Ý³³ÇÑ´Ù. ISampleParam* pSampleParam = 0; // // Á¢¼Ó ÀÎÅÍÆäÀ̽º¸¦ ¾È ¸¶¼£¸µ ÇØ ¹è¿¿¡ °Ý³³ÇÑ´Ù. // for (i = 0; i < pSampleCtrl->m_IStreamDispatchArray.GetSize(); ++i) { pStream = pSampleCtrl->m_IStreamDispatchArray[i]; IDispatch* pDispatch = 0; hr = CoGetInterfaceAndReleaseStream(pStream, IID_IDispatch, (void**) &pDispatch); if (FAILED(hr)) { TRACE("FAILURE: CSampleCtrl::TestThread() - CoGetInterfaceAndReleaseStream(): IID_IDispatch\n"); } else { ASSERT(pDispatch); dispatchArray.Add(pDispatch); } } // // ISampleParam ÀÎÅÍÆäÀ̽º¸¦ ¾È ¸¶¼£¸µ ÇØ , °Ý³³ÇÑ´Ù. // pSampleParam = 0; pStream = pSampleCtrl->m_IStreamSampleParam; hr = CoGetInterfaceAndReleaseStream(pStream, IID_ISampleParam, (void**) &pSampleParam); if (FAILED(hr)) { TRACE("FAILURE: CSampleCtrl::TestThread() - CoGetInterfaceAndReleaseStream(): IID_IResultEndPrint\n"); } else { ASSERT(pSampleParam); } // ISampleParam ÀÎÅÍÆäÀ̽º¿¡ °ªÀ» ¼³Á¤ÇØ À̺¥Æ®¸¦ ¹ß»ýÇÑ´Ù. if (pSampleParam) { CComVariant varResult; CString msg = _T("Çï·Î"); pSampleParam->put_Msg(msg.AllocSysString()); CComVariant* pvars = new CComVariant[1]; for (i = 0; i < dispatchArray.GetSize(); ++i) { VariantClear(&varResult); IDispatch* pDispatch = dispatchArray[i]; pvars[0] = pSampleParam; DISPPARAMS disp = { pvars, NULL, 1, 0 }; pDispatch->Invoke(0x1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, &varResult, NULL, NULL); } delete[] pvars; // varResult.scode ÀÇ °ªÀº ¹ö¸°´Ù. } } // COM ¶óÀ̺귯¸®¸¦ ÇعæÇÑ´Ù. CoUninitialize(); return 0; }ÄÁÅ×ÀÌ³Ê Á¾·á½Ã¿¡ ÅëÁöÇÏÁö ¾Ê°Ô ÇÏ°í ÀÖ´Â °ÍÀº , ŸÀֿ̹¡ µû¶ó¼´Â , Ä£ÃøÀÇ ÀνºÅϽº°¡ ¼Ò¸êÇÏ°í ÀÖÀ» °¡´É¼ºÀÌ ÀÖ¾î , ÅëÁö¸¦ ½Ç½ÃÇÏ´Â °Í¿¡ ÀÇÇØ ¾×¼¼½º À§¹ÝÀÌ ÀϾ±â (À§ÇØ)¶§¹®ÀÔ´Ï´Ù.