/* BossKey - Hide Miranda from your boss :) Copyright (C) 2002-2003 Goblineye Entertainment, (C) 2007-2010 Billy_Bons This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "stdafx.h" HGENMENU g_hMenuItem; HWINEVENTHOOK g_hWinHook; HWND g_hListenWindow, g_hDlgPass, hOldForegroundWindow; HWND_ITEM *g_pMirWnds; // a pretty simple linked list HMODULE hDwmApi; DWORD g_dwMirandaPID; uint16_t g_wMask, g_wMaskAdv; bool g_bWindowHidden, g_fPassRequested, g_TrayIcon; char g_password[MAXPASSLEN + 1]; HKL oldLangID, oldLayout; int protoCount; PROTOACCOUNT **proto; unsigned *oldStatus; wchar_t **oldStatusMsg; uint8_t g_bOldSetting; CMPlugin g_plugin; PFNDwmIsCompositionEnabled dwmIsCompositionEnabled; static void LanguageChanged(HWND hDlg); ///////////////////////////////////////////////////////////////////////////////////////// static PLUGININFOEX pluginInfoEx = { sizeof(PLUGININFOEX), __PLUGIN_NAME, PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), __DESCRIPTION, __AUTHOR, __COPYRIGHT, __AUTHORWEB, UNICODE_AWARE, // {4FAC353D-0A36-44A4-9064-6759C53AE782} { 0x4fac353d, 0x0a36, 0x44a4, { 0x90, 0x64, 0x67, 0x59, 0xc5, 0x3a, 0xe7, 0x82 } } }; CMPlugin::CMPlugin() : PLUGIN(MODULENAME, pluginInfoEx) {} ///////////////////////////////////////////////////////////////////////////////////////// static BOOL IsAeroMode() { BOOL result; return dwmIsCompositionEnabled && (dwmIsCompositionEnabled(&result) == S_OK) && result; } INT_PTR CALLBACK DlgStdInProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static uint32_t dwOldIcon = 0; HICON hIcon = nullptr; UINT uid; switch (uMsg) { case WM_INITDIALOG: g_hDlgPass = hDlg; hIcon = LoadIcon(g_plugin.getInst(), MAKEINTRESOURCE(IDI_DLGPASSWD)); dwOldIcon = SetClassLongPtr(hDlg, GCLP_HICON, (INT_PTR)hIcon); // set alt+tab icon SendDlgItemMessage(hDlg, IDC_EDIT1, EM_LIMITTEXT, MAXPASSLEN, 0); if (IsAeroMode()) { SetWindowLongPtr(hDlg, GWL_STYLE, GetWindowLongPtr(hDlg, GWL_STYLE) | WS_DLGFRAME | WS_SYSMENU); SetWindowLongPtr(hDlg, GWL_EXSTYLE, GetWindowLongPtr(hDlg, GWL_EXSTYLE) | WS_EX_TOOLWINDOW); RECT rect; GetClientRect(hDlg, &rect); SetWindowPos(hDlg, nullptr, 0, 0, rect.right, rect.bottom + GetSystemMetrics(SM_CYCAPTION), SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER); } SendDlgItemMessage(hDlg, IDC_HEADERBAR, WM_SETICON, 0, (LPARAM)hIcon); TranslateDialogDefault(hDlg); oldLangID = nullptr; SetTimer(hDlg, 1, 200, nullptr); oldLayout = GetKeyboardLayout(0); if (MAKELCID(LOWORD(oldLayout) & 0xffffffff, SORT_DEFAULT) != (LCID)0x00000409) ActivateKeyboardLayout((HKL)0x00000409, 0); LanguageChanged(hDlg); return TRUE; case WM_CTLCOLORSTATIC: if (GetWindowLongPtr((HWND)lParam, GWLP_ID) != IDC_LANG) break; SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT)); SetBkMode((HDC)wParam, TRANSPARENT); return (INT_PTR)GetSysColorBrush(COLOR_HIGHLIGHT); case WM_COMMAND: uid = LOWORD(wParam); if (uid == IDOK) { char password[MAXPASSLEN + 1] = { 0 }; int passlen = GetDlgItemTextA(hDlg, IDC_EDIT1, password, _countof(password)); if (passlen == 0) { SetDlgItemText(hDlg, IDC_HEADERBAR, TranslateT("Miranda NG is locked.\nEnter password to unlock it.")); SendDlgItemMessage(hDlg, IDC_HEADERBAR, WM_NCPAINT, 0, 0); break; } else if (mir_strcmp(password, g_password)) { SetDlgItemText(hDlg, IDC_HEADERBAR, TranslateT("Password is not correct!\nPlease, enter correct password.")); SendDlgItemMessage(hDlg, IDC_HEADERBAR, WM_NCPAINT, 0, 0); SetDlgItemText(hDlg, IDC_EDIT1, L""); break; } else EndDialog(hDlg, IDOK); } else if (uid == IDCANCEL) EndDialog(hDlg, IDCANCEL); case WM_TIMER: LanguageChanged(hDlg); break; case WM_DESTROY: KillTimer(hDlg, 1); if (GetKeyboardLayout(0) != oldLayout) ActivateKeyboardLayout(oldLayout, 0); SetClassLongPtr(hDlg, GCLP_HICON, (long)dwOldIcon); DestroyIcon(hIcon); break; } return FALSE; } static void LanguageChanged(HWND hDlg) { HKL LangID = GetKeyboardLayout(0); if (LangID != oldLangID) { char Lang[3] = { 0 }; oldLangID = LangID; GetLocaleInfoA(MAKELCID((LOWORD(LangID) & 0xffffffff), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, Lang, 2); Lang[0] = toupper(Lang[0]); Lang[1] = tolower(Lang[1]); SetDlgItemTextA(hDlg, IDC_LANG, Lang); } } BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM) { DWORD dwWndPID; GetWindowThreadProcessId(hWnd, &dwWndPID); if ((g_dwMirandaPID == dwWndPID) && hWnd != g_hDlgPass && IsWindowVisible(hWnd)) { wchar_t szTemp[32]; GetClassName(hWnd, szTemp, 32); if (!mir_wstrcmp(szTemp, L"MirandaThumbsWnd")) { // hide floating contacts CallService("FloatingContacts/MainHideAllThumbs", 0, 0); g_bOldSetting |= OLD_FLTCONT; } else if (!mir_wstrcmp(szTemp, L"PopupWnd2")) // destroy opened popups PUDeletePopup(hWnd); else { uint32_t threadId = GetWindowThreadProcessId(hWnd, 0); if (threadId != GetCurrentThreadId()) return false; // add to list HWND_ITEM *node = new HWND_ITEM; node->hWnd = hWnd; node->next = g_pMirWnds; g_pMirWnds = node; ShowWindow(hWnd, SW_HIDE); } } return true; } wchar_t* GetDefStatusMsg(unsigned uStatus, const char* szProto) { return (wchar_t*)CallService(MS_AWAYMSG_GETSTATUSMSGW, uStatus, (LPARAM)szProto); } void SetStatus(const char* szProto, unsigned status, wchar_t *tszAwayMsg) { if (tszAwayMsg && CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_MODEMSGSEND) CallProtoService(szProto, PS_SETAWAYMSG, status, (LPARAM)tszAwayMsg); CallProtoService(szProto, PS_SETSTATUS, status, 0); } static int ChangeAllProtoStatuses(unsigned statusMode, wchar_t *msg) { for (int i = 0; i < protoCount; i++) { unsigned status = Proto_GetStatus(proto[i]->szModuleName); if ( (g_wMask & OPT_ONLINEONLY) ? // check "Change only if current status is Online" option ((status == ID_STATUS_ONLINE) || (status == ID_STATUS_FREECHAT)) // process only "online" and "free for chat" : ((status > ID_STATUS_OFFLINE) && (status < ID_STATUS_IDLE) && (status != ID_STATUS_INVISIBLE))) // process all existing statuses except for "invisible" & "offline" { if (g_wMask & OPT_SETONLINEBACK) { // need to save old statuses & status messages oldStatus[i] = status; if (ProtoServiceExists(proto[i]->szModuleName, PS_GETMYAWAYMSG)) oldStatusMsg[i] = (wchar_t*)CallProtoService(proto[i]->szModuleName, PS_GETMYAWAYMSG, 0, SGMA_UNICODE); else oldStatusMsg[i] = GetDefStatusMsg(status, proto[i]->szModuleName); } SetStatus(proto[i]->szModuleName, statusMode, msg); } } return 0; } static int BackAllProtoStatuses(void) { for (int i = 0; i < protoCount; i++) { if (oldStatus[i]) { SetStatus(proto[i]->szModuleName, oldStatus[i], oldStatusMsg[i]); if (oldStatusMsg[i]) { mir_free(oldStatusMsg[i]); oldStatusMsg[i] = nullptr; } oldStatus[i] = 0; } } return 0; } static void CreateTrayIcon(bool create) { NOTIFYICONDATA nim; DBVARIANT dbVar; if (!g_plugin.getWString("ToolTipText", &dbVar)) { wcsncpy_s(nim.szTip, dbVar.pwszVal, _TRUNCATE); db_free(&dbVar); } else wcsncpy_s(nim.szTip, L"Miranda NG", _TRUNCATE); nim.cbSize = sizeof(nim); nim.hWnd = g_hListenWindow; nim.uID = 100; nim.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; nim.hIcon = IcoLib_GetIcon("hidemim"); nim.uCallbackMessage = WM_USER + 24; Shell_NotifyIcon(create ? NIM_ADD : NIM_DELETE, &nim); g_TrayIcon = create; } static void RestoreOldSettings(void) { if (g_bOldSetting & OLD_POPUP) Popup_Enable(true); if (g_bOldSetting & OLD_SOUND) db_set_b(0, "Skin", "UseSound", 1); if (g_bOldSetting & OLD_FLTCONT) // show Floating contacts if needed { if (ServiceExists("FloatingContacts/MainHideAllThumbs")) CallService("FloatingContacts/MainHideAllThumbs", 0, 0); else db_set_b(0, "FloatingContacts", "HideAll", 0); } g_bOldSetting = 0; } LRESULT CALLBACK ListenWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_WTSSESSION_CHANGE: if (wParam == WTS_SESSION_LOCK && g_wMaskAdv & OPT_HIDEIFLOCK && !g_bWindowHidden) // Windows locked PostMessage(hWnd, WM_USER + 40, 0, 0); return 0; case WM_USER + 24: if (lParam == WM_LBUTTONDBLCLK) PostMessage(hWnd, WM_USER + 52, 0, 0); return 0; case WM_USER + 40: // hide { if (g_bWindowHidden || g_fOptionsOpen) // already hidden or in options, no hiding break; DWORD dwWndPID; // remember foreground window HWND hForegroundWnd = GetForegroundWindow(); GetWindowThreadProcessId(hForegroundWnd, &dwWndPID); if (g_dwMirandaPID == dwWndPID) hOldForegroundWindow = hForegroundWnd; EnumWindows(EnumWindowsProc, 0); if (g_wMask & OPT_CHANGESTATUS) // is this even needed? { uint8_t bReqMode = g_plugin.getByte("stattype", 2); unsigned uMode = (STATUS_ARR_TO_ID[bReqMode]); DBVARIANT dbVar; if (g_wMask & OPT_USEDEFMSG || g_plugin.getWString("statmsg", &dbVar)) { wchar_t *ptszDefMsg = GetDefStatusMsg(uMode, nullptr); ChangeAllProtoStatuses(uMode, ptszDefMsg); mir_free(ptszDefMsg); } else { if (ServiceExists(MS_VARS_FORMATSTRING)) { wchar_t *ptszParsed = variables_parse(dbVar.pwszVal, nullptr, 0); ChangeAllProtoStatuses(uMode, ptszParsed); mir_free(ptszParsed); } else ChangeAllProtoStatuses(uMode, dbVar.pwszVal); db_free(&dbVar); } } Clist_TrayIconDestroy(g_clistApi.hwndContactList); if (g_wMask & OPT_TRAYICON) CreateTrayIcon(true); // disable popups if (Popup_Enabled()) { // save current g_bOldSetting |= OLD_POPUP; Popup_Enable(false); } // disable sounds if ((g_wMask & OPT_DISABLESNDS) && db_get_b(0, "Skin", "UseSound", 1)) { // save current g_bOldSetting |= OLD_SOUND; db_set_b(0, "Skin", "UseSound", 0); } g_bWindowHidden = true; g_bOldSetting |= OLD_WASHIDDEN; g_plugin.setByte("OldSetting", g_bOldSetting); } return 0; case WM_USER + 52: // back { if (!g_bWindowHidden || g_fPassRequested) break; if (g_wMask & OPT_REQPASS) { //password request DBVARIANT dbVar; if (!g_plugin.getString("password", &dbVar)) { g_fPassRequested = true; strncpy(g_password, dbVar.pszVal, MAXPASSLEN); db_free(&dbVar); int res = DialogBox(g_plugin.getInst(), (MAKEINTRESOURCE(IDD_PASSDIALOGNEW)), GetForegroundWindow(), DlgStdInProc); g_fPassRequested = false; if (res != IDOK) return 0; } } if (g_wMask & OPT_CHANGESTATUS && g_wMask & OPT_SETONLINEBACK) // set back to some status BackAllProtoStatuses(); HWND_ITEM *pCurWnd = g_pMirWnds; while (pCurWnd != nullptr) { HWND_ITEM *pNextWnd = pCurWnd->next; wchar_t szTemp[32]; GetClassName(pCurWnd->hWnd, szTemp, 32); if (IsWindow(pCurWnd->hWnd) && mir_wstrcmp(szTemp, L"SysShadow") != 0) // precaution ShowWindow(pCurWnd->hWnd, SW_SHOW); delete pCurWnd; // bye-bye pCurWnd = pNextWnd; // traverse to next item } g_pMirWnds = nullptr; if (hOldForegroundWindow) { SetForegroundWindow(hOldForegroundWindow); hOldForegroundWindow = nullptr; } RestoreOldSettings(); if (g_TrayIcon) CreateTrayIcon(false); g_clistApi.pfnTrayIconInit(g_clistApi.hwndContactList); // force a redraw // should prevent drawing problems InvalidateRect(g_clistApi.hwndContactList, nullptr, true); UpdateWindow(g_clistApi.hwndContactList); PostMessage(hWnd, WM_MOUSEMOVE, 0, (LPARAM)MAKELONG(2, 2)); // reset core's IDLE g_bWindowHidden = false; g_plugin.setByte("OldSetting", 0); } return 0; } return(DefWindowProc(hWnd, uMsg, wParam, lParam)); } static int MsgWinOpening(WPARAM, LPARAM) // hiding new message windows { if (g_bWindowHidden) EnumWindows(EnumWindowsProc, 0); return 0; } VOID CALLBACK WinEventProc(HWINEVENTHOOK, DWORD event, HWND hwnd, LONG idObject, LONG, DWORD, DWORD) { if (g_bWindowHidden && idObject == OBJID_WINDOW && (event == EVENT_OBJECT_CREATE || event == EVENT_OBJECT_SHOW) && (IsWindowVisible(hwnd))) { if (hwnd == g_clistApi.hwndContactList) ShowWindow(hwnd, SW_HIDE); else EnumWindows(EnumWindowsProc, 0); } } INT_PTR BossKeyHideMiranda(WPARAM, LPARAM) // for service :) { PostMessage(g_hListenWindow, WM_USER + ((g_bWindowHidden) ? (52) : (40)), 0, 0); return 0; } static wchar_t* HotkeyVkToName(uint16_t vkKey) { static wchar_t buf[32] = { 0 }; uint32_t code = MapVirtualKey(vkKey, 0) << 16; switch (vkKey) { case 0: case VK_CONTROL: case VK_SHIFT: case VK_MENU: case VK_LWIN: case VK_RWIN: case VK_PAUSE: case VK_CANCEL: case VK_CAPITAL: return L""; case VK_DIVIDE: case VK_INSERT: case VK_HOME: case VK_PRIOR: case VK_DELETE: case VK_END: case VK_NEXT: case VK_LEFT: case VK_RIGHT: case VK_UP: case VK_DOWN: case VK_NUMLOCK: code |= (1UL << 24); } GetKeyNameText(code, buf, _countof(buf)); return buf; } static wchar_t* GetBossKeyText(void) { uint16_t wHotKey = db_get_w(0, "SkinHotKeys", "Hide/Show Miranda", HOTKEYCODE(HOTKEYF_CONTROL, VK_F12)); uint8_t key = LOBYTE(wHotKey); uint8_t shift = HIBYTE(wHotKey); static wchar_t buf[128]; mir_snwprintf(buf, L"%s%s%s%s%s", (shift & HOTKEYF_CONTROL) ? L"Ctrl + " : L"", (shift & HOTKEYF_SHIFT) ? L"Shift + " : L"", (shift & HOTKEYF_ALT) ? L"Alt + " : L"", (shift & HOTKEYF_EXT) ? L"Win + " : L"", HotkeyVkToName(key)); return buf; } static IconItem iconList[] = { { LPGEN("Hide Miranda NG"), "hidemim", IDI_DLGPASSWD } }; static int GenMenuInit(WPARAM, LPARAM) // Modify menu item text before to show the main menu { wchar_t buf[128]; mir_snwprintf(buf, L"%s [%s]", TranslateT("Hide"), GetBossKeyText()); Menu_ModifyItem(g_hMenuItem, buf); return 0; } static void BossKeyMenuItemInit(void) // Add menu item { CMenuItem mi(&g_plugin); SET_UID(mi, 0x42428114, 0xfac7, 0x44c2, 0x9a, 0x11, 0x18, 0xbe, 0x81, 0xd4, 0xa9, 0xe3); mi.flags = CMIF_UNICODE; mi.position = 2000100000; mi.hIcolibItem = IcoLib_GetIcon("hidemim"); mi.name.w = LPGENW("Hide"); mi.pszService = MS_BOSSKEY_HIDE; g_hMenuItem = Menu_AddMainMenuItem(&mi); Menu_ConfigureItem(g_hMenuItem, MCI_OPT_DISABLED, TRUE); HookEvent(ME_CLIST_PREBUILDMAINMENU, GenMenuInit); } static void RegisterCoreHotKeys(void) { HOTKEYDESC hotkey = {}; hotkey.pszName = "Hide/Show Miranda"; hotkey.szDescription.a = LPGEN("Hide/Show Miranda"); hotkey.szSection.a = "BossKey"; hotkey.pszService = MS_BOSSKEY_HIDE; hotkey.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL, VK_F12); g_plugin.addHotkey(&hotkey); } static int TopToolbarInit(WPARAM, LPARAM) { TTBButton ttb = {}; ttb.pszService = MS_BOSSKEY_HIDE; ttb.pszTooltipUp = ttb.name = LPGEN("Hide Miranda NG"); ttb.dwFlags = TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP; ttb.hIconHandleUp = iconList[0].hIcolib; g_plugin.addTTB(&ttb); return 0; } // Tabsrmm toolbar support static int TabsrmmButtonPressed(WPARAM, LPARAM lParam) { CustomButtonClickData *cbcd = (CustomButtonClickData *)lParam; if (!mir_strcmp(cbcd->pszModule, MODULENAME)) BossKeyHideMiranda(0, 0); return 0; } static int TabsrmmButtonsInit(WPARAM, LPARAM) { BBButton bbd = {}; bbd.pszModuleName = MODULENAME; bbd.dwDefPos = 5000; bbd.pwszTooltip = LPGENW("Hide Miranda NG"); bbd.bbbFlags = BBBF_ISRSIDEBUTTON | BBBF_CANBEHIDDEN; bbd.hIcon = iconList[0].hIcolib; g_plugin.addButton(&bbd); return 0; } static wchar_t* VariablesBossKey(ARGUMENTSINFO *ai) { if (ai->cbSize < sizeof(ARGUMENTSINFO)) return nullptr; if (ai->argc != 1) return nullptr; ai->flags |= AIF_DONTPARSE; return GetBossKeyText(); } static int EnumProtos(WPARAM, LPARAM) { Proto_EnumAccounts(&protoCount, &proto); delete[] oldStatus; delete[] oldStatusMsg; oldStatus = new unsigned[protoCount]; oldStatusMsg = new wchar_t*[protoCount]; for (int i = 0; i < protoCount; i++) { oldStatus[i] = 0; oldStatusMsg[i] = nullptr; } return 0; } static int MirandaLoaded(WPARAM, LPARAM) { g_wMask = g_plugin.getWord("optsmask", DEFAULTSETTING); RegisterCoreHotKeys(); g_hWinHook = SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_SHOW, nullptr, WinEventProc, GetCurrentProcessId(), 0, 0); HookEvent(ME_TTB_MODULELOADED, TopToolbarInit); HookEvent(ME_MSG_WINDOWEVENT, MsgWinOpening); HookEvent(ME_PROTO_ACCLISTCHANGED, EnumProtos); HookEvent(ME_MSG_BUTTONPRESSED, TabsrmmButtonPressed); HookTemporaryEvent(ME_MSG_TOOLBARLOADED, TabsrmmButtonsInit); GetWindowThreadProcessId(g_clistApi.hwndContactList, &g_dwMirandaPID); WNDCLASS winclass = { 0 }; winclass.lpfnWndProc = ListenWndProc; winclass.hInstance = g_plugin.getInst(); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszClassName = BOSSKEY_LISTEN_INFO; if (RegisterClass(&winclass)) { g_hListenWindow = CreateWindow(BOSSKEY_LISTEN_INFO, BOSSKEY_LISTEN_INFO, WS_POPUP, 0, 0, 5, 5, g_clistApi.hwndContactList, nullptr, g_plugin.getInst(), nullptr); WTSRegisterSessionNotification(g_hListenWindow, 0); } if (IsWinVerVistaPlus()) { hDwmApi = LoadLibrary(L"dwmapi.dll"); if (hDwmApi) dwmIsCompositionEnabled = (PFNDwmIsCompositionEnabled)GetProcAddress(hDwmApi, "DwmIsCompositionEnabled"); } BossKeyMenuItemInit(); // Register token for variables plugin if (ServiceExists(MS_VARS_REGISTERTOKEN)) { TOKENREGISTER tr = { 0 }; tr.cbSize = sizeof(TOKENREGISTER); tr.memType = TR_MEM_OWNER; tr.flags = TRF_FIELD | TRF_TCHAR | TRF_PARSEFUNC; tr.szTokenString.w = L"bosskeyname"; tr.parseFunctionW = VariablesBossKey; tr.szHelpText = LPGEN("BossKey") "\t" LPGEN("get the BossKey name"); CallService(MS_VARS_REGISTERTOKEN, 0, (LPARAM)&tr); } EnumProtos(0, 0); if (g_bOldSetting && !(g_wMaskAdv & OPT_RESTORE)) // Restore settings if Miranda was crushed or killed in hidden mode and "Restore hiding on startup after failure" option is disabled RestoreOldSettings(); if ((g_wMaskAdv & OPT_HIDEONSTART) || (g_wMaskAdv & OPT_RESTORE && g_bOldSetting)) BossKeyHideMiranda(0, 0); g_plugin.impl.m_timer.Start(2000); return 0; } int CMPlugin::Load() { g_wMaskAdv = g_plugin.getWord("optsmaskadv", 0); g_bOldSetting = g_plugin.getByte("OldSetting", 0); if ((g_bOldSetting & OLD_POPUP) && !(g_wMaskAdv & OPT_RESTORE)) // Restore popup settings if Miranda was crushed or killed in hidden mode and "Restore hiding on startup after failure" option is disabled { if (Popup_Enabled() == 0) Popup_Enable(true); } if (g_wMaskAdv & OPT_HIDEONSTART && Popup_Enabled()) // hack for disabling popup on startup if "Hide Miranda on startup" is enabled { g_bOldSetting |= OLD_POPUP; Popup_Enable(false); } g_plugin.registerIcon("BossKey", iconList); CreateServiceFunction(MS_BOSSKEY_HIDE, BossKeyHideMiranda); // Create service HookEvent(ME_SYSTEM_MODULESLOADED, MirandaLoaded); HookEvent(ME_OPT_INITIALISE, OptsDlgInit); return 0; } ///////////////////////////////////////////////////////////////////////////////////////// int CMPlugin::Unload() { impl.m_timer.Stop(); if (g_hWinHook != nullptr) UnhookWinEvent(g_hWinHook); if (g_hListenWindow) { WTSUnRegisterSessionNotification(g_hListenWindow); DestroyWindow(g_hListenWindow); } if (hDwmApi) FreeLibrary(hDwmApi); // free all sessions HWND_ITEM *pTemp = g_pMirWnds; while (pTemp != nullptr) { HWND_ITEM *pNext = pTemp->next; delete pTemp; pTemp = pNext; } delete[] oldStatus; delete[] oldStatusMsg; return 0; }