MFC如何创建多按钮功能的界面
MFC如何创建多按钮功能的界面
最终的效果如下:点击按钮“方块”,弹出方块设置对话框,输入值然后点OK时,绘画方块图像;点击按钮“三角”,同样弹出三角设置对话框然后点OK时,绘画三角图像。
下面介绍制作步骤:
一、创建一图形显示界面
二、创建两图形显示界面
三、创建三图形显示界面
四、创建四图形显示界面
1.打开visual C++,点“文件”,“新建”,“MFC AppWizard(exe)”,“工程名称”,“位置”,
“确定”“基本对话框”“完成”
2.得到如图:
按照我的习惯,“确定”“取消”和“TODO”全部删掉,如图:
3. 创建三个按钮和一个静态文本,分别命名“方块”“三角”“OK”。静态文本清空,其属性里“扩展样式”“静态边缘”打勾。他们的ID分别为:IDC_fang,IDC_san,IDC_OK,IDC_DRAW。如图:
4. 双击“方块”按钮,点“确定”,然后输入代码:
void CTest425Dlg::Onfang()
{ // TODO: Add your control notification handler code here
extern int flag;
flag=1;
}
其中变量flag的作用是用来标志,用来判断接下来点“OK”的时候,执行哪种操作。
因为是全局变量,所以加上了extern
同样,双击“三角”按钮,输入代码:
void CTest425Dlg::Onsan()
{ // TODO: Add your control notification handler code here
extern int flag;
flag=2;
}
当然,如果我们需要更多功能时,可以绘制更多的按钮,然后给他们flag=3,flag=4等等的赋值。
5. 双击“OK”按钮,输入代码前半段:
void CTest425Dlg::OnOk()
{ // TODO: Add your control notification handler code here
extern int flag;
CWnd *pWnd=GetDlgItem(IDC_DRAW);
CDC *pDC=pWnd->GetDC();
CBrush WhiteBrush;
WhiteBrush.CreateSolidBrush(RGB(255,255,255));
CRect rect;
pWnd->Invalidate();
pWnd->UpdateWindow();
pWnd->GetClientRect(&rect);
}
这些代码的作用是初始画图功能。
再输入代码后半段:
switch(flag)
{
case 1: // fangkuai
pDC->MoveTo(20,20);
pDC->LineTo(20,200);
pDC->MoveTo(20,200);
pDC->LineTo(200,200);
pDC->MoveTo(200,200);
pDC->LineTo(200,20);
pDC->MoveTo(200,20);
pDC->LineTo(20,20);
break;
case 2: //sanjiao
pDC->MoveTo(20,20);
pDC->LineTo(20,200);
pDC->MoveTo(20,200);
pDC->LineTo(200,200);
pDC->MoveTo(200,200);
pDC->LineTo(20,20);
break;
case 3: //yuanxing
case 4: //zhengxuan
default:
break;
}
如果需要更多功能,可以不断加“case”对应于不同的flag值。代码内容不难分析,其中,方块和三角的顶点坐标值都是固定给好的,比如,三角的顶点坐标分别为:(20,20);(20,200);(200,200)。
6.最后,为了使全局变量flag可以正常使用,点击“FileView”
然后找到“StdAfx.cpp”,并双击,添加代码:“int flag”
像;点击按钮“三角”,然后点OK时,绘画三角图像。此时方块和三角的位置都是固定的。
8. 下面,我们继续添加更多功能:使得点击“方块”按钮时,弹出一个对话框,要求输入顶点初始值,确定后点击“OK”时,画出所需位置的方块。三角也同样如此。
首先,点击“插入”“资源”“Dialog”“新建”,然后再重复一次,这样我们新建了两个对话框。
再重复一次后:
9. 根据我的习惯,把两个对话框的“确定”“取消”都删掉,然后在对话框上点右键,点“属性”,ID分别为:IDD_FANGSET;IDD_SANSET;名称为:“方块设置”,“三角设置”。
10. 为了让对话框与函数关联,我们需要建立对应的类,在“方块设置”对话框上双击,选择“创建新的类”“OK”,
名字叫做CFangSetDlg,点“OK”,其中,名字开头的C是标识,我们可以注意到下面的文件名是不带C的。最后点“确定”。如此重复把三角的类也建立起来,名字叫:CSanSetDlg。
成功的话,我们可以在ClassView里看到这两个新建的类。
11. 下面我们把“方块”和“三角”按钮与调出对话框对应起来。在“方块”按钮上双击,更改“方块”按钮的代码:
void CMfcDlg::OnFang()
{
// TODO: Add your control notification handler code here
extern int flag;
flag=1;
CFangSetDlg dlg;
dlg.DoModal();
}
同理,三角也改了:
CSanSetDlg dlg;
dlg.DoModal();
这两条语句的作用是调出类所对应的对话框。
12. 不可缺少的是,如果不在头文件里引用我们所创建的两个对话框的类,程序是不能直接识别我们添加的代码的,所以点击“FileView”,“Header Files”,“test425Dlg.h”,在右边的代码里添加上引用类的语句:
#include”FangSetDlg.h”,
三角也同样加进去:
#include”SanSetDlg.h”
注意,test425是我工程的名称,Dlg是一定要加在后面的,不要选错点成了“test425.h”,而是“test425Dlg.h”,类的名称是不带C的,“FangSetDlg.h”不要写错成了“CFangSetDlg.h”
13. 现在,编译,执行,可以看到,点击“方块”和“三角”按钮时,对应的对话框会自动跳出来了。
我们继续在对话框内添加功能,“方块设置”对话框内添加两个编辑框,ID分别为:IDC_EDIT_LENGTH,IDC_EDIT_WIDTH;
再添加一个“设置好了”按钮,ID为:IDC_FANGOK
14. 双击“设置好了”,添加代码,目的是当点击“设置好了”时,把长和宽的数据转到变量中。
void CFangSetDlg::OnFangok()
{
// TODO: Add your control notification handler code here
extern double m_length, m_width;
extern char ch_length[10], ch_width[10];
GetDlgItem(IDC_EDIT_LENGTH)->GetWindowText(ch_length,10);
GetDlgItem(IDC_EDIT_WIDTH)->GetWindowText(ch_width,10);
m_length=atof(ch_length);
m_width=atof(ch_width);
CFangSetDlg::EndDialog(0);
}
赋值的过程是:先把编辑框的内容转到字符串数组中(ch_legth,ch_width),再把字符串数组转变成数据(m_length,m_width)。
最后EndDialog(0)的作用是关闭对话框。
和之前的Flag类似,我们要把extern变量全局化,所以在StdAfx.cpp中:
double m_length, m_width;
char ch_length[10], ch_width[10];
15. 同样的原理,添加“三角设置”的内容
ID自左到右,自上向下:
IDC_EDIT_AX,IDC_EDIT_AY,
IDC_EDIT_BX,IDC_EDIT_BY,
IDC_EDIT_CX,IDC_EDIT_CY,
IDC_SANOK
IDC_SANOK的代码:
void CSanSetDlg::OnSanok()
{
// TODO: Add your control notification handler code here
extern double m_ax, m_ay, m_bx, m_by, m_cx, m_cy;
extern char ch_ax[10],ch_ay[10],ch_bx[10],ch_by[10],ch_cx[10],ch_cy[10];
GetDlgItem(IDC_EDIT_AX)->GetWindowText(ch_ax,10);
GetDlgItem(IDC_EDIT_AY)->GetWindowText(ch_ay,10);
GetDlgItem(IDC_EDIT_BX)->GetWindowText(ch_bx,10);
GetDlgItem(IDC_EDIT_BY)->GetWindowText(ch_by,10);
GetDlgItem(IDC_EDIT_CX)->GetWindowText(ch_cx,10);
GetDlgItem(IDC_EDIT_CY)->GetWindowText(ch_cy,10);
m_ax=atof(ch_ax);
m_ay=atof(ch_ay);
m_bx=atof(ch_bx);
m_by=atof(ch_by);
m_cx=atof(ch_cx);
m_cy=atof(ch_cy);
CSanSetDlg::EndDialog(0);
}
添加StdAfx.cpp的内容:
#include "stdafx.h"
int flag;
double m_length, m_width;
char ch_length[10], ch_width[10];
double m_ax, m_ay, m_bx, m_by, m_cx, m_cy;
char ch_ax[10],ch_ay[10],ch_bx[10],ch_by[10],ch_cx[10],ch_cy[10];
16. 接着,我们要把“OK”按钮的画图语句更改,使之按照输入的数据值来画图第一步,添加extern:
void CMfcDlg::OnOk()
{
// TODO: Add your control notification handler code here
extern int flag;
extern double m_length, m_width;
extern char ch_length[10], ch_width[10];
extern double m_ax, m_ay, m_bx, m_by, m_cx, m_cy;
extern char ch_ax[10],ch_ay[10],ch_bx[10],ch_by[10],ch_cx[10],ch_cy[10];
CWnd *pWnd=GetDlgItem(IDC_DRAW);
CDC *pDC=pWnd->GetDC();
CBrush WhiteBrush;
WhiteBrush.CreateSolidBrush(RGB(255,255,255));
CRect rect;
pWnd->Invalidate();
pWnd->UpdateWindow();
pWnd->GetClientRect(&rect);
第二步,更改方块绘画语句:
switch(flag)
{
case 1: // fangkuai
pDC->MoveTo(20,20);
pDC->LineTo(20,20+m_width);
pDC->MoveTo(20,20+m_width);
pDC->LineTo(20+m_length,20+m_width);
pDC->MoveTo(20+m_length,20+m_width);
pDC->LineTo(20+m_length,20);
pDC->MoveTo(20+m_length,20);
pDC->LineTo(20,20);
break;
第三步,更改三角绘画语句:
case 2: //sanjiao
pDC->MoveTo(m_ax,m_ay);
pDC->LineTo(m_bx,m_by);
pDC->MoveTo(m_bx,m_by);
pDC->LineTo(m_cx,m_cy);
pDC->MoveTo(m_cx,m_cy);
pDC->LineTo(m_ax,m_ay);
break;
default:
break;
}
17. 然后编译,执行,即可看到所需效果。
可是我们发现,当点击“方块”,然后弹出“方块设置”对话框时,长与宽的内容是空的,需要用户自己设定。为了使程序更亲切,假如在设定之前里面本来就有预设好的数据,用户或者可以直接点“OK”画图;也可以打开“方块设置”对话框不做修改就点“设置好了”“OK”画图;也可以修改长宽数据,并且数据在下次打开“方块设置”对话框时仍然存在。我们需要进一步丰富程序的内容。
首先,点击“ClassView”“CTest425Dlg”“DoDataExchange”打开代码
这是数据交换区域,我们可以在这里把数据的初值定好,程序启动时,会自动先运行这里的语句。
void CMfcDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMfcDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
extern int flag;
extern double m_length, m_width;
extern double m_ax, m_ay, m_bx, m_by, m_cx, m_cy;
flag=1;
m_length=200.;
m_width=150.0;
m_ax=1.0; m_ay=1.0;
m_bx=230.0; m_by=20.0;
m_cx=150.; m_cy=210.0;
CDialog::DoDataExchange(pDX);
}
在这里,我们还默认flag值初始为1,这样即使打开程序直接点“OK”,也会默认画方形。
18. 同时,再打开“ClassView”“CFangSetDlg”“DoDataExchange”,添加代码
代码内容是,每当对话框打开时,会把长宽的值转成字符串,再传到对应编辑框。
最后MoveWindow语句的作用是把方块设置对话框移到左上角,不要挡到绘图区域。
void CFangSetDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CFangSetDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP
extern double m_length, m_width;
extern char ch_length[10], ch_width[10];
sprintf(ch_length, "%f",m_length);
sprintf(ch_width, "%f",m_width);
GetDlgItem(IDC_EDIT_LENGTH)->SetWindowText(ch_length); GetDlgItem(IDC_EDIT_WIDTH)->SetWindowText(ch_width);
CDialog::DoDataExchange(pDX);
MoveWindow(0,0,300,250,TRUE);
}
19. 同理,添加三角的初值设定:
void CSanSetDlg::DoDataExchange(CDataExchange* pDX)
{
//{{AFX_DATA_MAP(CSanSetDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
extern double m_ax, m_ay, m_bx, m_by, m_cx, m_cy;
extern char ch_ax[10],ch_ay[10],ch_bx[10],ch_by[10],ch_cx[10],ch_cy[10];
sprintf(ch_ax, "%f",m_ax);
sprintf(ch_ay, "%f",m_ay);
sprintf(ch_bx, "%f",m_bx);
sprintf(ch_by, "%f",m_by);
sprintf(ch_cx, "%f",m_cx);
sprintf(ch_cy, "%f",m_cy);
GetDlgItem(IDC_EDIT_AX)->SetWindowText(ch_ax);
GetDlgItem(IDC_EDIT_AY)->SetWindowText(ch_ay);
GetDlgItem(IDC_EDIT_BX)->SetWindowText(ch_bx);
GetDlgItem(IDC_EDIT_BY)->SetWindowText(ch_by);
GetDlgItem(IDC_EDIT_CX)->SetWindowText(ch_cx);
GetDlgItem(IDC_EDIT_CY)->SetWindowText(ch_cy);
CDialog::DoDataExchange(pDX);
MoveWindow(0,0,300,250,TRUE);
}
20. 这样,编译,运行,就会得到满意的结果了。
最后我们一起讨论如何产生绘图的动画,有时,动画会更直观。
在这个例子里,我们综合运用了上面的所有内容,所以把大致步骤介绍出来,不作具体一一