setConsoleIcon抛出奇怪的错误(未记录的WinAPI到JS-Ctypes)

时间:2014-07-04 04:03:06

标签: javascript firefox-addon jsctypes

有一个名为setConsoleIcon的无人值守的winapi胎儿。我和这个人在这里讨论过:

https://github.com/john-peterson/john-peterson/issues/1#issuecomment-47852560

C ++代码是这样的:

void SetIcon(LPCTSTR icon) {
    HMODULE hMainMod = GetModuleHandle(NULL);
    HICON hMainIcon = ::LoadIcon(hMainMod, icon);
    HMODULE hMod = LoadLibraryA("Kernel32.dll");
    typedef BOOL (CALLBACK *InsHook)(unsigned long, HANDLE);
    typedef DWORD (__stdcall *SCI)(HICON);
    SCI pfnSetConsoleIcon = reinterpret_cast<SCI>(GetProcAddress(hMod, "SetConsoleIcon"));
    pfnSetConsoleIcon(hMainIcon);
    FreeLibrary(hMod);
}

我把它转换成了这个:

Cu.import('resource://gre/modules/ctypes.jsm');

var kernel32 = ctypes.open('kernel32.dll');
var user32 = ctypes.open('user32.dll');

var SetConsoleIcon = kernel32.declare('SetConsoleIcon', ctypes.winapi_abi, ctypes.voidptr_t, // i have no idea what return value is so made it voidptr_t
    ctypes.voidptr_t // HICON
);

 /* http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045%28v=vs.85%29.aspx
* HANDLE WINAPI LoadImage(
* __in_opt_ HINSTANCE hinst,
* __in_ LPCTSTR lpszName,
* __in_ UINT uType,
* __in_ int cxDesired,
* __in_ int cyDesired,
* __in_ UINT fuLoad
* );
*/
var LoadImage = user32.declare('LoadImageA', ctypes.winapi_abi, ctypes.voidptr_t,
    ctypes.voidptr_t,
    ctypes.char.ptr,
    ctypes.unsigned_int,
    ctypes.int,
    ctypes.int,
    ctypes.unsigned_int
);

var IMAGE_BITMAP = 0;
var IMAGE_ICON = 1;
var LR_LOADFROMFILE = 16;


var aDOMWindow = window;
var baseWindow = aDOMWindow.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 hIconBig = LoadImage(targetWindow_handle, 'C:\\Users\\noit\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\1agqx535.default2\\profilist32.ico', IMAGE_ICON, 256, 256, LR_LOADFROMFILE);
var hIconBigNull = LoadImage(null, 'C:\\Users\\noit\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\1agqx535.default2\\profilist32.ico', IMAGE_ICON, 256, 256, LR_LOADFROMFILE);
var void = SetConsoleIcon(hIconBig); //SetConsoleIcon(hIconBigNull);

如果你注释掉最后一行并复制并运行它,你就不会有任何问题。

但是,如果您取消注释并将其与hIconBighIconBigNull一起使用,则会出现此错误: (两者之间的差异,是hIconBig我传递窗口句柄和hIconBigNull我传递null作为句柄)

/*
"missing variable name
WCA_evalWithDebugger@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/server/actors/webconsole.js:1069:7
WCA_onEvaluateJS@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/server/actors/webconsole.js:734:9
DSC_onPacket@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/server/main.js:1098:9
LDT_send/<@resource://gre/modules/devtools/dbg-client.jsm -> resource://gre/modules/devtools/server/transport.js:279:11
makeInfallible/<@resource://gre/modules/commonjs/toolkit/loader.js -> resource://gre/modules/devtools/DevToolsUtils.js:84:7"
*/

我无法解释这个missing variable name。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这里的问题是你的var void = ...void是Javascript中的保留关键字,因此不能用作变量名。

其他随机观察:

  • 在声明ctypes.void_t的功能或您不关心返回值的功能时使用void
  • 切勿使用窗口句柄调用LoadImage。它应该使用模块句柄或null来调用。您将要使用null调用它,因为您正在加载独立图像。
  • 使用未记录的API通常不是一个好主意,如果可行的话应该避免使用。我知道首先使用GetConsoleWindow()获取控制台窗口句柄,然后发送WM_SETICON就可以正常工作了,这是使用记录的功能。
  • 我不知道你到底想要做什么。 Firefox(通常)根本没有控制台窗口。