setConsoleIcon выдает странную ошибку (недокументированный WinAPI для JS-Ctypes)

Есть недокументированный winapi fetarue под названием setConsoleIcon. Я обсуждал с этим парнем здесь:

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

Код С++ таков:

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);

Если вы закомментируете последнюю строку, скопируете и запустите ее, у вас не возникнет проблем.

Однако, если вы раскомментируете его и используете с hIconBig или hIconBigNull, вы получите эту ошибку: (разница между двумя заключается в том, что 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. Любые идеи?


person Noitidart    schedule 04.07.2014    source источник


Ответы (1)


Проблема здесь в вашем var void = .... void — это зарезервированное ключевое слово в Javascript, поэтому его нельзя использовать в качестве имени переменной.

Другие случайные наблюдения:

  • Используйте ctypes.void_t при объявлении функций, которые являются void или когда вам не важно возвращаемое значение.
  • Никогда не вызывайте LoadImage с оконной ручкой. Предполагается, что он вызывается с дескриптором модуля или нулем. Вы захотите вызвать его с нулевым значением, так как вы загружаете автономные изображения.
  • Использование недокументированных API в целом не очень хорошая идея, и его следует избегать, если это возможно. Я знаю, что сначала получить дескриптор окна консоли с помощью GetConsoleWindow(), а затем отправить WM_SETICON работает просто отлично, и это с использованием задокументированной функциональности.
  • Я вообще понятия не имею, что ты пытаешься здесь сделать. Firefox (обычно) вообще не имеет окна консоли.
person nmaier    schedule 04.07.2014
comment
Окно консоли, черт возьми, не будет работать :( В Win7 я не смог установить значок Firefox на панели задач, когда он не закреплен. Очевидно, у него есть отдельный значок, когда он закреплен и не закреплен. Метод закрепления, над которым я работаю в другой теме, используя этот SHGetWindowProp материал. - person Noitidart; 04.07.2014