游戏安全实验室 首页 技术入门 查看内容

 阅读目录

使用MFC开发界面程序

发布于:2016-6-12 16:06   |    169966次阅读 作者: 管理员    |   原作者: TP   |   来自: 原创

一、创建基于对话框的MFC程序

    首先打开Visual Studio 2013开发环境,如图1所示。依次点击【文件】> 【新建】> 【项目】创建一个新的项目。

图1

接下来进入创建项目界面如图2所示。依次选择【已安装】 > 【模版】 > 【Visual C++】 > 【MFC】来到MFC程序类型选择界面,选择【MFC应用程序】这一列。在创建项目界面的最下方分别输入自定义的工程名称、项目保存路径以及项目名称,点击确定即可来到MFC工程创建界面,如图3所示。

图2

图3

在图3界面切记点击【下一步】按钮而不是点击【完成】按钮,否则你得到的将会是一个复杂的、基于文档的MFC程序而不是基于对话框的MFC程序。点击【下一步】之后来到MFC 程序类型选择界面,如图4所示。这时候【基于对话框(D)】单选按钮选中,点击【完成】即完成一个MFC对话框程序的创建。

图4

二、对工程进行个性化设置

依次点击菜单的【项目】 > 【工程】选项,如图5所示,可来到工程配置界面。

图5

1、给程序添加管理员权限

在Vista以后的操作系统中对权限控制变得比较严格,目前64位Win 7操作系统已经成为主流操作系统,在Win 7 x64系统上的很多操作都需要administrator权限。在VS2013以前的版本中开发一个指定administator权限的程序虽然可以,但实现起来会比较麻烦,在VS2013之后的开发环境中在完成这部分工作就变得十分容易。

    如图6所示,依次点击【配置属性】 > 【链接器】 > 【清单文件】,里面会有个【UAC执行级别】的选项。该选项默认值为:asInvoker (/level='asInvoker'),权限为一般用户权限,修改为:requireAdministrator (/level='requireAdministrator')点击应用,重新编译之后的程序将自动请求最高权限执行级别。

图6

当程序UAC执行级别为administrator级别时程序图标上都将具有一个盾牌状的标识,运行该程序时默认操作系统会弹出一个提示框,点击【是(Y)】之后程序将具有管理员权限。

7

2、对工程设定字符集

在windows平台上最常用的字符编码方式有2种,一种是ansi的,另一种是unicode的。每个ansi字符占一个字节,一个字节共8 bit,所以一个ansi字符最多能表达2的8次方种情况,也就是最多只有256种可能的情况。当计算机在全世界范围内流行起来之后,世界各地使用的语言各不相同,比如中国的汉字个数就远大与256种情况,这时候用一个字节就没法存储所有字符,为了解决这种情况后来就有采用unicode编码。unidoe字符每个字符用2个字节16 bit来表示,那么最多可以表达65536种情况,这已经满足了世界上绝大多数国家和地区的语言需求。

与字符编码方式相对应,字符集也分为2种。一种叫“多字节字符集”,另一种直接叫“unicode字符集”。多字节字符集是指当前字符如果能用1个字节表示的就用1个字节表示,而一些不能用1个字节表示的字符则用2个字节表示。例如字符串“叫我007”这句话,如果是多字节字符集则前2个中文字符每个占2字节,后3个字符则每个占用1字节,加上1字节结尾符共占用8字节;如果是unicode字符集则2个汉字和3个字母都是占用2字节,加上2字节的结尾符共占用12字节内存。

VC6等较老的开发环境默认采用多字节字符集,而VS2013等较新的开发环境则默认采用unicode字符集。一些习惯在VC6上开发代码的人才转移到VS2013平台上时可能不太习惯采用unicode字符集的编码方式,这时候就可以通过修改配置在VS2013上也采用多字节字符集。修改方式见图8,在工程的配置设置窗口里,依次选择【配置树形】 > 【常规】,里面有个字符集的配置项,点击下拉按钮可以看到使用多字节字符集的选项。

8

三、给对话框添加各种控件

首先要打开资源视图。如图9所示,在整个VS2013开发环境左下角有一行视图按钮,其中包含“解决方案资源管理器”、“类视图”、“资源视图”等Tab项,这3个视图是开发过程中使用较多的视图方式。如果选择“解决方案资源管理器”则通过文件的方式来查看整个工程;“类视图”则查看代码中的所有所有常量宏定义、全局函数及全局变量和类的定义及成员变量等;如果选择“资源视图”则程序中的对话框资源、菜单资源、Icon资源、以及Version和一些自定义资源等都在这里能看到。

9

见图9我们可以看到有2个Dialog资源,以Button控件为例。选择我们需要添加控件的Dialog资源进行双击就可以打开该资源。本案例我们选择资源ID为IDD_MFCAPPLICATION1_DIALOG的Dialog。开发过程中如果大家不清楚哪个Dialog是自己想修改的Dialog,那么可以都双击打开一下看看对话框布局就清楚了。

打开Dialog资源后点击最右变的“工具箱”按钮打开对话框的工具箱,工具箱里面包含了最常见的各种控件,如图10所示。

以Button控件为例,鼠标点击一下工具箱中的Button图标,然后在Dialog资源界面按住鼠标左键向右下角拉,拉到合适大小后松开左键即可发现对话框中已经有了一个Button控件。基本所有控件的添加方式都基本一致,其它控件的添加方法雷同后面就不再重复写了。

10

 

四、MFC中几个关键的函数以及成员函数添加方法

1、MFC对话框程序中常见的类

基于MFC的对话框程序一般包含2个类,一个是CWinApp的子类,一个是CDialog的子类。已本章节示例代码为例,本工程名为MFCApplication1,那么两个子类名分别为CMFCApplication1App,CMFCApplication1Dlg。在MFC的内部实现相当复杂,如果想对MFC内部实现有比较深刻的认识,建议学习一下侯捷大师编著的《深入浅出MFC》一书。而在这篇文章中不会详细解释原理,而更多介绍开发过程中需要注意什么。

在MFC程序执行过程中CWinApp的子类是先于CDialog的子类执行的。一个程序中一般只有一个CWinApp的子类而可以有多个CDialog的子类,CDialog子类可以根据需要随时添加。这两个类在开发过程中涉及最多的除了构造函数和析构函数外,还有以下几个函数需要关注:

CWinApp:InitInstance();

CWinApp:ExitInstance();

CDialog::DoModal();

CDialog::OnInitDialog();

CWinApp:InitInstance()和CWinApp:ExitInstance()这两个函数一般是成对出现,InitInstance()中一般添加程序整个生命周期内中只需要执行一次的初始化逻辑,比如网络初始化的WSAStartup操作等。而ExitInstance()中则是对这些初始化的反操作,例如WSACleanup。CDialog类一般是在CWinApp:InitInstance()内创建的,所以所有和对话框相关的操作不要放到CMFCApplication1App类的构造函数中或者InitInstance前半部分执行,那时候对话框对象还没有创建,做这些操作将会导致程序崩溃。CDialog子类的创建及对话框显示相关代码如下:

BOOL CMFCApplication1App::InitInstance()

{

INITCOMMONCONTROLSEX InitCtrls;

InitCtrls.dwSize = sizeof(InitCtrls);

// 将它设置为包括所有要在应用程序中使用的

// 公共控件类。

InitCtrls.dwICC = ICC_WIN95_CLASSES;

InitCommonControlsEx(&InitCtrls);

 

CWinApp::InitInstance();

 

AfxEnableControlContainer();

 

// 创建 shell 管理器,以防对话框包含

// 任何 shell 树视图控件或 shell 列表视图控件。

CShellManager *pShellManager = new CShellManager;

 

// 激活“Windows Native”视觉管理器,以便在 MFC 控件中启用主题

CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

 

// 标准初始化

SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

 

CMFCApplication1Dlg dlg;

m_pMainWnd = &dlg;

INT_PTR nResponse = dlg.DoModal();

......

 

DoModal()函数用来把一个对话框类显示出来,OnInitDialog()一般用来初始化一些控件的属性等。

2、MFC程序中类成员函数添加方法

MFC类的成员函数一般分为2类。一类是自定义的类成员函数,另外一类是类的虚函数。类的自定义成员函数可以自定义(函数名、参数个数、参数类型都可自定义),函数调用上也需要开发人员主动调用。例如对话框中如果有一个List Control控件,那么就可以添加一个自定义的函数来负责这部分操作,然后再OnInitDialog对话框中主动调用这个控件初始化函数。类的虚函数一般是消息处理函数,他们的函数定义一般是固定的,函数参数固定,调用时机也是固定的。比如OnInitDialog函数就是CDialog类的一个虚函数,该函数不需要开发人员主动调用,当对话框显示时系统(MFC库代码)会帮你自动调用。这两类函数添加方式并不相同,这里分别给出两种函数的添加方式。

自定义函数的添加方式如图11所示,在需要添加函数的类上点击右键弹出菜单,然后选【添加】 > 【添加函数】或者【添加变量】。

11

添加函数的界面如图12所示,可以添加自定义的函数,也可以添加一些非标准MFC的虚函数。如果是添加标准MFC虚函数则需要通过【类向导】菜单添加,添加界面如图13所示。

12

13

 

五、控件的变量关联

在程序中除了我们一定自己定义的各种数据型变量外,也可以定义一个控件变量,把控件的状态和变量值关联起来。在控件上点击鼠标右键,单击【添加变量】来到控件关联变量窗口,如下图14所示。在变量关联界面需要注意的地方有两个。第一个就是“类别”这里,通过下拉框选择是关联Control型变量还是Value型变量;第二个就是“变量类型”这里,一般关联Value型变量时可以有不同的Value类型。控件关联变量是一个很有用处的技巧,使用这里可以很大程度上减小开发工作量。

14

六、各控件关键属性介绍

    Button控件最重要的几个属性如下:

1、Disabled,该值表明该Button是否可用,可用则值为false;不可用则值为true,这时候Button为灰色不可点击状态。

2、Visible,该值表明该控件是否可见。如果为false则运行后该控件不可见,默认情况下该值为true。

3、Caption,该值是一个字符串,也就是Button按钮上边显示的文字。修改Caption的值则Button上的值也随之更新。

4、ID,该值是一个用字符串表示的INT型宏定义,你不修改该值也不影响该Button的使用。但从编码习惯来讲最好把改值修改为一个比较容易阅读和理解的字符串。如果该button我打算用来做一个功能的开关,那么我的个人习惯是会把IDC_BUTTON1修改为IDC_BTN_SWITCH,BTN是button的缩写表明该ID是一个button的控件ID,SWITCH表明该button的作用是开关作用。那么我只要看到该控件ID就知道控件类型和控件作用,对理解程序逻辑有帮助。

 

Edit Control控件最重要的几个属性如下:

1、Multiline,该属性用来指明edit控件是否可以支持多行输入。

2、Password,该属性用来指明edit控件是否为密码输入框,如为密码输入框则输入后以星号代替显示内容确保密码不泄漏。

3、Want Return,该属性用来指明是否可以回车换行。

4、Align Text,该属性用来指明文字是靠左显示还是靠右显示。

5、LowerCase\UpperCase,该属性用来指明只支持小写字符还是大写字符输入,如果不是则自动转换。

6、ID字段,和Button控件的ID字段作用类似。

 

Group Box控件、Static Text控件、Check Box控件、Radio Button控件的基本属性:

1、Caption,用来显示控件的显示文字。

    Group Box和Static Text一般都没有实际作用,都是起到美化UI的作用。Gruop Box用来分割窗口为几个相对独立的区域,而Static Text则用来在一些地方显示一些文字用来提示周围其它控件的作用。Check Box一种用来作为多选开关用,而Radio Button则用来做互斥的单选开关。

 

七、各控件使用demo

为了演示控件的使用,我们先虚构一个需求。假设我们刚刚分析完了一个FPS的游戏,实现了常规3D透视、驱动层透视以及自动喝血瓶功能,接下来想给我们的辅助程序开发一个界面出来,同时加入用户名和密码功能预防其它人使用我们的程序。本示例demo主要完成UI布局和用户输入信息的获取,涉及和游戏逻辑相关的部分暂不涉及后面再讲。

1、第一步根据前面介绍的添加控件方式添加各控件如下图15所示:

红字标注1:Button控件

红字标注2:Check Box控件

红字标注3:Edit Control控件

红字标注4:Group Box控件

红字标注5:Radio Button控件

红字标注6:Static Text控件

2、接下来修改各控件属性,设置帐号输入框ID为IDC_EDT_USER;密码输入框Password属性值为True,ID为IDC_EDT_PASSWORD;记住帐号控件ID为IDC_CHECK_SAVE,回血开关的控件ID为IDC_CHECK_HP,血量输入的输入框控件ID为IDC_EDT_HP,常规透视控件ID为IDC_RADIO_FN1,驱动透视的控件ID为IDC_RADIO_FN2。IDC_BTN_START的Disabled属性为True,确保登录验证没成功前该按钮不可点击。

3、开始之前先给控件关联变量以方便后面处理。先给IDC_CHECK_SAVE控件关联一个BOOL型变量值m_bSaveLastLogin;给IDC_CHECK_HP控件关联一个BOOL型变量m_bRecoverHp,给IDC_RADIO_FN1关联一个int型变量m_nRadioIndex;给IDC_EDT_HP关联一个int型变量m_nMinHpValue。 关联方式前面已介绍这里不再详细描述。关联操作最核心代码在CMFCApplication1Dlg::DoDataExchange中实现:

void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)

{

CDialogEx::DoDataExchange(pDX);

DDX_Radio(pDX, IDC_RADIO_FN1, m_nRadioIndex);

DDX_Check(pDX, IDC_CHECK_SAVE, m_bSaveLastLogin);

DDX_Check(pDX, IDC_CHECK_HP, m_bRecoverHp);

DDX_Text(pDX, IDC_EDT_HP, m_nMinHpValue);

}

4、双击登录按钮,添加登录按钮的响应处理函数。

void CMFCApplication1Dlg::OnBnClickedBtnLogin()

{

//使界面属于与关联变量同步

UpdateData(TRUE);

 

wchar_t wzUserName[256] = { 0 };

wchar_t wzPassword[256] = { 0 };

wchar_t wzOutputText[1024] = { 0 };

 

//从控件获取账户信息

GetDlgItem(IDC_EDT_USER)->GetWindowTextW(wzUserName, 256);

 

//从控件获取账户信息

GetDlgItem(IDC_EDT_PASSWORD)->GetWindowTextW(wzPassword, 256);

 

//这里假设标准账户为root,密码为gslab.qq.com 

if (wcscmp(wzUserName, L"root") != 0 || wcscmp(wzPassword, L"gslab.qq.com") != 0)

{

wsprintfW(wzOutputText,

L"你输入的用户名为:%s, 密码为:%s\r\n该信息不正确,请重新输入!",

wzUserName, wzPassword);

MessageBox(wzOutputText, L"警告");

return;

}

else

{

MessageBox(L"用户名和密码验证成功!", L"恭喜");

GetDlgItem(IDC_BTN_START)->EnableWindow(TRUE);

 

//该变量已与控件关联,如控件选中则变量为TRUE,否则为FALSE

if (m_bSaveLastLogin == TRUE)

{

//如果是一个真实的辅助,那么这里就需要把用户名和密码信息加密存档

MessageBox(L"你选择了保存用户名和密码信息!", L"通知");

}

}

}

5、双击功能开启按钮,添加按钮响应函数。

void CMFCApplication1Dlg::OnBnClickedBtnStart()

{

UpdateData(TRUE);

if (m_nRadioIndex == 0)

{

MessageBox(L"需开启常规透视功能!", L"警告");

}

if (m_nRadioIndex == 1)

{

MessageBox(L"需开启驱动透视功能!", L"警告");

}

if (m_bRecoverHp == TRUE)

{

wchar_t wzOutputText[1024] = { 0 };

wsprintfW(wzOutputText, 

L"你设定的血量最小值为:%d,获取当前血量值进行比较并判断是否要自动回血",

m_nMinHpValue);

MessageBox(wzOutputText, L"警告");

}

}


*转载请注明来自游戏安全实验室(GSLAB.QQ.COM)

分享到:
踩0 赞1

收藏

上一篇:开发篇导读

下一篇:List Control控件使用

最新评论
B Color Image Link Quote Code Smilies

发表评论