mirror of
https://github.com/moparisthebest/FireTray
synced 2024-08-13 15:53:47 -04:00
destroy tray icon, hidden window and window class on shutdown
This commit is contained in:
parent
083304cd56
commit
8e78f45d56
@ -42,7 +42,7 @@ new ctypes_library(KERNEL32_LIBNAME, KERNEL32_ABIS, kernel32_defines, this);
|
|||||||
let osvi = new kernel32.OSVERSIONINFOEXW();
|
let osvi = new kernel32.OSVERSIONINFOEXW();
|
||||||
osvi.dwOSVersionInfoSize = kernel32.OSVERSIONINFOEXW.size;
|
osvi.dwOSVersionInfoSize = kernel32.OSVERSIONINFOEXW.size;
|
||||||
if (kernel32.GetVersionExW(osvi.address())) {
|
if (kernel32.GetVersionExW(osvi.address())) {
|
||||||
win32.WINVER = osvi.dwMajorVersion*10 + osvi.dwMinorVersion;
|
win32.WINVER = (+osvi.dwMajorVersion)*10 + (+osvi.dwMinorVersion); // ctypes.UInt64 objects!
|
||||||
} else {
|
} else {
|
||||||
Cu.ReportError("win version not found");
|
Cu.ReportError("win version not found");
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,9 @@ function user32_defines(lib) {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
lib.lazy_bind("RegisterClassExW", win32.ATOM, this.WNDCLASSEXW.ptr);
|
lib.lazy_bind("RegisterClassExW", win32.ATOM, this.WNDCLASSEXW.ptr);
|
||||||
|
lib.lazy_bind("UnregisterClassW", win32.BOOL, win32.LPCTSTR, win32.HINSTANCE);
|
||||||
lib.lazy_bind("CreateWindowExW", win32.HWND, win32.DWORD, win32.LPCTSTR, win32.LPCTSTR, win32.DWORD, ctypes.int, ctypes.int, ctypes.int, ctypes.int, win32.HWND, win32.HMENU, win32.HINSTANCE, win32.LPVOID);
|
lib.lazy_bind("CreateWindowExW", win32.HWND, win32.DWORD, win32.LPCTSTR, win32.LPCTSTR, win32.DWORD, ctypes.int, ctypes.int, ctypes.int, ctypes.int, win32.HWND, win32.HMENU, win32.HINSTANCE, win32.LPVOID);
|
||||||
|
lib.lazy_bind("DestroyWindow", win32.BOOL, win32.HWND);
|
||||||
|
|
||||||
this.CW_USEDEFAULT = ctypes.int(0x80000000); // -2147483648
|
this.CW_USEDEFAULT = ctypes.int(0x80000000); // -2147483648
|
||||||
|
|
||||||
|
@ -26,13 +26,10 @@ if ("undefined" == typeof(firetray.Handler))
|
|||||||
firetray.StatusIcon = {
|
firetray.StatusIcon = {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
|
callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
|
||||||
trayIcon: null,
|
notifyIconData: null,
|
||||||
themedIconApp: null,
|
hwndHidden: null,
|
||||||
themedIconNewMail: null,
|
WNDCLASS_NAME: "FireTrayHiddenWindowClass",
|
||||||
prefAppIconNames: null,
|
WNDCLASS_ATOM: null,
|
||||||
prefNewMailIconNames: null,
|
|
||||||
defaultAppIconName: null,
|
|
||||||
defaultNewMailIconName: null,
|
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
|
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
|
||||||
@ -46,6 +43,9 @@ firetray.StatusIcon = {
|
|||||||
|
|
||||||
shutdown: function() {
|
shutdown: function() {
|
||||||
log.debug("Disabling StatusIcon");
|
log.debug("Disabling StatusIcon");
|
||||||
|
|
||||||
|
this.destroy();
|
||||||
|
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -56,8 +56,7 @@ firetray.StatusIcon = {
|
|||||||
let hwnd_hidden_moz = user32.FindWindowW("MozillaHiddenWindowClass", null);
|
let hwnd_hidden_moz = user32.FindWindowW("MozillaHiddenWindowClass", null);
|
||||||
log.debug("=== hwnd_hidden_moz="+hwnd_hidden_moz);
|
log.debug("=== hwnd_hidden_moz="+hwnd_hidden_moz);
|
||||||
|
|
||||||
let nid = new shell32.NOTIFYICONDATAW();
|
nid = new shell32.NOTIFYICONDATAW();
|
||||||
|
|
||||||
nid.cbSize = shell32.NOTIFYICONDATAW_SIZE();
|
nid.cbSize = shell32.NOTIFYICONDATAW_SIZE();
|
||||||
log.debug("SIZE="+nid.cbSize);
|
log.debug("SIZE="+nid.cbSize);
|
||||||
nid.szTip = firetray.Handler.appName;
|
nid.szTip = firetray.Handler.appName;
|
||||||
@ -67,29 +66,23 @@ firetray.StatusIcon = {
|
|||||||
nid.uFlags = shell32.NIF_ICON | shell32.NIF_MESSAGE | shell32.NIF_TIP;
|
nid.uFlags = shell32.NIF_ICON | shell32.NIF_MESSAGE | shell32.NIF_TIP;
|
||||||
nid.uVersion = shell32.NOTIFYICON_VERSION_4;
|
nid.uVersion = shell32.NOTIFYICON_VERSION_4;
|
||||||
|
|
||||||
/*
|
|
||||||
// string is truncate to size of buffer and null-terminated. nid.szTip is
|
|
||||||
// initialized automatically by ctypes
|
|
||||||
let nMaxCount = 127;
|
|
||||||
let len = user32.GetWindowTextW(hwnd, nid.szTip, nMaxCount);
|
|
||||||
log.debug("errno="+ctypes.errno+" winLastError="+ctypes.winLastError);
|
|
||||||
if (len != 0) {
|
|
||||||
log.info("nid.szTip="+nid.szTip.readString());
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Install the icon
|
// Install the icon
|
||||||
rv = shell32.Shell_NotifyIconW(shell32.NIM_ADD, nid.address());
|
rv = shell32.Shell_NotifyIconW(shell32.NIM_ADD, nid.address());
|
||||||
log.debug("Shell_NotifyIcon ADD="+rv+" winLastError="+ctypes.winLastError); // ERROR_INVALID_WINDOW_HANDLE(1400)
|
log.debug("Shell_NotifyIcon ADD="+rv+" winLastError="+ctypes.winLastError); // ERROR_INVALID_WINDOW_HANDLE(1400)
|
||||||
shell32.Shell_NotifyIconW(shell32.NIM_SETVERSION, nid.address());
|
rv = shell32.Shell_NotifyIconW(shell32.NIM_SETVERSION, nid.address());
|
||||||
log.debug("Shell_NotifyIcon SETVERSION="+rv+" winLastError="+ctypes.winLastError);
|
log.debug("Shell_NotifyIcon SETVERSION="+rv+" winLastError="+ctypes.winLastError);
|
||||||
|
|
||||||
|
this.notifyIconData = nid;
|
||||||
|
this.hwndHidden = hwnd_hidden;
|
||||||
},
|
},
|
||||||
|
|
||||||
createHiddenWindow: function() {
|
createHiddenWindow: function() {
|
||||||
|
this.registerWindowClass();
|
||||||
|
|
||||||
this.callbacks.hiddenWinProc = user32.WNDPROC(firetray.StatusIcon.hiddenWindowProc);
|
this.callbacks.hiddenWinProc = user32.WNDPROC(firetray.StatusIcon.hiddenWindowProc);
|
||||||
|
|
||||||
let hwnd_hidden = user32.CreateWindowExW(
|
let hwnd_hidden = user32.CreateWindowExW(
|
||||||
0, win32.LPCTSTR(firetray.Win32.WNDCLASS_ATOM), // lpClassName can also be _T(WNDCLASS_NAME)
|
0, win32.LPCTSTR(this.WNDCLASS_ATOM), // lpClassName can also be _T(WNDCLASS_NAME)
|
||||||
"Firetray Message Window", 0,
|
"Firetray Message Window", 0,
|
||||||
user32.CW_USEDEFAULT, user32.CW_USEDEFAULT, user32.CW_USEDEFAULT, user32.CW_USEDEFAULT,
|
user32.CW_USEDEFAULT, user32.CW_USEDEFAULT, user32.CW_USEDEFAULT, user32.CW_USEDEFAULT,
|
||||||
null, null, firetray.Win32.hInstance, null);
|
null, null, firetray.Win32.hInstance, null);
|
||||||
@ -99,11 +92,23 @@ firetray.StatusIcon = {
|
|||||||
ctypes.cast(this.callbacks.hiddenWinProc, win32.LONG_PTR));
|
ctypes.cast(this.callbacks.hiddenWinProc, win32.LONG_PTR));
|
||||||
log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError);
|
log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError);
|
||||||
|
|
||||||
|
firetray.Win32.acceptAllMessages(hwnd_hidden);
|
||||||
|
|
||||||
return hwnd_hidden;
|
return hwnd_hidden;
|
||||||
},
|
},
|
||||||
|
|
||||||
hiddenWindowProc: function(hWnd, uMsg, wParam, lParam) {
|
registerWindowClass: function() {
|
||||||
|
let wndClass = new user32.WNDCLASSEXW();
|
||||||
|
wndClass.cbSize = user32.WNDCLASSEXW.size;
|
||||||
|
wndClass.lpfnWndProc = ctypes.cast(user32.DefWindowProcW, user32.WNDPROC);
|
||||||
|
wndClass.hInstance = firetray.Win32.hInstance;
|
||||||
|
wndClass.lpszClassName = win32._T(this.WNDCLASS_NAME);
|
||||||
|
this.WNDCLASS_ATOM = user32.RegisterClassExW(wndClass.address());
|
||||||
|
log.debug("WNDCLASS_ATOM="+this.WNDCLASS_ATOM);
|
||||||
|
},
|
||||||
|
|
||||||
|
hiddenWindowProc: function(hWnd, uMsg, wParam, lParam) {
|
||||||
|
log.debug("HiddenWindowProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
|
||||||
// ... do something smart with this event!
|
// ... do something smart with this event!
|
||||||
|
|
||||||
return user32.DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
return user32.DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
@ -131,6 +136,23 @@ firetray.StatusIcon = {
|
|||||||
}
|
}
|
||||||
log.debug("=== icon="+icon);
|
log.debug("=== icon="+icon);
|
||||||
return icon;
|
return icon;
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyHiddenWindow: function() {
|
||||||
|
let rv = user32.DestroyWindow(this.hwndHidden);
|
||||||
|
|
||||||
|
rv = this.unregisterWindowClass();
|
||||||
|
log.debug("Hidden window removed");
|
||||||
|
},
|
||||||
|
|
||||||
|
unregisterWindowClass: function() {
|
||||||
|
return user32.UnregisterClassW(win32.LPCTSTR(this.WNDCLASS_ATOM), firetray.Win32.hInstance);
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function() {
|
||||||
|
let rv = shell32.Shell_NotifyIconW(shell32.NIM_DELETE, this.notifyIconData.address());
|
||||||
|
log.debug("Shell_NotifyIcon DELETE="+rv+" winLastError="+ctypes.winLastError);
|
||||||
|
this.destroyHiddenWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // firetray.StatusIcon
|
}; // firetray.StatusIcon
|
||||||
|
@ -32,21 +32,23 @@ function Win32Env() {
|
|||||||
this.hInstance = kernel32.GetModuleHandleW("xul"); // ordinary windows are created from xul.dll
|
this.hInstance = kernel32.GetModuleHandleW("xul"); // ordinary windows are created from xul.dll
|
||||||
log.debug("hInstance="+this.hInstance);
|
log.debug("hInstance="+this.hInstance);
|
||||||
|
|
||||||
/*
|
/* if Administrator, accept messages from applications running in a lower
|
||||||
let hUser = kernel32.LoadLibraryW("user32");
|
privilege level */
|
||||||
let defWindowProcW = kernel32.GetProcAddress(hUser, "DefWindowProcW");
|
this.acceptAllMessages = function(hwnd) {
|
||||||
log.debug("defWindowProcW="+defWindowProcW);
|
let rv = null;
|
||||||
log.debug("_______________DefWindowProcW="+user32.DefWindowProcW);
|
log.info(win32.WINVER+" >= "+win32.WIN_VERSIONS["7"]);
|
||||||
*/
|
if (win32.WINVER >= win32.WIN_VERSIONS["7"]) {
|
||||||
|
rv = user32.ChangeWindowMessageFilterEx(hwnd, firetray.Win32.WM_TASKBARCREATED, user32.MSGFLT_ALLOW, null);
|
||||||
|
log.debug("ChangeWindowMessageFilterEx res="+rv+" winLastError="+ctypes.winLastError);
|
||||||
|
} else if (win32.WINVER >= win32.WINVER["Vista"]) {
|
||||||
|
rv = user32.ChangeWindowMessageFilter(firetray.Win32.WM_TASKBARCREATED, user32.MSGFLT_ADD);
|
||||||
|
log.debug("ChangeWindowMessageFilter res="+rv+" winLastError="+ctypes.winLastError);
|
||||||
|
} else {
|
||||||
|
// no UIPI
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
};
|
||||||
|
|
||||||
this.WNDCLASS_NAME = "FireTrayHiddenWindowClass";
|
|
||||||
let wndClass = new user32.WNDCLASSEXW();
|
|
||||||
wndClass.cbSize = user32.WNDCLASSEXW.size;
|
|
||||||
wndClass.lpfnWndProc = ctypes.cast(user32.DefWindowProcW, user32.WNDPROC);
|
|
||||||
wndClass.hInstance = this.hInstance;
|
|
||||||
wndClass.lpszClassName = win32._T(this.WNDCLASS_NAME);
|
|
||||||
this.WNDCLASS_ATOM = user32.RegisterClassExW(wndClass.address());
|
|
||||||
log.debug("WNDCLASS_ATOM="+this.WNDCLASS_ATOM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
firetray.Win32 = new Win32Env();
|
firetray.Win32 = new Win32Env();
|
||||||
|
@ -64,22 +64,6 @@ firetray.Window = {
|
|||||||
setVisibility: function(xid, visibility) {
|
setVisibility: function(xid, visibility) {
|
||||||
},
|
},
|
||||||
|
|
||||||
/* if Administrator, accept messages from applications running in a lower
|
|
||||||
privilege level */
|
|
||||||
acceptAllMessages: function(hwnd) {
|
|
||||||
let rv = null;
|
|
||||||
if (win32.WINVER >= win32.WIN_VERSIONS["7"]) {
|
|
||||||
rv = user32.ChangeWindowMessageFilterEx(hwnd, WM_TASKBARCREATED, user32.MSGFLT_ALLOW, null);
|
|
||||||
log.debug("ChangeWindowMessageFilterEx res="+rv+" winLastError="+ctypes.winLastError);
|
|
||||||
} else if (win32.WINVER >= win32.WINVER["Vista"]) {
|
|
||||||
rv = user32.ChangeWindowMessageFilter(WM_TASKBARCREATED, user32.MSGFLT_ADD);
|
|
||||||
log.debug("ChangeWindowMessageFilter res="+rv+" winLastError="+ctypes.winLastError);
|
|
||||||
} else {
|
|
||||||
log.error("Unsupported windoz version "+win32.WINVER);
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // firetray.Window
|
}; // firetray.Window
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user