zoukankan      html  css  js  c++  java
  • VS2012下自定义打开文件对话框

    VS2012下自定义打开文件对话框,MFC的CFileDialog封装了太多,太复杂,绕得头晕,自己封装一个得了

    #pragma once
    
    #include <objbase.h>
    #include <commdlg.h>
    
    #include "ImagePreviewStatic.h"
    
    // XFileDialog
    
    class XFileDialog : public CWnd
    {
        DECLARE_DYNAMIC(XFileDialog)
    
    public:
        XFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
            LPCTSTR lpszDefExt = NULL,
            LPCTSTR lpszFileName = NULL,
            DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
            LPCTSTR lpszFilter = NULL, LPCTSTR lpszInitFolder = NULL,
            CWnd* pParentWnd = NULL);
        virtual ~XFileDialog();
    
    public:
        void EndDialog(int nResult);
    
        virtual BOOL OnInitDialog();
        virtual long DoModal();
        virtual    void DoDataExchange(CDataExchange *pDX);
        virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
    
        virtual void ProcFileChange(TCHAR* strFullName);
    
    protected:
        OPENFILENAME m_ofn;
        BOOL m_bOpenFileDialog;       // TRUE for file open, FALSE for file save
        CString m_strFilter;          // filter string
        TCHAR m_szFileTitle[64];       // contains file title after return
        TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return
    
        CWnd* m_pParentWnd;             // parent/owner window
        HWND m_hWndTop;                 // top level parent window (may be disabled)
    
        CImagePreviewStatic    m_preview;
    
        DECLARE_MESSAGE_MAP()
    };
      1 // XFileDialog.cpp : implementation file
      2 //
      3 
      4 #include "stdafx.h"
      5 #include "XFileDialog.h"
      6 #include "resource.h"
      7 
      8 // XFileDialog
      9 
     10 UINT_PTR CALLBACK OFNHookProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
     11 
     12 UINT_PTR CALLBACK OFNHookProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     13 {
     14     if (hWnd == NULL)
     15         return 0;
     16     _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
     17     if (pThreadState->m_pAlternateWndInit != NULL && CWnd::FromHandlePermanent(hWnd) == NULL)
     18     {
     19         ASSERT_KINDOF(XFileDialog, pThreadState->m_pAlternateWndInit);
     20         pThreadState->m_pAlternateWndInit->SubclassWindow(hWnd);
     21         pThreadState->m_pAlternateWndInit = NULL;
     22     }
     23 
     24     if (message == WM_INITDIALOG)
     25     {
     26         /*
     27         _afxMsgLBSELCHANGE = ::RegisterWindowMessage(LBSELCHSTRING);
     28         _afxMsgSHAREVI = ::RegisterWindowMessage(SHAREVISTRING);
     29         _afxMsgFILEOK = ::RegisterWindowMessage(FILEOKSTRING);
     30         _afxMsgCOLOROK = ::RegisterWindowMessage(COLOROKSTRING);
     31         _afxMsgHELP = ::RegisterWindowMessage(HELPMSGSTRING);
     32         _afxMsgSETRGB = ::RegisterWindowMessage(SETRGBSTRING);
     33         */
     34 
     35         XFileDialog* pDlg = DYNAMIC_DOWNCAST(XFileDialog, CWnd::FromHandlePermanent(hWnd));
     36         if (pDlg != NULL)
     37             return pDlg->OnInitDialog();
     38         else
     39             return 1;
     40     }
     41 
     42     return 0;
     43 }
     44 
     45 BEGIN_MESSAGE_MAP(XFileDialog, CWnd)
     46 END_MESSAGE_MAP()
     47 
     48 XFileDialog::XFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
     49         DWORD dwFlags, LPCTSTR lpszFilter, LPCTSTR lpszInitFolder, CWnd* pParentWnd) :
     50       CWnd()
     51 {
     52     m_szFileName[0] = '';
     53     m_szFileTitle[0] = '';
     54     m_bOpenFileDialog = bOpenFileDialog;
     55 
     56     m_pParentWnd = NULL;
     57     m_hWndTop = NULL;
     58 
     59     memset(&m_ofn, 0, sizeof(OPENFILENAME)); // initialize structure to 0/NULL
     60 
     61     m_ofn.Flags |=  dwFlags | OFN_ENABLETEMPLATE |OFN_HIDEREADONLY | OFN_EXPLORER  | OFN_ENABLEHOOK;
     62     m_ofn.lpstrTitle   =  _T("图像文件预览对话框");
     63     m_ofn.lpstrInitialDir = lpszInitFolder;
     64 
     65     m_ofn.lStructSize =  sizeof(OPENFILENAME);
     66     m_ofn.lpstrFile = m_szFileName;
     67     m_ofn.nMaxFile = _countof(m_szFileName);
     68     m_ofn.lpstrDefExt = lpszDefExt;
     69     m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
     70     m_ofn.nMaxFileTitle = _countof(m_szFileTitle);
     71     if(dwFlags & OFN_ENABLETEMPLATE)
     72         m_ofn.Flags &= ~OFN_ENABLESIZING;
     73     m_ofn.hInstance = AfxGetResourceHandle();
     74     m_ofn.lpfnHook =  (LPOFNHOOKPROC)OFNHookProc;
     75     m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_IMAGEPREVIEWDLG);
     76 
     77     // setup initial file name
     78     if (lpszFileName != NULL)
     79         Checked::tcsncpy_s(m_szFileName, _countof(m_szFileName), lpszFileName, _TRUNCATE);
     80 
     81     // Translate filter into commdlg format (lots of )
     82     if (lpszFilter != NULL)
     83     {
     84         m_strFilter = lpszFilter;
     85         LPTSTR pch = m_strFilter.GetBuffer(0); // modify the buffer in place
     86         // MFC delimits with '|' not ''
     87         while ((pch = _tcschr(pch, '|')) != NULL)
     88             *pch++ = '';
     89         m_ofn.lpstrFilter = m_strFilter;
     90         // do not call ReleaseBuffer() since the string contains '' characters
     91     }
     92 }
     93 
     94 XFileDialog::~XFileDialog()
     95 {
     96 }
     97 
     98 void XFileDialog::EndDialog(int nResult)
     99 {
    100     ASSERT(::IsWindow(m_hWnd));
    101 
    102     ::EndDialog(m_hWnd, nResult);
    103 }
    104 
    105 BOOL XFileDialog::OnInitDialog()
    106 {
    107     // transfer data into the dialog from member variables
    108 #if 1
    109     if (!UpdateData(FALSE))
    110     {
    111         TRACE(traceAppMsg, 0, "Warning: UpdateData failed during dialog init.
    ");
    112         EndDialog(-1);
    113         return FALSE;
    114     }
    115 #endif
    116 
    117     GetDlgItem(IDC_IMAGEPREVIEW)->ModifyStyle ( SS_TYPEMASK, SS_OWNERDRAW );
    118 
    119     return TRUE;    // set focus to first one
    120 }
    121 
    122 void XFileDialog::DoDataExchange(CDataExchange *pDX)
    123 {
    124     CWnd::DoDataExchange(pDX);
    125     DDX_Control(pDX, IDC_IMAGEPREVIEW, m_preview);
    126 }
    127 
    128 void XFileDialog::ProcFileChange(TCHAR* strFullName){
    129     //如果是文件名
    130     DWORD nFileAtts = GetFileAttributes(strFullName);
    131     if ((FILE_ATTRIBUTE_NORMAL == nFileAtts) ||
    132         (0 == (nFileAtts & (FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_DIRECTORY )) ) ){
    133         m_preview.SetFilename(strFullName);
    134     } else {
    135         //m_preview.SetFilename(NULL);
    136     }
    137 }
    138 
    139 
    140 BOOL XFileDialog::OnNotify(WPARAM, LPARAM lp, LRESULT *pResult)
    141 {
    142     LPOFNOTIFY of =    (LPOFNOTIFY) lp;
    143     CString       csTemp;
    144     TCHAR       strFileName[_MAX_PATH];
    145 
    146     HWND hParent;
    147     UINT nfiles;
    148 
    149     switch (of->hdr.code)
    150     {
    151     case CDN_SELCHANGE:
    152         hParent = GetParent()->GetSafeHwnd();
    153         nfiles = CommDlg_OpenSave_GetFilePath(hParent, strFileName, _MAX_PATH);
    154         if (nfiles > 0) {
    155             ProcFileChange(strFileName);
    156             //MessageBox(strFileName);
    157         }
    158         break;
    159 
    160     case CDN_FOLDERCHANGE:
    161         //    Once we    get    this notification our old subclassing of
    162         //    the    SHELL window is    lost, so we    have to
    163         //    subclass it    again. (Changing the folder    causes a 
    164         //    destroy    and    recreate of    the    SHELL window).
    165         //if (m_wndHook.GetSafeHwnd()    != HWND(NULL))
    166         //    m_wndHook.UnsubclassWindow();
    167 
    168         //m_wndHook.SubclassWindow(GetParent()->GetDlgItem(lst2)->GetSafeHwnd());
    169         //UpdatePreview(_T(""));
    170         break;
    171     }
    172 
    173     *pResult = 0;
    174     return FALSE;
    175 }
    176 
    177 long XFileDialog::DoModal()
    178 {
    179     HWND hWndFocus = ::GetFocus();
    180     BOOL bEnableParent = FALSE;
    181     // allow OLE servers to disable themselves
    182     CWinApp* pApp = AfxGetApp();
    183     if (pApp != NULL)
    184         pApp->EnableModeless(FALSE);
    185 
    186     _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
    187     pThreadState->m_pAlternateWndInit = this;
    188     //AfxHookWindowCreate(this);
    189 
    190     HWND hWndParent = CWnd::GetSafeOwner_(m_pParentWnd->GetSafeHwnd(), &m_hWndTop);;
    191     if (hWndParent && hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))
    192     {
    193         ::EnableWindow(hWndParent, FALSE);
    194         bEnableParent = TRUE;
    195     }
    196 
    197     INT_PTR nResult = 0;
    198 
    199     if (m_bOpenFileDialog)
    200         nResult = GetOpenFileName(&m_ofn);
    201     else
    202         nResult = GetSaveFileName(&m_ofn);
    203 
    204     if (nResult)
    205         ASSERT(pThreadState->m_pAlternateWndInit == NULL);
    206 
    207     // Second part of special case for file open/save dialog.
    208     if (bEnableParent)
    209         ::EnableWindow(hWndParent, TRUE);
    210     if (::IsWindow(hWndFocus))
    211         ::SetFocus(hWndFocus);
    212 
    213     AfxUnhookWindowCreate();   // just in case
    214     Detach();               // just in case
    215 
    216     if (pApp != NULL)
    217         pApp->EnableModeless(TRUE);
    218 
    219     return nResult ? nResult : IDCANCEL;
    220 }
    221 
    222 
    223 IMPLEMENT_DYNAMIC(XFileDialog, CWnd)
    224 
    225 // XFileDialog message handlers
    ImagePreviewStatic.h其实就是一个CStatic的继承类,实现图片预览
     1 /*
     2  *    $Header: $
     3  *
     4  *    $History: $
     5  */
     6 #pragma once
     7 
     8 #include <atlimage.h>
     9 
    10 // CImagePrieviewStatic
    11 class CImagePreviewStatic :    public CStatic
    12 {
    13     DECLARE_DYNAMIC(CImagePreviewStatic)
    14 public:
    15                     CImagePreviewStatic();
    16     virtual            ~CImagePreviewStatic();
    17 
    18     virtual    BOOL    Create();
    19     virtual    void    DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    20 
    21     void            SetFilename(LPCTSTR    szFilename);
    22 
    23 protected:
    24     WCHAR            m_wsFilename[_MAX_PATH];
    25     Image            *m_img;
    26     Graphics        *m_graphics;
    27     CImage          *m_img2;
    28 
    29     DECLARE_MESSAGE_MAP()
    30 };
      1 /*
      2  *    $Header: $
      3  *
      4  *    $History: $
      5  */
      6 #include "stdafx.h"
      7 #include "ImagePreviewStatic.h"
      8 
      9 
     10 // CImagePrieviewStatic
     11 IMPLEMENT_DYNAMIC(CImagePreviewStatic, CStatic)
     12 
     13 CImagePreviewStatic::CImagePreviewStatic() : CStatic()
     14 {
     15     m_img = (Image *) NULL;
     16     m_graphics = (Graphics *) NULL;
     17     m_img2 = (CImage*) NULL;
     18 }
     19 
     20 CImagePreviewStatic::~CImagePreviewStatic()
     21 {
     22     if (m_img) {
     23         delete m_img;
     24     }
     25     if (m_graphics) {
     26         delete m_graphics;
     27     }
     28     if (m_img2) {
     29         delete m_img2;
     30     }
     31 }
     32 
     33 BOOL CImagePreviewStatic::Create()
     34 {
     35     if (GetSafeHwnd() != HWND(NULL))
     36     {
     37         m_img =    new    Image(m_wsFilename);
     38         m_graphics = new Graphics(GetSafeHwnd());
     39         return TRUE;
     40     }
     41 
     42     return FALSE;
     43 }
     44 
     45 void CImagePreviewStatic::SetFilename(LPCTSTR szFilename)
     46 {
     47 #ifndef    _UNICODE
     48     USES_CONVERSION;
     49 #endif
     50 
     51     ASSERT(szFilename);
     52     ASSERT(AfxIsValidString(szFilename));
     53 
     54     TRACE("%s
    ", szFilename);
     55 
     56 #ifndef    _UNICODE
     57     wcscpy(m_wsFilename, A2W(szFilename));
     58 #else
     59     wcscpy(m_wsFilename, szFilename);
     60 #endif
     61 
     62     //delete m_img;
     63     //m_img =    new    Image(m_wsFilename,    FALSE);
     64     if (m_img2) {
     65         delete m_img2;
     66     }
     67     m_img2 = new CImage();
     68     m_img2->Load(szFilename);
     69 
     70     Invalidate();
     71 }
     72 
     73 void CImagePreviewStatic::DrawItem(LPDRAWITEMSTRUCT    /*lpDrawItemStruct*/)
     74 {
     75     Unit  units;
     76     CRect rect;
     77 
     78     /*
     79     if (m_img != NULL)
     80     {
     81         GetClientRect(&rect);
     82 
     83         RectF destRect(REAL(rect.left),    REAL(rect.top),    REAL(rect.Width()),    REAL(rect.Height())),
     84               srcRect;
     85         m_img->GetBounds(&srcRect, &units);
     86         m_graphics->DrawImage(m_img, destRect, srcRect.X, srcRect.Y, srcRect.Width,    srcRect.Height,    UnitPixel, NULL);
     87     } 
     88     */
     89     if (m_img2 != NULL) {
     90         HWND hWnd = GetParent()->m_hWnd;
     91         HDC hDc = ::GetDC(hWnd);
     92         GetWindowRect(&rect);
     93         ::ScreenToClient(hWnd, (LPPOINT)&rect);
     94         ::ScreenToClient(hWnd, (LPPOINT)(&rect) + 1);
     95         //获取到HDC
     96         m_img2->Draw(hDc,rect);
     97     }
     98 }
     99 
    100 BEGIN_MESSAGE_MAP(CImagePreviewStatic, CStatic)
    101 END_MESSAGE_MAP()
    102 
    103 // CImagePrieviewStatic message handlers

    其中的对话框资源
    IDD_IMAGEPREVIEWDLG DIALOGEX 0, 0, 365, 177
    STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS
    FONT 8, "MS Shell Dlg", 400, 0, 0x1
    BEGIN
        CONTROL         "",IDC_IMAGEPREVIEW,"Static",SS_OWNERDRAW,7,7,351,163
    END
  • 相关阅读:
    C#基于接口的编程
    在window组件服务中建立WCF宿主
    给WWF传递参数
    创建singleton模式的工作流引擎
    WCF消息交换模式之Duplex
    SqlServer中查询出多条记录变成一个记录(行变列)
    WCF三种消息交互模式MEP
    Asp.net实现在线截图!
    WWF之跟踪服务WorkFlowTrack
    hdu 2604 Queuing (Matrix)
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/11063516.html
Copyright © 2011-2022 走看看