自定义MFC打开/保存对话框的扩展名

HTML——使用表格对表单进行布局 当表单中输入项目过多时,合理采用表格布局会使表单显得更加有条理,方便用户填写。 阅读详情
  • “打开文件”对话框

这里的顶目名称是D-TriNet,文档扩展名是.dtn和.csv。

要让打开/保存对话框支持多个扩展名,最简单的方法是修改资源文件中的IDR_DTriNetTYPE字段:

STRINGTABLE 
BEGIN
    IDR_MAINFRAME           "D-TriNet"
    IDR_DTriNetTYPE         "\nDTriNet\nD-TriNet\nD-TriNet 
    Files(*.dtn;*.csv)\n.dtn;.csv\nDTriNet.Document\nD-TriNet.Document"
END
这样做的不足是,文件虽然可以有多个扩展名,但仍然只分为两类:"D-TriNet Files"和"All Files"。
要想更细致地分类,需要重写相关的虚函数,具体做法不唯一,我觉得比较好的一种是重写CDocManager::DoPromptFileName。

下面的文字有些凌乱,因为它的内容是按照我的探索过程组织的。

首先考虑打开对话框。第一步是要弄清,打开对话框是什么时候(在哪)弹出来的?

默认情况下,CDTriNetApp调用CWinApp::OnFileOpen方法处理FileOpen事件:

ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
CWinApp::OnFileOpen又调用CDocManager::OnFileOpen处理FileOpen事件:
void CWinApp::OnFileOpen()
{
    ENSURE(m_pDocManager != NULL);
    m_pDocManager->OnFileOpen();
}
CDocManager::OnFileOpen显示对话框与用户交互,然后调用CWinApp::OpenDocumentFile方法:
void CDocManager::OnFileOpen()
{
    // prompt the user (with all document templates)
    CString newName;
    if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,
        OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
	return; // open cancelled

    AfxGetApp()->OpenDocumentFile(newName);
    // if returns NULL, the user has already been alerted
}
显然,一种可能的解决办法是绕过CWinApp和CDocManager,在CDTriNetApp::OnFileOpen方法中显示自定义对话框,然后调用CWinApp::OpenDocumentFile方法。

ON_COMMAND(ID_FILE_OPEN, &CDTriNetApp::OnFileOpen)
void CDTriNetApp::OnFileOpen()
{
    LPCTSTR szFilter = L"DTriNet文件(*.dtn)|*.dtn|CSV文件(*.csv)|*.csv|所有文件(*.*)|*.*||";   

    CFileDialog oFileDlg(TRUE, L".dtn", NULL, 4|2, szFilter);

    if(oFileDlg.DoModal() == IDOK)
        OpenDocumentFile(oFileDlg.GetFileName()); 

    // CDTriNetApp不需要重写CWinApp::OpenDocumentFile方法
}


  • “保存文件”对话框

    现在考虑保存对话框。第一步仍然是弄清,保存对话框是什么时候(在哪)弹出来的?

   分发消息时,调用了CDocument::DoFileSave虚方法:

BOOL CDocument::DoFileSave()
{
    DWORD dwAttrib = GetFileAttributes(m_strPathName);

    if (dwAttrib & FILE_ATTRIBUTE_READONLY)
    {
        // we do not have read-write access or the file does not (now) exist
        if (!DoSave(NULL))
        {
            TRACE(traceAppMsg, 0, "Warning: File save with new name failed.\n");
            return FALSE;
        }
    }
    else
    {
        if (!DoSave(m_strPathName))
        {
            TRACE(traceAppMsg, 0, "Warning: File save failed.\n");
            return FALSE;
        }
    }
    return TRUE;
}

    CDocument::DoFileSave调用CDocument::DoSave,也是一个虚方法:

    (注:没有DoSaveAs方法,lpszPathName参数决定了CDocument::DoSave是表现为“保存”还是“另存为”。)


BOOL CDocument::DoSave(LPCTSTR lpszPathName, BOOL bReplace)
    // Save the document data to a file
    // lpszPathName = path name where to save document file
    // if lpszPathName is NULL then the user will be prompted (SaveAs)
    // note: lpszPathName can be different than 'm_strPathName'
    // if 'bReplace' is TRUE will change file name if successful (SaveAs)
    // if 'bReplace' is FALSE will not change path name (SaveCopyAs)
{
    CString newName = lpszPathName;
    if (newName.IsEmpty())
    {
        CDocTemplate* pTemplate = GetDocTemplate();
        ASSERT(pTemplate != NULL);
	      newName = m_strPathName;
	      
        if (bReplace && newName.IsEmpty())
        {
            newName = m_strTitle;
            
	          // check for dubious filename
	          int iBad = newName.FindOneOf(_T(":/\\"));
	          if (iBad != -1)
		            newName.ReleaseBuffer(iBad);

	          // append the default suffix if there is one
	          CString strExt;
	          if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
		            !strExt.IsEmpty())
	          {
		            ASSERT(strExt[0] == '.');
		            int iStart = 0;
		            newName += strExt.Tokenize(_T(";"), iStart);
	          }
	      }

	      if (!AfxGetApp()->DoPromptFileName(newName,
	          bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,
	          OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, pTemplate))
	          return FALSE;       // don't even attempt to save
    }

    CWaitCursor wait;

    if (!OnSaveDocument(newName))
    {
	      if (lpszPathName == NULL)
	      {
            // be sure to delete the file
	          TRY
	          {
		            CFile::Remove(newName);
	          }
	          CATCH_ALL(e)
	          {
		            TRACE(traceAppMsg, 0, 
	                  "Warning: failed to delete file after failed SaveAs.\n");
		            DELETE_EXCEPTION(e);
	          }
	          END_CATCH_ALL
    	  }
	 
	      return FALSE;
    }

    // reset the title and change the document name
    if (bReplace)
 	      SetPathName(newName);

    return TRUE;        // success
}

    CDocument::DoSave虚方法调用CWinApp::DoPromptFileName方法弹出保存对话框,后者又调用CDocManager::DoPromptFileName虚方法(情形与打开文件时相同):

BOOL CDocManager::DoPromptFileName(CString& fileName, UINT nIDSTitle, 
	  DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
{
    CFileDialog dlgFile(bOpenFileDialog, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, NULL, NULL, 0);
    CString title;
    VERIFY(title.LoadString(nIDSTitle));

    dlgFile.m_ofn.Flags |= lFlags;
    CString strFilter;
    CString strDefault;
    if (pTemplate != NULL)
    {
        ASSERT_VALID(pTemplate);
        _AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault);
    }
    else
    {// do for all doc template
        POSITION pos = m_templateList.GetHeadPosition();
        BOOL bFirst = TRUE;
        while (pos != NULL)
        {
            pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
            _AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate,bFirst ? &strDefault : NULL);
            bFirst = FALSE;
        }
    }

    // append the "*.*" all files filterCString allFilter;
    VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
    strFilter += allFilter;strFilter += (TCHAR)'\0';   
    
    // next string please
    strFilter += _T("*.*");
    strFilter += (TCHAR)'\0';   

    // last string
    dlgFile.m_ofn.nMaxCustFilter++;
    dlgFile.m_ofn.lpstrFilter = strFilter;
    dlgFile.m_ofn.lpstrTitle = title;
    dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);

    INT_PTR nResult = dlgFile.DoModal();
    fileName.ReleaseBuffer();

    return nResult == IDOK;
}

    看起来,重写CDocManager::DoPromptFileName方法比重写CDocument::DoSave方法要省事些:

BOOL CDTriNetDocMgr::DoPromptFileName(CString& fileName, UINT nIDSTitle,
			DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
{
    LPCTSTR strFilter = L"DTriNet文件(*.dtn)|*.dtn|CSV文件(*.csv)|*.csv|所有文件(*.*)|*.*||";
    CFileDialog dlgFile(bOpenFileDialog, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter, NULL, 0);
	
    CString title;
    VERIFY(title.LoadString(nIDSTitle));

    dlgFile.m_ofn.lpstrTitle = title;
    dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);

    INT_PTR nResult = dlgFile.DoModal();
    fileName.ReleaseBuffer();
    
    return nResult == IDOK;
}

    CDTriNetDocMgr是派生自CDocManager的类。
   
    下一步的问题是:怎么为CWinApp::m_pDocManager创建CDTriNetDocMgr对象(而非CDocManager对象)?
    m_pDocManager是在重写的CWinApp::InitInstance虚方法中创建的,具体来说,是在CWinApp::AddDocTemplate方法中创建的,CWinApp::AddDocTemplate方法在创建m_pDocManager之前会检查它是否为NULL,只有当m_pDocManager为NULL时才为它创建CDocManager对象,所以现在并不需要重写CWinApp::AddDocTemplate方法,而只需要在重写的CWinApp::InitInstance方法中、在调用CWinApp::AddDocTemplate方法之前为m_pDocManager创建CDTriNetDocMgr对象。

    一旦重写了CDocManager::DoPromptFileName方法,之前提到的自定义打开对话框文件扩展名的方法也就多此一举了,也不再需要修改资源文件中的IDR_DTriNetTYPE字段,因为无论打开还是保存对话框,最终都是由CDocManager::DoPromptFileName执行的。


创建一个HTML的form表格表单 创建一个HTML的form表格形式的表单,我们要实现如图的样式:话不多说,直接上代码:<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>用户信息</title> </head> <body& 阅读详情

相关推荐

使用 Mid360 从零开始搭建实物机器人入门级导航系统 —— 基于 Fast_Lio 和 Move_Base

本文详细介绍了如何使用Mid360机器人从零开始搭建一个基于Fast_Lio和Move_Base的入门级导航系统。通过配置 ROS2、集成激光雷达、IMU、Fast_Lio、Move_Base 等模块,我们成功构建了一个能够实现自动导航的机器人系统。在实际开发中,随着需求的变化,你可以不断调整参数、优化路径规划算法、增加新的传感器等,逐步提升机器人的智能与功能。

小蜗牛的珍贵百宝箱 3491

VC菜单命令详解(文件打开保存与关闭)

第一部分:五个命令ID: 处理函数   ID_FILE_NEW CWinApp::OnFileNew    ID_FILE_OPEN    CWinApp::OnFileOpen   ID_FILE_SAVE    CDocument::OnFileSave   ID_FILE_SAVEAS  CDocument::OnFileSaveAs   ID_FILE_CLOSE   CDocum

wirror800的专栏 1万+

波分复用技术原理

波分复用原理 把不同波长的光信号复用到同一根光纤中进行传送,这种方式我们把它叫做波分复用( Wavelength Division Multiplexing ) 一根光纤被划分为多个波道,多个波长以一定的间隔隔开,在光纤中独立传输。 波分复用应用演示 如果将WDM系统看作交通系统,光纤可以看作是多个车道的公用道路。 各种类型的业务就像货物一样,被打包装载到车辆中。 车辆按照分配的车道行驶至目的地,完成货物的运输。 想要提高波分复用系统的传输容量,就要增加波道数量或是提升单波传...

m0_63251770的博客 9971

MFC单文档打开文件默认后缀名修改

转载来源:http://www.iieeg.com/newscon.php?id=2305。 做单文档程序时,默认打开文档后缀为(*.*)。如果我们需要自定义打开后缀时,需要对文档模板相关函数做重载。 class CMySingleDocTemplate : public CSingleDocTemplate { public: CMySingleDocTemplate(UINT...

爱.NET 327

MFC SDI打开文件扩展名设置

修改字符串资源IDR_MAINFRAME SD5\n\nSD5\nSD5文件[*.fff]\n.fff\nSD5.Document\nSD5.Document

dxm809的博客 273

MFC的单文档程序修改打开文件对话框的后缀

常见方法 一种常见的方法是继承CSingleDocTemplate,然后修改GetDocString虚函数,并在BOOL CXXXApp::InitInstance 中,替换文件模板。 详细方法可以参看:MFC单文档打开文件默认后缀名修改 这个方法比较麻烦,需要新建类并继承修改虚函数。 这边介绍另一种方法 修改资源文件 在项目中搜索IDR_MAINFRAME 可以在资源文件中找到相关内容: STRINGTABLE BEGIN IDR_MAINFRAME "Emf.

sspdfn的专栏 1190

HTML表格与表单

目录HTMl表格与表单HTML表格表格常用标签表格常用属性表格demo实现效果实现代码HTML表单html表格与表单综合demo实现效果代码 HTMl表格与表单 HTML表格 表格由 <table> 标签来定义。每个表格均有若干行(由 <tr> 标签定义),每行被分割为若干单元格(由 <td> 标签定义)。字母 td 指表格数据(table data),即数据单元格的内容。数据单元格可以包含文本、图片、列表、段落、表单、水平线、表格等等。   表格常用标签

whhcs的博客 2829

如何使用HTML创建表格和表单

如何使用HTML创建表格和表单表格定义表格表单表单的创建 表格 定义表格 表格是用<table>元素来定义的如: <table border=n align="alignment" bgcolor="clr">....</table> 属性border用于定义表格边框的宽度,n可以是从0开始的整数,设置border=0和忽略border属性,浏览器不会显示边框。 属性align用于设置表格个的对齐方式,alignment可以是left、center、或right。

理想主义的花最终会盛开在浪漫主义的土壤里,我的热情永远不会熄灭在现实的平凡之中,我们终将上岸,阳光万里。 3980

Html表单与表格结合

表单、表格 html表单与表格的结合 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body&gt

weixin_45742613的博客 1705

关于HTML的form表单与table表格

HTML它的全称为 HyperText Mark-up LanguageHTML 是用来描述网页的一种语言。HTML 是一种在 Web 上使用的通用标记语言。HTML 允许你格式化文本,添加图片,创建链接、输入表单、框架和表格等等,并可将之存为文本文件,浏览器即可读取和显示。HTML 指的是超文本标记语言: HyperText Markup LanguageHTML 不是一种编程语言,而是一种标记语言标记语言是一套标记标签 (markup tag)HTML 使用标记标签来描述网页。

2301_76802665的博客 1634

一文搞懂HTML中的表格、表单、列表

由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!点击【学习资料】即可领取!由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!点击【学习资料】即可领取!

2301_78850344的博客 3179

Java Web(html表格,表单,表单项)

table 标签:定义表格。tr 标签:表示表格中的一行。td 标签:表示表格中的一个数据单元格。th 标签:表示表格中的表头单元格,通常用于表头,其内容会以加粗和居中的方式显示。貌似markdown看不出设置的表格底色,并且默认居中对齐。

k11582kk的博客 2805

WEB入门二 表格和表单

学习内容Ø表格的作用和制作Ø表单的制作能力目标Ø掌握表格的创建Ø掌握设置表格的常用属性;Ø理解表单的作用Ø熟练掌握表单常用元素本章简介表格对于网页制作而言极其重要,其最明显的优点是能够以行列整齐的形式来显示文本、数字、图片信息。而且,表格还可以用于固定文本或图像的显示位置。经常上网的用户会发现表格被大量

张晨光老师的播客 9673

html表格及表单

表格: 基础: table标签代表了创建一个表格,(块元素) th是表头中的内容,也属于td,不过有一些样式 tr为行标签,td为列标签 colspan表示跨行 rowspan表示跨列 样式: table和td之间有一个默认的距离,通过border-spacing属性可以设置这个距离 border-spacing:0px; 就可以让俩边框合并,但是会导致边框变粗,因为俩合并到一起了嘛 border-collapse可以用来设置表格的边框,如果设置了border-spacing,则border-coll

YuTinH的博客 1168

html表格和表单

HTML表格由和等标签组成,用于创建和格式化表格内容。

2302_81621310的博客 2716

html5表格表单

表格、框架

SilentLand的博客 477

HTML表单元素和表格元素

另外,我们还使用了placeholder属性来指定输入框的占位符文本,用于提示用户输入内容的格式或意义。这里我们使用了label元素来标注输入框的名称,for属性指定了label和input元素的关联关系。input元素是HTML表单元素中最常用的元素之一,它可以接收各种类型的用户输入,例如文本、密码、日期、时间、文件等。学习HTML表单元素时,需要了解各种表单元素的使用场景和相关属性,以便在实际开发中使用。同时,需要注意表单元素的布局和样式,以提高表单的可用性和用户体验。属性来设置默认选中的单选框。

GIS前端嘉欣的博客 1076

【HTML】表格表单

一 表格 表格的基本构成标签 <table> 表格标签 <tr> 行标签 <th></th> 表头标签(加粗并且居中) <th></th> </tr> <tr> <td></td> 单元格标签 <td></td> </tr> </table> 表

weixin_45321793的博客 388

SVPWM(simulink).rar_SVPWM simulink_SVPWM模块搭建_havingozn_svpwm si

用matlab(simulink)编写的SVPWM实现模块,采用模块搭建而成,可以单独设置载波频率。输入信号为克拉克变换后的Ualpha和Ubeta

上一篇: VC6.0转VS2005问题及解决办法
下一篇: Windows音频编程:Win32 Wave API 的使用
skywalker_leo
博客等级 码龄21年 165粉丝 59原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值