I imagine that that's done with some Win32 stuff but I have no idea how.
Ideas?
Alex
Amazingly enough, it turns out that this is possible to do without even needing to resort to any undocumented hacks! The key is the TrayBandSiteService class, whose CLSID is defined in the headers but is otherwise totally undocumented. The CLSID does not actually appear under [HKEY_CLASSES_ROOT\CLSID] but Explorer, on startup, registers a class factory whose CreateInstance method returns the tray's band site object. Marshalling support is provided for IBandSite and IDeskBand so this works nicely. Having got the tray's IBandSite interface, the desk bands can be enumerated. The "Address" band can be identified by comparing its known CLSID with that returned by IPersist::GetClassID. The final piece of the puzzle is finding and activating the band's window. The window can be obtained via IOleWindow::GetWindow; however, because the band is in a different thread (indeed a different process), the two threads must be attached using AttachThreadInput before calling SetFocus.
Here is some sample code:
#include <Windows.h>
#include <ShlObj.h>
#include <ComDef.h>
_COM_SMARTPTR_TYPEDEF(IBandSite, __uuidof(IBandSite));
#define QI_ARGS(Type, pp) IID_##Type, reinterpret_cast<void**>(static_cast<Type**>(pp))
bool ActivateAddressBand()
{
// The address band CLSID is not in any header but can be found in the "Desktop Bands" component category.
CLSID CLSID_AddressBand = {0x01E04581, 0x4EEE, 0x11d0, 0xBF, 0xE9, 0x00, 0xAA, 0x00, 0x5B, 0x43, 0x83};
// Connect to the tray band site.
IBandSitePtr bs;
bs.CreateInstance(CLSID_TrayBandSiteService);
if (bs)
{
// Iterate through the available bands.
LONG count = bs->EnumBands(UINT(-1), 0);
for (LONG i = 0; i != count; ++i)
{
// Get the band object.
IDeskBandPtr band;
DWORD bandID = 0;
bs->EnumBands(i, &bandID);
bs->GetBandObject(bandID, QI_ARGS(IDeskBand, &band));
// Get IPersist so we can check the CLSID.
if (IPersistPtr persist = band)
{
// Is it the Address band?
CLSID clsid = CLSID_NULL;
persist->GetClassID(&clsid);
if (clsid == CLSID_AddressBand)
{
// Found the band, so get its window handle.
if (IOleWindowPtr ow = band)
{
HWND window = 0;
ow->GetWindow(&window);
// To set the focus to a window in another thread, we need to use AttachThreadInput.
DWORD thread = GetWindowThreadProcessId(window, 0);
AttachThreadInput(GetCurrentThreadId(), thread, TRUE);
SetFocus(window);
AttachThreadInput(GetCurrentThreadId(), thread, FALSE);
return true;
}
}
}
}
}
return false;
}
--
Jim Barry, MVP for Windows SDK
I have some code running on XP, but on W2K i get:
"System.Runtime.InteropServices.COMException
Message: COM object with CLSID {F60AD0A0-E5E1-45CB-B51A-E15B9F8B2934} is
either not valid or not registered."
Regards, Tibor
"Jim Barry" <j...@mvps.org> wrote in message
news:e6uzXDkp...@TK2MSFTNGP15.phx.gbl...
No, it was introduced in XP.
What do you suggest:
1. Use messaging both on 2K and XP
2. Use messaging on 2K and TrayBandSiteService on XP?
BR, Tibor
"Jim Barry" <j...@mvps.org> wrote in message
news:%239Sttcw...@TK2MSFTNGP15.phx.gbl...
I would go for #2, though I would avoid an explicit version check, i.e. use TrayBandSiteService if available, otherwise do the other thing.
Have a nice day!
"Jim Barry" <j...@mvps.org> wrote in message
news:uW%23ARBh1...@tk2msftngp13.phx.gbl...
Again, you may need to update your SDK.
I installed the latest Paltform SDK (windows 2003 SP1 released in april) but
the compiler error persists ! :-(
Regards,
Marco
Hmmm, that is the error I get if I don't #include <ComDef.h>...
I'm all out of ideas then, I'm afraid.
Please, how is the messaging way for 2K, I have to do that but I don't find
documentation, do you have a link or a hint/clue to beging to search about?
Thanks, Demian.
Sorry, I'm actually not too sure what method Tibor was referring to.