Re: Folderselector dialog problems.
I'm guessing the memory failure is unrelated, but there are a couple of
things I'd check on the code here:
1. You are freeing pidlBrowse, but never retrieving the path from it (at
least in the code you show here). Are you attempting to access it after it
is free'd?
2. I don't see where you are releasing pMalloc. I would expect to see
something like:
TCHAR buffer[MAX_PATH]; // Retrieve the task memory allocator.
// If the user selected a folder...
if (pidlBrowse) {
// Convert the item ID to a pathname, and copy it to the
// out parameter.
if (::SHGetPathFromIDList(pidlBrowse, buffer)) {
CString dir = buffer;
}
// Free the PIDL allocated by SHBrowseForFolder
pMalloc->Free(item_list);
}
// Release the shell's allocator
pMalloc->Release();
3. Are you sure that the result of GetDlgItem() is actually the window you
intended to populate. You don't check the return at all.
4. I don't see any registry calls here. I don't know what is happening in
the shell function (could be something last value being stored there or
something), but I've never had a problem with it and I do this sort of thing
all the time. Here's the class, and similar callback that I use... I don't
have the special window write (I just write to the hWnd that is passed back:
//
// SetSelProc
// Callback procedure to set the initial selection of the browser.
int CALLBACK SetSelProc( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM
lpData )
{
switch(uMsg) {
case BFFM_INITIALIZED:
{
// Set start directory
::SendMessage( hWnd, BFFM_SETSELECTION, TRUE, lpData );
// Remove the ? from the caption
DWORD dwStyle = ::GetWindowLong(hWnd, GWL_EXSTYLE);
::SetWindowLong(hWnd, GWL_EXSTYLE, dwStyle & ~WS_EX_CONTEXTHELP);
}
break;
case BFFM_SELCHANGED:
{
// Set the window text to the path
TCHAR szText[MAX_PATH] = {0};
::SHGetPathFromIDList(reinterpret_cast<LPITEMIDLIST>(lParam), szText);
::SetWindowText(hWnd,szText);
}
break;
case BFFM_VALIDATEFAILED:
// Msg("\"%s\" is a wrong path name.",
reinterpret_cast<LPTSTR>(lParam));
return 1;
}
return 0;
}
//
// FolderBrowswer
// Display a folder browser allowing the user to browse for a directory.
//
BOOL FolderBrowser(CWnd *pWnd, CString& title, CString& dir, CString
&initial, BOOL bAll, BOOL bCreate)
{
BOOL r = FALSE;
LPMALLOC pMalloc;
TCHAR buffer[MAX_PATH]; // Retrieve the task memory allocator.
if (SUCCEEDED(::SHGetMalloc(&pMalloc))) {
// Fill in a BROWSEINFO structure, setting the flag toindicate
// that we are only interested in file systemdirectories.
BROWSEINFO bi;
ZeroMemory(&bi,sizeof(BROWSEINFO));
bi.hwndOwner = pWnd->GetSafeHwnd();
bi.pidlRoot = NULL;
bi.pszDisplayName = NULL;
bi.lpszTitle = (LPCTSTR) title;
if(!bAll) {
bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS |
BIF_DONTGOBELOWDOMAIN;
}
else {
bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
}
if(bCreate)
bi.ulFlags |= BIF_NEWDIALOGSTYLE | BIF_EDITBOX;
bi.iImage = 0;
bi.lpfn = SetSelProc;
bi.lParam = (LPARAM)(LPCTSTR)initial;
// Display the browser.
LPITEMIDLIST item_list = ::SHBrowseForFolder(&bi);
// If the user selected a folder...
if (item_list) {
// Convert the item ID to a pathname, and copy it to the
// out parameter.
if (::SHGetPathFromIDList(item_list, buffer)) {
dir = buffer;
dir = AddSlash(dir); // Just adds a backslash to the end of the
folder
r = TRUE;
}
// Free the PIDL allocated by SHBrowseForFolder
pMalloc->Free(item_list);
} // Release the shell's allocator
pMalloc->Release();
}
return r;
}
Tom
"Faisal" <faisalm83@gmail.com> wrote in message
news:d220764f-c37e-4aac-a750-1aa1daae44e2@u6g2000prc.googlegroups.com...
Hi,
I've some strange problem with folder selector dialog.
My folder selector dialog class CBrowseForFolder wraps the shell
function SHBrowseForFolder.
Some times when I closes the folder selector dialog application
crashes. I tried with rational purify, and it shows array out of
boundary problems in RegOpenKey(). I couldn't find the registry
operations in my code. If any one had this problem before please
update.
code for showing dialog is something like this
BROWSEINFO bi
//bi is initialized with all neede values
....................................................
LPITEMIDLIST pidlBrowse = SHBrowseForFolder ( & bi );
LPMALLOC pMalloc;
// Get the path name
SHGetPathFromIDList ( pidlBrowse, pDir );
// Free the memory
if ( SHGetMalloc ( & pMalloc ) == NOERROR )
pMalloc->Free ( pidlBrowse );
My callback function is like this
int CALLBACK CBrowseForFolder::BrowseCallbackProc( HWND hwnd, UINT
uMsg,
LPARAM lParam, LPARAM lpData )
{
TCHAR szDir[ MAX_PATH ];
//pThisClass contains the object of my folder selector class
CBrowseForFolder* pThisClass = (CBrowseForFolder*)
(((LPSParam)lpData)->thisClass);
switch( uMsg )
{
case BFFM_INITIALIZED:
{
pThisClass->m_hWnd = hwnd;
//lpszInit contains the folder name
if ( ((LPSParam)lpData)->lpszInit )
SendMessage ( hwnd, BFFM_SETSELECTION, TRUE,
(LPARAM)(((LPSParam)lpData)->lpszInit) );
}
break;
case BFFM_SELCHANGED:
{
if ( SHGetPathFromIDList ( ( LPITEMIDLIST ) lParam, szDir ) )
{
CString csFolderName = _T("Selected
Folder is: \n");
csFolderName += szDir;
HWND hStaticField
= ::GetDlgItem( pThisClass->m_hWnd, 0x3742 );
::SetWindowText( hStaticField,
csFolderName );
}
}
break;
default:
break;
}
return 0;
}