[MFC]DlgDemo1程序:基本的模态对话框

来源:互联网 发布:淘宝摄影棚什么样的好 编辑:程序博客网 时间:2024/06/05 18:49

1. 接下来所演示的DlgDemo1程序将演示基本的模态对话框的使用:

    1) 该程序是基于视图的MFC程序;

    2) 视图左上角将显示一个粉红色的矩形;

    3) 菜单“文件”中有一个Options菜单项,点击后可以打开一个对话框;

    4) 对话框中可以输入想设定的矩形的宽和高(范围必须在1 ~ 128内);

    5) 还可以选择显示模式(英寸、厘米、像素,是一组单选按钮);

    6) 退出按钮就是默认的OK和Cancel;

    7) 还有一个重置按钮Reset,点击后会把宽、高、显示模式重置为默认值(4、2和英寸),但是不关闭对话框,仅仅是控件中的数据发生变化;

    8) OK保存后退出对话框,视图中的矩形将会按照用户在对话框中的设置重新显示;

!!工程建立的步骤还是和之前的一样,只不过需要添加一个类COptionsDlg类,以及相应的文件OptionsDlg.h和OptionsDlg.cpp


2. 资源脚本CD了刚Demo1.rc:

    1) 菜单项Options的定义:

IDR_MAINFRAME MENU PRELOAD DISCARDABLE BEGINPOPUP "文件(&F)"BEGINMENUITEM "退出(&X)",                       ID_APP_EXITMENUITEM "&Options...",ID_FILE_OPTIONSEND
!!注意,必须加...表示需要用户进一步输入才能进行下一步响应;

    2) COptionsDlg的框架窗口口的定义:

IDD_OPTIONS DIALOG DISCARDABLE0, 0, 192, 121STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENUCAPTION "Options"FONT 8, "MS Sans Serif"BEGINLTEXT"&Width", IDC_STATIC, 16, 16, 28, 8EDITTEXTIDC_WIDTH, 44, 12, 64, 12, ES_AUTOHSCROLLLTEXT"&Height", IDC_STATIC, 16, 36, 28, 8EDITTEXTIDC_HEIGHT, 44, 32, 64, 12, ES_AUTOHSCROLLGROUPBOX"Units", IDC_STATIC, 16, 56, 92, 52CONTROL"&Inches", IDC_INCHES, "Button", BS_AUTORADIOBUTTON |WS_GROUP, 28, 68, 52, 8CONTROL"&Centimeters", IDC_CENTIMETERS, "Button", BS_AUTORADIOBUTTON, 28, 80, 52, 8CONTROL"&Pixels", IDC_PIXELS, "Button", BS_AUTORADIOBUTTON,28, 92, 52, 8DEFPUSHBUTTON"OK", IDOK, 128, 12, 50, 14, WS_GROUPPUSHBUTTON"Cancel", IDCANCEL, 128, 32, 50, 14, WS_GROUPPUSHBUTTON"&Reset", IDC_RESET, 128, 52, 50, 14, WS_GROUPEND


3. CMainFrame的定义和过去一样,只需要自己再添加一个OnCreate函数即可(注意消息映射也需要添加一下);


4. CChildView的定义:

    1) .h文件中添加成员数据和Options菜单项的消息映射:

protected:// 在视图中定义相应的矩形宽、高以及显示模式,作为和对话框交换数据的基础int m_nWidth;int m_nHeight;int m_nUnits; // 0是英尺,1是厘米,2是像素//{{AFX_MSG(CChildView)afx_msg void OnPaint();afx_msg void OnFileOptions(); // 菜单项命令处理程序//}}AFX_MSGDECLARE_MESSAGE_MAP()};
    2) .cpp文件中的定义:OnPaint和OnFileOptions

// ChildView.cpp : implementation of the CChildView class//#include "stdafx.h"#include "CDlgDemo1.h"#include "ChildView.h"#include "OptionsDialog.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CChildViewCChildView::CChildView() // 初始化要显示的矩形的相关参数{m_nWidth = 4;m_nHeight = 2;m_nUnits = 0; // 初始化为英尺比例显示}CChildView::~CChildView(){}BEGIN_MESSAGE_MAP(CChildView,CWnd )//{{AFX_MSG_MAP(CChildView)ON_WM_PAINT()ON_COMMAND(ID_FILE_OPTIONS, OnFileOptions)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CChildView message handlersBOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) {if (!CWnd::PreCreateWindow(cs))return FALSE;cs.dwExStyle |= WS_EX_CLIENTEDGE;cs.style &= ~WS_BORDER;cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL);return TRUE;}void CChildView::OnPaint() // 矩形信息由对话框传送而来,重画只要一句视图的矩形信息即可{CPaintDC dc(this); // device context for painting// TODO: Add your message handler code hereCBrush brush(RGB(255, 0, 255));CBrush* pOldBrush = dc.SelectObject(&brush);switch (m_nUnits){case 0: // 英尺比例显示dc.SetMapMode(MM_LOENGLISH);dc.Rectangle(0, 0, m_nWidth * 100, -m_nHeight * 100);break;case 1: // 厘米显示比例dc.SetMapMode(MM_LOMETRIC);dc.Rectangle(0, 0, m_nWidth * 100, -m_nHeight * 100);break;case 2: // 像素显示dc.SetMapMode(MM_TEXT);dc.Rectangle(0, 0, m_nWidth, m_nHeight);break;}dc.SelectObject(pOldBrush);// Do not call CWnd::OnPaint() for painting messages}// 选中Options菜单项后创建相应对话框// 并且视图窗口和对话框中的数据就在该函数中交换void CChildView::OnFileOptions(){COptionsDialog dlg;// 打开对话框之前先用视图中正确的数据初始化对话框中的数据dlg.m_nWidth = m_nWidth;dlg.m_nHeight = m_nHeight;dlg.m_nUnits = m_nUnits;if (dlg.DoModal() == IDOK) { // 用户相应完对话框后将数据回送至视图并重画视图中的矩形m_nWidth = dlg.m_nWidth;m_nHeight = dlg.m_nHeight;m_nUnits = dlg.m_nUnits;Invalidate(); // 无效导致重画}}

5. 对话框COptionsDlg的定义:

    1) .h文件:

#if !defined(AFX_OPTIONSDIALOG_H__5F0F17AA_D0C2_4CCC_A53D_3A3CC1284F9B__INCLUDED_)#define AFX_OPTIONSDIALOG_H__5F0F17AA_D0C2_4CCC_A53D_3A3CC1284F9B__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// OptionsDialog.h : header file///////////////////////////////////////////////////////////////////////////////// COptionsDialog dialogclass COptionsDialog : public CDialog{// Constructionpublic:COptionsDialog(CWnd* pParent = NULL);   // standard constructor// Dialog Data//{{AFX_DATA(COptionsDialog)enum { IDD = IDD_OPTIONS }; // COptionsDialog可以由ClassWizard自动生成// 并且选择从逻辑上链接到.rc中定义的对话框模板上// 逻辑上链接的方法就是定义IDD这个枚举值,之后可以在派生类的构造函数中作为// 该类的数据成员传给构造函数作为参数(构造时需要用到对话框模板的ID)// 三个成员变量,因为可以从ClassWizard中生成(并且是可以和控件交换数据的)// 因此处于AFX_DATA注释宏的包围中,作为MFC自动生成的数据成员看待intm_nHeight;intm_nWidth;intm_nUnits;//}}AFX_DATA// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(COptionsDialog)protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:// Generated message map functions//{{AFX_MSG(COptionsDialog)// NOTE: the ClassWizard will add member functions hereafx_msg void OnReset(); // Reset按钮的处理程序//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_OPTIONSDIALOG_H__5F0F17AA_D0C2_4CCC_A53D_3A3CC1284F9B__INCLUDED_)

    2) .cpp文件:

// OptionsDialog.cpp : implementation file//#include "stdafx.h"#include "CDlgDemo1.h"#include "OptionsDialog.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// COptionsDialog dialogCOptionsDialog::COptionsDialog(CWnd* pParent /*=NULL*/): CDialog(COptionsDialog::IDD, // 之前定义的枚举值作为构造函数的默认参数,实在是巧妙而安全,因为该枚举值成为了成员变量!pParent){//{{AFX_DATA_INIT(COptionsDialog)// 该初始值是MFC默认设定的,依据就是所这些数据成员所链接的控件// 一般链接编辑框的int类型的数据成员都会初始化成0// 链接单选按钮的int类型的数据成员都会初始化成-1,表示谁都没有选上// 由于这些初始化都可以由MFC的ClassWizard自动生成,因此包含在AFX_DATA_INIT的注释宏中m_nHeight = 0;m_nWidth = 0;m_nUnits = -1;//}}AFX_DATA_INIT// 但是问题就来了,我们定义宽和高的有效范围为1 ~ 128,而显示模式的有效范围为0 ~ 2,这个默认的初始化明显不符合要求// 会直接在DDV中报错// 但不过对话框中的数据是要和CChildView中相应的数据做交换的// CChildView中创建对话框时会将CChildView中初始的在有效范围内的值(4, 2, 0)赋给对话框中的数据成员// 而在关闭对话框后会将用户输入的对话框中的数据再回送到CChildView中}void COptionsDialog::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(COptionsDialog)DDX_Text(pDX, IDC_HEIGHT, m_nHeight);DDV_MinMaxInt(pDX, m_nHeight, 1, 128);DDX_Text(pDX, IDC_WIDTH, m_nWidth);DDV_MinMaxInt(pDX, m_nWidth, 1, 128);// 因为单选按钮在界面中是固定的// 在界面中有几个就是几个,不可能选择最大个数以外的按钮// 所以无需进行DDV校验DDX_Radio(pDX, IDC_INCHES, m_nUnits); //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(COptionsDialog, CDialog)//{{AFX_MSG_MAP(COptionsDialog)// NOTE: the ClassWizard will add message map macros hereON_BN_CLICKED(IDC_RESET, OnReset)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// COptionsDialog message handlers// 复位按钮处理程序void COptionsDialog::OnReset(){ // 成员变量重置为默认值m_nWidth = 4;m_nHeight = 2;m_nUnits = 0;// 需要将重置后的值回显到控件中UpdateData(FALSE);}


0 0
原创粉丝点击