MEGA Search
20.3 Million


Sign Up
From: lhaymehr  
Subject: Getting the IShellBrowser from a dialog
NewsGroup: borland.public.delphi.language.delphi.win32
Date Posted: 1-Nov-2007 at 10:43:18 PST
I'm trying to get the IShellBrowser interface from a Explorer window, 
Open/Save dialog and a SHBrowseForFolder dialog. From what I could make out 
out of numerous google searches, explorer windows expose a IShellBrowser 
interface via its' hidden "SHELLDLL_DefView" classed window. The reason why 
I need this is to set the current directory of those dialogs/explorer 
windows to a path I want to specify. If I'm correct, I can do this with 
IShellBrowser.BrowseObject Method.

Im doing it like:

var
  ShellBrowser: IShellBrowser;
const
  CWM_GETISHELLBROWSER = WM_USER + 7;
begin
  ShellBrowser := nil;
  ShellBrowser := IShellBrowser(SendMessage(aDialog, CWM_GETISHELLBROWSER, 
0, 0));

This was dug out of EasyNSE source.

Is this correct? Now I will not get Access Violations as this is called from 
a DLL that is injected into the process for which the IShellBrowser is 
queried.

What I don't know how to do is supply the BrowseObject method with a valid 
ITEMIDLIST structure, or better yet, how to simply convert a path of string 
into this data. To be honest, i still haven't ranished all the EasyNSE code 
for a solution so I'm hoping someone can supply me with a quicker solution 
:).

Thanks,
Vedran.
--
np: Jean Jaques Perrey & Luke Vibert - Analog Generique / Moog Acid 



From: Chris Morgan  
Subject: Re: Getting the IShellBrowser from a dialog
NewsGroup: borland.public.delphi.language.delphi.win32
Date Posted: 1-Nov-2007 at 12:9:1 PST
> var
>  ShellBrowser: IShellBrowser;
> const
>  CWM_GETISHELLBROWSER = WM_USER + 7;
> begin
>  ShellBrowser := nil;
>  ShellBrowser := IShellBrowser(SendMessage(aDialog, CWM_GETISHELLBROWSER,
> 0, 0));

OK so far, but add this:

ShellBrowser._AddRef; // interface is not automatically AddRef'd by 
Microsoft

This avoids a crash when Delphi releases the interface at the end of the 
method.

Now you need to convert your directory path into a PIDL
using the IShellFolder::ParseDisplayName method:

something like

var
   Desktop: IShellFolder;
   pidl: PItemIDList;
   i: cardinal;

....

   OleCheck(SHGetDesktopFolder(Desktop));
   Desktop.ParseDisplayName(0,nil,StringToOLEStr(dir),i,pidl,i);

   ShellBrowser.BrowseObject(0,pidl); // change dir

   CoTaskMemFree(pidl);

end;

That should do it.

SHGetDesktopFolder and CoTaskMemFree are windows APIs, (uses ShlObj, 
ActiveX)
StringToOLEStr is a Delphi function in the System unit

Cheers,

Chris




From: lhaymehr  
Subject: Re: Getting the IShellBrowser from a dialog
NewsGroup: borland.public.delphi.language.delphi.win32
Date Posted: 1-Nov-2007 at 19:38:39 PST
Remy Lebeau (TeamB) sayz:

> Open/Save dialogs already provide a native way to do that.

But that isn't of much use to me in this case. Read on.

> With that said, here is a gotcha for you to consider - BrowseObject() in
> those dialogs does not seem to work in Vista

I've found a post in MS boards on that one. A "MSVP" replied that 
BrowseObject is used even more in Vista, but that they've actually changed 
something. However, I just tested it under Vista and it works. I did notice 
annother bug though..

Still, this approach won't work for me, as it doesn't work on 
SHBrowseForFolder dialogs and they were the reason i tried using this.

Please see this:
http://snjezanat.net.amis.hr/EvilUtilities.wmv (460 KB (471.040 bytes))

The first app that i run is the app that initially sets the system wide 
hook. The dialog sizing and the popup menus on the dialog system menus are 
provided by the hook and the path setting/app executing is done via the hook 
also.

There is another way of doing this; changing the directories of the 
Open/Save dialogs by setting the text of the filename edit boxes to a path 
and simulating the OK button click, but I wanted something more universal 
which could be reused on SHBrowseForFolder dialogs also.

And that "text-setting way" won't work for SHBrowseForFolder because those 
dialogs need to have their EditBox shown in order for it to work, and that 
isn't always the case. This IShellBrowser approach is actually only usable 
on Explorer windows and Open/Save dialogs because they expose the 
"SHELLDLL_DefView" window, and the new SHBrowseForFolder dialogs have 
something else, which is "SHBrowseForFolder ShellNameSpace Control" classed 
window. Old-style Browse dialogs don't have anything like that at all. So 
all this is a real "show-stopper".
--
foobar is offline 



From: lhaymehr  
Subject: Re: Getting the IShellBrowser from a dialog
NewsGroup: borland.public.delphi.language.delphi.win32
Date Posted: 2-Nov-2007 at 5:41:30 PST
Remy Lebeau (TeamB) sayz:

> As I stated earlier, the official and preferred way to change the working
> folder in that dialog is to use the BFFM_SETSELECTION message instead.

Again you're right. I tried that before but I passed the path in an 
incorrect way. After fiddling with it now it works as expected.

SendMessage(aDialog, BFFM_SETSELECTION, 1, 
integer(@Favorites[aIndex].FileName[1]));

So the path setting now WORKS on all the dialogs and i can move on :)!
--
np: Cepia - Mr. Projectile - You Need (Cepia Mix) / Atlantic Blood