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

原创 2005年05月27日 23:10:00

        花了两天多的时间做了一个“信使服务”程序,呵呵,以前在网上见到过,居然要花钱注册的。其实就是用了那个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

A2BSTROLE2AT2AW2A
A2COLEOLE2BSTRT2BSTRW2BSTR
A2CTOLE2CAT2CAW2CA
A2CWOLE2CTT2COLEW2COLE
A2OLEOLE2CWT2CWW2CT
A2TOLE2TT2OLEW2OLE
A2WOLE2WT2WW2T

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

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)总是长度不够,后面有一个或几个字符截断了。

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

孙鑫VC学习笔记:第十五讲 编写一个基于MFC对话框的聊天程序

编写一个基于MFC对话框的聊天程序: 1.新建一个基于MFC项目工程Chat 2.加载套接字库,有下面两种方法,在这里选择第二种方法,因为更方便。 方法一、使用WSAStartup()加载套...
  • lvjun93
  • lvjun93
  • 2013年01月04日 17:32
  • 728

VC++深入详解 笔记 第三章(2) 一个单文档MFC应用程序的创建过程

P66 对于一个单文档应用程序,都有一个CMainFrame类,一个以"C+工程名+App"为名字的类,一个以"C+工程名+Doc"为名字的类和一个以"C+工程名+View"为名字的类。假设建立一个名...

又做了一个小程序,修改文件夹图标。

又做了一个小程序,修改文件夹图标。 回家有好几天,每天闲得蛋疼,想动手写点东西。之前学软件换肤的时候,发现这个界面设计呀是很重要的,直接可以影响用户对一款软件的评价。既然是美化那windows需不需要...

VC一个简化的贪吃蛇程序(MFC)

  • 2009年09月10日 20:19
  • 3.07MB
  • 下载

VC一个很简单的屏保程序(MFC)

  • 2009年09月10日 19:51
  • 13.19MB
  • 下载

文奇的WY实习连载日记:5.17-如果你觉得生活很无聊,你去问一个程序员,他一天都做了什么。

今天又和gradle完了一天。我日gradle大爷。有强迫症伤不起。 以前也说道,当我集成bottom-navigation-bar的时候会报错: Error:Execution failed f...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:终于用VC/MFC做了一个真正的程序
举报原因:
原因补充:

(最多只允许输入30个字)