weidagang2046的专栏

物格而后知致
随笔 - 8, 文章 - 409, 评论 - 101, 引用 - 0
数据加载中……

MFC文件浏览程序中改变文件读写对话框样式

在我告诉大家怎么样修改MFC浏览程序中文件读写对话框的缺省设置之前呢,我们应该先知道MFC是怎么样显示文件打开和文件保存对话框的。如果你选择了文件菜单中的打开,那么就会有一个消息发送给CWinApp::OnFileOpen,通过一个成员变量m_pDocManager(一个指向CDocManager 对象的指针)来调用CDocManager::OnFileOpen,那么函数就会调用CDocManager的虚函数DoPromptFileName,成功后再调用CWinApp::OpenDocumentFile函数,这个文件对话框就是在DoPromptFileName的虚函数中显示的。当我们打开的是保存对话框时,文件保存(或另存为)命令消息就会发给CDocument::OnFileSave (or CDocument::OnFileSaveAs),在这2种情况下,CDocument::DoSave函数都会被调用。最后,如果文件名是空的,那么CDocument::DoSave就会调用CWinApp::DoPromptFileName,使得成员变量m_pDocManager有效,并且调用CDocManager::DoPromptFileName来显示保存对话框。

  那么现在大家都明白了,CDocManager::DoPromptFileName函数(注意它是一个虚函数)就是负责显示标准的文件打开和保存对话框的(可是有一个BOOL变量来决定显示哪一个对话框的)。

  现在看起来,这好象对改变默认的对话框设置没什么用。你可能也没有考虑过在类CDocManager中的DoPromptFileName函数,或者不知道怎么改,来使用你自己的CDocManager类。那么你不用急,下面的代码就是告诉你怎么自定义CDocManager。

// CDocManager class declaration
//

class CDocManagerEx : public CDocManager
{
  DECLARE_DYNAMIC(CDocManagerEx)

// Construction
public:
  CDocManagerEx();

// Attributes
public:

// Operations
public:

// Overrides
  // helper for standard commdlg dialogs
  virtual BOOL DoPromptFileName(CString& fileName, UINT nIDSTitle,
      DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);

// Implementation
public:
  virtual ~CDocManagerEx();
};


// DocManager.cpp : implementation file
//

#include "stdafx.h"
#include "PreviewFileDlg.h"
#include "DocManager.h" // the header with the class declaration

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static void AppendFilterSuffix(CString& filter, OPENFILENAME& ofn,
  CDocTemplate* pTemplate, CString* pstrDefaultExt)
{
  ASSERT_VALID(pTemplate);
  ASSERT_KINDOF(CDocTemplate, pTemplate);

  CString strFilterExt, strFilterName;
  if (pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt) &&
  !strFilterExt.IsEmpty() &&
  pTemplate->GetDocString(strFilterName, CDocTemplate::filterName) &&
  !strFilterName.IsEmpty())
  {
    // a file based document template - add to filter list
#ifndef _MAC
    ASSERT(strFilterExt[0] == '.');
#endif
    if (pstrDefaultExt != NULL)
    {
      // set the default extension
#ifndef _MAC
      *pstrDefaultExt = ((LPCTSTR)strFilterExt) 1; // skip the '.'
#else
      *pstrDefaultExt = strFilterExt;
#endif
      ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt);
      ofn.nFilterIndex = ofn.nMaxCustFilter 1; // 1 based number
    }

    // add to filter
    filter = strFilterName;
    ASSERT(!filter.IsEmpty()); // must have a file type name
    filter = (TCHAR)'\0'; // next string please
#ifndef _MAC
    filter = (TCHAR)'*';
#endif
    filter = strFilterExt;
    filter = (TCHAR)'\0'; // next string please
    ofn.nMaxCustFilter ;
  }
}

/////////////////////////////////////////////////////////////////////////////
// CDocManagerEx

IMPLEMENT_DYNAMIC(CDocManagerEx, CDocManager)

CDocManagerEx::CDocManagerEx()
{
}

CDocManagerEx::~CDocManagerEx()
{
}

BOOL CDocManagerEx::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
{
  CPreviewFileDlg dlgFile(bOpenFileDialog); // this is the only modified line!

  CString title;
  VERIFY(title.LoadString(nIDSTitle));

  dlgFile.m_ofn.Flags |= lFlags;

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

  // append the "*.*" all files filter
  CString allFilter;
  VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
  strFilter = allFilter;
strFilter = (TCHAR)'\0'; // next string please
#ifndef _MAC
  strFilter = _T("*.*");
#else
  strFilter = _T("****");
#endif
  strFilter = (TCHAR)'\0'; // last string
  dlgFile.m_ofn.nMaxCustFilter ;

  dlgFile.m_ofn.lpstrFilter = strFilter;
#ifndef _MAC
  dlgFile.m_ofn.lpstrTitle = title;
#else
  dlgFile.m_ofn.lpstrPrompt = title;
#endif
  dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);

  BOOL bResult = dlgFile.DoModal() == IDOK ? TRUE : FALSE;
  fileName.ReleaseBuffer();
  return bResult;
}

  以上代码是从MFC原代码中完整的拷贝过来的,当中只有一行需要改:对话框的声明(当然,由于这是CFileDialog的子类,你可以有更多的修改权),而且对于标准对话框来说,还应该有预览功能。AppendFilterSuffix函数是从DoPromptFileName中被调用的,原代码可以从你的工程中获得。如果你想显示打开和保存对话框,你可以使用bOpenFileDialog参数,TRUE表示对话框是打开对话框,反之,亦然。


  当然我们也可以使用我们自己定义的CDocManagerEx类来代替原来的CDocManager类,CWinApp是通过成员变量m_pDocManager来使用文档管理器,所以我们必须正确的初始化这个变量。有必要特别关注一下在CWinApp::AddDocTemplate中CWinApp创建对象的原代码,这其中有一个很普通的函数调用,我们把它给忽略了,那就是CWinApp::InitInstance函数。当m_pDocManager参数是NULL的时候,CWinApp::AddDocTemplate函数只是创建CDocManager对象,那么一旦m_pDocManager指针被正确的初始化,CWinApp::AddDocTemplate函数也就能够被正确的调用了。因此,这最后一步就是在调用CWinApp::AddDocTemplate之前就初始化成员变量m_pDocManager,以达到我们想要的样子。(当然你也不一定得调用CWinApp::AddDocTemplate,而是直接调用m_pDocManager->AddDocTemplate也行)
以下就是代码:

BOOL COurApp::InitInstance()
{
  // Standard initialization
  // If you are not using these features and wish to reduce the size
  // of your final executable, you should remove from the following
  // the specific initialization routines you do not need.

#ifdef _AFXDLL
  Enable3dControls();      // Call this when using MFC in a shared DLL
#else
  Enable3dControlsStatic();  // Call this when linking to MFC statically
#endif

  // Change the registry key under which our settings are stored.
  // You should modify this string to be something appropriate
  // such as the name of your company or organization.
  SetRegistryKey(_T("Local AppWizard-Generated Applications"));

  LoadStdProfileSettings(); // Load standard INI file options (including MRU)

  // Register the application's document templates. Document templates
  // serve as the connection between documents, frame windows and views.

  CMultiDocTemplate* pDocTemplate;
  pDocTemplate = new CMultiDocTemplate(
    IDR_DIBTYPE,
    RUNTIME_CLASS(COurDoc),
    RUNTIME_CLASS(CChildFrame), // custom MDI child frame
    RUNTIME_CLASS(COurView));
  ASSERT(m_pDocManager == NULL);
  m_pDocManager = new CDocManagerEx;
  m_pDocManager->AddDocTemplate(pDocTemplate); // or just AddDocTemplate(pDocTemplate);

  // create main MDI Frame window
  CMainFrame* pMainFrame = new CMainFrame;
  if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
    return FALSE;
  m_pMainWnd = pMainFrame;

  // Enable drag/drop open
  m_pMainWnd->DragAcceptFiles();

  // Enable DDE Execute open
  EnableShellOpen();
  RegisterShellFileTypes(TRUE);

  // Parse command line for standard shell commands, DDE, file open
  CCommandLineInfo cmdInfo;
  ParseCommandLine(cmdInfo);

  // Dispatch commands specified on the command line
  if (!ProcessShellCommand(cmdInfo))
    return FALSE;

  // The main window has been initialized, so show and update it.
  pMainFrame->ShowWindow(m_nCmdShow);
  pMainFrame->UpdateWindow();

  return TRUE;
}

from: http://www.quickviews.net/data/2006/0421/article_16587_1.htm

posted on 2006-08-13 14:55 weidagang2046 阅读(517) 评论(0)  编辑  收藏 所属分类: Windows


只有注册用户登录后才能发表评论。


网站导航: