C++ MFC / VS2013 之十(对话框:非模态对话框的创建及显示)

     非模态对话框的创建及显示

     上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示

       已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换。鸡啄米会将上一讲中创建的Tip模态对话框改为非模态对话框,让大家看下效果。

一. 非模态对话框的对话框资源和对话框类

    实际上,模态对话框和非模态对话框在创建对话框资源和生成对话框类上是没有区别的,所以上一讲中创建的IDD_TIP_DIALOG对话框资源和CTipDlg类都不需要修改。

 二. 创建及显示非模态对话框的步骤

     需要修改的是,对话框类实例的创建和显示,也就是之前在CAdditionDlg::OnBnClickedAddButton()函数体中添加的对话框显示代码。下面是具体步骤:

    1.在AdditionDlg.h中包含CTipDlg头文件并定义CTipDlg类型的指针成员变量

      详细操作方法是,在AdditionDlg.cpp中删除之前添加的#include "TipDlg.h",而在AdditionDlg.h中添加#include "TipDlg.h",这是因为我们需要在AdditionDlg.h中定义CTipDlg类型的指针变量,所以要先包含它的头文件;然后在AdditionDlg.h中为CAdditionDlg类添加private成员变量CTipDlg  *m_pTipDlg;。

     2.在CAdditionDlg类的构造函数中初始化成员变量m_pTipDlg

     如果cpp文件中函数太多,我们可以在Class View上半个视图中找到CAdditionDlg类,再在下半个视图中找到其构造函数双击,中间客户区域即可马上切到构造函数的实现处。在构造函数体中添加m_pTipDlg = NULL;,这是个好习惯,在C++编程入门系列的指针的赋值和指针运算中说到过,在任何指针变量使用前都初始化,可以避免因误访问重要内存地址而破坏此地址的数据。

AdditionDlg.h中添加成员变量:

#include "TipDlg.h"

#pragma once

// CAdditionDlg 对话框
class CAdditionDlg : public CDialogEx
{
// 构造
public:
	CAdditionDlg(CWnd* pParent = NULL);	// 标准构造函数
// 对话框数据
	enum { IDD = IDD_ADDITION_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
private:
	CTipDlg* m_pTipDlg;

AdditionDlg.cpp中添加构造函数的并初始化:
// CAdditionDlg 对话框



CAdditionDlg::CAdditionDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CAdditionDlg::IDD, pParent)
	, m_editSummand(0)
	, m_editAddend(0)
	, m_editSum(0)
	, m_pTipDlg(NULL)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

    3.将上一讲中添加的模态对话框显示代码注释或删除掉,添加非模态对话框的创建和显示代码

     VC++中注释单行代码使用“//”,注释多行代码可以在需注释的代码开始处添加“/*”,结束处添加“*/”。修改后的CAdditionDlg::OnBnClickedAddButton()函数如下(AdditionDlg.cpp):

void CAdditionDlg::OnBnClickedAddButton()   
{   
    // TODO: Add your control notification handler code here   
    /*INT_PTR nRes;             // 用于保存DoModal函数的返回值  
  
    CTipDlg tipDlg;           // 构造对话框类CTipDlg的实例  
    nRes = tipDlg.DoModal();  // 弹出对话框  
    if (IDCANCEL == nRes)     // 判断对话框退出后返回值是否为IDCANCEL,如果是则return,否则继续向下执行  
        return;*/  
   
    // 如果指针变量m_pTipDlg的值为NULL,则对话框还未创建,需要动态创建   
    if (NULL == m_pTipDlg)   
    {   
        // 创建非模态对话框实例   
        m_pTipDlg = new CTipDlg();   
        m_pTipDlg->Create(IDD_TIP_DIALOG, this);   
    }   
    // 显示非模态对话框   
    m_pTipDlg->ShowWindow(SW_SHOW);   
   
    // 将各控件中的数据保存到相应的变量   
    UpdateData(TRUE);   
   
    // 将被加数和加数的加和赋值给m_editSum   
    m_editSum = m_editSummand + m_editAddend;   
   
    // 根据各变量的值更新相应的控件。和的编辑框会显示m_editSum的值   
    UpdateData(FALSE);   
}

      4.因为此非模态对话框实例是动态创建的,所以需要手动删除此动态对象来销毁对话框。

      我们在CAdditionDlg类的析构函数中添加删除代码,但是MFC并没有自动给出析构函数,这时需要我们手动添加,在对话框对象析构时就会调用我们自定义的析构函数了。在AdditionDlg.h文件中为CAdditionDlg添加析构函数声明:~CAdditionDlg();,然后在AdditionDlg.cpp文件中添加析构函数的实现,函数体如下:

CAdditionDlg::~CAdditionDlg()   
{   
    // 如果非模态对话框已经创建则删除它   
    if (NULL != m_pTipDlg)   
    {   
        // 删除非模态对话框对象   
        delete m_pTipDlg;   
    }   
}


                   

参考文章:http://www.jizhuomi.com/school/c/161.html


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
使用GDI+库显示gif动态图片,该类接口如下: 可以看出,该ImageEx完全继承了基类的接口函数。 说明: 如果打开多帧图片,该类几乎完全等价于基类,比如你可以把该类的对象代入Graphics类系列的成员函数中; 如果打开的是多帧的图片,你只要打开图片后不调用InitAnimation函数(它会创建线程),则上述做法依然可以; 但如果调用InitAnimation函数后(单帧图像没关系,因为不会创建线程),则不可以了, 所有的基类继承过来的接口成员函数和配合gdi+库其他类的函数调用都是不可以的,因为没有作线程同步, 你只能调用下面位数不多的几个public成员函数,调用Destroy成员函数后,则就可以了,因为它会关闭线程。 其实你会发现下面的public成员函数操作的成员变量都是新增的成员变量,没涉及到线程同步问题。 class ImageEx : public Image { public: //以长度为nSize的内存pBuff中的内容构造图像 ImageEx(const void* pBuff, size_t nSize, BOOL useEmbeddedColorManagement = FALSE); //以类型为sResourceType,名称为sResource的资源构造图像 ImageEx(LPCTSTR sResourceType, LPCTSTR sResource, BOOL useEmbeddedColorManagement = FALSE); //以文件构造图像 ImageEx(LPCTSTR filename, BOOL useEmbeddedColorManagement = FALSE); //调用Destroy成员函数 ~ImageEx(); public: //如果已经构造的对象是动画,则创建动画线程,并返回true, //如果为静态图像或已经创建过动画线程,则也返回false // 图像将绘制在m_hWnd客户区的rect区域,会拉伸,支持镜像 bool InitAnimation(HWND hWnd, RECT rect); //判断是否为动画 bool IsAnimatedGIF() { return m_nFrameCount > 1; } //设置动画暂停与否 void SetPause(bool bPause); //判断动画是否处于暂停状态 bool IsPaused() { return m_bPause; } //关闭动画,事实上基类Image中还有的两个成员变量没有关闭,因为析构函数会调用基类析构函数进行关闭的 void Destroy(); //另外的public的东西省略.. }; 用法: MFC对话框程序在下面添加: BOOL CTestDlgDlg::OnInitDialog() { CDialog::OnInitDialog(); //其它的初始化代码 // GDI+ //m_image为ImageEx指针类型成员变量,"GIF"为资源类型,"HEARTS"为资源名称 m_image = new ImageEx( _T("GIF"), _T("HEARTS") ); RECT rc; GetClientRect(&rc); m_image->InitAnimation(this->m_hWnd, rc);//创建gif播放线程 return TRUE; // return TRUE unless you set the focus to a control } CTestDlgDlg::~CTestDlgDlg() { // GDI+ delete m_image; } 其中的m_image = new ImageEx( _T("GIF"), _T("HEARTS") );你可以换成ImageEx类的另外两个构造函数
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值