文件文件夹混合多选对话框(修改GWL_WNDPROC)

/********************************************************************
    created:    2008/07/22
    created:    22:7:2008   10:23
    filename:     SelectDialog.h
    file base:    SelectDialog
    file ext:    h
    author:        Hojjat Bohlooli - software@tarhafarinin.ir
    
    purpose:    select multiple file and folders together in browse dialog
                free for non commercial uses.
*********************************************************************/
#pragma once

#include <wtl/atlapp.h>
#include <wtl/atldlgs.h>
#include <wtl/atlctrls.h>
#include <atlstr.h>
#include <vector>
#include <dlgs.h> // for (MULTI)FILEOPENORD
#include <set>

using namespace  std;

// CSelectDialog
class CSelectDialog : public CFileDialogImpl<CSelectDialog>
{
    //DECLARE_DYNAMIC(CSelectDialog)

public:
    CSelectDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
        LPCTSTR lpszDefExt = NULL,
        LPCTSTR lpszFileName = NULL,
        DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |
                        OFN_EXPLORER & (~OFN_SHOWHELP),
        LPCTSTR lpszFilter = NULL,
        HWND pParentWnd = NULL);
    virtual ~CSelectDialog();
    
    BEGIN_MSG_MAP(CSelectDialog)
        CHAIN_MSG_MAP(CFileDialogImpl<CSelectDialog>)
    END_MSG_MAP()

public:
    virtual void OnInitDone(LPOFNOTIFY /*lpon*/);
    virtual void OnFolderChange(LPOFNOTIFY /*lpon*/);
    virtual BOOL OnFileOK(LPOFNOTIFY /*lpon*/);
    static LRESULT CALLBACK WindowProcNew(HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam);
    LRESULT OnSelChange(LPOFNOTIFY pnmh);
    //DECLARE_MESSAGE_MAP()

public:
    static CString m_strCurrendDirectory;
    static vector<CString> m_SelectedItemList;    /*this list includes files and folders
                                            are selected by user. */
    static WNDPROC m_wndProc;
};
/********************************************************************
    created:    2008/07/22
    created:    22:7:2008   10:25
    filename:     SelectDialog.cpp
    file base:    SelectDialog
    file ext:    cpp
    author:        Hojjat Bohlooli - software@tarhafarinin.ir
    
    purpose:    
*********************************************************************/
#include "stdafx.h"
#include "SelectDialog.h"

#pragma warning( push )
#pragma warning( disable : 4311 4312 )
// CSelectDialog
CString CSelectDialog::m_strCurrendDirectory;
vector<CString> CSelectDialog::m_SelectedItemList;
WNDPROC CSelectDialog::m_wndProc = NULL;


CSelectDialog::CSelectDialog(BOOL bOpenFileDialog,
                             LPCTSTR lpszDefExt,
                             LPCTSTR lpszFileName,
                             DWORD dwFlags,
                             LPCTSTR lpszFilter,
                             HWND hWndParent)
                             :CFileDialogImpl<CSelectDialog>(
                             bOpenFileDialog,
                             lpszDefExt,
                             lpszFileName,
                             dwFlags | OFN_EXPLORER | OFN_HIDEREADONLY & (~OFN_SHOWHELP),
                             lpszFilter,
                             hWndParent)
{
    dwFlags |= (OFN_ENABLEINCLUDENOTIFY | OFN_EXPLORER | OFN_HIDEREADONLY & (~OFN_SHOWHELP));
};

CSelectDialog::~CSelectDialog()
{
};
// CSelectDialog message handlers
BOOL CSelectDialog::OnFileOK(LPOFNOTIFY /*lpon*/)
{
    CWindow pWind = GetParent();
    if (pWind)
    {
        CWindow pWnd = pWind.GetDlgItem(lst2);    //getting list
        if (pWnd == NULL)
            return FALSE;

        m_SelectedItemList.clear();            // emptying list
        
        CListViewCtrl wndLst1 = (CListViewCtrl)(pWnd.GetDlgItem(1));

        int nSelected = wndLst1.GetSelectedCount();
        if (!nSelected)        // nothing selected -- don't retrieve list
            return FALSE;
        CString strItemText, strDirectory = m_strCurrendDirectory;
        if (strDirectory.Right(1) != _T("\"))
            strDirectory += _T("\");

        CString fileslist = _T("");
        pWind.SendMessage(CDM_GETSPEC, (WPARAM)MAX_PATH,
            (LPARAM)fileslist.GetBuffer(MAX_PATH));
        fileslist.ReleaseBuffer();

        strItemText = strDirectory + fileslist;
        if(nSelected == 1 && fileslist != _T(""))
        {
            m_SelectedItemList.push_back(strItemText);
            return TRUE;
        }
    }
    ::MessageBeep( MB_ICONQUESTION );
    return 1; //don't let the dialog to close
};

LRESULT CSelectDialog::OnSelChange(LPOFNOTIFY pnmh)
{
    ATLASSERT(::IsWindow(m_hWnd));
    CString strFolderPath = _T("");
    SendMessage(pnmh->hdr.hwndFrom, CDM_GETFILEPATH, (WPARAM)MAX_PATH, (LPARAM)strFolderPath.GetBuffer(MAX_PATH));
    strFolderPath.ReleaseBuffer();
    DWORD newSelAttr = GetFileAttributes(strFolderPath);
    

    CString strLog1;
    strLog1 = "======>1";
    strLog1 += strFolderPath;
    OutputDebugString(strLog1);
    if ((newSelAttr != 0xFFFFFFFF) && (newSelAttr & FILE_ATTRIBUTE_DIRECTORY))
    {
        strFolderPath = strFolderPath.Left(strFolderPath.ReverseFind('\'));
    }
    else
    {
        PathRemoveFileSpec(strFolderPath.GetBuffer(MAX_PATH));
        strFolderPath.ReleaseBuffer();
    }
    if (m_strCurrendDirectory == "")
    {
        m_strCurrendDirectory = strFolderPath;
    }

    return 0;
}

void CSelectDialog::OnFolderChange(LPOFNOTIFY /*lpon*/)
{
    WCHAR szPath[MAX_PATH]={0};
    //m_strCurrendDirectory = GetFolderPath();
     GetFolderPath(szPath,MAX_PATH);
     m_strCurrendDirectory.Format(_T("%s"),szPath);
    //CFileDialog::OnFolderChange();
};

void CSelectDialog::OnInitDone(LPOFNOTIFY /*lpon*/)
{
    WCHAR szPath[MAX_PATH]={0};
    //m_strCurrendDirectory = GetFolderPath();
    //GetFolderPath(szPath,MAX_PATH);
    //m_strCurrendDirectory.Format(_T("%s"),szPath);
    CWindow pWind = GetParent();

    ////HWND hWnd = pWind.m_hWnd;

    //HideControl(edt1);
    //HideControl(cmb1);
    //HideControl(stc2);

    ////HideControl(cmb13);
    ////HideControl(stc3);

    //CRect rectCancel;
    //pWind.GetDlgItem(IDCANCEL).GetWindowRect(&rectCancel);
    //pWind.ScreenToClient(&rectCancel);

    //CRect rectOK;
    //pWind.GetDlgItem(IDOK).GetWindowRect(&rectOK);
    //pWind.ScreenToClient(&rectOK);
    //pWind.GetDlgItem(IDOK).SetWindowPos(0,rectCancel.left - rectOK.Width(), rectCancel.top, 0,0, SWP_NOZORDER | SWP_NOSIZE);

    //CRect rectList2;
    //pWind.GetDlgItem(lst1).GetWindowRect(&rectList2);
    //pWind.ScreenToClient(&rectList2);
    //pWind.GetDlgItem(lst1).SetWindowPos(0,0,0,rectList2.Width(), abs(rectList2.top - (rectCancel.top - 5)), SWP_NOMOVE | SWP_NOZORDER);

    //CRect rectStatic;
    //pWind.GetDlgItem(stc3).GetWindowRect(&rectStatic);
    //pWind.ScreenToClient(&rectStatic);
    //pWind.GetDlgItem(stc3).SetWindowPos(0,rectCancel.left - 375,rectCancel.top + 5, rectStatic.Width(), rectStatic.Height(), SWP_NOZORDER);

    //CRect rectEdit1;
    //pWind.GetDlgItem(cmb13).GetWindowRect(&rectEdit1);
    //pWind.ScreenToClient(&rectEdit1);
    //pWind.GetDlgItem(cmb13).SetWindowPos(0,rectCancel.left - 320,rectCancel.top, rectEdit1.Width() - 15, rectEdit1.Height(), SWP_NOZORDER);

    //SetControlText(stc3, _T("Item name:"));
    SetControlText(IDOK, _T("存入云盘"));

    m_wndProc = (WNDPROC)::SetWindowLong(pWind.m_hWnd, GWL_WNDPROC, (long)WindowProcNew);
    pWind.CenterWindow();
    SetForegroundWindow(pWind.m_hWnd);
};

LRESULT CALLBACK CSelectDialog::WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (message ==  WM_COMMAND&& HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
    {

        if (m_strCurrendDirectory == "")
        {
            goto Exit;
        }

        m_SelectedItemList.clear();        

        HWND pWnd = ::GetDlgItem(hwnd,lst2);
        if (pWnd == NULL)
        {
            return FALSE;
        }
        CListViewCtrl wndLst1 = (CListViewCtrl)(::GetDlgItem(pWnd,1));

        int nSelected = wndLst1.GetSelectedCount();
        if (!nSelected)        // nothing selected -- don't retrieve list
            return FALSE;


        HWND pcmbWnd = ::GetDlgItem(hwnd, cmb13);
        if (pcmbWnd)
            ::SetWindowTextW(pcmbWnd, _T(""));

        int nItem = wndLst1.GetNextItem(-1,LVNI_SELECTED);
        
        set<int> setSelected;
        
        while((nSelected--) > 0)
        {
            setSelected.insert(nItem);
            BOOL bRet = wndLst1.SetItemState(nItem, ~LVIS_SELECTED , LVIS_SELECTED);

            nItem = wndLst1.GetNextItem(nItem, LVNI_SELECTED);
        }

        
        for (std::set<int>::iterator ite = setSelected.begin(); ite != setSelected.end(); ++ite)
        {
            wndLst1.SetItemState(*ite, LVIS_SELECTED, LVIS_SELECTED);

            CString strFolderPath = _T("");
            SendMessage(hwnd, CDM_GETFILEPATH, (WPARAM)MAX_PATH, (LPARAM)strFolderPath.GetBuffer(MAX_PATH));
            strFolderPath.ReleaseBuffer();
            DWORD newSelAttr = GetFileAttributes(strFolderPath);


            CString strLog1;
            strLog1 = "======>3";
            strLog1 += strFolderPath;
            OutputDebugString(strLog1);

            wndLst1.SetItemState(*ite, ~LVIS_SELECTED, LVIS_SELECTED);

        }

        ::EndDialog(hwnd,IDOK);        
        return NULL;
    }

Exit:
    return CallWindowProc(m_wndProc, hwnd, message, wParam, lParam);
}


#pragma warning( pop )
原文地址:https://www.cnblogs.com/findumars/p/5788503.html