标准MFC WinSock ActiveX控件开发实例Word格式.docx

上传人:b****4 文档编号:17268752 上传时间:2022-11-30 格式:DOCX 页数:13 大小:238.87KB
下载 相关 举报
标准MFC WinSock ActiveX控件开发实例Word格式.docx_第1页
第1页 / 共13页
标准MFC WinSock ActiveX控件开发实例Word格式.docx_第2页
第2页 / 共13页
标准MFC WinSock ActiveX控件开发实例Word格式.docx_第3页
第3页 / 共13页
标准MFC WinSock ActiveX控件开发实例Word格式.docx_第4页
第4页 / 共13页
标准MFC WinSock ActiveX控件开发实例Word格式.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

标准MFC WinSock ActiveX控件开发实例Word格式.docx

《标准MFC WinSock ActiveX控件开发实例Word格式.docx》由会员分享,可在线阅读,更多相关《标准MFC WinSock ActiveX控件开发实例Word格式.docx(13页珍藏版)》请在冰豆网上搜索。

标准MFC WinSock ActiveX控件开发实例Word格式.docx

if(bInit)

{

//TODO:

Addyourownmoduleinitializationcodehere.

if(!

AfxSocketInit())

{

AfxMessageBox("

无法初始化Socket,请检查!

"

);

returnFALSE;

}

WSADATAwsaData;

WORDwVersion=MAKEWORD(1,1);

//设定为Winsock1.1版

interrCode;

errCode=WSAStartup(wVersion,&

wsaData);

//启动Socket服务

if(errCode)

无法找到可以使用的WSOCK32.DLL"

}

returnbInit;

}

 

ExitInstance-DLLtermination

intCMFCWinSockApp:

ExitInstance()

//TODO:

Addyourownmoduleterminationcodehere.

WSACleanup();

//结束网络服务

returnCOleControlModule:

ExitInstance();

三,提供控件接口和事件

1.在MFCWinSockCtl.cpp加入如下代码:

2.#ifndefWM_MYWINSOCK

3.#defineWM_MYWINSOCKWM_USER+1888

4.#endif

5.View->

ClassWizard->

Automation->

AddMethod…如下图:

图三创建接口

这个时候,我们为这个控件添加了一个Connect()的接口,出于通用性,安全性和扩展性的考虑,我们采用了VARIANT类型的参数,

很多人可能都不太了解该类型,又或者有接触过,但被吓怕了,那么我们来看清它的本来面目:

6.structtagVARIANT

7.{

8.union

9.{

10.struct__tagVARIANT

11.{

12.VARTYPEvt;

13.WORDwReserved1;

14.WORDwReserved2;

15.WORDwReserved3;

16.union

17.{

18.LONGlVal;

19.BYTEbVal;

20.SHORTiVal;

21.FLOATfltVal;

22.DOUBLEdblVal;

23.VARIANT_BOOLboolVal;

24._VARIANT_BOOLbool;

25.SCODEscode;

26.CYcyVal;

27.DATEdate;

28.BSTRbstrVal;

29.IUnknown__RPC_FAR*punkVal;

30.IDispatch__RPC_FAR*pdispVal;

31.SAFEARRAY__RPC_FAR*parray;

32.BYTE__RPC_FAR*pbVal;

33.SHORT__RPC_FAR*piVal;

34.LONG__RPC_FAR*plVal;

35.FLOAT__RPC_FAR*pfltVal;

36.DOUBLE__RPC_FAR*pdblVal;

37.VARIANT_BOOL__RPC_FAR*pboolVal;

38._VARIANT_BOOL__RPC_FAR*pbool;

39.SCODE__RPC_FAR*pscode;

40.CY__RPC_FAR*pcyVal;

41.DATE__RPC_FAR*pdate;

42.BSTR__RPC_FAR*pbstrVal;

43.IUnknown__RPC_FAR*__RPC_FAR*ppunkVal;

44.IDispatch__RPC_FAR*__RPC_FAR*ppdispVal;

45.SAFEARRAY__RPC_FAR*__RPC_FAR*pparray;

46.VARIANT__RPC_FAR*pvarVal;

47.PVOIDbyref;

48.CHARcVal;

49.USHORTuiVal;

50.ULONGulVal;

51.INTintVal;

52.UINTuintVal;

53.DECIMAL__RPC_FAR*pdecVal;

54.CHAR__RPC_FAR*pcVal;

55.USHORT__RPC_FAR*puiVal;

56.ULONG__RPC_FAR*pulVal;

57.INT__RPC_FAR*pintVal;

58.UINT__RPC_FAR*puintVal;

59.struct__tagBRECORD

60.{

61.PVOIDpvRecord;

62.IRecordInfo__RPC_FAR*pRecInfo;

63.}__VARIANT_NAME_4;

64.}__VARIANT_NAME_3;

65.}__VARIANT_NAME_2;

66.DECIMALdecVal;

67.}__VARIANT_NAME_1;

68.};

它先是一个结构体,里面有一个重要成员VARTYPEvt;

vt即是指明当前的数据类型,比如整型或者字符型,当指明vt后,

后面看到各种变量类型包括在一个联合体当中,也就是说指明vt后,你只能使用对应的其中之一变量类型。

看着这众多的各种不同

类型变量集中在一起,确实让人吓了一跳,但细细看来,大多数变量跟我们平时的用法相似。

值得一提的是SAFEARRAY__RPC_FAR*parray;

也许有很多人还没有接触过SAFEARRAY类型的变量,SAFEARRAY实际上也是一个结构,大家可以参考MSDN,我也将在后面介绍它的具体使用方法。

69.用同样的方法创建DisConnect()接口

70.创建两个事件,FireCloseWinsock()响应网络断开事件,FireRecvSockEvent()响应网络有数据到达的事件。

创建方法如下图:

图四创建事件

71.重载控件消息处理函数WindowProc(),在View->

ClassWizard中打开类向导,在消息映射中找到WindowProc,如下图:

图五重载WindowProc()

四、编写代码

1.编写VariantToLong()转换函数,该函数代码如下:

2.//类型转换,将VARIANT类型转换成Long类型

3.longCMFCWinSockCtrl:

VariantToLong(constVARIANT&

var)

4.{

5.longr;

6.switch(var.vt)

8.caseVT_UI2:

//USHORT

9.r=var.uiVal;

10.break;

11.caseVT_UI4:

//ULONG

12.r=var.ulVal;

13.break;

14.caseVT_INT:

//INT

15.r=var.intVal;

16.break;

17.caseVT_UINT:

//UINT

18.r=var.uintVal;

19.break;

20.caseVT_I4:

//LONG

21.r=var.lVal;

22.break;

23.caseVT_UI1:

//BYTE

24.r=var.bVal;

25.break;

26.caseVT_I2:

//SHORT

27.r=var.iVal;

28.break;

29.caseVT_R4:

//FLOAT

30.r=(long)var.fltVal;

31.break;

32.caseVT_R8:

//DOUBLE

33.r=(long)var.dblVal;

34.break;

35.default:

36.r=-1;

//无法转换该值

37.break;

38.}

39.returnr;

40.}

41.

大家可以看到,该函数将最基本的若干中数据类型转换成了long类型,但VARIANT决不是个简单的谱,我将在后面继续揭开它的神秘面纱.

42.编写我们刚才的接口Connect(),代码代码如下:

在MFCWinSockCtrl.h中加入

43.SOCKETOnlySock;

//建立的唯一Socket,不允许重复建立多个

44.boolisOnlyConnect;

//是否建立了连接

然后再编写Connect(),看起来如下:

BOOLCMFCWinSockCtrl:

Connect(constVARIANTFAR&

RemoteHost,constVARIANTFAR&

RemotePort)

Addyourdispatchhandlercodehere

if(isOnlyConnect)//该连接已建立,还没有断开

returnFALSE;

CStringIPAddress;

intPort;

//转换成整型的端口

switch(RemoteHost.vt)

caseVT_BSTR:

//字符串型

IPAddress=CString(RemoteHost.bstrVal);

break;

caseVT_BYREF|VT_I1:

//CHAR*

IPAddress.Format("

%s"

RemoteHost.pcVal);

//RemoteHost.pbstrVal);

default:

IPAddress="

;

Port=VariantToLong(RemotePort);

//我们编写的一个VARIANT转换成long类型的函数

if(Port<

=0)

_TCHAR*ip=0;

structhostent*host=0;

structsockaddr_inaddr;

ULONGdotIP=inet_addr(IPAddress);

OnlySock=socket(AF_INET,SOCK_STREAM,0);

//判断是否为点IP地址格式

if(OnlySock==INVALID_SOCKET)

shutdown(OnlySock,0x02);

closesocket(OnlySock);

//释放占有的SOCK资源

memset(&

addr,0,sizeof(structsockaddr_in));

//设定SOCKADDR_IN结构的内容

//如果通讯协议是选择IPProtocol,那此值固定为AF_INET

//AF_INET与PF_INET这两个常量值相同

addr.sin_family=AF_INET;

addr.sin_port=htons(Port);

addr.sin_addr.S_un.S_addr=dotIP;

if(dotIP==INADDR_NONE)

host=gethostbyname(IPAddress);

if(!

host)

};

ip=inet_ntoa(*(structin_addr*)(*host->

h_addr_list));

addr.sin_addr.S_un.S_addr=inet_addr(ip);

//开始连线

if(connect(OnlySock,(LPSOCKADDR)&

addr,sizeof(SOCKADDR)))

shutdown(OnlySock,0x02);

closesocket(OnlySock);

returnFALSE;

intiError=WSAAsyncSelect(OnlySock,m_hWnd,WM_MYWINSOCK,FD_READ|FD_CLOSE);

//只对网络断开和数据到达通知感兴趣

if(iError==SOCKET_ERROR)//无法绑定Winsock的事件通知

{

}

isOnlyConnect=true;

returnTRUE;

有必要提一下WSAAsyncSelect(),这里接收网络数据到达和断开的两个消息,我们收到WM_MYWINSOCK消息时将处理该消息并作为事件传送给调用者.

第二个参数,窗口句柄,我们传送了m_hWnd,这是因为MFCActiveX也属于一个窗口,并且是可见的,因此可以成功。

45.编写WindowProc(),代码看起来如下:

46.LRESULTCMFCWinSockCtrl:

WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)

47.{

48.//TODO:

Addyourspecializedcodehereand/orcallthebaseclass

49.switch(message)

50.{

51.caseWM_MYWINSOCK:

//响应自定义的消息

52.switch(WSAGETSELECTEVENT(lParam))

53.{

54.caseFD_READ:

//有新数据到达

55.FireRecvSockEvent();

56.break;

57.caseFD_CLOSE:

//对方已断掉当前连接

58.FireCloseWinsock();

59.break;

60.}

61.break;

62.default:

63.break;

64.}

65.returnCOleControl:

WindowProc(message,wParam,lParam);

66.}

本部分结束语:

好了,现在一个可以运行的控件已经完成,里面提供有Connect()和DisConnect()接口,和RecvSockEvent()及CloseWinsock()事件。

以及WinSock的使用方法。

在下一部分(高级篇)将讲解两个重要接口SendData()和GetData(),下期内容如下:

1.longSendData(constVARIANTFAR&

Data,constVARIANTFAR&

DataType,constVARIANTFAR&

DataLength,constVARIANTFAR&

TimeOut)

2.longGetData(VARIANTFAR*Data,constVARIANTFAR&

DataType,constVARIANTFAR&

DataMaxLength,constVARIANTFAR&

3.VARIANT和SAFEARRAY的复杂用法。

4.控件开发出来后在VC和VB环境下的使用方法。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 笔试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1