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] = '\0';
 53     m_szFileTitle[0] = '\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 \0)
 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 '\0'
 87         while ((pch = _tcschr(pch, '|')) != NULL)
 88             *pch++ = '\0';
 89         m_ofn.lpstrFilter = m_strFilter;
 90         // do not call ReleaseBuffer() since the string contains '\0' 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.\n");
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\n", 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

 

posted @ 2019-06-21 11:14  日月王  阅读(899)  评论(0编辑  收藏  举报