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 閱讀(523) 評論(0)  編輯  收藏 所屬分類: Windows

          主站蜘蛛池模板: 吴忠市| 静海县| 陇西县| 盐城市| 工布江达县| 平安县| 临猗县| 遵义县| 疏附县| 土默特右旗| 布拖县| 怀仁县| 阜宁县| 建湖县| 木兰县| 平江县| 苍溪县| 延长县| 年辖:市辖区| 建瓯市| 云霄县| 义乌市| 手机| 吴堡县| 微山县| 赤城县| 长白| 九龙县| 遂宁市| 宁安市| 亚东县| 嘉兴市| 连山| 云和县| 遂溪县| 玛曲县| 依安县| 都昌县| 民县| 盐亭县| 永善县|