본문 바로가기

Windows/MFC

CFileDialogEx

////////////////////////////////////////////////////////////////
// MSDN -- August 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably NT too.
//
#pragma once

// Windows 2000 version of OPENFILENAME.
// The new version has three extra members.
// This is copied from commdlg.h
//
struct OPENFILENAMEEX : public OPENFILENAME {
void *        pvReserved;
DWORD         dwReserved;
DWORD         FlagsEx;
};

/////////////////////////////////////////////////////////////////////////////
// CFileDialogEx: Encapsulate Windows-2000 style open dialog.
//
class CFileDialogEx : public CFileDialog {
    DECLARE_DYNAMIC(CFileDialogEx)
public:
    CFileDialogEx(BOOL bOpenFileDialog, // TRUE for open, FALSE for FileSaveAs
        LPCTSTR lpszDefExt = NULL,
        LPCTSTR lpszFileName = NULL,
        DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
        LPCTSTR lpszFilter = NULL,
        CWnd* pParentWnd = NULL);

    // override
    virtual int DoModal();

protected:
    OPENFILENAMEEX m_ofnEx;    // new Windows 2000 version of OPENFILENAME

    virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);

    // virtual fns that handle various notifications
    virtual BOOL OnFileNameOK();
    virtual void OnInitDone();
    virtual void OnFileNameChange();
    virtual void OnFolderChange();
    virtual void OnTypeChange();

    DECLARE_MESSAGE_MAP()
    //{{AFX_MSG(CFileDialogEx)
    //}}AFX_MSG
};



////////////////////////////////////////////////////////////////
// MSDN -- August 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Largely based on original implementation by Michael Lemley.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably NT too.
//
// CFileDialogEx implements a CFileDialog that uses the new Windows
// 2000 style open/save dialog. Use companion class CDocManagerEx in an
// MFC framework app.
//
#include "stdafx.h"
#include <afxpriv.h>

#include "FileDialogEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

static BOOL IsWin2000();

IMPLEMENT_DYNAMIC(CFileDialogEx, CFileDialog)

CFileDialogEx::CFileDialogEx(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,
    LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
    CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName,
        dwFlags, lpszFilter, pParentWnd)
{
}


BEGIN_MESSAGE_MAP(CFileDialogEx, CFileDialog)
    //{{AFX_MSG_MAP(CFileDialogEx)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL IsWin2000()
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;

// Try calling GetVersionEx using the OSVERSIONINFOEX structure,
// which is supported on Windows 2000.
//
// If that fails, try using the OSVERSIONINFO structure.

ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
{
     // If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.

     osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
     if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
         return FALSE;
}

switch (osvi.dwPlatformId)
{
     case VER_PLATFORM_WIN32_NT:

         if ( osvi.dwMajorVersion >= 5 )
            return TRUE;

         break;
}
return FALSE;
}

//////////////////
// DoModal override copied mostly from MFC, with modification to use
// m_ofnEx instead of m_ofn.
//
int CFileDialogEx::DoModal()
{
#if _MFC_VER >= 0x700
    return CFileDialog::DoModal();
#else
    ASSERT_VALID(this);
    ASSERT(m_ofn.Flags & OFN_ENABLEHOOK);
    ASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook

    // zero out the file buffer for consistent parsing later
    ASSERT(AfxIsValidAddress(m_ofn.lpstrFile, m_ofn.nMaxFile));
    DWORD nOffset = lstrlen(m_ofn.lpstrFile)+1;
    ASSERT(nOffset <= m_ofn.nMaxFile);
    memset(m_ofn.lpstrFile+nOffset, 0, (m_ofn.nMaxFile-nOffset)*sizeof(TCHAR));

    // WINBUG: This is a special case for the file open/save dialog,
    // which sometimes pumps while it is coming up but before it has
    // disabled the main window.
    HWND hWndFocus = ::GetFocus();
    BOOL bEnableParent = FALSE;
    m_ofn.hwndOwner = PreModal();
    AfxUnhookWindowCreate();
    if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner))
    {
        bEnableParent = TRUE;
        ::EnableWindow(m_ofn.hwndOwner, FALSE);
    }

    _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
    ASSERT(pThreadState->m_pAlternateWndInit == NULL);

    if (m_ofn.Flags & OFN_EXPLORER)
        pThreadState->m_pAlternateWndInit = this;
    else
        AfxHookWindowCreate(this);

    memset(&m_ofnEx, 0, sizeof(m_ofnEx));
    memcpy(&m_ofnEx, &m_ofn, sizeof(m_ofn));
if (IsWin2000())
     m_ofnEx.lStructSize = sizeof(m_ofnEx);

    int nResult;
    if (m_bOpenFileDialog)
        nResult = ::GetOpenFileName((OPENFILENAME*)&m_ofnEx);
    else
        nResult = ::GetSaveFileName((OPENFILENAME*)&m_ofnEx);

    memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
m_ofn.lStructSize = sizeof(m_ofn);

    if (nResult)
        ASSERT(pThreadState->m_pAlternateWndInit == NULL);
    pThreadState->m_pAlternateWndInit = NULL;

    // WINBUG: Second part of special case for file open/save dialog.
    if (bEnableParent)
        ::EnableWindow(m_ofnEx.hwndOwner, TRUE);
    if (::IsWindow(hWndFocus))
        ::SetFocus(hWndFocus);

    PostModal();
    return nResult ? nResult : IDCANCEL;
#endif

}

//////////////////
// When the open dialog sends a notification, copy m_ofnEx to m_ofn in
// case handler function is expecting updated information in the
// OPENFILENAME struct.
//
BOOL CFileDialogEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
#if _MFC_VER >= 0x700
    return CFileDialog::OnNotify(wParam, lParam, pResult);
#else
    memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
    m_ofn.lStructSize = sizeof(m_ofn);

    return CFileDialog::OnNotify( wParam, lParam, pResult);
#endif

}

////////////////////////////////////////////////////////////////
// The following functions are provided for testing purposes, to
// demonstrate that they in fact called; ie, that MFC's internal dialog
// proc is hooked up properly. Delete them if you like.
//
BOOL CFileDialogEx::OnFileNameOK()
{
    TRACE(_T("CFileDialogEx::OnFileNameOK\n"));
return CFileDialog::OnFileNameOK();
}

void CFileDialogEx::OnInitDone()
{
    TRACE(_T("CFileDialogEx::OnInitDone\n"));
CFileDialog::OnInitDone();
}

void CFileDialogEx::OnFileNameChange()
{
    TRACE(_T("CFileDialogEx::OnFileNameChange\n"));
CFileDialog::OnFileNameChange();
}

void CFileDialogEx::OnFolderChange()
{
    TRACE(_T("CFileDialogEx::OnFolderChange\n"));
CFileDialog::OnFolderChange();
}

void CFileDialogEx::OnTypeChange()
{
    TRACE(_T("OnTypeChange(), index = %d\n"), m_ofn.nFilterIndex);
CFileDialog::OnTypeChange();
}


'Windows > MFC' 카테고리의 다른 글

Close button Hide (닫기 버튼 숨기기)  (0) 2013.10.02
CFileDialog 새로운 다이얼로그 사용하기  (0) 2013.10.02
CDlgEvent  (0) 2013.10.02
Program files 구하는 법  (0) 2013.10.02
ACC:  (0) 2013.10.02