Re: MFC Icon Handler's IExtractIcon::GetIconLocation() never gets
"Jim Barry" wrote:
nomad wrote:
Yes, the MFC declarations for everything are much cleaner
Cleaner than what?
Well, ATL, for one thing.
Anyway, debugger aside, I've got a test app now and I can verify that I can
load the DLL and call into the IExtractIcon interface if I call
::CoInitialize(), CoCreateInstance(), do a QueryInterface(), and then call
the method off the pointer I get back:
::CoInitialize(NULL);
IUnknown* pUnk(NULL);
result = ::CoCreateInstance(kIHCLSID, NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown,
reinterpret_cast<LPVOID*>(&pUnk));
IPersistFile* pIPF(NULL);
if (S_OK == pUnk->QueryInterface(IID_IPersistFile,
reinterpret_cast<LPVOID*>(&pIPF)))
{
ASSERT(S_OK == pIPF->Load(_T("<path to my data file>"), 0));
}
IExtractIcon* pIEI(NULL);
TCHAR path[MAX_PATH];
if (S_OK == pUnk->QueryInterface(IID_IExtractIcon,
reinterpret_cast<LPVOID*>(&pIEI)))
{
int iIndex(0);
UINT wFlags(0);
if (S_OK == pIEI->GetIconLocation(0, path, MAX_PATH, &iIndex, &wFlags))
{
if (S_OK == pIEI->Extract(path, iIndex, &fHBigIcon, &fHSmallIcon,
MAKELONG(32, 16)))
{
(void) fBigIcon.SetIcon(fHBigIcon);
(void) fSmallIcon.SetIcon(fHSmallIcon);
}
}
}
That all works fine. I can also do it using SHGetDesktopFolder() and the
various related calls:
::CoInitialize(NULL);
if (FAILED(SHGetDesktopFolder(&deskFolder)))
return TRUE;
if (FAILED(deskFolder->ParseDisplayName(NULL, NULL,
_T("g:\\development\\projects\\sample files\\files with
embedded previews\\biotite.cmdf"),
NULL, &pidlLocal, NULL)))
{
deskFolder->Release();
return TRUE;
}
pidlRelative = ILClone(ILFindLastID(pidlLocal));
ILRemoveLastID(pidlLocal);
if (FAILED(deskFolder->BindToObject(pidlLocal, NULL, IID_IShellFolder,
(void**)&appObject)))
{
deskFolder->Release();
ILFree(pidlLocal);
return TRUE;
}
ILFree(pidlLocal);
hr = appObject->GetUIObjectOf(NULL, 1, (LPCITEMIDLIST*)&pidlRelative,
IID_IExtractIcon, NULL,
(void**)&extractIcon);
But if I attach to an explorer window with the debugger, what happens is
that my IPersistFile::Load() method gets called, then I load the interface
for IExtractIcon, and, right after that, my IExtractIcon::Release() method
gets called (apparently from CoWaitForMultipleHandles()). So the shell gets
the IExtractIcon interface, and releases it without (apparently) calling
anything.