问题
If I don't use WM_SETICON first to set the icon then WM_GETICON is always returning 0. This is weird. Please help.
This is my code, can copy paste into scratchpad and run.
When doing SendMessage(targetWindow_handle, WM_GETICON , ICON_SMALL, ctypes.voidptr_t(0))
, hIconSmall_orig
and hIconBig_orig
is always returning 0 I have no idea why. IF you go WM_SETICON on the window first then it properly gets the HICON but the whole purpose is to get the default icon.
Cu.import('resource://gre/modules/ctypes.jsm');
var user32 = ctypes.open('user32.dll');
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950%28v=vs.85%29.aspx
* LRESULT WINAPI SendMessage(
* __in HWND hWnd,
* __in UINT Msg,
* __in WPARAM wParam,
* __in LPARAM lParam
* );
*/
var SendMessage = user32.declare('SendMessageW', ctypes.winapi_abi, ctypes.uintptr_t,
ctypes.voidptr_t,
ctypes.unsigned_int,
ctypes.int32_t,
ctypes.voidptr_t
);
var WM_GETICON = 0x007F;
var WM_SETICON = 0x0080;
var ICON_SMALL = 0;
var ICON_BIG = 1;
var ICON_SMALL2 = 2; //for use with WM_GETICON only, not applicable to WM_SETICON
// RUNNING STUFF BELOW - ABVOE WAS JUST DEFINING STUFF
var baseWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.nsIBaseWindow;
var nativeHandle = baseWindow.nativeHandle;
var targetWindow_handle = ctypes.voidptr_t(ctypes.UInt64(nativeHandle));
var hIconSmall_orig = SendMessage(targetWindow_handle, WM_GETICON , ICON_SMALL, ctypes.voidptr_t(0));
var hIconBig_orig = SendMessage(targetWindow_handle, WM_GETICON , ICON_BIG, ctypes.voidptr_t(0));
Services.wm.getMostRecentWindow(null).alert('hIconSmall_orig = ' + hIconSmall_orig + '\nhIconBig_orig = ' + hIconBig_orig);
user32.close();
回答1:
Since you got the WM_GETICON
stuff from me (in another answer to another question) let me first say: It has been a while... So I forgot that WM_GETICON
will return null when the window has no particular window icon assigned, but instead the icon is taken from the registered window class.
So you should:
- Check
WM_GETICON
to see if the window has a specific icon assigned. - Check the class by
GetClassLongPtr(hwnd, GCLP_HICON /* or GCLP_HICONSM */)
- If that fails, you can always try to load the main icon from the
.exe
- If that fails, you can always try to load a stock icon.
Here is some C++ code which I use to actually get an icon from a window in my "mintrayr" extension:
// Get the window icon
HICON icon = reinterpret_cast<HICON>(::SendMessageW(hwnd, WM_GETICON, ICON_SMALL, 0));
if (icon == 0) {
// Alternative method. Get from the window class
icon = reinterpret_cast<HICON>(::GetClassLongPtrW(hwnd, GCLP_HICONSM));
}
// Alternative method: get the first icon from the main module (executable image of the process)
if (icon == 0) {
icon = ::LoadIcon(GetModuleHandleW(0), MAKEINTRESOURCE(0));
}
// Alternative method. Use OS default icon
if (icon == 0) {
icon = ::LoadIcon(0, IDI_APPLICATION);
}
回答2:
Well, there is a surprisingly easy (and cross-platform) way to retrieve the default icon of Firefox.
var foxexe = FileUtils.getFile("XREExeF", []);
var iconurl = "moz-icon:" + Services.io.newFileURI(foxexe).spec;
You can treat iconurl
the same way as any other image-pointing url. The default size is 16x16, append ?size=32
to get a bigger icon. It seems that these two values are the only supported on Windows. This might not be the case for other OSes.
来源:https://stackoverflow.com/questions/24047470/wm-geticon-not-working-windows