WTL檔案選擇對話方塊 – CFileDialogImpl

來源:互聯網
上載者:User

WTL檔案選擇對話方塊 - CFileDialogImpl

 

1)首先下面的代碼是直接使用Win32 API來開啟單個檔案的代碼:

 

void WinSDK_OpenFileDemo()
{
    OPENFILENAME    ofn = {0};
    char   szFile[MAX_PATH];
    *szFile = 0;

    // 開始設定OPENFILENAME結構成員
    ofn.lStructSize   = sizeof(OPENFILENAME);
    ofn.hwndOwner   =   hDlg;
    ofn.lpstrFile   =   szFile;
    ofn.nMaxFile   =   MAX_PATH;
    ofn.lpstrFilter    =  "ESRI Shape檔案(*.SHP)/0*.shp/0AutoCAD分頁檔(*.DXF;*.DXF.GZ)/0*.dxf;*.dxf.gz /0所有影像檔/0*.jpg;*.jpeg;*.png;*.gif;*.bmp;*.tif;*.tiff/0所有檔案(*.*)/0*.*/0/0";

    ofn.nFilterIndex   =  1;
    ofn.lpstrTitle   =  "開啟地圖檔案";
    ofn.lpstrInitialDir = 0;

    ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;

    // 指派給"開啟"對話方塊, 並顯示對話方塊
    if (::GetOpenFileName(&ofn))
    {

        // 現在下面的成員中存放了我們要的檔案名稱
        // ofn.lpstrFile;
    }
}

 

2)類似的用WTL來實現檔案開啟的功能就簡單多了。下面的代碼同時開啟多個檔案:

LRESULT CMainFrame::OnFileOpen(...)
{
    CMyFileDialog  openFileDlg( TRUE,
                                _T("shp"),
                                _T(""),
                                OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT,
                                _T("Shape 檔案(*.shp)|*.shp|CAD分頁檔(*.dxf)|*.dxf|影像檔|*.jpg;*.jpeg;*.png;*.gif;*.bmp;*.tif;*.tiff|所有檔案(*.*)|*.*|"),
                                this->m_hWnd,
                                _T("開啟地圖檔案")
                               );

    if ( IDOK == openFileDlg.DoModal() )
    {
        int nOpenFiles = openFileDlg.GetOpenFileCount();
       
        if (nOpenFiles>0)
        {
            for (int i=0; i<nOpenFiles; i++)
            {
                //檔案名稱:openFileDlg.GetOpenFileAt(i);
            }
        }
    }   

    return 0;
}

 

3)完整的CMyFileDialog的代碼如下(在WTL8.0, 8.1測試通過):

class CMyFileDialog :
    public CFileDialogImpl<CMyFileDialog>
{
public:
    // Construction
    CMyFileDialog (BOOL         bOpenFileDialog,
                  _U_STRINGorID szDefExt = 0U,
                  _U_STRINGorID szFileName = 0U,
                  DWORD         dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
                  _U_STRINGorID szFilter = 0U,
                  HWND          hwndParent = NULL,
                  _U_STRINGorID szTitle= 0U ) :
        CFileDialogImpl<CMyFileDialog>(bOpenFileDialog, NULL, NULL, dwFlags, NULL, hwndParent),
        m_sDefExt(szDefExt.m_lpstr),
        m_sFileName(szFileName.m_lpstr),
        m_sFilter(szFilter.m_lpstr),
        m_sTitle(szTitle.m_lpstr),
        _FilesCount(-1)
    {
        m_ofn.lpstrDefExt = m_sDefExt;
        m_ofn.lpstrFilter = PrepFilterString ( m_sFilter );
        m_ofn.lpstrTitle = m_sTitle;

        // setup initial file name
        if ( !m_sFileName.IsEmpty() )
            lstrcpyn ( m_szFileName, m_sFileName, _MAX_PATH );
    }

    // Maps
    BEGIN_MSG_MAP(CMyFileDialog)
        CHAIN_MSG_MAP(CFileDialogImpl<CMyFileDialog>)
    END_MSG_MAP()

    // Overrides
    void OnInitDone ( LPOFNOTIFY lpon )
    {
        GetFileDialogWindow().CenterWindow(lpon->lpOFN->hwndOwner);
    }

    // Get Open Files Count
    int GetOpenFileCount(void)
    {
        if (!m_bOpenFileDialog)
            return 0;

        if (_FilesCount==-1)
        {
            int i = 0;       
            int i0 = 0;
            _FilesCount = 0;
           
            while(i < _MAX_PATH-1){
                if (m_szFileName[i]==0){
                    _FileStarts[_FilesCount++] = i0;
                    i0 = i+1;

                    if (m_szFileName[i+1]==0)
                       break;
                }
                i++;
            }
           
            if (_FilesCount>1){
                _tcsncpy_s(_FileName, _MAX_PATH, m_szFileName, _FileStarts[1]);
                _FileName[ _FileStarts[1] ] = 0;
                _FileName[ _FileStarts[1]-1 ] = _T('//');
                _FilesCount--;
            }
        }

        return _FilesCount;
    }

    // Get Open FileName: index 0-based
    LPCTSTR GetOpenFileAt(int index)
    {
        ATLASSERT(_FilesCount > 0);
       
        if (_FilesCount==1){
            ATLASSERT(index==0);
            return m_szFileName;
        }

        _FileName[ _FileStarts[1] ] = 0;
        _tcscat_s(_FileName, _MAX_PATH, m_szFileName + _FileStarts[index+1]);
    
        return _FileName;
    }

protected:
    LPCTSTR PrepFilterString ( CString& sFilter )
    {
        LPTSTR psz = sFilter.GetBuffer(0);
        LPCTSTR pszRet = psz;

        while ( '/0' != *psz )
        {
            if ( '|' == *psz )
                *psz++ = '/0';
            else
                psz = CharNext ( psz );
        }

        return pszRet;
    }   
  
    int     _FilesCount;
    int     _FileStarts[_MAX_PATH];
    TCHAR   _FileName[_MAX_PATH];

    CString m_sDefExt, m_sFileName, m_sFilter, m_sTitle;
};

 

4)結論

編寫windows用戶端介面程式有不少於100種方法可用。經典的如MFC;時髦的如DHTML,Form,WPF;純理論的如SDK;跨平台的如Java(這裡面就有N多架構),QT等等。可是至今我覺得還是WTL/ATL最乾淨利落,也最強大。尤其WTL,雖然不是MS力推的主流,但這主要是因為MS為了.NET平台推廣而有意壓制的技術。WTL也是最適合我們玩的東西。

 

 

 

 

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.