int cliTrayIconPauseAutoHide(WPARAM, LPARAM) { if (db_get_b(NULL, "CList", "AutoHide", SETTING_AUTOHIDE_DEFAULT)) { if (GetActiveWindow() != pcli->hwndContactList && GetWindow(GetParent(GetActiveWindow()), GW_OWNER) != pcli->hwndContactList) { KillTimer(NULL, autoHideTimerId); autoHideTimerId = CLUI_SafeSetTimer(NULL, 0, 1000 * db_get_w(NULL, "CList", "HideTime", SETTING_HIDETIME_DEFAULT), TrayIconAutoHideTimer); } } return 0; }
INT_PTR cli_TrayIconProcessMessage(WPARAM wParam, LPARAM lParam) { MSG *msg = (MSG*)wParam; switch (msg->message) { case WM_EXITMENULOOP: if (pcli->bTrayMenuOnScreen) pcli->bTrayMenuOnScreen = FALSE; break; case TIM_CALLBACK: if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && msg->lParam == WM_LBUTTONDOWN && !db_get_b(NULL, "CList", "Tray1Click", SETTING_TRAY1CLICK_DEFAULT)) { POINT pt; HMENU hMenu = Menu_GetStatusMenu(); g_mutex_bOnTrayRightClick = 1; IS_WM_MOUSE_DOWN_IN_TRAY = 1; SetForegroundWindow(msg->hwnd); SetFocus(msg->hwnd); GetCursorPos(&pt); pcli->bTrayMenuOnScreen = TRUE; TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, msg->hwnd, NULL); PostMessage(msg->hwnd, WM_NULL, 0, 0); g_mutex_bOnTrayRightClick = 0; IS_WM_MOUSE_DOWN_IN_TRAY = 0; } else if (msg->lParam == WM_MBUTTONDOWN || msg->lParam == WM_LBUTTONDOWN || msg->lParam == WM_RBUTTONDOWN) { IS_WM_MOUSE_DOWN_IN_TRAY = 1; } else break; *((LRESULT*)lParam) = 0; return TRUE; case WM_ACTIVATE: SetCursor(LoadCursor(NULL, IDC_ARROW)); { HWND h1 = (HWND)msg->lParam; HWND h2 = h1 ? GetParent(h1) : NULL; if (db_get_b(NULL, "CList", "AutoHide", SETTING_AUTOHIDE_DEFAULT)) { if (LOWORD(msg->wParam) == WA_INACTIVE && h2 != pcli->hwndContactList) autoHideTimerId = CLUI_SafeSetTimer(NULL, 0, 1000 * db_get_w(NULL, "CList", "HideTime", SETTING_HIDETIME_DEFAULT), TrayIconAutoHideTimer); else { KillTimer(NULL, autoHideTimerId); autoHideTimerId = 0; } } else if (autoHideTimerId) { KillTimer(NULL, autoHideTimerId); autoHideTimerId = 0; } } return FALSE; //to avoid autohideTimer in core } return corecli.pfnTrayIconProcessMessage(wParam, lParam); }
static void gtaThreadProc(void*) { Netlib_Logf(NULL, "GTA thread start"); SHORTDATA data = { 0 }; while (!MirandaExiting()) { Sync(CLUI_SyncGetShortData, (WPARAM)pcli->hwndContactTree, (LPARAM)&data); while (true) { if (MirandaExiting()) goto LBL_Exit; SleepEx(0, TRUE); //1000 contacts per second GTACHAINITEM mpChain = { 0 }; SHORTDATA dat2 = { 0 }; if (!gtaGetItem(&mpChain)) break; SHORTDATA *dat; if (mpChain.dat == NULL || (!IsBadReadPtr(mpChain.dat, sizeof(*mpChain.dat)) && mpChain.dat->hWnd == data.hWnd)) dat = &data; else { Sync(CLUI_SyncGetShortData, (WPARAM)mpChain.dat->hWnd, (LPARAM)&dat2); dat = &dat2; } if (MirandaExiting()) goto LBL_Exit; ClcCacheEntry cacheEntry; memset(&cacheEntry, 0, sizeof(cacheEntry)); cacheEntry.hContact = mpChain.hContact; if (!Sync(CLUI_SyncGetPDNCE, (WPARAM)0, (LPARAM)&cacheEntry)) { Cache_GetSecondLineText(dat, &cacheEntry); Cache_GetThirdLineText(dat, &cacheEntry); Sync(CLUI_SyncSetPDNCE, (WPARAM)CCI_LINES, (LPARAM)&cacheEntry); CListSettings_FreeCacheItemData(&cacheEntry); } KillTimer(dat->hWnd, TIMERID_INVALIDATE_FULL); CLUI_SafeSetTimer(dat->hWnd, TIMERID_INVALIDATE_FULL, 500, NULL); } WaitForSingleObjectEx(hgtaWakeupEvent, INFINITE, TRUE); ResetEvent(hgtaWakeupEvent); } LBL_Exit: CloseHandle(hgtaWakeupEvent); hgtaWakeupEvent = NULL; g_hGetTextAsyncThread = NULL; Netlib_Logf(NULL, "GTA thread end"); }
int cliTrayIconInit(HWND hwnd) { BYTE Mode; if (pcli->trayIconCount != 0) return 0; if (TimerID) { KillTimer(NULL, TimerID); TimerID = 0; } // Присутствуют ли в базе новые настройки? Если да, то обновление не нужно. if (-1 == db_get_b(NULL, "CList", "tiModeS", -1)) SettingsMigrate(); // Нужно узнать количество годных аккаунтов и неодинаковость их статусов. bool bDiffers; pcli->trayIconCount = GetGoodAccNum(&bDiffers, NULL); // Если таковых аккаунтов не нашлось вообще, то будем показывать основную иконку Миранды. if (!pcli->trayIconCount) { pcli->trayIconCount = 1; pcli->trayIcon = (trayIconInfo_t*)mir_calloc(sizeof(trayIconInfo_t) * pcli->trayIconCount); pcli->pfnTrayIconAdd(hwnd, NULL, NULL, CListTray_GetGlobalStatus(0, 0)); OldMode = TRAY_ICON_MODE_GLOBAL; return 0; } if (!bDiffers) // all equal OldMode = Mode = db_get_b(NULL, "CList", "tiModeS", TRAY_ICON_MODE_GLOBAL); else OldMode = Mode = db_get_b(NULL, "CList", "tiModeV", TRAY_ICON_MODE_GLOBAL); // Некоторые режимы всегда показывают единственную иконку. if (Mode < 8) pcli->trayIconCount = 1; pcli->trayIcon = (trayIconInfo_t*)mir_calloc(sizeof(trayIconInfo_t) * pcli->trayIconCount); // Добавляем иконки. switch (Mode) { case TRAY_ICON_MODE_GLOBAL: pcli->pfnTrayIconAdd(hwnd, NULL, NULL, CListTray_GetGlobalStatus(0, 0)); break; case TRAY_ICON_MODE_ACC: { ptrA szProto(db_get_sa(NULL, "CList", (!bDiffers) ? "tiAccS" : "tiAccV")); if (!szProto) break; PROTOACCOUNT *pa = Proto_GetAccount(szProto); if (!pa || !pa->ppro) pcli->pfnTrayIconAdd(hwnd, NULL, NULL, CListTray_GetGlobalStatus(0, 0)); else pcli->pfnTrayIconAdd(hwnd, pa->szModuleName, NULL, pa->ppro->m_iStatus); } break; case TRAY_ICON_MODE_CYCLE: pcli->pfnTrayIconAdd(hwnd, NULL, NULL, CListTray_GetGlobalStatus(0, 0)); pcli->cycleStep = 0; cliTrayCycleTimerProc(0, 0, 0, 0); // force icon update // Не сохраняем ID таймера в pcli, чтобы fnTrayIconUpdateBase не убивала его. TimerID = CLUI_SafeSetTimer(NULL, 0, db_get_w(NULL, "CList", "CycleTime", SETTING_CYCLETIME_DEFAULT) * 1000, cliTrayCycleTimerProc); break; case TRAY_ICON_MODE_ALL: PROTOACCOUNT **acc; int AccNum, i; Proto_EnumAccounts(&AccNum, &acc); for (i = AccNum; i--;) { if (!acc[i]->bIsVirtual && acc[i]->bIsVisible && !acc[i]->bDynDisabled && acc[i]->ppro) pcli->pfnTrayIconAdd(hwnd, acc[i]->szModuleName, NULL, acc[i]->ppro->m_iStatus); } break; } return 0; }
static int gtaThreadProc(void * lpParam) { BOOL exit=FALSE; HWND hwnd=pcli->hwndContactList; struct SHORTDATA data={0}; struct SHORTDATA * dat; while (!MirandaExiting()) { Sync(CLUI_SyncGetShortData,(WPARAM)pcli->hwndContactTree,(LPARAM)&data); do { if (!MirandaExiting()) SleepEx(0,TRUE); //1000 contacts per second if (MirandaExiting()) { g_dwGetTextAsyncThreadID=0; return 0; } else { GTACHAINITEM mpChain={0}; struct SHORTDATA dat2={0}; if (!gtaGetItem(&mpChain)) break; if (mpChain.dat==NULL || (!IsBadReadPtr(mpChain.dat,sizeof(mpChain.dat)) && mpChain.dat->hWnd==data.hWnd)) dat=&data; else { Sync(CLUI_SyncGetShortData,(WPARAM)mpChain.dat->hWnd,(LPARAM)&dat2); dat=&dat2; } if (!MirandaExiting()) { displayNameCacheEntry cacheEntry; memset( &cacheEntry, 0, sizeof(cacheEntry)); cacheEntry.m_cache_hContact=mpChain.hContact; if (!Sync(CLUI_SyncGetPDNCE, (WPARAM) 0,(LPARAM)&cacheEntry)) { if (!MirandaExiting()) Cache_GetSecondLineText(dat, &cacheEntry); if (!MirandaExiting()) Cache_GetThirdLineText(dat, &cacheEntry); if (!MirandaExiting()) Sync(CLUI_SyncSetPDNCE, (WPARAM) CCI_LINES,(LPARAM)&cacheEntry); CListSettings_FreeCacheItemData(&cacheEntry); } } else { g_dwGetTextAsyncThreadID=0; return 0; } KillTimer(dat->hWnd,TIMERID_INVALIDATE_FULL); CLUI_SafeSetTimer(dat->hWnd,TIMERID_INVALIDATE_FULL,500,NULL); } } while (!exit); WaitForSingleObjectEx(hgtaWakeupEvent, INFINITE, FALSE ); ResetEvent(hgtaWakeupEvent); } g_dwGetTextAsyncThreadID=0; return 1; }