MFC练习5:使用非模态对话框

本文介绍如何在MFC应用程序中实现非模态对话框,包括创建对话框类、显示对话框及其实现文件浏览功能的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

非模态(Modalless)对话框,又叫做无模式对话框,当用户打开非模态对话框时,依然可以操作其他窗口。非模态对话框允许用户在处理非模态对话框的同时处理目标对话框。上次的练习已经说明了Modalless与Modal的区别,此处就不赘述。

这次将做一个窗口使看见某目录下的文件,以C盘为例。

Ⅰ、创建对话框类并且添加控件

1>在Resource的IDR_DIALOGTYPE里,在“查看”里添加菜单项,取名“非模态对话框(&E)”

2>如下创建对话框,并设置相关属性

 

控件属性
ID控件属性
IDC_TREETree Control选中Has buttons、Has lines和Lines at root
IDC_LISTList ControlStyles|View: Report
IDC_OKButtonCaption:OK
IDC_CANCELButtonCaption:Cancel

 

 

 

 

 

 

 

Ⅱ、显示非模态对话框

由于模态对话框生存周期较长,通常和父级窗口一样长。为此,我们使用非模态对话框指针,在父级窗口类的构造函数当中或菜单响应函数中动态为指针分配空间并显示对话框。最后记得在CDialogView的析构函数当中释放指针的空间。

1>在DialogView.h里添加#include "DialogModalless.h"

2>在CDialogView里Add member variable,添加类型为CDialogModalless*,名称为m_pModallessDlg

3>按下Ctrl+W,并在Class name里选CDialogView,在Object IDs里选ID_VIEW_MODALLESSDIALOG,在Message里选COMMAND,最后以默认函数名Add Function并进行Edit Code。相关代码如下:

void CDialogView::OnViewModallessdialog() 
{
	// TODO: Add your command handler code here
	if(NULL == m_pModallessDlg)
	{
		m_pModallessDlg = new CDialogModalless;
		m_pModallessDlg->Create(IDD_MODALLESS_DIALOG,this);
	}
	m_pModallessDlg->ShowWindow(SW_SHOW);//显示非模态对话框
}

4>修改视类的构造与析构函数

CDialogView::CDialogView()
{
	// TODO: add construction code here
	m_pModallessDlg = NULL;
}

CDialogView::~CDialogView()
{
	if(NULL == m_pModallessDlg)
		delete m_pModallessDlg;
}

Ⅲ、实现对话框功能

1>为之前添加的相关控件添加变量如下

 

Member Variable
控件TypeMember
IDC_LISTClistCtrlm_List
IDC_TreeCteeCtrlm_Tree

 

 

 

 

 

 

 

2>按下Ctrl+W,在Class name里选中CDialogModalless,在Object IDs里选中CDialogModalless,在Message里选中WM_INITDIALOG,最后Add Function

3>在Object IDs里选中ID_OK、ID_CANCEL和IDC_TREE,在Message里分别选中BN_CLICKED(OK与CANCEL)与TVN_SELCHANGED,添加OnOK()、OnCancel()和OnSelchangedTree()函数。相关代码添加如下:

BOOL CDialogModalless::OnInitDialog() 
{
	CDialog::OnInitDialog();
	// TODO: Add extra initialization here
	//往List控件中加入一列
	m_List.InsertColumn(0,"文件名",LVCFMT_LEFT,150,-1);
	TV_INSERTSTRUCT TreeItem;
	HTREEITEM hTreeItem;
	TreeItem.hInsertAfter = TVI_LAST;
	TreeItem.item.mask = TVIF_TEXT|TVIF_PARAM;
	//第一级
	CString str = "C:\\";
	TreeItem.hParent = TVI_ROOT;//父级为根部
	TreeItem.item.pszText = str.GetBuffer(50);//设置缓冲区大小并赋值
	TreeItem.item.lParam = 1;//对于根目录,设置为
	hTreeItem = m_Tree.InsertItem(&TreeItem);//插入Tree控件
	int number = 0;//计算文件个数
	CFileFind file;
	BOOL bfind;
	CString temp;
	//第二级
	TreeItem.hParent = hTreeItem;
	TreeItem.item.lParam = 10;//对于子目录,设置为10
	bfind = file.FindFile("C:\\*.*");//查找C:盘下所有文件和目录
	while(bfind)//发现文件
	{
		bfind = file.FindNextFile();//寻找下一个
		if(file.IsDirectory())//判断是否为目录
		{
			strcpy(TreeItem.item.pszText, file.GetFileName());//拷贝目录名
			hTreeItem = m_Tree.InsertItem(&TreeItem);//插入Tree插件
		}
		else//不是目录,插入List控件
		{
			temp = file.GetFileName();//获取文件名
			m_List.InsertItem(number, temp);//将文件插入第number行
			++number;
		}
	}
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CDialogModalless::OnOK() 
{
	// TODO: Add extra validation here
	CDialog::OnOK();
}

void CDialogModalless::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	CString temp,str;
	//获取当前被选的tree view项
	HTREEITEM CurItem = m_Tree.GetSelectedItem();
	TV_ITEM TreeItem;
	TreeItem.hItem = CurItem;
	m_Tree.GetItem(&TreeItem);//获取指定的tree view属性
	temp = m_Tree.GetItemText(m_Tree.GetSelectedItem());//获取当前条目的序号
	long CurlParam = TreeItem.lParam;//当前条目序号
	if (1 != CurlParam)//若为子目录
	{
		//获取当前被选项的父亲
		TreeItem.hItem = m_Tree.GetParentItem(m_Tree.GetSelectedItem());
		m_Tree.GetItem(&TreeItem);
		CurItem = TreeItem.hItem;
		//获取当前选中项的文本
		str = m_Tree.GetItemText(CurItem);
		str += temp;
		str += "\\";
	}
	else str = temp;
	m_List.DeleteAllItems();//删除控件中所有的项
	CFileFind file;
	BOOL bFind;
	int number = 0;
	str += "*.*";
	bFind = file.FindFile(str);//在str目录下查找
	while(bFind)//一旦找到
	{
		bFind = file.FindNextFile();
		if(!file.IsDirectory())//判断是否为目录,不是插入List控件
		{
			temp = file.GetFileName();
			m_List.InsertItem(number, temp);
			++number;
		}
	}
	UpdateData(false);//更新控件值
	*pResult = 0;
}

void CDialogModalless::OnCancel() 
{
	// TODO: Add extra cleanup here
	CDialog::OnCancel();
}

4>运行检测效果,记得是在多文档的“查看”菜单下运行这个非模态对话框。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值