现在的位置: 首页 > 综合 > 正文

终于用VC/MFC做了一个真正的程序

2013年09月06日 ⁄ 综合 ⁄ 共 2545字 ⁄ 字号 评论关闭

        花了两天多的时间做了一个“信使服务”程序,呵呵,以前在网上见到过,居然要花钱注册的。其实就是用了那个NetMessageBufferSend函数,再用一个NetMessageNameAdd函数把随便一个名字加进去,就可以把自己的身份隐藏了。以前在学校的时候由于用的是固定IP,经常收到的很多广告就是用这种方式发送的。有时候在课堂上老师正在讲课,突然就冒出这么一个窗口来,十分气人,所以我们一般都把Messenger服务给屏蔽掉,嘿嘿,现在我居然做起这个东西来。

  通过命令行方式用net send命令就可以发这种消息,不过会暴露你的计算机名,因为它没有选择名字的参数,而使用NetMessageBufferSend则可以使用你计算机上的任意一个“名字”,那个名字又叫“消息别名”,似乎跟计算机名不一样,但是默认的“消息别名”就是计算机名。开始的时候以为可以随便给NetMessageBufferSend的from参数赋值,网上很多人也这样说,但我试了总是出错。后来才发现那个名字必须是计算机上已经有的“消息别名”之一。那我怎么才能随便用一个名字呢?于是就必须用到NetMessageNameAdd函数,这个函数可以增加一个随便起的消息别名,接着就可以把这个名字传给NetMessageBufferSend来发送了。

  NetMessageBufferSend的原型是:

NET_API_STATUS NetMessageBufferSend(
  LPCWSTR servername,
  LPCWSTR msgname,
  LPCWSTR fromname,
  LPBYTE buf,
  DWORD buflen
);

  开始的时候以为第一个参数servername就是目标的名字,后来才知道原来是要运行这个函数的服务器的名字,因为这个函数一般用于局域网管理,有时候需要控制某台服务器来运行程序。如果在本机上运行,把这个参数设成NULL就可以了。以Net开头的很多函数都有这个参数。

  第二个参数msgname,在网上看到很多人说这个就是指向要发的消息字符串的指针,跟第4个参数buf是一样的。我试了很错次都是失败的。后来在某个地方看到一个牛人的解释才知道这个msgname的意思根本就不是“消息字符串的名字”,而是目标机器的“消息别名”!一般就是目标的计算机名了,如果那台计算机还有其他消息别名的话,这个也可以是其中一个,不过发消息的那台机器也要知道该别名指的是那台计算机才行。

  第三个参数最折腾人了,总以为随便起一个名字就可以了,后来跟踪了错误信息,说没有找到这个名字,想起以前用net send玩的时候还用过一个net name,通过net name xxx /add就可以增加一个名字xxx,然后用net send 就可以给xxx发消息了。既然说没找到这个名字,是不是那个名字还没通过net name来加进去呢?于是我就用了最古老的一种方法,通过system()函数执行net name命令,把随意输入的名字加进去,再用那个名字发消息,哈哈,成功了。不过要弹出那个黑黑的cmd 窗口比较难看。再到MSDN看看,有个NetNameAdd函数,正好可以干这种事情,呵呵,搞定。

  LPCWSTR与LPBYTE也比较难受。LPCWSTR的意思是“常量宽字符串”,因为Net系列函数使用的都是UNICODE。那怎么把CString转换成这个东西呢?CString本身可以被看作LPCTSTR,即“常量T字符串”,呵呵,T字符就是那种“骑墙”字符,你定义了_UNICODE,它就表示W,宽字符,没有定义_UNICODE,它就表示一般的8比特字符,为了同时兼容ASCII版本和UNICODE版本,定义字符串的时候最好都用T字符。那怎么把CString转换成宽字符串呢?在网上看到有人说用一些宏就可以了。那些宏是在atlconv.h里面定义的,包括:

ATL String Conversion Macros

A2BSTR OLE2A T2A W2A
A2COLE OLE2BSTR T2BSTR W2BSTR
A2CT OLE2CA T2CA W2CA
A2CW OLE2CT T2COLE W2COLE
A2OLE OLE2CW T2CW W2CT
A2T OLE2T T2OLE W2OLE
A2W OLE2W T2W W2T

  每次使用前,都要在前面加上一句:

USES_CONVERSION;

然后就可以很方便地在这些类型之间转换了。例如要把CString str转换成LPCWSTR lpw,只要:

#include <atlconv.h>

...

USES_CONVERSION;

LPCWSTR lpw=T2W(str);

这样,前三个参数就可以搞定了。

  第四个参数是LPBYTE,这又是一种奇怪的类型,从字面上看是指向BYTE类型的指针。在C里面是没有BYTE类型的,跟它最象的就是unsigned char类型了,实际上就是它。那怎么把CString转换成这个呢?首先,要把CString转换成LPCWSTR,因为Net用的都是UNICODE,里面的字符串编码必须是UNICODE;接着,由于LPCWSTR的每个字符是16bit,不符合LPBYTE的要求,所以还必须强制转换成LPBYTE。这样,可以写成:

LPBYTE=(LPBYTE)T2W(CString);

不过还是分步转换好一点:

LPCWSTR=T2W(CString);

LPBYTE=(LPBYTE)LPCWSTR;

  因为后面一个参数buflen要用到LPCWSTR的长度。buflen是以字节来计算的buf的长度,通过wcslen(LPCWSTR)可以得到LPCWSTR的字符个数,然后每个字符的长度是sizeof(wchar_t)字节,那么LPCWSTR的长度就是wcslen(LPCWSTR)*sizeof(wchar_t)字节。

  我想用CString的GetLength()函数来做,但是总是失败,不知道为什么。CString.GetLength()*sizeof(TCHAR)总是长度不够,后面有一个或几个字符截断了。

  到这里,输入的东西就搞定了,搞定了这个,后面的群发、局域网计算机列表就问题不大了。下次再把心得写出来

抱歉!评论已关闭.