VS2012下自定义打开文件对话框
VS2012下自定义打开文件对话框,MFC的CFileDialog封装了太多,太复杂,绕得头晕,自己封装一个得了
#pragma once#include<objbase.h>#include<commdlg.h>#include"ImagePreviewStatic.h" //XFileDialog class XFileDialog : publicCWnd
{
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(intnResult);virtualBOOL OnInitDialog();virtual longDoModal();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 file2 //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 place86 //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(intnResult)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 returnFALSE;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 caseCDN_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 caseCDN_FOLDERCHANGE:161 //Once we get this notification our old subclassing of162 //the SHELL window is lost, so we have to163 //subclass it again. (Changing the folder causes a164 //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 returnFALSE;175 }176 177 longXFileDialog::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 : publicCStatic12 {13 DECLARE_DYNAMIC(CImagePreviewStatic)14 public:15 CImagePreviewStatic();16 virtual ~CImagePreviewStatic();17 18 virtualBOOL Create();19 virtual voidDrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);20 21 voidSetFilename(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 deletem_img;24 }25 if(m_graphics) {26 deletem_graphics;27 }28 if(m_img2) {29 deletem_img2;30 }31 }32 33 BOOL CImagePreviewStatic::Create()34 {35 if (GetSafeHwnd() !=HWND(NULL))36 {37 m_img = newImage(m_wsFilename);38 m_graphics = newGraphics(GetSafeHwnd());39 returnTRUE;40 }41 42 returnFALSE;43 }44 45 voidCImagePreviewStatic::SetFilename(LPCTSTR szFilename)46 {47 #ifndef _UNICODE48 USES_CONVERSION;49 #endif 50 51 ASSERT(szFilename);52 ASSERT(AfxIsValidString(szFilename));53 54 TRACE("%s\n", szFilename);55 56 #ifndef _UNICODE57 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 deletem_img2;66 }67 m_img2 = newCImage();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