分享
 
 
 

CPathDialog 类学习方法

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

程序来源:http://www.codeguru.com/Cpp/W-D/dislog/dialogforselectingfolders/article.php/c2019/

一个非常好用的选择目录的类

/////////////////////////////////////////////////////////////////

头文件:

//////////////////////////////////////////////////////////////////////////

//PathDialog.h file

//

//Written by Nguyen Tan Hung <tanhung@yahoo.com>

//////////////////////////////////////////////////////////////////////////

#if !defined(AFX_PATHDIALOG_H__0F70BC86_11DB_11D4_B012_0000E8DD8DAA__INCLUDED_)

#define AFX_PATHDIALOG_H__0F70BC86_11DB_11D4_B012_0000E8DD8DAA__INCLUDED_

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

// PathDialog.h : header file

//

#include "shlobj.h"

class CPathDialog;

// CPathDialogSub - intercepts messages from child controls

class CPathDialogSub : public CWnd

{

friend CPathDialog;

public:

CPathDialog* m_pPathDialog;

protected:

afx_msg void OnOK(); // OK button clicked

afx_msg void OnChangeEditPath();

DECLARE_MESSAGE_MAP()

private:

};

/////////////////////////////////////////////////////////////////////////////

// CPathDialog dialog

class CPathDialog

{

friend CPathDialogSub;

// Construction

public:

CPathDialog(LPCTSTR lpszCaption=NULL,

LPCTSTR lpszTitle=NULL,

LPCTSTR lpszInitialPath=NULL,

CWnd* pParent = NULL);

CString GetPathName();

virtual int DoModal();

static Touch(LPCTSTR lpPath, BOOL bValidate=TRUE);

static int MakeSurePathExists(LPCTSTR lpPath);

static BOOL IsFileNameValid(LPCTSTR lpFileName);

static int ConcatPath(LPTSTR lpRoot, LPCTSTR lpMorePath);

private:

static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam, LPARAM pData);

LPCTSTR m_lpszCaption;

LPCTSTR m_lpszInitialPath;

TCHAR m_szPathName[MAX_PATH];

BROWSEINFO m_bi;

HWND m_hWnd;

CWnd* m_pParentWnd;

BOOL m_bParentDisabled;

BOOL m_bGetSuccess;

CPathDialogSub m_PathDialogSub;

};

//{{AFX_INSERT_LOCATION}}

// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_PATHDIALOG_H__0F70BC86_11DB_11D4_B012_0000E8DD8DAA__INCLUDED_)

/////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////

cpp文件:

//////////////////////////////////////////////////////////////////////////

//PathDialog.h file

//

//Written by Nguyen Tan Hung <tanhung@yahoo.com>

//////////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "PathDialog.h"

#include <io.h>

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

#define IDC_FOLDERTREE 0x3741

#define IDC_TITLE 0x3742

#define IDC_STATUSTEXT 0x3743

#define IDC_NEW_EDIT_PATH 0x3744

// Class CDlgWnd

BEGIN_MESSAGE_MAP(CPathDialogSub, CWnd)

ON_BN_CLICKED(IDOK, OnOK)

ON_EN_CHANGE(IDC_NEW_EDIT_PATH, OnChangeEditPath)

END_MESSAGE_MAP()

void CPathDialogSub::OnOK()

{

::GetWindowText(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH),

m_pPathDialog->m_szPathName, MAX_PATH);

if(CPathDialog::MakeSurePathExists(m_pPathDialog->m_szPathName)==0)

{

m_pPathDialog->m_bGetSuccess=TRUE;

::EndDialog(m_pPathDialog->m_hWnd, IDOK);

}

else

{

::SetFocus(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH));

}

}

void CPathDialogSub::OnChangeEditPath()

{

::GetWindowText(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH),

m_pPathDialog->m_szPathName, MAX_PATH);

BOOL bEnableOKButton = (_tcslen(m_pPathDialog->m_szPathName)>0);

SendMessage(BFFM_ENABLEOK, 0, bEnableOKButton);

}

/////////////////////////////////////////////////////////////////////////////

// CPathDialog dialog

CPathDialog::CPathDialog(LPCTSTR lpszCaption,

LPCTSTR lpszTitle,

LPCTSTR lpszInitialPath,

CWnd* pParent)

{

m_hWnd=NULL;

m_PathDialogSub.m_pPathDialog= this;

m_bParentDisabled = FALSE;

// Get the true parent of the dialog

m_pParentWnd = CWnd::GetSafeOwner(pParent);

m_lpszCaption = lpszCaption;

m_lpszInitialPath = lpszInitialPath;

memset(&m_bi, 0, sizeof(BROWSEINFO) );

m_bi.hwndOwner = (m_pParentWnd==NULL)?NULL:m_pParentWnd->GetSafeHwnd();

m_bi.pszDisplayName = 0;

m_bi.pidlRoot = 0;

m_bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;

m_bi.lpfn = BrowseCallbackProc;

m_bi.lpszTitle = lpszTitle;

}

/////////////////////////////////////////////////////////////////////////////

// CPathDialog message handlers

CString CPathDialog::GetPathName()

{

return CString(m_szPathName);

}

int CALLBACK CPathDialog::BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam, LPARAM pData)

{

CPathDialog* pDlg = (CPathDialog*)pData;

switch(uMsg)

{

case BFFM_INITIALIZED:

{

RECT rc;

HWND hEdit;

HFONT hFont;

pDlg->m_hWnd = hwnd;

if(pDlg->m_lpszCaption!=NULL)

{

::SetWindowText(hwnd, pDlg->m_lpszCaption);

}

VERIFY(pDlg->m_PathDialogSub.SubclassWindow(hwnd));

::ShowWindow(::GetDlgItem(hwnd, IDC_STATUSTEXT), SW_HIDE);

::GetWindowRect(::GetDlgItem(hwnd, IDC_FOLDERTREE), &rc);

rc.bottom = rc.top - 4;

rc.top = rc.bottom - 23;

::ScreenToClient(hwnd, (LPPOINT)&rc);

::ScreenToClient(hwnd, ((LPPOINT)&rc)+1);

hEdit = ::CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""),

WS_CHILD|WS_TABSTOP|WS_VISIBLE|ES_AUTOHSCROLL,

rc.left, rc.top,

rc.right-rc.left, rc.bottom-rc.top,

hwnd, NULL, NULL, NULL);

::SetWindowLong(hEdit, GWL_ID, IDC_NEW_EDIT_PATH);

::ShowWindow(hEdit, SW_SHOW);

hFont = (HFONT)::SendMessage(hwnd, WM_GETFONT, 0, 0);

::SendMessage(hEdit, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0));

LPCTSTR lpszPath = pDlg->m_lpszInitialPath;

TCHAR szTemp[MAX_PATH];

if(lpszPath==NULL)

{

::GetCurrentDirectory(MAX_PATH, szTemp );

lpszPath = szTemp;

}

// WParam is TRUE since you are passing a path.

// It would be FALSE if you were passing a pidl.

::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,

(LPARAM)lpszPath);

break;

}

case BFFM_SELCHANGED:

{

char szSelection[MAX_PATH];

if(!::SHGetPathFromIDList((LPITEMIDLIST)lParam, szSelection) ||

szSelection[1]!=':')

{

szSelection[0] = '\0';

::SendMessage(hwnd, BFFM_ENABLEOK, 0, FALSE);

}

else

{

::SendMessage(hwnd, BFFM_ENABLEOK, 0, TRUE);

}

::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szSelection);

::SetWindowText(::GetDlgItem(hwnd, IDC_NEW_EDIT_PATH), szSelection);

break;

}

default:

break;

}

return 0;

}

int CPathDialog::DoModal()

{

/////////////////////////////////////////////////////////

TCHAR szPathTemp[MAX_PATH];

m_bi.lpfn = BrowseCallbackProc; // address of callback function

m_bi.lParam = (LPARAM)this; // pass address of object to callback function

m_bi.pszDisplayName = szPathTemp;

LPITEMIDLIST pidl;

LPMALLOC pMalloc;

int iResult=-1;

if(SUCCEEDED(SHGetMalloc(&pMalloc)))

{

// if((m_pParentWnd!=NULL) && m_pParentWnd->IsWindowEnabled())

// {

// m_pParentWnd->EnableWindow(FALSE);

// m_bParentDisabled = TRUE;

// }

m_bGetSuccess = FALSE;

pidl = SHBrowseForFolder(&m_bi);

if (pidl!=NULL)

{

//not need do this because OnOK function did

//bSucceeded = SHGetPathFromIDList(pidl, m_szPathName);

// In C++:

pMalloc->Free(pidl);

//In C:

//pMalloc->lpVtbl->Free(pMalloc,pidl);

//pMalloc->lpVtbl->Release(pMalloc);

}

if(m_bGetSuccess)

{

iResult = IDOK;

}

pMalloc->Release();

}

if(m_bParentDisabled && (m_pParentWnd!=NULL))

{

m_pParentWnd->EnableWindow(TRUE);

}

m_bParentDisabled=FALSE;

return iResult;

}

BOOL CPathDialog::IsFileNameValid(LPCTSTR lpFileName)

{

if(lpFileName==NULL)

{

return FALSE;

}

int nLen = _tcslen(lpFileName);

if(nLen<=0)

{

return FALSE;

}

//check first char

switch(lpFileName[0])

{

case _T('.'):

case _T(' '):

case _T('\t'):

return FALSE;

}

//check last char

switch(lpFileName[nLen-1])

{

case _T('.'):

case _T(' '):

case _T('\t'):

return FALSE;

}

//check all

int i=0;

while(lpFileName[i]!=0)

{

switch(lpFileName[i])

{

case _T('\\'):

case _T('/'):

case _T(':'):

case _T('*'):

case _T('?'):

case _T('\"'):

case _T('<'):

case _T('>'):

case _T('|'):

return FALSE;

}

i++;

}

return TRUE;

}

const TCHAR c_FolderDoesNotExist[] = _T(

"The folder:\n\n"

"%s\n\n"

"does not exist. Do you want the folder to be created?");

const TCHAR c_szErrInvalidPath[] = _T(

"The folder:"

"\n\n"

"%s\n\n"

"is invalid. Please reenter.");

const TCHAR c_szErrCreatePath[] = _T(

"The folder:"

"\n\n"

"%s"

"\n\ncan not be created. Please double check.");

//return -1: user break;

//return 0: no error

//return 1: lpPath is invalid

//return 2: can not create lpPath

int CPathDialog::MakeSurePathExists(LPCTSTR lpPath)

{

CString strMsg;

int iRet;

try

{

//validate path

iRet=Touch(lpPath, TRUE);

if(iRet!=0)

{

throw iRet;

}

if(_taccess(lpPath, 0)==0)

{

return (int)0;

}

strMsg.Format(c_FolderDoesNotExist, lpPath);

if(AfxMessageBox(strMsg, MB_YESNO|MB_ICONQUESTION) != IDYES)

{

return (int)-1;

}

//create path

iRet=Touch(lpPath, FALSE);

if(iRet!=0)

{

throw iRet;

}

return 0;

}

catch(int nErrCode)

{

switch(nErrCode)

{

case 1:

strMsg.Format(c_szErrInvalidPath, lpPath);

break;

case 2:

default:

strMsg.Format(c_szErrCreatePath, lpPath);

break;

}

AfxMessageBox(strMsg, MB_OK|MB_ICONEXCLAMATION);

}

return iRet;

}

//return 0: no error

//return 1: lpPath is invalid

//return 2: lpPath can not be created(bValidate==FALSE)

int CPathDialog::Touch(LPCTSTR lpPath, BOOL bValidate)

{

if(lpPath==NULL)

{

return 1;

}

TCHAR szPath[MAX_PATH];

_tcscpy(szPath, lpPath);

int nLen = _tcslen(szPath);

//path must be "x:\..."

if( ( nLen<3 ) ||

( ( szPath[0]<_T('A') || _T('Z')<szPath[0] ) &&

( szPath[0]<_T('a') || _T('z')<szPath[0] ) ||

( szPath[1]!=_T(':') )||

( szPath[2]!=_T('\\') )

)

)

{

return 1;

}

int i;

if(nLen==3)

{

if(!bValidate)

{

if(_access(szPath, 0)!=0)

{

return 2;

}

}

return 0;

}

i = 3;

BOOL bLastOne=TRUE;

LPTSTR lpCurrentName;

while(szPath[i]!=0)

{

lpCurrentName = &szPath[i];

while( (szPath[i]!=0) && (szPath[i]!=_T('\\')) )

{

i++;

}

bLastOne =(szPath[i]==0);

szPath[i] = 0;

if( !IsFileNameValid(lpCurrentName) )

{

return 1;

}

if(!bValidate)

{

CreateDirectory(szPath, NULL);

if(_taccess(szPath, 0)!=0)

{

return 2;

}

}

if(bLastOne)

{

break; //it's done

}

else

{

szPath[i] = _T('\\');

}

i++;

}

return (bLastOne?0:1);

}

//return 0: ok

//return 1: error

int CPathDialog::ConcatPath(LPTSTR lpRoot, LPCTSTR lpMorePath)

{

if(lpRoot==NULL)

{

return 1;

}

int nLen = _tcslen(lpRoot);

if(nLen<3)

{

return 1;

}

if(lpMorePath==NULL)

{

return 0;

}

if(nLen==3)

{

_tcscat(lpRoot, lpMorePath);

return 0;

}

_tcscat(lpRoot, _T("\\"));

_tcscat(lpRoot, lpMorePath);

return 0;

}

///////////////////////////////////////////////////////////////////////

在工程中加入 Pathdialog.h 和 Pathdialog.cpp 后,调用代码如下:

#include "PathDialog.h"

void CTestPathDialogDlg::OnBrowserButton()

{

CString strInitialPath;

CString strYourCaption(_T("Your caption here..."));

CString strYourTitle(_T("Your tilte here..."));

m_ctrlPathName.GetWindowText(strInitialPath);

CPathDialog dlg(strYourCaption, strYourTitle, strInitialPath);

if (dlg.DoModal()==IDOK)

{

m_ctrlPathName.SetWindowText(dlg.GetPathName());

}

}

void CTestPathDialogDlg::OnOKButton()

{

CString strPath;

m_ctrlPathName.GetWindowText(strPath);

if(CPathDialog::MakeSurePathExists(strPath)==0)

{

CDialog::OnOK();

}

}

补充说明:本例中选择路径对话框不带有“新建文件夹”功能,需要的话可以参照:http://www.vccode.com/file_show.php?id=2661上的范例.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有