From 3b4342ead0909ee9f5d515db932272f901708a3a Mon Sep 17 00:00:00 2001 From: Vlad Mironov Date: Thu, 21 Feb 2013 15:59:28 +0000 Subject: =?UTF-8?q?=D1=81-plus-plusification?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.miranda-ng.org/main/trunk@3671 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/TrafficCounter/src/TrafficCounter.cpp | 1724 +++++++++++++++++++++++++ 1 file changed, 1724 insertions(+) create mode 100644 plugins/TrafficCounter/src/TrafficCounter.cpp (limited to 'plugins/TrafficCounter/src/TrafficCounter.cpp') diff --git a/plugins/TrafficCounter/src/TrafficCounter.cpp b/plugins/TrafficCounter/src/TrafficCounter.cpp new file mode 100644 index 0000000000..8a9611328e --- /dev/null +++ b/plugins/TrafficCounter/src/TrafficCounter.cpp @@ -0,0 +1,1724 @@ +/* +Traffic Counter plugin for Miranda IM +Copyright 2007-2012 Mironych. + +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 "commonheaders.h" +#include "m_skin_eng.h" +#include "m_tipper.h" + +/*-------------------------------------------------------------------------------------------------------------------*/ +//GLOBAL +/*-------------------------------------------------------------------------------------------------------------------*/ +uTCFLAGS unOptions; +PROTOLIST *ProtoList; // Данные обо всех аккаунтах. +PROTOLIST OverallInfo; // Суммарные данные по видимым аккаунтам. +int NumberOfAccounts; +extern WORD Stat_SelAcc; +HWND TrafficHwnd; +DWORD mirandaVer; + +HINSTANCE hInst; + +int hLangpack = 0; // Поддержка плагинозависимого перевода. + +TCHAR* TRAFFIC_COUNTER_WINDOW_CLASS = _T("TrafficCounterWnd"); + +/*-------------------------------------------------------------------------------------------------------------------*/ +//TRAFFIC COUNTER +/*-------------------------------------------------------------------------------------------------------------------*/ +OPTTREE_OPTION *pOptions; // Через этот указатель модуль opttree.c может добраться до списка опций. +WORD notify_send_size = 0; +WORD notify_recv_size = 0; +// +// Цвет шрифта и фона +COLORREF Traffic_BkColor,Traffic_FontColor; + +//notify +int Traffic_PopupBkColor; +int Traffic_PopupFontColor; +char Traffic_Notify_time_value; +short int Traffic_Notify_size_value; +char Traffic_PopupTimeoutDefault; +char Traffic_PopupTimeoutValue; + +unsigned short int Traffic_LineHeight; +// +TCHAR Traffic_CounterFormat[512]; +TCHAR Traffic_TooltipFormat[512]; +// +HANDLE Traffic_FrameID = NULL; + +char Traffic_AdditionSpace; + +HANDLE h_OptInit; +HANDLE h_ModulesLoaded; +HANDLE h_SystemShutDown; +HANDLE h_OnRecv, h_OnSend; +HANDLE h_OnAccListChange; +HANDLE h_FontReload; + +HFONT Traffic_h_font = NULL; +HMENU TrafficPopupMenu = NULL; +HGENMENU hTrafficMainMenuItem = NULL; + +/*-------------------------------------------------------------------------------------------------------------------*/ +//TIME COUNTER +/*-------------------------------------------------------------------------------------------------------------------*/ +static HANDLE h_AckHook; +BYTE online_count = 0; + +/*-------------------------------------------------------------------------------------------------------------------*/ +//font service support +/*-------------------------------------------------------------------------------------------------------------------*/ +int TrafficFontHeight = 0; +FontIDT TrafficFontID; +ColourIDT TrafficBackgroundColorID; + +//--------------------------------------------------------------------------------------------- +// Для ToolTip +//--------------------------------------------------------------------------------------------- +BOOL TooltipShowing; +POINT TooltipPosition; + +// Вспомогательные переменные чтобы заставить работать ключевой цвет +BOOL UseKeyColor; +COLORREF KeyColor; + +// Внутренние функции модуля. +void Traffic_AddMainMenuItem(void); + + +PLUGININFOEX pluginInfoEx = +{ + sizeof(PLUGININFOEX), + "Traffic Counter", + 0, // Начиная с версии ядра 0.92.1.0 поле с версией не используется. + "Adding traffic and time counters.", + "Ghost, Mironych", + "", + "© 2002-2006 Ghost, © 2007-2012 Mironych", + "", + UNICODE_AWARE, + {0x82181510, 0x5dfa, 0x49d7, { 0xb4, 0x69, 0x33, 0x87, 0x1e, 0x2a, 0xe8, 0xb5}} // {82181510-5DFA-49d7-B469-33871E2AE8B5} +}; + +extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion) +{ + mirandaVer = mirandaVersion; + return &pluginInfoEx; +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst = hinstDLL; + DisableThreadLibraryCalls(hInst); + + return TRUE; +} + +extern "C" int __declspec(dllexport) Load(void) +{ + if (mirandaVer < PLUGIN_MAKE_VERSION(0, 92, 2, 0)) return -1; + + // Получаем дескриптор языкового пакета. + mir_getLP(&pluginInfoEx); + + h_OptInit = HookEvent(ME_OPT_INITIALISE,TrafficCounterOptInitialise); + h_ModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED,TrafficCounterModulesLoaded); + h_AckHook = HookEvent(ME_PROTO_ACK,ProtocolAckHook); + h_OnAccListChange = HookEvent(ME_PROTO_ACCLISTCHANGED, OnAccountsListChange); + h_SystemShutDown = HookEvent(ME_SYSTEM_OKTOEXIT, TrafficCounterShutdown); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + return 0; +} + +int TrafficCounterShutdown(WPARAM wParam, LPARAM lParam) +{ + KillTimer(TrafficHwnd, TIMER_REDRAW); + KillTimer(TrafficHwnd, TIMER_NOTIFY_TICK); + + // Отказываемся от обработки событий. + UnhookEvent(h_FontReload); + UnhookEvent(h_OnAccListChange); + UnhookEvent(h_AckHook); + UnhookEvent(h_ModulesLoaded); + UnhookEvent(h_OnRecv); + UnhookEvent(h_OnSend); + UnhookEvent(h_OptInit); + UnhookEvent(h_SystemShutDown); + + SaveSettings(0); + + // Удаляем пункт главного меню. + if (hTrafficMainMenuItem) + { + CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)hTrafficMainMenuItem, 0); + hTrafficMainMenuItem = NULL; + } + // Удаляем контекстное меню. + if (TrafficPopupMenu) + { + DestroyMenu(TrafficPopupMenu); + TrafficPopupMenu = NULL; + } + // Разрегистрируем процедуру отрисовки фрейма. + CallService(MS_SKINENG_REGISTERPAINTSUB, (WPARAM)TrafficHwnd, (LPARAM)NULL); + // Удаляем фрейм. + if( (ServiceExists(MS_CLIST_FRAMES_REMOVEFRAME)) && Traffic_FrameID ) + { + CallService(MS_CLIST_FRAMES_REMOVEFRAME, (WPARAM)Traffic_FrameID, 0); + Traffic_FrameID = NULL; + } + // Разрегистрируем горячую клавишу. + CallService(MS_HOTKEY_UNREGISTER, 0, (LPARAM)"TC_Show_Hide"); + // Разрегистрируем функцию переключения видимости окна. + DestroyServiceFunction(MenuCommand_TrafficShowHide); + // Удаляем шрифт. + if (Traffic_h_font) + { + DeleteObject(Traffic_h_font); + Traffic_h_font = NULL; + } + + // Убиваем все рабочие данные. + DestroyProtocolList(); + + return 0; +} + +int TrafficCounterModulesLoaded(WPARAM wParam,LPARAM lParam) +{ + DBVARIANT dbv; + + CreateProtocolList(); + + // Читаем флаги + unOptions.Flags = db_get_dw(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_WHAT_DRAW, 0x0882); + Stat_SelAcc = db_get_w(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_STAT_ACC_OPT, 0x01); + + //settings for notification + Traffic_PopupBkColor = db_get_dw(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_BKCOLOR,RGB(200,255,200)); + Traffic_PopupFontColor = db_get_dw(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_FONTCOLOR,RGB(0,0,0)); + // + Traffic_Notify_time_value = db_get_b(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_NOTIFY_TIME_VALUE,10); + // + Traffic_Notify_size_value = db_get_w(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_NOTIFY_SIZE_VALUE,100); + // + //popup timeout + Traffic_PopupTimeoutDefault = db_get_b(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_TIMEOUT_DEFAULT,1); + Traffic_PopupTimeoutValue = db_get_b(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_TIMEOUT_VALUE,5); + + // Формат счётчика для каждого активного протокола + if (db_get_ts(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_COUNTER_FORMAT, &dbv) == 0) + { + if(lstrlen(dbv.ptszVal) > 0) + lstrcpyn(Traffic_CounterFormat, dbv.ptszVal, SIZEOF(Traffic_CounterFormat)); + // + db_free(&dbv); + } + else //defaults here + { + _tcscpy(Traffic_CounterFormat, _T("{I4}\x0D\x0A\x0A\ +{R65}?tc_GetTraffic(%extratext%,now,sent,d)\x0D\x0A\x0A\ +{R115}?tc_GetTraffic(%extratext%,now,received,d)\x0D\x0A\x0A\ +{R165}?tc_GetTraffic(%extratext%,total,both,d)\x0D\x0A\x0A\ +{L180}?if3(?tc_GetTime(%extratext%,now,hh:mm:ss),)\x0D\x0A\x0A\ +{L230}?if3(?tc_GetTime(%extratext%,total,d hh:mm),)")); + } + + // Формат всплывающих подсказок + if (db_get_ts(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_TOOLTIP_FORMAT, &dbv) == 0) + { + if(lstrlen(dbv.ptszVal) > 0) + lstrcpyn(Traffic_TooltipFormat, dbv.ptszVal, SIZEOF(Traffic_TooltipFormat)); + // + db_free(&dbv); + } + else //defaults here + { + _tcscpy(Traffic_TooltipFormat, _T("Traffic Counter")); + } + + Traffic_AdditionSpace = db_get_b(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_ADDITION_SPACE, 0); + + // Счётчик времени онлайна + OverallInfo.Total.Timer = db_get_dw(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_TOTAL_ONLINE_TIME, 0); + + //register traffic font + TrafficFontID.cbSize = sizeof(FontIDT); + _tcscpy(TrafficFontID.group, LPGENT("Traffic counter")); + _tcscpy(TrafficFontID.name, LPGENT("Font")); + strcpy(TrafficFontID.dbSettingsGroup, TRAFFIC_SETTINGS_GROUP); + strcpy(TrafficFontID.prefix, "Font"); + TrafficFontID.flags = FIDF_DEFAULTVALID | FIDF_SAVEPOINTSIZE; + TrafficFontID.deffontsettings.charset = DEFAULT_CHARSET; + TrafficFontID.deffontsettings.colour = GetSysColor(COLOR_BTNTEXT); + TrafficFontID.deffontsettings.size = 12; + TrafficFontID.deffontsettings.style = 0; + _tcscpy(TrafficFontID.deffontsettings.szFace, _T("Arial")); + TrafficFontID.order = 0; + FontRegisterT(&TrafficFontID); + + // Регистрируем цвет фона + TrafficBackgroundColorID.cbSize = sizeof(ColourIDT); + _tcscpy(TrafficBackgroundColorID.group, LPGENT("Traffic counter")); + _tcscpy(TrafficBackgroundColorID.name, LPGENT("Font")); + strcpy(TrafficBackgroundColorID.dbSettingsGroup, TRAFFIC_SETTINGS_GROUP); + strcpy(TrafficBackgroundColorID.setting, "FontBkColor"); + TrafficBackgroundColorID.defcolour = GetSysColor(COLOR_BTNFACE); + ColourRegisterT(&TrafficBackgroundColorID); + + h_FontReload = HookEvent(ME_FONT_RELOAD, UpdateFonts); + + // Добавляем поддержку плагина Variables + RegisterVariablesTokens(); + + CreateServiceFunction("TrafficCounter/ShowHide", MenuCommand_TrafficShowHide); + // Регистрируем горячую клавишу для показа/скрытия фрейма + { + HOTKEYDESC hkd = {0}; + hkd.cbSize = sizeof(hkd); + hkd.DefHotKey = HOTKEYCODE(HOTKEYF_CONTROL|HOTKEYF_SHIFT,'T'); + hkd.pszSection = "Traffic Counter"; + hkd.pszDescription = "Show/Hide frame"; + hkd.pszName = "TC_Show_Hide"; + hkd.pszService = "TrafficCounter/ShowHide"; + Hotkey_Register(&hkd); + } + + // Добавляем пункт в главное меню. + if (unOptions.ShowMainMenuItem) + Traffic_AddMainMenuItem(); + + // Создаём контекстное меню. + if (TrafficPopupMenu = CreatePopupMenu()) + { + AppendMenu(TrafficPopupMenu,MF_STRING,POPUPMENU_HIDE,TranslateT("Hide traffic window")); + AppendMenu(TrafficPopupMenu,MF_STRING,POPUPMENU_CLEAR_NOW,TranslateT("Clear the current (Now:) value")); + } + + // Регистрируем обработчики событий Netlib + h_OnRecv = HookEvent(ME_NETLIB_FASTRECV, TrafficRecv); + h_OnSend = HookEvent(ME_NETLIB_FASTSEND, TrafficSend); + + CreateTrafficWindow((HWND)CallService(MS_CLUI_GETHWND, 0, 0)); + UpdateFonts(0, 0); //Load and create fonts here + + return 0; +} + +static INT_PTR CALLBACK DlgProcPopupsTraffic(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + // + CheckDlgButton(hwndDlg,IDC_NOTIFYSIZE,(unOptions.NotifyBySize) ? BST_CHECKED : BST_UNCHECKED); + SetDlgItemInt(hwndDlg,IDC_ENOTIFYSIZE,Traffic_Notify_size_value,0); + SendDlgItemMessage(hwndDlg,IDC_ENOTIFYSIZE,EM_LIMITTEXT,4,0); + if (!unOptions.NotifyBySize) EnableWindow(GetDlgItem(hwndDlg,IDC_ENOTIFYSIZE),0); + CheckDlgButton(hwndDlg,IDC_NOTIFYTIME,(unOptions.NotifyByTime) ? BST_CHECKED : BST_UNCHECKED); + SetDlgItemInt(hwndDlg,IDC_ENOTIFYTIME,Traffic_Notify_time_value,0); + SendDlgItemMessage(hwndDlg,IDC_ENOTIFYTIME,EM_LIMITTEXT,2,0); + if (!unOptions.NotifyByTime) EnableWindow(GetDlgItem(hwndDlg,IDC_ENOTIFYTIME),0); + //colors + SendDlgItemMessage(hwndDlg,IDC_COLOR1,CPM_SETDEFAULTCOLOUR,0,RGB(200,255,200)); + SendDlgItemMessage(hwndDlg,IDC_COLOR1,CPM_SETCOLOUR,0,Traffic_PopupBkColor); + SendDlgItemMessage(hwndDlg,IDC_COLOR2,CPM_SETDEFAULTCOLOUR,0,RGB(0,0,0)); + SendDlgItemMessage(hwndDlg,IDC_COLOR2,CPM_SETCOLOUR,0,Traffic_PopupFontColor); + //timeout + CheckDlgButton(hwndDlg,IDC_RADIO_FROMPOPUP,(Traffic_PopupTimeoutDefault != 0) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg,IDC_RADIO_CUSTOM,(Traffic_PopupTimeoutDefault == 0) ? BST_CHECKED : BST_UNCHECKED); + EnableWindow(GetDlgItem(hwndDlg,IDC_POPUP_TIMEOUT),Traffic_PopupTimeoutDefault == 0); + SetDlgItemInt(hwndDlg,IDC_POPUP_TIMEOUT,Traffic_PopupTimeoutValue,0); + SendDlgItemMessage(hwndDlg,IDC_POPUP_TIMEOUT,EM_LIMITTEXT,2,0); + + return 0; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_NOTIFYSIZE: + EnableWindow(GetDlgItem(hwndDlg,IDC_ENOTIFYSIZE),IsDlgButtonChecked(hwndDlg,IDC_NOTIFYSIZE)); + break; + + case IDC_ENOTIFYSIZE: + if (HIWORD(wParam)!=EN_CHANGE || (HWND)lParam!=GetFocus()) return 0; + break; + + case IDC_NOTIFYTIME: + EnableWindow(GetDlgItem(hwndDlg,IDC_ENOTIFYTIME),IsDlgButtonChecked(hwndDlg,IDC_NOTIFYTIME)); + break; + + case IDC_ENOTIFYTIME: + if (HIWORD(wParam)!=EN_CHANGE || (HWND)lParam!=GetFocus()) return 0; + break; + + case IDC_RESETCOLORS: + SendDlgItemMessage(hwndDlg,IDC_COLOR1,CPM_SETDEFAULTCOLOUR,0,RGB(200,255,200)); + SendDlgItemMessage(hwndDlg,IDC_COLOR1,CPM_SETCOLOUR,0,RGB(200,255,200)); + SendDlgItemMessage(hwndDlg,IDC_COLOR2,CPM_SETDEFAULTCOLOUR,0,RGB(0,0,0)); + SendDlgItemMessage(hwndDlg,IDC_COLOR2,CPM_SETCOLOUR,0,RGB(0,0,0)); + break; + + case IDC_RADIO_FROMPOPUP: + case IDC_RADIO_CUSTOM: + EnableWindow(GetDlgItem(hwndDlg,IDC_POPUP_TIMEOUT),IsDlgButtonChecked(hwndDlg,IDC_RADIO_CUSTOM)); + break; + + case IDC_TEST: + NotifyOnRecv(); + NotifyOnSend(); + return 0; + + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + return 0; + + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) + { + case 0: + if (((LPNMHDR)lParam)->code == PSN_APPLY ) { + unOptions.NotifyBySize = IsDlgButtonChecked(hwndDlg,IDC_NOTIFYSIZE); + Traffic_Notify_size_value = GetDlgItemInt(hwndDlg,IDC_ENOTIFYSIZE,NULL,0); + unOptions.NotifyByTime = IsDlgButtonChecked(hwndDlg,IDC_NOTIFYTIME); + Traffic_Notify_time_value = GetDlgItemInt(hwndDlg,IDC_ENOTIFYTIME,NULL,0); + // + Traffic_PopupBkColor = SendDlgItemMessage(hwndDlg,IDC_COLOR1,CPM_GETCOLOUR,0,0); + Traffic_PopupFontColor = SendDlgItemMessage(hwndDlg,IDC_COLOR2,CPM_GETCOLOUR,0,0); + // + Traffic_PopupTimeoutDefault = IsDlgButtonChecked(hwndDlg,IDC_RADIO_FROMPOPUP); + if (Traffic_PopupTimeoutDefault == 0) Traffic_PopupTimeoutValue = GetDlgItemInt(hwndDlg,IDC_POPUP_TIMEOUT,NULL,0); + // + UpdateNotifyTimer(); + return TRUE; + } + break; + } + break; + } + return 0; +} + +static INT_PTR CALLBACK DlgProcTCOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD i, j, l; + BOOL result; + static BYTE Initialized = 0; + static WORD optionCount = 0; + static OPTTREE_OPTION options[] = + { + {0, LPGENT("Display/") LPGENT("Icon"), + OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, "DrawProtoIcon"}, + {0, LPGENT("Display/") LPGENT("Account name"), + OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, "DrawProtoName"}, + {0, LPGENT("Display/") LPGENT("Current traffic"), + OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, "DrawCurrentTraffic"}, + {0, LPGENT("Display/") LPGENT("Total traffic"), + OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, "DrawTotalTraffic"}, + {0, LPGENT("Display/") LPGENT("Current online"), + OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, "DrawCurrentTime"}, + {0, LPGENT("Display/") LPGENT("Total online"), + OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, "DrawTotalTime"}, + {0, LPGENT("General/") LPGENT("Draw frame as skin element"), + OPTTREE_CHECK, 1, NULL, "DrawFrmAsSkin"}, + {0, LPGENT("General/") LPGENT("Show tooltip in traffic window"), + OPTTREE_CHECK, 1, NULL, "ShowTooltip"}, + {0, LPGENT("General/") LPGENT("\"Toggle traffic counter\" in main menu"), + OPTTREE_CHECK, 1, NULL, "ShowMainMenuItem"}, + // Резервируем место под активные и видимые протоколы + // Максимум 16 позиций видимых и 16 активных + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, NULL, OPTTREE_CHECK, OPTTREE_INVISIBLE, NULL, NULL}, + {0, LPGENT("Visible accounts/") LPGENT("Summary traffic for visible accounts"), + OPTTREE_CHECK, 1, NULL, "ShowSummary"}, + {0, LPGENT("Visible accounts/") LPGENT("Overall traffic"), + OPTTREE_CHECK, 1, NULL, "ShowOverall"}, + }; + + if (!Initialized) + { + pOptions = options; + optionCount = SIZEOF(options); + // Если нет Variables, активируем галочки для старого метода рисования + if (!ServiceExists(MS_VARS_FORMATSTRING)) + { + for (i = 0; i < 8; i++) options[i].dwFlag = 1; + } + + // Флажки для видимости аккаунтов создаются в любом случае. + for (i = j = 0; (j < NumberOfAccounts) && (i < optionCount) ; i++) + if ((options[i].dwFlag & OPTTREE_INVISIBLE) && !options[i].szSettingName) + { + options[i].szSettingName = (char*)mir_alloc(1 + strlen(ProtoList[j].name)); + strcpy(options[i].szSettingName, ProtoList[j].name); + l = 20 + _tcslen(ProtoList[j].tszAccountName); + options[i].szOptionName = (TCHAR*)mir_alloc(sizeof(TCHAR) * l); + mir_sntprintf(options[i].szOptionName, + l, + _T("Visible accounts/%s"), + ProtoList[j].tszAccountName); + options[i].dwFlag = (ProtoList[j++].Enabled ? 1 : OPTTREE_INVISIBLE) + | OPTTREE_NOTRANSLATE; + } + Initialized = 1; + } + + if (OptTree_ProcessMessage(hwndDlg, msg, wParam, lParam, &result, IDC_APPEARANCEOPTIONS, options, optionCount)) + return result; + + switch (msg) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + + SendDlgItemMessage(hwndDlg, IDC_SPIN1, UDM_SETRANGE, 0, MAKELONG(15, 0)); + SendDlgItemMessage(hwndDlg, IDC_SPIN1, UDM_SETPOS, 0, GetDlgItemInt(hwndDlg, IDC_EDIT_SPACE, NULL, FALSE)); + + //show/hide button + SetDlgItemText(hwndDlg,IDC_BSHOWHIDE,(IsWindowVisible(TrafficHwnd) != 0)? TranslateT("Hide now") : TranslateT("Show now")); + + // Строки формата для счётчиков + EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_COUNTER_FORMAT),ServiceExists(MS_VARS_FORMATSTRING)); + SetWindowText(GetDlgItem(hwndDlg, IDC_EDIT_COUNTER_FORMAT), Traffic_CounterFormat); + + // Формат всплывающей подсказки + EnableWindow(GetDlgItem(hwndDlg,IDC_EDIT_TOOLTIP_FORMAT), + ServiceExists("mToolTip/ShowTipW") || ServiceExists("mToolTip/ShowTip")); + SetWindowText(GetDlgItem(hwndDlg, IDC_EDIT_TOOLTIP_FORMAT), Traffic_TooltipFormat); + + // Display traffic for current... + SendDlgItemMessage(hwndDlg, IDC_COMBO_AUTO_CLEAR, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Day")); + SendDlgItemMessage(hwndDlg, IDC_COMBO_AUTO_CLEAR, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Week")); + SendDlgItemMessage(hwndDlg, IDC_COMBO_AUTO_CLEAR, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Month")); + SendDlgItemMessage(hwndDlg, IDC_COMBO_AUTO_CLEAR, CB_INSERTSTRING, -1, (LPARAM)TranslateT("Year")); + SendDlgItemMessage(hwndDlg, IDC_COMBO_AUTO_CLEAR, CB_SETCURSEL, unOptions.PeriodForShow, 0); + + // Интервал между строками + SetDlgItemInt(hwndDlg, IDC_EDIT_SPACE, Traffic_AdditionSpace, 0); + SendDlgItemMessage(hwndDlg, IDC_EDIT_SPACE, EM_LIMITTEXT, 2, 0); + + // Appearance + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.DrawProtoIcon, "DrawProtoIcon"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.DrawProtoName, "DrawProtoName"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.DrawCurrentTraffic, "DrawCurrentTraffic"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.DrawTotalTraffic, "DrawTotalTraffic"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.DrawCurrentTimeCounter, "DrawCurrentTime"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.DrawTotalTimeCounter, "DrawTotalTime"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.DrawFrmAsSkin, "DrawFrmAsSkin"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.ShowSummary , "ShowSummary"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.ShowTooltip, "ShowTooltip"); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.ShowMainMenuItem, "ShowMainMenuItem"); + + // Настройки видимости протоколов + for (i = 0; i < NumberOfAccounts; i++) + { + char buffer[32]; + strcpy(buffer, ProtoList[i].name); + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, ProtoList[i].Visible, buffer); + } + OptTree_SetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, unOptions.ShowOverall, "ShowOverall"); + + EnableWindow(GetDlgItem(GetParent(hwndDlg),IDC_APPLY),FALSE); + return 0; + + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDC_BSHOWHIDE: + MenuCommand_TrafficShowHide(0, 0); + SetDlgItemText(hwndDlg,IDC_BSHOWHIDE,IsWindowVisible(TrafficHwnd)? TranslateT("Hide now") : TranslateT("Show now")); + return 0; + + case IDC_EDIT_SPACE: + case IDC_EDIT_COUNTER_FORMAT: + case IDC_EDIT_OVERALL_COUNTER_FORMAT: + case IDC_EDIT_TOOLTIP_FORMAT: + if (HIWORD(wParam) == EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case IDC_COMBO_AUTO_CLEAR: + if (HIWORD(wParam) == CBN_SELCHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + break; + } + + case WM_NOTIFY: + { + LPNMHDR lpnmhdr = (LPNMHDR)lParam; + + switch (lpnmhdr->code) + { + case PSN_APPLY: + { + unOptions.PeriodForShow = (char)SendDlgItemMessage(hwndDlg,IDC_COMBO_AUTO_CLEAR,CB_GETCURSEL,0,0); + + // Интервал между строками + Traffic_AdditionSpace = GetDlgItemInt(hwndDlg, IDC_EDIT_SPACE, NULL, 0); + // Настройки Appearance + unOptions.DrawProtoIcon = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawProtoIcon"); + unOptions.DrawProtoName = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawProtoName"); + unOptions.DrawCurrentTraffic = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawCurrentTraffic"); + unOptions.DrawTotalTraffic = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawTotalTraffic"); + unOptions.DrawTotalTimeCounter = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawTotalTime"); + unOptions.DrawCurrentTimeCounter = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawCurrentTime"); + unOptions.DrawTotalTimeCounter = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawTotalTime"); + unOptions.DrawFrmAsSkin = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "DrawFrmAsSkin"); + unOptions.ShowSummary = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "ShowSummary"); + unOptions.ShowTooltip = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "ShowTooltip"); + unOptions.ShowMainMenuItem = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "ShowMainMenuItem"); + + // Настройки видимости протоколов + for (i = 0; i < NumberOfAccounts; i++) + { + char buffer[32]; + strcpy(buffer, ProtoList[i].name); + ProtoList[i].Visible = (BYTE)OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, buffer); + } + unOptions.ShowOverall = OptTree_GetOptions(hwndDlg, IDC_APPEARANCEOPTIONS, options, optionCount, "ShowOverall"); + + // Формат счётчиков + GetWindowText(GetDlgItem(hwndDlg, IDC_EDIT_COUNTER_FORMAT), Traffic_CounterFormat, 512); + // Формат всплывающей подсказки + GetWindowText(GetDlgItem(hwndDlg, IDC_EDIT_TOOLTIP_FORMAT), Traffic_TooltipFormat, 512); + + // Ключевой цвет + UseKeyColor = db_get_b(NULL, "ModernSettings", "UseKeyColor", 1); + KeyColor = db_get_dw(NULL, "ModernSettings", "KeyColor", 0); + + // Перерисовываем фрейм + UpdateTrafficWindowSize(); + + // Если отключается показ пункта главного меню, то удаляем его. + if (!unOptions.ShowMainMenuItem && hTrafficMainMenuItem) + { + CallService(MS_CLIST_REMOVEMAINMENUITEM, (WPARAM)hTrafficMainMenuItem, 0); + hTrafficMainMenuItem = NULL; + } + // Если включается, то создаём. + if (unOptions.ShowMainMenuItem && !hTrafficMainMenuItem) + Traffic_AddMainMenuItem(); + + SaveSettings(0); + // + return TRUE; + } // case PSN_APPLY + } // switch + } + + case WM_DESTROY: + return FALSE; + } + return 0; +} + +int TrafficCounterOptInitialise(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp={0}; + // Main options page + odp.cbSize=sizeof(odp); + odp.position=900000000; + odp.groupPosition = 1; + odp.hInstance=hInst; + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_TRAFFIC); + odp.pszGroup = LPGEN("Services"); + odp.pszTab = LPGEN("Options"); + odp.pszTitle = LPGEN("Traffic counter"); + odp.pfnDlgProc=DlgProcTCOptions; + odp.flags=ODPF_BOLDGROUPS; + Options_AddPage(wParam, &odp); + + // Statistics options page + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_STATS); + odp.pszTab = LPGEN("Statistics"); + odp.pfnDlgProc = DlgProcOptStatistics; + Options_AddPage(wParam, &odp); + + // Popups option page + if (ServiceExists(MS_POPUP_ADDPOPUP)) + { + odp.groupPosition = 100; + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_TRAFFIC_POPUPS); + odp.pszGroup=LPGEN("PopUps"); + odp.pszTitle=LPGEN("Traffic counter"); + odp.pfnDlgProc=DlgProcPopupsTraffic; + odp.flags=ODPF_BOLDGROUPS; + Options_AddPage(wParam, &odp); + } + + return 0; +} + +void SaveSettings(BYTE OnlyCnt) +{ + unsigned short int i; + + // Сохраняем счётчик времени онлайна + db_set_dw(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_TOTAL_ONLINE_TIME, OverallInfo.Total.Timer); + + if (OnlyCnt) return; + + // Для каждого протокола сохраняем флаги + for (i = 0; i < NumberOfAccounts; i++) + { + if (!ProtoList[i].name) continue; + db_set_b(NULL, ProtoList[i].name, SETTINGS_PROTO_FLAGS, ProtoList[i].Flags); + } + + //settings for notification + db_set_dw(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_BKCOLOR,Traffic_PopupBkColor); + db_set_dw(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_FONTCOLOR,Traffic_PopupFontColor); + // + db_set_b(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_NOTIFY_TIME_VALUE,Traffic_Notify_time_value); + // + db_set_w(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_NOTIFY_SIZE_VALUE,Traffic_Notify_size_value); + // + //popup timeout + db_set_b(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_TIMEOUT_DEFAULT,Traffic_PopupTimeoutDefault); + db_set_b(NULL,TRAFFIC_SETTINGS_GROUP,SETTINGS_POPUP_TIMEOUT_VALUE,Traffic_PopupTimeoutValue); + // + // Формат счётчиков + db_set_ts(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_COUNTER_FORMAT, Traffic_CounterFormat); + + db_set_ts(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_TOOLTIP_FORMAT, Traffic_TooltipFormat); + + db_set_b(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_ADDITION_SPACE, Traffic_AdditionSpace); + // Сохраняем флаги + db_set_dw(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_WHAT_DRAW, unOptions.Flags); + db_set_w(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_STAT_ACC_OPT, Stat_SelAcc); +} + +/*--------------------------------------------------------------------------------------------*/ +int TrafficRecv(WPARAM wParam,LPARAM lParam) +{ + NETLIBNOTIFY *nln = (NETLIBNOTIFY*)wParam; + NETLIBUSER *nlu = (NETLIBUSER*)lParam; + int i; + + if (nln->result > 0) + for (i = 0; i < NumberOfAccounts; i++) + if (!strcmp(ProtoList[i].name, nlu->szSettingsModule)) + InterlockedExchangeAdd(&ProtoList[i].AllStatistics[ProtoList[i].NumberOfRecords-1].Incoming, nln->result); + return 0; +} + +int TrafficSend(WPARAM wParam,LPARAM lParam) +{ + NETLIBNOTIFY *nln = (NETLIBNOTIFY*)wParam; + NETLIBUSER *nlu = (NETLIBUSER*)lParam; + int i; + + if (nln->result > 0) + for (i = 0; i < NumberOfAccounts; i++) + if (!strcmp(ProtoList[i].name, nlu->szSettingsModule)) + InterlockedExchangeAdd(&ProtoList[i].AllStatistics[ProtoList[i].NumberOfRecords-1].Outgoing, nln->result); + return 0; +} + +int TrafficCounter_PaintCallbackProc(HWND hWnd, HDC hDC, RECT * rcPaint, HRGN rgn, DWORD dFlags, void * CallBackData) +{ + return TrafficCounter_Draw(hWnd,hDC); +} + +int TrafficCounter_Draw(HWND hwnd, HDC hDC) +{ + if (hwnd==(HWND)-1) return 0; + if (GetParent(hwnd) == (HWND)CallService(MS_CLUI_GETHWND, 0, 0)) + return PaintTrafficCounterWindow(hwnd, hDC); + else + InvalidateRect(hwnd,NULL,FALSE); + return 0; +} + +static void TC_AlphaText(HDC hDC, LPCTSTR lpString, RECT* lpRect, UINT format, BYTE ClistModernPresent) +{ + int nCount = lstrlen( lpString ); + + if (ClistModernPresent) + AlphaText(hDC, lpString, nCount, lpRect, format, Traffic_FontColor); + else + DrawText( hDC, lpString, nCount, lpRect, format ); +} + +static void TC_DrawIconEx( HDC hdc,int xLeft,int yTop,HICON hIcon, HBRUSH hbrFlickerFreeDraw, BYTE ClistModernPresent) +{ + if (ClistModernPresent) + mod_DrawIconEx_helper( hdc, xLeft, yTop, hIcon, 16, 16, 0, hbrFlickerFreeDraw, DI_NORMAL ); + else + DrawIconEx( hdc, xLeft, yTop, hIcon, 16, 16, 0, hbrFlickerFreeDraw, DI_NORMAL ); +} + +int PaintTrafficCounterWindow(HWND hwnd, HDC hDC) +{ + RECT rect, rect2; + HFONT old_font; + int i, dx, height, width; + HBRUSH b, t; + HDC hdc; + HBITMAP hbmp, oldbmp; + BITMAPINFO RGB32BitsBITMAPINFO = {0}; + BLENDFUNCTION aga = {AC_SRC_OVER, 0, 0xFF, AC_SRC_ALPHA}; + DWORD SummarySession, SummaryTotal; + + BYTE ClistModernPresent = (GetModuleHandleA("clist_modern.dll") || GetModuleHandleA("clist_modern_dora.dll")) + && !db_get_b(NULL, "ModernData", "DisableEngine", 0) + && db_get_b(NULL, "ModernData", "EnableLayering", 1); + + GetClientRect (hwnd, &rect); + height = rect.bottom - rect.top; + width = rect.right - rect.left; + + // Свой контекст устройства. + hdc = CreateCompatibleDC(hDC); + // + RGB32BitsBITMAPINFO.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + RGB32BitsBITMAPINFO.bmiHeader.biWidth = width; + RGB32BitsBITMAPINFO.bmiHeader.biHeight = height; + RGB32BitsBITMAPINFO.bmiHeader.biPlanes = 1; + RGB32BitsBITMAPINFO.bmiHeader.biBitCount = 32; + RGB32BitsBITMAPINFO.bmiHeader.biCompression = BI_RGB; + hbmp = CreateDIBSection(NULL, + &RGB32BitsBITMAPINFO, + DIB_RGB_COLORS, + NULL, + NULL, 0); + oldbmp = (HBITMAP)SelectObject(hdc, hbmp); + + b = CreateSolidBrush(Traffic_BkColor); + t = CreateSolidBrush(KeyColor); + + if ( ClistModernPresent + && unOptions.DrawFrmAsSkin) + { + SKINDRAWREQUEST rq; + + rq.hDC = hdc; + rq.rcDestRect = rect; + rq.rcClipRect = rect; + strncpy(rq.szObjectID, "Main,ID=EventArea", sizeof(rq.szObjectID)); + if (CallService(MS_SKIN_DRAWGLYPH, (WPARAM)&rq, 0)) + { + strncpy(rq.szObjectID, "Main,ID=StatusBar", sizeof(rq.szObjectID)); + CallService(MS_SKIN_DRAWGLYPH, (WPARAM)&rq, 0); + } + } + else + { + SetTextColor(hdc, Traffic_FontColor); + SetBkColor(hdc, Traffic_BkColor); + FillRect(hdc, &rect, b); + AlphaBlend(hdc, 0, 0, width, height, hdc, 0, 0, width, height, aga); + } + + old_font = (HFONT)SelectObject(hdc, Traffic_h_font); + + // Ограничиваем область рисования + rect.top += 2; + rect.left += 3; + rect.bottom -= 2; + rect.right -= 3; + +//------------------- +// Если нет плагина Variables, рисуем упрощённо. +//------------------- + if (!ServiceExists(MS_VARS_FORMATSTRING)) + { + SummarySession = SummaryTotal = 0; + // Для каждого аккаунта + for (i = 0; i < NumberOfAccounts; i++) + { + // Только если разрешено его отображение. + if (ProtoList[i].Visible && ProtoList[i].Enabled) + { + dx = 0; + // Изображаем иконку аккаунта. + if (unOptions.DrawProtoIcon) + { + TC_DrawIconEx(hdc, rect.left, rect.top, + LoadSkinnedProtoIcon(ProtoList[i].name, CallProtoService(ProtoList[i].name,PS_GETSTATUS,0,0)), b, ClistModernPresent); + dx = 19; + } + // Изображаем имя аккаунта + if (unOptions.DrawProtoName) + { + rect.left += dx; + TC_AlphaText(hdc, ProtoList[i].tszAccountName, &rect, DT_SINGLELINE | DT_LEFT | DT_TOP, ClistModernPresent); + rect.left -= dx; + } + // Следующие позиции строятся от правого края. + // Общее время. + if (unOptions.DrawTotalTimeCounter) + { + TCHAR bu[32]; + + GetDurationFormatM(ProtoList[i].Total.Timer, _T("h:mm:ss"), bu, 32); + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + } + // Текущее время. + if (unOptions.DrawCurrentTimeCounter) + { + TCHAR bu[32]; + + GetDurationFormatM(ProtoList[i].Session.Timer, _T("h:mm:ss"), bu, 32); + rect.right -= 50; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 50; + } + // Изображаем общий трафик. + if (unOptions.DrawTotalTraffic) + { + TCHAR bu[32]; + + GetFormattedTraffic(ProtoList[i].TotalSentTraffic + ProtoList[i].TotalRecvTraffic, 3, bu, 32); + rect.right -= 100; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 100; + + if (ProtoList[i].Visible) + SummaryTotal += ProtoList[i].TotalRecvTraffic + ProtoList[i].TotalSentTraffic; + } + // Изображаем текущий трафик. + if (unOptions.DrawCurrentTraffic) + { + TCHAR bu[32]; + + GetFormattedTraffic(ProtoList[i].CurrentRecvTraffic + ProtoList[i].CurrentSentTraffic, 3, bu, 32); + rect.right -= 150; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 150; + + if (ProtoList[i].Visible) + SummarySession += ProtoList[i].CurrentRecvTraffic + ProtoList[i].CurrentSentTraffic; + } + + rect.top += Traffic_LineHeight + Traffic_AdditionSpace; + } + } + // Рисуем суммарный трафик выбранных аккаунтов. + if (unOptions.ShowSummary) + { + // Изображаем иконку. + dx = 0; + if (unOptions.DrawProtoIcon) + { + TC_DrawIconEx(hdc, rect.left, rect.top, + LoadSkinnedIcon(SKINICON_OTHER_MIRANDA), b, ClistModernPresent); + dx = 19; + } + // Выводим текст + // Изображаем имя + if (unOptions.DrawProtoName) + { + TCHAR *bu = mir_a2t("Summary"); + + rect.left += dx; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_LEFT | DT_TOP, ClistModernPresent); + rect.left -= dx; + mir_free(bu); + } + // Общее время. + if (unOptions.DrawTotalTimeCounter) + { + TCHAR bu[32]; + + GetDurationFormatM(OverallInfo.Total.Timer, _T("h:mm:ss"), bu, 32); + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + } + // Текущее время. + if (unOptions.DrawCurrentTimeCounter) + { + TCHAR bu[32]; + + GetDurationFormatM(OverallInfo.Session.Timer, _T("h:mm:ss"), bu, 32); + rect.right -= 50; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 50; + } + // Изображаем общий трафик. + if (unOptions.DrawTotalTraffic) + { + TCHAR bu[32]; + + GetFormattedTraffic(SummaryTotal, 3, bu, 32); + rect.right -= 100; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 100; + } + // Изображаем текущий трафик. + if (unOptions.DrawCurrentTraffic) + { + TCHAR bu[32]; + + GetFormattedTraffic(SummarySession, 3, bu, 32); + rect.right -= 150; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 150; + } + } + rect.top += Traffic_LineHeight + Traffic_AdditionSpace; + // Рисуем всеобщий трафик. + if (unOptions.ShowOverall) + { + // Изображаем иконку. + dx = 0; + if (unOptions.DrawProtoIcon) + { + TC_DrawIconEx(hdc, rect.left, rect.top, + LoadSkinnedIcon(SKINICON_OTHER_MIRANDA), b, ClistModernPresent); + dx = 19; + } + // Выводим текст + // Изображаем имя + if (unOptions.DrawProtoName) + { + TCHAR *bu = mir_a2t("Overall"); + + rect.left += dx; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_LEFT | DT_TOP, ClistModernPresent); + rect.left -= dx; + mir_free(bu); + } + // Следующие позиции строятся от правого края. + // Изображаем общий трафик. + if (unOptions.DrawTotalTraffic) + { + TCHAR bu[32]; + + GetFormattedTraffic(OverallInfo.TotalSentTraffic + OverallInfo.TotalRecvTraffic, 3, bu, 32); + rect.right -= 100; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 100; + } + // Изображаем текущий трафик. + if (unOptions.DrawCurrentTraffic) + { + TCHAR bu[32]; + + GetFormattedTraffic(OverallInfo.CurrentRecvTraffic + OverallInfo.CurrentSentTraffic, 3, bu, 32); + rect.right -= 150; + TC_AlphaText(hdc, bu, &rect, DT_SINGLELINE | DT_RIGHT | DT_TOP, ClistModernPresent); + rect.right += 150; + } + } + } + else +//------------- +// Если есть Variables - рисуем по-новому +//------------- + { + RowItemInfo *ItemsList; + WORD ItemsNumber, RowsNumber; + TCHAR **ExtraText; + HICON *ahIcon; + + // Готовим список строк для Variables и иконок. + ExtraText = (TCHAR**)mir_alloc(sizeof(TCHAR*)); + ahIcon = (HICON*)mir_alloc(sizeof(HICON)); + RowsNumber = 0; + // Цикл по аккаунтам. + for (i = 0; i < NumberOfAccounts; i++) + { + if (ProtoList[i].Visible && ProtoList[i].Enabled) + { + ExtraText = (TCHAR**)mir_realloc(ExtraText, sizeof(TCHAR*) * (RowsNumber + 1)); + ahIcon = (HICON*)mir_realloc(ahIcon, sizeof(HICON) * (RowsNumber + 1)); + + ExtraText[RowsNumber] = mir_a2t(ProtoList[i].name); + ahIcon[RowsNumber++] = LoadSkinnedProtoIcon(ProtoList[i].name, CallProtoService(ProtoList[i].name, PS_GETSTATUS, 0, 0)); + } + } + // Ещё 2 особых элемента. + if (unOptions.ShowSummary) + { + ExtraText = (TCHAR**)mir_realloc(ExtraText, sizeof(TCHAR*) * (RowsNumber + 1)); + ahIcon = (HICON*)mir_realloc(ahIcon, sizeof(HICON) * (RowsNumber + 1)); + + ExtraText[RowsNumber] = mir_a2t("summary"); + ahIcon[RowsNumber++] = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + } + if (unOptions.ShowOverall) + { + ExtraText = (TCHAR**)mir_realloc(ExtraText, sizeof(TCHAR*) * (RowsNumber + 1)); + ahIcon = (HICON*)mir_realloc(ahIcon, sizeof(HICON) * (RowsNumber + 1)); + + ExtraText[RowsNumber] = mir_a2t("overall"); + ahIcon[RowsNumber++] = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + } + + // Рисуем свой счётчик для каждого из выбранных протоколов + for (i = 0; i < RowsNumber; i++) + { + TCHAR *buf; + + buf = variables_parse(Traffic_CounterFormat, ExtraText[i], NULL); + if (ItemsNumber = GetRowItems(buf, &ItemsList)) + { + // Рисуем текст. + for (dx = 0; dx < ItemsNumber; dx++) + { + // Делаем копию прямоугольника для рисования. + memcpy(&rect2, &rect, sizeof(RECT)); + rect2.bottom = rect2.top + Traffic_LineHeight; + // Что за тег? + switch (ItemsList[dx].Alignment) + { + case 'I': + TC_DrawIconEx(hdc, ItemsList[dx].Interval, rect2.top, ahIcon[i], b, ClistModernPresent); + break; + case 'i': + TC_DrawIconEx(hdc, width - 16 - ItemsList[dx].Interval, rect2.top, ahIcon[i], b, ClistModernPresent); + break; + case 'L': + rect2.left = ItemsList[dx].Interval; + TC_AlphaText(hdc, ItemsList[dx].String, &rect2, DT_SINGLELINE | DT_LEFT | DT_VCENTER, ClistModernPresent); + break; + case 'R': + rect2.right = width - ItemsList[dx].Interval; + TC_AlphaText(hdc, ItemsList[dx].String, &rect2, DT_SINGLELINE | DT_RIGHT | DT_VCENTER, ClistModernPresent); + break; + default: + continue; + } + + } + + // Нужно освободить память. + for (; ItemsNumber--; ) + { + mir_free(ItemsList[ItemsNumber].String); + } + mir_free(ItemsList); + } + mir_free(buf); + rect.top += Traffic_LineHeight + Traffic_AdditionSpace; + } + + // Удаляем список строк. + for (; RowsNumber--; ) + mir_free(ExtraText[RowsNumber]); + mir_free(ExtraText); + } + + DeleteObject(b); + DeleteObject(t); + SelectObject(hdc, old_font); + + if (ClistModernPresent) + { + AlphaBlend(hDC, 0, 0, width, height, hdc, 0, 0, width, height, aga); + } + else + { + BitBlt(hDC, 0, 0, width, height, hdc, 0, 0, SRCCOPY); + } + + SelectObject(hdc, oldbmp); + DeleteObject(hbmp); + DeleteDC(hdc); + + return 0; +} + +void ProtocolIsOnLine(int num) +{ + DWORD CurrentTimeMs; + + if (ProtoList[num].State) return; + + online_count++; + CurrentTimeMs = GetTickCount(); + + ProtoList[num].State = 1; + ProtoList[num].Session.TimeAtStart = CurrentTimeMs; + ProtoList[num].Total.TimeAtStart = CurrentTimeMs + - 1000 * ProtoList[num].AllStatistics[ProtoList[num].NumberOfRecords - 1].Time; + ProtoList[num].Session.Timer = 0; + + if (online_count == 1) // Хотя бы один аккаунт перешёл в онлайн - готовимся считать суммарное время. + { + OverallInfo.Session.TimeAtStart = CurrentTimeMs - 1000 * OverallInfo.Session.Timer; + OverallInfo.Total.TimeAtStart = CurrentTimeMs - 1000 * OverallInfo.Total.Timer; + } +} + +void ProtocolIsOffLine(int num) +{ + if (!ProtoList[num].State) return; + + online_count--; + ProtoList[num].State = 0; +} + +static POINT ptMouse = {0}; + +LRESULT CALLBACK TrafficCounterWndProc_MW(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + POINT p; + int i; + // + switch (msg) + { + case (WM_USER+697): + if (lParam == 666) + DestroyWindow(hwnd); + break; + + case WM_PAINT: + { + if ( !db_get_b(NULL, "ModernData", "DisableEngine", 0) + && db_get_b(NULL, "ModernData", "EnableLayering", 1) + && ServiceExists(MS_SKINENG_INVALIDATEFRAMEIMAGE)) + CallService(MS_SKINENG_INVALIDATEFRAMEIMAGE, (WPARAM)TrafficHwnd, 0); + else + { + HDC hdc = GetDC(hwnd); + PaintTrafficCounterWindow(hwnd, hdc); + ReleaseDC(hwnd, hdc); + } + } + break; + + case WM_ERASEBKGND: + return 1; + + case WM_LBUTTONDOWN : + if (db_get_b(NULL,"CLUI","ClientAreaDrag",SETTING_CLIENTDRAG_DEFAULT)) + { + ClientToScreen(GetParent(hwnd),&p); + return SendMessage(GetParent(hwnd), WM_SYSCOMMAND, SC_MOVE|HTCAPTION,MAKELPARAM(p.x,p.y)); + } + break; + + case WM_RBUTTONDOWN : + p.x = GET_X_LPARAM(lParam); + p.y = GET_Y_LPARAM(lParam); + ClientToScreen(hwnd,&p); + TrackPopupMenu(TrafficPopupMenu,TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,p.x,p.y,0,hwnd,NULL); + break; + + case WM_COMMAND : + switch (wParam) + { + case POPUPMENU_HIDE: + MenuCommand_TrafficShowHide(0, 0); + break; + + case POPUPMENU_CLEAR_NOW: + for (i = 0; i < NumberOfAccounts; i++) + { + ProtoList[i].StartIncoming = + ProtoList[i].AllStatistics[ProtoList[i].NumberOfRecords - 1].Incoming; + ProtoList[i].StartOutgoing = + ProtoList[i].AllStatistics[ProtoList[i].NumberOfRecords - 1].Outgoing; + ProtoList[i].Session.TimeAtStart = GetTickCount(); + } + OverallInfo.CurrentRecvTraffic = OverallInfo.CurrentSentTraffic = 0; + } + break; + + case WM_SETCURSOR: + { + POINT pt; + + GetCursorPos(&pt); + if ( (abs(pt.x - ptMouse.x) < 20) + && (abs(pt.y - ptMouse.y) < 20) ) + return 1; + + if (TooltipShowing) + { + KillTimer(TrafficHwnd, TIMER_TOOLTIP); + CallService("mToolTip/HideTip", 0, 0); + TooltipShowing = FALSE; + } + KillTimer(TrafficHwnd, TIMER_TOOLTIP); + SetTimer(TrafficHwnd, TIMER_TOOLTIP, CallService(MS_CLC_GETINFOTIPHOVERTIME, 0, 0), 0); + break; + } + + case WM_TIMER : + switch(wParam) + { + case TIMER_NOTIFY_TICK: + NotifyOnRecv(); + NotifyOnSend(); + break; + + case TIMER_REDRAW: // Перерисовка раз в полсекунды. + { + DWORD CurrentTimeMs; + SYSTEMTIME stNow; + + SaveSettings(1); + // Перед подсчётом суммарного трафика обнуляем счётчики. + OverallInfo.CurrentRecvTraffic = + OverallInfo.CurrentSentTraffic = + OverallInfo.TotalRecvTraffic = + OverallInfo.TotalSentTraffic = 0; + + CurrentTimeMs = GetTickCount(); + + for (i = 0; i < NumberOfAccounts; i++) + { + if (ProtoList[i].State) + { + ProtoList[i].AllStatistics[ProtoList[i].NumberOfRecords-1].Time = + (CurrentTimeMs - ProtoList[i].Total.TimeAtStart) / 1000; + ProtoList[i].Session.Timer = + (CurrentTimeMs - ProtoList[i].Session.TimeAtStart) / 1000; + } + + Stat_CheckStatistics(i); + + { // Здесь на основании статистики вычисляются значения всех трафиков и времени. + DWORD Sum1, Sum2; + unsigned long int j; + + // Значения для текущей сессии. + for (Sum1 = Sum2 = 0, j = ProtoList[i].StartIndex; j < ProtoList[i].NumberOfRecords; j++) + { + Sum1 += ProtoList[i].AllStatistics[j].Incoming; + Sum2 += ProtoList[i].AllStatistics[j].Outgoing; + } + ProtoList[i].CurrentRecvTraffic = Sum1 - ProtoList[i].StartIncoming; + ProtoList[i].CurrentSentTraffic = Sum2 - ProtoList[i].StartOutgoing; + OverallInfo.CurrentRecvTraffic += ProtoList[i].CurrentRecvTraffic; + OverallInfo.CurrentSentTraffic += ProtoList[i].CurrentSentTraffic; + // Значения для выбранного периода. + ProtoList[i].TotalRecvTraffic = + Stat_GetItemValue(1 << i, + unOptions.PeriodForShow + 1, + Stat_GetRecordsNumber(i, unOptions.PeriodForShow + 1) - 1, + 1); + ProtoList[i].TotalSentTraffic = + Stat_GetItemValue(1 << i, + unOptions.PeriodForShow + 1, + Stat_GetRecordsNumber(i, unOptions.PeriodForShow + 1) - 1, + 2); + ProtoList[i].Total.Timer = + Stat_GetItemValue(1 << i, + unOptions.PeriodForShow + 1, + Stat_GetRecordsNumber(i, unOptions.PeriodForShow + 1) - 1, + 4); + OverallInfo.TotalRecvTraffic += ProtoList[i].TotalRecvTraffic; + OverallInfo.TotalSentTraffic += ProtoList[i].TotalSentTraffic; + } + } + // Не пора ли уведомить? + if (unOptions.NotifyBySize && Traffic_Notify_size_value) + { + if (!((OverallInfo.CurrentRecvTraffic >> 10) % Traffic_Notify_size_value) + && notify_recv_size != OverallInfo.CurrentRecvTraffic >> 10 ) + NotifyOnRecv(); + + if (!((OverallInfo.CurrentSentTraffic >> 10) % Traffic_Notify_size_value) + && notify_send_size != OverallInfo.CurrentSentTraffic >> 10) + NotifyOnSend(); + } + + // Счётчики суммарного времени. + GetLocalTime(&stNow); + + // Не пора ли сбросить общий счётчик? + if ( (unOptions.PeriodForShow == 0 + && stNow.wHour == 0 + && stNow.wMinute == 0 + && stNow.wSecond == 0) + || (unOptions.PeriodForShow == 1 + && DayOfWeek(stNow.wDay, stNow.wMonth, stNow.wYear) == 1 + && stNow.wHour == 0 + && stNow.wMinute == 0 + && stNow.wSecond == 0) + || (unOptions.PeriodForShow == 2 + && stNow.wDay == 1 + && stNow.wHour == 0 + && stNow.wMinute == 0 + && stNow.wSecond == 0) + || (unOptions.PeriodForShow == 3 + && stNow.wMonth == 1 + && stNow.wDay == 1 + && stNow.wHour == 0 + && stNow.wMinute == 0 + && stNow.wSecond == 0) ) + OverallInfo.Total.TimeAtStart = CurrentTimeMs; + + if (online_count > 0) + { + OverallInfo.Session.Timer = + (CurrentTimeMs - OverallInfo.Session.TimeAtStart) / 1000; + OverallInfo.Total.Timer = + (CurrentTimeMs - OverallInfo.Total.TimeAtStart) / 1000; + } + + CallService(MS_CLIST_FRAMES_UPDATEFRAME, (WPARAM)Traffic_FrameID, FU_FMREDRAW); + } + break; + + case TIMER_TOOLTIP: + { + TCHAR *TooltipText; + CLCINFOTIP ti = {0}; + RECT rt; + + GetCursorPos(&TooltipPosition); + if (!TooltipShowing && unOptions.ShowTooltip ) + { + KillTimer(TrafficHwnd, TIMER_TOOLTIP); + ScreenToClient(TrafficHwnd, &TooltipPosition); + GetClientRect(TrafficHwnd, &rt); + if (PtInRect(&rt, TooltipPosition)) + { + GetCursorPos(&ptMouse); + ti.rcItem.left = TooltipPosition.x - 10; + ti.rcItem.right = TooltipPosition.x + 10; + ti.rcItem.top = TooltipPosition.y - 10; + ti.rcItem.bottom = TooltipPosition.y + 10; + ti.cbSize = sizeof( ti ); + TooltipText = variables_parsedup(Traffic_TooltipFormat, NULL, NULL); + + CallService(MS_TIPPER_SHOWTIPW, (WPARAM)TooltipText, (LPARAM)&ti); + + TooltipShowing = TRUE; + mir_free(TooltipText); + } + } + } + break; + } + break; + + default: + return DefWindowProc(hwnd,msg,wParam,lParam); + } + // + return DefWindowProc(hwnd,msg,wParam,lParam); +} + +void CreateTrafficWindow(HWND hCluiWnd) +{ + WNDCLASSEX wcx = {0}; + CLISTFrame f; + + wcx.cbSize = sizeof( WNDCLASSEX ); + wcx.style = 0; + wcx.lpfnWndProc = TrafficCounterWndProc_MW; + wcx.cbClsExtra = 0; + wcx.cbWndExtra = 0; + wcx.hInstance = hInst; + wcx.hIcon = NULL; + wcx.hCursor = LoadCursor(hInst,IDC_ARROW); + wcx.hbrBackground = 0; + wcx.lpszMenuName = NULL; + wcx.lpszClassName = TRAFFIC_COUNTER_WINDOW_CLASS; + wcx.hIconSm = NULL; + RegisterClassEx( &wcx ); + TrafficHwnd = CreateWindowEx(WS_EX_TOOLWINDOW, TRAFFIC_COUNTER_WINDOW_CLASS, + TRAFFIC_COUNTER_WINDOW_CLASS, + WS_CHILDWINDOW | WS_CLIPCHILDREN, + 0, 0, 0, 0, hCluiWnd, NULL, hInst, NULL); + + if ( ServiceExists(MS_CLIST_FRAMES_ADDFRAME) ) + { + // Готовимся создавать фрейм + ZeroMemory( &f, sizeof(CLISTFrame) ); + f.align = alBottom; + f.cbSize = sizeof(CLISTFrame); + f.height = TrafficWindowHeight(); + f.Flags= unOptions.FrameIsVisible | F_LOCKED | F_NOBORDER | F_NO_SUBCONTAINER; + f.hWnd = TrafficHwnd; + f.TBname = ("Traffic counter"); + f.name = ("Traffic counter"); + // Создаём фрейм + Traffic_FrameID = (HANDLE)CallService(MS_CLIST_FRAMES_ADDFRAME,(WPARAM)&f,(LPARAM)0); + CallService(MS_SKINENG_REGISTERPAINTSUB,(WPARAM)f.hWnd,(LPARAM)TrafficCounter_PaintCallbackProc); + } + + // Создаём таймеры. + SetTimer(TrafficHwnd, TIMER_REDRAW, 500, NULL); + UpdateNotifyTimer(); +} + +INT_PTR MenuCommand_TrafficShowHide(WPARAM wParam,LPARAM lParam) +{ + unOptions.FrameIsVisible = !unOptions.FrameIsVisible; + if (Traffic_FrameID == NULL) + ShowWindow(TrafficHwnd, unOptions.FrameIsVisible ? SW_SHOW : SW_HIDE); + else + CallService(MS_CLIST_FRAMES_SHFRAME, (WPARAM)Traffic_FrameID, 0); + db_set_dw(NULL, TRAFFIC_SETTINGS_GROUP, SETTINGS_WHAT_DRAW, unOptions.Flags); + // + return 0; +} + +void Traffic_AddMainMenuItem(void) +{ + CLISTMENUITEM mi = { sizeof(mi) }; + mi.position = -0x7FFFFFFF; + mi.flags = 0; + mi.hIcon = NULL; + mi.pszName = LPGEN("Toggle traffic counter"); + mi.pszService="TrafficCounter/ShowHide"; + + hTrafficMainMenuItem = Menu_AddMainMenuItem(&mi); +} + +/*-------------------------------------------------------------------------------------------------------------------*/ +void UpdateNotifyTimer(void) +{ + if (!ServiceExists(MS_POPUP_ADDPOPUP)) return; + + if (Traffic_Notify_time_value && unOptions.NotifyByTime) + SetTimer(TrafficHwnd, TIMER_NOTIFY_TICK, Traffic_Notify_time_value * 1000 * 60, NULL); + else + KillTimer(TrafficHwnd, TIMER_NOTIFY_TICK); +} + +void NotifyOnSend(void) +{ + POPUPDATAT ppd; + + ZeroMemory(&ppd, sizeof(ppd)); + ppd.lchContact = NULL; + ppd.lchIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); + _tcsncpy(ppd.lptzContactName, TranslateT("Traffic counter notification"), MAX_CONTACTNAME); + // + mir_sntprintf(ppd.lptzText, MAX_SECONDLINE, TranslateT("%d kilobytes sent"), + notify_send_size = OverallInfo.CurrentSentTraffic >> 10); + // + ppd.colorBack = Traffic_PopupBkColor; + ppd.colorText = Traffic_PopupFontColor; + ppd.PluginWindowProc = NULL; + ppd.iSeconds = (Traffic_PopupTimeoutDefault ? 0 : Traffic_PopupTimeoutValue); + PUAddPopUpT(&ppd); +} + +void NotifyOnRecv(void) +{ + POPUPDATAT ppd; + + ZeroMemory(&ppd, sizeof(ppd)); + ppd.lchContact = NULL; + ppd.lchIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE); + _tcsncpy(ppd.lptzContactName, TranslateT("Traffic counter notification"),MAX_CONTACTNAME); + // + mir_sntprintf(ppd.lptzText, MAX_SECONDLINE, TranslateT("%d kilobytes received"), + notify_recv_size = OverallInfo.CurrentRecvTraffic >> 10); + // + ppd.colorBack = Traffic_PopupBkColor; + ppd.colorText = Traffic_PopupFontColor; + ppd.PluginWindowProc = NULL; + ppd.iSeconds = (Traffic_PopupTimeoutDefault ? 0 : Traffic_PopupTimeoutValue); + PUAddPopUpT(&ppd); +} + +void CreateProtocolList(void) +{ + int i; + PROTOACCOUNT **acc; + // + ProtoEnumAccounts(&NumberOfAccounts,&acc); + // + ProtoList = (PROTOLIST*)mir_alloc(sizeof(PROTOLIST)*(NumberOfAccounts)); + // + for (i = 0; i < NumberOfAccounts; i++) + { + ProtoList[i].name = (char*)mir_alloc(strlen(acc[i]->szModuleName) + 1); + strcpy(ProtoList[i].name, acc[i]->szModuleName); + ProtoList[i].tszAccountName = (TCHAR*)mir_alloc(sizeof(TCHAR) * (1 + _tcslen(acc[i]->tszAccountName))); + _tcscpy(ProtoList[i].tszAccountName, acc[i]->tszAccountName); + // + ProtoList[i].Flags = db_get_b(NULL, ProtoList[i].name, SETTINGS_PROTO_FLAGS, 3); + ProtoList[i].CurrentRecvTraffic = + ProtoList[i].CurrentSentTraffic = + ProtoList[i].Session.Timer = 0; + // + ProtoList[i].Enabled = acc[i]->bIsEnabled; + ProtoList[i].State = 0; + + Stat_ReadFile(i); + ProtoList[i].StartIndex = ProtoList[i].NumberOfRecords - 1; + ProtoList[i].StartIncoming = ProtoList[i].AllStatistics[ProtoList[i].StartIndex].Incoming; + ProtoList[i].StartOutgoing = ProtoList[i].AllStatistics[ProtoList[i].StartIndex].Outgoing; + } // цикл по аккаунтам + // Начальные значения для суммарной информации. + OverallInfo.Session.Timer = OverallInfo.Total.Timer = 0; +} + +void DestroyProtocolList(void) +{ + int i; + // + for (i = 0; i < NumberOfAccounts; i++) + { + Stat_CheckStatistics(i); + CloseHandle(ProtoList[i].hFile); + mir_free(ProtoList[i].name); + mir_free(ProtoList[i].AllStatistics); + } + // + mir_free(ProtoList); +} + +int ProtocolAckHook(WPARAM wParam,LPARAM lParam) +{ + ACKDATA* pAck=(ACKDATA*)lParam; + WORD i; + + if (ACKTYPE_STATUS == pAck->type) + { + if(ID_STATUS_OFFLINE == pAck->lParam) + { + for (i = 0; i < NumberOfAccounts; i++) + { + if (!ProtoList[i].name) continue; + if (!strcmp(ProtoList[i].name, pAck->szModule)) + { + ProtocolIsOffLine(i); + break; + } + } + } + else + { + if ((pAck->lParam >= ID_STATUS_ONLINE) && (pAck->lParam <= ID_STATUS_OUTTOLUNCH)) + { + for (i = 0; i < NumberOfAccounts; i++) + if (!strcmp(ProtoList[i].name, pAck->szModule)) + { + ProtocolIsOnLine(i); + break; + } + } + } + } + return 0; +} + +int UpdateFonts(WPARAM wParam, LPARAM lParam) +{ + LOGFONT logfont; + //if no font service + if (!ServiceExists(MS_FONT_GETT)) return 0; + //update traffic font + if (Traffic_h_font) DeleteObject(Traffic_h_font); + Traffic_FontColor = CallService(MS_FONT_GETT, (WPARAM)&TrafficFontID, (LPARAM)&logfont); + Traffic_h_font = CreateFontIndirect(&logfont); + // + TrafficFontHeight = abs(logfont.lfHeight) + 1; + Traffic_BkColor = CallService(MS_COLOUR_GETT, (WPARAM)&TrafficBackgroundColorID, 0); + + // Ключевой цвет + UseKeyColor = db_get_b(NULL, "ModernSettings", "UseKeyColor", 1); + KeyColor = db_get_dw(NULL, "ModernSettings", "KeyColor", 0); + + UpdateTrafficWindowSize(); + return 0; +} + +void UpdateTrafficWindowSize(void) +{ + if (Traffic_FrameID != NULL) + { + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS, MAKEWPARAM(FO_HEIGHT, Traffic_FrameID), TrafficWindowHeight()); + } +} + +unsigned short int TrafficWindowHeight(void) +{ + BYTE HeightLineTime = (unOptions.DrawProtoIcon) ? 16 : TrafficFontHeight, + i, ActProto; + WORD MaxWndHeight; + + for (i = 0, ActProto = unOptions.ShowOverall + unOptions.ShowSummary; i < NumberOfAccounts; i++) + ActProto += ProtoList[i].Visible && ProtoList[i].Enabled; + + // Высота строки минимум 16 пикселей (для иконки). + Traffic_LineHeight = TrafficFontHeight > 16 ? TrafficFontHeight: 16; + + // Высота фрейма равна количеству строк. + MaxWndHeight = ActProto * Traffic_LineHeight + + Traffic_AdditionSpace * (ActProto - 1) + + 4; + + return (MaxWndHeight < TrafficFontHeight) ? 0 : MaxWndHeight; +} + +// Функция вносит изменения в ProtoList при коммутации аккаунтов +int OnAccountsListChange(WPARAM wParam, LPARAM lParam) +{ + BYTE i; + PROTOACCOUNT *acc = (PROTOACCOUNT*)lParam; + + switch (wParam) + { + case PRAC_ADDED: + case PRAC_REMOVED: + DestroyProtocolList(); + CreateProtocolList(); + break; + case PRAC_CHANGED: + case PRAC_CHECKED: + for (i = 0; i < NumberOfAccounts; i++) + if (!strcmp(acc->szModuleName, ProtoList[i].name)) + ProtoList[i].Enabled = acc->bIsEnabled; + break; + } + UpdateTrafficWindowSize(); + return 0; +} -- cgit v1.2.3