From 5c9237cf7a1f1e1dd7492b5e58e9082903abeb15 Mon Sep 17 00:00:00 2001 From: Rozhuk Ivan Date: Wed, 26 Nov 2014 23:55:58 +0000 Subject: KeyboardNotify: code cleanup git-svn-id: http://svn.miranda-ng.org/main/trunk@11111 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/KeyboardNotify/src/main.cpp | 1986 ++++++++++----------- plugins/KeyboardNotify/src/options.cpp | 2951 ++++++++++++++++---------------- 2 files changed, 2470 insertions(+), 2467 deletions(-) (limited to 'plugins/KeyboardNotify/src') diff --git a/plugins/KeyboardNotify/src/main.cpp b/plugins/KeyboardNotify/src/main.cpp index 7f5f072fc5..29d448d822 100644 --- a/plugins/KeyboardNotify/src/main.cpp +++ b/plugins/KeyboardNotify/src/main.cpp @@ -1,992 +1,994 @@ -/* - KeyboardNotify plugin v1.5 for Miranda IM - _________________________________________ - - Copyright (C) 2002,2003 Martin Öberg - Copyright (C) 2004 Std - Copyright (C) 2005,2006 TioDuke (tioduke@yahoo.ca) - - - 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 "Common.h" - -#define NCONVERS_BLINKID ((HANDLE)123456) //nconvers' random identifier used to flash an icon for "incoming message" on contact list - -HINSTANCE hInst; - -int hLangpack; - -DWORD IDThread = 0; -HANDLE hThread = NULL; -HANDLE hFlashEvent; -HANDLE hExitEvent; - -HHOOK hMirandaMouseHook = NULL; -HHOOK hMirandaKeyBoardHook = NULL; -HHOOK hMirandaWndProcHook = NULL; -UINT hReminderTimer = 0; - -HHOOK hMouseHook = NULL; -HHOOK hKeyBoardHook = NULL; -BYTE bEmulateKeypresses = 0; -DWORD dwLastInput = 0; -POINT lastGlobalMousePos = {0, 0}; - -BYTE bFlashOnMsg; -BYTE bFlashOnURL; -BYTE bFlashOnFile; -BYTE bFlashOnOther; -BYTE bFullScreenMode; -BYTE bScreenSaverRunning; -BYTE bWorkstationLocked; -BYTE bProcessesAreRunning; -BYTE bWorkstationActive; -BYTE bFlashIfMsgOpen; -BYTE bFlashIfMsgWinNotTop; -BYTE bFlashIfMsgOlder; -WORD wSecondsOlder; -BYTE bFlashUntil; -WORD wBlinksNumber; -BYTE bMirandaOrWindows; -WORD wStatusMap; -WORD wReminderCheck; -BYTE bFlashLed[3]; -BYTE bFlashEffect; -BYTE bSequenceOrder; -WORD wCustomTheme; -WORD wStartDelay; -BYTE bFlashSpeed; -BYTE bOverride; -BYTE bTrillianLedsMsg; -BYTE bTrillianLedsURL; -BYTE bTrillianLedsFile; -BYTE bTrillianLedsOther; - -PROTOCOL_LIST ProtoList = {0, NULL}; -PROCESS_LIST ProcessList = {0, NULL}; - -int nWaitDelay; -unsigned int nExternCount = 0; -BOOL bFlashingEnabled = TRUE; -BOOL bReminderDisabled = FALSE; - -BYTE bMetaProtoEnabled = 0; - -PLUGININFOEX pluginInfo={ - sizeof(PLUGININFOEX), - __PLUGIN_NAME, - PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), - __DESCRIPTION, - __AUTHOR, - __AUTHOREMAIL, - __COPYRIGHT, - __AUTHORWEB, - UNICODE_AWARE, - //{119D7288-2050-448D-9900-D86AC70426BF} - {0x119d7288, 0x2050, 0x448d, {0x99, 0x00, 0xd8, 0x6a, 0xc7, 0x04, 0x26, 0xbf}} -}; - -int InitializeOptions(WPARAM,LPARAM); -void LoadSettings(void); -int HookWindowsHooks(void); -int UnhookWindowsHooks(void); -static LRESULT CALLBACK MouseHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK KeyBoardHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK MirandaMouseHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK MirandaKeyBoardHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK MirandaWndProcHookFunction(int, WPARAM, LPARAM); -BOOL CheckMsgWnd(MCONTACT, BOOL *); - -BOOL checkOpenWindow(MCONTACT hContact) -{ - if (bFlashIfMsgOpen && !bFlashIfMsgWinNotTop) - return TRUE; - - BOOL focus, found = CheckMsgWnd(hContact, &focus); - if (!found && bMetaProtoEnabled) - found = CheckMsgWnd(db_mc_getMeta(hContact), &focus); - - if (!found) - return TRUE; - - if (bFlashIfMsgOpen && !focus) - return TRUE; - - return FALSE; -} - -BOOL checkNotifyOptions() -{ - BOOL screenSaverIsRunning = IsScreenSaverRunning(); - if (screenSaverIsRunning && bScreenSaverRunning) - return TRUE; - - BOOL workstationIsLocked = IsWorkstationLocked(); - if (workstationIsLocked && bWorkstationLocked) - return TRUE; - - BOOL fullScreenMode = IsFullScreen() && !screenSaverIsRunning; - if (fullScreenMode && bFullScreenMode) - return TRUE; - - BOOL processesRunning = areThereProcessesRunning(); - if (processesRunning && bProcessesAreRunning) - return TRUE; - - return (!fullScreenMode && !screenSaverIsRunning && !workstationIsLocked && !processesRunning && bWorkstationActive); -} - -BOOL isStatusEnabled(int status) -{ - switch (status) { - case ID_STATUS_OFFLINE: return wStatusMap & MAP_OFFLINE; - case ID_STATUS_ONLINE: return wStatusMap & MAP_ONLINE; - case ID_STATUS_AWAY: return wStatusMap & MAP_AWAY; - case ID_STATUS_NA: return wStatusMap & MAP_NA; - case ID_STATUS_OCCUPIED: return wStatusMap & MAP_OCCUPIED; - case ID_STATUS_DND: return wStatusMap & MAP_DND; - case ID_STATUS_FREECHAT: return wStatusMap & MAP_FREECHAT; - case ID_STATUS_INVISIBLE: return wStatusMap & MAP_INVISIBLE; - case ID_STATUS_ONTHEPHONE: return wStatusMap & MAP_ONTHEPHONE; - case ID_STATUS_OUTTOLUNCH: return wStatusMap & MAP_OUTTOLUNCH; - default: return FALSE; - } -} - -BOOL checkGlobalStatus() -{ - return isStatusEnabled(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)); -} - -BOOL checkGlobalXstatus() -{ - int protosSupporting=0, status=0; - - for (int i=0; i < ProtoList.protoCount; i++) { - if ( !ProtoList.protoInfo[i].enabled || !ProtoList.protoInfo[i].xstatus.count) - continue; - - protosSupporting++; - // Retrieve xstatus for protocol - CUSTOM_STATUS xstatus = { sizeof(CUSTOM_STATUS) }; - xstatus.flags = CSSF_MASK_STATUS; - xstatus.status = &status; - CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - - if (ProtoList.protoInfo[i].xstatus.enabled[status]) - return TRUE; - } - - return protosSupporting == 0; -} - -DBEVENTINFO createMsgEventInfo(MCONTACT hContact) -{ - DBEVENTINFO einfo = { sizeof(einfo) }; - einfo.eventType = EVENTTYPE_MESSAGE; - einfo.szModule = GetContactProto(hContact); - return einfo; -} - -DBEVENTINFO readEventInfo(HANDLE hDbEvent, MCONTACT hContact) -{ - if (hDbEvent == NCONVERS_BLINKID) // we need to handle nconvers' blink event - return createMsgEventInfo(hContact); - - DBEVENTINFO einfo = { sizeof(einfo) }; - db_event_get(hDbEvent, &einfo); - return einfo; -} - -BOOL checkIgnore(MCONTACT hContact, WORD eventType) -{ - return !IsIgnored(hContact, eventType); -} - -BOOL checkProtocol(char *szProto) -{ - if (!szProto) - return FALSE; - - for (int i=0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) - return ProtoList.protoInfo[i].enabled; - - return FALSE; -} - -BOOL metaCheckProtocol(char *szProto, MCONTACT hContact, WORD eventType) -{ - MCONTACT hSubContact=NULL; - - if (bMetaProtoEnabled && szProto && !strcmp(META_PROTO, szProto)) - if (hSubContact = db_mc_getMostOnline(hContact)) - szProto = GetContactProto(hSubContact); - - return checkProtocol(szProto) && checkIgnore(hSubContact?hSubContact:hContact, eventType); -} - - -BOOL checkUnopenEvents() -{ - int nIndex; - CLISTEVENT *pCLEvent; - - if (nExternCount && bFlashOnOther) - return TRUE; - - for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { - DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); - - if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || - (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || - (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || - (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) - - if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) - return TRUE; - } - - return FALSE; -} - -static void FlashThreadFunction() -{ - BOOL bEvent = FALSE; - DWORD dwEventStarted, dwFlashStarted; - BYTE data, unchangedLeds; - - while (TRUE) { - unchangedLeds = (BYTE)(LedState(VK_PAUSE) * !bFlashLed[2] + ((LedState(VK_NUMLOCK) * !bFlashLed[0])<<1) + ((LedState(VK_CAPITAL) * !bFlashLed[1])<<2)); - GetAsyncKeyState(VK_PAUSE); // empty Pause/Break's keystroke buffer - - // Start flashing - while(bEvent && bFlashingEnabled) - { - // Let's give the user the opportunity of finishing flashing manually :) - if (GetAsyncKeyState(VK_PAUSE) & 1) - break; - - if ((bFlashUntil & UNTIL_NBLINKS) && GetTickCount() > (dwFlashStarted + wBlinksNumber * 1000)) - break; - if (bFlashUntil & UNTIL_REATTENDED) { - if (bMirandaOrWindows == ACTIVE_WINDOWS && !bEmulateKeypresses) { - LASTINPUTINFO ii = { sizeof(ii) }; - GetLastInputInfo(&ii); - dwLastInput = ii.dwTime; - } - if (dwLastInput > dwEventStarted) - break; - } - if ((bFlashUntil & UNTIL_EVENTSOPEN) && !checkUnopenEvents()) - break; - if ((bFlashUntil & UNTIL_CONDITIONS) && (!checkNotifyOptions() || !checkGlobalStatus() || !checkGlobalXstatus())) - break; - - data = getBlinkingLeds(); - ToggleKeyboardLights((BYTE)(data|unchangedLeds)); - - // Wait for exit event - if (WaitForSingleObject(hExitEvent, nWaitDelay) == WAIT_OBJECT_0) - return; - } - RestoreLEDState(); - - setFlashingSequence(); - bReminderDisabled = FALSE; - - // Wait for new event - { - DWORD dwEvent; - HANDLE Objects[2]; - Objects[0] = hFlashEvent; - Objects[1] = hExitEvent; - dwEvent = WaitForMultipleObjects(2, Objects, FALSE, INFINITE); - if ((dwEvent - WAIT_OBJECT_0) == 1) - return; - } - - bEvent = TRUE; - bReminderDisabled = TRUE; - dwEventStarted = GetTickCount(); - // Wait StartDelay seconds - if (wStartDelay > 0) - Sleep(wStartDelay * 1000); - dwFlashStarted = GetTickCount(); - - } - -} - - -BOOL checkMsgTimestamp(MCONTACT hContact, HANDLE hEventCurrent, DWORD timestampCurrent) -{ - if (!bFlashIfMsgOlder) - return TRUE; - - for (HANDLE hEvent = db_event_prev(hContact, hEventCurrent); hEvent; hEvent = db_event_prev(hContact, hEvent)) { - DBEVENTINFO einfo = { sizeof(einfo) }; - if(!db_event_get(hEvent, &einfo)) { - if ((einfo.timestamp + wSecondsOlder) <= timestampCurrent) - return TRUE; - if (einfo.eventType == EVENTTYPE_MESSAGE) - return FALSE; - } - } - - return TRUE; -} - - -BOOL contactCheckProtocol(char *szProto, MCONTACT hContact, WORD eventType) -{ - if (bMetaProtoEnabled && hContact) { - MCONTACT hMetaContact = (MCONTACT)db_get_dw(hContact, META_PROTO, "Handle", 0); - if (hMetaContact && db_mc_getMeta(hContact) == hMetaContact) - return FALSE; - } - - return metaCheckProtocol(szProto, hContact, eventType); -} - - -BOOL checkStatus(char *szProto) -{ - if (!szProto) - return checkGlobalStatus(); - - return isStatusEnabled(CallProtoService(szProto, PS_GETSTATUS, 0, 0)); -} - - -BOOL checkXstatus(char *szProto) -{ - int status=0; - - if (!szProto) - return checkGlobalXstatus(); - - for (int i=0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) { - if (!ProtoList.protoInfo[i].xstatus.count) return TRUE; - - // Retrieve xstatus for protocol - CUSTOM_STATUS xstatus = { sizeof(CUSTOM_STATUS) }; - xstatus.flags = CSSF_MASK_STATUS; - xstatus.status = &status; - CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - - return ProtoList.protoInfo[i].xstatus.enabled[status]; - } - - return TRUE; -} - - -// 'Pings' the FlashThread to keep the LEDs flashing. -static int PluginMessageEventHook(WPARAM hContact, LPARAM lParam) -{ - HANDLE hEvent = (HANDLE)lParam; - - //get DBEVENTINFO without pBlob - DBEVENTINFO einfo = { sizeof(einfo) }; - if (!db_event_get(hEvent, &einfo) && !(einfo.flags & DBEF_SENT)) - if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg && checkOpenWindow(hContact) && checkMsgTimestamp(hContact, hEvent, einfo.timestamp)) || - (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || - (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || - (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) { - - if (contactCheckProtocol(einfo.szModule, hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) - - SetEvent(hFlashEvent); - } - - return 0; -} - - -// ** -// ** Checks for pending events. If it finds any, it pings the FlashThread to keep the LEDs flashing. -// ** - -static VOID CALLBACK ReminderTimer(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) -{ - int nIndex; - CLISTEVENT *pCLEvent; - - if (!bReminderDisabled && nExternCount && bFlashOnOther) { - SetEvent(hFlashEvent); - return; - } - - for (nIndex = 0; !bReminderDisabled && (pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex)); nIndex++) { - DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); - - if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || - (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || - (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || - (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) - - if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) { - - SetEvent(hFlashEvent); - return; - } - } - -} - - -// Support for third-party plugins and mBot's scripts -static INT_PTR EnableService(WPARAM wParam, LPARAM lParam) -{ - bFlashingEnabled = TRUE; - return 0; -} - -static INT_PTR DisableService(WPARAM wParam, LPARAM lParam) -{ - bFlashingEnabled = FALSE; - return 0; -} - -static INT_PTR StartBlinkService(WPARAM wParam, LPARAM lParam) -{ - nExternCount += (unsigned int)wParam; - if (bFlashOnOther && checkNotifyOptions() && checkGlobalStatus() && checkGlobalXstatus()) { - if (lParam) - useExternSequence((TCHAR *)lParam); - SetEvent(hFlashEvent); - } - - return 0; -} - -static INT_PTR EventsWereOpenedService(WPARAM wParam, LPARAM lParam) -{ - if ((unsigned int)wParam > nExternCount) - nExternCount = 0; - else - nExternCount -= (unsigned int)wParam; - - return 0; -} - - -static INT_PTR IsFlashingActiveService(WPARAM wParam, LPARAM lParam) -{ - if (!bReminderDisabled) - return 0; - - return (int)getCurrentSequenceString(); -} - - -INT_PTR NormalizeSequenceService(WPARAM wParam, LPARAM lParam) -{ - TCHAR strAux[MAX_PATH+1], *strIn = (TCHAR *)lParam; - - mir_sntprintf(strAux, MAX_PATH, _T("%s"), strIn); - mir_sntprintf(strIn, MAX_PATH, _T("%s"), normalizeCustomString(strAux)); - - return (int)strIn; -} - - -// Support for Trigger plugin -static void ForceEventsWereOpenedThread(void *eventMaxSeconds) -{ - Sleep(((WORD)eventMaxSeconds) * 1000); - CallService(MS_KBDNOTIFY_EVENTSOPENED, 1, 0); -} - - -void StartBlinkAction(char *flashSequence, WORD eventMaxSeconds) -{ - DWORD threadID = 0; - - if (eventMaxSeconds) - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ForceEventsWereOpenedThread, (void *)eventMaxSeconds, 0, &threadID); - - CallService(MS_KBDNOTIFY_STARTBLINK, 1, (LPARAM)flashSequence); -} - - -void createProcessList(void) -{ - DBVARIANT dbv; - unsigned int i, count; - - count = (unsigned int)db_get_w(NULL, KEYBDMODULE, "processcount", 0); - - ProcessList.count = 0; - ProcessList.szFileName = (TCHAR **)malloc(count * sizeof(TCHAR *)); - if (ProcessList.szFileName) { - for (i=0; i < count; i++) - if (db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i), &dbv)) - ProcessList.szFileName[i] = NULL; - else { - ProcessList.szFileName[i] = (TCHAR *)malloc(wcslen(dbv.ptszVal) + 1); - if (ProcessList.szFileName[i]) - wcscpy(ProcessList.szFileName[i], dbv.ptszVal); - db_free(&dbv); - } - ProcessList.count = count; - } - -} - - -void destroyProcessList(void) -{ - unsigned int count = ProcessList.count; - - ProcessList.count = 0; - for (unsigned int i=0; i < count; i++) - if (ProcessList.szFileName[i]) - free(ProcessList.szFileName[i]); - - if (ProcessList.szFileName) - free(ProcessList.szFileName); - ProcessList.szFileName = NULL; -} - - -void LoadSettings(void) -{ - bFlashOnMsg = db_get_b(NULL, KEYBDMODULE, "onmsg", DEF_SETTING_ONMSG); - bFlashOnURL = db_get_b(NULL, KEYBDMODULE, "onurl", DEF_SETTING_ONURL); - bFlashOnFile = db_get_b(NULL, KEYBDMODULE, "onfile", DEF_SETTING_ONFILE); - bFlashOnOther = db_get_b(NULL, KEYBDMODULE, "onother", DEF_SETTING_OTHER); - bFullScreenMode = db_get_b(NULL, KEYBDMODULE, "fscreenmode", DEF_SETTING_FSCREEN); - bScreenSaverRunning = db_get_b(NULL, KEYBDMODULE, "ssaverrunning", DEF_SETTING_SSAVER); - bWorkstationLocked = db_get_b(NULL, KEYBDMODULE, "wstationlocked", DEF_SETTING_LOCKED); - bProcessesAreRunning = db_get_b(NULL, KEYBDMODULE, "procsrunning", DEF_SETTING_PROCS); - bWorkstationActive = db_get_b(NULL, KEYBDMODULE, "wstationactive", DEF_SETTING_ACTIVE); - bFlashIfMsgOpen = db_get_b(NULL, KEYBDMODULE, "ifmsgopen", DEF_SETTING_IFMSGOPEN); - bFlashIfMsgWinNotTop = db_get_b(NULL, KEYBDMODULE, "ifmsgnottop", DEF_SETTING_IFMSGNOTTOP); - bFlashIfMsgOlder = db_get_b(NULL, KEYBDMODULE, "ifmsgolder", DEF_SETTING_IFMSGOLDER); - wSecondsOlder = db_get_w(NULL, KEYBDMODULE, "secsolder", DEF_SETTING_SECSOLDER); - bFlashUntil = db_get_b(NULL, KEYBDMODULE, "funtil", DEF_SETTING_FLASHUNTIL); - wBlinksNumber = db_get_w(NULL, KEYBDMODULE, "nblinks", DEF_SETTING_NBLINKS); - bMirandaOrWindows = db_get_b(NULL, KEYBDMODULE, "mirorwin", DEF_SETTING_MIRORWIN); - wStatusMap = db_get_w(NULL, KEYBDMODULE, "status", DEF_SETTING_STATUS); - wReminderCheck = db_get_w(NULL, KEYBDMODULE, "remcheck", DEF_SETTING_CHECKTIME); - bFlashLed[0] = !!db_get_b(NULL, KEYBDMODULE, "fnum", DEF_SETTING_FLASHNUM); - bFlashLed[1] = !!db_get_b(NULL, KEYBDMODULE, "fcaps", DEF_SETTING_FLASHCAPS); - bFlashLed[2] = !!db_get_b(NULL, KEYBDMODULE, "fscroll", DEF_SETTING_FLASHSCROLL); - bFlashEffect = db_get_b(NULL, KEYBDMODULE, "feffect", DEF_SETTING_FLASHEFFECT); - bSequenceOrder = db_get_b(NULL, KEYBDMODULE, "order", DEF_SETTING_SEQORDER); - wCustomTheme = db_get_w(NULL, KEYBDMODULE, "custom", DEF_SETTING_CUSTOMTHEME); - bTrillianLedsMsg = db_get_b(NULL, KEYBDMODULE, "ledsmsg", DEF_SETTING_LEDSMSG); - bTrillianLedsURL = db_get_b(NULL, KEYBDMODULE, "ledsurl", DEF_SETTING_LEDSURL); - bTrillianLedsFile = db_get_b(NULL, KEYBDMODULE, "ledsfile", DEF_SETTING_LEDSFILE); - bTrillianLedsOther = db_get_b(NULL, KEYBDMODULE, "ledsother", DEF_SETTING_LEDSOTHER); - wStartDelay = db_get_w(NULL, KEYBDMODULE, "sdelay", DEF_SETTING_STARTDELAY); - bFlashSpeed = db_get_b(NULL, KEYBDMODULE, "speed", DEF_SETTING_FLASHSPEED); - switch (bFlashSpeed) { - case 0: nWaitDelay = 1500; break; - case 1: nWaitDelay = 0750; break; - case 2: nWaitDelay = 0250; break; - case 3: nWaitDelay = 0150; break; - case 4: nWaitDelay = 0100; break; - default: nWaitDelay = 0050; break; - } - setFlashingSequence(); - bEmulateKeypresses = db_get_b(NULL, KEYBDMODULE, "keypresses", DEF_SETTING_KEYPRESSES); - bOverride = db_get_b(NULL, KEYBDMODULE, "override", DEF_SETTING_OVERRIDE); - // Create hidden settings (for test button) if needed - if (db_get_b(NULL, KEYBDMODULE, "testnum", -1) == -1) - db_set_b(NULL, KEYBDMODULE, "testnum", DEF_SETTING_TESTNUM); - if (db_get_b(NULL, KEYBDMODULE, "testsecs", -1) == -1) - db_set_b(NULL, KEYBDMODULE, "testsecs", DEF_SETTING_TESTSECS); - for (int i=0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].visible) { - unsigned int j; - ProtoList.protoInfo[i].enabled = db_get_b(NULL, KEYBDMODULE, ProtoList.protoInfo[i].szProto, DEF_SETTING_PROTOCOL); - for (j=0; j < ProtoList.protoInfo[i].xstatus.count; j++) - ProtoList.protoInfo[i].xstatus.enabled[j] = db_get_b(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), DEF_SETTING_XSTATUS); - } - - bMetaProtoEnabled = db_mc_isEnabled(); - - destroyProcessList(); - createProcessList(); - UnhookWindowsHooks(); - HookWindowsHooks(); -} - - -void GetWindowsVersion(void) -{ - OSVERSIONINFOEX osvi = { sizeof(OSVERSIONINFOEX) }; - BOOL bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi); - - if (!bOsVersionInfoEx) { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (!GetVersionEx((OSVERSIONINFO *)&osvi)) - osvi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; - } -} - - -void updateXstatusProto(PROTOCOL_INFO *protoInfo) -{ - if (!ProtoServiceExists(protoInfo->szProto, PS_GETCUSTOMSTATUSEX)) - return; - - // Retrieve xstatus.count - CUSTOM_STATUS xstatus = { sizeof(xstatus) }; - xstatus.flags = CSSF_STATUSES_COUNT; - xstatus.wParam = &(protoInfo->xstatus.count); - CallProtoService(protoInfo->szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - (protoInfo->xstatus.count)++; // Don't forget about xstatus=0 (None) - - // Alloc and initiailize xstatus.enabled array - protoInfo->xstatus.enabled = (BOOL *)malloc(protoInfo->xstatus.count * sizeof(BOOL)); - if (!protoInfo->xstatus.enabled) - protoInfo->xstatus.count = 0; - else - for (unsigned i=0; i < protoInfo->xstatus.count; i++) - protoInfo->xstatus.enabled[i] = FALSE; -} - - -void createProtocolList(void) -{ - PROTOACCOUNT **proto; - ProtoEnumAccounts(&ProtoList.protoCount, &proto); - ProtoList.protoInfo = (PROTOCOL_INFO *)malloc(ProtoList.protoCount * sizeof(PROTOCOL_INFO)); - if (!ProtoList.protoInfo) { - ProtoList.protoCount = 0; - return; - } - - for (int i=0; i < ProtoList.protoCount; i++) { - ProtoList.protoInfo[i].xstatus.count = 0; - ProtoList.protoInfo[i].xstatus.enabled = NULL; - ProtoList.protoInfo[i].szProto = (char *)malloc(strlen(proto[i]->szModuleName) + 1); - if (!ProtoList.protoInfo[i].szProto) { - ProtoList.protoInfo[i].enabled = FALSE; - ProtoList.protoInfo[i].visible = FALSE; - } - else { - strcpy(ProtoList.protoInfo[i].szProto, proto[i]->szModuleName); - ProtoList.protoInfo[i].enabled = FALSE; - if (!strcmp(proto[i]->szModuleName, META_PROTO)) - ProtoList.protoInfo[i].visible = FALSE; - else { - ProtoList.protoInfo[i].visible = TRUE; - updateXstatusProto(&(ProtoList.protoInfo[i])); - } - } - } -} - - -// We use the profile name to create the first part of each event name -// We do so to avoid problems between different instances of the plugin concurrently running -void createEventPrefix(TCHAR *prefixName, size_t maxLen) -{ - size_t len; - TCHAR profileName[MAX_PATH+1], *str; - - getAbsoluteProfileName(profileName, MAX_PATH); - - while (str = _tcschr(profileName, _T('\\'))) - *str = _T('/'); - if ((len = _tcslen(profileName)) <= maxLen) - _tcscpy(prefixName, profileName); - else { - str = profileName + len - maxLen / 2; - mir_sntprintf(prefixName, maxLen / 2, _T("%s"), profileName); - _tcscat(prefixName, str); - } -} - - -// ** -// ** Everything below is just Miranda init/uninit stuff -// ** - -static int OnMetaChanged(WPARAM wParam, LPARAM) -{ - bMetaProtoEnabled = wParam; - return 0; -} - -static int ModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - TCHAR eventPrefix[MAX_PATH+1], eventName[MAX_PATH+1]; - - createProtocolList(); - LoadSettings(); - - // Create some synchronisation objects - createEventPrefix(eventPrefix, MAX_PATH - 11); - mir_sntprintf(eventName, SIZEOF(eventName), _T("%s/FlashEvent"), eventPrefix); - hFlashEvent = CreateEvent(NULL, FALSE, FALSE, eventName); - mir_sntprintf(eventName, SIZEOF(eventName), _T("%s/ExitEvent"), eventPrefix); - hExitEvent = CreateEvent(NULL, FALSE, FALSE, eventName); - - hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FlashThreadFunction, NULL, 0, &IDThread); - - HookEvent(ME_MC_ENABLED, OnMetaChanged); - HookEvent(ME_DB_EVENT_ADDED, PluginMessageEventHook); - HookEvent(ME_OPT_INITIALISE, InitializeOptions); - - CreateServiceFunction(MS_KBDNOTIFY_ENABLE, EnableService); - CreateServiceFunction(MS_KBDNOTIFY_DISABLE, DisableService); - CreateServiceFunction(MS_KBDNOTIFY_STARTBLINK, StartBlinkService); - CreateServiceFunction(MS_KBDNOTIFY_EVENTSOPENED, EventsWereOpenedService); - CreateServiceFunction(MS_KBDNOTIFY_FLASHINGACTIVE, IsFlashingActiveService); - CreateServiceFunction(MS_KBDNOTIFY_NORMALSEQUENCE, NormalizeSequenceService); - return 0; -} - - - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - hInst = hinstDLL; - return TRUE; -} - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) int Load(void) -{ - mir_getLP(&pluginInfo); - - GetWindowsVersion(); - OpenKeyboardDevice(); - - HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); - return 0; -} - - - -void destroyProtocolList(void) -{ - for (int i=0; i < ProtoList.protoCount; i++) { - if (ProtoList.protoInfo[i].szProto) - free(ProtoList.protoInfo[i].szProto); - if (ProtoList.protoInfo[i].xstatus.enabled) - free(ProtoList.protoInfo[i].xstatus.enabled); - } - - ProtoList.protoCount = 0; - if (ProtoList.protoInfo) - free(ProtoList.protoInfo); -} - - -extern "C" __declspec(dllexport) int Unload(void) -{ - UnhookWindowsHooks(); - - // Wait for thread to exit - SetEvent(hExitEvent); - WaitForSingleObject(hThread, INFINITE); - - RestoreLEDState(); - CloseKeyboardDevice(); - - destroyProcessList(); - destroyProtocolList(); - - return 0; -} - - -// ========================== Windows hooks ========================== -int HookWindowsHooks() -{ - if (wReminderCheck) - hReminderTimer = SetTimer(NULL,0, wReminderCheck * 60000, ReminderTimer); - - if (bFlashUntil & UNTIL_REATTENDED) - switch (bMirandaOrWindows) { - case ACTIVE_WINDOWS: - if (bEmulateKeypresses) { - if (hMouseHook == NULL) - hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookFunction, 0, GetCurrentThreadId()); - if (hKeyBoardHook == NULL) - hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardHookFunction, 0, GetCurrentThreadId()); - } - break; - case ACTIVE_MIRANDA: - if (hMirandaMouseHook == NULL) - hMirandaMouseHook = SetWindowsHookEx(WH_MOUSE, MirandaMouseHookFunction, NULL, GetCurrentThreadId()); - if (hMirandaKeyBoardHook == NULL) - hMirandaKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, MirandaKeyBoardHookFunction, NULL, GetCurrentThreadId()); - if (hMirandaWndProcHook == NULL) - hMirandaWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, MirandaWndProcHookFunction, NULL, GetCurrentThreadId()); - } - - return 0; -} - -int UnhookWindowsHooks() -{ - if (hReminderTimer) - KillTimer(NULL, hReminderTimer); - if (hMouseHook) - UnhookWindowsHookEx(hMouseHook); - if (hKeyBoardHook) - UnhookWindowsHookEx(hKeyBoardHook); - if (hMirandaMouseHook) - UnhookWindowsHookEx(hMirandaMouseHook); - if (hMirandaKeyBoardHook) - UnhookWindowsHookEx(hMirandaKeyBoardHook); - if (hMirandaWndProcHook) - UnhookWindowsHookEx(hMirandaWndProcHook); - - hReminderTimer = 0; - hMouseHook = hKeyBoardHook = hMirandaMouseHook = hMirandaKeyBoardHook = hMirandaWndProcHook = NULL; - - return 0; -} - -static LRESULT CALLBACK MouseHookFunction(int code, WPARAM wParam, LPARAM lParam) -{ - if (code >= 0) { - /* This should handle all mouse buttons ... */ - if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) - dwLastInput = GetTickCount(); - /* ... and here it is either mouse move, hover, leave or something unexpected */ - else { - PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; - POINT pt = mouseInfo->pt; - if (pt.x!=lastGlobalMousePos.x || pt.y!=lastGlobalMousePos.y) { - lastGlobalMousePos = pt; - dwLastInput = GetTickCount(); - } - } - } - - return CallNextHookEx(hMouseHook, code, wParam, lParam); -} - -static LRESULT CALLBACK KeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) -{ - if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) - dwLastInput = GetTickCount(); - - return CallNextHookEx(hKeyBoardHook, code, wParam, lParam); -} - -static LRESULT CALLBACK MirandaMouseHookFunction(int code, WPARAM wParam, LPARAM lParam) -{ - static POINT lastMousePos = {0, 0}; - - if (code >= 0) { - /* Movement mouse messages are for some reason incoming in inactive/background window too, that is not input */ - DWORD pid; - GetWindowThreadProcessId(GetForegroundWindow(), &pid); - if(pid == GetCurrentProcessId()) { - /* This should handle all mouse buttons ... */ - if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) - dwLastInput = GetTickCount(); - /* ... and here it is either mouse move, hover, leave or something unexpected */ - else { - PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; - POINT pt = mouseInfo->pt; - if (pt.x!=lastMousePos.x || pt.y!=lastMousePos.y) { - lastMousePos = pt; - dwLastInput = GetTickCount(); - } - } - } - } - - return CallNextHookEx(hMirandaMouseHook, code, wParam, lParam); -} - -static LRESULT CALLBACK MirandaKeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) { - - if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) - dwLastInput = GetTickCount(); - - return CallNextHookEx(hMirandaKeyBoardHook, code, wParam, lParam); -} - -static LRESULT CALLBACK MirandaWndProcHookFunction(int code, WPARAM wParam, LPARAM lParam) { - - if (code >= 0) { - /* WM_ACTIVATEAPP with nonzero wParam means someone brought miranda to foreground, that equals to input */ - PCWPSTRUCT cwpInfo = (PCWPSTRUCT)lParam; - if(cwpInfo->message == WM_ACTIVATEAPP && cwpInfo->wParam) - dwLastInput = GetTickCount(); - } - - return CallNextHookEx(hMirandaWndProcHook, code, wParam, lParam); -} - -BOOL CheckMsgWnd(MCONTACT hContact, BOOL *focus) -{ - if (hContact) { - MessageWindowData mwd = { sizeof(MessageWindowData) }; - MessageWindowInputData mwid = { sizeof(MessageWindowInputData) }; - mwid.hContact = hContact; - mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; - mwd.hContact = hContact; - if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow) { - *focus = mwd.uState & MSG_WINDOW_STATE_FOCUS; - return TRUE; - } - } - - *focus = FALSE; - return FALSE; -} - - -void countUnopenEvents(int *msgCount, int *fileCount, int *urlCount, int *otherCount) -{ - int nIndex; - CLISTEVENT *pCLEvent; - - for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { - DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); - - if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) - switch (einfo.eventType) { - case EVENTTYPE_MESSAGE: - if (bFlashOnMsg) - (*msgCount)++; - break; - case EVENTTYPE_URL: - if (bFlashOnURL) - (*urlCount)++; - break; - case EVENTTYPE_FILE: - if (bFlashOnFile) - (*fileCount)++; - break; - default: - if (bFlashOnOther) - (*otherCount)++; - } - } - if (bFlashOnOther) - (*otherCount) += nExternCount; -} +/* + KeyboardNotify plugin v1.5 for Miranda IM + _________________________________________ + + Copyright (C) 2002,2003 Martin Öberg + Copyright (C) 2004 Std + Copyright (C) 2005,2006 TioDuke (tioduke@yahoo.ca) + + + 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 "Common.h" + +#define NCONVERS_BLINKID ((HANDLE)123456) //nconvers' random identifier used to flash an icon for "incoming message" on contact list + +HINSTANCE hInst; + +int hLangpack; + +DWORD IDThread = 0; +HANDLE hThread = NULL; +HANDLE hFlashEvent; +HANDLE hExitEvent; + +HHOOK hMirandaMouseHook = NULL; +HHOOK hMirandaKeyBoardHook = NULL; +HHOOK hMirandaWndProcHook = NULL; +UINT hReminderTimer = 0; + +HHOOK hMouseHook = NULL; +HHOOK hKeyBoardHook = NULL; +BYTE bEmulateKeypresses = 0; +DWORD dwLastInput = 0; +POINT lastGlobalMousePos = {0, 0}; + +BYTE bFlashOnMsg; +BYTE bFlashOnURL; +BYTE bFlashOnFile; +BYTE bFlashOnOther; +BYTE bFullScreenMode; +BYTE bScreenSaverRunning; +BYTE bWorkstationLocked; +BYTE bProcessesAreRunning; +BYTE bWorkstationActive; +BYTE bFlashIfMsgOpen; +BYTE bFlashIfMsgWinNotTop; +BYTE bFlashIfMsgOlder; +WORD wSecondsOlder; +BYTE bFlashUntil; +WORD wBlinksNumber; +BYTE bMirandaOrWindows; +WORD wStatusMap; +WORD wReminderCheck; +BYTE bFlashLed[3]; +BYTE bFlashEffect; +BYTE bSequenceOrder; +WORD wCustomTheme; +WORD wStartDelay; +BYTE bFlashSpeed; +BYTE bOverride; +BYTE bTrillianLedsMsg; +BYTE bTrillianLedsURL; +BYTE bTrillianLedsFile; +BYTE bTrillianLedsOther; + +PROTOCOL_LIST ProtoList = {0, NULL}; +PROCESS_LIST ProcessList = {0, NULL}; + +int nWaitDelay; +unsigned int nExternCount = 0; +BOOL bFlashingEnabled = TRUE; +BOOL bReminderDisabled = FALSE; + +BYTE bMetaProtoEnabled = 0; + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + //{119D7288-2050-448D-9900-D86AC70426BF} + {0x119d7288, 0x2050, 0x448d, {0x99, 0x00, 0xd8, 0x6a, 0xc7, 0x04, 0x26, 0xbf}} +}; + +int InitializeOptions(WPARAM,LPARAM); +void LoadSettings(void); +int HookWindowsHooks(void); +int UnhookWindowsHooks(void); +static LRESULT CALLBACK MouseHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK KeyBoardHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK MirandaMouseHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK MirandaKeyBoardHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK MirandaWndProcHookFunction(int, WPARAM, LPARAM); +BOOL CheckMsgWnd(MCONTACT, BOOL *); + +BOOL checkOpenWindow(MCONTACT hContact) +{ + if (bFlashIfMsgOpen && !bFlashIfMsgWinNotTop) + return TRUE; + + BOOL focus, found = CheckMsgWnd(hContact, &focus); + if (!found && bMetaProtoEnabled) + found = CheckMsgWnd(db_mc_getMeta(hContact), &focus); + + if (!found) + return TRUE; + + if (bFlashIfMsgOpen && !focus) + return TRUE; + + return FALSE; +} + +BOOL checkNotifyOptions() +{ + BOOL screenSaverIsRunning = IsScreenSaverRunning(); + if (screenSaverIsRunning && bScreenSaverRunning) + return TRUE; + + BOOL workstationIsLocked = IsWorkstationLocked(); + if (workstationIsLocked && bWorkstationLocked) + return TRUE; + + BOOL fullScreenMode = IsFullScreen() && !screenSaverIsRunning; + if (fullScreenMode && bFullScreenMode) + return TRUE; + + BOOL processesRunning = areThereProcessesRunning(); + if (processesRunning && bProcessesAreRunning) + return TRUE; + + return (!fullScreenMode && !screenSaverIsRunning && !workstationIsLocked && !processesRunning && bWorkstationActive); +} + +BOOL isStatusEnabled(int status) +{ + switch (status) { + case ID_STATUS_OFFLINE: return wStatusMap & MAP_OFFLINE; + case ID_STATUS_ONLINE: return wStatusMap & MAP_ONLINE; + case ID_STATUS_AWAY: return wStatusMap & MAP_AWAY; + case ID_STATUS_NA: return wStatusMap & MAP_NA; + case ID_STATUS_OCCUPIED: return wStatusMap & MAP_OCCUPIED; + case ID_STATUS_DND: return wStatusMap & MAP_DND; + case ID_STATUS_FREECHAT: return wStatusMap & MAP_FREECHAT; + case ID_STATUS_INVISIBLE: return wStatusMap & MAP_INVISIBLE; + case ID_STATUS_ONTHEPHONE: return wStatusMap & MAP_ONTHEPHONE; + case ID_STATUS_OUTTOLUNCH: return wStatusMap & MAP_OUTTOLUNCH; + default: return FALSE; + } +} + +BOOL checkGlobalStatus() +{ + return isStatusEnabled(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)); +} + +BOOL checkGlobalXstatus() +{ + int protosSupporting=0, status=0; + + for (int i=0; i < ProtoList.protoCount; i++) { + if ( !ProtoList.protoInfo[i].enabled || !ProtoList.protoInfo[i].xstatus.count) + continue; + + protosSupporting++; + // Retrieve xstatus for protocol + CUSTOM_STATUS xstatus = { sizeof(CUSTOM_STATUS) }; + xstatus.flags = CSSF_MASK_STATUS; + xstatus.status = &status; + CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + + if (ProtoList.protoInfo[i].xstatus.enabled[status]) + return TRUE; + } + + return protosSupporting == 0; +} + +DBEVENTINFO createMsgEventInfo(MCONTACT hContact) +{ + DBEVENTINFO einfo = { sizeof(einfo) }; + einfo.eventType = EVENTTYPE_MESSAGE; + einfo.szModule = GetContactProto(hContact); + return einfo; +} + +DBEVENTINFO readEventInfo(HANDLE hDbEvent, MCONTACT hContact) +{ + if (hDbEvent == NCONVERS_BLINKID) // we need to handle nconvers' blink event + return createMsgEventInfo(hContact); + + DBEVENTINFO einfo = { sizeof(einfo) }; + db_event_get(hDbEvent, &einfo); + return einfo; +} + +BOOL checkIgnore(MCONTACT hContact, WORD eventType) +{ + return !IsIgnored(hContact, eventType); +} + +BOOL checkProtocol(char *szProto) +{ + if (!szProto) + return FALSE; + + for (int i=0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) + return ProtoList.protoInfo[i].enabled; + + return FALSE; +} + +BOOL metaCheckProtocol(char *szProto, MCONTACT hContact, WORD eventType) +{ + MCONTACT hSubContact=NULL; + + if (bMetaProtoEnabled && szProto && !strcmp(META_PROTO, szProto)) + if (hSubContact = db_mc_getMostOnline(hContact)) + szProto = GetContactProto(hSubContact); + + return checkProtocol(szProto) && checkIgnore(hSubContact?hSubContact:hContact, eventType); +} + + +BOOL checkUnopenEvents() +{ + int nIndex; + CLISTEVENT *pCLEvent; + + if (nExternCount && bFlashOnOther) + return TRUE; + + for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { + DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); + + if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || + (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || + (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || + (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) + + if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) + return TRUE; + } + + return FALSE; +} + +static void FlashThreadFunction() +{ + BOOL bEvent = FALSE; + DWORD dwEventStarted, dwFlashStarted; + BYTE data, unchangedLeds; + + while (TRUE) { + unchangedLeds = (BYTE)(LedState(VK_PAUSE) * !bFlashLed[2] + ((LedState(VK_NUMLOCK) * !bFlashLed[0])<<1) + ((LedState(VK_CAPITAL) * !bFlashLed[1])<<2)); + GetAsyncKeyState(VK_PAUSE); // empty Pause/Break's keystroke buffer + + // Start flashing + while(bEvent && bFlashingEnabled) + { + // Let's give the user the opportunity of finishing flashing manually :) + if (GetAsyncKeyState(VK_PAUSE) & 1) + break; + + if ((bFlashUntil & UNTIL_NBLINKS) && GetTickCount() > (dwFlashStarted + wBlinksNumber * 1000)) + break; + if (bFlashUntil & UNTIL_REATTENDED) { + if (bMirandaOrWindows == ACTIVE_WINDOWS && !bEmulateKeypresses) { + LASTINPUTINFO ii = { sizeof(ii) }; + GetLastInputInfo(&ii); + dwLastInput = ii.dwTime; + } + if (dwLastInput > dwEventStarted) + break; + } + if ((bFlashUntil & UNTIL_EVENTSOPEN) && !checkUnopenEvents()) + break; + if ((bFlashUntil & UNTIL_CONDITIONS) && (!checkNotifyOptions() || !checkGlobalStatus() || !checkGlobalXstatus())) + break; + + data = getBlinkingLeds(); + ToggleKeyboardLights((BYTE)(data|unchangedLeds)); + + // Wait for exit event + if (WaitForSingleObject(hExitEvent, nWaitDelay) == WAIT_OBJECT_0) + return; + } + RestoreLEDState(); + + setFlashingSequence(); + bReminderDisabled = FALSE; + + // Wait for new event + { + DWORD dwEvent; + HANDLE Objects[2]; + Objects[0] = hFlashEvent; + Objects[1] = hExitEvent; + dwEvent = WaitForMultipleObjects(2, Objects, FALSE, INFINITE); + if ((dwEvent - WAIT_OBJECT_0) == 1) + return; + } + + bEvent = TRUE; + bReminderDisabled = TRUE; + dwEventStarted = GetTickCount(); + // Wait StartDelay seconds + if (wStartDelay > 0) + Sleep(wStartDelay * 1000); + dwFlashStarted = GetTickCount(); + + } + +} + + +BOOL checkMsgTimestamp(MCONTACT hContact, HANDLE hEventCurrent, DWORD timestampCurrent) +{ + if (!bFlashIfMsgOlder) + return TRUE; + + for (HANDLE hEvent = db_event_prev(hContact, hEventCurrent); hEvent; hEvent = db_event_prev(hContact, hEvent)) { + DBEVENTINFO einfo = { sizeof(einfo) }; + if(!db_event_get(hEvent, &einfo)) { + if ((einfo.timestamp + wSecondsOlder) <= timestampCurrent) + return TRUE; + if (einfo.eventType == EVENTTYPE_MESSAGE) + return FALSE; + } + } + + return TRUE; +} + + +BOOL contactCheckProtocol(char *szProto, MCONTACT hContact, WORD eventType) +{ + if (bMetaProtoEnabled && hContact) { + MCONTACT hMetaContact = (MCONTACT)db_get_dw(hContact, META_PROTO, "Handle", 0); + if (hMetaContact && db_mc_getMeta(hContact) == hMetaContact) + return FALSE; + } + + return metaCheckProtocol(szProto, hContact, eventType); +} + + +BOOL checkStatus(char *szProto) +{ + if (!szProto) + return checkGlobalStatus(); + + return isStatusEnabled(CallProtoService(szProto, PS_GETSTATUS, 0, 0)); +} + + +BOOL checkXstatus(char *szProto) +{ + int status=0; + + if (!szProto) + return checkGlobalXstatus(); + + for (int i=0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) { + if (!ProtoList.protoInfo[i].xstatus.count) return TRUE; + + // Retrieve xstatus for protocol + CUSTOM_STATUS xstatus = { sizeof(CUSTOM_STATUS) }; + xstatus.flags = CSSF_MASK_STATUS; + xstatus.status = &status; + CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + + return ProtoList.protoInfo[i].xstatus.enabled[status]; + } + + return TRUE; +} + + +// 'Pings' the FlashThread to keep the LEDs flashing. +static int PluginMessageEventHook(WPARAM hContact, LPARAM lParam) +{ + HANDLE hEvent = (HANDLE)lParam; + + //get DBEVENTINFO without pBlob + DBEVENTINFO einfo = { sizeof(einfo) }; + if (!db_event_get(hEvent, &einfo) && !(einfo.flags & DBEF_SENT)) + if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg && checkOpenWindow(hContact) && checkMsgTimestamp(hContact, hEvent, einfo.timestamp)) || + (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || + (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || + (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) { + + if (contactCheckProtocol(einfo.szModule, hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) + + SetEvent(hFlashEvent); + } + + return 0; +} + + +// ** +// ** Checks for pending events. If it finds any, it pings the FlashThread to keep the LEDs flashing. +// ** + +static VOID CALLBACK ReminderTimer(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) +{ + int nIndex; + CLISTEVENT *pCLEvent; + + if (!bReminderDisabled && nExternCount && bFlashOnOther) { + SetEvent(hFlashEvent); + return; + } + + for (nIndex = 0; !bReminderDisabled && (pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex)); nIndex++) { + DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); + + if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || + (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || + (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || + (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) + + if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) { + + SetEvent(hFlashEvent); + return; + } + } + +} + + +// Support for third-party plugins and mBot's scripts +static INT_PTR EnableService(WPARAM wParam, LPARAM lParam) +{ + bFlashingEnabled = TRUE; + return 0; +} + +static INT_PTR DisableService(WPARAM wParam, LPARAM lParam) +{ + bFlashingEnabled = FALSE; + return 0; +} + +static INT_PTR StartBlinkService(WPARAM wParam, LPARAM lParam) +{ + nExternCount += (unsigned int)wParam; + if (bFlashOnOther && checkNotifyOptions() && checkGlobalStatus() && checkGlobalXstatus()) { + if (lParam) + useExternSequence((TCHAR *)lParam); + SetEvent(hFlashEvent); + } + + return 0; +} + +static INT_PTR EventsWereOpenedService(WPARAM wParam, LPARAM lParam) +{ + if ((unsigned int)wParam > nExternCount) + nExternCount = 0; + else + nExternCount -= (unsigned int)wParam; + + return 0; +} + + +static INT_PTR IsFlashingActiveService(WPARAM wParam, LPARAM lParam) +{ + if (!bReminderDisabled) + return 0; + + return (int)getCurrentSequenceString(); +} + + +INT_PTR NormalizeSequenceService(WPARAM wParam, LPARAM lParam) +{ + TCHAR strAux[MAX_PATH+1], *strIn = (TCHAR *)lParam; + + mir_sntprintf(strAux, MAX_PATH, _T("%s"), strIn); + mir_sntprintf(strIn, MAX_PATH, _T("%s"), normalizeCustomString(strAux)); + + return (int)strIn; +} + + +// Support for Trigger plugin +static void ForceEventsWereOpenedThread(void *eventMaxSeconds) +{ + Sleep(((WORD)eventMaxSeconds) * 1000); + CallService(MS_KBDNOTIFY_EVENTSOPENED, 1, 0); +} + + +void StartBlinkAction(char *flashSequence, WORD eventMaxSeconds) +{ + DWORD threadID = 0; + + if (eventMaxSeconds) + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ForceEventsWereOpenedThread, (void *)eventMaxSeconds, 0, &threadID); + + CallService(MS_KBDNOTIFY_STARTBLINK, 1, (LPARAM)flashSequence); +} + + +void createProcessList(void) +{ + DBVARIANT dbv; + unsigned int i, count; + + count = (unsigned int)db_get_w(NULL, KEYBDMODULE, "processcount", 0); + + ProcessList.count = 0; + ProcessList.szFileName = (TCHAR **)malloc(count * sizeof(TCHAR *)); + if (ProcessList.szFileName) { + for (i=0; i < count; i++) + if (db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i), &dbv)) + ProcessList.szFileName[i] = NULL; + else { + ProcessList.szFileName[i] = (TCHAR *)malloc(wcslen(dbv.ptszVal) + 1); + if (ProcessList.szFileName[i]) + wcscpy(ProcessList.szFileName[i], dbv.ptszVal); + db_free(&dbv); + } + ProcessList.count = count; + } + +} + + +void destroyProcessList(void) +{ + if (ProcessList.szFileName == NULL) + return; + for (int i = 0; i < ProcessList.count; i ++) { + if (ProcessList.szFileName[i]) { + free(ProcessList.szFileName[i]); + } + } + free(ProcessList.szFileName); + ProcessList.count = 0; + ProcessList.szFileName = NULL; +} + + +void LoadSettings(void) +{ + bFlashOnMsg = db_get_b(NULL, KEYBDMODULE, "onmsg", DEF_SETTING_ONMSG); + bFlashOnURL = db_get_b(NULL, KEYBDMODULE, "onurl", DEF_SETTING_ONURL); + bFlashOnFile = db_get_b(NULL, KEYBDMODULE, "onfile", DEF_SETTING_ONFILE); + bFlashOnOther = db_get_b(NULL, KEYBDMODULE, "onother", DEF_SETTING_OTHER); + bFullScreenMode = db_get_b(NULL, KEYBDMODULE, "fscreenmode", DEF_SETTING_FSCREEN); + bScreenSaverRunning = db_get_b(NULL, KEYBDMODULE, "ssaverrunning", DEF_SETTING_SSAVER); + bWorkstationLocked = db_get_b(NULL, KEYBDMODULE, "wstationlocked", DEF_SETTING_LOCKED); + bProcessesAreRunning = db_get_b(NULL, KEYBDMODULE, "procsrunning", DEF_SETTING_PROCS); + bWorkstationActive = db_get_b(NULL, KEYBDMODULE, "wstationactive", DEF_SETTING_ACTIVE); + bFlashIfMsgOpen = db_get_b(NULL, KEYBDMODULE, "ifmsgopen", DEF_SETTING_IFMSGOPEN); + bFlashIfMsgWinNotTop = db_get_b(NULL, KEYBDMODULE, "ifmsgnottop", DEF_SETTING_IFMSGNOTTOP); + bFlashIfMsgOlder = db_get_b(NULL, KEYBDMODULE, "ifmsgolder", DEF_SETTING_IFMSGOLDER); + wSecondsOlder = db_get_w(NULL, KEYBDMODULE, "secsolder", DEF_SETTING_SECSOLDER); + bFlashUntil = db_get_b(NULL, KEYBDMODULE, "funtil", DEF_SETTING_FLASHUNTIL); + wBlinksNumber = db_get_w(NULL, KEYBDMODULE, "nblinks", DEF_SETTING_NBLINKS); + bMirandaOrWindows = db_get_b(NULL, KEYBDMODULE, "mirorwin", DEF_SETTING_MIRORWIN); + wStatusMap = db_get_w(NULL, KEYBDMODULE, "status", DEF_SETTING_STATUS); + wReminderCheck = db_get_w(NULL, KEYBDMODULE, "remcheck", DEF_SETTING_CHECKTIME); + bFlashLed[0] = !!db_get_b(NULL, KEYBDMODULE, "fnum", DEF_SETTING_FLASHNUM); + bFlashLed[1] = !!db_get_b(NULL, KEYBDMODULE, "fcaps", DEF_SETTING_FLASHCAPS); + bFlashLed[2] = !!db_get_b(NULL, KEYBDMODULE, "fscroll", DEF_SETTING_FLASHSCROLL); + bFlashEffect = db_get_b(NULL, KEYBDMODULE, "feffect", DEF_SETTING_FLASHEFFECT); + bSequenceOrder = db_get_b(NULL, KEYBDMODULE, "order", DEF_SETTING_SEQORDER); + wCustomTheme = db_get_w(NULL, KEYBDMODULE, "custom", DEF_SETTING_CUSTOMTHEME); + bTrillianLedsMsg = db_get_b(NULL, KEYBDMODULE, "ledsmsg", DEF_SETTING_LEDSMSG); + bTrillianLedsURL = db_get_b(NULL, KEYBDMODULE, "ledsurl", DEF_SETTING_LEDSURL); + bTrillianLedsFile = db_get_b(NULL, KEYBDMODULE, "ledsfile", DEF_SETTING_LEDSFILE); + bTrillianLedsOther = db_get_b(NULL, KEYBDMODULE, "ledsother", DEF_SETTING_LEDSOTHER); + wStartDelay = db_get_w(NULL, KEYBDMODULE, "sdelay", DEF_SETTING_STARTDELAY); + bFlashSpeed = db_get_b(NULL, KEYBDMODULE, "speed", DEF_SETTING_FLASHSPEED); + switch (bFlashSpeed) { + case 0: nWaitDelay = 1500; break; + case 1: nWaitDelay = 0750; break; + case 2: nWaitDelay = 0250; break; + case 3: nWaitDelay = 0150; break; + case 4: nWaitDelay = 0100; break; + default: nWaitDelay = 0050; break; + } + setFlashingSequence(); + bEmulateKeypresses = db_get_b(NULL, KEYBDMODULE, "keypresses", DEF_SETTING_KEYPRESSES); + bOverride = db_get_b(NULL, KEYBDMODULE, "override", DEF_SETTING_OVERRIDE); + // Create hidden settings (for test button) if needed + if (db_get_b(NULL, KEYBDMODULE, "testnum", -1) == -1) + db_set_b(NULL, KEYBDMODULE, "testnum", DEF_SETTING_TESTNUM); + if (db_get_b(NULL, KEYBDMODULE, "testsecs", -1) == -1) + db_set_b(NULL, KEYBDMODULE, "testsecs", DEF_SETTING_TESTSECS); + for (int i=0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].visible) { + unsigned int j; + ProtoList.protoInfo[i].enabled = db_get_b(NULL, KEYBDMODULE, ProtoList.protoInfo[i].szProto, DEF_SETTING_PROTOCOL); + for (j=0; j < ProtoList.protoInfo[i].xstatus.count; j++) + ProtoList.protoInfo[i].xstatus.enabled[j] = db_get_b(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), DEF_SETTING_XSTATUS); + } + + bMetaProtoEnabled = db_mc_isEnabled(); + + destroyProcessList(); + createProcessList(); + UnhookWindowsHooks(); + HookWindowsHooks(); +} + + +void GetWindowsVersion(void) +{ + OSVERSIONINFOEX osvi = { sizeof(OSVERSIONINFOEX) }; + BOOL bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi); + + if (!bOsVersionInfoEx) { + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (!GetVersionEx((OSVERSIONINFO *)&osvi)) + osvi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; + } +} + + +void updateXstatusProto(PROTOCOL_INFO *protoInfo) +{ + if (!ProtoServiceExists(protoInfo->szProto, PS_GETCUSTOMSTATUSEX)) + return; + + // Retrieve xstatus.count + CUSTOM_STATUS xstatus = { sizeof(xstatus) }; + xstatus.flags = CSSF_STATUSES_COUNT; + xstatus.wParam = &(protoInfo->xstatus.count); + CallProtoService(protoInfo->szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + (protoInfo->xstatus.count)++; // Don't forget about xstatus=0 (None) + + // Alloc and initiailize xstatus.enabled array + protoInfo->xstatus.enabled = (BOOL *)malloc(protoInfo->xstatus.count * sizeof(BOOL)); + if (!protoInfo->xstatus.enabled) + protoInfo->xstatus.count = 0; + else + for (unsigned i=0; i < protoInfo->xstatus.count; i++) + protoInfo->xstatus.enabled[i] = FALSE; +} + + +void createProtocolList(void) +{ + PROTOACCOUNT **proto; + ProtoEnumAccounts(&ProtoList.protoCount, &proto); + ProtoList.protoInfo = (PROTOCOL_INFO *)malloc(ProtoList.protoCount * sizeof(PROTOCOL_INFO)); + if (!ProtoList.protoInfo) { + ProtoList.protoCount = 0; + return; + } + + for (int i=0; i < ProtoList.protoCount; i++) { + ProtoList.protoInfo[i].xstatus.count = 0; + ProtoList.protoInfo[i].xstatus.enabled = NULL; + ProtoList.protoInfo[i].szProto = (char *)malloc(strlen(proto[i]->szModuleName) + 1); + if (!ProtoList.protoInfo[i].szProto) { + ProtoList.protoInfo[i].enabled = FALSE; + ProtoList.protoInfo[i].visible = FALSE; + } + else { + strcpy(ProtoList.protoInfo[i].szProto, proto[i]->szModuleName); + ProtoList.protoInfo[i].enabled = FALSE; + if (!strcmp(proto[i]->szModuleName, META_PROTO)) + ProtoList.protoInfo[i].visible = FALSE; + else { + ProtoList.protoInfo[i].visible = TRUE; + updateXstatusProto(&(ProtoList.protoInfo[i])); + } + } + } +} + + +// We use the profile name to create the first part of each event name +// We do so to avoid problems between different instances of the plugin concurrently running +void createEventPrefix(TCHAR *prefixName, size_t maxLen) +{ + size_t len; + TCHAR profileName[MAX_PATH+1], *str; + + getAbsoluteProfileName(profileName, MAX_PATH); + + while (str = _tcschr(profileName, _T('\\'))) + *str = _T('/'); + if ((len = _tcslen(profileName)) <= maxLen) + _tcscpy(prefixName, profileName); + else { + str = profileName + len - maxLen / 2; + mir_sntprintf(prefixName, maxLen / 2, _T("%s"), profileName); + _tcscat(prefixName, str); + } +} + + +// ** +// ** Everything below is just Miranda init/uninit stuff +// ** + +static int OnMetaChanged(WPARAM wParam, LPARAM) +{ + bMetaProtoEnabled = wParam; + return 0; +} + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + TCHAR eventPrefix[MAX_PATH+1], eventName[MAX_PATH+1]; + + createProtocolList(); + LoadSettings(); + + // Create some synchronisation objects + createEventPrefix(eventPrefix, MAX_PATH - 11); + mir_sntprintf(eventName, SIZEOF(eventName), _T("%s/FlashEvent"), eventPrefix); + hFlashEvent = CreateEvent(NULL, FALSE, FALSE, eventName); + mir_sntprintf(eventName, SIZEOF(eventName), _T("%s/ExitEvent"), eventPrefix); + hExitEvent = CreateEvent(NULL, FALSE, FALSE, eventName); + + hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FlashThreadFunction, NULL, 0, &IDThread); + + HookEvent(ME_MC_ENABLED, OnMetaChanged); + HookEvent(ME_DB_EVENT_ADDED, PluginMessageEventHook); + HookEvent(ME_OPT_INITIALISE, InitializeOptions); + + CreateServiceFunction(MS_KBDNOTIFY_ENABLE, EnableService); + CreateServiceFunction(MS_KBDNOTIFY_DISABLE, DisableService); + CreateServiceFunction(MS_KBDNOTIFY_STARTBLINK, StartBlinkService); + CreateServiceFunction(MS_KBDNOTIFY_EVENTSOPENED, EventsWereOpenedService); + CreateServiceFunction(MS_KBDNOTIFY_FLASHINGACTIVE, IsFlashingActiveService); + CreateServiceFunction(MS_KBDNOTIFY_NORMALSEQUENCE, NormalizeSequenceService); + return 0; +} + + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) int Load(void) +{ + mir_getLP(&pluginInfo); + + GetWindowsVersion(); + OpenKeyboardDevice(); + + HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + return 0; +} + + + +void destroyProtocolList(void) +{ + if (ProtoList.protoInfo == NULL) + return; + for (int i = 0; i < ProtoList.protoCount; i ++) { + if (ProtoList.protoInfo[i].szProto) + free(ProtoList.protoInfo[i].szProto); + if (ProtoList.protoInfo[i].xstatus.enabled) + free(ProtoList.protoInfo[i].xstatus.enabled); + } + + free(ProtoList.protoInfo); + ProtoList.protoCount = 0; + ProtoList.protoInfo = NULL; +} + + +extern "C" __declspec(dllexport) int Unload(void) +{ + UnhookWindowsHooks(); + + // Wait for thread to exit + SetEvent(hExitEvent); + WaitForSingleObject(hThread, INFINITE); + + RestoreLEDState(); + CloseKeyboardDevice(); + + destroyProcessList(); + destroyProtocolList(); + + return 0; +} + + +// ========================== Windows hooks ========================== +int HookWindowsHooks() +{ + if (wReminderCheck) + hReminderTimer = SetTimer(NULL,0, wReminderCheck * 60000, ReminderTimer); + + if (bFlashUntil & UNTIL_REATTENDED) + switch (bMirandaOrWindows) { + case ACTIVE_WINDOWS: + if (bEmulateKeypresses) { + if (hMouseHook == NULL) + hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookFunction, 0, GetCurrentThreadId()); + if (hKeyBoardHook == NULL) + hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardHookFunction, 0, GetCurrentThreadId()); + } + break; + case ACTIVE_MIRANDA: + if (hMirandaMouseHook == NULL) + hMirandaMouseHook = SetWindowsHookEx(WH_MOUSE, MirandaMouseHookFunction, NULL, GetCurrentThreadId()); + if (hMirandaKeyBoardHook == NULL) + hMirandaKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, MirandaKeyBoardHookFunction, NULL, GetCurrentThreadId()); + if (hMirandaWndProcHook == NULL) + hMirandaWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, MirandaWndProcHookFunction, NULL, GetCurrentThreadId()); + } + + return 0; +} + +int UnhookWindowsHooks() +{ + if (hReminderTimer) + KillTimer(NULL, hReminderTimer); + if (hMouseHook) + UnhookWindowsHookEx(hMouseHook); + if (hKeyBoardHook) + UnhookWindowsHookEx(hKeyBoardHook); + if (hMirandaMouseHook) + UnhookWindowsHookEx(hMirandaMouseHook); + if (hMirandaKeyBoardHook) + UnhookWindowsHookEx(hMirandaKeyBoardHook); + if (hMirandaWndProcHook) + UnhookWindowsHookEx(hMirandaWndProcHook); + + hReminderTimer = 0; + hMouseHook = hKeyBoardHook = hMirandaMouseHook = hMirandaKeyBoardHook = hMirandaWndProcHook = NULL; + + return 0; +} + +static LRESULT CALLBACK MouseHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0) { + /* This should handle all mouse buttons ... */ + if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) + dwLastInput = GetTickCount(); + /* ... and here it is either mouse move, hover, leave or something unexpected */ + else { + PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; + POINT pt = mouseInfo->pt; + if (pt.x!=lastGlobalMousePos.x || pt.y!=lastGlobalMousePos.y) { + lastGlobalMousePos = pt; + dwLastInput = GetTickCount(); + } + } + } + + return CallNextHookEx(hMouseHook, code, wParam, lParam); +} + +static LRESULT CALLBACK KeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) + dwLastInput = GetTickCount(); + + return CallNextHookEx(hKeyBoardHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MirandaMouseHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + static POINT lastMousePos = {0, 0}; + + if (code >= 0) { + /* Movement mouse messages are for some reason incoming in inactive/background window too, that is not input */ + DWORD pid; + GetWindowThreadProcessId(GetForegroundWindow(), &pid); + if(pid == GetCurrentProcessId()) { + /* This should handle all mouse buttons ... */ + if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) + dwLastInput = GetTickCount(); + /* ... and here it is either mouse move, hover, leave or something unexpected */ + else { + PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; + POINT pt = mouseInfo->pt; + if (pt.x!=lastMousePos.x || pt.y!=lastMousePos.y) { + lastMousePos = pt; + dwLastInput = GetTickCount(); + } + } + } + } + + return CallNextHookEx(hMirandaMouseHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MirandaKeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) { + + if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) + dwLastInput = GetTickCount(); + + return CallNextHookEx(hMirandaKeyBoardHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MirandaWndProcHookFunction(int code, WPARAM wParam, LPARAM lParam) { + + if (code >= 0) { + /* WM_ACTIVATEAPP with nonzero wParam means someone brought miranda to foreground, that equals to input */ + PCWPSTRUCT cwpInfo = (PCWPSTRUCT)lParam; + if(cwpInfo->message == WM_ACTIVATEAPP && cwpInfo->wParam) + dwLastInput = GetTickCount(); + } + + return CallNextHookEx(hMirandaWndProcHook, code, wParam, lParam); +} + +BOOL CheckMsgWnd(MCONTACT hContact, BOOL *focus) +{ + if (hContact) { + MessageWindowData mwd = { sizeof(MessageWindowData) }; + MessageWindowInputData mwid = { sizeof(MessageWindowInputData) }; + mwid.hContact = hContact; + mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; + mwd.hContact = hContact; + if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow) { + *focus = mwd.uState & MSG_WINDOW_STATE_FOCUS; + return TRUE; + } + } + + *focus = FALSE; + return FALSE; +} + + +void countUnopenEvents(int *msgCount, int *fileCount, int *urlCount, int *otherCount) +{ + int nIndex; + CLISTEVENT *pCLEvent; + + for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { + DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); + + if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) + switch (einfo.eventType) { + case EVENTTYPE_MESSAGE: + if (bFlashOnMsg) + (*msgCount)++; + break; + case EVENTTYPE_URL: + if (bFlashOnURL) + (*urlCount)++; + break; + case EVENTTYPE_FILE: + if (bFlashOnFile) + (*fileCount)++; + break; + default: + if (bFlashOnOther) + (*otherCount)++; + } + } + if (bFlashOnOther) + (*otherCount) += nExternCount; +} diff --git a/plugins/KeyboardNotify/src/options.cpp b/plugins/KeyboardNotify/src/options.cpp index 0f853b03e9..99c459e453 100644 --- a/plugins/KeyboardNotify/src/options.cpp +++ b/plugins/KeyboardNotify/src/options.cpp @@ -1,1475 +1,1476 @@ -/* - -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 "Common.h" - -#define IDI_BLANK 200 - -void LoadSettings(void); -int InitializeOptions(WPARAM,LPARAM); -INT_PTR CALLBACK DlgProcOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcProtoOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcBasicOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcEffectOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcThemeOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcProcesses(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcEventLeds(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcXstatusList(HWND, UINT, WPARAM, LPARAM); -void exportThemes(const TCHAR *); -void importThemes(const TCHAR *, BOOL); -void writeThemeToCombo(const TCHAR *, const TCHAR *, BOOL); -void createProcessListAux(void); -void destroyProcessListAux(void); -void createXstatusListAux(void); -void destroyXstatusListAux(void); - - -extern HINSTANCE hInst; - -extern BYTE bFlashOnMsg; -extern BYTE bFlashOnURL; -extern BYTE bFlashOnFile; -extern BYTE bFlashOnOther; -extern BYTE bFullScreenMode; -extern BYTE bScreenSaverRunning; -extern BYTE bWorkstationLocked; -extern BYTE bProcessesAreRunning; -extern BYTE bWorkstationActive; -extern BYTE bFlashIfMsgOpen; -extern BYTE bFlashIfMsgOlder; -extern WORD wSecondsOlder; -extern BYTE bFlashUntil; -extern WORD wBlinksNumber; -extern BYTE bMirandaOrWindows; -extern WORD wStatusMap; -extern WORD wReminderCheck; -extern BYTE bFlashLed[3]; -extern BYTE bFlashEffect; -extern BYTE bSequenceOrder; -extern WORD wCustomTheme; -extern WORD wStartDelay; -extern BYTE bFlashSpeed; -extern BYTE bEmulateKeypresses; -extern BYTE bOverride; -extern BYTE bFlashIfMsgWinNotTop; -extern BYTE bTrillianLedsMsg; -extern BYTE bTrillianLedsURL; -extern BYTE bTrillianLedsFile; -extern BYTE bTrillianLedsOther; - -extern PROTOCOL_LIST ProtoList; -extern PROCESS_LIST ProcessList; - -HWND hwndProto, hwndBasic, hwndEffect, hwndTheme, hwndIgnore, hwndCurrentTab; - -TCHAR *AttendedName[]={_T("Miranda"), _T("Windows")}; -TCHAR *OrderName[]={TranslateT("left->right"), TranslateT("right->left"), TranslateT("left<->right")}; - -PROCESS_LIST ProcessListAux; -XSTATUS_INFO *XstatusListAux; -BYTE trillianLedsMsg, trillianLedsURL, trillianLedsFile, trillianLedsOther; - -// ** -// ** Initialize the Miranda options page -// ** -int InitializeOptions(WPARAM wParam,LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = { sizeof(odp) }; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.pszTitle = LPGEN("Keyboard Flash"); - odp.pszGroup = LPGEN("Events"); - odp.groupPosition = 910000000; - odp.flags = ODPF_BOLDGROUPS; - odp.pfnDlgProc = DlgProcOptions; - Options_AddPage(wParam, &odp); - return 0; -} - -INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - { - HWND tc; - TCITEM tci; - tc = GetDlgItem(hwndDlg, IDC_TABS); - tci.mask = TCIF_TEXT; - tci.pszText = TranslateT("Accounts"); - TabCtrl_InsertItem(tc, 0, &tci); - tci.pszText = TranslateT("Rules"); - TabCtrl_InsertItem(tc, 1, &tci); - tci.pszText = TranslateT("Flashing"); - TabCtrl_InsertItem(tc, 2, &tci); - tci.pszText = TranslateT("Themes"); - TabCtrl_InsertItem(tc, 3, &tci); - tci.pszText = TranslateT("Ignore"); - TabCtrl_InsertItem(tc, 4, &tci); - - hwndProto = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PROTO_OPTIONS), hwndDlg, DlgProcProtoOptions, (LPARAM) NULL); - EnableThemeDialogTexture(hwndProto, ETDT_ENABLETAB); - SetWindowPos(hwndProto, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - ShowWindow(hwndProto, SW_SHOW); - hwndBasic = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_BASIC_OPTIONS), hwndDlg, DlgProcBasicOptions, (LPARAM) NULL); - EnableThemeDialogTexture(hwndBasic, ETDT_ENABLETAB); - SetWindowPos(hwndBasic, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndEffect = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EFFECT_OPTIONS), hwndDlg, DlgProcEffectOptions, (LPARAM) NULL); - EnableThemeDialogTexture(hwndEffect, ETDT_ENABLETAB); - SetWindowPos(hwndEffect, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndTheme = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_THEME_OPTIONS), hwndDlg, DlgProcThemeOptions, (LPARAM) NULL); - EnableThemeDialogTexture(hwndTheme, ETDT_ENABLETAB); - SetWindowPos(hwndTheme, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndIgnore = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_IGNORE_OPTIONS), hwndDlg, DlgProcIgnoreOptions, (LPARAM) NULL); - EnableThemeDialogTexture(hwndIgnore, ETDT_ENABLETAB); - SetWindowPos(hwndIgnore, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndCurrentTab = hwndProto; - return TRUE; - - } - case WM_COMMAND: - break; - case WM_NOTIFY: - { - switch (((LPNMHDR) lParam)->code) { - case TCN_SELCHANGE: - switch (wParam) { - case IDC_TABS: - { - HWND hwnd; - switch (TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))) { - default: - case 0: - hwnd = hwndProto; - break; - case 1: - hwnd = hwndBasic; - break; - case 2: - hwnd = hwndEffect; - break; - case 3: - hwnd = hwndTheme; - break; - case 4: - hwnd = hwndIgnore; - break; - } - if (hwnd!=hwndCurrentTab) { - ShowWindow(hwnd, SW_SHOW); - ShowWindow(hwndCurrentTab, SW_HIDE); - hwndCurrentTab = hwnd; - } - } - break; - } - break; - case PSN_APPLY: - SendMessage(hwndProto, WM_NOTIFY, wParam, lParam); - SendMessage(hwndBasic, WM_NOTIFY, wParam, lParam); - SendMessage(hwndEffect, WM_NOTIFY, wParam, lParam); - SendMessage(hwndTheme, WM_NOTIFY, wParam, lParam); - SendMessage(hwndIgnore, WM_NOTIFY, wParam, lParam); - return TRUE; - } - } - break; - case WM_DESTROY: - break; - } - return FALSE; -} - - -INT_PTR CALLBACK DlgProcProtoOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - // proto list - { - LVCOLUMN lvCol; - LVITEM lvItem; - HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); - - // create columns - ListView_SetExtendedListViewStyleEx(hList, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES); - memset(&lvCol, 0, sizeof(lvCol)); - lvCol.mask = LVCF_WIDTH|LVCF_TEXT; - lvCol.pszText = TranslateT("Protocol"); - lvCol.cx = 118; - ListView_InsertColumn(hList, 0, &lvCol); - // fill - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_TEXT|LVIF_PARAM; - lvItem.cchTextMax = 256; - lvItem.iItem = 0; - lvItem.iSubItem = 0; - for (int i=0; i < ProtoList.protoCount; i++) { - int count; PROTOACCOUNT** protos; - ProtoEnumAccounts( &count, &protos ); - if(ProtoList.protoInfo[i].visible) { - lvItem.lParam = (LPARAM)ProtoList.protoInfo[i].szProto; - lvItem.pszText = protos[i] -> tszAccountName; - ListView_InsertItem(hList, &lvItem); - ListView_SetCheckState(hList, lvItem.iItem, ProtoList.protoInfo[i].enabled); - lvItem.iItem++; - } - } - } - - initDlg=FALSE; - return TRUE; - - case WM_NOTIFY: - { - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - // enabled protos - { - int i; - LVITEM lvItem; - HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); - - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_PARAM; - lvItem.iSubItem = 0; - for (i=0; i < ListView_GetItemCount(hList); i++) { - lvItem.iItem = i; - ListView_GetItem(hList, &lvItem); - db_set_b(NULL, KEYBDMODULE, (char *)lvItem.lParam, (BYTE)!!ListView_GetCheckState(hList, lvItem.iItem)); - } - } - - LoadSettings(); - - return TRUE; - } // switch code - 0 - break; - case IDC_PROTOCOLLIST: - switch(((NMHDR*)lParam)->code) { - case LVN_ITEMCHANGED: - { - NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam; - - if (!initDlg && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK)) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - break; - } // switch code - IDC_PROTOCOLLIST - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - default: - break; - } - - return FALSE; -} - -INT_PTR CALLBACK DlgProcBasicOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - createProcessListAux(); - createXstatusListAux(); - - CheckDlgButton(hwndDlg, IDC_ONMESSAGE, bFlashOnMsg ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONURL, bFlashOnURL ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONFILE, bFlashOnFile ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONOTHER, bFlashOnOther ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_FSCREEN, bFullScreenMode ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_SSAVER, bScreenSaverRunning ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_LOCKED, bWorkstationLocked ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_PGMS, bProcessesAreRunning ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ACTIVE, bWorkstationActive ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_IFOPEN, bFlashIfMsgOpen ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_IFNOTTOP, bFlashIfMsgWinNotTop ? BST_CHECKED:BST_UNCHECKED); - if (!bFlashIfMsgOpen) - EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), FALSE); - CheckDlgButton(hwndDlg, IDC_IFOLDER, bFlashIfMsgOlder ? BST_CHECKED:BST_UNCHECKED); - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SOLDER), 0); - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(wSecondsOlder, 0)); - if (!bFlashIfMsgOlder) { - EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), FALSE); - } - - CheckDlgButton(hwndDlg, IDC_UNTILBLK, bFlashUntil&UNTIL_NBLINKS ? BST_CHECKED:BST_UNCHECKED); - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SBLINK), 0); - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(wBlinksNumber, 0)); - if (!(bFlashUntil & UNTIL_NBLINKS)) { - EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), FALSE); - } - CheckDlgButton(hwndDlg, IDC_UNTILATTENDED, bFlashUntil&UNTIL_REATTENDED ? BST_CHECKED:BST_UNCHECKED); - for (int i = 0; i < 2; i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)AttendedName[i]); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETCURSEL, (WPARAM)bMirandaOrWindows, 0); - if (!(bFlashUntil & UNTIL_REATTENDED)) - EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), FALSE); - CheckDlgButton(hwndDlg, IDC_UNTILOPEN, bFlashUntil&UNTIL_EVENTSOPEN ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_UNTILCOND, bFlashUntil&UNTIL_CONDITIONS ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_ONLINE, wStatusMap&MAP_ONLINE ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_AWAY, wStatusMap&MAP_AWAY ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_NA, wStatusMap&MAP_NA ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OCCUPIED, wStatusMap&MAP_OCCUPIED ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DND, wStatusMap&MAP_DND ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_FREECHAT, wStatusMap&MAP_FREECHAT ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_INVISIBLE, wStatusMap&MAP_INVISIBLE ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONTHEPHONE, wStatusMap&MAP_ONTHEPHONE ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OUTTOLUNCH, wStatusMap&MAP_OUTTOLUNCH ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OFFLINE, wStatusMap&MAP_OFFLINE ? BST_CHECKED:BST_UNCHECKED); - - SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SREMCHECK), 0); - SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETPOS, 0, MAKELONG(wReminderCheck, 0)); - - initDlg=FALSE; - return TRUE; - - case WM_VSCROLL: - case WM_HSCROLL: - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - break; - - case WM_DESTROY: - destroyProcessListAux(); - destroyXstatusListAux(); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ONMESSAGE: - case IDC_ONURL: - case IDC_ONFILE: - case IDC_ONOTHER: - case IDC_IFOPEN: - case IDC_IFNOTTOP: - case IDC_IFOLDER: - case IDC_UNTILBLK: - case IDC_UNTILATTENDED: - case IDC_UNTILOPEN: - case IDC_UNTILCOND: - case IDC_FSCREEN: - case IDC_SSAVER: - case IDC_LOCKED: - case IDC_PGMS: - case IDC_ACTIVE: - case IDC_ONLINE: - case IDC_AWAY: - case IDC_NA: - case IDC_OCCUPIED: - case IDC_DND: - case IDC_FREECHAT: - case IDC_INVISIBLE: - case IDC_ONTHEPHONE: - case IDC_OUTTOLUNCH: - case IDC_OFFLINE: - EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SOLDER: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) { - BOOL translated; - int val = GetDlgItemInt(hwndDlg, IDC_SOLDER, &translated, FALSE); - if (translated && val < 1) - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - return TRUE; - case IDC_SBLINK: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) { - BOOL translated; - int val = GetDlgItemInt(hwndDlg, IDC_SBLINK, &translated, FALSE); - if (translated && val < 1) - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - return TRUE; - case IDC_ASSIGNPGMS: - if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PROCESSES), hwndDlg, DlgProcProcesses, 0) == IDC_OKPGM) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SELECTXSTATUS: - if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_XSTATUSES), hwndDlg, DlgProcXstatusList, 0) == IDC_OKXST) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SREMCHECK: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_MIRORWIN: - if(HIWORD(wParam) == CBN_SELCHANGE) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - } - break; - - case WM_NOTIFY: - { - BYTE untilMap = 0; - WORD statusMap = 0; - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - db_set_b(NULL, KEYBDMODULE, "onmsg", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONMESSAGE) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "onurl", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONURL) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "onfile", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONFILE) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "onother", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONOTHER) == BST_CHECKED ? 1:0)); - - db_set_b(NULL, KEYBDMODULE, "fscreenmode", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_FSCREEN) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "ssaverrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SSAVER) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "wstationlocked", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "procsrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_PGMS) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "wstationactive", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ACTIVE) == BST_CHECKED ? 1:0)); - - db_set_b(NULL, KEYBDMODULE, "ifmsgopen", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "ifmsgnottop", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFNOTTOP) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "ifmsgolder", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED ? 1:0)); - db_set_w(NULL, KEYBDMODULE, "secsolder", (WORD)SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_GETPOS, 0, 0)); - - if(IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED) - untilMap |= UNTIL_NBLINKS; - if (IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED) - untilMap |= UNTIL_REATTENDED; - if (IsDlgButtonChecked(hwndDlg, IDC_UNTILOPEN) == BST_CHECKED) - untilMap |= UNTIL_EVENTSOPEN; - if (IsDlgButtonChecked(hwndDlg, IDC_UNTILCOND) == BST_CHECKED) - untilMap |= UNTIL_CONDITIONS; - db_set_b(NULL, KEYBDMODULE, "funtil", untilMap); - db_set_w(NULL, KEYBDMODULE, "nblinks", (WORD)SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_GETPOS, 0, 0)); - db_set_b(NULL, KEYBDMODULE, "mirorwin", (BYTE)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETCURSEL, 0, 0), 0)); - - if(IsDlgButtonChecked(hwndDlg, IDC_ONLINE) == BST_CHECKED) - statusMap |= MAP_ONLINE; - if(IsDlgButtonChecked(hwndDlg, IDC_AWAY) == BST_CHECKED) - statusMap |= MAP_AWAY; - if(IsDlgButtonChecked(hwndDlg, IDC_NA) == BST_CHECKED) - statusMap |= MAP_NA; - if(IsDlgButtonChecked(hwndDlg, IDC_OCCUPIED) == BST_CHECKED) - statusMap |= MAP_OCCUPIED; - if(IsDlgButtonChecked(hwndDlg, IDC_DND) == BST_CHECKED) - statusMap |= MAP_DND; - if(IsDlgButtonChecked(hwndDlg, IDC_FREECHAT) == BST_CHECKED) - statusMap |= MAP_FREECHAT; - if(IsDlgButtonChecked(hwndDlg, IDC_INVISIBLE) == BST_CHECKED) - statusMap |= MAP_INVISIBLE; - if(IsDlgButtonChecked(hwndDlg, IDC_ONTHEPHONE) == BST_CHECKED) - statusMap |= MAP_ONTHEPHONE; - if(IsDlgButtonChecked(hwndDlg, IDC_OUTTOLUNCH) == BST_CHECKED) - statusMap |= MAP_OUTTOLUNCH; - if(IsDlgButtonChecked(hwndDlg, IDC_OFFLINE) == BST_CHECKED) - statusMap |= MAP_OFFLINE; - db_set_w(NULL, KEYBDMODULE, "status", statusMap); - - db_set_w(NULL, KEYBDMODULE, "remcheck", (WORD)SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_GETPOS, 0, 0)); - - int i = 0; - for (int j = 0; j < ProcessListAux.count; j++) - if (ProcessListAux.szFileName[j]) - db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++), ProcessListAux.szFileName[j]); - db_set_w(NULL, KEYBDMODULE, "processcount", (WORD)i); - while (!db_unset(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++))); - - if (XstatusListAux) - for (int i = 0; i < ProtoList.protoCount; i++) - for (int j = 0; j < (int)XstatusListAux[i].count; j++) - db_set_b(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), (BYTE)XstatusListAux[i].enabled[j]); - - LoadSettings(); - - return TRUE; - } // switch code - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - default: - break; - } - - return FALSE; -} - -INT_PTR CALLBACK DlgProcEffectOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - DBVARIANT dbv; - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - trillianLedsMsg = bTrillianLedsMsg; - trillianLedsURL = bTrillianLedsURL; - trillianLedsFile = bTrillianLedsFile; - trillianLedsOther = bTrillianLedsOther; - - CheckDlgButton(hwndDlg, IDC_NUM, bFlashLed[0] ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CAPS, bFlashLed[1] ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_SCROLL, bFlashLed[2] ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_SAMETIME, bFlashEffect == FLASH_SAMETIME ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_INTURN, bFlashEffect == FLASH_INTURN ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_INSEQUENCE, bFlashEffect == FLASH_INSEQUENCE ? BST_CHECKED:BST_UNCHECKED); - for (i=0; i < 3; i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(OrderName[i])); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETCURSEL, (WPARAM)bSequenceOrder, 0); - if (bFlashEffect != FLASH_INSEQUENCE) - EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), FALSE); - CheckDlgButton(hwndDlg, IDC_CUSTOM, bFlashEffect == FLASH_CUSTOM ? BST_CHECKED:BST_UNCHECKED); - for (i=0; !db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.ptszVal); - db_free(&dbv); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); - if (bFlashEffect != FLASH_CUSTOM) - EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), FALSE); - CheckDlgButton(hwndDlg, IDC_TRILLIAN, bFlashEffect == FLASH_TRILLIAN ? BST_CHECKED:BST_UNCHECKED); - if (bFlashEffect != FLASH_TRILLIAN) - EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), FALSE); - - SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SDELAY), 0); - SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETPOS, 0, MAKELONG(wStartDelay, 0)); - - SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, FALSE, MAKELONG(0, 5)); - SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, bFlashSpeed); - - CheckDlgButton(hwndDlg, IDC_KEYPRESSES, bEmulateKeypresses ? BST_CHECKED:BST_UNCHECKED); - - initDlg=FALSE; - return TRUE; - - case WM_VSCROLL: - case WM_HSCROLL: - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - break; - - case WM_DESTROY: - previewFlashing(FALSE); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_NUM: - case IDC_CAPS: - case IDC_SCROLL: - case IDC_SAMETIME: - case IDC_INTURN: - case IDC_INSEQUENCE: - case IDC_CUSTOM: - case IDC_TRILLIAN: - case IDC_SPEED: - case IDC_KEYPRESSES: - EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_ASSIGNLEDS: - if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EVENTLEDS), hwndDlg, DlgProcEventLeds, 0) == IDC_OK) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SDELAY: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_PREVIEW: - previewFlashing(IsDlgButtonChecked(hwndDlg, IDC_PREVIEW) == BST_CHECKED); - return TRUE; - case IDC_SEQORDER: - case IDC_SCUSTOM: - if(HIWORD(wParam) == CBN_SELCHANGE) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - } - break; - - case WM_NOTIFY: - { - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - db_set_b(NULL, KEYBDMODULE, "fnum", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_NUM) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "fcaps", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CAPS) == BST_CHECKED ? 1:0)); - db_set_b(NULL, KEYBDMODULE, "fscroll", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SCROLL) == BST_CHECKED ? 1:0)); - - if(IsDlgButtonChecked(hwndDlg, IDC_INTURN) == BST_CHECKED) - db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_INTURN); - else - if (IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED) - db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_INSEQUENCE); - else - if (IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED) - db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_CUSTOM); - else - if (IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED) - db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_TRILLIAN); - else - db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_SAMETIME); - db_set_b(NULL, KEYBDMODULE, "order", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETCURSEL, 0, 0), 0)); - db_set_w(NULL, KEYBDMODULE, "custom", (WORD)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETCURSEL, 0, 0), 0)); - - db_set_b(NULL, KEYBDMODULE, "ledsmsg", trillianLedsMsg); - db_set_b(NULL, KEYBDMODULE, "ledsfile", trillianLedsFile); - db_set_b(NULL, KEYBDMODULE, "ledsurl", trillianLedsURL); - db_set_b(NULL, KEYBDMODULE, "ledsother", trillianLedsOther); - - db_set_w(NULL, KEYBDMODULE, "sdelay", (WORD)SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_GETPOS, 0, 0)); - - db_set_b(NULL, KEYBDMODULE, "speed", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0)); - - db_set_b(NULL, KEYBDMODULE, "keypresses", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_KEYPRESSES) == BST_CHECKED ? 1:0)); - - LoadSettings(); - - return TRUE; - } // switch code - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - default: - break; - } - - return FALSE; -} - -INT_PTR CALLBACK DlgProcThemeOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - TCHAR *str; - DBVARIANT dbv; - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - SendDlgItemMessage(hwndDlg, IDC_THEME, EM_LIMITTEXT, MAX_PATH, 0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOMSTRING, EM_LIMITTEXT, MAX_PATH, 0); - - for (i=0; !db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.ptszVal); - db_free(&dbv); - if (index != CB_ERR && index != CB_ERRSPACE) { - str = (TCHAR *)malloc(MAX_PATH+1); - if (str) - if (db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) - str[0] = _T('\0'); - else { - _tcscpy(str, dbv.ptszVal); - db_free(&dbv); - } - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)index, (LPARAM)str); - } - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); - else { - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)wCustomTheme, 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - } - - CheckDlgButton(hwndDlg, IDC_OVERRIDE, bOverride ? BST_CHECKED:BST_UNCHECKED); - - initDlg=FALSE; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_THEME: - switch (HIWORD(wParam)) { - int item; - TCHAR theme[MAX_PATH+1]; - - case CBN_SELENDOK: - case CBN_SELCHANGE: - str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - else - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); - break; - case CBN_EDITCHANGE: - GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); - if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) { //new theme - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); - } else { - str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - else - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - break; - } - return TRUE; - case IDC_CUSTOMSTRING: - if(HIWORD(wParam) == EN_CHANGE) { - int item; - TCHAR theme[MAX_PATH+1], customAux[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); - if ((item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) - return TRUE; - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) { - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, customAux, MAX_PATH); - if (wcscmp(str, customAux)) - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), TRUE); - else - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - } - } - return TRUE; - case IDC_TEST: - { - TCHAR custom[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, custom, MAX_PATH); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(custom)); - testSequence(custom); - } - return TRUE; - case IDC_ADD: - { - int item; - TCHAR theme[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); - if (!theme[0]) - return TRUE; - item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); - str = (TCHAR *)malloc(MAX_PATH+1); - if (str) { - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); - } - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); - } - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_UPDATE: - { - int item; - TCHAR theme[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); - item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) { - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - } - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_DELETE: - { - int item; - TCHAR theme[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); - item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - free(str); - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_DELETESTRING, (WPARAM)item, 0); - if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) { - SetDlgItemText(hwndDlg, IDC_THEME, _T("")); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); - } else { - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, 0, 0); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, 0, 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - } - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_EXPORT: - { - TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; - OPENFILENAME ofn={0}; - - path[0] = _T('\0'); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = hwndDlg; - ofn.hInstance = NULL; - _tcscpy(filter, TranslateT("Keyboard Notify Theme")); - wcscat(filter, _T(" (*.knt)")); - pfilter = filter + _tcslen(filter) + 1; - _tcscpy(pfilter, _T("*.knt")); - pfilter = pfilter + _tcslen(pfilter) + 1; - _tcscpy(pfilter, TranslateT("All Files")); - pfilter = pfilter + _tcslen(pfilter) + 1; - _tcscpy(pfilter, _T("*.*")); - pfilter = pfilter + _tcslen(pfilter) + 1; - *pfilter = _T('\0'); - ofn.lpstrFilter = filter; - ofn.lpstrFile = path; - ofn.Flags = OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST; - ofn.nMaxFile = SIZEOF(path); - ofn.lpstrDefExt = _T("knt"); - if(GetSaveFileName(&ofn)) - exportThemes(path); - } - return TRUE; - case IDC_IMPORT: - { - TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; - OPENFILENAME ofn={0}; - - path[0] = _T('\0'); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = hwndDlg; - ofn.hInstance = NULL; - _tcscpy(filter, TranslateT("Keyboard Notify Theme")); - wcscat(filter, _T(" (*.knt)")); - pfilter = filter + _tcslen(filter) + 1; - _tcscpy(pfilter, _T("*.knt")); - pfilter = pfilter + _tcslen(pfilter) + 1; - _tcscpy(pfilter, TranslateT("All Files")); - pfilter = pfilter + _tcslen(pfilter) + 1; - _tcscpy(pfilter, _T("*.*")); - pfilter = pfilter + _tcslen(pfilter) + 1; - *pfilter = _T('\0'); - ofn.lpstrFilter = filter; - ofn.lpstrFile = path; - ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR; - ofn.nMaxFile = SIZEOF(path); - ofn.lpstrDefExt = _T("knt"); - if(GetOpenFileName(&ofn)) { - importThemes(path, IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - } - return TRUE; - case IDC_OVERRIDE: - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - } - break; - - case WM_NOTIFY: - { - int count; - TCHAR theme[MAX_PATH+1], themeAux[MAX_PATH+1], *str; - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - if (!db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", wCustomTheme), &dbv)) - _tcscpy(theme, dbv.ptszVal); - else - theme[0] = _T('\0'); - - // Here we will delete all the items in the theme combo on the Flashing tab: we will load them again later - for (i=0; SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_DELETESTRING, 0, (LPARAM)i) != CB_ERR; i++); - - count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); - for (i=0, wCustomTheme=0; i < count; i++) { - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETLBTEXT, (WPARAM)i, (LPARAM)themeAux); - db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), themeAux); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)i, 0); - if (str) - db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), str); - else - db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), _T("")); - - if (!wcscmp(theme, themeAux)) - wCustomTheme = i; - - // Here we will update the theme combo on the Flashing tab: horrible but can't imagine a better way right now - SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)i, (LPARAM)themeAux); - SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)i, (LPARAM)i); - } - for (i=count; !db_unset(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i)); i++) - db_unset(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i)); - - db_set_w(NULL, KEYBDMODULE, "custom", wCustomTheme); - // Still updating here the the Flashing tab's controls - SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); - - db_set_b(NULL, KEYBDMODULE, "override", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED ? 1:0)); - - return TRUE; - } // switch code - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - case WM_DESTROY: - { - int item, count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); - - for (item=0; item < count; item++) { - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - free(str); - } - break; - } - - default: - break; - } - - return FALSE; -} - - -void exportThemes(const TCHAR *filename) -{ - int i; - FILE *fExport = _tfopen(filename, _T("wt")); - DBVARIANT dbv; - - if (!fExport) - return; - - fwprintf(fExport, TranslateT("\n; Automatically generated Keyboard Notify Theme file\n\n\n")); - - for (i=0; !db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { - _ftprintf(fExport, _T("[%s]\n"), dbv.ptszVal); - db_free(&dbv); - if (db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) - _ftprintf(fExport, _T("0\n\n")); - else { - _ftprintf(fExport, _T("%s\n\n"), dbv.ptszVal); - db_free(&dbv); - } - } - - _ftprintf(fExport, TranslateT("\n; End of automatically generated Keyboard Notify Theme file\n")); - - fclose(fExport); -} - - -void importThemes(const TCHAR *filename, BOOL overrideExisting) -{ - int status=0; - size_t i; - FILE *fImport = _tfopen(filename, _T("rt")); - TCHAR buffer[MAX_PATH+1], theme[MAX_PATH+1], *str; - - if (!fImport) - return; - - while (_fgetts(buffer, MAX_PATH, fImport) != NULL) { - for (str=buffer; *str && isspace(*str); str++); //ltrim - if (!*str || *str == ';') //empty line or comment - continue; - for (i=_tcslen(str)-1; isspace(str[i]); str[i--]='\0'); //rtrim - switch (status) { - case 0: - if (i > 1 && str[0] == '[' && str[i] == ']') { - status = 1; - _tcscpy(theme, str+1); - theme[i-1] = '\0'; - } - break; - case 1: - status = 0; - writeThemeToCombo(theme, normalizeCustomString(str), overrideExisting); - break; - } - } - - fclose(fImport); -} - - -void writeThemeToCombo(const TCHAR *theme, const TCHAR *custom, BOOL overrideExisting) -{ - int item; - TCHAR *str; - - item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); - if (item == CB_ERR) { - item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); - str = (TCHAR *)malloc(MAX_PATH+1); - if (str) - _tcscpy(str, custom); - SendDlgItemMessage(hwndTheme, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); - } else - if (overrideExisting) { - str = (TCHAR *)SendDlgItemMessage(hwndTheme, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - _tcscpy(str, custom); - } -} - - -INT_PTR CALLBACK DlgProcProcesses(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, EM_LIMITTEXT, MAX_PATH, 0); - - for (int i = 0; i < ProcessListAux.count; i++) - if (ProcessListAux.szFileName[i]) { - int index = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)ProcessListAux.szFileName[i]); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); - else - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_PROGRAMS: - switch (HIWORD(wParam)) { - int item; - TCHAR szFileName[MAX_PATH+1]; - - case CBN_SELENDOK: - case CBN_SELCHANGE: - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); - break; - case CBN_EDITCHANGE: - GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, SIZEOF(szFileName)); - if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName)) == CB_ERR) { //new program - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); - } else { - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); - } - break; - } - break; - case IDC_ADDPGM: - { - int item; - TCHAR szFileName[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, SIZEOF(szFileName)); - if (!szFileName[0]) - break; - item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_ADDSTRING, 0, (LPARAM)szFileName); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); - } - break; - case IDC_DELETEPGM: - { - int item; - TCHAR szFileName[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, SIZEOF(szFileName)); - item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName); - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_DELETESTRING, (WPARAM)item, 0); - if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) { - SetDlgItemText(hwndDlg, IDC_PROGRAMS, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); - } else - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); - } - break; - case IDC_OKPGM: - destroyProcessListAux(); - - ProcessListAux.count = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0); - ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(TCHAR *)); - if (!ProcessListAux.szFileName) - ProcessListAux.count = 0; - else - for (int i = 0; i < ProcessListAux.count; i++) { - TCHAR szFileNameAux[MAX_PATH+1]; - - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETLBTEXT, (WPARAM)i, (LPARAM)szFileNameAux); - ProcessListAux.szFileName[i] = (TCHAR *)malloc(_tcslen(szFileNameAux) + 1); - if (ProcessListAux.szFileName[i]) - _tcscpy(ProcessListAux.szFileName[i], szFileNameAux); - } - - case IDC_CANCELPGM: - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - break; - } - - return FALSE; -} - - -void createProcessListAux(void) -{ - ProcessListAux.count = ProcessList.count; - ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(char *)); - if (!ProcessListAux.szFileName) - ProcessListAux.count = 0; - else - for (int i = 0; i < ProcessListAux.count; i++) - if (!ProcessList.szFileName[i]) - ProcessListAux.szFileName[i] = NULL; - else { - ProcessListAux.szFileName[i] = (TCHAR *)malloc(_tcslen(ProcessList.szFileName[i]) + 1); - if (ProcessListAux.szFileName[i]) - _tcscpy(ProcessListAux.szFileName[i], ProcessList.szFileName[i]); - } - -} - - -void destroyProcessListAux(void) -{ - for (int i = 0; i < ProcessListAux.count; i++) - if (ProcessListAux.szFileName[i]) - free(ProcessListAux.szFileName[i]); - - if (ProcessListAux.szFileName) - free(ProcessListAux.szFileName); - - ProcessListAux.count = 0; - ProcessListAux.szFileName = NULL; -} - - -INT_PTR CALLBACK DlgProcEventLeds(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - CheckDlgButton(hwndDlg, IDC_MSGLEDNUM, trillianLedsMsg&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_MSGLEDCAPS, trillianLedsMsg&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_MSGLEDSCROLL, trillianLedsMsg&1 ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_FILELEDNUM, trillianLedsFile&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_FILELEDCAPS, trillianLedsFile&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_FILELEDSCROLL, trillianLedsFile&1 ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_URLLEDNUM, trillianLedsURL&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_URLLEDCAPS, trillianLedsURL&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_URLLEDSCROLL, trillianLedsURL&1 ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_OTHERLEDNUM, trillianLedsOther&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OTHERLEDCAPS, trillianLedsOther&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OTHERLEDSCROLL, trillianLedsOther&1 ? BST_CHECKED:BST_UNCHECKED); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_OK: - trillianLedsMsg = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDNUM) == BST_CHECKED) - trillianLedsMsg |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDCAPS) == BST_CHECKED) - trillianLedsMsg |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDSCROLL) == BST_CHECKED) - trillianLedsMsg |= 1; - - trillianLedsFile = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDNUM) == BST_CHECKED) - trillianLedsFile |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDCAPS) == BST_CHECKED) - trillianLedsFile |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDSCROLL) == BST_CHECKED) - trillianLedsFile |= 1; - - trillianLedsURL = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDNUM) == BST_CHECKED) - trillianLedsURL |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDCAPS) == BST_CHECKED) - trillianLedsURL |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDSCROLL) == BST_CHECKED) - trillianLedsURL |= 1; - - trillianLedsOther = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDNUM) == BST_CHECKED) - trillianLedsOther |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDCAPS) == BST_CHECKED) - trillianLedsOther |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDSCROLL) == BST_CHECKED) - trillianLedsOther |= 1; - - case IDC_CANCEL: - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - break; - } - - return FALSE; -} - - -void createXstatusListAux(void) -{ - XstatusListAux = (XSTATUS_INFO *)malloc(ProtoList.protoCount * sizeof(XSTATUS_INFO)); - if (XstatusListAux) - for (int i = 0; i < ProtoList.protoCount; i++) { - XstatusListAux[i].count = ProtoList.protoInfo[i].xstatus.count; - if (!XstatusListAux[i].count) - XstatusListAux[i].enabled = NULL; - else { - XstatusListAux[i].enabled = (BOOL *)malloc(XstatusListAux[i].count * sizeof(BOOL)); - if (!XstatusListAux[i].enabled) - XstatusListAux[i].count = 0; - else - for (int j = 0; j < (int)XstatusListAux[i].count; j++) - XstatusListAux[i].enabled[j] = ProtoList.protoInfo[i].xstatus.enabled[j]; - } - } - -} - - -void destroyXstatusListAux(void) -{ - if (XstatusListAux) { - for (int i = 0; i < ProtoList.protoCount; i++) - if (XstatusListAux[i].enabled) - free(XstatusListAux[i].enabled); - free(XstatusListAux); - XstatusListAux = NULL; - } - -} - - -INT_PTR CALLBACK DlgProcXstatusList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - - case WM_INITDIALOG: - - { - WPARAM j; - int imageCount; - HICON hIconAux; - HIMAGELIST hImageList; - TVINSERTSTRUCT tvis={0}; - TVITEM tvi={0}; - HTREEITEM hSectionItem, hItem; - HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); - - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndTree, GWL_STYLE, GetWindowLongPtr(hwndTree, GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES); - - if (!XstatusListAux) return TRUE; - - // Calculate hImageList size - imageCount=1; - for (int i = 0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) - imageCount += XstatusListAux[i].count; - - hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, imageCount, imageCount); - TreeView_SetImageList(hwndTree, hImageList, TVSIL_NORMAL); - - ImageList_AddIcon(hImageList, hIconAux=(HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, 0, 0, 0)); - if (hIconAux) DestroyIcon(hIconAux); - - TreeView_SelectItem(hwndTree, NULL); - ShowWindow(hwndTree, SW_HIDE); - TreeView_DeleteAllItems(hwndTree); - - for (int i = 0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) { - HTREEITEM hParent; - - int count; PROTOACCOUNT** protos; - ProtoEnumAccounts( &count, &protos ); - - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE|TVIF_IMAGE|TVIF_SELECTEDIMAGE; - tvis.item.pszText = protos[i] -> tszAccountName; - tvis.item.lParam = (LPARAM)i; - tvis.item.stateMask = TVIS_BOLD|TVIS_EXPANDED; - tvis.item.state = TVIS_BOLD|TVIS_EXPANDED; - tvis.item.iImage = tvis.item.iSelectedImage = ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_LOADICON, PLI_PROTOCOL, 0)); - if (hIconAux) DestroyIcon(hIconAux); - hParent = TreeView_InsertItem(hwndTree, &tvis); - for (j = 0; j < XstatusListAux[i].count; j++) { - tvis.hParent = hParent; - tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; - if (!j){ - tvis.item.pszText = TranslateT("None"); } - else { - TCHAR szDefaultName[1024]; - CUSTOM_STATUS xstatus={0}; - xstatus.cbSize = sizeof(CUSTOM_STATUS); - xstatus.flags = CSSF_MASK_NAME|CSSF_DEFAULT_NAME|CSSF_TCHAR; - xstatus.ptszName = szDefaultName; - xstatus.wParam = &j; - CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - tvis.item.pszText = TranslateTS(szDefaultName); - } - tvis.item.lParam = (LPARAM)j; - tvis.item.iImage = tvis.item.iSelectedImage = j?ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSICON, (WPARAM)j, 0)):0; - if (hIconAux) DestroyIcon(hIconAux); - TreeView_InsertItem(hwndTree, &tvis); - } - } - - tvi.mask = TVIF_HANDLE|TVIF_PARAM; - for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { - tvi.hItem = hSectionItem; - TreeView_GetItem(hwndTree, &tvi); - unsigned int i = (unsigned int)tvi.lParam; - TreeView_SetItemState(hwndTree, hSectionItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK); - for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { - tvi.hItem = hItem; - TreeView_GetItem(hwndTree, &tvi); - j = (unsigned int)tvi.lParam; - TreeView_SetItemState(hwndTree, hItem, INDEXTOSTATEIMAGEMASK(XstatusListAux[i].enabled[j]?2:1), TVIS_STATEIMAGEMASK); - } - } - - ShowWindow(hwndTree, SW_SHOW); - TreeView_SetItemState(hwndTree, 0, TVIS_SELECTED, TVIS_SELECTED); - return TRUE; - } - - case WM_DESTROY: - { - HIMAGELIST hImageList; - - // Destroy tree view imagelist since it does not get destroyed automatically (see msdn docs) - hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_STATE); - if (hImageList) { - TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_STATE); - ImageList_Destroy(hImageList); - } - hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_NORMAL); - if (hImageList) { - TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_NORMAL); - ImageList_Destroy(hImageList); - } - return TRUE; - } - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_OKXST: - { - unsigned int i, j; - HTREEITEM hSectionItem, hItem; - TVITEM tvi={0}; - HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); - - tvi.mask = TVIF_HANDLE|TVIF_PARAM; - for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { - tvi.hItem = hSectionItem; - TreeView_GetItem(hwndTree, &tvi); - i = (unsigned int)tvi.lParam; - for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { - tvi.hItem = hItem; - TreeView_GetItem(hwndTree, &tvi); - j = (unsigned int)tvi.lParam; - XstatusListAux[i].enabled[j] = !!(TreeView_GetItemState(hwndTree, hItem, TVIS_STATEIMAGEMASK)&INDEXTOSTATEIMAGEMASK(2)); - } - } - } - - case IDC_CANCELXST: - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; - } - break; - } - - return FALSE; -} +/* + +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 "Common.h" + +#define IDI_BLANK 200 + +void LoadSettings(void); +int InitializeOptions(WPARAM,LPARAM); +INT_PTR CALLBACK DlgProcOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcProtoOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcBasicOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcEffectOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcThemeOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcProcesses(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcEventLeds(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcXstatusList(HWND, UINT, WPARAM, LPARAM); +void exportThemes(const TCHAR *); +void importThemes(const TCHAR *, BOOL); +void writeThemeToCombo(const TCHAR *, const TCHAR *, BOOL); +void createProcessListAux(void); +void destroyProcessListAux(void); +void createXstatusListAux(void); +void destroyXstatusListAux(void); + + +extern HINSTANCE hInst; + +extern BYTE bFlashOnMsg; +extern BYTE bFlashOnURL; +extern BYTE bFlashOnFile; +extern BYTE bFlashOnOther; +extern BYTE bFullScreenMode; +extern BYTE bScreenSaverRunning; +extern BYTE bWorkstationLocked; +extern BYTE bProcessesAreRunning; +extern BYTE bWorkstationActive; +extern BYTE bFlashIfMsgOpen; +extern BYTE bFlashIfMsgOlder; +extern WORD wSecondsOlder; +extern BYTE bFlashUntil; +extern WORD wBlinksNumber; +extern BYTE bMirandaOrWindows; +extern WORD wStatusMap; +extern WORD wReminderCheck; +extern BYTE bFlashLed[3]; +extern BYTE bFlashEffect; +extern BYTE bSequenceOrder; +extern WORD wCustomTheme; +extern WORD wStartDelay; +extern BYTE bFlashSpeed; +extern BYTE bEmulateKeypresses; +extern BYTE bOverride; +extern BYTE bFlashIfMsgWinNotTop; +extern BYTE bTrillianLedsMsg; +extern BYTE bTrillianLedsURL; +extern BYTE bTrillianLedsFile; +extern BYTE bTrillianLedsOther; + +extern PROTOCOL_LIST ProtoList; +extern PROCESS_LIST ProcessList; + +HWND hwndProto, hwndBasic, hwndEffect, hwndTheme, hwndIgnore, hwndCurrentTab; + +TCHAR *AttendedName[]={_T("Miranda"), _T("Windows")}; +TCHAR *OrderName[]={TranslateT("left->right"), TranslateT("right->left"), TranslateT("left<->right")}; + +PROCESS_LIST ProcessListAux; +XSTATUS_INFO *XstatusListAux; +BYTE trillianLedsMsg, trillianLedsURL, trillianLedsFile, trillianLedsOther; + +// ** +// ** Initialize the Miranda options page +// ** +int InitializeOptions(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszTitle = LPGEN("Keyboard Flash"); + odp.pszGroup = LPGEN("Events"); + odp.groupPosition = 910000000; + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = DlgProcOptions; + Options_AddPage(wParam, &odp); + return 0; +} + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + { + HWND tc; + TCITEM tci; + tc = GetDlgItem(hwndDlg, IDC_TABS); + tci.mask = TCIF_TEXT; + tci.pszText = TranslateT("Accounts"); + TabCtrl_InsertItem(tc, 0, &tci); + tci.pszText = TranslateT("Rules"); + TabCtrl_InsertItem(tc, 1, &tci); + tci.pszText = TranslateT("Flashing"); + TabCtrl_InsertItem(tc, 2, &tci); + tci.pszText = TranslateT("Themes"); + TabCtrl_InsertItem(tc, 3, &tci); + tci.pszText = TranslateT("Ignore"); + TabCtrl_InsertItem(tc, 4, &tci); + + hwndProto = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PROTO_OPTIONS), hwndDlg, DlgProcProtoOptions, (LPARAM) NULL); + EnableThemeDialogTexture(hwndProto, ETDT_ENABLETAB); + SetWindowPos(hwndProto, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + ShowWindow(hwndProto, SW_SHOW); + hwndBasic = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_BASIC_OPTIONS), hwndDlg, DlgProcBasicOptions, (LPARAM) NULL); + EnableThemeDialogTexture(hwndBasic, ETDT_ENABLETAB); + SetWindowPos(hwndBasic, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndEffect = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EFFECT_OPTIONS), hwndDlg, DlgProcEffectOptions, (LPARAM) NULL); + EnableThemeDialogTexture(hwndEffect, ETDT_ENABLETAB); + SetWindowPos(hwndEffect, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndTheme = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_THEME_OPTIONS), hwndDlg, DlgProcThemeOptions, (LPARAM) NULL); + EnableThemeDialogTexture(hwndTheme, ETDT_ENABLETAB); + SetWindowPos(hwndTheme, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndIgnore = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_IGNORE_OPTIONS), hwndDlg, DlgProcIgnoreOptions, (LPARAM) NULL); + EnableThemeDialogTexture(hwndIgnore, ETDT_ENABLETAB); + SetWindowPos(hwndIgnore, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndCurrentTab = hwndProto; + return TRUE; + + } + case WM_COMMAND: + break; + case WM_NOTIFY: + { + switch (((LPNMHDR) lParam)->code) { + case TCN_SELCHANGE: + switch (wParam) { + case IDC_TABS: + { + HWND hwnd; + switch (TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))) { + default: + case 0: + hwnd = hwndProto; + break; + case 1: + hwnd = hwndBasic; + break; + case 2: + hwnd = hwndEffect; + break; + case 3: + hwnd = hwndTheme; + break; + case 4: + hwnd = hwndIgnore; + break; + } + if (hwnd!=hwndCurrentTab) { + ShowWindow(hwnd, SW_SHOW); + ShowWindow(hwndCurrentTab, SW_HIDE); + hwndCurrentTab = hwnd; + } + } + break; + } + break; + case PSN_APPLY: + SendMessage(hwndProto, WM_NOTIFY, wParam, lParam); + SendMessage(hwndBasic, WM_NOTIFY, wParam, lParam); + SendMessage(hwndEffect, WM_NOTIFY, wParam, lParam); + SendMessage(hwndTheme, WM_NOTIFY, wParam, lParam); + SendMessage(hwndIgnore, WM_NOTIFY, wParam, lParam); + return TRUE; + } + } + break; + case WM_DESTROY: + break; + } + return FALSE; +} + + +INT_PTR CALLBACK DlgProcProtoOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + // proto list + { + LVCOLUMN lvCol; + LVITEM lvItem; + HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); + + // create columns + ListView_SetExtendedListViewStyleEx(hList, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES); + memset(&lvCol, 0, sizeof(lvCol)); + lvCol.mask = LVCF_WIDTH|LVCF_TEXT; + lvCol.pszText = TranslateT("Protocol"); + lvCol.cx = 118; + ListView_InsertColumn(hList, 0, &lvCol); + // fill + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_TEXT|LVIF_PARAM; + lvItem.cchTextMax = 256; + lvItem.iItem = 0; + lvItem.iSubItem = 0; + for (int i=0; i < ProtoList.protoCount; i++) { + int count; PROTOACCOUNT** protos; + ProtoEnumAccounts( &count, &protos ); + if(ProtoList.protoInfo[i].visible) { + lvItem.lParam = (LPARAM)ProtoList.protoInfo[i].szProto; + lvItem.pszText = protos[i] -> tszAccountName; + ListView_InsertItem(hList, &lvItem); + ListView_SetCheckState(hList, lvItem.iItem, ProtoList.protoInfo[i].enabled); + lvItem.iItem++; + } + } + } + + initDlg=FALSE; + return TRUE; + + case WM_NOTIFY: + { + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + // enabled protos + { + int i; + LVITEM lvItem; + HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); + + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_PARAM; + lvItem.iSubItem = 0; + for (i=0; i < ListView_GetItemCount(hList); i++) { + lvItem.iItem = i; + ListView_GetItem(hList, &lvItem); + db_set_b(NULL, KEYBDMODULE, (char *)lvItem.lParam, (BYTE)!!ListView_GetCheckState(hList, lvItem.iItem)); + } + } + + LoadSettings(); + + return TRUE; + } // switch code - 0 + break; + case IDC_PROTOCOLLIST: + switch(((NMHDR*)lParam)->code) { + case LVN_ITEMCHANGED: + { + NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam; + + if (!initDlg && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK)) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + break; + } // switch code - IDC_PROTOCOLLIST + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK DlgProcBasicOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + createProcessListAux(); + createXstatusListAux(); + + CheckDlgButton(hwndDlg, IDC_ONMESSAGE, bFlashOnMsg ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONURL, bFlashOnURL ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONFILE, bFlashOnFile ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONOTHER, bFlashOnOther ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_FSCREEN, bFullScreenMode ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SSAVER, bScreenSaverRunning ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_LOCKED, bWorkstationLocked ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_PGMS, bProcessesAreRunning ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ACTIVE, bWorkstationActive ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_IFOPEN, bFlashIfMsgOpen ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IFNOTTOP, bFlashIfMsgWinNotTop ? BST_CHECKED:BST_UNCHECKED); + if (!bFlashIfMsgOpen) + EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), FALSE); + CheckDlgButton(hwndDlg, IDC_IFOLDER, bFlashIfMsgOlder ? BST_CHECKED:BST_UNCHECKED); + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SOLDER), 0); + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(wSecondsOlder, 0)); + if (!bFlashIfMsgOlder) { + EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), FALSE); + } + + CheckDlgButton(hwndDlg, IDC_UNTILBLK, bFlashUntil&UNTIL_NBLINKS ? BST_CHECKED:BST_UNCHECKED); + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SBLINK), 0); + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(wBlinksNumber, 0)); + if (!(bFlashUntil & UNTIL_NBLINKS)) { + EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), FALSE); + } + CheckDlgButton(hwndDlg, IDC_UNTILATTENDED, bFlashUntil&UNTIL_REATTENDED ? BST_CHECKED:BST_UNCHECKED); + for (int i = 0; i < 2; i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)AttendedName[i]); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETCURSEL, (WPARAM)bMirandaOrWindows, 0); + if (!(bFlashUntil & UNTIL_REATTENDED)) + EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), FALSE); + CheckDlgButton(hwndDlg, IDC_UNTILOPEN, bFlashUntil&UNTIL_EVENTSOPEN ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_UNTILCOND, bFlashUntil&UNTIL_CONDITIONS ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_ONLINE, wStatusMap&MAP_ONLINE ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_AWAY, wStatusMap&MAP_AWAY ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NA, wStatusMap&MAP_NA ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OCCUPIED, wStatusMap&MAP_OCCUPIED ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_DND, wStatusMap&MAP_DND ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_FREECHAT, wStatusMap&MAP_FREECHAT ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_INVISIBLE, wStatusMap&MAP_INVISIBLE ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONTHEPHONE, wStatusMap&MAP_ONTHEPHONE ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OUTTOLUNCH, wStatusMap&MAP_OUTTOLUNCH ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OFFLINE, wStatusMap&MAP_OFFLINE ? BST_CHECKED:BST_UNCHECKED); + + SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SREMCHECK), 0); + SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETPOS, 0, MAKELONG(wReminderCheck, 0)); + + initDlg=FALSE; + return TRUE; + + case WM_VSCROLL: + case WM_HSCROLL: + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + break; + + case WM_DESTROY: + destroyProcessListAux(); + destroyXstatusListAux(); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ONMESSAGE: + case IDC_ONURL: + case IDC_ONFILE: + case IDC_ONOTHER: + case IDC_IFOPEN: + case IDC_IFNOTTOP: + case IDC_IFOLDER: + case IDC_UNTILBLK: + case IDC_UNTILATTENDED: + case IDC_UNTILOPEN: + case IDC_UNTILCOND: + case IDC_FSCREEN: + case IDC_SSAVER: + case IDC_LOCKED: + case IDC_PGMS: + case IDC_ACTIVE: + case IDC_ONLINE: + case IDC_AWAY: + case IDC_NA: + case IDC_OCCUPIED: + case IDC_DND: + case IDC_FREECHAT: + case IDC_INVISIBLE: + case IDC_ONTHEPHONE: + case IDC_OUTTOLUNCH: + case IDC_OFFLINE: + EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SOLDER: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) { + BOOL translated; + int val = GetDlgItemInt(hwndDlg, IDC_SOLDER, &translated, FALSE); + if (translated && val < 1) + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + return TRUE; + case IDC_SBLINK: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) { + BOOL translated; + int val = GetDlgItemInt(hwndDlg, IDC_SBLINK, &translated, FALSE); + if (translated && val < 1) + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + return TRUE; + case IDC_ASSIGNPGMS: + if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PROCESSES), hwndDlg, DlgProcProcesses, 0) == IDC_OKPGM) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SELECTXSTATUS: + if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_XSTATUSES), hwndDlg, DlgProcXstatusList, 0) == IDC_OKXST) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SREMCHECK: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_MIRORWIN: + if(HIWORD(wParam) == CBN_SELCHANGE) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + } + break; + + case WM_NOTIFY: + { + BYTE untilMap = 0; + WORD statusMap = 0; + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + db_set_b(NULL, KEYBDMODULE, "onmsg", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONMESSAGE) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "onurl", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONURL) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "onfile", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONFILE) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "onother", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONOTHER) == BST_CHECKED ? 1:0)); + + db_set_b(NULL, KEYBDMODULE, "fscreenmode", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_FSCREEN) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "ssaverrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SSAVER) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "wstationlocked", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "procsrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_PGMS) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "wstationactive", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ACTIVE) == BST_CHECKED ? 1:0)); + + db_set_b(NULL, KEYBDMODULE, "ifmsgopen", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "ifmsgnottop", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFNOTTOP) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "ifmsgolder", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED ? 1:0)); + db_set_w(NULL, KEYBDMODULE, "secsolder", (WORD)SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_GETPOS, 0, 0)); + + if(IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED) + untilMap |= UNTIL_NBLINKS; + if (IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED) + untilMap |= UNTIL_REATTENDED; + if (IsDlgButtonChecked(hwndDlg, IDC_UNTILOPEN) == BST_CHECKED) + untilMap |= UNTIL_EVENTSOPEN; + if (IsDlgButtonChecked(hwndDlg, IDC_UNTILCOND) == BST_CHECKED) + untilMap |= UNTIL_CONDITIONS; + db_set_b(NULL, KEYBDMODULE, "funtil", untilMap); + db_set_w(NULL, KEYBDMODULE, "nblinks", (WORD)SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_GETPOS, 0, 0)); + db_set_b(NULL, KEYBDMODULE, "mirorwin", (BYTE)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETCURSEL, 0, 0), 0)); + + if(IsDlgButtonChecked(hwndDlg, IDC_ONLINE) == BST_CHECKED) + statusMap |= MAP_ONLINE; + if(IsDlgButtonChecked(hwndDlg, IDC_AWAY) == BST_CHECKED) + statusMap |= MAP_AWAY; + if(IsDlgButtonChecked(hwndDlg, IDC_NA) == BST_CHECKED) + statusMap |= MAP_NA; + if(IsDlgButtonChecked(hwndDlg, IDC_OCCUPIED) == BST_CHECKED) + statusMap |= MAP_OCCUPIED; + if(IsDlgButtonChecked(hwndDlg, IDC_DND) == BST_CHECKED) + statusMap |= MAP_DND; + if(IsDlgButtonChecked(hwndDlg, IDC_FREECHAT) == BST_CHECKED) + statusMap |= MAP_FREECHAT; + if(IsDlgButtonChecked(hwndDlg, IDC_INVISIBLE) == BST_CHECKED) + statusMap |= MAP_INVISIBLE; + if(IsDlgButtonChecked(hwndDlg, IDC_ONTHEPHONE) == BST_CHECKED) + statusMap |= MAP_ONTHEPHONE; + if(IsDlgButtonChecked(hwndDlg, IDC_OUTTOLUNCH) == BST_CHECKED) + statusMap |= MAP_OUTTOLUNCH; + if(IsDlgButtonChecked(hwndDlg, IDC_OFFLINE) == BST_CHECKED) + statusMap |= MAP_OFFLINE; + db_set_w(NULL, KEYBDMODULE, "status", statusMap); + + db_set_w(NULL, KEYBDMODULE, "remcheck", (WORD)SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_GETPOS, 0, 0)); + + int i = 0; + for (int j = 0; j < ProcessListAux.count; j++) + if (ProcessListAux.szFileName[j]) + db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++), ProcessListAux.szFileName[j]); + db_set_w(NULL, KEYBDMODULE, "processcount", (WORD)i); + while (!db_unset(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++))); + + if (XstatusListAux) + for (int i = 0; i < ProtoList.protoCount; i++) + for (int j = 0; j < (int)XstatusListAux[i].count; j++) + db_set_b(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), (BYTE)XstatusListAux[i].enabled[j]); + + LoadSettings(); + + return TRUE; + } // switch code + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK DlgProcEffectOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + DBVARIANT dbv; + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + trillianLedsMsg = bTrillianLedsMsg; + trillianLedsURL = bTrillianLedsURL; + trillianLedsFile = bTrillianLedsFile; + trillianLedsOther = bTrillianLedsOther; + + CheckDlgButton(hwndDlg, IDC_NUM, bFlashLed[0] ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CAPS, bFlashLed[1] ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SCROLL, bFlashLed[2] ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_SAMETIME, bFlashEffect == FLASH_SAMETIME ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_INTURN, bFlashEffect == FLASH_INTURN ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_INSEQUENCE, bFlashEffect == FLASH_INSEQUENCE ? BST_CHECKED:BST_UNCHECKED); + for (i=0; i < 3; i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(OrderName[i])); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETCURSEL, (WPARAM)bSequenceOrder, 0); + if (bFlashEffect != FLASH_INSEQUENCE) + EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), FALSE); + CheckDlgButton(hwndDlg, IDC_CUSTOM, bFlashEffect == FLASH_CUSTOM ? BST_CHECKED:BST_UNCHECKED); + for (i=0; !db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.ptszVal); + db_free(&dbv); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); + if (bFlashEffect != FLASH_CUSTOM) + EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), FALSE); + CheckDlgButton(hwndDlg, IDC_TRILLIAN, bFlashEffect == FLASH_TRILLIAN ? BST_CHECKED:BST_UNCHECKED); + if (bFlashEffect != FLASH_TRILLIAN) + EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), FALSE); + + SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SDELAY), 0); + SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETPOS, 0, MAKELONG(wStartDelay, 0)); + + SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, FALSE, MAKELONG(0, 5)); + SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, bFlashSpeed); + + CheckDlgButton(hwndDlg, IDC_KEYPRESSES, bEmulateKeypresses ? BST_CHECKED:BST_UNCHECKED); + + initDlg=FALSE; + return TRUE; + + case WM_VSCROLL: + case WM_HSCROLL: + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + break; + + case WM_DESTROY: + previewFlashing(FALSE); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_NUM: + case IDC_CAPS: + case IDC_SCROLL: + case IDC_SAMETIME: + case IDC_INTURN: + case IDC_INSEQUENCE: + case IDC_CUSTOM: + case IDC_TRILLIAN: + case IDC_SPEED: + case IDC_KEYPRESSES: + EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_ASSIGNLEDS: + if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EVENTLEDS), hwndDlg, DlgProcEventLeds, 0) == IDC_OK) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SDELAY: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_PREVIEW: + previewFlashing(IsDlgButtonChecked(hwndDlg, IDC_PREVIEW) == BST_CHECKED); + return TRUE; + case IDC_SEQORDER: + case IDC_SCUSTOM: + if(HIWORD(wParam) == CBN_SELCHANGE) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + } + break; + + case WM_NOTIFY: + { + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + db_set_b(NULL, KEYBDMODULE, "fnum", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_NUM) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "fcaps", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CAPS) == BST_CHECKED ? 1:0)); + db_set_b(NULL, KEYBDMODULE, "fscroll", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SCROLL) == BST_CHECKED ? 1:0)); + + if(IsDlgButtonChecked(hwndDlg, IDC_INTURN) == BST_CHECKED) + db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_INTURN); + else + if (IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED) + db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_INSEQUENCE); + else + if (IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED) + db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_CUSTOM); + else + if (IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED) + db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_TRILLIAN); + else + db_set_b(NULL, KEYBDMODULE, "feffect", FLASH_SAMETIME); + db_set_b(NULL, KEYBDMODULE, "order", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETCURSEL, 0, 0), 0)); + db_set_w(NULL, KEYBDMODULE, "custom", (WORD)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETCURSEL, 0, 0), 0)); + + db_set_b(NULL, KEYBDMODULE, "ledsmsg", trillianLedsMsg); + db_set_b(NULL, KEYBDMODULE, "ledsfile", trillianLedsFile); + db_set_b(NULL, KEYBDMODULE, "ledsurl", trillianLedsURL); + db_set_b(NULL, KEYBDMODULE, "ledsother", trillianLedsOther); + + db_set_w(NULL, KEYBDMODULE, "sdelay", (WORD)SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_GETPOS, 0, 0)); + + db_set_b(NULL, KEYBDMODULE, "speed", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0)); + + db_set_b(NULL, KEYBDMODULE, "keypresses", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_KEYPRESSES) == BST_CHECKED ? 1:0)); + + LoadSettings(); + + return TRUE; + } // switch code + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK DlgProcThemeOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + TCHAR *str; + DBVARIANT dbv; + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + SendDlgItemMessage(hwndDlg, IDC_THEME, EM_LIMITTEXT, MAX_PATH, 0); + SendDlgItemMessage(hwndDlg, IDC_CUSTOMSTRING, EM_LIMITTEXT, MAX_PATH, 0); + + for (i=0; !db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.ptszVal); + db_free(&dbv); + if (index != CB_ERR && index != CB_ERRSPACE) { + str = (TCHAR *)malloc(MAX_PATH+1); + if (str) + if (db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) + str[0] = _T('\0'); + else { + _tcscpy(str, dbv.ptszVal); + db_free(&dbv); + } + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)index, (LPARAM)str); + } + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); + else { + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)wCustomTheme, 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + } + + CheckDlgButton(hwndDlg, IDC_OVERRIDE, bOverride ? BST_CHECKED:BST_UNCHECKED); + + initDlg=FALSE; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_THEME: + switch (HIWORD(wParam)) { + int item; + TCHAR theme[MAX_PATH+1]; + + case CBN_SELENDOK: + case CBN_SELCHANGE: + str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + else + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); + break; + case CBN_EDITCHANGE: + GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); + if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) { //new theme + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); + } else { + str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + else + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + break; + } + return TRUE; + case IDC_CUSTOMSTRING: + if(HIWORD(wParam) == EN_CHANGE) { + int item; + TCHAR theme[MAX_PATH+1], customAux[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); + if ((item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) + return TRUE; + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) { + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, customAux, MAX_PATH); + if (wcscmp(str, customAux)) + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), TRUE); + else + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + } + } + return TRUE; + case IDC_TEST: + { + TCHAR custom[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, custom, MAX_PATH); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(custom)); + testSequence(custom); + } + return TRUE; + case IDC_ADD: + { + int item; + TCHAR theme[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); + if (!theme[0]) + return TRUE; + item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); + str = (TCHAR *)malloc(MAX_PATH+1); + if (str) { + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); + } + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); + } + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_UPDATE: + { + int item; + TCHAR theme[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); + item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) { + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + } + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_DELETE: + { + int item; + TCHAR theme[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, SIZEOF(theme)); + item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + free(str); + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_DELETESTRING, (WPARAM)item, 0); + if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) { + SetDlgItemText(hwndDlg, IDC_THEME, _T("")); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); + } else { + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, 0, 0); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, 0, 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + } + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_EXPORT: + { + TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; + OPENFILENAME ofn={0}; + + path[0] = _T('\0'); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndDlg; + ofn.hInstance = NULL; + _tcscpy(filter, TranslateT("Keyboard Notify Theme")); + wcscat(filter, _T(" (*.knt)")); + pfilter = filter + _tcslen(filter) + 1; + _tcscpy(pfilter, _T("*.knt")); + pfilter = pfilter + _tcslen(pfilter) + 1; + _tcscpy(pfilter, TranslateT("All Files")); + pfilter = pfilter + _tcslen(pfilter) + 1; + _tcscpy(pfilter, _T("*.*")); + pfilter = pfilter + _tcslen(pfilter) + 1; + *pfilter = _T('\0'); + ofn.lpstrFilter = filter; + ofn.lpstrFile = path; + ofn.Flags = OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST; + ofn.nMaxFile = SIZEOF(path); + ofn.lpstrDefExt = _T("knt"); + if(GetSaveFileName(&ofn)) + exportThemes(path); + } + return TRUE; + case IDC_IMPORT: + { + TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; + OPENFILENAME ofn={0}; + + path[0] = _T('\0'); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndDlg; + ofn.hInstance = NULL; + _tcscpy(filter, TranslateT("Keyboard Notify Theme")); + wcscat(filter, _T(" (*.knt)")); + pfilter = filter + _tcslen(filter) + 1; + _tcscpy(pfilter, _T("*.knt")); + pfilter = pfilter + _tcslen(pfilter) + 1; + _tcscpy(pfilter, TranslateT("All Files")); + pfilter = pfilter + _tcslen(pfilter) + 1; + _tcscpy(pfilter, _T("*.*")); + pfilter = pfilter + _tcslen(pfilter) + 1; + *pfilter = _T('\0'); + ofn.lpstrFilter = filter; + ofn.lpstrFile = path; + ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR; + ofn.nMaxFile = SIZEOF(path); + ofn.lpstrDefExt = _T("knt"); + if(GetOpenFileName(&ofn)) { + importThemes(path, IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + } + return TRUE; + case IDC_OVERRIDE: + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + } + break; + + case WM_NOTIFY: + { + int count; + TCHAR theme[MAX_PATH+1], themeAux[MAX_PATH+1], *str; + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + if (!db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", wCustomTheme), &dbv)) + _tcscpy(theme, dbv.ptszVal); + else + theme[0] = _T('\0'); + + // Here we will delete all the items in the theme combo on the Flashing tab: we will load them again later + for (i=0; SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_DELETESTRING, 0, (LPARAM)i) != CB_ERR; i++); + + count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); + for (i=0, wCustomTheme=0; i < count; i++) { + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETLBTEXT, (WPARAM)i, (LPARAM)themeAux); + db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), themeAux); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)i, 0); + if (str) + db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), str); + else + db_set_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), _T("")); + + if (!wcscmp(theme, themeAux)) + wCustomTheme = i; + + // Here we will update the theme combo on the Flashing tab: horrible but can't imagine a better way right now + SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)i, (LPARAM)themeAux); + SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)i, (LPARAM)i); + } + for (i=count; !db_unset(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i)); i++) + db_unset(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i)); + + db_set_w(NULL, KEYBDMODULE, "custom", wCustomTheme); + // Still updating here the the Flashing tab's controls + SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); + + db_set_b(NULL, KEYBDMODULE, "override", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED ? 1:0)); + + return TRUE; + } // switch code + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + case WM_DESTROY: + { + int item, count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); + + for (item=0; item < count; item++) { + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + free(str); + } + break; + } + + default: + break; + } + + return FALSE; +} + + +void exportThemes(const TCHAR *filename) +{ + int i; + FILE *fExport = _tfopen(filename, _T("wt")); + DBVARIANT dbv; + + if (!fExport) + return; + + fwprintf(fExport, TranslateT("\n; Automatically generated Keyboard Notify Theme file\n\n\n")); + + for (i=0; !db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { + _ftprintf(fExport, _T("[%s]\n"), dbv.ptszVal); + db_free(&dbv); + if (db_get_ts(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) + _ftprintf(fExport, _T("0\n\n")); + else { + _ftprintf(fExport, _T("%s\n\n"), dbv.ptszVal); + db_free(&dbv); + } + } + + _ftprintf(fExport, TranslateT("\n; End of automatically generated Keyboard Notify Theme file\n")); + + fclose(fExport); +} + + +void importThemes(const TCHAR *filename, BOOL overrideExisting) +{ + int status=0; + size_t i; + FILE *fImport = _tfopen(filename, _T("rt")); + TCHAR buffer[MAX_PATH+1], theme[MAX_PATH+1], *str; + + if (!fImport) + return; + + while (_fgetts(buffer, MAX_PATH, fImport) != NULL) { + for (str=buffer; *str && isspace(*str); str++); //ltrim + if (!*str || *str == ';') //empty line or comment + continue; + for (i=_tcslen(str)-1; isspace(str[i]); str[i--]='\0'); //rtrim + switch (status) { + case 0: + if (i > 1 && str[0] == '[' && str[i] == ']') { + status = 1; + _tcscpy(theme, str+1); + theme[i-1] = '\0'; + } + break; + case 1: + status = 0; + writeThemeToCombo(theme, normalizeCustomString(str), overrideExisting); + break; + } + } + + fclose(fImport); +} + + +void writeThemeToCombo(const TCHAR *theme, const TCHAR *custom, BOOL overrideExisting) +{ + int item; + TCHAR *str; + + item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); + if (item == CB_ERR) { + item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); + str = (TCHAR *)malloc(MAX_PATH+1); + if (str) + _tcscpy(str, custom); + SendDlgItemMessage(hwndTheme, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); + } else + if (overrideExisting) { + str = (TCHAR *)SendDlgItemMessage(hwndTheme, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + _tcscpy(str, custom); + } +} + + +INT_PTR CALLBACK DlgProcProcesses(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, EM_LIMITTEXT, MAX_PATH, 0); + + for (int i = 0; i < ProcessListAux.count; i++) + if (ProcessListAux.szFileName[i]) { + int index = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)ProcessListAux.szFileName[i]); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); + else + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_PROGRAMS: + switch (HIWORD(wParam)) { + int item; + TCHAR szFileName[MAX_PATH+1]; + + case CBN_SELENDOK: + case CBN_SELCHANGE: + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); + break; + case CBN_EDITCHANGE: + GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, SIZEOF(szFileName)); + if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName)) == CB_ERR) { //new program + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); + } else { + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); + } + break; + } + break; + case IDC_ADDPGM: + { + int item; + TCHAR szFileName[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, SIZEOF(szFileName)); + if (!szFileName[0]) + break; + item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_ADDSTRING, 0, (LPARAM)szFileName); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); + } + break; + case IDC_DELETEPGM: + { + int item; + TCHAR szFileName[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, SIZEOF(szFileName)); + item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName); + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_DELETESTRING, (WPARAM)item, 0); + if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) { + SetDlgItemText(hwndDlg, IDC_PROGRAMS, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); + } else + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); + } + break; + case IDC_OKPGM: + destroyProcessListAux(); + + ProcessListAux.count = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0); + ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(TCHAR *)); + if (!ProcessListAux.szFileName) + ProcessListAux.count = 0; + else + for (int i = 0; i < ProcessListAux.count; i++) { + TCHAR szFileNameAux[MAX_PATH+1]; + + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETLBTEXT, (WPARAM)i, (LPARAM)szFileNameAux); + ProcessListAux.szFileName[i] = (TCHAR *)malloc(_tcslen(szFileNameAux) + 1); + if (ProcessListAux.szFileName[i]) + _tcscpy(ProcessListAux.szFileName[i], szFileNameAux); + } + + case IDC_CANCELPGM: + EndDialog(hwndDlg, LOWORD(wParam)); + break; + } + break; + } + + return FALSE; +} + + +void createProcessListAux(void) +{ + ProcessListAux.count = ProcessList.count; + ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(char *)); + if (!ProcessListAux.szFileName) + ProcessListAux.count = 0; + else + for (int i = 0; i < ProcessListAux.count; i++) + if (!ProcessList.szFileName[i]) + ProcessListAux.szFileName[i] = NULL; + else { + ProcessListAux.szFileName[i] = (TCHAR *)malloc(_tcslen(ProcessList.szFileName[i]) + 1); + if (ProcessListAux.szFileName[i]) + _tcscpy(ProcessListAux.szFileName[i], ProcessList.szFileName[i]); + } + +} + + +void destroyProcessListAux(void) +{ + if (ProcessListAux.szFileName == NULL) + return; + for (int i = 0; i < ProcessListAux.count; i ++) { + if (ProcessListAux.szFileName[i]) { + free(ProcessListAux.szFileName[i]); + } + } + free(ProcessListAux.szFileName); + ProcessListAux.count = 0; + ProcessListAux.szFileName = NULL; +} + + +INT_PTR CALLBACK DlgProcEventLeds(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + + CheckDlgButton(hwndDlg, IDC_MSGLEDNUM, trillianLedsMsg&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_MSGLEDCAPS, trillianLedsMsg&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_MSGLEDSCROLL, trillianLedsMsg&1 ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_FILELEDNUM, trillianLedsFile&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_FILELEDCAPS, trillianLedsFile&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_FILELEDSCROLL, trillianLedsFile&1 ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_URLLEDNUM, trillianLedsURL&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_URLLEDCAPS, trillianLedsURL&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_URLLEDSCROLL, trillianLedsURL&1 ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_OTHERLEDNUM, trillianLedsOther&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OTHERLEDCAPS, trillianLedsOther&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OTHERLEDSCROLL, trillianLedsOther&1 ? BST_CHECKED:BST_UNCHECKED); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_OK: + trillianLedsMsg = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDNUM) == BST_CHECKED) + trillianLedsMsg |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDCAPS) == BST_CHECKED) + trillianLedsMsg |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDSCROLL) == BST_CHECKED) + trillianLedsMsg |= 1; + + trillianLedsFile = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDNUM) == BST_CHECKED) + trillianLedsFile |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDCAPS) == BST_CHECKED) + trillianLedsFile |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDSCROLL) == BST_CHECKED) + trillianLedsFile |= 1; + + trillianLedsURL = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDNUM) == BST_CHECKED) + trillianLedsURL |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDCAPS) == BST_CHECKED) + trillianLedsURL |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDSCROLL) == BST_CHECKED) + trillianLedsURL |= 1; + + trillianLedsOther = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDNUM) == BST_CHECKED) + trillianLedsOther |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDCAPS) == BST_CHECKED) + trillianLedsOther |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDSCROLL) == BST_CHECKED) + trillianLedsOther |= 1; + + case IDC_CANCEL: + EndDialog(hwndDlg, LOWORD(wParam)); + break; + } + break; + } + + return FALSE; +} + + +void createXstatusListAux(void) +{ + XstatusListAux = (XSTATUS_INFO *)malloc(ProtoList.protoCount * sizeof(XSTATUS_INFO)); + if (XstatusListAux) + for (int i = 0; i < ProtoList.protoCount; i++) { + XstatusListAux[i].count = ProtoList.protoInfo[i].xstatus.count; + if (!XstatusListAux[i].count) + XstatusListAux[i].enabled = NULL; + else { + XstatusListAux[i].enabled = (BOOL *)malloc(XstatusListAux[i].count * sizeof(BOOL)); + if (!XstatusListAux[i].enabled) + XstatusListAux[i].count = 0; + else + for (int j = 0; j < (int)XstatusListAux[i].count; j++) + XstatusListAux[i].enabled[j] = ProtoList.protoInfo[i].xstatus.enabled[j]; + } + } + +} + + +void destroyXstatusListAux(void) +{ + if (XstatusListAux) { + for (int i = 0; i < ProtoList.protoCount; i++) + if (XstatusListAux[i].enabled) + free(XstatusListAux[i].enabled); + free(XstatusListAux); + XstatusListAux = NULL; + } + +} + + +INT_PTR CALLBACK DlgProcXstatusList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + + case WM_INITDIALOG: + + { + WPARAM j; + int imageCount; + HICON hIconAux; + HIMAGELIST hImageList; + TVINSERTSTRUCT tvis={0}; + TVITEM tvi={0}; + HTREEITEM hSectionItem, hItem; + HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); + + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndTree, GWL_STYLE, GetWindowLongPtr(hwndTree, GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES); + + if (!XstatusListAux) return TRUE; + + // Calculate hImageList size + imageCount=1; + for (int i = 0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) + imageCount += XstatusListAux[i].count; + + hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR32 | ILC_MASK, imageCount, imageCount); + TreeView_SetImageList(hwndTree, hImageList, TVSIL_NORMAL); + + ImageList_AddIcon(hImageList, hIconAux=(HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, 0, 0, 0)); + if (hIconAux) DestroyIcon(hIconAux); + + TreeView_SelectItem(hwndTree, NULL); + ShowWindow(hwndTree, SW_HIDE); + TreeView_DeleteAllItems(hwndTree); + + for (int i = 0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) { + HTREEITEM hParent; + + int count; PROTOACCOUNT** protos; + ProtoEnumAccounts( &count, &protos ); + + tvis.hParent = NULL; + tvis.hInsertAfter = TVI_LAST; + tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + tvis.item.pszText = protos[i] -> tszAccountName; + tvis.item.lParam = (LPARAM)i; + tvis.item.stateMask = TVIS_BOLD|TVIS_EXPANDED; + tvis.item.state = TVIS_BOLD|TVIS_EXPANDED; + tvis.item.iImage = tvis.item.iSelectedImage = ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_LOADICON, PLI_PROTOCOL, 0)); + if (hIconAux) DestroyIcon(hIconAux); + hParent = TreeView_InsertItem(hwndTree, &tvis); + for (j = 0; j < XstatusListAux[i].count; j++) { + tvis.hParent = hParent; + tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + if (!j){ + tvis.item.pszText = TranslateT("None"); } + else { + TCHAR szDefaultName[1024]; + CUSTOM_STATUS xstatus={0}; + xstatus.cbSize = sizeof(CUSTOM_STATUS); + xstatus.flags = CSSF_MASK_NAME|CSSF_DEFAULT_NAME|CSSF_TCHAR; + xstatus.ptszName = szDefaultName; + xstatus.wParam = &j; + CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + tvis.item.pszText = TranslateTS(szDefaultName); + } + tvis.item.lParam = (LPARAM)j; + tvis.item.iImage = tvis.item.iSelectedImage = j?ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_GETCUSTOMSTATUSICON, (WPARAM)j, 0)):0; + if (hIconAux) DestroyIcon(hIconAux); + TreeView_InsertItem(hwndTree, &tvis); + } + } + + tvi.mask = TVIF_HANDLE|TVIF_PARAM; + for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { + tvi.hItem = hSectionItem; + TreeView_GetItem(hwndTree, &tvi); + unsigned int i = (unsigned int)tvi.lParam; + TreeView_SetItemState(hwndTree, hSectionItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK); + for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { + tvi.hItem = hItem; + TreeView_GetItem(hwndTree, &tvi); + j = (unsigned int)tvi.lParam; + TreeView_SetItemState(hwndTree, hItem, INDEXTOSTATEIMAGEMASK(XstatusListAux[i].enabled[j]?2:1), TVIS_STATEIMAGEMASK); + } + } + + ShowWindow(hwndTree, SW_SHOW); + TreeView_SetItemState(hwndTree, 0, TVIS_SELECTED, TVIS_SELECTED); + return TRUE; + } + + case WM_DESTROY: + { + HIMAGELIST hImageList; + + // Destroy tree view imagelist since it does not get destroyed automatically (see msdn docs) + hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_STATE); + if (hImageList) { + TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_STATE); + ImageList_Destroy(hImageList); + } + hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_NORMAL); + if (hImageList) { + TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_NORMAL); + ImageList_Destroy(hImageList); + } + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_OKXST: + { + unsigned int i, j; + HTREEITEM hSectionItem, hItem; + TVITEM tvi={0}; + HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); + + tvi.mask = TVIF_HANDLE|TVIF_PARAM; + for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { + tvi.hItem = hSectionItem; + TreeView_GetItem(hwndTree, &tvi); + i = (unsigned int)tvi.lParam; + for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { + tvi.hItem = hItem; + TreeView_GetItem(hwndTree, &tvi); + j = (unsigned int)tvi.lParam; + XstatusListAux[i].enabled[j] = !!(TreeView_GetItemState(hwndTree, hItem, TVIS_STATEIMAGEMASK)&INDEXTOSTATEIMAGEMASK(2)); + } + } + } + + case IDC_CANCELXST: + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + } + break; + } + + return FALSE; +} -- cgit v1.2.3