一个定制CFileDialog对话框的实例

哈利波波波特0

哈利波波波特0

2016-01-29 11:52

一个定制CFileDialog对话框的实例,一个定制CFileDialog对话框的实例

一个定制CFileDialog对话框的实例

编译:northtibet

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/cyuyanjiaocheng/) 下载源代码


    很多程序员都喜欢让自己的代码运行效果与众不同。Windows系统的应用程序打开某个文件一般使用的都是默认的CFileDialog。但是这个默认的CFileDialog往往满足不了用户的要求。我就碰到一个这样的用户,他的要求如下: 1、在默认的CFileDialog对话框中加一个预览窗格,以便在选中ASCII文件时能看到所选文件的内容,也就是用*.txt作为文件过滤条件。 2、在默认的CFileDialog对话框中加一个"全部"按钮来选择某个目录中所有的.txt文件。 3、如果选择的目录中没有.txt文件时,要将"全部"按钮disable,也就是置灰这个按钮。    实现上面这些需求必须要改装CFileDialog对话框。当最后写完程序时,功能到是全都实现了,但在Windows2000环境测试中,用户发现了这样一个问题:如果先选中某个文件,然后再去选某个文件夹,预览窗格仍然显示的那个文件的内容。尽管在OnFileNameChange中对CDN_SELCHANGE进行了处理,为了获取所选的文件/路径名,也调用了CFileDialog::GetPathName。但是即使是选中了文件夹,GetPathName仍然返回的是文件的名字。即便尝试用其它的通知消息和函数,比如 CDN_FOLDERCHANGE 和 GetFileName,但仍旧存在同样的问题。必须承认在Windows 2000中,CFileDialog是个不完美的对话框,确实存在上述问题。正是有这些不完美,程序员们才忙得个不亦乐乎......那么到底如何判断用户选中的是文件还是文件夹呢?下面就让我们从用户需求开始,一个一个解决所碰到的问题。
    首先简单介绍下本文引入的三个辅助类:CFileDialogHook;CFileDialogOwnerHook和CFileDlgHelper,这三个类很简单,其功能分别是:子类化文件对话框;子类化文件对话框的父窗口或宿主窗口,这两个类只在CFileDlgHelper类中使用,一些重要的处理都在CFileDlgHelper中。它的使用方法很简单,实例化CFileDlgHelper以后调用Init即可。
class CMyOpenDlg ... {protected:  CFileDlgHelper m_dlghelper;//实例化};BOOL CMyOpenDlg::OnInitDialog(){  m_dlghelper.Init(this)//初始化……}     
    初始化CFileDlgHelper以后,便可以用它来获取列表控制以及判断选项是否有文件夹属性,例如:
CListCtrl* plc = m_dlghelper.GetListCtrl();POSITION pos = plc->GetFirstSelectedItemPosition();while (pos) {  int i = plc->GetNextSelectedItem(pos);  if (fdh.IsItemFolder(i)) {    // 显示"(FOLDER)"……  } else {    // 显示其它内容  }}

    毫无疑问,要改装CFileDialog对话框,必须建立一个它的派生类以及一个新的对话框资源。“全部”按钮的实现代码是这样的:

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/cyuyanjiaocheng/)
void CMyOpenDlg::OnSelectAll(){  CListCtrl* plc = m_dlghelper.GetListCtrl();  for (int i=0; i<plc->GetItemCount(); i++) {    CString fn = plc->GetItemText(i,0);    if (IsTextFileName(fn)) {      plc->SetItemState(i,LVIS_SELECTED,        LVIS_SELECTED);    }  }  plc->SetFocus();}
    当所选目录中没有.txt文件时,要disable“全部”按钮的处理稍微麻烦一些,要用到ON_UPDATE_COMMAND_UI消息。回顾一下MFC有关UI更新的基本方法,通常是在主消息循环处于空闲状态时候——也就是说在消息队列中没有待处理的消息。但对话框则有所不同,尤其是运行模式对话框时,MFC启动另外一个消息循环。当没有消息等待处理的时候,CWnd::DoModal向对话框发送一个WM_KICKIDLE消息。所以要想让对话框处理UI,常用的方式是这样的:
LRESULT CMyDialog::OnKickIdle(WPARAM wp, LPARAM lp){  UpdateDialogControls(this, TRUE);  return 0;}      
    CWnd::UpdateDialogControls将神奇的CN_UPDATE_COMMAND_UI消息发送到对话框,触发ON_UPDATE_COMMAND_UI处理例程。可惜这个方法对CFileDialog对话框不灵。原因是CFileDialog重写了DoModal,它不会以正常方式运行某个消息循环,而是调用::GetOpenFileName (或::GetSaveFileName)。这些API函数都有自己消息循环,并且你无法钻进去进行消息空闲处理。无论什么时候,每当模式对话框处于等待消息状态时,对话框发送自己的WM_ENTERIDLE消息。从这里进去才可以处理UI更新事宜。但有几个细节需要注意。首先,Windows只发送WM_ENTERIDLE消息到对话框的所有者——此处为主框架
展开更多 50%)
分享

猜你喜欢

一个定制CFileDialog对话框的实例

C语言教程 C语言函数
一个定制CFileDialog对话框的实例

再谈 CFileDialog 对话框的定制

C语言教程 C语言函数
再谈 CFileDialog 对话框的定制

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

关于 CFileDialog 对话框多选功能的一个问题

C语言教程 C语言函数
关于 CFileDialog 对话框多选功能的一个问题

一个简单的登录对话框的实现

C语言教程 C语言函数
一个简单的登录对话框的实现

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

一个支持皮肤化的对话框类

编程语言 网络编程
一个支持皮肤化的对话框类

VC实现一个对话框里的动圆

编程语言 网络编程
VC实现一个对话框里的动圆

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

AutoCAD教程:绘制铅笔全过程

AutoCAD教程:绘制铅笔全过程

网站首页head区代码规范

网站首页head区代码规范
下拉加载更多内容 ↓