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
|