MFC 飞信发短信

这段时间,我在学习vc。以前一直是在用C#和Java的,最近发现MFC还是有一定的用处的,所以就利用暑假这段时间来学习一下。但是光看书没有用,几 个月之前,我用C#实现了一个飞信发短信的接口。所以这次,以学习MFC为目的,写了一个MFC版的飞信发短信接口。开发工具用的是Visual studio 2005。

    其中用到了MFC中的众多功能,如Socket、CString类的使用、Winnet、加密(hash)、ATl提供的正则表达式库和调用Dom解析 xml等等。最后,我将该接口做成了一个MFC dll,从而也学习了MFC dll的制作和使用。编译的时候采用默认的Unicode编码。另外,其中还涉及到编码的转换等等。在处理字符串的时候基本都用CString,不知道这 种习惯好不好。
    接口中只提供一个CFetion类,其中提供3个函数,功能主要登陆、发送短信和登出,相当简单,一看就明白。由于其中调用了Com,所以调用的时候需要进行Com的初始化工作。下面是一个使用的例子:
#include "Fetion.h"
#pragma comment(lib, "MFCFetionSDK.lib")
CoInitialize(NULL);
CFetion fetion(_T("你的手机号"), _T("你的密码"));
fetion.Login();
fetion.SendSMSToPhone(_T("好友手机号"), _T("要发送的消息。"));
fetion.Logout();
CoUninitialize();
    速度方面,我测试一下,还是相当快的,占的内存也非常的少。
    关于飞信协议方面,还是采用MD5进行加密的,改成SHA1也相当简单。在我之前的文章中,我讲到一些关键技术的实现方法。由于刚刚初学MFC,其中肯定写得很烂,所以代码先不提供了。如果有需要,可以发邮件给我。mailto:ssdut@126.com。
    下面说一下,我解决的几个关键性的问题,也方便刚初学MFC的朋友。
    1、如何导出MFC类?
    这个问题折磨了我很久,vs2005中新建一个MFC dll的时候会产生一个.def文件,用来导出函数,但我上网查了好多资料,都没有实现用.def导出类。网上有说可以生成map文件后,通过查看其中的 信息导出类中的函数。我嫌麻烦,最后通过AFX_CLASS_EXPORT进行导出的。导入用AFX_CLASS_IMPORT。
    2、如何用afxinet.h访问https
    飞信在登录的时候用到https,好像我试了一下http同样是可行的,但是我觉得不够安全,所以选择使用https。但是这和C#中一样,访问 https的是有会出现证书的问题。网上资料很少,可能是我找资料的方法不对,最后在一个国外网站上找到一个solution。
AfxParseURL(url, type, server, param, port);
connection = session.GetHttpConnection(server, port);
if(type == 4107)
{
file = connection->OpenRequest(CHttpConnection::HTTP_VERB_GET, param, NULL, 1, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID);
}
    3、编码转换和hash的计算
    编码转换用的Windows api中的WideCharToMultiByte和MultiByteToWideChar。而hash用的是#include <wincrypt.h>。下面是我用到的工具类。

#pragma  once


//  CUtils

#pragma  region  编码CodePage表
enum  CodePages
{
    IBM037
= 37 ,
    IBM437
= 437 ,
    IBM500
= 500 ,
    ASMO_708
= 708 ,
    DOS_720
= 720 ,
    ibm737
= 737 ,
    ibm775
= 775 ,
    ibm850
= 850 ,
    ibm852
= 852 ,
    IBM855
= 855 ,
    ibm857
= 857 ,
    IBM00858
= 858 ,
    IBM860
= 860 ,
    ibm861
= 861 ,
    DOS_862
= 862 ,
    IBM863
= 863 ,
    IBM864
= 864 ,
    IBM865
= 865 ,
    cp866
= 866 ,
    ibm869
= 869 ,
    IBM870
= 870 ,
    windows_874
= 874 ,
    cp875
= 875 ,
    shift_jis
= 932 ,
    gb2312
= 936 ,
    ks_c_5601_1987
= 949 ,
    big5
= 950 ,
    IBM1026
= 1026 ,
    IBM01047
= 1047 ,
    IBM01140
= 1140 ,
    IBM01141
= 1141 ,
    IBM01142
= 1142 ,
    IBM01143
= 1143 ,
    IBM01144
= 1144 ,
    IBM01145
= 1145 ,
    IBM01146
= 1146 ,
    IBM01147
= 1147 ,
    IBM01148
= 1148 ,
    IBM01149
= 1149 ,
    utf_16
= 1200 ,
    unicodeFFFE
= 1201 ,
    windows_1250
= 1250 ,
    windows_1251
= 1251 ,
    Windows_1252
= 1252 ,
    windows_1253
= 1253 ,
    windows_1254
= 1254 ,
    windows_1255
= 1255 ,
    windows_1256
= 1256 ,
    windows_1257
= 1257 ,
    windows_1258
= 1258 ,
    Johab
= 1361 ,
    macintosh
= 10000 ,
    x_mac_japanese
= 10001 ,
    x_mac_chinesetrad
= 10002 ,
    x_mac_korean
= 10003 ,
    x_mac_arabic
= 10004 ,
    x_mac_hebrew
= 10005 ,
    x_mac_greek
= 10006 ,
    x_mac_cyrillic
= 10007 ,
    x_mac_chinesesimp
= 10008 ,
    x_mac_romanian
= 10010 ,
    x_mac_ukrainian
= 10017 ,
    x_mac_thai
= 10021 ,
    x_mac_ce
= 10029 ,
    x_mac_icelandic
= 10079 ,
    x_mac_turkish
= 10081 ,
    x_mac_croatian
= 10082 ,
    utf_32
= 12000 ,
    utf_32BE
= 12001 ,
    x_Chinese_CNS
= 20000 ,
    x_cp20001
= 20001 ,
    x_Chinese_Eten
= 20002 ,
    x_cp20003
= 20003 ,
    x_cp20004
= 20004 ,
    x_cp20005
= 20005 ,
    x_IA5
= 20105 ,
    x_IA5_German
= 20106 ,
    x_IA5_Swedish
= 20107 ,
    x_IA5_Norwegian
= 20108 ,
    us_ascii
= 20127 ,
    x_cp20261
= 20261 ,
    x_cp20269
= 20269 ,
    IBM273
= 20273 ,
    IBM277
= 20277 ,
    IBM278
= 20278 ,
    IBM280
= 20280 ,
    IBM284
= 20284 ,
    IBM285
= 20285 ,
    IBM290
= 20290 ,
    IBM297
= 20297 ,
    IBM420
= 20420 ,
    IBM423
= 20423 ,
    IBM424
= 20424 ,
    x_EBCDIC_KoreanExtended
= 20833 ,
    IBM_Thai
= 20838 ,
    koi8_r
= 20866 ,
    IBM871
= 20871 ,
    IBM880
= 20880 ,
    IBM905
= 20905 ,
    IBM00924
= 20924 ,
    EUC_JP
= 20932 ,
    x_cp20936
= 20936 ,
    x_cp20949
= 20949 ,
    cp1025
= 21025 ,
    koi8_u
= 21866 ,
    iso_8859_1
= 28591 ,
    iso_8859_2
= 28592 ,
    iso_8859_3
= 28593 ,
    iso_8859_4
= 28594 ,
    iso_8859_5
= 28595 ,
    iso_8859_6
= 28596 ,
    iso_8859_7
= 28597 ,
    iso_8859_8
= 28598 ,
    iso_8859_9
= 28599 ,
    iso_8859_13
= 28603 ,
    iso_8859_15
= 28605 ,
    x_Europa
= 29001 ,
    iso_8859_8_i
= 38598 ,
    iso_2022_jp
= 50220 ,
    csISO2022JP
= 50221 ,
    iso_2022_kr
= 50225 ,
    x_cp50227
= 50227 ,
    euc_jp
= 51932 ,
    EUC_CN
= 51936 ,
    euc_kr
= 51949 ,
    hz_gb_2312
= 52936 ,
    GB18030
= 54936 ,
    x_iscii_de
= 57002 ,
    x_iscii_be
= 57003 ,
    x_iscii_ta
= 57004 ,
    x_iscii_te
= 57005 ,
    x_iscii_as
= 57006 ,
    x_iscii_or
= 57007 ,
    x_iscii_ka
= 57008 ,
    x_iscii_ma
= 57009 ,
    x_iscii_gu
= 57010 ,
    x_iscii_pa
= 57011 ,
    utf_7
= 65000 ,
    utf_8
= 65001
};
#pragma  endregion

class  CUtils :  public  CObject
{
public :
    CUtils();
    
virtual  ~ CUtils();
    
static  void  UnicodeToOther( const  CStringW  & src, CStringA &  result, CodePages codePage);
    
static  void  OtherToUnicode( const  CStringA &  src, CStringW &  result, CodePages codePage);
    
static  void  EncodingConvert( const  CStringA &  src, CodePages srcCodePage, CStringA &  result, CodePages resultCodePage);
    
static  CStringA ComputeHash( const  CStringA &  pbData, UINT algId);
};
CUtils::CUtils()
{

}

CUtils::
~ CUtils()
{
}

void  CUtils::UnicodeToOther( const  CStringW  & src, CStringA  & result, CodePages codePage)
{
    
int  n  =  WideCharToMultiByte(codePage,  0 , src.GetString(),  - 1 0 0 0 0  );
    WideCharToMultiByte(codePage, 
0 , src.GetString(),  - 1 , result.GetBuffer(n), n,  0 0  );
    result.ReleaseBuffer();
}

void  CUtils::OtherToUnicode( const  CStringA  & src, CStringW  & result, CodePages codePage)
{
    
int  n  =  MultiByteToWideChar(codePage,  0 , src.GetString(),  - 1 , NULL,  0 );
    MultiByteToWideChar(codePage, 
0 , src.GetString(),  - 1 , result.GetBuffer(n), n);
    result.ReleaseBuffer();
}

void  CUtils::EncodingConvert( const  CStringA  & src, CodePages srcCodePage, CStringA  & result, CodePages resultCodePage)
{
    CStringW buffer;
    OtherToUnicode(src, buffer, srcCodePage);
    UnicodeToOther(buffer, result, resultCodePage);
}

CStringA CUtils::ComputeHash(
const  CStringA &  pbData, UINT algId)
{
    HCRYPTPROV hProv;
    CryptAcquireContext(
& hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    HCRYPTHASH hHash;

    
// Alg Id:CALG_MD5,CALG_SHA
    CryptCreateHash(hProv, algId,  0 0 & hHash);
    CryptHashData(hHash, (
const  BYTE * )pbData.GetString(), pbData.GetLength(),  0 );
    CStringA pbOutHash;
    DWORD dwHashLen;
    DWORD dwLen 
=  sizeof (dwHashLen);
    CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE
* )( & dwHashLen),  & dwLen,  0 );
    dwLen 
=  dwHashLen;
    CryptGetHashParam(hHash, HP_HASHVAL, (BYTE
* )pbOutHash.GetBufferSetLength(dwLen),  & dwLen,  0 );

    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 
0 );
    
return  pbOutHash;
}

    其中用到的都是CString,Unicode用的是CStringW,多字节的用的是CStringA。这好像在VC6中只有CString,并不分 什么CStringA和CStringW。所以这不适合在VC6中使用。 那个Codepages是我从C#中找过来的,竟然发现一个重复的,我直接做删 除处理,也不知道对不对,但我知道utf-8是对的。
    4、关于头文件的问题
    我的dll中Fetion.dll中远不只这三个函数,还有很多私有函数和私有成员。我在提供Fetion.h中都删除了,开始发现删除之后不好用了, 后来我把其中要到的指针成员改成普通的对象就好用了。但是在debug的版本的时候,告诉我fetion对象被破坏了,不知道怎么回事。幸好在 release版本中,一切正常。
    5、关于飞信
    飞信的协议分析,我是借助别人的成果,我自己没有去抓包分析,也没有去反编译,和我写的C#版本一样,是通过看别人用php版本,翻译过来的。
   总结
   通过这个简单的小例子,基本对MFC的非窗体使用有了一个了解,会运用各种东西来处理自己想要的效果。对于窗体编程,我的经验不是很多。我也编写了一个小例子,一个隐藏和现实窗口的小程序。在以后的文章中介绍。
   dll和例子: MFCFetionSDK.rar
    由于好多人发邮件给我要源代码,所以在此提供源代码的下载:mfcfetion.rar
    转载请保持文章的完整性,并注明出处。
作者: 小橋流水
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

另外一个飞信实现例子开源

http://www.cnblogs.com/solo/archive/2009/03/11/1408801.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值