오전 5:37 99-12-18 조경민 ( bro@shinbiro.com)
AUTOMATION 자동화
========================================================
' 자동화 예 : Excel. 비베에서 엑셀 객체 애플리케이션을
쓰면 서버 애플리케이션인 엑셀이 뜨게 된다. -

자동화는 OLE에서 쓰이는 말로 어떤 애플리케이션이 제공하는
서버 객체를 다른 클라이언트에 붙일수 있다는 것으로,
풀어서 본다면 OOP의 재사용성 및 캡슐화를 의미하는것이다.
즉, 서버 애플리케이션이( OLE 서버) 쓰이는 클라이언트에서
자동화되어 처리된다는 것이다.

Automation Client - 서버에 속한 노출된 인터페이스를 생성
해 낼수 있는( 그것을 사용할수 있는) 애플리케이션을 의미한다.
다른 말로는 Automation Controller라고 한다.

Automation Server - 다른 애플리케이션이 쓸수 있게 객체를
노출시킨 애플리케이션으로 Automation Component라고 한다.

애플리케이션 서버는 객체들을 노출시킨다. 이 객체들은 메소드와
프라퍼티를 외부 인터페이스에 의해 갖는다.

파라미터를 넘겨주는 방식
자동화에선 VARIANT로 파라미터를 넘겨주게 된다.

자동화 서버 객체를 사용하는 클라이언트는 두가지 방법이 있을수 있다.

- 동적으로 클라이언트가 서버의 객체를 사용한다.
- static하게 컴파일타임시 서버의 객체를 얻어와 사용한다.

클라이언트는 서버의 메소드나 프라퍼티를 얻어오기 위해서
OLE 시스템의 IDispatch 메커니즘으로 Query함으로써 얻어낼수
있다.
그러나 만일 static하게 서버객체를 사용하게 된다면 IDispatch
를 쓰지 않고 MFC에서 제공하는 COleDispatchDriver라는 것을
사용하면 됀다. ( 클래스 위자드로 부터 제공 받게 된다. )
이 static bound client는 프락시 클래스를 사용하게 되는데
이 클래스가 안전한 타입체킹된 서버의 메소드나 프로퍼티를
제공해 준다.

클라이언트가 자동화서버 객체를 갖고 프로젝팅 하기
AppWizard에서 MFC Dialog에서 두번째 스탭에 Automation 선택

그러면 기존 App,Dlg 이외에 IMy(나의 인터페이스),CMyProxy(내
프락시 클래스)가 생기는데 IMy는 서배 객체에 대한 인터페이스
이며, 프락시 클래스의 객체가 이미 Dlg안에 m_pMyProxy로 저장
되어 있는데 나는 단지 m_pMyProxy->Method()를 쓰면 된다.


AUTOMATION 서버 만들기 기초 처음 무작정 따라하기
서버 프로그램도 독자 프로그램이고 프로젝트안에 자동화객체도
만들고 그런다.
===========================================================

New/ MFC Dialog Base로 하나 만든다 이때 두번째 스탭을
Automation을 추가한다. 프로젝트명 Test
( 이를 함으로써 App::InitInstance()에서 OleInit()일 일어난다.
또한 COleTemplateServer::RegisterAll()등 자동화 서버의
초기화등을 한다 )

이렇게 하면 일딴 CTestDlgProxy클래스와 ITest가 생기게 된다.

Automation Class 추가하기
--------------------------
클래스 위자드에서 New Class후 베이스 클래스를 My로 정한다.
그리고 아래에 Type ID로 선택하고 OK를 누룬다.

그러면 disinterface IMy (Test.odl 안에서 )와 이를 구현하는
My.cpp와 My.h가 생성된다. ( 이때 My클래스가 프락시 클래스이다. )

Property와 Method 인터페이스에 추가하기
---------------------------------------
클래스 위자드에서 Automation탭에서 하면 된다.
( 또는 클래스 뷰에서 IMy에서 오른 클릭후 Add Method나 Add Propery
하면 된다. )

Automation Interface 사용하기
------------------------------
Dlg.h에다가 사용하려는 자동화 프락시 클래스의 포인터 맴버자료를
하나 만든다. ( My* m_pAutoProxy2;);
그리고 버튼 클릭시 m_pAutoProxy2->Mothod(); 하면 알아서 인터페이
스를 얻어와서 호출하게 된다. ( IDispatch::Invoke()가 된다.)

컴파일하면 tlb가 나오게 된다.
-----------------------------
tlb 가 나오게 되면 이를 VB나 VC에서 다시 쓸수 있다.


방금전의 서버 객체로 실제 클라이언트를 구현하기
================================================
클라이언트 프로젝트를 하나 연다 역시 다이얼로그 베이스..
그리고 클래스 위자드에서 New Class를 From TypeLib로 한후
아까 만든 tlb를 선택하게되면 Test.h test.cpp가 포함되게
되는데 이 안에는 쓰려는 ITest와 IMy가 들어 있다.
( 이때 이들은 COleDispatchDriver를 상속 받게 되는데
모두 클래스 위자드가 알아서 해주는것임으로 몰라도 된다.
이것을 static bind라고 한다. 컴파일 타임시 어떤 객체를
쓸것인지 프로젝트안에 명시되어 있게 되므로)

dlg.h의 맴버 자료로 IMy m_Auto;를 하나 만들고
dlg의 WM_CREATE부분에서

if (!m_Auto.CreateDispatch(_T("Test.Application")))
{
        AfxMessageBox("Cant Dispatch");
        return -1;  // fail
}

를 해준다.

디스패치를 생성할때의 인자는 문자열인데 이는 생성하려는
서버 객체 애플리케이션의 ProgID이다.
( 이는 Test 아까 프로젝트내에서 Test.reg안에서 찾다보면
ProgID = "Test.Application"이라고 써있을 것이다.
그런데 -_-.. 서버 애플리케이션도 전의 다이얼로그 프로그램도
뜨게 된다 -.- )

그리고 이제는 마음대로 디스패치를 이용해서 IMy 인터페이스
안의 메소드와 프라퍼티를 쓸수 있다.
m_Auto.Method(); 가능하게 된다.

m_Auto.Method() 호출하면...
InvokeHelper() => COleDispatchDriver::Dispatch() =>
COleDispatchDriver::DispatchV() =>
COleDispatchDriver::lpDispatch->Invoke() =>
DispatchImp::Invoke() => CCmdTaget::CallMemberFunction() =>
_afxMemberFunctionCall() // 어셈 코드로 되어 있다.
   ........ ; vtable 찾아가기 맴버 함수 찾아내서
   call esx ; 이때 Method1이 호출된다.

'KB > MFC/Win32' 카테고리의 다른 글

UDP 소켓 다루기  (3) 2004.03.19
#pragma  (0) 2004.03.19
ATLCOM 객체에서 두번째 스레드에서 Fire하기 에러  (0) 2004.03.19
ATL COM 반환값 만들기  (0) 2004.03.19
ATL 객체포인터 참조하기  (0) 2004.03.19

+ Recent posts