COM, ATL

ATL_COM Event 사용 하기. COM

디버그정 2008. 8. 20. 05:35
ATL_COM Event 사용 하기. COM

사용자 삽입 이미지


화면 캡처: 2007-10-11, 오후 9:29


================ COM SERVER 만들기 ===========================

1. 프로젝트 생성 ALT COM .


2. 클래스를 만들때 클래스 오브젝트를 사용하여 만든다.

  - 속성에서 Connection Port 를 체크하여 이벤트를 지원하게 만든다.


3. 현재까지는 가상접근(VB,SCRIPT)을 위한 이벤트관련 코드가 생성되있다.

   이것을 직접접근가능한( C++ ) 이벤트 관련 코드도 추가한다.

// idl 파일에서 아래의 코드를 비슷한 코드 밑에 추가한다. 전부..

 [
  object,
  uuid(4A1B430E-FF18-4974-BC4B-30DFC1E33B08), // 각자 수정
  dual,
  helpstring("ITest Interface"),
  pointer_default(unique)
 ]
 interface ITestEvents : IDispatch // ITestEvent라는 Event 인터페이스를 생성한다.
 {
 };

// 기존의 이벤트 인터페이스는 _ITestEvent라고 되어있는데 스크립트 언어를 위한 인터페이스다.

// 우리는 _ITestEvent 라는 인터페이스에서 _언더바만 빼고 ITestEvent라고 생성한다.


위의 코드를 추가하고 나면 Class Wizerd 에 ITestEvent라는 인터페이스가 추가된것이 보인다.


4. 다시 idi 파일 맨 밑쪽에 아래 코드에서 빨간색 부분을 추가한다.

  coclass Test
 {
  [default] interface ITest;
  [default, source] dispinterface _ITestEvents;

 [source] interface ITestEvents;  // 이 코드 추가.

 // 우리가 3번에서 직접접근인터페이스를 추가했으므로 여기에서도 추가해야 됨....
 };


5. 저장하고 Clean 하고 Rebuild 한후 Class 위져드에서 우리가 만든 CoClass 에서 마우스 오른쪽 버튼을 눌러      Implement Connection Point 선택하면 창이 뜨는데 두개다 선택 후 OK 누르면 템플릿 클래스 2개가 생성됨.



 

사용자 삽입 이미지


6. CoClass 헤더파일에 상속받는 부분에

 class ATL_NO_VTABLE CTest :
 public CComObjectRootEx<CComSingleThreadModel>,
 public CComCoClass<CTest, &CLSID_Test>,
 public ISupportErrorInfo,
 public IConnectionPointContainerImpl<CTest>,
 public IDispatchImpl<ITest, &IID_ITest, &LIBID_CTESTLib>,
 public CProxy_ITestEvents< CTest >,
 public CProxyITestEvents< CTest > // 이놈이 추가 돼있다..
{


7. 각 인터페이스에( ITestEvents , _ITestEvents ) 에  foo 라는 메소드를 추가한다.

그냥 마우스로 오른쪽 버튼 눌러서 Add Method 으로 추가한다.

추가하면 idl 파일에 함수 코드가 추가됨.

8. 전부다 저장하고 Clean 하고 Rebuild 한 후 다시 5 번을 하면 템플릿 클래스(CTestCP.h) 에 저절로 7번에서 만든 메소드의 구현코드 가 들어간다.

  ( Fire_Foo() 라는 함수.. )

   각 인터페이스에 메소드를 만들때마다 현재 과정을 되풀이한다......

 

*. CoClass 에 함수를 추가할때는 CoClass안에있는 인터페이스에서 마우스 오른쪽을

눌러스 Add Method 로 만든다.

* 이벤트 발생 시키기 : 아래 와 같이 만든 함수를 직접 호출 하면 이벤트가 발생됨.

   CProxyITestEvents<CTest>::Fire_Foo(100);
   CProxy_ITestEvents<CTest>::Fire_Foo(100);

-> Client 의 raw_Foo함수가 자동실행되며 매개별수로 100 이 들어온다.

이렇게 하면 COM DLL 은 완성인가???



  - 컴파일 해보면 오류가 6개날 수 도있는데 그 오류를 보면

CONNECTION_POINT_ENTRY(IID__ITestEvents) 이 부분인데 이 부분을 아래 처럼 수정한다.

CONNECTION_POINT_ENTRY(DIID__ITestEvents)



 

========================== 클라이언트 프로그램 =========================

1. 다이얼로그 베이스 MFC 생성

2. StdAfx.h 에 아래 코드 추가

#import "..\CTest\CTest.tlb" no_namespace named_guids // 만든 DLL tib 임폴트
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>

3. StdAfx.cpp 에 아래 코드 추가


#include <atlimpl.cpp>

4. App 클래스 Cpp 파일에 아래 코드 추가


CUseTestApp theApp; // 이 녀석 밑에
CComModule _Module; // 이놈추가

 

5. App클래스의 InitInstance() 함수 에 아래 코드 추가

BOOL CCTestUsingApp::InitInstance()
{
 AfxEnableControlContainer();

 // Standard initialization
 // If you are not using these features and wish to reduce the size
 //  of your final executable, you should remove from the following
 //  the specific initialization routines you do not need.
 _Module.Init(NULL,NULL);  //추가
 AfxOleInit();                    //추가

....

맨 밑에

_Module.Term();                  //추가

return FALSE;

 

5,5 Dlg 클래스에 사용  IxxxPtr m_pSocket; 포인터 변수 선언

     초기화 부분에  m_pSocket = ISocketPtr(__uuidof(Socket)); 이런식으로 객체 생성


6. EventHandler.h 와 EventHandler.cpp 파일 작성

- PPT 30쪽에서 32쪽 보고 제작



7. Shink Object 생성

- PPT 33 ~ 35 보고 작성.


* 혹시 C4259 등 오류 2개 경고2개 이런류의 오류가 나면 EventHadnler.h 에서나 cpp 에서

함수를 정의하고 구현할때 함수명 앞에 raw_ 를 안붙여서 나는 에러이다.