#include "stdafx.h" SettingListInfo info = {0}; HWND hwnd2List = 0; static int lastColumn = -1; struct ColumnsSettings csSettingList[] = { { LPGENT("Name"), 0, "Column0width", 180 }, { LPGENT("Value"), 1, "Column1width", 250 }, { LPGENT("Type"), 2, "Column2width", 60 }, { LPGENT("Size"), 3, "Column3width", 80 }, { LPGENT("#"), 4, "Column4width", 30 }, { 0 } }; int ListView_GetItemTextA(HWND hwndLV, int i, int iSubItem, char *pszText, int cchTextMax) { LV_ITEMA lvi; lvi.iSubItem = iSubItem; lvi.cchTextMax = cchTextMax; lvi.pszText = pszText; return SendMessageA(hwndLV, LVM_GETITEMTEXTA, (WPARAM)(i), (LPARAM)(LV_ITEMA *)&lvi); } int ListView_SetItemTextA(HWND hwndLV, int i, int iSubItem, const char *pszText) { LV_ITEMA lvi; lvi.iSubItem = iSubItem; lvi.pszText = (char*)pszText; return SendMessageA(hwndLV, LVM_SETITEMTEXTA, (WPARAM)(i), (LPARAM)(LV_ITEMA *)&lvi); } int convertSetting(MCONTACT hContact, const char *module, const char *setting, int toType) { DBVARIANT dbv = { 0 }; if (db_get_s(hContact, module, setting, &dbv, 0)) return 0; if (dbv.type == toType) { db_free(&dbv); return 1; } int res = 0; DWORD val = 0; TCHAR tmp[16]; ptrT value; switch (dbv.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: val = getNumericValue(&dbv); value = mir_tstrdup(_ultot(val, tmp, 10)); break; case DBVT_WCHAR: if (!value) value = mir_u2t(dbv.pwszVal); // fall through case DBVT_UTF8: if (!value) value = mir_utf8decodeT(dbv.pszVal); // fall through case DBVT_ASCIIZ: if (!value) value = mir_a2t(dbv.pszVal); if (mir_tstrlen(value) < 11) val = _tcstoul(value, NULL, NULL); } switch (toType) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: if (val != 0 || !mir_tstrcmp(value, _T("0"))) res = setNumericValue(hContact, module, setting, val, toType); break; case DBVT_ASCIIZ: case DBVT_UTF8: case DBVT_WCHAR: if (value) res = setTextValue(hContact, module, setting, value, toType); break; } if (!res) msg(TranslateT("Unable to store value in this data type!")); db_free(&dbv); return res; } void EditFinish(int selected) { if (info.hwnd2Edit) { SendMessage(info.hwnd2Edit, WM_COMMAND, MAKEWPARAM(IDOK, 0), 0); info.hwnd2Edit = NULL; } info.selectedItem = selected; } void ClearListView() { EditFinish(0); info.module[0] = 0; info.setting[0] = 0; info.hContact = 0; ListView_DeleteAllItems(hwnd2List); } void DeleteSettingsFromList(MCONTACT hContact, const char *module, const char *setting) { int count = ListView_GetSelectedCount(hwnd2List); if (!count) return; if (db_get_b(NULL, modname, "WarnOnDelete", 1)) { TCHAR text[MSG_SIZE]; mir_sntprintf(text, TranslateT("Are you sure you want to delete setting(s): %d?"), count); if (dlg(text, MB_YESNO | MB_ICONEXCLAMATION) == IDNO) return; } if (count == 1) db_unset(hContact, module, setting); else { int items = ListView_GetItemCount(hwnd2List); int i = 0; char text[FLD_SIZE]; while (i < items) { if (ListView_GetItemState(hwnd2List, i, LVIS_SELECTED)) { if (ListView_GetItemTextA(hwnd2List, i, 0, text, _countof(text))) db_unset(hContact, module, text); items--; } else i++; } } if (ListView_GetItemCount(hwnd2List) == 0) replaceTreeItem(hContact, module, 0); } int findListItem(const char *setting) { if (!setting || !setting[0]) return -1; LVFINDINFOA lvfi; lvfi.flags = LVFI_STRING; lvfi.psz = setting; lvfi.vkDirection = VK_DOWN; return SendMessageA(hwnd2List, LVM_FINDITEMA, -1, (LPARAM)&lvfi); } void deleteListItem(const char *setting) { int item = findListItem(setting); if (item > -1) ListView_DeleteItem(hwnd2List, item); } void updateListItem(int index, const char *setting, DBVARIANT *dbv, int resident) { if (!dbv || !dbv->type) { ListView_DeleteItem(hwnd2List, index); return; } if (index < 0) return; LVITEM lvi = { 0 }; lvi.mask = LVIF_IMAGE; lvi.iItem = index; ListView_SetItemText(hwnd2List, index, 4, resident ? _T("[R]") : _T("")); if (g_db && g_db->IsSettingEncrypted(info.module, setting)) { lvi.iImage = IMAGE_UNICODE; ListView_SetItem(hwnd2List, &lvi); ListView_SetItemTextA(hwnd2List, index, 0, setting); ListView_SetItemText(hwnd2List, index, 1, TranslateT("*** encrypted ***")); ListView_SetItemText(hwnd2List, index, 2, _T("UNICODE")); ListView_SetItemText(hwnd2List, index, 3, _T("")); return; } TCHAR data[32]; int length; switch (dbv->type) { case DBVT_BLOB: lvi.iImage = IMAGE_BINARY; ListView_SetItem(hwnd2List, &lvi); ListView_SetItemTextA(hwnd2List, index, 1, ptrA(StringFromBlob(dbv->pbVal, dbv->cpbVal))); mir_sntprintf(data, _T("0x%04X (%u)"), dbv->cpbVal, dbv->cpbVal); ListView_SetItemText(hwnd2List, index, 3, data); break; case DBVT_BYTE: lvi.iImage = IMAGE_BYTE; ListView_SetItem(hwnd2List, &lvi); mir_sntprintf(data, _T("0x%02X (%u)"), dbv->bVal, dbv->bVal); ListView_SetItemText(hwnd2List, index, 1, data); ListView_SetItemText(hwnd2List, index, 3, _T("0x0001 (1)")); break; case DBVT_WORD: lvi.iImage = IMAGE_WORD; ListView_SetItem(hwnd2List, &lvi); mir_sntprintf(data, _T("0x%04X (%u)"), dbv->wVal, dbv->wVal); ListView_SetItemText(hwnd2List, index, 1, data); ListView_SetItemText(hwnd2List, index, 3, _T("0x0002 (2)")); break; case DBVT_DWORD: lvi.iImage = IMAGE_DWORD; ListView_SetItem(hwnd2List, &lvi); mir_sntprintf(data, _T("0x%08X (%u)"), dbv->dVal, dbv->dVal); ListView_SetItemText(hwnd2List, index, 1, data); ListView_SetItemText(hwnd2List, index, 3, _T("0x0004 (4)")); break; case DBVT_ASCIIZ: lvi.iImage = IMAGE_STRING; ListView_SetItem(hwnd2List, &lvi); ListView_SetItemTextA(hwnd2List, index, 1, dbv->pszVal); length = (int)mir_strlen(dbv->pszVal) + 1; mir_sntprintf(data, _T("0x%04X (%u)"), length, length); ListView_SetItemText(hwnd2List, index, 3, data); break; case DBVT_WCHAR: lvi.iImage = IMAGE_UNICODE; ListView_SetItem(hwnd2List, &lvi); length = (int)mir_wstrlen(dbv->pwszVal) + 1; ListView_SetItemText(hwnd2List, index, 1, dbv->pwszVal); mir_sntprintf(data, _T("0x%04X (%u)"), length, length); ListView_SetItemText(hwnd2List, index, 3, data); break; case DBVT_UTF8: lvi.iImage = IMAGE_UNICODE; ListView_SetItem(hwnd2List, &lvi); length = (int)mir_strlen(dbv->pszVal) + 1; ListView_SetItemText(hwnd2List, index, 1, ptrT(mir_utf8decodeT(dbv->pszVal))); mir_sntprintf(data, _T("0x%04X (%u)"), length, length); ListView_SetItemText(hwnd2List, index, 3, data); break; default: return; } ListView_SetItemText(hwnd2List, index, 2, DBVType(dbv->type)); } void addListHandle(MCONTACT hContact) { TCHAR name[NAME_SIZE], data[32]; LVITEM lvi = { 0 }; lvi.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM; lvi.lParam = hContact; lvi.iImage = IMAGE_HANDLE; GetContactName(hContact, NULL, name, _countof(name)); lvi.pszText = name; int index = ListView_InsertItem(hwnd2List, &lvi); mir_sntprintf(data, _T("0x%08X (%ld)"), hContact, hContact); ListView_SetItemText(hwnd2List, index, 1, data); ListView_SetItemText(hwnd2List, index, 2, _T("HANDLE")); ListView_SetItemText(hwnd2List, index, 3, _T("0x0004 (4)")); if (db_mc_isEnabled()) { if (db_mc_isSub(hContact)) { ListView_SetItemText(hwnd2List, index, 4, _T("[S]")); } else if (db_mc_isMeta(hContact)) { ListView_SetItemText(hwnd2List, index, 4, _T("[M]")); } } } void addListItem(const char *setting, int resident) { DBVARIANT dbv; if (!db_get_s(info.hContact, info.module, setting, &dbv, 0)) { LVITEMA lvi = { 0 }; lvi.mask = LVIF_TEXT; lvi.pszText = (char*)setting; int index = SendMessageA(hwnd2List, LVM_INSERTITEMA, 0, (LPARAM)&lvi); updateListItem(index, setting, &dbv, resident); db_free(&dbv); } else if (!resident) { LVITEMA lvi = { 0 }; lvi.mask = LVIF_TEXT; lvi.pszText = (char*)setting; int index = SendMessageA(hwnd2List, LVM_INSERTITEMA, 0, (LPARAM)&lvi); ListView_SetItemText(hwnd2List, index, 1, TranslateT("*** buggy resident ***")); return; } } void PopulateSettings(MCONTACT hContact, const char *module) { // save module as it can be erased by ClearListView() char tmp[FLD_SIZE]; mir_strncpy(tmp, module, _countof(tmp)); // clear any settings that may be there... ClearListView(); info.hContact = hContact; mir_strncpy(info.module, tmp, _countof(info.module)); ModuleSettingLL setlist; if (IsModuleEmpty(info.hContact, info.module) || !EnumSettings(info.hContact, info.module, &setlist)) return; for (ModSetLinkLinkItem *setting = setlist.first; setting; setting = setting->next) addListItem(setting->name, 0); FreeModuleSettingLL(&setlist); // Resident settings if (!EnumResidentSettings(module, &setlist)) return; for (ModSetLinkLinkItem *setting = setlist.first; setting; setting = setting->next) addListItem(setting->name, 1); FreeModuleSettingLL(&setlist); } void SelectSetting(const char *setting) { LVITEM lvItem = { 0 }; lvItem.mask = LVIF_STATE; lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED; int items = ListView_GetItemCount(hwnd2List); for (int i = 0; i < items; i++) { if (ListView_GetItemState(hwnd2List, i, lvItem.stateMask)) ListView_SetItemState(hwnd2List, i, 0, lvItem.stateMask); } lvItem.iItem = findListItem(setting); if (lvItem.iItem != -1) { EditFinish(lvItem.iItem); lvItem.state = LVIS_SELECTED | LVIS_FOCUSED; ListView_SetItem(hwnd2List, &lvItem); } } void settingChanged(MCONTACT hContact, const char *module, const char *setting, DBVARIANT *dbv) { // modules tree if (dbv->type != DBVT_DELETED) { HTREEITEM hItem = findItemInTree(hContact, module); if (!hItem) { HTREEITEM hParent = findItemInTree(hContact, NULL); if (hParent) insertItem(hContact, module, hParent); } } // settings list if (hContact != info.hContact || mir_strcmp(info.module, module)) return; if (dbv->type == DBVT_DELETED) { deleteListItem(setting); } else { LVITEMA lvi = { 0 }; lvi.iItem = findListItem(setting); if (lvi.iItem == -1) { lvi.iItem = 0; lvi.mask = LVIF_TEXT; lvi.pszText = (char*)setting; lvi.iItem = SendMessageA(hwnd2List, LVM_INSERTITEMA, 0, (LPARAM)&lvi); } updateListItem(lvi.iItem, setting, dbv, IsResidentSetting(module, setting)); } } static LRESULT CALLBACK SettingLabelEditSubClassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_KEYDOWN: switch (wParam) { case VK_RETURN: if (GetKeyState(VK_CONTROL) & 0x8000) // ctrl is pressed break; SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDOK, 0), 0); return 0; case VK_ESCAPE: SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), 0); return 0; } break; case WM_USER: SetFocus(hwnd); SendMessage(hwnd, WM_SETFONT, SendMessage(GetParent(hwnd), WM_GETFONT, 0, 0), 1); if (info.subitem) SendMessage(hwnd, EM_LIMITTEXT, (WPARAM)65535, 0); else SendMessage(hwnd, EM_LIMITTEXT, (WPARAM)255, 0); SendMessage(hwnd, EM_SETSEL, 0, -1); break; case WM_PAINT: break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: { DBVARIANT dbv = { 0 }; int len = GetWindowTextLength(hwnd) + 1; if ((!info.subitem && len <= 1) || db_get_s(info.hContact, info.module, info.setting, &dbv, 0)) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), 0); return 0; } TCHAR *value = (TCHAR*)mir_alloc(len*sizeof(TCHAR)); GetWindowText(hwnd, value, len); _T2A szValue(value); int res = 0; switch (info.subitem) { case 0: // setting name if (!mir_strcmp(info.setting, szValue) || mir_strlen(szValue) > 0xFE) { db_free(&dbv); mir_free(value); SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), 0); return 0; } if (db_set(info.hContact, info.module, szValue, &dbv)) break; res = 1; db_unset(info.hContact, info.module, info.setting); deleteListItem(info.setting); break; case 1: // value DWORD val; int i = 0; if (dbv.type == DBVT_BLOB) { res = WriteBlobFromString(info.hContact, info.module, info.setting, szValue, (int)mir_strlen(szValue)); break; } switch (value[0]) { case _T('b'): case _T('B'): val = _tcstoul(&value[1], NULL, 0); if (!val || value[1] == _T('0')) { res = !db_set_b(info.hContact, info.module, info.setting, (BYTE)val); } else res = setTextValue(info.hContact, info.module, info.setting, value, dbv.type); break; case _T('w'): case _T('W'): val = _tcstoul(&value[1], NULL, 0); if (!val || value[1] == _T('0')) res = !db_set_w(info.hContact, info.module, info.setting, (WORD)val); else res = setTextValue(info.hContact, info.module, info.setting, value, dbv.type); break; case _T('d'): case _T('D'): val = _tcstoul(&value[1], NULL, 0); if (!val || value[1] == _T('0')) res = !db_set_dw(info.hContact, info.module, info.setting, val); else res = setTextValue(info.hContact, info.module, info.setting, value, dbv.type); break; case _T('0'): i = 1; // fall through case _T('1'): case _T('2'): case _T('3'): case _T('4'): case _T('5'): case _T('6'): case _T('7'): case _T('8'): case _T('9'): case _T('-'): case _T('x'): case _T('X'): if (value[i] == _T('x') || value[i] == _T('X')) val = _tcstoul(&value[i + 1], NULL, 16); else val = _tcstoul(value, NULL, 10); switch (dbv.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: res = setNumericValue(info.hContact, info.module, info.setting, val, dbv.type); break; case DBVT_ASCIIZ: case DBVT_WCHAR: case DBVT_UTF8: res = setTextValue(info.hContact, info.module, info.setting, value, dbv.type); break; } break; case _T('\"'): case _T('\''): { size_t nlen = mir_tstrlen(value); int sh = 0; if (nlen > 3) { if (value[nlen - 1] == value[0]) { value[nlen - 1] = 0; sh = 1; } } res = setTextValue(info.hContact, info.module, info.setting, &value[sh], dbv.type); } break; default: res = setTextValue(info.hContact, info.module, info.setting, value, dbv.type); break; } break; } mir_free(value); db_free(&dbv); if (!res) { msg(TranslateT("Unable to store value in this data type!")); break; } } // fall through case IDCANCEL: DestroyWindow(hwnd); return 0; } case WM_GETDLGCODE: return DLGC_WANTALLKEYS; case WM_DESTROY: info.hwnd2Edit = NULL; break; } return mir_callNextSubclass(hwnd, SettingLabelEditSubClassProc, msg, wParam, lParam); } void EditLabel(int item, int subitem) { RECT rc; char setting[FLD_SIZE]; DBVARIANT dbv; if (info.hwnd2Edit) { SendMessage(info.hwnd2Edit, WM_COMMAND, MAKEWPARAM(IDCANCEL, 0), 0); // ignore the new value of the last edit info.hwnd2Edit = NULL; } if (!ListView_GetItemTextA(hwnd2List, item, 0, setting, _countof(setting))) return; if (!setting[0] || !ListView_GetSubItemRect(hwnd2List, item, subitem, LVIR_LABEL, &rc)) return; if (db_get_s(info.hContact, info.module, setting, &dbv, 0)) return; mir_strcpy(info.setting, setting); info.subitem = subitem; if (!subitem) info.hwnd2Edit = CreateWindow(_T("EDIT"), _A2T(setting), WS_BORDER | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), hwnd2List, 0, hInst, 0); else { TCHAR *str = NULL, value[16] = { 0 }; switch (dbv.type) { case DBVT_ASCIIZ: str = mir_a2t(dbv.pszVal); break; case DBVT_BYTE: mir_sntprintf(value, (g_Hex & HEX_BYTE) ? _T("0x%02X") : _T("%u"), dbv.bVal); break; case DBVT_WORD: mir_sntprintf(value, (g_Hex & HEX_WORD) ? _T("0x%04X") : _T("%u"), dbv.wVal); break; case DBVT_DWORD: mir_sntprintf(value, (g_Hex & HEX_DWORD) ? _T("0x%08X") : _T("%u"), dbv.dVal); break; case DBVT_WCHAR: str = mir_u2t(dbv.pwszVal); break; case DBVT_UTF8: str = mir_utf8decodeT(dbv.pszVal); break; case DBVT_BLOB: str = mir_a2t(ptrA(StringFromBlob(dbv.pbVal, dbv.cpbVal))); break; } if (str) { int height = (rc.bottom - rc.top) * 4; RECT rclist; GetClientRect(hwnd2List, &rclist); if (rc.top + height > rclist.bottom && rclist.bottom - rclist.top > height) rc.top = rc.bottom - height; info.hwnd2Edit = CreateWindow(_T("EDIT"), str, WS_BORDER | WS_VISIBLE | WS_CHILD | WS_VSCROLL | ES_MULTILINE | ES_AUTOHSCROLL, rc.left, rc.top, rc.right - rc.left, height, hwnd2List, 0, hInst, 0); mir_free(str); } else if (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD) info.hwnd2Edit = CreateWindow(_T("EDIT"), value, WS_BORDER | WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), hwnd2List, 0, hInst, 0); } db_free(&dbv); mir_subclassWindow(info.hwnd2Edit, SettingLabelEditSubClassProc); SendMessage(info.hwnd2Edit, WM_USER, 0, 0); } void SettingsListRightClick(HWND hwnd, WPARAM wParam, LPARAM lParam); void SettingsListWM_NOTIFY(HWND hwnd, UINT, WPARAM wParam, LPARAM lParam) { LVHITTESTINFO hti; switch (((NMHDR*)lParam)->code) { case NM_CLICK: hti.pt = ((NMLISTVIEW*)lParam)->ptAction; if (ListView_SubItemHitTest(hwnd2List, &hti) > -1) { if (g_Inline && hti.iSubItem <= 1 && hti.flags != LVHT_ONITEMICON && info.selectedItem == hti.iItem) EditLabel(hti.iItem, hti.iSubItem); else EditFinish(hti.iItem); } else EditFinish(0); break; case NM_DBLCLK: hti.pt = ((NMLISTVIEW*)lParam)->ptAction; if (ListView_SubItemHitTest(hwnd2List, &hti) > -1) { if (!info.module[0]) { // contact LVITEM lvi = { 0 }; lvi.mask = LVIF_PARAM; lvi.iItem = hti.iItem; if (!ListView_GetItem(hwnd2List, &lvi)) break; ItemInfo ii = { 0 }; ii.hContact = (MCONTACT)lvi.lParam; SendMessage(hwnd2mainWindow, WM_FINDITEM, (WPARAM)&ii, 0); break; } if (!g_Inline || hti.iSubItem > 1 || hti.flags == LVHT_ONITEMICON) { char setting[FLD_SIZE]; EditFinish(hti.iItem); if (ListView_GetItemTextA(hwnd2List, hti.iItem, 0, setting, _countof(setting))) editSetting(info.hContact, info.module, setting); } else EditLabel(hti.iItem, hti.iSubItem); } break; case NM_RCLICK: SettingsListRightClick(hwnd, wParam, lParam); break; case LVN_COLUMNCLICK: LPNMLISTVIEW lv = (LPNMLISTVIEW)lParam; ColumnsSortParams params = { 0 }; params.hList = hwnd2List; params.column = lv->iSubItem; params.last = lastColumn; ListView_SortItemsEx(params.hList, ColumnsCompare, (LPARAM)¶ms); lastColumn = (params.column == lastColumn) ? -1 : params.column; break; } } void SettingsListRightClick(HWND hwnd, WPARAM, LPARAM lParam) // hwnd here is to the main window, NOT the listview { LVHITTESTINFO hti; POINT pt; HMENU hMenu, hSubMenu; hti.pt = ((NMLISTVIEW*)lParam)->ptAction; if (ListView_SubItemHitTest(hwnd2List, &hti) == -1) { // nowhere.. new item menu GetCursorPos(&pt); hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU)); hSubMenu = GetSubMenu(hMenu, 6); TranslateMenu(hSubMenu); if (!info.module[0]) { RemoveMenu(hSubMenu, 0, MF_BYPOSITION); // new RemoveMenu(hSubMenu, 0, MF_BYPOSITION); // separator } switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL)) { case MENU_ADD_BYTE: newSetting(info.hContact, info.module, DBVT_BYTE); return; case MENU_ADD_WORD: newSetting(info.hContact, info.module, DBVT_WORD); return; case MENU_ADD_DWORD: newSetting(info.hContact, info.module, DBVT_DWORD); return; case MENU_ADD_STRING: newSetting(info.hContact, info.module, DBVT_ASCIIZ); return; case MENU_ADD_UNICODE: newSetting(info.hContact, info.module, DBVT_WCHAR); return; case MENU_ADD_BLOB: newSetting(info.hContact, info.module, DBVT_BLOB); return; case MENU_REFRESH: PopulateSettings(info.hContact, info.module); return; } return; } // on item GetCursorPos(&pt); hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXTMENU)); hSubMenu = GetSubMenu(hMenu, 0); TranslateMenu(hSubMenu); LVITEM lvi = { 0 }; lvi.mask = LVIF_IMAGE; lvi.iItem = hti.iItem; lvi.iSubItem = 0; ListView_GetItem(hwnd2List, &lvi); switch (lvi.iImage) { case IMAGE_STRING: RemoveMenu(hSubMenu, MENU_CHANGE2STRING, MF_BYCOMMAND); break; case IMAGE_BYTE: RemoveMenu(hSubMenu, MENU_CHANGE2BYTE, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); break; case IMAGE_WORD: RemoveMenu(hSubMenu, MENU_CHANGE2WORD, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); break; case IMAGE_DWORD: RemoveMenu(hSubMenu, MENU_CHANGE2DWORD, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); break; case IMAGE_BINARY: RemoveMenu(hSubMenu, 3, MF_BYPOSITION); // convert break; case IMAGE_UNICODE: RemoveMenu(hSubMenu, MENU_CHANGE2DWORD, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_CHANGE2WORD, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_CHANGE2BYTE, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_CHANGE2UNICODE, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_CHANGE2BYTE, MF_BYCOMMAND); break; case IMAGE_EMPTY: // resident RemoveMenu(hSubMenu, 3, MF_BYPOSITION); // convert RemoveMenu(hSubMenu, MENU_COPY_SET, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_DELETE_SET, MF_BYCOMMAND); break; case IMAGE_HANDLE: RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_COPY_SET, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_DELETE_SET, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_WATCH_ITEM, MF_BYCOMMAND); RemoveMenu(hSubMenu, 0, MF_BYPOSITION); // convert RemoveMenu(hSubMenu, 0, MF_BYPOSITION); // separator RemoveMenu(hSubMenu, 0, MF_BYPOSITION); // new break; } if (ListView_GetSelectedCount(hwnd2List) > 1) { RemoveMenu(hSubMenu, 3, MF_BYPOSITION); // convert RemoveMenu(hSubMenu, MENU_EDIT_SET, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_COPY_SET, MF_BYCOMMAND); RemoveMenu(hSubMenu, MENU_WATCH_ITEM, MF_BYCOMMAND); } char setting[FLD_SIZE]; if (!ListView_GetItemTextA(hwnd2List, hti.iItem, 0, setting, _countof(setting))) return; // check if the setting is being watched and if it is then check the menu item int watchIdx = WatchedArrayIndex(info.hContact, info.module, setting, 1); if (watchIdx >= 0) CheckMenuItem(hSubMenu, MENU_WATCH_ITEM, MF_CHECKED | MF_BYCOMMAND); switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL)) { case MENU_EDIT_SET: editSetting(info.hContact, info.module, setting); break; case MENU_COPY_SET: copySetting(info.hContact, info.module, setting); break; case MENU_ADD_BYTE: newSetting(info.hContact, info.module, DBVT_BYTE); return; case MENU_ADD_WORD: newSetting(info.hContact, info.module, DBVT_WORD); return; case MENU_ADD_DWORD: newSetting(info.hContact, info.module, DBVT_DWORD); return; case MENU_ADD_STRING: newSetting(info.hContact, info.module, DBVT_ASCIIZ); return; case MENU_ADD_UNICODE: newSetting(info.hContact, info.module, DBVT_WCHAR); return; case MENU_ADD_BLOB: newSetting(info.hContact, info.module, DBVT_BLOB); return; case MENU_CHANGE2BYTE: convertSetting(info.hContact, info.module, setting, DBVT_BYTE); break; case MENU_CHANGE2WORD: convertSetting(info.hContact, info.module, setting, DBVT_WORD); break; case MENU_CHANGE2DWORD: convertSetting(info.hContact, info.module, setting, DBVT_DWORD); break; case MENU_CHANGE2STRING: convertSetting(info.hContact, info.module, setting, DBVT_ASCIIZ); break; case MENU_CHANGE2UNICODE: convertSetting(info.hContact, info.module, setting, DBVT_UTF8); break; case MENU_WATCH_ITEM: if (watchIdx < 0) addSettingToWatchList(info.hContact, info.module, setting); else freeWatchListItem(watchIdx); PopulateWatchedWindow(); break; case MENU_DELETE_SET: DeleteSettingsFromList(info.hContact, info.module, setting); break; case MENU_REFRESH: PopulateSettings(info.hContact, info.module); break; } }