Already done that... and low-res icons are still being shown. Could you explain the WMI stuff a litte bit more?
matonga, on Apr 2nd 2009, 05:23 AM, said:
You should pass GCL_HICON first (after WM_GETICON), then GCL_HICONSM.
But you'll still get low-res icons probably.
The best I can think of is to use WMI to get executable full path from hwnd, then extract first icon and use that.
Edit:
Never mind, I found a way to retrieve the module (executable) associated with a given running process (thanks to MSDN and to the GetModuleFileNameEx API. Ok, I've got the executable full path... from there what should I do?
Edit 2:
I have modified the procedure to retrieve icons like this:
Gdiplus::Bitmap *GetWindowIcon(HWND hWnd, PTCHAR szFullPath, DWORD icon_type)
{
HICON hIcon = NULL;
SHFILEINFO *lpSfi = new SHFILEINFO;
ZeroMemory(lpSfi, sizeof(SHFILEINFO));
SHGetFileInfo(szFullPath, 0, lpSfi, sizeof(SHFILEINFO), SHGFI_LARGEICON);
hIcon = lpSfi->hIcon;
if (hIcon == NULL)
hIcon = (HICON)SendMessage(hWnd, WM_GETICON, (WPARAM) icon_type, 0);
if (hIcon == NULL)
hIcon = (HICON)GetClassLong(hWnd, GCL_HICON);
if (hIcon == NULL)
hIcon = (HICON)GetClassLong(hWnd, GCL_HICONSM);
if (hIcon == NULL)
return NULL;
if (lpSfi)
delete lpSfi;
return IconToAlphaBitmap(hIcon);
}
but the icons are still low-res and look crappy when setting the stack icon to 128.
Edit 3:
Ok, I finally got it right! thanks to
PogoPixel I found how to extract the hi-res icon out of the imagelist that windows keeps. This is the modified code:
Gdiplus::Bitmap *GetWindowIcon(HWND hWnd, PTCHAR szFullPath, DWORD icon_type)
{
HICON hIcon = NULL;
// Get the icon index using SHGetFileInfo
SHFILEINFO *lpSfi = new SHFILEINFO;
ZeroMemory(lpSfi, sizeof(SHFILEINFO));
SHGetFileInfo(szFullPath, 0, lpSfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX);
// Retrieve the system image list.
// To get the 48x48 icons, use SHIL_EXTRALARGE
// To get the 256x256 icons (Vista only), use SHIL_JUMBO
HIMAGELIST *imageList;
HRESULT hResult = SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&imageList);
if (hResult == S_OK)
{
// Get the icon we need from the list. Note that the HIMAGELIST we retrieved
// earlier needs to be casted to the IImageList interface before use.
((IImageList*)imageList)->GetIcon(lpSfi->iIcon, ILD_TRANSPARENT, &hIcon);
}
if (hIcon == NULL)
hIcon = (HICON)SendMessage(hWnd, WM_GETICON, (WPARAM) icon_type, 0);
if (hIcon == NULL)
hIcon = (HICON)GetClassLong(hWnd, GCL_HICON);
if (hIcon == NULL)
hIcon = (HICON)GetClassLong(hWnd, GCL_HICONSM);
if (hIcon == NULL)
return NULL;
if (lpSfi)
delete lpSfi;
return IconToAlphaBitmap(hIcon);
}
Edit 4:
Unfortunately, further testing showed that this method does come with several problems... first, although in my dev system it retrieves the executable icons correctly on my host machine it does not work (all icons, no mather what executable is are being shown as the very same hi-res icon as if the image list were empty). Another problem is that for many running processes the executable icon is not always the running app icon (specially for items like explorer folders which do not correspond to the explorer.exe icon). I am not sure how to overcome this... maybe you already have dealt with this.
Edit 5:
Well I have still found no way to retrieve the appropiate hi-res icon for the running process, but thanks to vantha's help and his XWindowDock docklet I think I found a better way to show the tasks. Now it shows a snapshot of the application among the large icon of it. I have included a couple of snapshots here.
Anyway, there are many possibilities here...
1) To get the hi-res icon, how do you do that in the stacks docklet matonga?
2) To show the snapshot only for not minimized apps.
3) Do as now, show an snapshot of all windows (it cames with a price... performance, it takes some time to do the snapshot of minimized apps).
What do you think?
On the other hand, the docket could be much enhanced by adding some features to the stacklib:
1) Highlight of the current hovered item in the grid/fan (Matonga, I believe you might be working on that, if not that would be an excellent feature).
2) left-button click support so I would be able to add a context menu to say, show, hide, close, etc. the currently selected task.
3) Enable/disable state, that dimms (alpha channel) some item, this could help show minimized windows by dimming the a bit (this would be helpful for other scenarios like the RSS Feed docklet, so I could show items already read as dimmed).
Well... i think that's for now.
This post has been edited by Smaky: 04 April 2009 - 06:44 PM