Thread View: borland.public.cppbuilder.nativeapi
13 messages
13 total messages
Started by Mark Jacobs
Mon, 05 Mar 2007 12:46
Shbrowseforfolder edit box problems
Author: Mark Jacobs
Date: Mon, 05 Mar 2007 12:46
Date: Mon, 05 Mar 2007 12:46
39 lines
2519 bytes
2519 bytes
I am using BCB5 Pro SP1, and I have the following code :-
int CALLBACK mjBrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM
lpData)
{
if (uMsg==BFFM_INITIALIZED) SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);
return 0;
}
//---------------------------------------------------------------------------
void __fastcall Tmjgrabstr::xbtnClick(TObject *Sender)
{
AnsiString Dir=Edit1->Text;
BROWSEINFO mjbi;
char rcvdir[999];
if (!DirectoryExists(Dir)) Dir=GetCurrentDir();
strcpy(rcvdir,Dir.c_str());
mjbi.hwndOwner=Application->Handle;
mjbi.pidlRoot=0;
mjbi.pszDisplayName=rcvdir;
mjbi.lpszTitle="Choose a Directory :-";
mjbi.ulFlags=BIF_USENEWUI;
mjbi.lpfn=mjBrowseCallbackProc;
mjbi.lParam=(long)rcvdir;
ITEMIDLIST *mjites=SHBrowseForFolder(&mjbi);
rcvdir[0]='\0'; if (mjites) SHGetPathFromIDList(mjites,rcvdir);
CoTaskMemFree(mjites);
if (rcvdir[0]) Edit1->Text=AnsiString(rcvdir);
}
This is to present a directory selector with an edit box to manually enter a
directory name. The directory chosen or entered, does not have to exist. When
the dialog appears, it changes itself to the current directory. When I enter
text into the edit box on this dialog, and hit OK, the dialog returns the
directory in the window above the text box, but not that entered into the text
box itself. How do I get to the text in the edit box in this dialog?
--
Mark Jacobs
DK Computing
http://www.dkcomputing.co.uk
Re: Shbrowseforfolder edit box problems
Author: Bob Gonder
Date: Mon, 05 Mar 2007 15:58
Date: Mon, 05 Mar 2007 15:58
51 lines
2421 bytes
2421 bytes
"Mark Jacobs" <http://www.jacobsm.com/mjmsg.htm?BorlandNG> wrote:
>This is to present a directory selector with an edit box to manually enter a
>directory name. The directory chosen or entered, does not have to exist. When
>the dialog appears, it changes itself to the current directory. When I enter
>text into the edit box on this dialog, and hit OK, the dialog returns the
>directory in the window above the text box, but not that entered into the text
>box itself. How do I get to the text in the edit box in this dialog?
It looks like you are almost there.
>int CALLBACK mjBrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM
>lpData)
>{
> if (uMsg==BFFM_INITIALIZED) SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);
if( uMsg == BFFM_INITIALIZED )
{
if( lpData )
{
if( *lpData)
SendMessage(hwnd,BFFM_SETSELECTION,TRUE,lpData);
* lpData = 0;
};
return 0;
};
if (uMsg==BFFM_VALIDATEFAILED )
{
lstrcpy( lpData, lParam );
return 0; /*end dialog*/
};
- - - - -
mjbi.ulFlags=BIF_USENEWUI |
BIF_VALIDATE;
> mjbi.lpfn=mjBrowseCallbackProc;
> mjbi.lParam=(long)rcvdir;
> ITEMIDLIST *mjites=SHBrowseForFolder(&mjbi);
if( rcvdir[0] == 0 )
{ get rcvdir from pidl
}else{
use rcvdir directly
}
> rcvdir[0]='\0'; if (mjites) SHGetPathFromIDList(mjites,rcvdir);
> CoTaskMemFree(mjites);
> if (rcvdir[0]) Edit1->Text=AnsiString(rcvdir);
>}
>
Re: Shbrowseforfolder edit box problems
Author: Remy Lebeau (TeamB)
Date: Mon, 05 Mar 2007 18:24
Date: Mon, 05 Mar 2007 18:24
24 lines
1685 bytes
1685 bytes
"Mark Jacobs" <http://www.jacobsm.com/mjmsg.htm?BorlandNG> wrote in message news:45ec10db$1@newsgroups.borland.com... > This is to present a directory selector with an edit box to manually > enter a directory name. The directory chosen or entered, does not > have to exist. Then you are using the wrong dialog, as it can only return directories that do exist. > When I enter text into the edit box on this dialog, and hit OK, the > dialog returns the directory in the window above the text box That is what the dialog is designed to do. > How do I get to the text in the edit box in this dialog? You don't. That box is not for your code to use at all. It is only for the user to use. The dialog only returns the final folder that is selected. An ITEMIDLIST cannot point to a non-existant item. Gambit
Re: Shbrowseforfolder edit box problems
Author: Mark Jacobs
Date: Mon, 05 Mar 2007 18:30
Date: Mon, 05 Mar 2007 18:30
10 lines
1386 bytes
1386 bytes
"Bob Gonder" <notbg@notmindspring.invalid> wrote in message news:99dou21t2sbmue94iobfekf2en3dfgegek@4ax.com... > It looks like you are almost there. ><code snips> None of your code helped. But thanks all the same. Anyone else know how to get the contents of the edit box in a Shbrowseforfolder dialog? -- Mark Jacobs http://jacobsm.com
Re: Shbrowseforfolder edit box problems
Author: Remy Lebeau (TeamB)
Date: Mon, 05 Mar 2007 18:40
Date: Mon, 05 Mar 2007 18:40
68 lines
2858 bytes
2858 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:45ec6a71@newsgroups.borland.com...
> You don't. That box is not for your code to use at all. It is only
> for the user to use.
I stand corrected. Bob's approach is the key. It just needs some
cleaning up. The following code works fine for me:
int CALLBACK mjBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM
lParam, LPARAM lpData)
{
switch( uMsg )
{
case BFFM_INITIALIZED:
{
LPTSTR ptr = reinterpret_cast<LPTSTR>(lpData);
if( ptr[0] != 0 )
{
SendMessage(hwnd, BFFM_SETSELECTION, TRUE,
lpData);
ptr[0] = 0;
}
break;
}
case BFFM_VALIDATEFAILED:
{
lstrcpyn(reinterpret_cast<LPTSTR>(lpData),
reinterpret_cast<LPTSTR>(lParam), MAX_PATH);
break;
}
}
return 0;
}
void __fastcall Tmjgrabstr::xbtnClick(TObject *Sender)
{
AnsiString Dir = Edit1->Text;
if( !DirectoryExists(Dir) )
Dir = GetCurrentDir();
TCHAR rcvdir[MAX_PATH+1] = {0};
lstrcpy(rcvdir, Dir.c_str(), MAX_PATH);
BROWSEINFO mjbi = {0};
mjbi.hwndOwner = Application->Handle;
mjbi.lpszTitle = TEXT("Choose a Directory :-");
mjbi.ulFlags = BIF_EDITBOX | BIF_VALIDATE;
mjbi.lpfn = mjBrowseCallbackProc;
mjbi.lParam = reinterpret_cast<LPARAM>(rcvdir);
LPITEMIDLIST mjites = SHBrowseForFolder(&mjbi);
if( mjites )
{
rcvdir[0] = 0;
SHGetPathFromIDList(mjites, rcvdir);
CoTaskMemFree(mjites);
}
if( rcvdir[0] != 0 )
Edit1->Text = rcvdir;
}
Gambit
Re: Shbrowseforfolder edit box problems
Author: Remy Lebeau (TeamB)
Date: Mon, 05 Mar 2007 18:41
Date: Mon, 05 Mar 2007 18:41
11 lines
1144 bytes
1144 bytes
"Mark Jacobs" <www.jacobsm.com/mjmsg.htm?Borland Newsgroup> wrote in message news:45ec61b9@newsgroups.borland.com... > None of your code helped. Yes, it does. His approach is exactly what you need. See my other reply. Gambit
Re: Shbrowseforfolder edit box problems
Author: Bob Gonder
Date: Mon, 05 Mar 2007 22:49
Date: Mon, 05 Mar 2007 22:49
28 lines
1768 bytes
1768 bytes
Remy Lebeau (TeamB) wrote:
> LPITEMIDLIST mjites = SHBrowseForFolder(&mjbi);
> if( mjites )
> {
> rcvdir[0] = 0;
> SHGetPathFromIDList(mjites, rcvdir);
> CoTaskMemFree(mjites);
> }
I seem to always get a pidl returned when Validate closes the dialog
(return 0;) So the above should always run unless the Cancel was
pressed. But that would overwrite the manual entry copied by the
Validate code.
That's why I checked rcvdir[0] instead of mjites after the call.
(another way)
> if( mjites )
> {
if( rcvdir[0] == 0 )
{
> SHGetPathFromIDList(mjites, rcvdir);
}else{
//nothing, rcvdir filled in by Validate
};
> CoTaskMemFree(mjites);
> }
Re: Shbrowseforfolder edit box problems
Author: Mark Jacobs
Date: Mon, 05 Mar 2007 23:26
Date: Mon, 05 Mar 2007 23:26
15 lines
1648 bytes
1648 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:45ec71a5 > mjbi.ulFlags = BIF_EDITBOX | BIF_VALIDATE; ... Thanks for your help. However, I also need the new UI as in BIF_USENEWUI This makes your code *not* return the edit box contents when stuff is typed in. Try it. Without the BIF_USENEWUI (as in your code), I agree, it returns the contents of that edit box. But I want the new UI. complete with make new folder functionality, and simply or'ing in the BIF_USENEWUI flag makes it *not* return the box contents! Perhaps it's a limitation of the Windows folder UI. -- Mark Jacobs www.jacobsm.com
Re: Shbrowseforfolder edit box problems
Author: Remy Lebeau (TeamB)
Date: Mon, 05 Mar 2007 23:47
Date: Mon, 05 Mar 2007 23:47
44 lines
2562 bytes
2562 bytes
"Bob Gonder" <notbg@notmindspring.invalid> wrote in message
news:5t6pu2922athot41785ihioe33et7h0mao@4ax.com...
> I seem to always get a pidl returned when Validate closes
> the dialog (return 0;)
The only way a non-NULL ITEMIDLIST can be returned is if there is a
valid folder selected in the dialog's TreeView when the dialog is
closed.
I tested the code before I posting it, and was able to get the edit
box's text as expected, even with a folder selected in the TreeView,
as the edit box has priority.
> So the above should always run unless the Cancel was pressed.
> But that would overwrite the manual entry copied by the Validate
code.
No, it would not. The value would remain untouched when canceling the
dialog. However, because a NULL ITEMIDLIST is returned when the
dialog is cancelled, there is no way to differentiate between a cancel
and a failed validation.
> That's why I checked rcvdir[0] instead of mjites after the call.
If the dialog returns a valid ITEMIDLIST, you have to use that as the
chosen path, so you should be checking the ITEMIDLIST first before
then falling back to the captured value.
> if( rcvdir[0] == 0 )
> {
> > SHGetPathFromIDList(mjites, rcvdir);
> }else{
> //nothing, rcvdir filled in by Validate
> };
That condition can never happen. If the dialog returns a valid
ITEMIDLIST, then the edit box text had to pass validation first, so
the contents of the captured buffer would not represent the folder the
user actually chose.
Gambit
Re: Shbrowseforfolder edit box problems
Author: Remy Lebeau (TeamB)
Date: Mon, 05 Mar 2007 23:53
Date: Mon, 05 Mar 2007 23:53
13 lines
1434 bytes
1434 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:45ecac3f$1@newsgroups.borland.com... > However, because a NULL ITEMIDLIST is returned when the > dialog is cancelled, there is no way to differentiate between a > cancel and a failed validation. Scratch that. The capture buffer will be empty if the dialog is canceled, but not if the validation fails. Gambit
Re: Shbrowseforfolder edit box problems
Author: Remy Lebeau (TeamB)
Date: Mon, 05 Mar 2007 23:59
Date: Mon, 05 Mar 2007 23:59
89 lines
3434 bytes
3434 bytes
"Mark Jacobs" <mark@jacobsm.com> wrote in message
news:45eca715@newsgroups.borland.com...
> Thanks for your help. However, I also need the new UI as in
> BIF_USENEWUI
>
> This makes your code *not* return the edit box contents when
> stuff is typed in.
The following code works for me now:
#include <shlobj.h>
int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM
lParam, LPARAM lpData)
{
switch( uMsg )
{
case BFFM_INITIALIZED:
{
LPTSTR ptr = reinterpret_cast<LPTSTR>(lpData);
if( ptr[0] != 0 )
{
SendMessage(hwnd, BFFM_SETSELECTION, TRUE,
lpData);
ptr[0] = 0;
}
break;
}
case BFFM_VALIDATEFAILED:
{
lstrcpyn(reinterpret_cast<LPTSTR>(lpData),
reinterpret_cast<LPTSTR>(lParam), MAX_PATH);
break;
}
}
return 0;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString Dir = Edit1->Text;
if( !DirectoryExists(Dir) )
Dir = GetCurrentDir();
TCHAR path[MAX_PATH+1] = {0};
lstrcpyn(path, Dir.c_str(), MAX_PATH);
BROWSEINFO bi = {0};
bi.hwndOwner = Handle;
bi.ulFlags = BIF_USENEWUI | BIF_EDITBOX | BIF_VALIDATE;
bi.lpfn = BrowseCallbackProc;
bi.lParam = reinterpret_cast<LPARAM>(path);
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
if( pidl )
{
if( path[0] != 0 )
{
// user text was entered ...
}
else
{
// no user text was entered ...
SHGetPathFromIDList(pidl, path);
}
CoTaskMemFree(pidl);
Edit1->Text = path;
}
else
{
// dialog canceled...
}
}
> Without the BIF_USENEWUI (as in your code), I agree, it returns
> the contents of that edit box. But I want the new UI. complete with
> make new folder functionality, and simply or'ing in the BIF_USENEWUI
> flag makes it *not* return the box contents!
That is because the TreeView has priority over the edit box when that
flag is enabled. Without it, the edit box has priority instead.
Gambit
Re: Shbrowseforfolder edit box problems
Author: Bob Gonder
Date: Tue, 06 Mar 2007 02:30
Date: Tue, 06 Mar 2007 02:30
31 lines
1897 bytes
1897 bytes
Remy Lebeau (TeamB) wrote:
> LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
> if( pidl )
> {
> if( path[0] != 0 )
> {
> // user text was entered ...
> }
> else
> {
> // no user text was entered ...
> SHGetPathFromIDList(pidl, path);
> }
>
> CoTaskMemFree(pidl);
> Edit1->Text = path;
> }
> else
> {
> // dialog canceled...
> }
Hey!
That's my code!
Glad I'm not terminally stupid.
Also see now that SHBrowseForFolder returns NULL when Validate returns
0 and BIF_NEWDIALOGSTYLE is turned off (I was testing with the OPs
settings)
Thanks for the elephant, MS !
Re: Shbrowseforfolder edit box problems
Author: Mark Jacobs
Date: Tue, 06 Mar 2007 10:27
Date: Tue, 06 Mar 2007 10:27
5 lines
1430 bytes
1430 bytes
Thanks guys - everything works fine now. Thanks for your perseverance. -- Mark Jacobs DK Computing http://www.dkcomputing.co.uk
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads