2008年1月3日星期四

SHBrowseForFolder设置初始目录中CALLBACK函数的使用

目的:
通过BROWSEINFO,SHBrowseForFolder打开Directory对话框,并且通过int CALLBACK BrowseCallbackProc()设置初始目录.

(源代码)打开目录选择对话框:
void CUnpackView::OnButtonPath(CDataExchange* pDX)
{
// TODO: Add your control notification handler code here
char dispname[MAX_PATH];
char copytopath[MAX_PATH];


BROWSEINFO bi;
ITEMIDLIST *pidl;

bi.hwndOwner = 0;
bi.pidlRoot = 0; //set the default browser path
bi.pszDisplayName = dispname;
bi.lpszTitle = "Verzeichniss auswählen";
bi.ulFlags = BIF_STATUSTEXT;//BIF_RETURNONLYFSDIRS;
bi.lpfn = BrowseCallbackProc; //调用回调函数
bi.lParam = 0;
bi.iImage = 0;



if ((pidl = SHBrowseForFolder(&bi))!=NULL) //
{
memset(copytopath, 0, MAX_PATH);
SHGetPathFromIDList(pidl, copytopath);//copytopath
//
sourceDir = (CString) copytopath;


}
//OnInitialUpdate();
UpdateData(false);
Invalidate();

if ( plc.checkFolder((LPCTSTR)sourceDir) )
{
openedSourceDir = (LPCTSTR)sourceDir;

//--get the LastWriteTime of folder/files
WIN32_FIND_DATA ffd ;
HANDLE hFind = FindFirstFile(openedSourceDir,&ffd);
SYSTEMTIME stUTC, stLocal;
FileTimeToSystemTime(&(ffd.ftLastWriteTime), &stUTC);
SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);
myTime.Format("%d. %d %d, %d:%d", stLocal.wDay,stLocal.wMonth,stLocal.wYear,stLocal.wHour,stLocal.wMinute);
//--
d_ColorStatic.SetWindowText((LPCTSTR)myTime);


GetDlgItem(IDC_BUTTON_ROLLBACK)->EnableWindow(true);
GetDlgItem(IDC_BUTTON_REPORT)->EnableWindow(true);
GetDlgItem(IDC_STATIC_STATUSTITLE)->EnableWindow(false);

}
else
{
GetDlgItem(IDC_BUTTON_ROLLBACK)->EnableWindow(false);
GetDlgItem(IDC_BUTTON_REPORT)->EnableWindow(false);
GetDlgItem(IDC_STATIC_STATUSTITLE)->EnableWindow(false);
AfxMessageBox("Die angegebene Verzeichniss ist nicht richtig, bitte versuchen Sie nochmal.");

}

}


(源代码)CALLBACK函数:
在.h中:

CString sicherungDir;
static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);



在.cpp中:
int CALLBACK CUnpackView::BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
//CALLBACKSTRUCT * cs = (CALLBACKSTRUCT*) lpData;

CString dir(_T(""));
BOOL hasInitial = false;
// * Statische Member-Funktionen haben keinen this-Zeiger: *
// * this does not work, because the pUnpack is a new obj,
// * pUnpack->openedSourceDir is the new one

//---- use the View pointobject
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
CUnpackView *pView = (CUnpackView *) pChild->GetActiveView();
//--

if ( pView->openedSourceDir != "")
dir = pView->openedSourceDir; // the default stays at the opened folder failed!because pView is a new pObject

else
dir = CPublic::sSicherungDir; //if first time to open the folder dialog


/////////////////////////////////////////////////
//'d:\\' can not be recognised by SHGetPathFromIDList()
// must be changed into 'd:\'
/////////////////////////////////////////////////
dir.Replace("\\\\","\\");

switch(uMsg)
{
case BFFM_INITIALIZED: //initial
hasInitial =true;
::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)dir ); //"d:\\datenversicherung"
//AfxMessageBox("BFFM_INITIALIZED");

break;

case BFFM_SELCHANGED: //path changed
{
/////////////////////////////////////////////
// to avoid SHGetPathFromIDList()twice running
// before "case BFFM_INITIALIZED" has been done
////////////////////////////////////////////
if (hasInitial)
{
char curr[MAX_PATH];

SHGetPathFromIDList((LPCITEMIDLIST)lParam,curr);

CString s;
s.Format("BFFM_SELCHANGED, curr: %s",curr);
AfxMessageBox(s);

if(curr[strlen(curr)-1]==92)
sprintf(curr,"%s",curr);
else
sprintf(curr,"%s\\",curr);

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

}

}
break;

}
return 0;

}


注意:
在对CALLBACK函数的使用中,必须是类的静态成员函数。
否则,用MS编译器,会得到这个编译错误:
error C2664: 'Bubblesort' : cannot convert parameter 4 from 'int (__stdcall CCallbackTester::*)(const unsigned char *,const unsigned char *)' to 'int (__stdcall *)(const unsigned char *,const unsigned char *)' There is no context in which this conversion is possible


参考:
Visual C++中回调函数使用的变身大法
回调函数指南(Callback Functions Tutorial)
How to Implement Callbacks in C and C++

没有评论: