diff options
author | Rozhuk Ivan <rozhuk.im@gmail.com> | 2014-11-25 14:09:27 +0000 |
---|---|---|
committer | Rozhuk Ivan <rozhuk.im@gmail.com> | 2014-11-25 14:09:27 +0000 |
commit | d318b6b8b91344cf74ded01e8ff550a5faf0c97a (patch) | |
tree | 98f54667be3eb4d9b39ccfe2969b53992f6620fc /src/modules/skin | |
parent | 07f48ba259728dea36c36ad7879c4f8b5fbf8e60 (diff) |
add null ptr check
git-svn-id: http://svn.miranda-ng.org/main/trunk@11058 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'src/modules/skin')
-rw-r--r-- | src/modules/skin/hotkey_opts.cpp | 2023 |
1 files changed, 1012 insertions, 1011 deletions
diff --git a/src/modules/skin/hotkey_opts.cpp b/src/modules/skin/hotkey_opts.cpp index 53c7ba77fe..bcbbac7ac1 100644 --- a/src/modules/skin/hotkey_opts.cpp +++ b/src/modules/skin/hotkey_opts.cpp @@ -1,1011 +1,1012 @@ -/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org),
-Copyright (c) 2000-12 Miranda IM project,
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-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 "..\..\core\commonheaders.h"
-
-#include <m_hotkeys.h>
-#include "skin.h"
-
-static TCHAR *sttHokeyVkToName(WORD vkKey)
-{
- static TCHAR buf[256] = {0};
- DWORD code = MapVirtualKey(vkKey, 0) << 16;
-
- switch (vkKey)
- {
- case 0:
- case VK_CONTROL:
- case VK_SHIFT:
- case VK_MENU:
- case VK_LWIN:
- case VK_RWIN:
- case VK_PAUSE:
- case VK_CANCEL:
- case VK_NUMLOCK:
- case VK_CAPITAL:
- case VK_SCROLL:
- return _T("");
-
- case VK_DIVIDE:
- case VK_INSERT:
- case VK_HOME:
- case VK_PRIOR:
- case VK_DELETE:
- case VK_END:
- case VK_NEXT:
- case VK_LEFT:
- case VK_RIGHT:
- case VK_UP:
- case VK_DOWN:
- code |= (1UL << 24);
- }
-
- GetKeyNameText(code, buf, 256);
- return buf;
-}
-
-void HotkeyToName(TCHAR *buf, int size, BYTE shift, BYTE key)
-{
- mir_sntprintf(buf, size, _T("%s%s%s%s%s"),
- (shift & HOTKEYF_CONTROL) ? TranslateT("Ctrl + ") : _T(""),
- (shift & HOTKEYF_ALT) ? TranslateT("Alt + ") : _T(""),
- (shift & HOTKEYF_SHIFT) ? TranslateT("Shift + ") : _T(""),
- (shift & HOTKEYF_EXT) ? TranslateT("Win + ") : _T(""),
- sttHokeyVkToName(key));
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Hotkey control
-
-static LRESULT CALLBACK sttHotkeyEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- THotkeyBoxData *data = (THotkeyBoxData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
- BOOL bKeyDown = FALSE;
- if (!data) return 0;
-
- switch (msg) {
- case HKM_GETHOTKEY:
- return data->key ? MAKEWORD(data->key, data->shift) : 0;
-
- case HKM_SETHOTKEY:
- {
- TCHAR buf[256] = {0};
- data->key = (BYTE)LOWORD(wParam);
- data->shift = (BYTE)HIWORD(wParam);
- HotkeyToName(buf, SIZEOF(buf), data->shift, data->key);
- SetWindowText(hwnd, buf);
- }
- return 0;
-
- case WM_GETDLGCODE:
- return DLGC_WANTALLKEYS;
-
- case WM_KILLFOCUS:
- break;
-
- case WM_CHAR:
- case WM_SYSCHAR:
- case WM_PASTE:
- case WM_CONTEXTMENU:
- return TRUE;
-
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- bKeyDown = TRUE;
-
- case WM_KEYUP:
- case WM_SYSKEYUP:
- {
- TCHAR buf[256] = {0};
-
- BYTE shift = 0;
- BYTE key = wParam;
- TCHAR *name = sttHokeyVkToName(key);
- if (!*name || !bKeyDown)
- key = 0;
-
- if (GetAsyncKeyState(VK_CONTROL)) shift |= HOTKEYF_CONTROL;
- if (GetAsyncKeyState(VK_MENU)) shift |= HOTKEYF_ALT;
- if (GetAsyncKeyState(VK_SHIFT)) shift |= HOTKEYF_SHIFT;
- if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN)) shift |= HOTKEYF_EXT;
-
- if (bKeyDown || !data->key) {
- data->shift = shift;
- data->key = key;
- }
-
- HotkeyToName(buf, SIZEOF(buf), data->shift, data->key);
- SetWindowText(hwnd, buf);
-
- if (bKeyDown && data->key)
- SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(GetWindowLongPtr(hwnd, GWL_ID), 0), (LPARAM)hwnd);
- }
- return TRUE;
-
- case WM_DESTROY:
- SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
- mir_free(data);
- }
-
- return mir_callNextSubclass(hwnd, sttHotkeyEditProc, msg, wParam, lParam);
-}
-
-void HotkeyEditCreate(HWND hwnd)
-{
- THotkeyBoxData *data = (THotkeyBoxData *)mir_alloc(sizeof(THotkeyBoxData));
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (ULONG_PTR)data);
- mir_subclassWindow(hwnd, sttHotkeyEditProc);
-}
-
-void HotkeyEditDestroy(HWND hwnd)
-{
- THotkeyBoxData *data = (THotkeyBoxData *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
- SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
- mir_free(data);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Options
-
-enum { COL_NAME, COL_TYPE, COL_KEY, COL_RESET, COL_ADDREMOVE };
-
-static void sttOptionsSetupItem(HWND hwndList, int idx, THotkeyItem *item)
-{
- TCHAR buf[256];
- LVITEM lvi = {0};
- lvi.iItem = idx;
-
- if (!item->rootHotkey) {
- lvi.mask = LVIF_TEXT|LVIF_IMAGE;
- lvi.iSubItem = COL_NAME;
- lvi.pszText = item->getDescr();
- lvi.iImage = item->OptType;
- ListView_SetItem(hwndList, &lvi);
-
- ListView_SetCheckState(hwndList, lvi.iItem, item->Enabled);
- }
-
- lvi.mask = LVIF_TEXT;
- lvi.iSubItem = COL_KEY;
- HotkeyToName(buf, SIZEOF(buf), HIBYTE(item->OptHotkey), LOBYTE(item->OptHotkey));
- lvi.pszText = buf;
- ListView_SetItem(hwndList, &lvi);
-
- if (item->rootHotkey) {
- lvi.mask = LVIF_IMAGE;
- lvi.iSubItem = COL_TYPE;
- lvi.iImage = item->OptType;
- ListView_SetItem(hwndList, &lvi);
- }
-
- lvi.mask = LVIF_IMAGE;
- lvi.iSubItem = COL_RESET;
- lvi.iImage = (item->Hotkey != item->OptHotkey) ? 5 : -1;
- ListView_SetItem(hwndList, &lvi);
-
- lvi.mask = LVIF_IMAGE|LVIF_TEXT;
- lvi.iSubItem = COL_ADDREMOVE;
- if (item->rootHotkey) {
- lvi.iImage = 4;
- lvi.pszText = TranslateT("Remove shortcut");
- }
- else {
- lvi.iImage = 3;
- lvi.pszText = TranslateT("Add another shortcut");
- }
- ListView_SetItem(hwndList, &lvi);
-}
-
-static void sttOptionsDeleteHotkey(HWND hwndList, int idx, THotkeyItem *item)
-{
- item->OptDeleted = TRUE;
- ListView_DeleteItem(hwndList, idx);
- if (item->rootHotkey)
- item->rootHotkey->OptChanged = TRUE;
-}
-
-static int CALLBACK sttOptionsSortList(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
-{
- TCHAR title1[256] = {0}, title2[256] = {0};
- THotkeyItem *item1 = NULL, *item2 = NULL;
- LVITEM lvi = {0};
- int res;
-
- lvi.mask = LVIF_TEXT|LVIF_PARAM;
- lvi.iItem = lParam1;
- lvi.pszText = title1;
- lvi.cchTextMax = SIZEOF(title1);
- if (ListView_GetItem((HWND)lParamSort, &lvi))
- item1 = (THotkeyItem *)lvi.lParam;
-
- lvi.mask = LVIF_TEXT|LVIF_PARAM;
- lvi.iItem = lParam2;
- lvi.pszText = title2;
- lvi.cchTextMax = SIZEOF(title2);
- if (ListView_GetItem((HWND)lParamSort, &lvi))
- item2 = (THotkeyItem *)lvi.lParam;
-
- if (!item1 && !item2)
- return lstrcmp(title1, title2);
-
- if (!item1) {
- if (res = lstrcmp(title1, item2->getSection()))
- return res;
- return -1;
- }
-
- if (!item2) {
- if (res = lstrcmp(item1->getSection(), title2))
- return res;
- return 1;
- }
-
- if (res = lstrcmp(item1->getSection(), item2->getSection())) return res;
- if (res = lstrcmp(item1->getDescr(), item2->getDescr())) return res;
- if (!item1->rootHotkey && item2->rootHotkey) return -1;
- if (item1->rootHotkey && !item2->rootHotkey) return 1;
- return 0;
-}
-
-static void sttOptionsAddHotkey(HWND hwndList, THotkeyItem *item)
-{
- char buf[256];
- mir_snprintf(buf, SIZEOF(buf), "mir_hotkey_%d_%d", g_pid, g_hkid++);
-
- THotkeyItem *newItem = (THotkeyItem *)mir_alloc(sizeof(THotkeyItem));
- newItem->pszName = NULL;
- newItem->pszService = item->pszService ? mir_strdup(item->pszService) : NULL;
- newItem->ptszSection = mir_tstrdup(item->ptszSection);
- newItem->ptszDescription = mir_tstrdup(item->ptszDescription);
- newItem->lParam = item->lParam;
- newItem->idHotkey = GlobalAddAtomA(buf);
- newItem->rootHotkey = item;
- newItem->Hotkey = newItem->DefHotkey = newItem->OptHotkey = 0;
- newItem->type = newItem->OptType = item->OptType;
- newItem->Enabled = newItem->OptEnabled = TRUE;
- newItem->OptChanged = newItem->OptDeleted = FALSE;
- newItem->OptNew = TRUE;
- hotkeys.insert(newItem);
-
- SendMessage(hwndList, WM_SETREDRAW, FALSE, 0);
-
- LVITEM lvi = {0};
- lvi.mask |= LVIF_PARAM;
- lvi.lParam = (LPARAM)newItem;
- sttOptionsSetupItem(hwndList, ListView_InsertItem(hwndList, &lvi), newItem);
- ListView_SortItemsEx(hwndList, sttOptionsSortList, (LPARAM)hwndList);
-
- SendMessage(hwndList, WM_SETREDRAW, TRUE, 0);
- RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE);
-
- item->OptChanged = TRUE;
-}
-
-static void sttOptionsSetChanged(THotkeyItem *item)
-{
- item->OptChanged = TRUE;
- if (item->rootHotkey)
- item->rootHotkey->OptChanged = TRUE;
-}
-
-static void sttOptionsSaveItem(THotkeyItem *item)
-{
- int i;
- char buf[MAXMODULELABELLENGTH];
-
- if (item->rootHotkey) return;
- if (!item->OptChanged) return;
-
- item->Hotkey = item->OptHotkey;
- item->type = item->OptType;
- item->Enabled = item->OptEnabled;
-
- db_set_w(NULL, DBMODULENAME, item->pszName, item->Hotkey);
- db_set_b(NULL, DBMODULENAME "Off", item->pszName, (BYTE)!item->Enabled);
- if (item->type != HKT_MANUAL)
- db_set_b(NULL, DBMODULENAME "Types", item->pszName, (BYTE)item->type);
-
- item->nSubHotkeys = 0;
- for (i=0; i < hotkeys.getCount(); i++) {
- THotkeyItem *subItem = hotkeys[i];
- if (subItem->rootHotkey == item) {
- subItem->Hotkey = subItem->OptHotkey;
- subItem->type = subItem->OptType;
-
- mir_snprintf(buf, SIZEOF(buf), "%s$%d", item->pszName, item->nSubHotkeys);
- db_set_w(NULL, DBMODULENAME, buf, subItem->Hotkey);
- if (subItem->type != HKT_MANUAL)
- db_set_b(NULL, DBMODULENAME "Types", buf, (BYTE)subItem->type);
-
- ++item->nSubHotkeys;
- } }
-
- mir_snprintf(buf, SIZEOF(buf), "%s$count", item->pszName);
- db_set_dw(NULL, DBMODULENAME, buf, item->nSubHotkeys);
-}
-
-static void sttBuildHotkeyList(HWND hwndList)
-{
- int i, nItems = 0;
- ListView_DeleteAllItems(hwndList);
-
- for (i=0; i < hotkeys.getCount(); i++) {
- LVITEM lvi = {0};
- THotkeyItem *item = hotkeys[i];
-
- if (item->OptDeleted)
- continue;
-
- if (!i || lstrcmp(item->ptszSection, hotkeys[i-1]->ptszSection)) {
- lvi.mask = LVIF_TEXT|LVIF_PARAM;
- lvi.iItem = nItems++;
- lvi.iSubItem = 0;
- lvi.lParam = 0;
- lvi.pszText = item->getSection();
- ListView_InsertItem(hwndList, &lvi);
- ListView_SetCheckState(hwndList, lvi.iItem, TRUE);
-
- lvi.mask = LVIF_TEXT;
- lvi.iSubItem = 1;
- lvi.pszText = item->ptszSection;
- ListView_SetItem(hwndList, &lvi);
-
- lvi.iSubItem = 0;
- }
-
- lvi.mask = LVIF_PARAM | LVIF_INDENT;
- lvi.iIndent = 1;
- lvi.iItem = nItems++;
- lvi.lParam = (LPARAM)item;
- ListView_InsertItem(hwndList, &lvi);
- sttOptionsSetupItem(hwndList, nItems-1, item);
- }
-
- ListView_SortItemsEx(hwndList, sttOptionsSortList, (LPARAM)hwndList);
-}
-
-static void sttOptionsStartEdit(HWND hwndDlg, HWND hwndHotkey)
-{
- LVITEM lvi;
- THotkeyItem *item;
- int iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED);
- if (iItem < 0) return;
-
- lvi.mask = LVIF_PARAM;
- lvi.iItem = iItem;
- ListView_GetItem(hwndHotkey, &lvi);
-
- if (item = (THotkeyItem *)lvi.lParam) {
- RECT rc;
- ListView_GetSubItemRect(hwndHotkey, iItem, COL_KEY, LVIR_BOUNDS, &rc);
- MapWindowPoints(hwndHotkey, hwndDlg, (LPPOINT)&rc, 2);
- SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_SETHOTKEY, MAKELONG(LOBYTE(item->OptHotkey), HIBYTE(item->OptHotkey)), 0);
-
- SetWindowPos(hwndHotkey, HWND_BOTTOM, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
- SetWindowPos( GetDlgItem(hwndDlg, IDC_HOTKEY), HWND_TOP, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, SWP_SHOWWINDOW);
- RedrawWindow( GetDlgItem(hwndDlg, IDC_HOTKEY), NULL, NULL, RDW_INVALIDATE);
-
- SetFocus( GetDlgItem(hwndDlg, IDC_HOTKEY));
- RedrawWindow( GetDlgItem(hwndDlg, IDC_HOTKEY), NULL, NULL, RDW_INVALIDATE);
- }
-}
-
-static void sttOptionsDrawTextChunk(HDC hdc, TCHAR *text, RECT *rc)
-{
- SIZE sz;
- DrawText(hdc, text, lstrlen(text), rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER|DT_WORD_ELLIPSIS);
- GetTextExtentPoint32(hdc, text, lstrlen(text), &sz);
- rc->left += sz.cx;
-}
-
-static INT_PTR CALLBACK sttOptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- static BOOL initialized = FALSE;
- static int colWidth = 0;
- static WORD currentLanguage = 0;
-
- HWND hwndHotkey = GetDlgItem(hwndDlg, IDC_LV_HOTKEYS);
-
- switch (msg) {
- case WM_INITDIALOG:
- initialized = FALSE;
-
- TranslateDialogDefault(hwndDlg);
-
- HotkeyEditCreate( GetDlgItem(hwndDlg, IDC_HOTKEY));
- {
- HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 3, 1);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_WINDOWS);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_MIRANDA);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_WINDOW);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_ADDCONTACT);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_DELETE);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_UNDO);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_GROUPOPEN);
- ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_GROUPSHUT);
- ListView_SetImageList(hwndHotkey, hIml, LVSIL_SMALL);
- }
- ListView_SetExtendedListViewStyle(hwndHotkey, LVS_EX_CHECKBOXES|LVS_EX_SUBITEMIMAGES|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER|LVS_EX_INFOTIP);
- {
- RECT rc;
- GetClientRect(hwndHotkey, &rc);
- colWidth = rc.right - GetSystemMetrics(SM_CXHTHUMB) - 3*GetSystemMetrics(SM_CXSMICON) - 5;
-
- LVCOLUMN lvc;
- lvc.mask = LVCF_WIDTH;
- lvc.cx = colWidth * 2 / 3;
- ListView_InsertColumn(hwndHotkey, COL_NAME, &lvc);
- lvc.cx = GetSystemMetrics(SM_CXSMICON);
- ListView_InsertColumn(hwndHotkey, COL_TYPE, &lvc);
- lvc.cx = colWidth / 3;
- ListView_InsertColumn(hwndHotkey, COL_KEY, &lvc);
- lvc.cx = GetSystemMetrics(SM_CXSMICON);
- ListView_InsertColumn(hwndHotkey, COL_RESET, &lvc);
- lvc.cx = GetSystemMetrics(SM_CXSMICON);
- ListView_InsertColumn(hwndHotkey, COL_ADDREMOVE, &lvc);
-
- for (int i=0; i < hotkeys.getCount(); i++) {
- THotkeyItem *item = hotkeys[i];
-
- item->OptChanged = FALSE;
- item->OptDeleted = item->OptNew = FALSE;
- item->OptEnabled = item->Enabled;
- item->OptHotkey = item->Hotkey;
- item->OptType = item->type;
- }
-
- currentLanguage = LOWORD(GetKeyboardLayout(0));
- sttBuildHotkeyList(hwndHotkey);
- }
- SetTimer(hwndDlg, 1024, 1000, NULL);
- initialized = TRUE;
- {
- /* load group states */
- int count = ListView_GetItemCount(hwndHotkey);
- TCHAR buf[128];
- LVITEM lvi = {0};
- lvi.pszText = buf;
- lvi.cchTextMax = SIZEOF(buf);
- for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) {
- char *szSetting;
-
- lvi.mask = LVIF_PARAM;
- lvi.iSubItem = 0;
- ListView_GetItem(hwndHotkey, &lvi);
- if (lvi.lParam) continue;
-
- lvi.mask = LVIF_TEXT;
- lvi.iSubItem = 1;
- ListView_GetItem(hwndHotkey, &lvi);
-
- szSetting = mir_t2a(lvi.pszText);
-
- ListView_SetCheckState(hwndHotkey, lvi.iItem,
- db_get_b(NULL, DBMODULENAME "UI", szSetting, TRUE));
-
- mir_free(szSetting);
- }
- }
-
- g_hwndHkOptions = hwndDlg;
- break;
-
- case WM_TIMER:
- if (initialized) {
- WORD newLanguage = LOWORD(GetKeyboardLayout(0));
- if (newLanguage == currentLanguage)
- break;
-
- int count = ListView_GetItemCount(hwndHotkey);
-
- LVITEM lvi = {0};
- lvi.mask = LVIF_PARAM;
- for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) {
- ListView_GetItem(hwndHotkey, &lvi);
- if (lvi.lParam)
- sttOptionsSetupItem(hwndHotkey, lvi.iItem, (THotkeyItem *)lvi.lParam);
- }
- currentLanguage = newLanguage;
- }
- break;
-
- case WM_HOTKEYUNREGISTERED:
- {
- int count = ListView_GetItemCount(hwndHotkey);
-
- LVITEM lvi = {0};
- lvi.mask = LVIF_PARAM;
- for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) {
- ListView_GetItem(hwndHotkey, &lvi);
- if (!lvi.lParam) continue;
-
- if (((THotkeyItem *)lvi.lParam)->UnregisterHotkey) {
- ListView_DeleteItem(hwndHotkey, lvi.iItem);
- --lvi.iItem;
- --count;
- }
- }
- }
- break;
-
- case WM_DRAWITEM:
- {
- LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
- RECT rc = lpdis->rcItem;
- int prefix = 65;
- int width = (lpdis->rcItem.right - lpdis->rcItem.left - prefix) / 3;
- rc.left += 5;
-
- HIMAGELIST hIml = ListView_GetImageList(hwndHotkey, LVSIL_SMALL);
-
- if (lpdis->CtlID == IDC_CANVAS2) {
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Scope:"), &rc);
-
- rc.left = prefix + width * 0;
- ImageList_Draw(hIml, 0, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT);
- rc.left += 20;
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("System"), &rc);
-
- rc.left = prefix + width * 1;
- ImageList_Draw(hIml, 1, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT);
- rc.left += 20;
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Miranda"), &rc);
-
- rc.left = prefix + width * 2;
- ImageList_Draw(hIml, 2, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT);
- rc.left += 20;
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Window"), &rc);
- return TRUE;
- }
-
- if (lpdis->CtlID == IDC_CANVAS) {
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Actions:"), &rc);
- rc.left += 10;
-
- rc.left = prefix + width * 0;
- ImageList_Draw(hIml, 5, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT);
- rc.left += 20;
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Undo"), &rc);
-
- rc.left = prefix + width * 1;
- ImageList_Draw(hIml, 3, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT);
- rc.left += 20;
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Add binding"), &rc);
-
- rc.left = prefix + width * 2;
- ImageList_Draw(hIml, 4, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT);
- rc.left += 20;
- sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Remove"), &rc);
- return TRUE;
- }
- }
- break;
-
- case WM_COMMAND:
- if ((LOWORD(wParam) == IDC_HOTKEY) && ((HIWORD(wParam) == EN_KILLFOCUS) || (HIWORD(wParam) == 0))) {
- LVITEM lvi;
- THotkeyItem *item;
- WORD wHotkey = (WORD)SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_GETHOTKEY, 0, 0);
-
- ShowWindow( GetDlgItem(hwndDlg, IDC_HOTKEY), SW_HIDE);
- SetFocus(hwndHotkey);
- if (!wHotkey || (wHotkey == VK_ESCAPE) || (HIWORD(wParam) != 0))
- break;
-
- lvi.mask = LVIF_PARAM;
- lvi.iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED);
- if (lvi.iItem >= 0) {
- ListView_GetItem(hwndHotkey, &lvi);
- if (item = (THotkeyItem *)lvi.lParam) {
- item->OptHotkey = wHotkey;
-
- sttOptionsSetupItem(hwndHotkey, lvi.iItem, item);
- sttOptionsSetChanged(item);
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- } } }
- break;
-
- case WM_CONTEXTMENU:
- if (GetWindowLongPtr((HWND)wParam, GWL_ID) == IDC_LV_HOTKEYS) {
- HWND hwndList = (HWND)wParam;
- POINT pt = { (signed short)LOWORD(lParam), (signed short)HIWORD(lParam) };
- LVITEM lvi = {0};
- THotkeyItem *item = NULL;
-
- lvi.iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED);
- if (lvi.iItem < 0) return FALSE;
-
- lvi.mask = LVIF_PARAM;
- ListView_GetItem(hwndList, &lvi);
- if (!(item = (THotkeyItem *)lvi.lParam)) return FALSE;
-
- if ((pt.x == -1) && (pt.y == -1)) {
- RECT rc;
- ListView_GetItemRect(hwndList, lvi.iItem, &rc, LVIR_LABEL);
- pt.x = rc.left;
- pt.y = rc.bottom;
- ClientToScreen(hwndList, &pt);
- }
-
- enum { MI_CANCEL, MI_CHANGE, MI_SYSTEM, MI_LOCAL, MI_ADD, MI_REMOVE, MI_REVERT };
-
- MENUITEMINFO mii = {0};
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STATE;
- mii.fState = MFS_DEFAULT;
-
- HMENU hMenu = CreatePopupMenu();
- AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_CHANGE, TranslateT("Modify"));
- SetMenuItemInfo(hMenu, (UINT_PTR)MI_CHANGE, FALSE, &mii);
- if (item->type != HKT_MANUAL) {
- AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
- AppendMenu(hMenu, MF_STRING|
- ((item->OptType == HKT_GLOBAL) ? MF_CHECKED : 0),
- (UINT_PTR)MI_SYSTEM, TranslateT("System scope"));
- AppendMenu(hMenu, MF_STRING|
- ((item->OptType == HKT_LOCAL) ? MF_CHECKED : 0),
- (UINT_PTR)MI_LOCAL, TranslateT("Miranda scope"));
- }
- AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
- if (!item->rootHotkey)
- AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_ADD, TranslateT("Add binding"));
- else
- AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_REMOVE, TranslateT("Remove"));
- if (item->Hotkey != item->OptHotkey) {
- AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
- AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_REVERT, TranslateT("Undo"));
- }
-
- switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) {
- case MI_CHANGE:
- sttOptionsStartEdit(hwndDlg, hwndHotkey);
- break;
- case MI_SYSTEM:
- item->OptType = HKT_GLOBAL;
- sttOptionsSetupItem(hwndList, lvi.iItem, item);
- sttOptionsSetChanged(item);
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- case MI_LOCAL:
- item->OptType = HKT_LOCAL;
- sttOptionsSetupItem(hwndList, lvi.iItem, item);
- sttOptionsSetChanged(item);
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- break;
- case MI_ADD:
- initialized = FALSE;
- sttOptionsAddHotkey(hwndList, item);
- initialized = FALSE;
- break;
- case MI_REMOVE:
- sttOptionsDeleteHotkey(hwndList, lvi.iItem, item);
- break;
- case MI_REVERT:
- item->OptHotkey = item->Hotkey;
- sttOptionsSetupItem(hwndList, lvi.iItem, item);
- break;
- }
- DestroyMenu(hMenu);
- break;
- }
- break;
-
- case WM_NOTIFY:
- {
- LPNMHDR lpnmhdr = (LPNMHDR)lParam;
- switch (lpnmhdr->idFrom) {
- case 0:
- {
- int i;
-
- if ((lpnmhdr->code != PSN_APPLY) && (lpnmhdr->code != PSN_RESET))
- break;
-
- UnregisterHotkeys();
-
- for (i=0; i < hotkeys.getCount(); i++) {
- THotkeyItem *item = hotkeys[i];
- if (item->OptNew && item->OptDeleted ||
- item->rootHotkey && !item->OptHotkey ||
- (lpnmhdr->code == PSN_APPLY) && item->OptDeleted ||
- (lpnmhdr->code == PSN_RESET) && item->OptNew)
- {
- FreeHotkey(item);
- hotkeys.remove(i--);
- }
- }
-
- if (lpnmhdr->code == PSN_APPLY) {
- LVITEM lvi = {0};
- int count = ListView_GetItemCount(hwndHotkey);
-
- for (i=0; i < hotkeys.getCount(); i++)
- sttOptionsSaveItem(hotkeys[i]);
-
- lvi.mask = LVIF_IMAGE;
- lvi.iSubItem = COL_RESET;
- lvi.iImage = -1;
- for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem)
- ListView_SetItem(hwndHotkey, &lvi);
- }
-
- RegisterHotkeys();
-
- NotifyEventHooks(hEvChanged, 0, 0);
- }
- break;
-
- case IDC_LV_HOTKEYS:
- switch (lpnmhdr->code) {
- case NM_CLICK:
- {
- THotkeyItem *item = NULL;
- LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam;
- LVHITTESTINFO lvhti = {0};
- LVITEM lvi = {0};
-
- lvi.mask = LVIF_PARAM|LVIF_IMAGE;
- lvi.iItem = lpnmia->iItem;
- ListView_GetItem(lpnmia->hdr.hwndFrom, &lvi);
- item = (THotkeyItem *)lvi.lParam;
-
- lvhti.pt = lpnmia->ptAction;
- lvhti.iItem = lpnmia->iItem;
- lvhti.iSubItem = lpnmia->iSubItem;
- ListView_HitTest(lpnmia->hdr.hwndFrom, &lvhti);
-
- if (item &&
- (!item->rootHotkey && (lpnmia->iSubItem == COL_NAME) && ((lvhti.flags & LVHT_ONITEM) == LVHT_ONITEMICON) ||
- item->rootHotkey && (lpnmia->iSubItem == COL_TYPE)) &&
- ((item->OptType == HKT_GLOBAL) || (item->OptType == HKT_LOCAL)))
- {
- item->OptType = (item->OptType == HKT_GLOBAL) ? HKT_LOCAL : HKT_GLOBAL;
- sttOptionsSetupItem(lpnmia->hdr.hwndFrom, lpnmia->iItem, item);
- sttOptionsSetChanged(item);
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- }
- else if (item && (lpnmia->iSubItem == COL_RESET)) {
- item->OptHotkey = item->Hotkey;
- sttOptionsSetupItem(lpnmia->hdr.hwndFrom, lpnmia->iItem, item);
- }
- else if (item && (lpnmia->iSubItem == COL_ADDREMOVE)) {
- if (item->rootHotkey)
- sttOptionsDeleteHotkey(lpnmia->hdr.hwndFrom, lpnmia->iItem, item);
- else {
- initialized = FALSE;
- sttOptionsAddHotkey(lpnmia->hdr.hwndFrom, item);
- initialized = TRUE;
- }
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- }
- }
- break;
-
- case LVN_KEYDOWN:
- {
- LPNMLVKEYDOWN param = (LPNMLVKEYDOWN)lParam;
- if (param->wVKey == VK_SUBTRACT || param->wVKey == VK_LEFT || param->wVKey == VK_ADD || param->wVKey == VK_RIGHT) {
- LVITEM lvi = {0};
- lvi.mask = LVIF_PARAM;
- lvi.iItem = ListView_GetNextItem(lpnmhdr->hwndFrom, -1, LVNI_SELECTED);
- if (lvi.iItem < 0)
- break;
-
- ListView_GetItem(lpnmhdr->hwndFrom, &lvi);
- if (lvi.lParam)
- break;
-
- if (param->wVKey == VK_ADD || param->wVKey == VK_RIGHT) {
- ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, TRUE);
- }
- else {
- ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, FALSE);
- }
- }
- else if (param->wVKey == VK_F2)
- sttOptionsStartEdit(hwndDlg, hwndHotkey);
- }
- break;
-
- case LVN_ITEMACTIVATE:
- {
- LVITEM lvi = {0};
- lvi.mask = LVIF_PARAM;
- lvi.iItem = ListView_GetNextItem(lpnmhdr->hwndFrom, -1, LVNI_SELECTED);
- if (lvi.iItem < 0) break;
- ListView_GetItem(lpnmhdr->hwndFrom, &lvi);
-
- if (lvi.lParam)
- sttOptionsStartEdit(hwndDlg, hwndHotkey);
- else
- ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, !ListView_GetCheckState(lpnmhdr->hwndFrom, lvi.iItem));
- }
- break;
-
- case LVN_ITEMCHANGED:
- {
- LPNMLISTVIEW param = (LPNMLISTVIEW)lParam;
- THotkeyItem *item = (THotkeyItem *)param->lParam;
- if (!initialized || (param->uNewState>>12 == param->uOldState>>12))
- break;
-
- if (item && !item->rootHotkey) {
- item->OptEnabled = ListView_GetCheckState(lpnmhdr->hwndFrom, param->iItem) ? 1 : 0;
- sttOptionsSetChanged(item);
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- }
- else if (!item) {
- TCHAR buf[256];
- LVITEM lvi = {0};
- lvi.mask = LVIF_TEXT;
- lvi.iItem = param->iItem;
- lvi.pszText = buf;
- lvi.cchTextMax = SIZEOF(buf);
- ListView_GetItem(lpnmhdr->hwndFrom, &lvi);
-
- if (param->uNewState>>12 == 1) {
- int count = ListView_GetItemCount(lpnmhdr->hwndFrom);
- LVITEM lvi = {0};
- lvi.mask = LVIF_PARAM;
- for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) {
- THotkeyItem *item;
- ListView_GetItem(lpnmhdr->hwndFrom, &lvi);
- item = (THotkeyItem *)lvi.lParam;
- if (!item) continue;
- if (!lstrcmp( item->getSection(), buf)) {
- ListView_DeleteItem(lpnmhdr->hwndFrom, lvi.iItem);
- --lvi.iItem;
- --count;
- } }
- }
- else if (param->uNewState>>12 == 2) {
- int i, nItems = ListView_GetItemCount(lpnmhdr->hwndFrom);
- initialized = FALSE;
- for (i=0; i < hotkeys.getCount(); i++) {
- LVITEM lvi = {0};
- THotkeyItem *item = hotkeys[i];
-
- if (item->OptDeleted)
- continue;
- if ( lstrcmp(buf, item->getSection()))
- continue;
-
- lvi.mask = LVIF_PARAM|LVIF_INDENT;
- lvi.iIndent = 1;
- lvi.iItem = nItems++;
- lvi.lParam = (LPARAM)item;
- ListView_InsertItem(lpnmhdr->hwndFrom, &lvi);
- sttOptionsSetupItem(lpnmhdr->hwndFrom, nItems-1, item);
- }
- ListView_SortItemsEx(lpnmhdr->hwndFrom, sttOptionsSortList, (LPARAM)lpnmhdr->hwndFrom);
- initialized = TRUE;
- }
- }
- break;
- }
- case NM_CUSTOMDRAW:
- {
- NMLVCUSTOMDRAW *param = (NMLVCUSTOMDRAW *) lParam;
- switch (param->nmcd.dwDrawStage) {
- case CDDS_PREPAINT:
- case CDDS_ITEMPREPAINT:
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW);
- return TRUE;
-
- case CDDS_SUBITEM|CDDS_ITEMPREPAINT:
- {
- THotkeyItem *item;
- TCHAR buf[256];
- LVITEM lvi = {0};
- lvi.mask = LVIF_TEXT|LVIF_PARAM;
- lvi.iItem = param->nmcd.dwItemSpec;
- lvi.pszText = buf;
- lvi.cchTextMax = SIZEOF(buf);
- ListView_GetItem(lpnmhdr->hwndFrom, &lvi);
-
- item = (THotkeyItem *)lvi.lParam;
- if (!item) {
- RECT rc;
- HFONT hfnt;
-
- ListView_GetSubItemRect(lpnmhdr->hwndFrom, param->nmcd.dwItemSpec, param->iSubItem, LVIR_BOUNDS, &rc);
- FillRect(param->nmcd.hdc, &rc, GetSysColorBrush(param->nmcd.uItemState&CDIS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW));
- SetTextColor(param->nmcd.hdc, GetSysColor(param->nmcd.uItemState&CDIS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
-
- if (param->iSubItem == 0) {
- rc.left += 3;
- HIMAGELIST hIml = ListView_GetImageList(hwndHotkey, LVSIL_SMALL);
- ImageList_Draw(hIml,
- ListView_GetCheckState(hwndHotkey, lvi.iItem) ? 6 : 7,
- param->nmcd.hdc, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT);
- rc.left += 18;
- hfnt = (HFONT)SelectObject(param->nmcd.hdc, (HFONT)SendMessage(GetParent(hwndDlg), PSM_GETBOLDFONT, 0, 0));
- DrawText(param->nmcd.hdc, buf, -1, &rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER);
- SelectObject(param->nmcd.hdc, hfnt);
- }
-
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT);
- return TRUE;
- }
-
- if (item->rootHotkey && (param->iSubItem == 0)) {
- RECT rc;
- ListView_GetSubItemRect(lpnmhdr->hwndFrom, param->nmcd.dwItemSpec, param->iSubItem, LVIR_BOUNDS, &rc);
- FillRect(param->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
- SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT);
- return TRUE;
- }
- break;
- }
- }
- break;
- }
- break;
- }
- }
- }
- break;
-
- case WM_DESTROY:
- {
- int count = ListView_GetItemCount(hwndHotkey);
-
- g_hwndHkOptions = NULL;
-
- KillTimer(hwndDlg, 1024);
-
- TCHAR buf[128];
- LVITEM lvi = {0};
- lvi.pszText = buf;
- lvi.cchTextMax = SIZEOF(buf);
- for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) {
- lvi.mask = LVIF_PARAM;
- lvi.iSubItem = 0;
- ListView_GetItem(hwndHotkey, &lvi);
- if (lvi.lParam) continue;
-
- lvi.mask = LVIF_TEXT;
- lvi.iSubItem = 1;
- ListView_GetItem(hwndHotkey, &lvi);
-
- db_set_b(NULL, DBMODULENAME "UI", _T2A(lvi.pszText), ListView_GetCheckState(hwndHotkey, lvi.iItem));
- }
- }
- }
-
- return FALSE;
-}
-
-int HotkeyOptionsInit(WPARAM wParam, LPARAM)
-{
- OPTIONSDIALOGPAGE odp = { sizeof(odp) };
- odp.hInstance = hInst;
- odp.flags = ODPF_BOLDGROUPS;
- odp.position = -180000000;
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_HOTKEYS);
- odp.pszTitle = LPGEN("Hotkeys");
- odp.pszGroup = LPGEN("Customize");
- odp.pfnDlgProc = sttOptionsDlgProc;
- Options_AddPage(wParam, &odp);
- return 0;
-}
+/* + +Miranda NG: the free IM client for Microsoft* Windows* + +Copyright (c) 2012-14 Miranda NG project (http://miranda-ng.org), +Copyright (c) 2000-12 Miranda IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +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 "..\..\core\commonheaders.h" + +#include <m_hotkeys.h> +#include "skin.h" + +static TCHAR *sttHokeyVkToName(WORD vkKey) +{ + static TCHAR buf[256] = {0}; + DWORD code = MapVirtualKey(vkKey, 0) << 16; + + switch (vkKey) + { + case 0: + case VK_CONTROL: + case VK_SHIFT: + case VK_MENU: + case VK_LWIN: + case VK_RWIN: + case VK_PAUSE: + case VK_CANCEL: + case VK_NUMLOCK: + case VK_CAPITAL: + case VK_SCROLL: + return _T(""); + + case VK_DIVIDE: + case VK_INSERT: + case VK_HOME: + case VK_PRIOR: + case VK_DELETE: + case VK_END: + case VK_NEXT: + case VK_LEFT: + case VK_RIGHT: + case VK_UP: + case VK_DOWN: + code |= (1UL << 24); + } + + GetKeyNameText(code, buf, 256); + return buf; +} + +void HotkeyToName(TCHAR *buf, int size, BYTE shift, BYTE key) +{ + mir_sntprintf(buf, size, _T("%s%s%s%s%s"), + (shift & HOTKEYF_CONTROL) ? TranslateT("Ctrl + ") : _T(""), + (shift & HOTKEYF_ALT) ? TranslateT("Alt + ") : _T(""), + (shift & HOTKEYF_SHIFT) ? TranslateT("Shift + ") : _T(""), + (shift & HOTKEYF_EXT) ? TranslateT("Win + ") : _T(""), + sttHokeyVkToName(key)); +} + +/////////////////////////////////////////////////////////////////////////////// +// Hotkey control + +static LRESULT CALLBACK sttHotkeyEditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + THotkeyBoxData *data = (THotkeyBoxData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + BOOL bKeyDown = FALSE; + if (!data) return 0; + + switch (msg) { + case HKM_GETHOTKEY: + return data->key ? MAKEWORD(data->key, data->shift) : 0; + + case HKM_SETHOTKEY: + { + TCHAR buf[256] = {0}; + data->key = (BYTE)LOWORD(wParam); + data->shift = (BYTE)HIWORD(wParam); + HotkeyToName(buf, SIZEOF(buf), data->shift, data->key); + SetWindowText(hwnd, buf); + } + return 0; + + case WM_GETDLGCODE: + return DLGC_WANTALLKEYS; + + case WM_KILLFOCUS: + break; + + case WM_CHAR: + case WM_SYSCHAR: + case WM_PASTE: + case WM_CONTEXTMENU: + return TRUE; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + bKeyDown = TRUE; + + case WM_KEYUP: + case WM_SYSKEYUP: + { + TCHAR buf[256] = {0}; + + BYTE shift = 0; + BYTE key = wParam; + TCHAR *name = sttHokeyVkToName(key); + if (!*name || !bKeyDown) + key = 0; + + if (GetAsyncKeyState(VK_CONTROL)) shift |= HOTKEYF_CONTROL; + if (GetAsyncKeyState(VK_MENU)) shift |= HOTKEYF_ALT; + if (GetAsyncKeyState(VK_SHIFT)) shift |= HOTKEYF_SHIFT; + if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN)) shift |= HOTKEYF_EXT; + + if (bKeyDown || !data->key) { + data->shift = shift; + data->key = key; + } + + HotkeyToName(buf, SIZEOF(buf), data->shift, data->key); + SetWindowText(hwnd, buf); + + if (bKeyDown && data->key) + SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(GetWindowLongPtr(hwnd, GWL_ID), 0), (LPARAM)hwnd); + } + return TRUE; + + case WM_DESTROY: + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + mir_free(data); + } + + return mir_callNextSubclass(hwnd, sttHotkeyEditProc, msg, wParam, lParam); +} + +void HotkeyEditCreate(HWND hwnd) +{ + THotkeyBoxData *data = (THotkeyBoxData *)mir_alloc(sizeof(THotkeyBoxData)); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (ULONG_PTR)data); + mir_subclassWindow(hwnd, sttHotkeyEditProc); +} + +void HotkeyEditDestroy(HWND hwnd) +{ + THotkeyBoxData *data = (THotkeyBoxData *)GetWindowLongPtr(hwnd, GWLP_USERDATA); + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + mir_free(data); +} + +/////////////////////////////////////////////////////////////////////////////// +// Options + +enum { COL_NAME, COL_TYPE, COL_KEY, COL_RESET, COL_ADDREMOVE }; + +static void sttOptionsSetupItem(HWND hwndList, int idx, THotkeyItem *item) +{ + TCHAR buf[256]; + LVITEM lvi = {0}; + lvi.iItem = idx; + + if (!item->rootHotkey) { + lvi.mask = LVIF_TEXT|LVIF_IMAGE; + lvi.iSubItem = COL_NAME; + lvi.pszText = item->getDescr(); + lvi.iImage = item->OptType; + ListView_SetItem(hwndList, &lvi); + + ListView_SetCheckState(hwndList, lvi.iItem, item->Enabled); + } + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = COL_KEY; + HotkeyToName(buf, SIZEOF(buf), HIBYTE(item->OptHotkey), LOBYTE(item->OptHotkey)); + lvi.pszText = buf; + ListView_SetItem(hwndList, &lvi); + + if (item->rootHotkey) { + lvi.mask = LVIF_IMAGE; + lvi.iSubItem = COL_TYPE; + lvi.iImage = item->OptType; + ListView_SetItem(hwndList, &lvi); + } + + lvi.mask = LVIF_IMAGE; + lvi.iSubItem = COL_RESET; + lvi.iImage = (item->Hotkey != item->OptHotkey) ? 5 : -1; + ListView_SetItem(hwndList, &lvi); + + lvi.mask = LVIF_IMAGE|LVIF_TEXT; + lvi.iSubItem = COL_ADDREMOVE; + if (item->rootHotkey) { + lvi.iImage = 4; + lvi.pszText = TranslateT("Remove shortcut"); + } + else { + lvi.iImage = 3; + lvi.pszText = TranslateT("Add another shortcut"); + } + ListView_SetItem(hwndList, &lvi); +} + +static void sttOptionsDeleteHotkey(HWND hwndList, int idx, THotkeyItem *item) +{ + item->OptDeleted = TRUE; + ListView_DeleteItem(hwndList, idx); + if (item->rootHotkey) + item->rootHotkey->OptChanged = TRUE; +} + +static int CALLBACK sttOptionsSortList(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + TCHAR title1[256] = {0}, title2[256] = {0}; + THotkeyItem *item1 = NULL, *item2 = NULL; + LVITEM lvi = {0}; + int res; + + lvi.mask = LVIF_TEXT|LVIF_PARAM; + lvi.iItem = lParam1; + lvi.pszText = title1; + lvi.cchTextMax = SIZEOF(title1); + if (ListView_GetItem((HWND)lParamSort, &lvi)) + item1 = (THotkeyItem *)lvi.lParam; + + lvi.mask = LVIF_TEXT|LVIF_PARAM; + lvi.iItem = lParam2; + lvi.pszText = title2; + lvi.cchTextMax = SIZEOF(title2); + if (ListView_GetItem((HWND)lParamSort, &lvi)) + item2 = (THotkeyItem *)lvi.lParam; + + if (!item1 && !item2) + return lstrcmp(title1, title2); + + if (!item1 && item2) { + if (res = lstrcmp(title1, item2->getSection())) + return res; + return -1; + } + + if (!item2 && item1) { + if (res = lstrcmp(item1->getSection(), title2)) + return res; + return 1; + } + /* item1 != NULL && item2 != NULL */ + + if (res = lstrcmp(item1->getSection(), item2->getSection())) return res; + if (res = lstrcmp(item1->getDescr(), item2->getDescr())) return res; + if (!item1->rootHotkey && item2->rootHotkey) return -1; + if (item1->rootHotkey && !item2->rootHotkey) return 1; + return 0; +} + +static void sttOptionsAddHotkey(HWND hwndList, THotkeyItem *item) +{ + char buf[256]; + mir_snprintf(buf, SIZEOF(buf), "mir_hotkey_%d_%d", g_pid, g_hkid++); + + THotkeyItem *newItem = (THotkeyItem *)mir_alloc(sizeof(THotkeyItem)); + newItem->pszName = NULL; + newItem->pszService = item->pszService ? mir_strdup(item->pszService) : NULL; + newItem->ptszSection = mir_tstrdup(item->ptszSection); + newItem->ptszDescription = mir_tstrdup(item->ptszDescription); + newItem->lParam = item->lParam; + newItem->idHotkey = GlobalAddAtomA(buf); + newItem->rootHotkey = item; + newItem->Hotkey = newItem->DefHotkey = newItem->OptHotkey = 0; + newItem->type = newItem->OptType = item->OptType; + newItem->Enabled = newItem->OptEnabled = TRUE; + newItem->OptChanged = newItem->OptDeleted = FALSE; + newItem->OptNew = TRUE; + hotkeys.insert(newItem); + + SendMessage(hwndList, WM_SETREDRAW, FALSE, 0); + + LVITEM lvi = {0}; + lvi.mask |= LVIF_PARAM; + lvi.lParam = (LPARAM)newItem; + sttOptionsSetupItem(hwndList, ListView_InsertItem(hwndList, &lvi), newItem); + ListView_SortItemsEx(hwndList, sttOptionsSortList, (LPARAM)hwndList); + + SendMessage(hwndList, WM_SETREDRAW, TRUE, 0); + RedrawWindow(hwndList, NULL, NULL, RDW_INVALIDATE); + + item->OptChanged = TRUE; +} + +static void sttOptionsSetChanged(THotkeyItem *item) +{ + item->OptChanged = TRUE; + if (item->rootHotkey) + item->rootHotkey->OptChanged = TRUE; +} + +static void sttOptionsSaveItem(THotkeyItem *item) +{ + int i; + char buf[MAXMODULELABELLENGTH]; + + if (item->rootHotkey) return; + if (!item->OptChanged) return; + + item->Hotkey = item->OptHotkey; + item->type = item->OptType; + item->Enabled = item->OptEnabled; + + db_set_w(NULL, DBMODULENAME, item->pszName, item->Hotkey); + db_set_b(NULL, DBMODULENAME "Off", item->pszName, (BYTE)!item->Enabled); + if (item->type != HKT_MANUAL) + db_set_b(NULL, DBMODULENAME "Types", item->pszName, (BYTE)item->type); + + item->nSubHotkeys = 0; + for (i=0; i < hotkeys.getCount(); i++) { + THotkeyItem *subItem = hotkeys[i]; + if (subItem->rootHotkey == item) { + subItem->Hotkey = subItem->OptHotkey; + subItem->type = subItem->OptType; + + mir_snprintf(buf, SIZEOF(buf), "%s$%d", item->pszName, item->nSubHotkeys); + db_set_w(NULL, DBMODULENAME, buf, subItem->Hotkey); + if (subItem->type != HKT_MANUAL) + db_set_b(NULL, DBMODULENAME "Types", buf, (BYTE)subItem->type); + + ++item->nSubHotkeys; + } } + + mir_snprintf(buf, SIZEOF(buf), "%s$count", item->pszName); + db_set_dw(NULL, DBMODULENAME, buf, item->nSubHotkeys); +} + +static void sttBuildHotkeyList(HWND hwndList) +{ + int i, nItems = 0; + ListView_DeleteAllItems(hwndList); + + for (i=0; i < hotkeys.getCount(); i++) { + LVITEM lvi = {0}; + THotkeyItem *item = hotkeys[i]; + + if (item->OptDeleted) + continue; + + if (!i || lstrcmp(item->ptszSection, hotkeys[i-1]->ptszSection)) { + lvi.mask = LVIF_TEXT|LVIF_PARAM; + lvi.iItem = nItems++; + lvi.iSubItem = 0; + lvi.lParam = 0; + lvi.pszText = item->getSection(); + ListView_InsertItem(hwndList, &lvi); + ListView_SetCheckState(hwndList, lvi.iItem, TRUE); + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 1; + lvi.pszText = item->ptszSection; + ListView_SetItem(hwndList, &lvi); + + lvi.iSubItem = 0; + } + + lvi.mask = LVIF_PARAM | LVIF_INDENT; + lvi.iIndent = 1; + lvi.iItem = nItems++; + lvi.lParam = (LPARAM)item; + ListView_InsertItem(hwndList, &lvi); + sttOptionsSetupItem(hwndList, nItems-1, item); + } + + ListView_SortItemsEx(hwndList, sttOptionsSortList, (LPARAM)hwndList); +} + +static void sttOptionsStartEdit(HWND hwndDlg, HWND hwndHotkey) +{ + LVITEM lvi; + THotkeyItem *item; + int iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED); + if (iItem < 0) return; + + lvi.mask = LVIF_PARAM; + lvi.iItem = iItem; + ListView_GetItem(hwndHotkey, &lvi); + + if (item = (THotkeyItem *)lvi.lParam) { + RECT rc; + ListView_GetSubItemRect(hwndHotkey, iItem, COL_KEY, LVIR_BOUNDS, &rc); + MapWindowPoints(hwndHotkey, hwndDlg, (LPPOINT)&rc, 2); + SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_SETHOTKEY, MAKELONG(LOBYTE(item->OptHotkey), HIBYTE(item->OptHotkey)), 0); + + SetWindowPos(hwndHotkey, HWND_BOTTOM, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE); + SetWindowPos( GetDlgItem(hwndDlg, IDC_HOTKEY), HWND_TOP, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, SWP_SHOWWINDOW); + RedrawWindow( GetDlgItem(hwndDlg, IDC_HOTKEY), NULL, NULL, RDW_INVALIDATE); + + SetFocus( GetDlgItem(hwndDlg, IDC_HOTKEY)); + RedrawWindow( GetDlgItem(hwndDlg, IDC_HOTKEY), NULL, NULL, RDW_INVALIDATE); + } +} + +static void sttOptionsDrawTextChunk(HDC hdc, TCHAR *text, RECT *rc) +{ + SIZE sz; + DrawText(hdc, text, lstrlen(text), rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER|DT_WORD_ELLIPSIS); + GetTextExtentPoint32(hdc, text, lstrlen(text), &sz); + rc->left += sz.cx; +} + +static INT_PTR CALLBACK sttOptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL initialized = FALSE; + static int colWidth = 0; + static WORD currentLanguage = 0; + + HWND hwndHotkey = GetDlgItem(hwndDlg, IDC_LV_HOTKEYS); + + switch (msg) { + case WM_INITDIALOG: + initialized = FALSE; + + TranslateDialogDefault(hwndDlg); + + HotkeyEditCreate( GetDlgItem(hwndDlg, IDC_HOTKEY)); + { + HIMAGELIST hIml = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 3, 1); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_WINDOWS); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_MIRANDA); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_WINDOW); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_ADDCONTACT); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_DELETE); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_UNDO); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_GROUPOPEN); + ImageList_AddIcon_IconLibLoaded(hIml, SKINICON_OTHER_GROUPSHUT); + ListView_SetImageList(hwndHotkey, hIml, LVSIL_SMALL); + } + ListView_SetExtendedListViewStyle(hwndHotkey, LVS_EX_CHECKBOXES|LVS_EX_SUBITEMIMAGES|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER|LVS_EX_INFOTIP); + { + RECT rc; + GetClientRect(hwndHotkey, &rc); + colWidth = rc.right - GetSystemMetrics(SM_CXHTHUMB) - 3*GetSystemMetrics(SM_CXSMICON) - 5; + + LVCOLUMN lvc; + lvc.mask = LVCF_WIDTH; + lvc.cx = colWidth * 2 / 3; + ListView_InsertColumn(hwndHotkey, COL_NAME, &lvc); + lvc.cx = GetSystemMetrics(SM_CXSMICON); + ListView_InsertColumn(hwndHotkey, COL_TYPE, &lvc); + lvc.cx = colWidth / 3; + ListView_InsertColumn(hwndHotkey, COL_KEY, &lvc); + lvc.cx = GetSystemMetrics(SM_CXSMICON); + ListView_InsertColumn(hwndHotkey, COL_RESET, &lvc); + lvc.cx = GetSystemMetrics(SM_CXSMICON); + ListView_InsertColumn(hwndHotkey, COL_ADDREMOVE, &lvc); + + for (int i=0; i < hotkeys.getCount(); i++) { + THotkeyItem *item = hotkeys[i]; + + item->OptChanged = FALSE; + item->OptDeleted = item->OptNew = FALSE; + item->OptEnabled = item->Enabled; + item->OptHotkey = item->Hotkey; + item->OptType = item->type; + } + + currentLanguage = LOWORD(GetKeyboardLayout(0)); + sttBuildHotkeyList(hwndHotkey); + } + SetTimer(hwndDlg, 1024, 1000, NULL); + initialized = TRUE; + { + /* load group states */ + int count = ListView_GetItemCount(hwndHotkey); + TCHAR buf[128]; + LVITEM lvi = {0}; + lvi.pszText = buf; + lvi.cchTextMax = SIZEOF(buf); + for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { + char *szSetting; + + lvi.mask = LVIF_PARAM; + lvi.iSubItem = 0; + ListView_GetItem(hwndHotkey, &lvi); + if (lvi.lParam) continue; + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 1; + ListView_GetItem(hwndHotkey, &lvi); + + szSetting = mir_t2a(lvi.pszText); + + ListView_SetCheckState(hwndHotkey, lvi.iItem, + db_get_b(NULL, DBMODULENAME "UI", szSetting, TRUE)); + + mir_free(szSetting); + } + } + + g_hwndHkOptions = hwndDlg; + break; + + case WM_TIMER: + if (initialized) { + WORD newLanguage = LOWORD(GetKeyboardLayout(0)); + if (newLanguage == currentLanguage) + break; + + int count = ListView_GetItemCount(hwndHotkey); + + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { + ListView_GetItem(hwndHotkey, &lvi); + if (lvi.lParam) + sttOptionsSetupItem(hwndHotkey, lvi.iItem, (THotkeyItem *)lvi.lParam); + } + currentLanguage = newLanguage; + } + break; + + case WM_HOTKEYUNREGISTERED: + { + int count = ListView_GetItemCount(hwndHotkey); + + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { + ListView_GetItem(hwndHotkey, &lvi); + if (!lvi.lParam) continue; + + if (((THotkeyItem *)lvi.lParam)->UnregisterHotkey) { + ListView_DeleteItem(hwndHotkey, lvi.iItem); + --lvi.iItem; + --count; + } + } + } + break; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam; + RECT rc = lpdis->rcItem; + int prefix = 65; + int width = (lpdis->rcItem.right - lpdis->rcItem.left - prefix) / 3; + rc.left += 5; + + HIMAGELIST hIml = ListView_GetImageList(hwndHotkey, LVSIL_SMALL); + + if (lpdis->CtlID == IDC_CANVAS2) { + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Scope:"), &rc); + + rc.left = prefix + width * 0; + ImageList_Draw(hIml, 0, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT); + rc.left += 20; + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("System"), &rc); + + rc.left = prefix + width * 1; + ImageList_Draw(hIml, 1, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT); + rc.left += 20; + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Miranda"), &rc); + + rc.left = prefix + width * 2; + ImageList_Draw(hIml, 2, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT); + rc.left += 20; + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Window"), &rc); + return TRUE; + } + + if (lpdis->CtlID == IDC_CANVAS) { + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Actions:"), &rc); + rc.left += 10; + + rc.left = prefix + width * 0; + ImageList_Draw(hIml, 5, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT); + rc.left += 20; + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Undo"), &rc); + + rc.left = prefix + width * 1; + ImageList_Draw(hIml, 3, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT); + rc.left += 20; + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Add binding"), &rc); + + rc.left = prefix + width * 2; + ImageList_Draw(hIml, 4, lpdis->hDC, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT); + rc.left += 20; + sttOptionsDrawTextChunk(lpdis->hDC, TranslateT("Remove"), &rc); + return TRUE; + } + } + break; + + case WM_COMMAND: + if ((LOWORD(wParam) == IDC_HOTKEY) && ((HIWORD(wParam) == EN_KILLFOCUS) || (HIWORD(wParam) == 0))) { + LVITEM lvi; + THotkeyItem *item; + WORD wHotkey = (WORD)SendDlgItemMessage(hwndDlg, IDC_HOTKEY, HKM_GETHOTKEY, 0, 0); + + ShowWindow( GetDlgItem(hwndDlg, IDC_HOTKEY), SW_HIDE); + SetFocus(hwndHotkey); + if (!wHotkey || (wHotkey == VK_ESCAPE) || (HIWORD(wParam) != 0)) + break; + + lvi.mask = LVIF_PARAM; + lvi.iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED); + if (lvi.iItem >= 0) { + ListView_GetItem(hwndHotkey, &lvi); + if (item = (THotkeyItem *)lvi.lParam) { + item->OptHotkey = wHotkey; + + sttOptionsSetupItem(hwndHotkey, lvi.iItem, item); + sttOptionsSetChanged(item); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } } } + break; + + case WM_CONTEXTMENU: + if (GetWindowLongPtr((HWND)wParam, GWL_ID) == IDC_LV_HOTKEYS) { + HWND hwndList = (HWND)wParam; + POINT pt = { (signed short)LOWORD(lParam), (signed short)HIWORD(lParam) }; + LVITEM lvi = {0}; + THotkeyItem *item = NULL; + + lvi.iItem = ListView_GetNextItem(hwndHotkey, -1, LVNI_SELECTED); + if (lvi.iItem < 0) return FALSE; + + lvi.mask = LVIF_PARAM; + ListView_GetItem(hwndList, &lvi); + if (!(item = (THotkeyItem *)lvi.lParam)) return FALSE; + + if ((pt.x == -1) && (pt.y == -1)) { + RECT rc; + ListView_GetItemRect(hwndList, lvi.iItem, &rc, LVIR_LABEL); + pt.x = rc.left; + pt.y = rc.bottom; + ClientToScreen(hwndList, &pt); + } + + enum { MI_CANCEL, MI_CHANGE, MI_SYSTEM, MI_LOCAL, MI_ADD, MI_REMOVE, MI_REVERT }; + + MENUITEMINFO mii = {0}; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STATE; + mii.fState = MFS_DEFAULT; + + HMENU hMenu = CreatePopupMenu(); + AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_CHANGE, TranslateT("Modify")); + SetMenuItemInfo(hMenu, (UINT_PTR)MI_CHANGE, FALSE, &mii); + if (item->type != HKT_MANUAL) { + AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); + AppendMenu(hMenu, MF_STRING| + ((item->OptType == HKT_GLOBAL) ? MF_CHECKED : 0), + (UINT_PTR)MI_SYSTEM, TranslateT("System scope")); + AppendMenu(hMenu, MF_STRING| + ((item->OptType == HKT_LOCAL) ? MF_CHECKED : 0), + (UINT_PTR)MI_LOCAL, TranslateT("Miranda scope")); + } + AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); + if (!item->rootHotkey) + AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_ADD, TranslateT("Add binding")); + else + AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_REMOVE, TranslateT("Remove")); + if (item->Hotkey != item->OptHotkey) { + AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); + AppendMenu(hMenu, MF_STRING, (UINT_PTR)MI_REVERT, TranslateT("Undo")); + } + + switch (TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) { + case MI_CHANGE: + sttOptionsStartEdit(hwndDlg, hwndHotkey); + break; + case MI_SYSTEM: + item->OptType = HKT_GLOBAL; + sttOptionsSetupItem(hwndList, lvi.iItem, item); + sttOptionsSetChanged(item); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case MI_LOCAL: + item->OptType = HKT_LOCAL; + sttOptionsSetupItem(hwndList, lvi.iItem, item); + sttOptionsSetChanged(item); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + case MI_ADD: + initialized = FALSE; + sttOptionsAddHotkey(hwndList, item); + initialized = FALSE; + break; + case MI_REMOVE: + sttOptionsDeleteHotkey(hwndList, lvi.iItem, item); + break; + case MI_REVERT: + item->OptHotkey = item->Hotkey; + sttOptionsSetupItem(hwndList, lvi.iItem, item); + break; + } + DestroyMenu(hMenu); + break; + } + break; + + case WM_NOTIFY: + { + LPNMHDR lpnmhdr = (LPNMHDR)lParam; + switch (lpnmhdr->idFrom) { + case 0: + { + int i; + + if ((lpnmhdr->code != PSN_APPLY) && (lpnmhdr->code != PSN_RESET)) + break; + + UnregisterHotkeys(); + + for (i=0; i < hotkeys.getCount(); i++) { + THotkeyItem *item = hotkeys[i]; + if (item->OptNew && item->OptDeleted || + item->rootHotkey && !item->OptHotkey || + (lpnmhdr->code == PSN_APPLY) && item->OptDeleted || + (lpnmhdr->code == PSN_RESET) && item->OptNew) + { + FreeHotkey(item); + hotkeys.remove(i--); + } + } + + if (lpnmhdr->code == PSN_APPLY) { + LVITEM lvi = {0}; + int count = ListView_GetItemCount(hwndHotkey); + + for (i=0; i < hotkeys.getCount(); i++) + sttOptionsSaveItem(hotkeys[i]); + + lvi.mask = LVIF_IMAGE; + lvi.iSubItem = COL_RESET; + lvi.iImage = -1; + for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) + ListView_SetItem(hwndHotkey, &lvi); + } + + RegisterHotkeys(); + + NotifyEventHooks(hEvChanged, 0, 0); + } + break; + + case IDC_LV_HOTKEYS: + switch (lpnmhdr->code) { + case NM_CLICK: + { + THotkeyItem *item = NULL; + LPNMITEMACTIVATE lpnmia = (LPNMITEMACTIVATE)lParam; + LVHITTESTINFO lvhti = {0}; + LVITEM lvi = {0}; + + lvi.mask = LVIF_PARAM|LVIF_IMAGE; + lvi.iItem = lpnmia->iItem; + ListView_GetItem(lpnmia->hdr.hwndFrom, &lvi); + item = (THotkeyItem *)lvi.lParam; + + lvhti.pt = lpnmia->ptAction; + lvhti.iItem = lpnmia->iItem; + lvhti.iSubItem = lpnmia->iSubItem; + ListView_HitTest(lpnmia->hdr.hwndFrom, &lvhti); + + if (item && + (!item->rootHotkey && (lpnmia->iSubItem == COL_NAME) && ((lvhti.flags & LVHT_ONITEM) == LVHT_ONITEMICON) || + item->rootHotkey && (lpnmia->iSubItem == COL_TYPE)) && + ((item->OptType == HKT_GLOBAL) || (item->OptType == HKT_LOCAL))) + { + item->OptType = (item->OptType == HKT_GLOBAL) ? HKT_LOCAL : HKT_GLOBAL; + sttOptionsSetupItem(lpnmia->hdr.hwndFrom, lpnmia->iItem, item); + sttOptionsSetChanged(item); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + else if (item && (lpnmia->iSubItem == COL_RESET)) { + item->OptHotkey = item->Hotkey; + sttOptionsSetupItem(lpnmia->hdr.hwndFrom, lpnmia->iItem, item); + } + else if (item && (lpnmia->iSubItem == COL_ADDREMOVE)) { + if (item->rootHotkey) + sttOptionsDeleteHotkey(lpnmia->hdr.hwndFrom, lpnmia->iItem, item); + else { + initialized = FALSE; + sttOptionsAddHotkey(lpnmia->hdr.hwndFrom, item); + initialized = TRUE; + } + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + break; + + case LVN_KEYDOWN: + { + LPNMLVKEYDOWN param = (LPNMLVKEYDOWN)lParam; + if (param->wVKey == VK_SUBTRACT || param->wVKey == VK_LEFT || param->wVKey == VK_ADD || param->wVKey == VK_RIGHT) { + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + lvi.iItem = ListView_GetNextItem(lpnmhdr->hwndFrom, -1, LVNI_SELECTED); + if (lvi.iItem < 0) + break; + + ListView_GetItem(lpnmhdr->hwndFrom, &lvi); + if (lvi.lParam) + break; + + if (param->wVKey == VK_ADD || param->wVKey == VK_RIGHT) { + ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, TRUE); + } + else { + ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, FALSE); + } + } + else if (param->wVKey == VK_F2) + sttOptionsStartEdit(hwndDlg, hwndHotkey); + } + break; + + case LVN_ITEMACTIVATE: + { + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + lvi.iItem = ListView_GetNextItem(lpnmhdr->hwndFrom, -1, LVNI_SELECTED); + if (lvi.iItem < 0) break; + ListView_GetItem(lpnmhdr->hwndFrom, &lvi); + + if (lvi.lParam) + sttOptionsStartEdit(hwndDlg, hwndHotkey); + else + ListView_SetCheckState(lpnmhdr->hwndFrom, lvi.iItem, !ListView_GetCheckState(lpnmhdr->hwndFrom, lvi.iItem)); + } + break; + + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW param = (LPNMLISTVIEW)lParam; + THotkeyItem *item = (THotkeyItem *)param->lParam; + if (!initialized || (param->uNewState>>12 == param->uOldState>>12)) + break; + + if (item && !item->rootHotkey) { + item->OptEnabled = ListView_GetCheckState(lpnmhdr->hwndFrom, param->iItem) ? 1 : 0; + sttOptionsSetChanged(item); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + else if (!item) { + TCHAR buf[256]; + LVITEM lvi = {0}; + lvi.mask = LVIF_TEXT; + lvi.iItem = param->iItem; + lvi.pszText = buf; + lvi.cchTextMax = SIZEOF(buf); + ListView_GetItem(lpnmhdr->hwndFrom, &lvi); + + if (param->uNewState>>12 == 1) { + int count = ListView_GetItemCount(lpnmhdr->hwndFrom); + LVITEM lvi = {0}; + lvi.mask = LVIF_PARAM; + for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { + THotkeyItem *item; + ListView_GetItem(lpnmhdr->hwndFrom, &lvi); + item = (THotkeyItem *)lvi.lParam; + if (!item) continue; + if (!lstrcmp( item->getSection(), buf)) { + ListView_DeleteItem(lpnmhdr->hwndFrom, lvi.iItem); + --lvi.iItem; + --count; + } } + } + else if (param->uNewState>>12 == 2) { + int i, nItems = ListView_GetItemCount(lpnmhdr->hwndFrom); + initialized = FALSE; + for (i=0; i < hotkeys.getCount(); i++) { + LVITEM lvi = {0}; + THotkeyItem *item = hotkeys[i]; + + if (item->OptDeleted) + continue; + if ( lstrcmp(buf, item->getSection())) + continue; + + lvi.mask = LVIF_PARAM|LVIF_INDENT; + lvi.iIndent = 1; + lvi.iItem = nItems++; + lvi.lParam = (LPARAM)item; + ListView_InsertItem(lpnmhdr->hwndFrom, &lvi); + sttOptionsSetupItem(lpnmhdr->hwndFrom, nItems-1, item); + } + ListView_SortItemsEx(lpnmhdr->hwndFrom, sttOptionsSortList, (LPARAM)lpnmhdr->hwndFrom); + initialized = TRUE; + } + } + break; + } + case NM_CUSTOMDRAW: + { + NMLVCUSTOMDRAW *param = (NMLVCUSTOMDRAW *) lParam; + switch (param->nmcd.dwDrawStage) { + case CDDS_PREPAINT: + case CDDS_ITEMPREPAINT: + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW); + return TRUE; + + case CDDS_SUBITEM|CDDS_ITEMPREPAINT: + { + THotkeyItem *item; + TCHAR buf[256]; + LVITEM lvi = {0}; + lvi.mask = LVIF_TEXT|LVIF_PARAM; + lvi.iItem = param->nmcd.dwItemSpec; + lvi.pszText = buf; + lvi.cchTextMax = SIZEOF(buf); + ListView_GetItem(lpnmhdr->hwndFrom, &lvi); + + item = (THotkeyItem *)lvi.lParam; + if (!item) { + RECT rc; + HFONT hfnt; + + ListView_GetSubItemRect(lpnmhdr->hwndFrom, param->nmcd.dwItemSpec, param->iSubItem, LVIR_BOUNDS, &rc); + FillRect(param->nmcd.hdc, &rc, GetSysColorBrush(param->nmcd.uItemState&CDIS_SELECTED ? COLOR_HIGHLIGHT : COLOR_WINDOW)); + SetTextColor(param->nmcd.hdc, GetSysColor(param->nmcd.uItemState&CDIS_SELECTED ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT)); + + if (param->iSubItem == 0) { + rc.left += 3; + HIMAGELIST hIml = ListView_GetImageList(hwndHotkey, LVSIL_SMALL); + ImageList_Draw(hIml, + ListView_GetCheckState(hwndHotkey, lvi.iItem) ? 6 : 7, + param->nmcd.hdc, rc.left, (rc.top+rc.bottom-16)/2, ILD_TRANSPARENT); + rc.left += 18; + hfnt = (HFONT)SelectObject(param->nmcd.hdc, (HFONT)SendMessage(GetParent(hwndDlg), PSM_GETBOLDFONT, 0, 0)); + DrawText(param->nmcd.hdc, buf, -1, &rc, DT_LEFT|DT_NOPREFIX|DT_SINGLELINE|DT_VCENTER); + SelectObject(param->nmcd.hdc, hfnt); + } + + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); + return TRUE; + } + + if (item->rootHotkey && (param->iSubItem == 0)) { + RECT rc; + ListView_GetSubItemRect(lpnmhdr->hwndFrom, param->nmcd.dwItemSpec, param->iSubItem, LVIR_BOUNDS, &rc); + FillRect(param->nmcd.hdc, &rc, GetSysColorBrush(COLOR_WINDOW)); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, CDRF_SKIPDEFAULT); + return TRUE; + } + break; + } + } + break; + } + break; + } + } + } + break; + + case WM_DESTROY: + { + int count = ListView_GetItemCount(hwndHotkey); + + g_hwndHkOptions = NULL; + + KillTimer(hwndDlg, 1024); + + TCHAR buf[128]; + LVITEM lvi = {0}; + lvi.pszText = buf; + lvi.cchTextMax = SIZEOF(buf); + for (lvi.iItem = 0; lvi.iItem < count; ++lvi.iItem) { + lvi.mask = LVIF_PARAM; + lvi.iSubItem = 0; + ListView_GetItem(hwndHotkey, &lvi); + if (lvi.lParam) continue; + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 1; + ListView_GetItem(hwndHotkey, &lvi); + + db_set_b(NULL, DBMODULENAME "UI", _T2A(lvi.pszText), ListView_GetCheckState(hwndHotkey, lvi.iItem)); + } + } + } + + return FALSE; +} + +int HotkeyOptionsInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = hInst; + odp.flags = ODPF_BOLDGROUPS; + odp.position = -180000000; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_HOTKEYS); + odp.pszTitle = LPGEN("Hotkeys"); + odp.pszGroup = LPGEN("Customize"); + odp.pfnDlgProc = sttOptionsDlgProc; + Options_AddPage(wParam, &odp); + return 0; +} |