COM 컴포넌트를만드는방법은다양하다. 사람이라는것이간사해서한번맛들인방법을끝까지고집하게된다. 그래서 ATL을사용해본사람은절대다른방법으로하려고하지않는다. 하지만, ATL은 COM을완벽하게지원하지않는다는걸알아야한다. 그렇다고 ATL에서지원하는것이상만들자신도없지만말이다. 그래

Similar documents
No Slide Title

그리고 난절대 COM과관련된프로그래밍을하지않아 라고장담하는사람들조차도자신도모르게사용하고있다는것을알고있는지모르겠다. 쉘이바로그대표적인예이다. 단축아이콘을만들고, 아이콘트레이를사용하고하는것에서실제코딩에는 COM과관련된부분이없을지라도내부적으로 COM을사용한다는것을말이다. 바

K&R2 Reference Manual 번역본

Dialog Box 실행파일을 Web에 포함시키는 방법

ISP and CodeVisionAVR C Compiler.hwp

<4D F736F F F696E74202D B3E22032C7D0B1E220C0A9B5B5BFECB0D4C0D3C7C1B7CEB1D7B7A1B9D620C1A638B0AD202D20C7C1B7B9C0D320BCD3B5B5C0C720C1B6C0FD>

Microsoft PowerPoint - chap01-C언어개요.pptx

12 강. 문자출력 Direct3D 에서는문자를출력하기위해서 LPD3DXFONT 객체를사용한다 LPD3DXFONT 객체생성과초기화 LPD3DXFONT 객체를생성하고초기화하는함수로 D3DXCreateFont() 가있다. HRESULT D3DXCreateFont

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

Microsoft Word - ntasFrameBuilderInstallGuide2.5.doc

슬라이드 1

슬라이드 1

JUNIT 실습및발표

슬라이드 1

초보자를 위한 C# 21일 완성

PowerPoint 프레젠테이션

1. 자바프로그램기초 및개발환경 2 장 & 3 장. 자바개발도구 충남대학교 컴퓨터공학과

변수윤.PDF

chap10.PDF

Chapter_02-3_NativeApp

제8장 자바 GUI 프로그래밍 II

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

Microsoft PowerPoint - 09network.ppt

PowerPoint 프레젠테이션

Microsoft PowerPoint - Java7.pptx

MPLAB C18 C

Microsoft PowerPoint - C++ 5 .pptx

JVM 메모리구조

Data Sync Manager(DSM) Example Guide Data Sync Manager (DSM) Example Guide DSM Copyright 2003 Ari System, Inc. All Rights reserved. Data Sync Manager

Spring Boot/JDBC JdbcTemplate/CRUD 예제

UI TASK & KEY EVENT

<4D F736F F F696E74202D20C1A63034B0AD202D20C7C1B7B9C0D3B8AEBDBAB3CABFCD20B9ABB9F6C6DBC0D4B7C2>

(Microsoft PowerPoint - \301\24613\260\255 - oFusion \276\300 \261\270\274\272)

슬라이드 1

자그럼마이크로소프트에서말하는 COM은무엇인가? 답은이렇다. 오브젝트와시스템이개방적이고변화가능한방식으로상호동작할수있는방법을정의하는다수의기술에대한바이너리사양이다. 오 ~ 훌륭한정의가아닌가? 우리의마이크로소프트에서 COM을정의해주셨다. 그것도정확하게말이다. 이글을읽자마자바로

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

윤성우의 열혈 TCP/IP 소켓 프로그래밍

Microsoft PowerPoint Android-SDK설치.HelloAndroid(1.0h).pptx

<4D F736F F F696E74202D20C1A63139C0E520B9E8C4A120B0FCB8AEC0DA28B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

Microsoft PowerPoint - 08-C-App-19-Quick-Preprocessor

bn2019_2

ThisJava ..

Convenience Timetable Design

슬라이드 1

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

Microsoft Word - Armjtag_문서1.doc

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

8 장데이터베이스 8.1 기본개념 - 데이터베이스 : 데이터를조직적으로구조화한집합 (cf. 엑셀파일 ) - 테이블 : 데이터의기록형식 (cf. 엑셀시트의첫줄 ) - 필드 : 같은종류의데이터 (cf. 엑셀시트의각칸 ) - 레코드 : 데이터내용 (cf. 엑셀시트의한줄 )

10 장세균전프로그래밍 10.1 게임룰 (1) 사람과컴퓨터가싸우는 2인용보드게임이다. (2) 사람이먼저움직이고, 컴퓨터가움직인다. (3) 세균을가로및세로방향으로 2칸까지빈칸으로이동시킬수있다. (4) 1칸을이동할경우에는복제가된다. (5) 이동한후주변세균은내편으로바뀐다.

BMP 파일 처리

Chapter #01 Subject

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

Microsoft Word - Modelsim_QuartusII타이밍시뮬레이션.doc

Microsoft PowerPoint - es-arduino-lecture-03

Microsoft PowerPoint - chap12-고급기능.pptx

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

Microsoft PowerPoint - 04-UDP Programming.ppt

쉽게 풀어쓴 C 프로그래밍

PowerPoint 프레젠테이션

슬라이드 1

Slide 1

PowerPoint 프레젠테이션

PowerPoint Presentation

tr02.doc

02 C h a p t e r Java

The C++ Programming Language 4 장타입과선언 4.11 연습문제 Hello,world! 프로그램을실행시킨다. 프로그램이컴파일되지않으면 B3.1 을참고하자. #include<iostream> //#include 문, 헤더파일, 전처리지시

03_queue

C프로-3장c03逞풚

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호

슬라이드 1

PowerPoint 프레젠테이션

Microsoft PowerPoint - chap10-함수의활용.pptx

슬라이드 1

Microsoft Word - src.doc

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

학습목표 함수프로시저, 서브프로시저의의미를안다. 매개변수전달방식을학습한다. 함수를이용한프로그래밍한다. 2

<B9CCB5F0BEEE20C1A4BAB8C3B3B8AE2E687770>

Microsoft PowerPoint _Monthly InsighT 19년 1월.pptx

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

어댑터뷰

var answer = confirm(" 확인이나취소를누르세요."); // 확인창은사용자의의사를묻는데사용합니다. if(answer == true){ document.write(" 확인을눌렀습니다."); else { document.write(" 취소를눌렀습니다.");

Microsoft Word - windows server 2003 수동설치_non pro support_.doc

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

PowerPoint 프레젠테이션

Network Programming

슬라이드 1

중간고사

09-interface.key

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

Interstage5 SOAP서비스 설정 가이드

슬라이드 1

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

윈도우시스템프로그래밍

vi 사용법

DLL(Dynamic Linked Library)

Microsoft PowerPoint - Chapter 6.ppt

Microsoft PowerPoint - MonthlyInsighT-2018_9월%20v1[1]

Transcription:

나의 COM(Component Object Model) 경험담 #5 드디어다섯번째까지왔습니다. 얻으신것이있었나요? 없었다구요? ㅜㅜ ;; 어쨌든그건상관없습니다. 이번은내용이좀깁니다. 그렇다고할게많은것은아닙니다. 자세한건나중에뒤에보시면아실테고. 생각보다많은분들이좋아해주셨습니다. 기분이좋았습니다. 잠시개인적인얘기를하려고합니다. 저의일과는이렇습니다. 회사퇴근해서밥먹고 인어아가씨 본다음 ( 이거정말재미있습니다. 요즘은이거보는낙으로살죠 ^^) 바로 9시뉴스보면서세상이어떻게돌아가나봅니다. 그리고요며칠 (4일동안인가봅니다.) 이글쓰느라보통 3 ~ 4시간보내고새벽 1시나 3시쯤에글데브피아에올린다음잡니다. 그래서비몽사몽간에글을씁니다. 따라서주절주절앞뒤안맞는얘기도많았을겁니다. 하루를쉬니머리가조금은맑아졌습니다. 그래도앞뒤가잘안맞을겁니다.( 원래이렇습니다. 비몽사몽어쩌고는다핑계입니다. ^^) 오늘은시간이꽤걸릴것같습니다. 잠못잘지도모릅니다. 회사에서요즘밤에뭐하느냐고의심의눈초리로째려봅니다. [ ㅡㅡ ] 잡담그만하고빨리하라구요? 넵! 알겠습니다. 그럼시작하겠습니다. 오늘설명하지않겠다. 설명은 #6 에서본격적으로하겠다. 오늘은그냥흐름을파악하면된다. 그냥이렇게만들면되는구나라고생각만하면될듯 싶다. ( 중간에설명이없더라도섭섭하게생각하지마라.)

COM 컴포넌트를만드는방법은다양하다. 사람이라는것이간사해서한번맛들인방법을끝까지고집하게된다. 그래서 ATL을사용해본사람은절대다른방법으로하려고하지않는다. 하지만, ATL은 COM을완벽하게지원하지않는다는걸알아야한다. 그렇다고 ATL에서지원하는것이상만들자신도없지만말이다. 그래도기분나쁘잖아 ~~. 있어보이는척하는거빼면시체인난데.. 그럴순없쥐 ~. 오늘여러분은개념이해하느라머리쥐어뜯을일이없다. 그냥아무생각없이따라하기만하면된다. 그럼 COM 서버한번만들어보자. ( 서버란말이나오니, 왠지서버프로그래머가된것같다. ^^) 먼저오늘만들놈에대해서미리어떤일을하는놈인지알고들어가면쉬울것이다. 이번에만들 COM 컴포넌트가하는일은두숫자를입력받아서더한결과를돌려준다. 간단하다. 더이상말이필요없다. 대부분의 COM 예제들이이런걸로알고있다. 그리고먼저밝혀둘것이있다. 이소스는 codeguru 사이트의 COM 란에서가져온소스를내나름대로조금편집한소스이다. 모든기능을죽이고우리나라정서 (?) 에맞게조금수정했다. ( 아무래도내가만들면사람들이믿지않을것같다.) 그럼시작해보자. 먼저새프로젝트를열자. 아주친숙한화면이나타났다. COM 을만든다고 ATL COM AppWizard 를선택하면안된다. Win32 DLL 을선택하고프로젝트명을넣자. 다끝났다면 OK 버튼을누른다.

An empty DLL project를선택하고 Finish 버튼을누른다. 자기본적인준비는끝났다. 그리고이제.idl 파일이필요하다. 인터페이스를정의하는파일이다. 그러려면 GUID도하나필요하다. GUID를쉽게만드는방법이있다. 실행에서다음과같이명령어를입력해보자.

그럼다음과같은창이하나뜬다. 말그대로 GUID 를랜덤하게계속만들수있다. 여기서하나를만들어서 Copy 버튼을누른다. 그리고소스에서 GUID 가필요한부분에서 Paste 하면나타난다. 새파일을하나열고다음과같이타이핑한다. 아니다. Copy & Paste 하면되겠다. import "unknwn.idl"; [ uuid(12d90058 C2A5 4950 8355 1DC0189FFD0D), helpstring(" 여기에필요한설명을적는다.") ] interface IAdd : IUnknown HRESULT SetFirstNum(long nfirst); HRESULT SetSecondNum(long nsecond); HRESULT GetSum([out, retval] long *pbuffer);

[ uuid(9d807a19 9A1A 4879 A7C0 6D3AFD04F7B8), helpstring(" 라이브러리에대한설명을적는다.") ] library AddComObjLib importlib("stdole32.tlb"); importlib("stdole2.tlb"); interface IAdd; 여기서잠시 IDL이뭔지알아보자. IDL(Interface Definition Language) 해석하면인터페이스정의언어란말이다. 일반적으로인터페이스는 C++ 언어로표현이가능했다. 즉, 순수가상함수로만들수도있다. 하지만, IDL 로만드는것이여러모로노가다작업을줄일수있다. 그리고그렇게어렵지도않다. 이언어는 MIDL(Microsoft Interface Definition Language) 컴파일러로컴파일할수있다. 도스창에서 midl IAdd.idl 이렇게실행하면컴파일된다. 여기서여러가지부산물들을얻을수있다. 우리가사용할수있는헤더파일도만들어준다. 그리고가장중요한것은나중에설명하겠지만, Proxy 와 Stub 코드를만들어준다는것이다. 그리고또한가지타입라이브러리를만들어준다는것이다. 대충이렇게알고넘어가자. 이부분도하루종일해야하는부분들이다. 이쪽을파다가는오늘실습은그냥포기해야한다.

그럼다시노가다작업으로들어가자. IAdd.idl 로파일이름을저장하고 Project 메뉴를사용해 서프로젝트에추가한다. 그럼다음과같이나타날것이다. Project 메뉴에서 Settings.. 메뉴를클릭한다. 다시거기서 Iadd.idl 파일을선택한다. 컴파일을먼저해보기위해서다.

Always use custom build step 를체크하고다음텝을선택한다. 위의그림과같이명령어를입력한다. 이과정이귀찮으면도스창에서직접 midl IAdd.idl 을직접입력해도상관없다. 결과는같은테니깐말이다.

그럼다음과같이같은폴더에 5 개의파일이덤으로생성된다. 그리고추가로 COM 컴포넌트를다만들고나서레지스트리에추가하는것도귀찮으니그것도설정을미리해버리자. 아래그림과같이프로젝트를선택하고마지막텝의 Post build step를선택하고명령어를입력한다. 그러면컴파일이끝나면알아서이명령어를실행시킨다.

그다음부터는아래의파일들을전부위의주석에나온파일이름대로다저장하자. 그리고다끝났다면 *.cpp 와 *.def 파일을프로젝트에추가한다. 자, 그럼지금부터노가다를좀해라. 나는노가다하는동안좀쉬어야겠다. 커피도고프고담배도고프다. 룰루랄라 ~ ~ ~ ~ ~ ~ ~

//////////////////////////////////////////////////////////////////// // AddComObj.h 파일 //////////////////////////////////////////////////////////////////// #include "IAdd.h" extern long g_ncomobjsinuse; class CAddComObj : public IAdd private: long m_nfirst, m_nsecond; //operands for addition long m_nrefcount; //for managing the reference count public: //IUnknown 인터페이스의메서드를구현한다. HRESULT stdcall QueryInterface(REFIID riid, void **ppobj); ULONG stdcall AddRef(); ULONG stdcall Release(); //IAdd 인터페이스의메서드들... HRESULT stdcall SetFirstNum( long nfirst); HRESULT stdcall SetSecondNum( long nsecond); HRESULT stdcall GetSum( long *pbuffer); CAddComObj() m_nrefcount=0; InterlockedIncrement(&g_nComObjsInUse); ; ~CAddComObj() InterlockedDecrement(&g_nComObjsInUse);

//////////////////////////////////////////////////////////////////// // AddComObj.cpp 파일 //////////////////////////////////////////////////////////////////// #include <objbase.h> #include "AddComObj.h" #include "IAdd_i.c" ///////////////////////////////////////////////////////////////////// // IAdd 인터페이스의메서드들을구현한다. // // SetFirstNum : 더할숫자들중첫번째수를지정한다. // SetSecondNum : 더할숫자들중두번째수를지정한다. // GetSum : 두숫자의합을얻어온다. ///////////////////////////////////////////////////////////////////// HRESULT stdcall CAddComObj::SetFirstNum(long nfirst) m_nfirst = nfirst; return S_OK; HRESULT stdcall CAddComObj::SetSecondNum(long nsecond) m_nsecond = nsecond; return S_OK; HRESULT stdcall CAddComObj::GetSum(long *pbuffer) *pbuffer = m_nfirst + m_nsecond; return S_OK; ///////////////////////////////////////////////////////////////////// // IUnknown 인터페이스의메서드들을구현한다. // 다음의 3개메서드가기본이쥐 ~~~~~ // AddRef()

// Release() // QueryInterface(REFIID riid, void **ppobj) ///////////////////////////////////////////////////////////////////// ULONG stdcall CAddComObj::AddRef() return InterlockedIncrement(&m_nRefCount); ULONG stdcall CAddComObj::Release() long nrefcount = 0; nrefcount = InterlockedDecrement(&m_nRefCount); // 참조카운트가없으면스스로해제한다. if (nrefcount == 0) delete this; return nrefcount; HRESULT stdcall CAddComObj::QueryInterface(REFIID riid, void **ppobj) if (riid == IID_IUnknown) *ppobj = static_cast<iadd*>(this); AddRef(); return S_OK; if (riid == IID_IAdd) *ppobj = static_cast<iadd*>(this); AddRef(); return S_OK;

*ppobj = NULL; return E_NOINTERFACE;

//////////////////////////////////////////////////////////////////// // AddComObjFactory.h 파일 //////////////////////////////////////////////////////////////////// extern long g_ncomobjsinuse; class CAddComObjFactory : public IClassFactory private: long m_nrefcount; public: CAddComObjFactory() m_nrefcount=0; InterlockedIncrement(&g_nComObjsInUse); ~CAddComObjFactory() InterlockedDecrement(&g_nComObjsInUse); // IUnknown 인터페이스의메서드들... HRESULT stdcall QueryInterface(REFIID riid, void **ppobj); ULONG stdcall AddRef(); ULONG stdcall Release(); ; // IClassFactory 인터페이스의메서드들... virtual HRESULT stdcall CreateInstance(IUnknown* punknownouter, const IID& iid, void** ppv) ; virtual HRESULT stdcall LockServer(BOOL block) ;

//////////////////////////////////////////////////////////////////// // AddComObjFactory.cpp 파일 //////////////////////////////////////////////////////////////////// #include <objbase.h> #include "AddComObjFactory.h" #include "AddComObj.h" ///////////////////////////////////////////////////////////////////// // IUnknown 인터페이스의메서드들을구현한다. // // AddRef // Release // QueryInterface ///////////////////////////////////////////////////////////////////// ULONG stdcall CAddComObjFactory::AddRef() return InterlockedIncrement(&m_nRefCount) ; ULONG stdcall CAddComObjFactory::Release() long nrefcount = 0; nrefcount = InterlockedDecrement(&m_nRefCount); if (nrefcount == 0) delete this; return nrefcount; HRESULT stdcall CAddComObjFactory::QueryInterface(const IID& iid, void** ppv) if ((iid == IID_IUnknown) (iid == IID_IClassFactory)) *ppv = static_cast<iclassfactory*>(this); else *ppv = NULL;

return E_NOINTERFACE; reinterpret_cast<iunknown*>(*ppv) >AddRef(); return S_OK; ///////////////////////////////////////////////////////////////////// // IClassFactory 인터페이스의메서드들을구현한다. // // LockServer // CreateInstance ///////////////////////////////////////////////////////////////////// HRESULT stdcall CAddComObjFactory::CreateInstance(IUnknown* punknownouter, const IID& iid, void** ppv) // Aggregation을사용하지않는다. if (punknownouter!= NULL) return CLASS_E_NOAGGREGATION; CAddComObj* pobject = new CAddComObj; if (pobject == NULL) return E_OUTOFMEMORY; return pobject >QueryInterface(iid, ppv); HRESULT stdcall CAddComObjFactory::LockServer(BOOL block) return E_NOTIMPL;

//////////////////////////////////////////////////////////////////// // AddComObjGuid.h 파일 //////////////////////////////////////////////////////////////////// #ifndef AddObjGuid_h #define AddObjGuid_h // // 4EE0DC95 64F3 4ad6 A1FC 191A9FAEA849 static const GUID CLSID_AddObject = 0x4ee0dc95, 0x64f3, 0x4ad6, 0xa1, 0xfc, 0x19, 0x1a, 0x9f, 0xae, 0xa8, 0x49 ; #endif

//////////////////////////////////////////////////////////////////// // Exports.cpp 파일 //////////////////////////////////////////////////////////////////// #include <objbase.h> #include "AddComObj.h" #include "AddComObjFactory.h" #include "AddComObjGuid.h" HMODULE g_hmodule = NULL; long g_ncomobjsinuse = 0; /////////////////////////////////////////////////////////////////////////////// // 여기가 DllMain 이다. // DLL_PROCESS_ATTACH : DLL이프로세스의주소영역에맵핑된다. /////////////////////////////////////////////////////////////////////////////// BOOL APIENTRY DllMain(HANDLE hmodule, DWORD dwreason, void* lpreserved) if (dwreason == DLL_PROCESS_ATTACH) g_hmodule = (HMODULE)hModule ; return TRUE ; /////////////////////////////////////////////////////////////////////////////// // COM 라이브러리의 CoGetClassObject 함수에서 DLL의 DllGetClassObject함수를호출하고, // 이함수에서실제로클래스팩토리 COM 개체를생성하게된다. /////////////////////////////////////////////////////////////////////////////// STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void** ppv) if (clsid == CLSID_AddObject) // CAddComObjFactory 를생성한다. CAddComObjFactory *paddfact = new CAddComObjFactory;

if (paddfact == NULL) return E_OUTOFMEMORY; else return paddfact >QueryInterface(iid, ppv); return CLASS_E_CLASSNOTAVAILABLE; /////////////////////////////////////////////////////////////////////////////// // COM 라이브러리의 CoFreeUnusedLibraries 함수는 DLL의 DllCanUnloadNow 함수를호출한다. // 즉, DLL을해제시켜도좋은지물어본다. /////////////////////////////////////////////////////////////////////////////// STDAPI DllCanUnloadNow() if (g_ncomobjsinuse == 0) return S_OK; else return S_FALSE; ;Experts.def 파일이다.

DESCRIPTION "Simple COM object" EXPORTS DllGetClassObject DllCanUnloadNow DllRegisterServer DllUnregisterServer PRIVATE PRIVATE PRIVATE PRIVATE ////////////////////////////////////////////////////////////////////

// Registry.h 파일 //////////////////////////////////////////////////////////////////// #ifndef Registry_H #define Registry_H HRESULT RegisterServer(HMODULE hmodule, const CLSID& clsid, const char* szfriendlyname, const char* szverindprogid, const char* szprogid) ; HRESULT UnregisterServer(const CLSID& clsid, const char* szverindprogid, const char* szprogid) ; #endif ////////////////////////////////////////////////////////////////////

// Registry.cpp 파일 //////////////////////////////////////////////////////////////////// #include <windows.h> #include <objbase.h> #include "AddComObjGuid.h" #define AddObjProgId "IcoddyLib.Sum" extern HMODULE g_hmodule; BOOL HelperWriteKey(HKEY roothk, const char *lpsubkey, LPCTSTR val_name, DWORD dwtype, void *lpvdata, DWORD dwdatasize) HKEY hk; if (ERROR_SUCCESS!= RegCreateKey(roothk,lpSubKey,&hk) ) return FALSE; if (ERROR_SUCCESS!= RegSetValueEx(hk,val_name,0,dwType,(CONST BYTE *)lpvdata,dwdatasize)) return FALSE; if (ERROR_SUCCESS!= RegCloseKey(hk)) return FALSE; return TRUE; // COM 개체를시스템레지스트리에등록할때 Regsvr32.exe 에의해호출된다. HRESULT stdcall DllRegisterServer(void) WCHAR *lpwszclsid; char szbuff[max_path]=""; char szclsid[max_path]="", szinproc[max_path]="",szprogid[max_path]; char szdescriptionval[256]=""; StringFromCLSID(CLSID_AddObject, &lpwszclsid);

wsprintf(szclsid,"%s",lpwszclsid); wsprintf(szinproc,"%s\\%s\\%s","clsid",szclsid,"inprocserver32"); wsprintf(szprogid,"%s\\%s\\%s","clsid",szclsid,"progid"); wsprintf(szbuff,"%s","icoddy's sum"); wsprintf(szdescriptionval,"%s\\%s","clsid",szclsid); HelperWriteKey (HKEY_CLASSES_ROOT, szdescriptionval, NULL, REG_SZ, (void*)szbuff, lstrlen(szbuff)); GetModuleFileName(g_hModule, szbuff, sizeof(szbuff)); HelperWriteKey (HKEY_CLASSES_ROOT, szinproc, NULL, REG_SZ, (void*)szbuff, lstrlen(szbuff)); lstrcpy(szbuff,addobjprogid); HelperWriteKey (HKEY_CLASSES_ROOT, szprogid, NULL, REG_SZ, (void*)szbuff, lstrlen(szbuff)); wsprintf(szbuff,"%s","icoddy's sum"); HelperWriteKey (HKEY_CLASSES_ROOT, AddObjProgId, NULL, REG_SZ, (void*)szbuff, lstrlen(szbuff)); wsprintf(szprogid,"%s\\%s",addobjprogid,"clsid"); HelperWriteKey (HKEY_CLASSES_ROOT, szprogid, NULL, REG_SZ, (void*)szclsid, lstrlen(szclsid)); return 1; // COM 개체를시스템레지스트리에등록할때 Regsvr32.exe 에의해호출된다. HRESULT stdcall DllUnregisterServer(void)

char szkeyname[256]="",szclsid[256]=""; WCHAR *lpwszclsid; wsprintf(szkeyname,"%s\\%s",addobjprogid,"clsid"); RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName); RegDeleteKey(HKEY_CLASSES_ROOT,AddObjProgId); StringFromCLSID(CLSID_AddObject, &lpwszclsid); wsprintf(szclsid,"%s",lpwszclsid); wsprintf(szkeyname,"%s\\%s\\%s","clsid",szclsid,"inprocserver32"); RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName); wsprintf(szkeyname,"%s\\%s\\%s","clsid",szclsid,"progid"); RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName); wsprintf(szkeyname,"%s\\%s","clsid",szclsid); RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName); return 1; 여기가끝이다. 마지막으로컴파일을해보자. 이렇게나오면성공한거다. 진심으로축하한다. 드뎌 COM 컴포넌트를만든것이다. 그럼이제클라이언트프로그램을만들어서실제로잘동작하는지확인해야한다. 내가

이수고를덜겠다. 해보니깐잘된다. 밑에그림보이쥐? 그럼됐다. 저거조작한거아냐? 라 고의심하는사람은잘봐라. 결과가읽기속성으로되어있다. 그래도조작한거라고? 우쒸 ~ 그래조작했다. 어쩔건데? 여긴할게별로없으니소스나한번훑어보고지나가라. 결과보기버튼을누르면결과가나온다. void CAddComClientDlg::OnButtonSum() // TODO: Add your control notification handler code here UpdateData(TRUE); HRESULT hr; hr = CoInitialize(NULL); if(failed(hr)) AfxMessageBox("COM 라이브러리를초기화하지못했습니다."); SendMessage(WM_CLOSE); IcoddyLib::IAddPtr picoddylib; picoddylib.createinstance("icoddylib.sum"); picoddylib >SetFirstNum(m_nFirst); picoddylib >SetSecondNum(m_nSecond); m_nsum = picoddylib >GetSum(); UpdateData(FALSE); 오늘은따로설명을하지않겠다. 오늘이것을나에게요구한다면나그만둘거다. 협박하

는거다. 절대강요하지마라. 기분나쁘면언제든지그만둔다. 내맘이다.( 헛 ~~ 또돌날라 오넹 ) 자, 여러분들너무지쳤을것이다. 설명은다음경험담 #6 에서본격적으로하겠다. 열심히깊이팔준비를하고오면고맙겠다. 오늘의핵심은이과정을기억하라는것이다. 소스는나중일이다. 이과정만알면다음에 언제든지소스참조하면서만들면된다. 헐 ~~~ 날다샜다. 대충예상은했었지만, 정말이렇게될줄이야. TV 좀보다가씻고출근해야한다. 밥은뭐해먹지? 음.. 즉석미역국이있었네. 그거해먹어야겠다. 800원인데두개들어있다. 즉, 한개 400원꼴이니, 정말싸고맛있게먹는거다. 여러분도라면으로끼니떼우지말고이런거사먹어라. 이건 3분도안걸린다. 몸에도좋다. 아침먹는사람이그렇지않은사람보다수명이 10년이더길다고한다. 진짜다. 믿어라.( 사실은, 나도귀찮아서일주일에한번도아침못먹는다.) 그럼날밤새도끄떡없는건강한 (?) 프로그래머세계를꿈꾸며이만끝내야겠다. e mail : icoddy@hotmail.com msn id : icoddy@hotmail.com 박성규