유용한 정보

[VC++] ActiveX Component 제작 방법

DevReff 2024. 12. 26. 21:24




728x90
반응형

 

1. 제작 목적

ActiveX Component를 제작하는 목적은 Woindows 계열 운영체제에서 GUI Flash, IE(Internet Explorer)에서 전등과 가스벨브를 제어하는 것이다.ActiveX Component Home Network 단말기용 프로그램 개발 툴로 사용된 VC++에서 직접 기기를 제어하던 것을 Flash 또는 IE에서 직접 기기를 제어할 수 있게 해 준다. , VC++과 연동하지 않고 Flash IE 내에서 기기를 제어할 수 있게 된다.

 

2. 제작 방법

A. 개발 환경

(ㄱ) OS : Windows XP + Service Pack 1

(ㄴ) Tool : Visual Studio 6.0 (VC++) , MFC

 

B. 프로젝트 생성

(ㄱ) VC++ 통합환경을 시작한다.

(ㄴ) File의 하위 메뉴 ‘New’를 실행한다.

 

(ㄷ) ‘MFC ActiveX ContolWizard’를 선택한다.

(ㄹ) ‘Project name’을 입력한다.

 

(ㅁ) ‘OK’를 클릭한다.

 

(ㅂ) 실행시 라이센스를 요구할 경우가 아니면 ‘Next’를 클릭한다.

 

(ㅅ) 컨트롤이 실행시 화면에 보일 필요가 없고 Component Object 리스트에 추가하기 위해서 ‘invisible at runtime’ ‘Available in “Insert Object” dialog’ 항목을 체크한다.



(ㅇ) ‘Finish’ 를 클릭한다.

 

(ㅈ) ‘OK’ 를 클릭한다.

C. Property 추가

(ㄱ) ‘Ctrl + W’ 키를 눌러서 ‘ClassWizard’ 를 실행한다.

 

(ㄴ) ‘Automation’ 탭을 클릭한다.



(ㄷ) ‘Add Property…’ 버튼을 클릭한다.

 

(ㄹ) Component의 외부에서 사용할 External name’ 을 입력하고 ‘Get/Set methods’ 버튼을 클릭한 후, ‘Type’ 을 선택한다.

(ㅁ) ‘OK’ 를 클릭한다.

D. Method 추가

(ㄱ) ‘Ctrl + W’ 키를 눌러서 ‘ClassWizard’ 를 실행한다.

 

(ㄴ) ‘Automation’ 탭을 클릭한다.

 

(ㄷ) Add Method…’ 버튼을 클릭한 후, 외부에서 사용할 함수명 External name’ 을 입력하고 ‘Return type:’ 을 선택한다. ‘Return type:’‘OLE_HANDLE’ 을 선택한 이유는 BYTE형 포인터를 반환하는 유형이 없기 때문이다. 외부에서 사용할 때에는 리턴값을 BYTE형 포인터로 변환하여 사용해야 한다.

 

(ㄹ) ‘OK’ 를 클릭한다.

 

3. Light Component

A. 구성

(ㄱ) OCX 등록: Light.cpp, light.h

(ㄴ) Method Property : LightCtl.cpp, LightCtl.h

(ㄷ) COM port 통신 : CommThread.cpp, CommThread.h

Queue.cpp, Queue.h

(ㄹ) Socket 통신 : ClientSocket.cpp, ClientSocket.h

B. 사용방법

(ㄱ) Light.ocx 파일을 레지스트리에 등록한다. 등록하는 방법은 Prompt command 상태에서 ‘regsvr32 Light.ocx’ 를 실행한다.

(ㄴ) COM port로 기기를 제어할 경우에는 Start() 함수에 COM port, Socket에 의해 기기를 제어할 경우에는 IP와 통신 port를 매개변수로 넘겨준다.

(ㄷ) COM 또는 Socket 포트를 통하여 전달받게 되는 데이터는 GetData() 함수를 사용한다.

(ㄹ) 전등을 제어하거나 상태정보를 구하고자 할 경우에는 CtlLight() StuLight() 함수를 사용한다.

 

4. Gas Component

A. 구성

(ㄱ) OCX 등록: Gas.cpp, Gas.h

(ㄴ) Method Property : GasCtl.cpp, GasCtl.h

(ㄷ) COM port 통신 : CommThread.cpp, CommThread.h

(ㄹ) Queue.cpp, Queue.h

(ㅁ) Socket 통신 : ClientSocket.cpp, ClientSocket.h

B. 사용방법

(ㄱ) Gas.ocx 파일을 레지스트리에 등록한다. 등록하는 방법은 Prompt command 상태에서 ‘regsvr32 Gas.ocx’ 를 실행한다.

(ㄴ) COM port로 기기를 제어할 경우에는 Start() 함수에 COM port , Socket에 의해 기기를 제어할 경우에는 IP와 통신 port를 매개변수로 넘겨준다.

(ㄷ) COM 또는 Socket 포트를 통하여 전달받게 되는 데이터는 GetData() 함수를 사용한다.

(ㄹ) 전등을 제어하거나 상태정보를 구하고자 할 경우에는 CtlGas() StuGas() 함수를 사용한다.

 

<

부록>

 

1. CLightCtl class

A. 구성

 

class CLightCtrl : public COleControl

{

DECLARE_DYNCREATE(CLightCtrl)

 

void Process485Light(BYTE *pRevData, int nDataSize);

void SetRs485ActLight(BYTE *pRevData, int nDataSize);

 

// Constructor

public:

CLightCtrl();

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CLightCtrl)

public:

virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);

virtual void DoPropExchange(CPropExchange* pPX);

virtual void OnResetState();

//}}AFX_VIRTUAL

 

// Implementation

protected:

~CLightCtrl();

 

DECLARE_OLECREATE_EX(CLightCtrl) // Class factory and guid

DECLARE_OLETYPELIB(CLightCtrl) // GetTypeInfo

DECLARE_PROPPAGEIDS(CLightCtrl) // Property page IDs

DECLARE_OLECTLTYPE(CLightCtrl) // Type name and misc status

 

// Message maps

//{{AFX_MSG(CLightCtrl)

afx_msg LRESULT OnRs485Notify(WPARAM wParam, LPARAM lParam);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

 

// Dispatch maps

//{{AFX_DISPATCH(CLightCtrl)

afx_msg OLE_HANDLE GetParentWnd();

afx_msg void SetParentWnd(OLE_HANDLE nNewValue);

afx_msg short GetComPort();

afx_msg void SetComPort(short nNewValue);

afx_msg long GetBaudRate();

afx_msg void SetBaudRate(long nNewValue);

afx_msg short GetByteSize();

afx_msg void SetByteSize(short nNewValue);

afx_msg short GetParity();

afx_msg void SetParity(short nNewValue);

afx_msg short GetStopbit();

afx_msg void SetStopbit(short nNewValue);

afx_msg BSTR GetIP();

afx_msg void SetIP(LPCTSTR lpszNewValue);

afx_msg long GetLanPort();

afx_msg void SetLanPort(long nNewValue);

afx_msg short GetType();

afx_msg void SetType(short nNewValue);

afx_msg short GetLightCount();

afx_msg void SetLightCount(short nNewValue);

afx_msg short GetID();

afx_msg void SetID(short nNewValue);

afx_msg short GetOnOff();

afx_msg void SetOnOff(short nNewValue);

afx_msg BOOL OpenCom(short port, long baudRate, short byteSize, short parity, short stopBit);

afx_msg BOOL OpenSocket(LPCTSTR strIP, long lanPort);

afx_msg BOOL Start(short comPort, LPCTSTR strIP, long lanPort, short type, short lightCount, OLE_HANDLE pParentWnd);

afx_msg BOOL CtlLight(short lightID, short onOff);

afx_msg void StuLight(short lightID, short onOff);

afx_msg OLE_HANDLE GetData();

afx_msg long GetDataSize();

afx_msg void CloseCom();

afx_msg BOOL DCtlLight(short FAR* pProtocol, short dataSize);

afx_msg void DStuLight(short FAR* pProtocol, short dataSize);

//}}AFX_DISPATCH

DECLARE_DISPATCH_MAP()

 

afx_msg void AboutBox();

 

// Event maps

//{{AFX_EVENT(CLightCtrl)

void FireComNotify()

{FireEvent(eventidComNotify,EVENT_PARAM(VTS_NONE));}

//}}AFX_EVENT

DECLARE_EVENT_MAP()

 

// Dispatch and event IDs

public:

BYTE* m_data;

int m_dataSize;

 

BYTE m_iOnOff; // 전등상태(0x00=Off, 0x01=On) BYTE m_iID; // 전등ID(0x00=전체, 0x01=전구1, 0x02=전구2, ...) BYTE m_iLightCount; // 전등수 UINT m_iType; // 0=일반전구, 1=디밍

 

long m_iLanPort; // Socket Port

CString m_strIP; // Socket IP

CClientSocket *m_pClient; // Socket communications

 

BOOL m_bOpenCom;

BYTE m_iStopBit; // Stop bit

BYTE m_iParity; // Parity

BYTE m_iByteSize; // Byte size

DWORD m_dwBaudRate; // 전송속도

int m_iPort; // Port(one-based)

//CgtComPort m_gtComPort; // COM port control

CCommThread m_comPort; // COM port control

 

CWnd* m_pParentWnd;

 

enum {

//{{AFX_DISP_ID(CLightCtrl)

dispidParentWnd = 1L,

dispidComPort = 2L,

dispidBaudRate = 3L,

dispidByteSize = 4L,

dispidParity = 5L,

dispidStopbit = 6L,

dispidIP = 7L,

dispidLanPort = 8L,

dispidType = 9L,

dispidLightCount = 10L,

dispidID = 11L,

dispidOnOff = 12L,

dispidOpenCom = 13L,

dispidOpenSocket = 14L,

dispidStart = 15L,

dispidCtlLight = 16L,

dispidStuLight = 17L,

dispidGetData = 18L,

dispidGetDataSize = 19L,

dispidCloseCom = 20L,

dispidDCtlLight = 21L, // 프로토콜에 의한 제어 dispidDStuLight = 22L, // 프로토콜에 의한 상태정보 획득

eventidComNotify = 1L,

//}}AFX_DISP_ID

};

};

 

 

B. COM port 감시 메시지

//{{AFX_MSG_MAP(CLightCtrl)

ON_MESSAGE(WM_COMM_NOTIFY, OnRs485Notify)

//}}AFX_MSG_MAP

 

 

C. 외부에서 사용하게 Method Property Dispatch map

 

//{{AFX_DISPATCH_MAP(CLightCtrl)

DISP_PROPERTY_EX(CLightCtrl, "ParentWnd", GetParentWnd, SetParentWnd, VT_HANDLE)

DISP_PROPERTY_EX(CLightCtrl, "ComPort", GetComPort, SetComPort, VT_I2)

DISP_PROPERTY_EX(CLightCtrl, "BaudRate", GetBaudRate, SetBaudRate, VT_I4)

DISP_PROPERTY_EX(CLightCtrl, "ByteSize", GetByteSize, SetByteSize, VT_I2)

DISP_PROPERTY_EX(CLightCtrl, "Parity", GetParity, SetParity, VT_I2)

DISP_PROPERTY_EX(CLightCtrl, "Stopbit", GetStopbit, SetStopbit, VT_I2)

DISP_PROPERTY_EX(CLightCtrl, "IP", GetIP, SetIP, VT_BSTR)

DISP_PROPERTY_EX(CLightCtrl, "LanPort", GetLanPort, SetLanPort, VT_I4)

DISP_PROPERTY_EX(CLightCtrl, "Type", GetType, SetType, VT_I2)

DISP_PROPERTY_EX(CLightCtrl, "LightCount", GetLightCount, SetLightCount, VT_I2)

DISP_PROPERTY_EX(CLightCtrl, "ID", GetID, SetID, VT_I2)

DISP_PROPERTY_EX(CLightCtrl, "OnOff", GetOnOff, SetOnOff, VT_I2)

DISP_FUNCTION(CLightCtrl, "OpenCom", OpenCom, VT_BOOL, VTS_I2 VTS_I4 VTS_I2 VTS_I2 VTS_I2)

DISP_FUNCTION(CLightCtrl, "OpenSocket", OpenSocket, VT_BOOL, VTS_BSTR VTS_I4)

DISP_FUNCTION(CLightCtrl, "Start", Start, VT_BOOL, VTS_I2 VTS_BSTR VTS_I4 VTS_I2 VTS_I2 VTS_HANDLE)

DISP_FUNCTION(CLightCtrl, "CtlLight", CtlLight, VT_BOOL, VTS_I2 VTS_I2)

DISP_FUNCTION(CLightCtrl, "StuLight", StuLight, VT_EMPTY, VTS_I2 VTS_I2)

DISP_FUNCTION(CLightCtrl, "GetData", GetData, VT_HANDLE, VTS_NONE)

DISP_FUNCTION(CLightCtrl, "GetDataSize", GetDataSize, VT_I4, VTS_NONE)

DISP_FUNCTION(CLightCtrl, "CloseCom", CloseCom, VT_EMPTY, VTS_NONE)

DISP_FUNCTION(CLightCtrl, "DCtlLight", DCtlLight, VT_BOOL, VTS_PI2 VTS_I2)

DISP_FUNCTION(CLightCtrl, "DStuLight", DStuLight, VT_EMPTY, VTS_PI2 VTS_I2)

//}}AFX_DISPATCH_MAP

 

 

D. 외부와 통신하게 Event map

 

//{{AFX_EVENT_MAP(CLightCtrl)

EVENT_CUSTOM("ComNotify", FireComNotify, VTS_NONE)

//}}AFX_EVENT_MAP

 

 

E. GUID

 

(0xc69169e2, 0x1bff, 0x44bd, 0x87, 0x6e, 0xd1, 0xe8, 0xf7, 0xed, 0xa, 0x65)

 

 

F. Interface ID

 

const IID BASED_CODE IID_DLight =

{ 0x415ea118, 0xc0a2, 0x4037, { 0x96, 0x6, 0xdb, 0xc1, 0x45, 0xa2, 0xa2, 0xd1 } };

const IID BASED_CODE IID_DLightEvents =

{ 0xd596ca3a, 0x818c, 0x420d, { 0xba, 0x80, 0xbc, 0x42, 0x7f, 0x3a, 0x65, 0x42 } };

 

2. CGasCtl class

A. 구성

 

class CGasCtrl : public COleControl

{

DECLARE_DYNCREATE(CGasCtrl)

 

void Process485Gas(BYTE *pRevData, int nByteSize);

 

// Constructor

public:

CGasCtrl();

 

// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CGasCtrl)

public:

virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid);

virtual void DoPropExchange(CPropExchange* pPX);

virtual void OnResetState();

//}}AFX_VIRTUAL

 

// Implementation

protected:

~CGasCtrl();

 

DECLARE_OLECREATE_EX(CGasCtrl) // Class factory and guid

DECLARE_OLETYPELIB(CGasCtrl) // GetTypeInfo

DECLARE_PROPPAGEIDS(CGasCtrl) // Property page IDs

DECLARE_OLECTLTYPE(CGasCtrl) // Type name and misc status

 

// Message maps

//{{AFX_MSG(CGasCtrl)

afx_msg LRESULT OnRs485Notify(WPARAM wParam, LPARAM lParam);

//}}AFX_MSG

DECLARE_MESSAGE_MAP()

 

// Dispatch maps

//{{AFX_DISPATCH(CGasCtrl)

BOOL m_isOpenCom;

afx_msg void OnIsOpenComChanged();

afx_msg OLE_HANDLE GetParentWnd();

afx_msg void SetParentWnd(OLE_HANDLE nNewValue);

afx_msg short GetComPort();

afx_msg void SetComPort(short nNewValue);

afx_msg long GetBaudRate();

afx_msg void SetBaudRate(long nNewValue);

afx_msg short GetByteSize();

afx_msg void SetByteSize(short nNewValue);

afx_msg short GetParity();

afx_msg void SetParity(short nNewValue);

afx_msg short GetStopBit();

afx_msg void SetStopBit(short nNewValue);

afx_msg BSTR GetIP();

afx_msg void SetIP(LPCTSTR lpszNewValue);

afx_msg long GetLanPort();

afx_msg void SetLanPort(long nNewValue);

afx_msg short GetValue();

afx_msg void SetValue(short nNewValue);

afx_msg short GetDataSize();

afx_msg OLE_HANDLE GetData();

afx_msg BOOL OpenCom(short port, long baudRate, short byteSize, short parity, short stopBit);

afx_msg BOOL OpenSocket(LPCTSTR strIP, long lanPort);

afx_msg BOOL Start(short comPort, LPCTSTR strIP, long lanPort, OLE_HANDLE pParentWnd);

afx_msg BOOL CtlGas();

afx_msg void StuGas();

afx_msg void CloseCom();

afx_msg BOOL DCtlGas(short FAR* pProtocol, short dataSize);

afx_msg void DStuGas(short FAR* pProtocol, short dataSize);

//}}AFX_DISPATCH

DECLARE_DISPATCH_MAP()

 

afx_msg void AboutBox();

 

// Event maps

//{{AFX_EVENT(CGasCtrl)

void FireComNotify()

{FireEvent(eventidComNotify,EVENT_PARAM(VTS_NONE));}

//}}AFX_EVENT

DECLARE_EVENT_MAP()

 

// Dispatch and event IDs

public:

enum {

//{{AFX_DISP_ID(CGasCtrl)

dispidParentWnd = 2L,

dispidComPort = 3L,

dispidBaudRate = 4L,

dispidByteSize = 5L,

dispidParity = 6L,

dispidStopBit = 7L,

dispidIsOpenCom = 1L,

dispidIP = 8L,

dispidLanPort = 9L,

dispidValue = 10L,

dispidGetDataSize = 11L,

dispidGetData = 12L,

dispidOpenCom = 13L,

dispidOpenSocket = 14L,

dispidStart = 15L,

dispidCtlGas = 16L,

dispidStuGas = 17L,

dispidCloseCom = 18L,

dispidDCtlGas = 19L, // 프로토콜에 의한 제어 dispidDStuGas = 20L, // 프로토콜에 의한 상태정보 획득

eventidComNotify = 1L,

//}}AFX_DISP_ID

};

 

private:

BYTE* m_data;

int m_dataSize;

 

BOOL m_iValue; // 가스벨브를 닫을지의 여부(0x00=닫음, 0x01=열음)

 

long m_iLanPort; // Socket Port

CString m_strIP; // Socket IP

CClientSocket *m_pClient; // Socket communications

 

BOOL m_bOpenCom;

BYTE m_iStopBit; // Stop bit

BYTE m_iParity; // Parity

BYTE m_iByteSize; // Byte size

DWORD m_dwBaudRate; // 전송속도

int m_iPort; // Port(one-based)

CCommThread m_comPort; // COM port control

 

CWnd* m_pParentWnd;

};

 

B. COM port 감시 메시지

//{{AFX_MSG_MAP(CLightCtrl)

ON_MESSAGE(WM_COMM_NOTIFY, OnRs485Notify)

//}}AFX_MSG_MAP

 

 

C. 외부에서 사용하게 Method Property Dispatch map

 

//{{AFX_DISPATCH_MAP(CLightCtrl)

DISP_PROPERTY_NOTIFY(CGasCtrl, "IsOpenCom", m_isOpenCom, OnIsOpenComChanged, VT_BOOL)

DISP_PROPERTY_EX(CGasCtrl, "ParentWnd", GetParentWnd, SetParentWnd, VT_HANDLE)

DISP_PROPERTY_EX(CGasCtrl, "ComPort", GetComPort, SetComPort, VT_I2)

DISP_PROPERTY_EX(CGasCtrl, "BaudRate", GetBaudRate, SetBaudRate, VT_I4)

DISP_PROPERTY_EX(CGasCtrl, "ByteSize", GetByteSize, SetByteSize, VT_I2)

DISP_PROPERTY_EX(CGasCtrl, "Parity", GetParity, SetParity, VT_I2)

DISP_PROPERTY_EX(CGasCtrl, "StopBit", GetStopBit, SetStopBit, VT_I2)

DISP_PROPERTY_EX(CGasCtrl, "IP", GetIP, SetIP, VT_BSTR)

DISP_PROPERTY_EX(CGasCtrl, "LanPort", GetLanPort, SetLanPort, VT_I4)

DISP_PROPERTY_EX(CGasCtrl, "Value", GetValue, SetValue, VT_I2)

DISP_FUNCTION(CGasCtrl, "GetDataSize", GetDataSize, VT_I2, VTS_NONE)

DISP_FUNCTION(CGasCtrl, "GetData", GetData, VT_HANDLE, VTS_NONE)

DISP_FUNCTION(CGasCtrl, "OpenCom", OpenCom, VT_BOOL, VTS_I2 VTS_I4 VTS_I2 VTS_I2 VTS_I2)

DISP_FUNCTION(CGasCtrl, "OpenSocket", OpenSocket, VT_BOOL, VTS_BSTR VTS_I4)

DISP_FUNCTION(CGasCtrl, "Start", Start, VT_BOOL, VTS_I2 VTS_BSTR VTS_I4 VTS_HANDLE)

DISP_FUNCTION(CGasCtrl, "CtlGas", CtlGas, VT_BOOL, VTS_NONE)

DISP_FUNCTION(CGasCtrl, "StuGas", StuGas, VT_EMPTY, VTS_NONE)

DISP_FUNCTION(CGasCtrl, "CloseCom", CloseCom, VT_EMPTY, VTS_NONE)

DISP_FUNCTION(CGasCtrl, "DCtlGas", DCtlGas, VT_BOOL, VTS_PI2 VTS_I2)

DISP_FUNCTION(CGasCtrl, "DStuGas", DStuGas, VT_EMPTY, VTS_PI2 VTS_I2)

//}}AFX_DISPATCH_MAP

 

 

D. 외부와 통신하게 Event map

 

//{{AFX_EVENT_MAP(CLightCtrl)

EVENT_CUSTOM("ComNotify", FireComNotify, VTS_NONE)

//}}AFX_EVENT_MAP

 

 

E. GUID

 

(0x39e95745, 0xa094, 0x41f6, 0xbc, 0xf7, 0x17, 0x28, 0x78, 0x20, 0xda, 0xc5)

 

 

F. Interface ID

const IID BASED_CODE IID_DGas =

{ 0xce6ed7ee, 0x9bb3, 0x4960, { 0x97, 0x6e, 0x9d, 0x37, 0xa5, 0xb1, 0x6f, 0x1c } };

const IID BASED_CODE IID_DGasEvents =

{ 0x417cd414, 0xa2fa, 0x48cd, { 0xb7, 0x74, 0x4f, 0x39, 0x1a, 0xf8, 0x8c, 0xf9 } };

출처: https://use1348.tistory.com/41 [유용한 정보:티스토리]