WEB开发网
开发学院软件开发VC 一个定制CFileDialog对话框的实例 阅读

一个定制CFileDialog对话框的实例

 2010-06-27 20:41:55 来源:WEB开发网   
核心提示:很多程序员都喜欢让自己的代码运行效果与众不同,Windows系统的应用程序打开某个文件一般使用的都是默认的CFileDialog,一个定制CFileDialog对话框的实例,但是这个默认的CFileDialog往往满足不了用户的要求,我就碰到一个这样的用户,例如:CListCtrl* plc = m_dlghelper

很多程序员都喜欢让自己的代码运行效果与众不同。Windows系统的应用程序打开某个文件一般使用的都是默认的CFileDialog。但是这个默认的CFileDialog往往满足不了用户的要求。我就碰到一个这样的用户,他的要求如下:

1、在默认的CFileDialog对话框中加一个预览窗格,以便在选中ASCII文件时能看到所选文件的内容,也就是用*.txt作为文件过滤条件。

2、在默认的CFileDialog对话框中加一个"全部"按钮来选择某个目录中所有的.txt文件。

3、如果选择的目录中没有.txt文件时,要将"全部"按钮disable,也就是置灰这个按钮。

实现上面这些需求必须要改装CFileDialog对话框。当最后写完程序时,功能到是全都实现了,但在Windows 2000环境测试中,用户发现了这样一个问题:如果先选中某个文件,然后再去选某个文件夹,预览窗格仍然显示的那个文件的内容。尽管在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对话框,必须建立一个它的派生类以及一个新的对话框资源。“全部”按钮的实现代码是这样的:

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();
}

1 2 3  下一页

Tags:一个 定制 CFileDialog

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接