summaryrefslogtreecommitdiff
path: root/plugins/TabSRMM/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2017-03-23 22:07:41 +0300
committerGeorge Hazan <ghazan@miranda.im>2017-03-23 22:07:41 +0300
commit61fde2711609ea8a2f1005f21d9ec4502044bce1 (patch)
treee88ceb6981745c88cd5580c37308a41ed21c2c82 /plugins/TabSRMM/src
parent34e059269d3c8a5d999575efce347c116b7be52a (diff)
tabSRMM: windows virtualization
Diffstat (limited to 'plugins/TabSRMM/src')
-rw-r--r--plugins/TabSRMM/src/chat_window.cpp1757
-rw-r--r--plugins/TabSRMM/src/msgdialog.cpp669
-rw-r--r--plugins/TabSRMM/src/msgs.h21
-rw-r--r--plugins/TabSRMM/src/themes.cpp11
-rw-r--r--plugins/TabSRMM/src/utils.cpp2
5 files changed, 1211 insertions, 1249 deletions
diff --git a/plugins/TabSRMM/src/chat_window.cpp b/plugins/TabSRMM/src/chat_window.cpp
index f1f66ff400..f28590f15e 100644
--- a/plugins/TabSRMM/src/chat_window.cpp
+++ b/plugins/TabSRMM/src/chat_window.cpp
@@ -40,15 +40,6 @@ extern HMENU g_hMenu;
static HKL hkl = nullptr;
char szIndicators[] = { 0, '+', '%', '@', '!', '*' };
-struct MESSAGESUBDATA
-{
- time_t lastEnterTime;
- wchar_t *szSearchQuery;
- wchar_t *szSearchResult;
- BOOL iSavedSpaces;
- SESSION_INFO *lastSession;
-};
-
const CLSID IID_ITextDocument = { 0x8CC497C0, 0xA1DF, 0x11CE, { 0x80, 0x98, 0x00, 0xAA, 0x00, 0x47, 0xBE, 0x5D } };
/////////////////////////////////////////////////////////////////////////////////////////
@@ -378,19 +369,16 @@ int CChatRoomDlg::Resizer(UTILRESIZECONTROL *urc)
return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
}
-/////////////////////////////////////////////////////////////////////////////////////////
-// subclassing for the message input control(a richedit text control)
-
-static bool TabAutoComplete(HWND hwnd, MESSAGESUBDATA *dat, SESSION_INFO *si)
+bool CChatRoomDlg::TabAutoComplete()
{
- LRESULT lResult = (LRESULT)SendMessage(hwnd, EM_GETSEL, 0, 0);
+ LRESULT lResult = m_message.SendMsg(EM_GETSEL, 0, 0);
int start = LOWORD(lResult), end = HIWORD(lResult);
- SendMessage(hwnd, EM_SETSEL, end, end);
+ m_message.SendMsg(EM_SETSEL, end, end);
GETTEXTEX gt = { 0 };
gt.codepage = 1200;
gt.flags = GTL_DEFAULT | GTL_PRECISE;
- int iLen = SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);
+ int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);
if (iLen <= 0)
return false;
@@ -400,14 +388,14 @@ static bool TabAutoComplete(HWND hwnd, MESSAGESUBDATA *dat, SESSION_INFO *si)
gt.flags = GT_DEFAULT;
gt.cb = (iLen + 9) * sizeof(wchar_t);
- SendMessage(hwnd, EM_GETTEXTEX, (WPARAM)&gt, (LPARAM)pszText);
+ m_message.SendMsg(EM_GETTEXTEX, (WPARAM)&gt, (LPARAM)pszText);
if (start > 1 && pszText[start - 1] == ' ' && pszText[start - 2] == ':')
start -= 2;
- if (dat->szSearchResult != nullptr) {
- int cbResult = (int)mir_wstrlen(dat->szSearchResult);
- if (start >= cbResult && !wcsnicmp(dat->szSearchResult, pszText + start - cbResult, cbResult)) {
+ if (m_wszSearchResult != nullptr) {
+ int cbResult = (int)mir_wstrlen(m_wszSearchResult);
+ if (start >= cbResult && !wcsnicmp(m_wszSearchResult, pszText + start - cbResult, cbResult)) {
start -= cbResult;
goto LBL_SkipEnd;
}
@@ -429,24 +417,24 @@ LBL_SkipEnd:
if (topicStart > 5 && wcsstr(&pszText[topicStart - 6], L"/topic") == &pszText[topicStart - 6])
isTopic = TRUE;
}
- if (dat->szSearchQuery == nullptr) {
- dat->szSearchQuery = mir_wstrndup(pszText + start, end - start);
- dat->szSearchResult = mir_wstrdup(dat->szSearchQuery);
- dat->lastSession = nullptr;
+ if (m_wszSearchQuery == nullptr) {
+ m_wszSearchQuery = mir_wstrndup(pszText + start, end - start);
+ m_wszSearchResult = mir_wstrdup(m_wszSearchQuery);
+ m_pLastSession = nullptr;
}
if (isTopic)
- pszName = si->ptszTopic;
+ pszName = m_si->ptszTopic;
else if (isRoom) {
- dat->lastSession = SM_FindSessionAutoComplete(si->pszModule, si, dat->lastSession, dat->szSearchQuery, dat->szSearchResult);
- if (dat->lastSession != nullptr)
- pszName = dat->lastSession->ptszName;
+ m_pLastSession = SM_FindSessionAutoComplete(m_si->pszModule, m_si, m_pLastSession, m_wszSearchQuery, m_wszSearchResult);
+ if (m_pLastSession != nullptr)
+ pszName = m_pLastSession->ptszName;
}
- else pszName = pci->UM_FindUserAutoComplete(si->pUsers, dat->szSearchQuery, dat->szSearchResult);
+ else pszName = pci->UM_FindUserAutoComplete(m_si->pUsers, m_wszSearchQuery, m_wszSearchResult);
- replaceStrW(dat->szSearchResult, nullptr);
+ replaceStrW(m_wszSearchResult, nullptr);
if (pszName != nullptr) {
- dat->szSearchResult = mir_wstrdup(pszName);
+ m_wszSearchResult = mir_wstrdup(pszName);
if (end != start) {
ptrW szReplace;
if (!isRoom && !isTopic && g_Settings.bAddColonToAutoComplete && start == 0) {
@@ -455,877 +443,20 @@ LBL_SkipEnd:
mir_wstrcat(szReplace, g_Settings.bUseCommaAsColon ? L", " : L": ");
pszName = szReplace;
}
- SendMessage(hwnd, EM_SETSEL, start, end);
- SendMessage(hwnd, EM_REPLACESEL, TRUE, (LPARAM)pszName);
+ m_message.SendMsg(EM_SETSEL, start, end);
+ m_message.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)pszName);
}
return true;
}
if (end != start) {
- SendMessage(hwnd, EM_SETSEL, start, end);
- SendMessage(hwnd, EM_REPLACESEL, TRUE, (LPARAM)dat->szSearchQuery);
+ m_message.SendMsg(EM_SETSEL, start, end);
+ m_message.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)m_wszSearchQuery);
}
- replaceStrW(dat->szSearchQuery, nullptr);
+ replaceStrW(m_wszSearchQuery, nullptr);
return false;
}
-LRESULT CALLBACK CChatRoomDlg::MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND hwndParent = GetParent(hwnd);
- CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
- if (pDlg == nullptr)
- return 0;
-
- MESSAGESUBDATA *dat = (MESSAGESUBDATA*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-
- if (pDlg->m_bkeyProcessed && (msg == WM_KEYUP)) {
- GetKeyboardState(pDlg->kstate);
- if (!(pDlg->kstate[VK_CONTROL] & 0x80) && !(pDlg->kstate[VK_SHIFT] & 0x80))
- pDlg->m_bkeyProcessed = false;
- return 0;
- }
-
- switch (msg) {
- case WM_NCCALCSIZE:
- return CSkin::NcCalcRichEditFrame(hwnd, pDlg, ID_EXTBKINPUTAREA, msg, wParam, lParam, MessageSubclassProc);
-
- case WM_NCPAINT:
- return CSkin::DrawRichEditFrame(hwnd, pDlg, ID_EXTBKINPUTAREA, msg, wParam, lParam, MessageSubclassProc);
-
- case EM_SUBCLASSED:
- dat = (MESSAGESUBDATA*)mir_calloc(sizeof(MESSAGESUBDATA));
- SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat);
- return 0;
-
- case WM_CONTEXTMENU:
- POINT pt;
- GetCursorPos(&pt);
- {
- HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT));
- HMENU hSubMenu = GetSubMenu(hMenu, 2);
- RemoveMenu(hSubMenu, 9, MF_BYPOSITION);
- RemoveMenu(hSubMenu, 8, MF_BYPOSITION);
- RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
-
- MODULEINFO *mi = pci->MM_FindModule(pDlg->m_si->pszModule);
- EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | ((mi && mi->bBold) ? MF_ENABLED : MF_GRAYED));
- TranslateMenu(hSubMenu);
-
- CHARRANGE sel, all = { 0, -1 };
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);
- if (sel.cpMin == sel.cpMax) {
- EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(hSubMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED);
- }
-
- MessageWindowPopupData mwpd = { sizeof(mwpd) };
- mwpd.uType = MSG_WINDOWPOPUP_SHOWING;
- mwpd.uFlags = MSG_WINDOWPOPUP_INPUT;
- mwpd.hContact = pDlg->m_hContact;
- mwpd.hwnd = hwnd;
- mwpd.hMenu = hSubMenu;
- mwpd.pt = pt;
- NotifyEventHooks(PluginConfig.m_event_MsgPopup, 0, (LPARAM)&mwpd);
-
- int iSelection = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, GetParent(hwnd), nullptr);
-
- mwpd.selection = iSelection;
- mwpd.uType = MSG_WINDOWPOPUP_SELECTED;
- NotifyEventHooks(PluginConfig.m_event_MsgPopup, 0, (LPARAM)&mwpd);
-
- switch (iSelection) {
- case IDM_COPY:
- SendMessage(hwnd, WM_COPY, 0, 0);
- break;
- case IDM_CUT:
- SendMessage(hwnd, WM_CUT, 0, 0);
- break;
- case IDM_PASTE:
- case IDM_PASTEFORMATTED:
- SendMessage(hwnd, EM_PASTESPECIAL, (iSelection == IDM_PASTE) ? CF_UNICODETEXT : 0, 0);
- break;
- case IDM_COPYALL:
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&all);
- SendMessage(hwnd, WM_COPY, 0, 0);
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);
- break;
- case IDM_SELECTALL:
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&all);
- break;
- }
- DestroyMenu(hMenu);
- }
- return TRUE;
-
- case WM_MOUSEWHEEL:
- if (pDlg->DM_MouseWheelHandler(wParam, lParam) == 0)
- return 0;
-
- dat->lastEnterTime = 0;
- break;
-
- case WM_SYSKEYUP:
- if (wParam == VK_MENU) {
- ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_MESSAGE);
- return 0;
- }
- break;
-
- case WM_SYSKEYDOWN:
- pDlg->m_bkeyProcessed = false;
- if (ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_MESSAGE)) {
- pDlg->m_bkeyProcessed = true;
- return 0;
- }
- break;
-
- case WM_SYSCHAR:
- if (pDlg->m_bkeyProcessed) {
- pDlg->m_bkeyProcessed = false; // preceeding key event has been processed by miranda hotkey service
- return 0;
- }
-
- if ((wParam >= '0' && wParam <= '9') && (GetKeyState(VK_MENU) & 0x8000)) { // ALT-1 -> ALT-0 direct tab selection
- BYTE bChar = (BYTE)wParam;
- int iIndex = (bChar == '0') ? 10 : bChar - (BYTE)'0';
- SendMessage(pDlg->m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_BY_INDEX, (LPARAM)iIndex);
- return 0;
- }
- break;
-
- case WM_CHAR:
- bool isShift, isAlt, isCtrl;
- pDlg->KbdState(isShift, isCtrl, isAlt);
-
- if (PluginConfig.m_bSoundOnTyping && !isAlt && !isCtrl && !(pDlg->m_pContainer->dwFlags & CNT_NOSOUND) && wParam != VK_ESCAPE && !(wParam == VK_TAB && PluginConfig.m_bAllowTab))
- SkinPlaySound("SoundOnTyping");
-
- if (isCtrl && !isAlt && !isShift)
- switch(wParam) {
- case 0x17:
- PostMessage(hwndParent, WM_CLOSE, 0, 1);
- return 0;
- }
-
- break;
-
- case WM_KEYDOWN:
- pDlg->KbdState(isShift, isCtrl, isAlt);
-
- // sound on typing..
- if (PluginConfig.m_bSoundOnTyping && !isAlt && wParam == VK_DELETE)
- SkinPlaySound("SoundOnTyping");
-
- if (pDlg->ProcessHotkeys(wParam, isShift, isCtrl, isAlt))
- return true;
-
- if (wParam == VK_INSERT && !isShift && !isCtrl && !isAlt) {
- pDlg->m_bInsertMode = !pDlg->m_bInsertMode;
- SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM)hwnd);
- }
- if (wParam == VK_CAPITAL || wParam == VK_NUMLOCK)
- SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM)hwnd);
-
- if (isCtrl && isAlt && !isShift) {
- switch (wParam) {
- case VK_UP:
- case VK_DOWN:
- case VK_PRIOR:
- case VK_NEXT:
- case VK_HOME:
- case VK_END:
- WPARAM wp = 0;
-
- if (wParam == VK_UP)
- wp = MAKEWPARAM(SB_LINEUP, 0);
- else if (wParam == VK_PRIOR)
- wp = MAKEWPARAM(SB_PAGEUP, 0);
- else if (wParam == VK_NEXT)
- wp = MAKEWPARAM(SB_PAGEDOWN, 0);
- else if (wParam == VK_HOME)
- wp = MAKEWPARAM(SB_TOP, 0);
- else if (wParam == VK_END) {
- pDlg->DM_ScrollToBottom(0, 0);
- return 0;
- }
- else if (wParam == VK_DOWN)
- wp = MAKEWPARAM(SB_LINEDOWN, 0);
-
- SendDlgItemMessage(hwndParent, IDC_LOG, WM_VSCROLL, wp, 0);
- return 0;
- }
- }
-
- if (wParam == VK_RETURN) {
- if (isShift) {
- if (PluginConfig.m_bSendOnShiftEnter) {
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- break;
- }
- if ((isCtrl && !isShift) ^ (0 != PluginConfig.m_bSendOnEnter)) {
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- if (!PluginConfig.m_bSendOnEnter && !PluginConfig.m_bSendOnDblEnter)
- break;
- if (isCtrl)
- break;
-
- if (PluginConfig.m_bSendOnDblEnter) {
- if (dat->lastEnterTime + 2 < time(nullptr)) {
- dat->lastEnterTime = time(nullptr);
- break;
- }
-
- SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 0);
- SendMessage(hwnd, WM_KEYUP, VK_BACK, 0);
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- else dat->lastEnterTime = 0;
-
- if ((wParam == VK_NEXT && isCtrl && !isShift) || (wParam == VK_TAB && isCtrl && !isShift)) { // CTRL-TAB (switch tab/window)
- SendMessage(pDlg->m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_NEXT, 0);
- return TRUE;
- }
-
- if ((wParam == VK_PRIOR && isCtrl && !isShift) || (wParam == VK_TAB && isCtrl && isShift)) { // CTRL_SHIFT-TAB (switch tab/window)
- SendMessage(pDlg->m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_PREV, 0);
- return TRUE;
- }
- if (wParam == VK_TAB && !isCtrl && !isShift) { // tab-autocomplete
- SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
- bool fCompleted = TabAutoComplete(hwnd, dat, pDlg->m_si);
- SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
- RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE);
- if (!fCompleted && !PluginConfig.m_bAllowTab) {
- if ((GetSendButtonState(pDlg->GetHwnd()) != PBS_DISABLED))
- SetFocus(GetDlgItem(pDlg->GetHwnd(), IDOK));
- else
- SetFocus(GetDlgItem(pDlg->GetHwnd(), IDC_LOG));
- }
- return 0;
- }
- if (wParam != VK_RIGHT && wParam != VK_LEFT) {
- mir_free(dat->szSearchQuery);
- dat->szSearchQuery = nullptr;
- mir_free(dat->szSearchResult);
- dat->szSearchResult = nullptr;
- }
-
- if (wParam == VK_F4 && isCtrl && !isAlt) { // ctrl-F4 (close tab)
- SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(IDC_CLOSE, BN_CLICKED), 0);
- return 0;
- }
-
- if (wParam == VK_NEXT || wParam == VK_PRIOR) {
- HWND htemp = hwndParent;
- SendDlgItemMessage(htemp, IDC_LOG, msg, wParam, lParam);
- dat->lastEnterTime = 0;
- return 0;
- }
-
- if (wParam == VK_UP && isCtrl && !isAlt) {
- char *lpPrevCmd = pci->SM_GetPrevCommand(pDlg->m_si->ptszID, pDlg->m_si->pszModule);
-
- if (!pDlg->m_si->lpCurrentCommand || !pDlg->m_si->lpCurrentCommand->last) {
- // Next command is not defined. It means currently entered text is not saved in the history and it
- // need to be saved in the window context.
- char *enteredText = Message_GetFromStream(hwndParent);
- if (pDlg->m_enteredText)
- mir_free(pDlg->m_enteredText);
-
- pDlg->m_enteredText = enteredText;
- }
-
- SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
-
- LOGFONTA lf;
- LoadLogfont(FONTSECTION_IM, MSGFONTID_MESSAGEAREA, &lf, nullptr, FONTMODULE);
-
- SETTEXTEX ste;
- ste.flags = ST_DEFAULT;
- ste.codepage = CP_ACP;
- if (lpPrevCmd)
- SendMessage(hwnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd);
- else
- SetWindowText(hwnd, L"");
-
- GETTEXTLENGTHEX gtl = { 0 };
- gtl.flags = GTL_PRECISE;
- gtl.codepage = CP_ACP;
- int iLen = SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)&gtl, 0);
- SendMessage(hwnd, EM_SCROLLCARET, 0, 0);
- SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
- RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE);
- SendMessage(hwnd, EM_SETSEL, iLen, iLen);
- dat->lastEnterTime = 0;
- return 0;
- }
-
- if (wParam == VK_DOWN && isCtrl && !isAlt) {
- SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
-
- SETTEXTEX ste;
- ste.flags = ST_DEFAULT;
- ste.codepage = CP_ACP;
-
- char *lpPrevCmd = pci->SM_GetNextCommand(pDlg->m_si->ptszID, pDlg->m_si->pszModule);
- if (lpPrevCmd)
- SendMessage(hwnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd);
- else if (pDlg->m_enteredText) {
- // If we cannot load the message from history, load the last edited text.
- SendMessage(hwnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)pDlg->m_enteredText);
- mir_free(pDlg->m_enteredText);
- pDlg->m_enteredText = nullptr;
- }
-
- GETTEXTLENGTHEX gtl = { 0 };
- gtl.flags = GTL_PRECISE;
- gtl.codepage = CP_ACP;
- int iLen = SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)&gtl, 0);
- SendMessage(hwnd, EM_SCROLLCARET, 0, 0);
- SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
- RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE);
- SendMessage(hwnd, EM_SETSEL, iLen, iLen);
- dat->lastEnterTime = 0;
- return 0;
- }
- // fall through
-
- case WM_LBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_KILLFOCUS:
- dat->lastEnterTime = 0;
- break;
-
- case WM_KEYUP:
- case WM_LBUTTONUP:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- pDlg->RefreshButtonStatus();
- break;
-
- case WM_INPUTLANGCHANGE:
- if (PluginConfig.m_bAutoLocaleSupport && GetFocus() == hwnd && pDlg->m_pContainer->m_hwndActive == hwndParent && GetForegroundWindow() == pDlg->m_pContainer->m_hwnd && GetActiveWindow() == pDlg->m_pContainer->m_hwnd) {
- pDlg->DM_SaveLocale(wParam, lParam);
- SendMessage(hwnd, EM_SETLANGOPTIONS, 0, (LPARAM)SendMessage(hwnd, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
- return 1;
- }
- break;
-
- case WM_ERASEBKGND:
- return !CSkin::m_skinEnabled;
-
- case WM_DESTROY:
- mir_free(dat);
- }
-
- return mir_callNextSubclass(hwnd, MessageSubclassProc, msg, wParam, lParam);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// subclassing for the message filter dialog (set and configure event filters for the
-// current session
-
-static UINT _eventorder[] =
-{
- GC_EVENT_ACTION,
- GC_EVENT_MESSAGE,
- GC_EVENT_NICK,
- GC_EVENT_JOIN,
- GC_EVENT_PART,
- GC_EVENT_TOPIC,
- GC_EVENT_ADDSTATUS,
- GC_EVENT_INFORMATION,
- GC_EVENT_QUIT,
- GC_EVENT_KICK,
- GC_EVENT_NOTICE
-};
-
-INT_PTR CALLBACK CChatRoomDlg::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- switch (uMsg) {
- case WM_INITDIALOG:
- pDlg = (CChatRoomDlg*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
- {
- DWORD dwMask = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "FilterMask", 0);
- DWORD dwFlags = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "FilterFlags", 0);
-
- DWORD dwPopupMask = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "PopupMask", 0);
- DWORD dwPopupFlags = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "PopupFlags", 0);
-
- DWORD dwTrayMask = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconMask", 0);
- DWORD dwTrayFlags = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconFlags", 0);
-
- for (int i = 0; i < _countof(_eventorder); i++) {
- CheckDlgButton(hwndDlg, IDC_1 + i, dwMask & _eventorder[i] ? (dwFlags & _eventorder[i] ? BST_CHECKED : BST_UNCHECKED) : BST_INDETERMINATE);
- CheckDlgButton(hwndDlg, IDC_P1 + i, dwPopupMask & _eventorder[i] ? (dwPopupFlags & _eventorder[i] ? BST_CHECKED : BST_UNCHECKED) : BST_INDETERMINATE);
- CheckDlgButton(hwndDlg, IDC_T1 + i, dwTrayMask & _eventorder[i] ? (dwTrayFlags & _eventorder[i] ? BST_CHECKED : BST_UNCHECKED) : BST_INDETERMINATE);
- }
- }
- return FALSE;
-
- case WM_CTLCOLOREDIT:
- case WM_CTLCOLORSTATIC:
- SetTextColor((HDC)wParam, RGB(60, 60, 150));
- SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
- return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
-
- case WM_CLOSE:
- if (wParam == 1 && lParam == 1) {
- int iFlags = 0, i;
- DWORD dwMask = 0;
-
- for (i = 0; i < _countof(_eventorder); i++) {
- int result = IsDlgButtonChecked(hwndDlg, IDC_1 + i);
- dwMask |= (result != BST_INDETERMINATE ? _eventorder[i] : 0);
- iFlags |= (result == BST_CHECKED ? _eventorder[i] : 0);
- }
-
- if (iFlags & GC_EVENT_ADDSTATUS)
- iFlags |= GC_EVENT_REMOVESTATUS;
-
- if (pDlg) {
- if (dwMask == 0) {
- db_unset(pDlg->m_hContact, CHAT_MODULE, "FilterFlags");
- db_unset(pDlg->m_hContact, CHAT_MODULE, "FilterMask");
- }
- else {
- db_set_dw(pDlg->m_hContact, CHAT_MODULE, "FilterFlags", iFlags);
- db_set_dw(pDlg->m_hContact, CHAT_MODULE, "FilterMask", dwMask);
- }
- }
-
- dwMask = iFlags = 0;
-
- for (i = 0; i < _countof(_eventorder); i++) {
- int result = IsDlgButtonChecked(hwndDlg, IDC_P1 + i);
- dwMask |= (result != BST_INDETERMINATE ? _eventorder[i] : 0);
- iFlags |= (result == BST_CHECKED ? _eventorder[i] : 0);
- }
-
- if (iFlags & GC_EVENT_ADDSTATUS)
- iFlags |= GC_EVENT_REMOVESTATUS;
-
- if (pDlg) {
- if (dwMask == 0) {
- db_unset(pDlg->m_hContact, CHAT_MODULE, "PopupFlags");
- db_unset(pDlg->m_hContact, CHAT_MODULE, "PopupMask");
- }
- else {
- db_set_dw(pDlg->m_hContact, CHAT_MODULE, "PopupFlags", iFlags);
- db_set_dw(pDlg->m_hContact, CHAT_MODULE, "PopupMask", dwMask);
- }
- }
-
- dwMask = iFlags = 0;
-
- for (i = 0; i < _countof(_eventorder); i++) {
- int result = IsDlgButtonChecked(hwndDlg, IDC_T1 + i);
- dwMask |= (result != BST_INDETERMINATE ? _eventorder[i] : 0);
- iFlags |= (result == BST_CHECKED ? _eventorder[i] : 0);
- }
- if (iFlags & GC_EVENT_ADDSTATUS)
- iFlags |= GC_EVENT_REMOVESTATUS;
-
- if (pDlg) {
- if (dwMask == 0) {
- db_unset(pDlg->m_hContact, CHAT_MODULE, "TrayIconFlags");
- db_unset(pDlg->m_hContact, CHAT_MODULE, "TrayIconMask");
- }
- else {
- db_set_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconFlags", iFlags);
- db_set_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconMask", dwMask);
- }
- Chat_SetFilters(pDlg->m_si);
- if (pDlg->m_iLogFilterFlags == 0 && pDlg->m_bFilterEnabled)
- pDlg->onClick_Filter(&pDlg->m_btnFilter);
- if (pDlg->m_bFilterEnabled)
- pDlg->RedrawLog();
- }
- }
- DestroyWindow(hwndDlg);
- break;
-
- case WM_DESTROY:
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
- break;
- }
- return FALSE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// subclassing for the message history display(rich edit control in which the chat history appears)
-
-static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND hwndParent = GetParent(hwnd);
- CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
-
- switch (msg) {
- case WM_NCCALCSIZE:
- return CSkin::NcCalcRichEditFrame(hwnd, pDlg, ID_EXTBKHISTORY, msg, wParam, lParam, LogSubclassProc);
-
- case WM_NCPAINT:
- return CSkin::DrawRichEditFrame(hwnd, pDlg, ID_EXTBKHISTORY, msg, wParam, lParam, LogSubclassProc);
-
- case WM_COPY:
- return Utils::WMCopyHandler(hwnd, LogSubclassProc, msg, wParam, lParam);
-
- case WM_SETCURSOR:
- if (g_Settings.bClickableNicks && (LOWORD(lParam) == HTCLIENT)) {
- POINT pt;
- GetCursorPos(&pt);
- ScreenToClient(hwnd, &pt);
- if (CheckCustomLink(hwnd, &pt, msg, wParam, lParam, FALSE)) return TRUE;
- }
- break;
-
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- case WM_RBUTTONUP:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONDBLCLK:
- if (g_Settings.bClickableNicks) {
- POINT pt = { LOWORD(lParam), HIWORD(lParam) };
- CheckCustomLink(hwnd, &pt, msg, wParam, lParam, TRUE);
- }
- break;
-
- case WM_LBUTTONUP:
- if (g_Settings.bClickableNicks) {
- POINT pt = { LOWORD(lParam), HIWORD(lParam) };
- CheckCustomLink(hwnd, &pt, msg, wParam, lParam, TRUE);
- }
- if (M.GetByte("autocopy", 1)) {
- CHARRANGE sel;
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);
- if (sel.cpMin != sel.cpMax) {
- SendMessage(hwnd, WM_COPY, 0, 0);
- sel.cpMin = sel.cpMax;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);
- SetFocus(GetDlgItem(hwndParent, IDC_MESSAGE));
- }
- }
- break;
-
- case WM_KEYDOWN:
- if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window)
- PostMessage(hwndParent, WM_CLOSE, 0, 1);
- return TRUE;
- }
- if (wParam == VK_INSERT && GetKeyState(VK_CONTROL) & 0x8000)
- return Utils::WMCopyHandler(hwnd, LogSubclassProc, msg, wParam, lParam);
- break;
-
- case WM_SYSKEYUP:
- if (wParam == VK_MENU) {
- ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_LOG);
- return 0;
- }
- break;
-
- case WM_SYSKEYDOWN:
- pDlg->m_bkeyProcessed = false;
- if (ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_LOG)) {
- pDlg->m_bkeyProcessed = true;
- return 0;
- }
- break;
-
- case WM_SYSCHAR:
- if (pDlg->m_bkeyProcessed) {
- pDlg->m_bkeyProcessed = false;
- return 0;
- }
- break;
-
- case WM_ACTIVATE:
- if (LOWORD(wParam) == WA_INACTIVE) {
- CHARRANGE sel;
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);
- if (sel.cpMin != sel.cpMax) {
- sel.cpMin = sel.cpMax;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);
- }
- }
- break;
-
- case WM_CHAR:
- bool isCtrl, isShift, isAlt;
- pDlg->KbdState(isShift, isCtrl, isAlt);
- if (wParam == 0x03 && isCtrl) // Ctrl+C
- return Utils::WMCopyHandler(hwnd, LogSubclassProc, msg, wParam, lParam);
-
- SetFocus(GetDlgItem(hwndParent, IDC_MESSAGE));
- SendDlgItemMessage(hwndParent, IDC_MESSAGE, WM_CHAR, wParam, lParam);
- break;
- }
-
- return mir_callNextSubclass(hwnd, LogSubclassProc, msg, wParam, lParam);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// subclassing for the nickname list control.It is an ownerdrawn listbox
-
-LRESULT CALLBACK CChatRoomDlg::NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND hwndParent = GetParent(hwnd);
- CChatRoomDlg *dat = (CChatRoomDlg*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
-
- switch (msg) {
- case WM_NCCALCSIZE:
- if (CSkin::m_DisableScrollbars) {
- RECT lpRect;
- GetClientRect(hwnd, &lpRect);
- LONG itemHeight = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0);
- g_cLinesPerPage = (lpRect.bottom - lpRect.top) / itemHeight;
- }
- return CSkin::NcCalcRichEditFrame(hwnd, dat, ID_EXTBKUSERLIST, msg, wParam, lParam, NicklistSubclassProc);
-
- case WM_NCPAINT:
- return CSkin::DrawRichEditFrame(hwnd, dat, ID_EXTBKUSERLIST, msg, wParam, lParam, NicklistSubclassProc);
-
- case WM_ERASEBKGND:
- {
- HDC dc = (HDC)wParam;
- if (dc) {
- int index = SendMessage(hwnd, LB_GETTOPINDEX, 0, 0);
- if (index == LB_ERR || dat->m_si->nUsersInNicklist <= 0)
- return 0;
-
- int items = dat->m_si->nUsersInNicklist - index;
- int height = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0);
-
- if (height != LB_ERR) {
- RECT rc = { 0 };
- GetClientRect(hwnd, &rc);
-
- if (rc.bottom - rc.top > items * height) {
- rc.top = items * height;
- FillRect(dc, &rc, pci->hListBkgBrush);
- }
- }
- }
- }
- return 1;
-
- case WM_MOUSEWHEEL:
- if (CSkin::m_DisableScrollbars) {
- UINT uScroll;
- short zDelta = (short)HIWORD(wParam);
- if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &uScroll, 0))
- uScroll = 3; /* default value */
-
- if (uScroll == WHEEL_PAGESCROLL)
- uScroll = g_cLinesPerPage;
- if (uScroll == 0)
- return 0;
-
- zDelta += g_iWheelCarryover; /* Accumulate wheel motion */
-
- int dLines = zDelta * (int)uScroll / WHEEL_DELTA;
-
- //Record the unused portion as the next carryover.
- g_iWheelCarryover = zDelta - dLines * WHEEL_DELTA / (int)uScroll;
-
- // scrolling.
- while (abs(dLines)) {
- if (dLines > 0) {
- SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);
- dLines--;
- }
- else {
- SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
- dLines++;
- }
- }
- return 0;
- }
- break;
-
- case WM_KEYDOWN:
- if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window)
- PostMessage(hwndParent, WM_CLOSE, 0, 1);
- return TRUE;
- }
-
- if (wParam == VK_ESCAPE || wParam == VK_UP || wParam == VK_DOWN || wParam == VK_NEXT ||
- wParam == VK_PRIOR || wParam == VK_TAB || wParam == VK_HOME || wParam == VK_END) {
- if (dat) {
- dat->m_wszSearch[0] = 0;
- dat->m_iSearchItem = -1;
- }
- }
- break;
-
- case WM_SETFOCUS:
- case WM_KILLFOCUS:
- if (dat) { // set/kill focus invalidates incremental search status
- dat->m_wszSearch[0] = 0;
- dat->m_iSearchItem = -1;
- }
- break;
-
- case WM_CHAR:
- case WM_UNICHAR:
- // simple incremental search for the user (nick) - list control
- // typing esc or movement keys will clear the current search string
- if (dat) {
- if (wParam == 27 && dat->m_wszSearch[0]) { // escape - reset everything
- dat->m_wszSearch[0] = 0;
- dat->m_iSearchItem = -1;
- break;
- }
- if (wParam == '\b' && dat->m_wszSearch[0]) // backspace
- dat->m_wszSearch[mir_wstrlen(dat->m_wszSearch) - 1] = '\0';
- else if (wParam < ' ')
- break;
- else {
- if (mir_wstrlen(dat->m_wszSearch) >= _countof(dat->m_wszSearch) - 2) {
- MessageBeep(MB_OK);
- break;
- }
- wchar_t szNew[2];
- szNew[0] = (wchar_t)wParam;
- szNew[1] = '\0';
- mir_wstrcat(dat->m_wszSearch, szNew);
- }
- if (dat->m_wszSearch[0]) {
- // iterate over the (sorted) list of nicknames and search for the
- // string we have
- int i, iItems = SendMessage(hwnd, LB_GETCOUNT, 0, 0);
- for (i = 0; i < iItems; i++) {
- USERINFO *ui = pci->UM_FindUserFromIndex(dat->m_si->pUsers, i);
- if (ui) {
- if (!wcsnicmp(ui->pszNick, dat->m_wszSearch, mir_wstrlen(dat->m_wszSearch))) {
- SendMessage(hwnd, LB_SETSEL, FALSE, -1);
- SendMessage(hwnd, LB_SETSEL, TRUE, i);
- dat->m_iSearchItem = i;
- InvalidateRect(hwnd, nullptr, FALSE);
- return 0;
- }
- }
- }
- if (i == iItems) {
- MessageBeep(MB_OK);
- dat->m_wszSearch[mir_wstrlen(dat->m_wszSearch) - 1] = '\0';
- return 0;
- }
- }
- }
- break;
-
- case WM_RBUTTONDOWN:
- {
- int iCounts = SendMessage(hwnd, LB_GETSELCOUNT, 0, 0);
- if (iCounts != LB_ERR && iCounts > 1)
- return 0;
- SendMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);
- }
- break;
-
- case WM_RBUTTONUP:
- SendMessage(hwnd, WM_LBUTTONUP, wParam, lParam);
- break;
-
- case WM_MEASUREITEM:
- {
- MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
- if (mis->CtlType == ODT_MENU)
- return Menu_MeasureItem(lParam);
- }
- return FALSE;
-
- case WM_DRAWITEM:
- {
- DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
- if (dis->CtlType == ODT_MENU)
- return Menu_DrawItem(lParam);
- }
- return FALSE;
-
- case WM_CONTEXTMENU:
- {
- SESSION_INFO *si = dat->m_si;
- if (si == nullptr)
- break;
-
- int height = 0;
- TVHITTESTINFO hti;
- hti.pt.x = GET_X_LPARAM(lParam);
- hti.pt.y = GET_Y_LPARAM(lParam);
- if (hti.pt.x == -1 && hti.pt.y == -1) {
- int index = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
- int top = SendMessage(hwnd, LB_GETTOPINDEX, 0, 0);
- height = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0);
- hti.pt.x = 4;
- hti.pt.y = (index - top) * height + 1;
- }
- else ScreenToClient(hwnd, &hti.pt);
-
- int item = (DWORD)(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y)));
- if (HIWORD(item) == 1)
- item = (DWORD)(-1);
- else
- item &= 0xFFFF;
-
- USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, item);
- if (ui) {
- HMENU hMenu = 0;
- USERINFO uinew;
- memcpy(&uinew, ui, sizeof(USERINFO));
- if (hti.pt.x == -1 && hti.pt.y == -1)
- hti.pt.y += height - 4;
- ClientToScreen(hwnd, &hti.pt);
-
- UINT uID = CreateGCMenu(hwnd, &hMenu, 0, hti.pt, si, uinew.pszUID, uinew.pszNick);
- switch (uID) {
- case 0:
- break;
-
- case 20020: // add to highlight...
- {
- THighLightEdit the = { THighLightEdit::CMD_ADD, si, ui };
- HWND hwndDlg = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_ADDHIGHLIGHT), dat->m_pContainer->m_hwnd, CMUCHighlight::dlgProcAdd, (LPARAM)&the);
- TranslateDialogDefault(hwndDlg);
-
- RECT rc, rcWnd;
- GetClientRect(dat->m_pContainer->m_hwnd, &rcWnd);
- GetWindowRect(hwndDlg, &rc);
- SetWindowPos(hwndDlg, HWND_TOP, (rcWnd.right - (rc.right - rc.left)) / 2, (rcWnd.bottom - (rc.bottom - rc.top)) / 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
- }
- break;
-
- case ID_MESS:
- dat->DoEventHook(GC_USER_PRIVMESS, ui, nullptr, 0);
- break;
-
- default:
- dat->DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID);
- break;
- }
- DestroyGCMenu(&hMenu, 1);
- return TRUE;
- }
- }
- break;
-
- case WM_MOUSEMOVE:
- Chat_HoverMouse(dat->m_si, hwnd, lParam, ServiceExists("mToolTip/HideTip"));
- break;
- }
- return mir_callNextSubclass(hwnd, NicklistSubclassProc, msg, wParam, lParam);
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
// calculate the required rectangle for a string using the given font. This is more
// precise than using GetTextExtentPoint...()
@@ -1451,11 +582,6 @@ void CChatRoomDlg::OnInitDialog()
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERX), SplitterSubclassProc);
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERY), SplitterSubclassProc);
- mir_subclassWindow(m_nickList.GetHwnd(), NicklistSubclassProc);
- mir_subclassWindow(m_log.GetHwnd(), LogSubclassProc);
-
- mir_subclassWindow(m_message.GetHwnd(), MessageSubclassProc);
- m_message.SendMsg(EM_SUBCLASSED, 0, 0);
UpdateOptions();
UpdateStatusBar();
@@ -1521,7 +647,8 @@ void CChatRoomDlg::OnDestroy()
if (m_pContainer->dwFlags & CNT_SIDEBAR)
m_pContainer->SideBar->removeSession(this);
mir_free(m_enteredText);
- SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
+
+ CSuper::OnDestroy();
}
void CChatRoomDlg::onClick_OK(CCtrlButton*)
@@ -1881,6 +1008,838 @@ void CChatRoomDlg::UpdateTitle()
}
/////////////////////////////////////////////////////////////////////////////////////////
+// subclassing for the message history display(rich edit control in which the chat history appears)
+
+LRESULT CChatRoomDlg::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_NCCALCSIZE:
+ return CSkin::NcCalcRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, nullptr);
+
+ case WM_NCPAINT:
+ return CSkin::DrawRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, nullptr);
+
+ case WM_COPY:
+ return Utils::WMCopyHandler(m_log.GetHwnd(), nullptr, msg, wParam, lParam);
+
+ case WM_SETCURSOR:
+ if (g_Settings.bClickableNicks && (LOWORD(lParam) == HTCLIENT)) {
+ POINT pt;
+ GetCursorPos(&pt);
+ ScreenToClient(m_log.GetHwnd(), &pt);
+ if (CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, FALSE)) return TRUE;
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONDBLCLK:
+ if (g_Settings.bClickableNicks) {
+ POINT pt = { LOWORD(lParam), HIWORD(lParam) };
+ CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE);
+ }
+ break;
+
+ case WM_LBUTTONUP:
+ if (g_Settings.bClickableNicks) {
+ POINT pt = { LOWORD(lParam), HIWORD(lParam) };
+ CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE);
+ }
+ if (M.GetByte("autocopy", 1)) {
+ CHARRANGE sel;
+ SendMessage(m_log.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)&sel);
+ if (sel.cpMin != sel.cpMax) {
+ SendMessage(m_log.GetHwnd(), WM_COPY, 0, 0);
+ sel.cpMin = sel.cpMax;
+ SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel);
+ SetFocus(m_message.GetHwnd());
+ }
+ }
+ break;
+
+ case WM_KEYDOWN:
+ if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window)
+ PostMessage(m_hwnd, WM_CLOSE, 0, 1);
+ return TRUE;
+ }
+ if (wParam == VK_INSERT && GetKeyState(VK_CONTROL) & 0x8000)
+ return Utils::WMCopyHandler(m_log.GetHwnd(), nullptr, msg, wParam, lParam);
+ break;
+
+ case WM_SYSKEYUP:
+ if (wParam == VK_MENU) {
+ ProcessHotkeysByMsgFilter(m_log.GetHwnd(), msg, wParam, lParam, IDC_LOG);
+ return 0;
+ }
+ break;
+
+ case WM_SYSKEYDOWN:
+ m_bkeyProcessed = false;
+ if (ProcessHotkeysByMsgFilter(m_log.GetHwnd(), msg, wParam, lParam, IDC_LOG)) {
+ m_bkeyProcessed = true;
+ return 0;
+ }
+ break;
+
+ case WM_SYSCHAR:
+ if (m_bkeyProcessed) {
+ m_bkeyProcessed = false;
+ return 0;
+ }
+ break;
+
+ case WM_ACTIVATE:
+ if (LOWORD(wParam) == WA_INACTIVE) {
+ CHARRANGE sel;
+ SendMessage(m_log.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)&sel);
+ if (sel.cpMin != sel.cpMax) {
+ sel.cpMin = sel.cpMax;
+ SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel);
+ }
+ }
+ break;
+
+ case WM_CHAR:
+ bool isCtrl, isShift, isAlt;
+ KbdState(isShift, isCtrl, isAlt);
+ if (wParam == 0x03 && isCtrl) // Ctrl+C
+ return Utils::WMCopyHandler(m_log.GetHwnd(), nullptr, msg, wParam, lParam);
+
+ SetFocus(m_message.GetHwnd());
+ m_message.SendMsg(WM_CHAR, wParam, lParam);
+ break;
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// subclassing for the message input control(a richedit text control)
+
+LRESULT CChatRoomDlg::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ if (m_bkeyProcessed && (msg == WM_KEYUP)) {
+ GetKeyboardState(kstate);
+ if (!(kstate[VK_CONTROL] & 0x80) && !(kstate[VK_SHIFT] & 0x80))
+ m_bkeyProcessed = false;
+ return 0;
+ }
+
+ switch (msg) {
+ case WM_NCCALCSIZE:
+ return CSkin::NcCalcRichEditFrame(m_message.GetHwnd(), this, ID_EXTBKINPUTAREA, msg, wParam, lParam, nullptr);
+
+ case WM_NCPAINT:
+ return CSkin::DrawRichEditFrame(m_message.GetHwnd(), this, ID_EXTBKINPUTAREA, msg, wParam, lParam, nullptr);
+
+ case WM_CONTEXTMENU:
+ POINT pt;
+ GetCursorPos(&pt);
+ {
+ HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT));
+ HMENU hSubMenu = GetSubMenu(hMenu, 2);
+ RemoveMenu(hSubMenu, 9, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 8, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
+
+ MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
+ EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | ((mi && mi->bBold) ? MF_ENABLED : MF_GRAYED));
+ TranslateMenu(hSubMenu);
+
+ CHARRANGE sel, all = { 0, -1 };
+ m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel);
+ if (sel.cpMin == sel.cpMax) {
+ EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(hSubMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED);
+ }
+
+ MessageWindowPopupData mwpd = { sizeof(mwpd) };
+ mwpd.uType = MSG_WINDOWPOPUP_SHOWING;
+ mwpd.uFlags = MSG_WINDOWPOPUP_INPUT;
+ mwpd.hContact = m_hContact;
+ mwpd.hwnd = m_message.GetHwnd();
+ mwpd.hMenu = hSubMenu;
+ mwpd.pt = pt;
+ NotifyEventHooks(PluginConfig.m_event_MsgPopup, 0, (LPARAM)&mwpd);
+
+ int iSelection = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr);
+
+ mwpd.selection = iSelection;
+ mwpd.uType = MSG_WINDOWPOPUP_SELECTED;
+ NotifyEventHooks(PluginConfig.m_event_MsgPopup, 0, (LPARAM)&mwpd);
+
+ switch (iSelection) {
+ case IDM_COPY:
+ m_message.SendMsg(WM_COPY, 0, 0);
+ break;
+ case IDM_CUT:
+ m_message.SendMsg(WM_CUT, 0, 0);
+ break;
+ case IDM_PASTE:
+ case IDM_PASTEFORMATTED:
+ m_message.SendMsg(EM_PASTESPECIAL, (iSelection == IDM_PASTE) ? CF_UNICODETEXT : 0, 0);
+ break;
+ case IDM_COPYALL:
+ m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all);
+ m_message.SendMsg(WM_COPY, 0, 0);
+ m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel);
+ break;
+ case IDM_SELECTALL:
+ m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all);
+ break;
+ }
+ DestroyMenu(hMenu);
+ }
+ return TRUE;
+
+ case WM_MOUSEWHEEL:
+ if (DM_MouseWheelHandler(wParam, lParam) == 0)
+ return 0;
+
+ m_iLastEnterTime = 0;
+ break;
+
+ case WM_SYSKEYUP:
+ if (wParam == VK_MENU) {
+ ProcessHotkeysByMsgFilter(m_message.GetHwnd(), msg, wParam, lParam, IDC_MESSAGE);
+ return 0;
+ }
+ break;
+
+ case WM_SYSKEYDOWN:
+ m_bkeyProcessed = false;
+ if (ProcessHotkeysByMsgFilter(m_message.GetHwnd(), msg, wParam, lParam, IDC_MESSAGE)) {
+ m_bkeyProcessed = true;
+ return 0;
+ }
+ break;
+
+ case WM_SYSCHAR:
+ if (m_bkeyProcessed) {
+ m_bkeyProcessed = false; // preceeding key event has been processed by miranda hotkey service
+ return 0;
+ }
+
+ if ((wParam >= '0' && wParam <= '9') && (GetKeyState(VK_MENU) & 0x8000)) { // ALT-1 -> ALT-0 direct tab selection
+ BYTE bChar = (BYTE)wParam;
+ int iIndex = (bChar == '0') ? 10 : bChar - (BYTE)'0';
+ SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_BY_INDEX, (LPARAM)iIndex);
+ return 0;
+ }
+ break;
+
+ case WM_CHAR:
+ bool isShift, isAlt, isCtrl;
+ KbdState(isShift, isCtrl, isAlt);
+
+ if (PluginConfig.m_bSoundOnTyping && !isAlt && !isCtrl && !(m_pContainer->dwFlags & CNT_NOSOUND) && wParam != VK_ESCAPE && !(wParam == VK_TAB && PluginConfig.m_bAllowTab))
+ SkinPlaySound("SoundOnTyping");
+
+ if (isCtrl && !isAlt && !isShift)
+ switch (wParam) {
+ case 0x17:
+ PostMessage(m_hwnd, WM_CLOSE, 0, 1);
+ return 0;
+ }
+
+ break;
+
+ case WM_KEYDOWN:
+ KbdState(isShift, isCtrl, isAlt);
+
+ // sound on typing..
+ if (PluginConfig.m_bSoundOnTyping && !isAlt && wParam == VK_DELETE)
+ SkinPlaySound("SoundOnTyping");
+
+ if (ProcessHotkeys(wParam, isShift, isCtrl, isAlt))
+ return true;
+
+ if (wParam == VK_INSERT && !isShift && !isCtrl && !isAlt) {
+ m_bInsertMode = !m_bInsertMode;
+ m_message.OnChange(&m_message);
+ }
+ if (wParam == VK_CAPITAL || wParam == VK_NUMLOCK)
+ m_message.OnChange(&m_message);
+
+ if (isCtrl && isAlt && !isShift) {
+ switch (wParam) {
+ case VK_UP:
+ case VK_DOWN:
+ case VK_PRIOR:
+ case VK_NEXT:
+ case VK_HOME:
+ case VK_END:
+ WPARAM wp = 0;
+
+ if (wParam == VK_UP)
+ wp = MAKEWPARAM(SB_LINEUP, 0);
+ else if (wParam == VK_PRIOR)
+ wp = MAKEWPARAM(SB_PAGEUP, 0);
+ else if (wParam == VK_NEXT)
+ wp = MAKEWPARAM(SB_PAGEDOWN, 0);
+ else if (wParam == VK_HOME)
+ wp = MAKEWPARAM(SB_TOP, 0);
+ else if (wParam == VK_END) {
+ DM_ScrollToBottom(0, 0);
+ return 0;
+ }
+ else if (wParam == VK_DOWN)
+ wp = MAKEWPARAM(SB_LINEDOWN, 0);
+
+ SendDlgItemMessage(m_hwnd, IDC_LOG, WM_VSCROLL, wp, 0);
+ return 0;
+ }
+ }
+
+ if (wParam == VK_RETURN) {
+ if (isShift) {
+ if (PluginConfig.m_bSendOnShiftEnter) {
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ break;
+ }
+ if ((isCtrl && !isShift) ^ (0 != PluginConfig.m_bSendOnEnter)) {
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ if (!PluginConfig.m_bSendOnEnter && !PluginConfig.m_bSendOnDblEnter)
+ break;
+ if (isCtrl)
+ break;
+
+ if (PluginConfig.m_bSendOnDblEnter) {
+ if (m_iLastEnterTime + 2 < time(nullptr)) {
+ m_iLastEnterTime = time(nullptr);
+ break;
+ }
+
+ m_message.SendMsg(WM_KEYDOWN, VK_BACK, 0);
+ m_message.SendMsg(WM_KEYUP, VK_BACK, 0);
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ else m_iLastEnterTime = 0;
+
+ if ((wParam == VK_NEXT && isCtrl && !isShift) || (wParam == VK_TAB && isCtrl && !isShift)) { // CTRL-TAB (switch tab/window)
+ SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_NEXT, 0);
+ return TRUE;
+ }
+
+ if ((wParam == VK_PRIOR && isCtrl && !isShift) || (wParam == VK_TAB && isCtrl && isShift)) { // CTRL_SHIFT-TAB (switch tab/window)
+ SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_PREV, 0);
+ return TRUE;
+ }
+ if (wParam == VK_TAB && !isCtrl && !isShift) { // tab-autocomplete
+ m_message.SendMsg(WM_SETREDRAW, FALSE, 0);
+ bool fCompleted = TabAutoComplete();
+ m_message.SendMsg(WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE);
+ if (!fCompleted && !PluginConfig.m_bAllowTab) {
+ if ((GetSendButtonState(GetHwnd()) != PBS_DISABLED))
+ SetFocus(GetDlgItem(GetHwnd(), IDOK));
+ else
+ SetFocus(GetDlgItem(GetHwnd(), IDC_LOG));
+ }
+ return 0;
+ }
+ if (wParam != VK_RIGHT && wParam != VK_LEFT) {
+ mir_free(m_wszSearchQuery);
+ m_wszSearchQuery = nullptr;
+ mir_free(m_wszSearchResult);
+ m_wszSearchResult = nullptr;
+ }
+
+ if (wParam == VK_F4 && isCtrl && !isAlt) { // ctrl-F4 (close tab)
+ SendMessage(m_hwnd, WM_COMMAND, MAKEWPARAM(IDC_CLOSE, BN_CLICKED), 0);
+ return 0;
+ }
+
+ if (wParam == VK_NEXT || wParam == VK_PRIOR) {
+ HWND htemp = m_hwnd;
+ SendDlgItemMessage(htemp, IDC_LOG, msg, wParam, lParam);
+ m_iLastEnterTime = 0;
+ return 0;
+ }
+
+ if (wParam == VK_UP && isCtrl && !isAlt) {
+ char *lpPrevCmd = pci->SM_GetPrevCommand(m_si->ptszID, m_si->pszModule);
+
+ if (!m_si->lpCurrentCommand || !m_si->lpCurrentCommand->last) {
+ // Next command is not defined. It means currently entered text is not saved in the history and it
+ // need to be saved in the window context.
+ char *enteredText = Message_GetFromStream(m_hwnd);
+ if (m_enteredText)
+ mir_free(m_enteredText);
+
+ m_enteredText = enteredText;
+ }
+
+ m_message.SendMsg(WM_SETREDRAW, FALSE, 0);
+
+ LOGFONTA lf;
+ LoadLogfont(FONTSECTION_IM, MSGFONTID_MESSAGEAREA, &lf, nullptr, FONTMODULE);
+
+ SETTEXTEX ste;
+ ste.flags = ST_DEFAULT;
+ ste.codepage = CP_ACP;
+ if (lpPrevCmd)
+ m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd);
+ else
+ m_message.SetText(L"");
+
+ GETTEXTLENGTHEX gtl = { 0 };
+ gtl.flags = GTL_PRECISE;
+ gtl.codepage = CP_ACP;
+ int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)&gtl, 0);
+ m_message.SendMsg(EM_SCROLLCARET, 0, 0);
+ m_message.SendMsg(WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE);
+ m_message.SendMsg(EM_SETSEL, iLen, iLen);
+ m_iLastEnterTime = 0;
+ return 0;
+ }
+
+ if (wParam == VK_DOWN && isCtrl && !isAlt) {
+ m_message.SendMsg(WM_SETREDRAW, FALSE, 0);
+
+ SETTEXTEX ste;
+ ste.flags = ST_DEFAULT;
+ ste.codepage = CP_ACP;
+
+ char *lpPrevCmd = pci->SM_GetNextCommand(m_si->ptszID, m_si->pszModule);
+ if (lpPrevCmd)
+ m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd);
+ else if (m_enteredText) {
+ // If we cannot load the message from history, load the last edited text.
+ m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)m_enteredText);
+ mir_free(m_enteredText);
+ m_enteredText = nullptr;
+ }
+
+ GETTEXTLENGTHEX gtl = { 0 };
+ gtl.flags = GTL_PRECISE;
+ gtl.codepage = CP_ACP;
+ int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)&gtl, 0);
+ m_message.SendMsg(EM_SCROLLCARET, 0, 0);
+ m_message.SendMsg(WM_SETREDRAW, TRUE, 0);
+ RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE);
+ m_message.SendMsg(EM_SETSEL, iLen, iLen);
+ m_iLastEnterTime = 0;
+ return 0;
+ }
+ // fall through
+
+ case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_KILLFOCUS:
+ m_iLastEnterTime = 0;
+ break;
+
+ case WM_KEYUP:
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ RefreshButtonStatus();
+ break;
+
+ case WM_INPUTLANGCHANGE:
+ if (PluginConfig.m_bAutoLocaleSupport && GetFocus() == m_message.GetHwnd() && m_pContainer->m_hwndActive == m_hwnd && GetForegroundWindow() == m_pContainer->m_hwnd && GetActiveWindow() == m_pContainer->m_hwnd) {
+ DM_SaveLocale(wParam, lParam);
+ m_message.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_message.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
+ return 1;
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ return !CSkin::m_skinEnabled;
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// subclassing for the nickname list control.It is an ownerdrawn listbox
+
+LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_NCCALCSIZE:
+ if (CSkin::m_DisableScrollbars) {
+ RECT lpRect;
+ GetClientRect(m_nickList.GetHwnd(), &lpRect);
+ LONG itemHeight = m_nickList.SendMsg(LB_GETITEMHEIGHT, 0, 0);
+ g_cLinesPerPage = (lpRect.bottom - lpRect.top) / itemHeight;
+ }
+ return CSkin::NcCalcRichEditFrame(m_nickList.GetHwnd(), this, ID_EXTBKUSERLIST, msg, wParam, lParam, nullptr);
+
+ case WM_NCPAINT:
+ return CSkin::DrawRichEditFrame(m_nickList.GetHwnd(), this, ID_EXTBKUSERLIST, msg, wParam, lParam, nullptr);
+
+ case WM_ERASEBKGND:
+ {
+ HDC dc = (HDC)wParam;
+ if (dc) {
+ int index = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0);
+ if (index == LB_ERR || m_si->nUsersInNicklist <= 0)
+ return 0;
+
+ int items = m_si->nUsersInNicklist - index;
+ int height = m_nickList.SendMsg(LB_GETITEMHEIGHT, 0, 0);
+
+ if (height != LB_ERR) {
+ RECT rc = { 0 };
+ GetClientRect(m_nickList.GetHwnd(), &rc);
+
+ if (rc.bottom - rc.top > items * height) {
+ rc.top = items * height;
+ FillRect(dc, &rc, pci->hListBkgBrush);
+ }
+ }
+ }
+ }
+ return 1;
+
+ case WM_MOUSEWHEEL:
+ if (CSkin::m_DisableScrollbars) {
+ UINT uScroll;
+ short zDelta = (short)HIWORD(wParam);
+ if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &uScroll, 0))
+ uScroll = 3; /* default value */
+
+ if (uScroll == WHEEL_PAGESCROLL)
+ uScroll = g_cLinesPerPage;
+ if (uScroll == 0)
+ return 0;
+
+ zDelta += g_iWheelCarryover; /* Accumulate wheel motion */
+
+ int dLines = zDelta * (int)uScroll / WHEEL_DELTA;
+
+ //Record the unused portion as the next carryover.
+ g_iWheelCarryover = zDelta - dLines * WHEEL_DELTA / (int)uScroll;
+
+ // scrolling.
+ while (abs(dLines)) {
+ if (dLines > 0) {
+ m_nickList.SendMsg(WM_VSCROLL, SB_LINEUP, 0);
+ dLines--;
+ }
+ else {
+ m_nickList.SendMsg(WM_VSCROLL, SB_LINEDOWN, 0);
+ dLines++;
+ }
+ }
+ return 0;
+ }
+ break;
+
+ case WM_KEYDOWN:
+ if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window)
+ PostMessage(m_hwnd, WM_CLOSE, 0, 1);
+ return TRUE;
+ }
+
+ if (wParam == VK_ESCAPE || wParam == VK_UP || wParam == VK_DOWN || wParam == VK_NEXT || wParam == VK_PRIOR || wParam == VK_TAB || wParam == VK_HOME || wParam == VK_END) {
+ m_wszSearch[0] = 0;
+ m_iSearchItem = -1;
+ }
+ break;
+
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
+ m_wszSearch[0] = 0;
+ m_iSearchItem = -1;
+ break;
+
+ case WM_CHAR:
+ case WM_UNICHAR:
+ // simple incremental search for the user (nick) - list control
+ // typing esc or movement keys will clear the current search string
+ if (wParam == 27 && m_wszSearch[0]) { // escape - reset everything
+ m_wszSearch[0] = 0;
+ m_iSearchItem = -1;
+ break;
+ }
+ if (wParam == '\b' && m_wszSearch[0]) // backspace
+ m_wszSearch[mir_wstrlen(m_wszSearch) - 1] = '\0';
+ else if (wParam < ' ')
+ break;
+ else {
+ if (mir_wstrlen(m_wszSearch) >= _countof(m_wszSearch) - 2) {
+ MessageBeep(MB_OK);
+ break;
+ }
+ wchar_t szNew[2];
+ szNew[0] = (wchar_t)wParam;
+ szNew[1] = '\0';
+ mir_wstrcat(m_wszSearch, szNew);
+ }
+ if (m_wszSearch[0]) {
+ // iterate over the (sorted) list of nicknames and search for the
+ // string we have
+ int i, iItems = m_nickList.SendMsg(LB_GETCOUNT, 0, 0);
+ for (i = 0; i < iItems; i++) {
+ USERINFO *ui = pci->UM_FindUserFromIndex(m_si->pUsers, i);
+ if (ui) {
+ if (!wcsnicmp(ui->pszNick, m_wszSearch, mir_wstrlen(m_wszSearch))) {
+ m_nickList.SendMsg(LB_SETSEL, FALSE, -1);
+ m_nickList.SendMsg(LB_SETSEL, TRUE, i);
+ m_iSearchItem = i;
+ InvalidateRect(m_nickList.GetHwnd(), nullptr, FALSE);
+ return 0;
+ }
+ }
+ }
+ if (i == iItems) {
+ MessageBeep(MB_OK);
+ m_wszSearch[mir_wstrlen(m_wszSearch) - 1] = '\0';
+ return 0;
+ }
+ }
+ break;
+
+ case WM_RBUTTONDOWN:
+ {
+ int iCounts = m_nickList.SendMsg(LB_GETSELCOUNT, 0, 0);
+ if (iCounts != LB_ERR && iCounts > 1)
+ return 0;
+ m_nickList.SendMsg(WM_LBUTTONDOWN, wParam, lParam);
+ }
+ break;
+
+ case WM_RBUTTONUP:
+ m_nickList.SendMsg(WM_LBUTTONUP, wParam, lParam);
+ break;
+
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
+ if (mis->CtlType == ODT_MENU)
+ return Menu_MeasureItem(lParam);
+ }
+ return FALSE;
+
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
+ if (dis->CtlType == ODT_MENU)
+ return Menu_DrawItem(lParam);
+ }
+ return FALSE;
+
+ case WM_CONTEXTMENU:
+ {
+ SESSION_INFO *si = m_si;
+ if (si == nullptr)
+ break;
+
+ int height = 0;
+ TVHITTESTINFO hti;
+ hti.pt.x = GET_X_LPARAM(lParam);
+ hti.pt.y = GET_Y_LPARAM(lParam);
+ if (hti.pt.x == -1 && hti.pt.y == -1) {
+ int index = m_nickList.SendMsg(LB_GETCURSEL, 0, 0);
+ int top = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0);
+ height = m_nickList.SendMsg(LB_GETITEMHEIGHT, 0, 0);
+ hti.pt.x = 4;
+ hti.pt.y = (index - top) * height + 1;
+ }
+ else ScreenToClient(m_nickList.GetHwnd(), &hti.pt);
+
+ int item = (DWORD)(m_nickList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y)));
+ if (HIWORD(item) == 1)
+ item = (DWORD)(-1);
+ else
+ item &= 0xFFFF;
+
+ USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, item);
+ if (ui) {
+ HMENU hMenu = 0;
+ USERINFO uinew;
+ memcpy(&uinew, ui, sizeof(USERINFO));
+ if (hti.pt.x == -1 && hti.pt.y == -1)
+ hti.pt.y += height - 4;
+ ClientToScreen(m_nickList.GetHwnd(), &hti.pt);
+
+ UINT uID = CreateGCMenu(m_nickList.GetHwnd(), &hMenu, 0, hti.pt, si, uinew.pszUID, uinew.pszNick);
+ switch (uID) {
+ case 0:
+ break;
+
+ case 20020: // add to highlight...
+ {
+ THighLightEdit the = { THighLightEdit::CMD_ADD, si, ui };
+ HWND hwndDlg = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_ADDHIGHLIGHT), m_pContainer->m_hwnd, CMUCHighlight::dlgProcAdd, (LPARAM)&the);
+ TranslateDialogDefault(hwndDlg);
+
+ RECT rc, rcWnd;
+ GetClientRect(m_pContainer->m_hwnd, &rcWnd);
+ GetWindowRect(hwndDlg, &rc);
+ SetWindowPos(hwndDlg, HWND_TOP, (rcWnd.right - (rc.right - rc.left)) / 2, (rcWnd.bottom - (rc.bottom - rc.top)) / 2, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+ }
+ break;
+
+ case ID_MESS:
+ DoEventHook(GC_USER_PRIVMESS, ui, nullptr, 0);
+ break;
+
+ default:
+ DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID);
+ break;
+ }
+ DestroyGCMenu(&hMenu, 1);
+ return TRUE;
+ }
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ Chat_HoverMouse(m_si, m_nickList.GetHwnd(), lParam, ServiceExists("mToolTip/HideTip"));
+ break;
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// subclassing for the message filter dialog (set and configure event filters for the
+// current session
+
+static UINT _eventorder[] =
+{
+ GC_EVENT_ACTION,
+ GC_EVENT_MESSAGE,
+ GC_EVENT_NICK,
+ GC_EVENT_JOIN,
+ GC_EVENT_PART,
+ GC_EVENT_TOPIC,
+ GC_EVENT_ADDSTATUS,
+ GC_EVENT_INFORMATION,
+ GC_EVENT_QUIT,
+ GC_EVENT_KICK,
+ GC_EVENT_NOTICE
+};
+
+INT_PTR CALLBACK CChatRoomDlg::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ pDlg = (CChatRoomDlg*)lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
+ {
+ DWORD dwMask = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "FilterMask", 0);
+ DWORD dwFlags = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "FilterFlags", 0);
+
+ DWORD dwPopupMask = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "PopupMask", 0);
+ DWORD dwPopupFlags = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "PopupFlags", 0);
+
+ DWORD dwTrayMask = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconMask", 0);
+ DWORD dwTrayFlags = db_get_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconFlags", 0);
+
+ for (int i = 0; i < _countof(_eventorder); i++) {
+ CheckDlgButton(hwndDlg, IDC_1 + i, dwMask & _eventorder[i] ? (dwFlags & _eventorder[i] ? BST_CHECKED : BST_UNCHECKED) : BST_INDETERMINATE);
+ CheckDlgButton(hwndDlg, IDC_P1 + i, dwPopupMask & _eventorder[i] ? (dwPopupFlags & _eventorder[i] ? BST_CHECKED : BST_UNCHECKED) : BST_INDETERMINATE);
+ CheckDlgButton(hwndDlg, IDC_T1 + i, dwTrayMask & _eventorder[i] ? (dwTrayFlags & _eventorder[i] ? BST_CHECKED : BST_UNCHECKED) : BST_INDETERMINATE);
+ }
+ }
+ return FALSE;
+
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ SetTextColor((HDC)wParam, RGB(60, 60, 150));
+ SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
+ return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
+
+ case WM_CLOSE:
+ if (wParam == 1 && lParam == 1) {
+ int iFlags = 0, i;
+ DWORD dwMask = 0;
+
+ for (i = 0; i < _countof(_eventorder); i++) {
+ int result = IsDlgButtonChecked(hwndDlg, IDC_1 + i);
+ dwMask |= (result != BST_INDETERMINATE ? _eventorder[i] : 0);
+ iFlags |= (result == BST_CHECKED ? _eventorder[i] : 0);
+ }
+
+ if (iFlags & GC_EVENT_ADDSTATUS)
+ iFlags |= GC_EVENT_REMOVESTATUS;
+
+ if (pDlg) {
+ if (dwMask == 0) {
+ db_unset(pDlg->m_hContact, CHAT_MODULE, "FilterFlags");
+ db_unset(pDlg->m_hContact, CHAT_MODULE, "FilterMask");
+ }
+ else {
+ db_set_dw(pDlg->m_hContact, CHAT_MODULE, "FilterFlags", iFlags);
+ db_set_dw(pDlg->m_hContact, CHAT_MODULE, "FilterMask", dwMask);
+ }
+ }
+
+ dwMask = iFlags = 0;
+
+ for (i = 0; i < _countof(_eventorder); i++) {
+ int result = IsDlgButtonChecked(hwndDlg, IDC_P1 + i);
+ dwMask |= (result != BST_INDETERMINATE ? _eventorder[i] : 0);
+ iFlags |= (result == BST_CHECKED ? _eventorder[i] : 0);
+ }
+
+ if (iFlags & GC_EVENT_ADDSTATUS)
+ iFlags |= GC_EVENT_REMOVESTATUS;
+
+ if (pDlg) {
+ if (dwMask == 0) {
+ db_unset(pDlg->m_hContact, CHAT_MODULE, "PopupFlags");
+ db_unset(pDlg->m_hContact, CHAT_MODULE, "PopupMask");
+ }
+ else {
+ db_set_dw(pDlg->m_hContact, CHAT_MODULE, "PopupFlags", iFlags);
+ db_set_dw(pDlg->m_hContact, CHAT_MODULE, "PopupMask", dwMask);
+ }
+ }
+
+ dwMask = iFlags = 0;
+
+ for (i = 0; i < _countof(_eventorder); i++) {
+ int result = IsDlgButtonChecked(hwndDlg, IDC_T1 + i);
+ dwMask |= (result != BST_INDETERMINATE ? _eventorder[i] : 0);
+ iFlags |= (result == BST_CHECKED ? _eventorder[i] : 0);
+ }
+ if (iFlags & GC_EVENT_ADDSTATUS)
+ iFlags |= GC_EVENT_REMOVESTATUS;
+
+ if (pDlg) {
+ if (dwMask == 0) {
+ db_unset(pDlg->m_hContact, CHAT_MODULE, "TrayIconFlags");
+ db_unset(pDlg->m_hContact, CHAT_MODULE, "TrayIconMask");
+ }
+ else {
+ db_set_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconFlags", iFlags);
+ db_set_dw(pDlg->m_hContact, CHAT_MODULE, "TrayIconMask", dwMask);
+ }
+ Chat_SetFilters(pDlg->m_si);
+ if (pDlg->m_iLogFilterFlags == 0 && pDlg->m_bFilterEnabled)
+ pDlg->onClick_Filter(&pDlg->m_btnFilter);
+ if (pDlg->m_bFilterEnabled)
+ pDlg->RedrawLog();
+ }
+ }
+ DestroyWindow(hwndDlg);
+ break;
+
+ case WM_DESTROY:
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
+ break;
+ }
+ return FALSE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
diff --git a/plugins/TabSRMM/src/msgdialog.cpp b/plugins/TabSRMM/src/msgdialog.cpp
index 32ebdcf0ee..ba1b37c796 100644
--- a/plugins/TabSRMM/src/msgdialog.cpp
+++ b/plugins/TabSRMM/src/msgdialog.cpp
@@ -428,339 +428,6 @@ void TSAPI SetDialogToType(HWND hwndDlg)
dat->m_pPanel.Configure();
}
-static LRESULT CALLBACK MessageLogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- HWND hwndParent = GetParent(hwnd);
- CSrmmWindow *mwdat = (CSrmmWindow*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
- bool isCtrl, isShift, isAlt;
-
- switch (msg) {
- case WM_KILLFOCUS:
- if (wParam != (WPARAM)hwnd && 0 != wParam) {
- CHARRANGE cr;
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&cr);
- if (cr.cpMax != cr.cpMin) {
- cr.cpMin = cr.cpMax;
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&cr);
- }
- }
- break;
-
- case WM_CHAR:
- mwdat->KbdState(isShift, isCtrl, isAlt);
- if (wParam == 0x03 && isCtrl) // Ctrl+C
- return Utils::WMCopyHandler(hwnd, MessageLogSubclassProc, msg, wParam, lParam);
- if (wParam == 0x11 && isCtrl)
- SendMessage(mwdat->GetHwnd(), WM_COMMAND, IDC_QUOTE, 0);
- break;
-
- case WM_SYSKEYUP:
- if (wParam == VK_MENU) {
- ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_LOG);
- return 0;
- }
- break;
-
- case WM_SYSKEYDOWN:
- mwdat->m_bkeyProcessed = false;
- if (ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_LOG)) {
- mwdat->m_bkeyProcessed = true;
- return 0;
- }
- break;
-
- case WM_SYSCHAR:
- if (mwdat->m_bkeyProcessed) {
- mwdat->m_bkeyProcessed = false;
- return 0;
- }
- break;
-
- case WM_KEYDOWN:
- mwdat->KbdState(isShift, isCtrl, isAlt);
- if (wParam == VK_INSERT && isCtrl)
- return Utils::WMCopyHandler(hwnd, MessageLogSubclassProc, msg, wParam, lParam);
- break;
-
- case WM_COPY:
- return Utils::WMCopyHandler(hwnd, MessageLogSubclassProc, msg, wParam, lParam);
-
- case WM_NCCALCSIZE:
- return CSkin::NcCalcRichEditFrame(hwnd, mwdat, ID_EXTBKHISTORY, msg, wParam, lParam, MessageLogSubclassProc);
-
- case WM_NCPAINT:
- return CSkin::DrawRichEditFrame(hwnd, mwdat, ID_EXTBKHISTORY, msg, wParam, lParam, MessageLogSubclassProc);
-
- case WM_CONTEXTMENU:
- POINT pt;
-
- if (lParam == 0xFFFFFFFF) {
- CHARRANGE sel;
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);
- SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax);
- ClientToScreen(hwnd, &pt);
- }
- else {
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- }
-
- ShowPopupMenu(mwdat, IDC_LOG, hwnd, pt);
- return TRUE;
- }
-
- return mir_callNextSubclass(hwnd, MessageLogSubclassProc, msg, wParam, lParam);
-}
-
-static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- bool isCtrl, isShift, isAlt;
- HWND hwndParent = GetParent(hwnd);
- CSrmmWindow *mwdat = (CSrmmWindow*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
- if (mwdat == nullptr)
- return 0;
-
- // prevent the rich edit from switching text direction or keyboard layout when
- // using hotkeys with ctrl-shift or alt-shift modifiers
- if (mwdat->m_bkeyProcessed && (msg == WM_KEYUP)) {
- GetKeyboardState(mwdat->kstate);
- if (mwdat->kstate[VK_CONTROL] & 0x80 || mwdat->kstate[VK_SHIFT] & 0x80)
- return 0;
-
- mwdat->m_bkeyProcessed = false;
- return 0;
- }
-
- switch (msg) {
- case WM_NCCALCSIZE:
- return CSkin::NcCalcRichEditFrame(hwnd, mwdat, ID_EXTBKINPUTAREA, msg, wParam, lParam, MessageEditSubclassProc);
-
- case WM_NCPAINT:
- return CSkin::DrawRichEditFrame(hwnd, mwdat, ID_EXTBKINPUTAREA, msg, wParam, lParam, MessageEditSubclassProc);
-
- case WM_DROPFILES:
- SendMessage(hwndParent, WM_DROPFILES, (WPARAM)wParam, (LPARAM)lParam);
- return 0;
-
- case WM_CHAR:
- mwdat->KbdState(isShift, isCtrl, isAlt);
-
- if (PluginConfig.m_bSoundOnTyping && !isAlt && !isCtrl && !(mwdat->m_pContainer->dwFlags & CNT_NOSOUND) && wParam != VK_ESCAPE && !(wParam == VK_TAB && PluginConfig.m_bAllowTab))
- SkinPlaySound("SoundOnTyping");
-
- if (isCtrl && !isAlt) {
- switch (wParam) {
- case 0x02: // bold
- if (mwdat->m_SendFormat)
- SendMessage(hwndParent, WM_COMMAND, MAKELONG(IDC_SRMM_BOLD, IDC_MESSAGE), 0);
- return 0;
- case 0x09:
- if (mwdat->m_SendFormat)
- SendMessage(hwndParent, WM_COMMAND, MAKELONG(IDC_SRMM_ITALICS, IDC_MESSAGE), 0);
- return 0;
- case 21:
- if (mwdat->m_SendFormat)
- SendMessage(hwndParent, WM_COMMAND, MAKELONG(IDC_SRMM_UNDERLINE, IDC_MESSAGE), 0);
- return 0;
- case 0x0b:
- SetWindowText(hwnd, L"");
- return 0;
- }
- }
- break;
-
- case WM_MOUSEWHEEL:
- if (mwdat->DM_MouseWheelHandler(wParam, lParam) == 0)
- return 0;
- break;
-
- case EM_PASTESPECIAL:
- case WM_PASTE:
- if (OpenClipboard(hwnd)) {
- HANDLE hClip = GetClipboardData(CF_TEXT);
- if (hClip) {
- if ((int)mir_strlen((char*)hClip) > mwdat->m_nMax) {
- wchar_t szBuffer[512];
- if (M.GetByte("autosplit", 0))
- mir_snwprintf(szBuffer, TranslateT("WARNING: The message you are trying to paste exceeds the message size limit for the active protocol. It will be sent in chunks of max %d characters"), mwdat->m_nMax - 10);
- else
- mir_snwprintf(szBuffer, TranslateT("The message you are trying to paste exceeds the message size limit for the active protocol. Only the first %d characters will be sent."), mwdat->m_nMax);
- SendMessage(hwndParent, DM_ACTIVATETOOLTIP, IDC_MESSAGE, (LPARAM)szBuffer);
- }
- }
- else if (hClip = GetClipboardData(CF_BITMAP))
- mwdat->SendHBitmapAsFile((HBITMAP)hClip);
-
- CloseClipboard();
- }
- break;
-
- case WM_KEYDOWN:
- mwdat->KbdState(isShift, isCtrl, isAlt);
-
- if (PluginConfig.m_bSoundOnTyping && !isAlt && !(mwdat->m_pContainer->dwFlags & CNT_NOSOUND) && wParam == VK_DELETE)
- SkinPlaySound("SoundOnTyping");
-
- if (wParam == VK_INSERT && !isShift && !isCtrl && !isAlt) {
- mwdat->m_bInsertMode = !mwdat->m_bInsertMode;
- SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM)hwnd);
- }
- if (wParam == VK_CAPITAL || wParam == VK_NUMLOCK)
- SendMessage(hwndParent, WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(hwnd), EN_CHANGE), (LPARAM)hwnd);
-
- if (wParam == VK_RETURN) {
- if (mwdat->m_bEditNotesActive)
- break;
-
- if (isShift) {
- if (PluginConfig.m_bSendOnShiftEnter) {
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- else break;
- }
- if ((isCtrl && !isShift) ^ (0 != PluginConfig.m_bSendOnEnter)) {
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- if (PluginConfig.m_bSendOnEnter || PluginConfig.m_bSendOnDblEnter) {
- if (isCtrl)
- break;
-
- if (PluginConfig.m_bSendOnDblEnter) {
- LONG_PTR lastEnterTime = GetWindowLongPtr(hwnd, GWLP_USERDATA);
- if (lastEnterTime + 2 < time(nullptr)) {
- lastEnterTime = time(nullptr);
- SetWindowLongPtr(hwnd, GWLP_USERDATA, lastEnterTime);
- break;
- }
- else {
- SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 0);
- SendMessage(hwnd, WM_KEYUP, VK_BACK, 0);
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- }
- PostMessage(hwndParent, WM_COMMAND, IDOK, 0);
- return 0;
- }
- else break;
- }
- else SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
-
- if (isCtrl && !isAlt && !isShift) {
- if (!isShift && (wParam == VK_UP || wParam == VK_DOWN)) { // input history scrolling (ctrl-up / down)
- SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
- if (mwdat)
- mwdat->m_cache->inputHistoryEvent(wParam);
- return 0;
- }
- }
- if (isCtrl && isAlt && !isShift) {
- switch (wParam) {
- case VK_UP:
- case VK_DOWN:
- case VK_PRIOR:
- case VK_NEXT:
- case VK_HOME:
- case VK_END:
- WPARAM wp = 0;
-
- SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
- if (wParam == VK_UP)
- wp = MAKEWPARAM(SB_LINEUP, 0);
- else if (wParam == VK_PRIOR)
- wp = MAKEWPARAM(SB_PAGEUP, 0);
- else if (wParam == VK_NEXT)
- wp = MAKEWPARAM(SB_PAGEDOWN, 0);
- else if (wParam == VK_HOME)
- wp = MAKEWPARAM(SB_TOP, 0);
- else if (wParam == VK_END) {
- mwdat->DM_ScrollToBottom(0, 0);
- return 0;
- }
- else if (wParam == VK_DOWN)
- wp = MAKEWPARAM(SB_LINEDOWN, 0);
-
- if (mwdat->m_hwndIEView == 0 && mwdat->m_hwndHPP == 0)
- SendDlgItemMessage(hwndParent, IDC_LOG, WM_VSCROLL, wp, 0);
- else
- SendMessage(mwdat->m_hwndIWebBrowserControl, WM_VSCROLL, wp, 0);
- return 0;
- }
- }
-
- case WM_SYSKEYDOWN:
- mwdat->m_bkeyProcessed = false;
- if (ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_MESSAGE)) {
- mwdat->m_bkeyProcessed = true;
- return 0;
- }
- break;
-
- case WM_SYSKEYUP:
- if (wParam == VK_MENU) {
- ProcessHotkeysByMsgFilter(hwnd, msg, wParam, lParam, IDC_MESSAGE);
- return 0;
- }
- break;
-
- case WM_SYSCHAR:
- if (mwdat->m_bkeyProcessed) {
- mwdat->m_bkeyProcessed = false;
- return 0;
- }
-
- mwdat->KbdState(isShift, isCtrl, isAlt);
- if ((wParam >= '0' && wParam <= '9') && isAlt) { // ALT-1 -> ALT-0 direct tab selection
- BYTE bChar = (BYTE)wParam;
- int iIndex;
-
- if (bChar == '0')
- iIndex = 10;
- else
- iIndex = bChar - (BYTE)'0';
- SendMessage(mwdat->m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_BY_INDEX, (LPARAM)iIndex);
- return 0;
- }
- break;
-
- case WM_INPUTLANGCHANGE:
- if (PluginConfig.m_bAutoLocaleSupport && GetFocus() == hwnd && mwdat->m_pContainer->m_hwndActive == hwndParent && GetForegroundWindow() == mwdat->m_pContainer->m_hwnd && GetActiveWindow() == mwdat->m_pContainer->m_hwnd) {
- mwdat->DM_SaveLocale(wParam, lParam);
- SendMessage(hwnd, EM_SETLANGOPTIONS, 0, (LPARAM)SendMessage(hwnd, EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
- return 1;
- }
- break;
-
- case WM_ERASEBKGND:
- return(CSkin::m_skinEnabled ? 0 : 1);
-
- // sent by smileyadd when the smiley selection window dies
- // just grab the focus :)
- case WM_USER + 100:
- SetFocus(hwnd);
- break;
-
- case WM_CONTEXTMENU:
- POINT pt;
- if (lParam == 0xFFFFFFFF) {
- CHARRANGE sel;
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);
- SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax);
- ClientToScreen(hwnd, &pt);
- }
- else {
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- }
-
- ShowPopupMenu(mwdat, IDC_MESSAGE, hwnd, pt);
- return TRUE;
- }
- return mir_callNextSubclass(hwnd, MessageEditSubclassProc, msg, wParam, lParam);
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
// subclasses the avatar display controls, needed for skinning and to prevent
// it from flickering during resize/move operations.
@@ -1114,7 +781,6 @@ void CSrmmWindow::OnInitDialog()
m_log.SendMsg(EM_EXLIMITTEXT, 0, 0x80000000);
// subclassing stuff
- mir_subclassWindow(m_message.GetHwnd(), MessageEditSubclassProc);
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CONTACTPIC), AvatarSubclassProc);
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERY), SplitterSubclassProc);
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_MULTISPLITTER), SplitterSubclassProc);
@@ -1161,11 +827,6 @@ void CSrmmWindow::OnInitDialog()
}
SendMessage(m_pContainer->m_hwnd, DM_QUERYCLIENTAREA, 0, (LPARAM)&rc);
- {
- WNDCLASS wndClass = { 0 };
- GetClassInfo(g_hInst, L"RICHEDIT50W", &wndClass);
- mir_subclassWindowFull(m_log.GetHwnd(), MessageLogSubclassProc, wndClass.lpfnWndProc);
- }
SetWindowPos(m_hwnd, 0, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), m_bActivate ? 0 : SWP_NOZORDER | SWP_NOACTIVATE);
LoadSplitter();
@@ -1312,6 +973,8 @@ void CSrmmWindow::OnDestroy()
ieWindow.hwnd = m_hwndHPP;
CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow);
}
+
+ CSuper::OnDestroy();
}
void CSrmmWindow::ReplayQueue()
@@ -2205,6 +1868,334 @@ int CSrmmWindow::OnFilter(MSGFILTER *pFilter)
}
/////////////////////////////////////////////////////////////////////////////////////////
+
+LRESULT CSrmmWindow::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ bool isCtrl, isShift, isAlt;
+
+ switch (msg) {
+ case WM_KILLFOCUS:
+ if (wParam != (WPARAM)m_log.GetHwnd() && 0 != wParam) {
+ CHARRANGE cr;
+ m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&cr);
+ if (cr.cpMax != cr.cpMin) {
+ cr.cpMin = cr.cpMax;
+ m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&cr);
+ }
+ }
+ break;
+
+ case WM_CHAR:
+ KbdState(isShift, isCtrl, isAlt);
+ if (wParam == 0x03 && isCtrl) // Ctrl+C
+ return Utils::WMCopyHandler(m_log.GetHwnd(), nullptr, msg, wParam, lParam);
+ if (wParam == 0x11 && isCtrl)
+ SendMessage(GetHwnd(), WM_COMMAND, IDC_QUOTE, 0);
+ break;
+
+ case WM_SYSKEYUP:
+ if (wParam == VK_MENU) {
+ ProcessHotkeysByMsgFilter(m_log.GetHwnd(), msg, wParam, lParam, IDC_LOG);
+ return 0;
+ }
+ break;
+
+ case WM_SYSKEYDOWN:
+ m_bkeyProcessed = false;
+ if (ProcessHotkeysByMsgFilter(m_log.GetHwnd(), msg, wParam, lParam, IDC_LOG)) {
+ m_bkeyProcessed = true;
+ return 0;
+ }
+ break;
+
+ case WM_SYSCHAR:
+ if (m_bkeyProcessed) {
+ m_bkeyProcessed = false;
+ return 0;
+ }
+ break;
+
+ case WM_KEYDOWN:
+ KbdState(isShift, isCtrl, isAlt);
+ if (wParam == VK_INSERT && isCtrl)
+ return Utils::WMCopyHandler(m_log.GetHwnd(), nullptr, msg, wParam, lParam);
+ break;
+
+ case WM_COPY:
+ return Utils::WMCopyHandler(m_log.GetHwnd(), nullptr, msg, wParam, lParam);
+
+ case WM_NCCALCSIZE:
+ return CSkin::NcCalcRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, nullptr);
+
+ case WM_NCPAINT:
+ return CSkin::DrawRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, nullptr);
+
+ case WM_CONTEXTMENU:
+ POINT pt;
+
+ if (lParam == 0xFFFFFFFF) {
+ CHARRANGE sel;
+ m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel);
+ m_log.SendMsg(EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax);
+ ClientToScreen(m_log.GetHwnd(), &pt);
+ }
+ else {
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+ }
+
+ ShowPopupMenu(this, IDC_LOG, m_log.GetHwnd(), pt);
+ return TRUE;
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ bool isCtrl, isShift, isAlt;
+
+ // prevent the rich edit from switching text direction or keyboard layout when
+ // using hotkeys with ctrl-shift or alt-shift modifiers
+ if (m_bkeyProcessed && (msg == WM_KEYUP)) {
+ GetKeyboardState(kstate);
+ if (kstate[VK_CONTROL] & 0x80 || kstate[VK_SHIFT] & 0x80)
+ return 0;
+
+ m_bkeyProcessed = false;
+ return 0;
+ }
+
+ switch (msg) {
+ case WM_NCCALCSIZE:
+ return CSkin::NcCalcRichEditFrame(m_message.GetHwnd(), this, ID_EXTBKINPUTAREA, msg, wParam, lParam, nullptr);
+
+ case WM_NCPAINT:
+ return CSkin::DrawRichEditFrame(m_message.GetHwnd(), this, ID_EXTBKINPUTAREA, msg, wParam, lParam, nullptr);
+
+ case WM_DROPFILES:
+ SendMessage(m_hwnd, WM_DROPFILES, (WPARAM)wParam, (LPARAM)lParam);
+ return 0;
+
+ case WM_CHAR:
+ KbdState(isShift, isCtrl, isAlt);
+
+ if (PluginConfig.m_bSoundOnTyping && !isAlt && !isCtrl && !(m_pContainer->dwFlags & CNT_NOSOUND) && wParam != VK_ESCAPE && !(wParam == VK_TAB && PluginConfig.m_bAllowTab))
+ SkinPlaySound("SoundOnTyping");
+
+ if (isCtrl && !isAlt) {
+ switch (wParam) {
+ case 0x02: // bold
+ if (m_SendFormat)
+ SendMessage(m_hwnd, WM_COMMAND, MAKELONG(IDC_SRMM_BOLD, IDC_MESSAGE), 0);
+ return 0;
+ case 0x09:
+ if (m_SendFormat)
+ SendMessage(m_hwnd, WM_COMMAND, MAKELONG(IDC_SRMM_ITALICS, IDC_MESSAGE), 0);
+ return 0;
+ case 21:
+ if (m_SendFormat)
+ SendMessage(m_hwnd, WM_COMMAND, MAKELONG(IDC_SRMM_UNDERLINE, IDC_MESSAGE), 0);
+ return 0;
+ case 0x0b:
+ m_message.SetText(L"");
+ return 0;
+ }
+ }
+ break;
+
+ case WM_MOUSEWHEEL:
+ if (DM_MouseWheelHandler(wParam, lParam) == 0)
+ return 0;
+ break;
+
+ case EM_PASTESPECIAL:
+ case WM_PASTE:
+ if (OpenClipboard(m_message.GetHwnd())) {
+ HANDLE hClip = GetClipboardData(CF_TEXT);
+ if (hClip) {
+ if ((int)mir_strlen((char*)hClip) > m_nMax) {
+ wchar_t szBuffer[512];
+ if (M.GetByte("autosplit", 0))
+ mir_snwprintf(szBuffer, TranslateT("WARNING: The message you are trying to paste exceeds the message size limit for the active protocol. It will be sent in chunks of max %d characters"), m_nMax - 10);
+ else
+ mir_snwprintf(szBuffer, TranslateT("The message you are trying to paste exceeds the message size limit for the active protocol. Only the first %d characters will be sent."), m_nMax);
+ SendMessage(m_hwnd, DM_ACTIVATETOOLTIP, IDC_MESSAGE, (LPARAM)szBuffer);
+ }
+ }
+ else if (hClip = GetClipboardData(CF_BITMAP))
+ SendHBitmapAsFile((HBITMAP)hClip);
+
+ CloseClipboard();
+ }
+ break;
+
+ case WM_KEYDOWN:
+ KbdState(isShift, isCtrl, isAlt);
+
+ if (PluginConfig.m_bSoundOnTyping && !isAlt && !(m_pContainer->dwFlags & CNT_NOSOUND) && wParam == VK_DELETE)
+ SkinPlaySound("SoundOnTyping");
+
+ if (wParam == VK_INSERT && !isShift && !isCtrl && !isAlt) {
+ m_bInsertMode = !m_bInsertMode;
+ m_message.OnChange(&m_message);
+ }
+ if (wParam == VK_CAPITAL || wParam == VK_NUMLOCK)
+ m_message.OnChange(&m_message);
+
+ if (wParam == VK_RETURN) {
+ if (m_bEditNotesActive)
+ break;
+
+ if (isShift) {
+ if (PluginConfig.m_bSendOnShiftEnter) {
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ else break;
+ }
+ if ((isCtrl && !isShift) ^ (0 != PluginConfig.m_bSendOnEnter)) {
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ if (PluginConfig.m_bSendOnEnter || PluginConfig.m_bSendOnDblEnter) {
+ if (isCtrl)
+ break;
+
+ if (PluginConfig.m_bSendOnDblEnter) {
+ if (m_iLastEnterTime + 2 < time(nullptr)) {
+ m_iLastEnterTime = time(nullptr);
+ break;
+ }
+ else {
+ m_message.SendMsg(WM_KEYDOWN, VK_BACK, 0);
+ m_message.SendMsg(WM_KEYUP, VK_BACK, 0);
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ }
+ PostMessage(m_hwnd, WM_COMMAND, IDOK, 0);
+ return 0;
+ }
+ else break;
+ }
+ else m_iLastEnterTime = 0;
+
+ if (isCtrl && !isAlt && !isShift) {
+ if (!isShift && (wParam == VK_UP || wParam == VK_DOWN)) { // input history scrolling (ctrl-up / down)
+ m_iLastEnterTime = 0;
+ m_cache->inputHistoryEvent(wParam);
+ return 0;
+ }
+ }
+ if (isCtrl && isAlt && !isShift) {
+ switch (wParam) {
+ case VK_UP:
+ case VK_DOWN:
+ case VK_PRIOR:
+ case VK_NEXT:
+ case VK_HOME:
+ case VK_END:
+ WPARAM wp = 0;
+
+ m_iLastEnterTime = 0;
+ if (wParam == VK_UP)
+ wp = MAKEWPARAM(SB_LINEUP, 0);
+ else if (wParam == VK_PRIOR)
+ wp = MAKEWPARAM(SB_PAGEUP, 0);
+ else if (wParam == VK_NEXT)
+ wp = MAKEWPARAM(SB_PAGEDOWN, 0);
+ else if (wParam == VK_HOME)
+ wp = MAKEWPARAM(SB_TOP, 0);
+ else if (wParam == VK_END) {
+ DM_ScrollToBottom(0, 0);
+ return 0;
+ }
+ else if (wParam == VK_DOWN)
+ wp = MAKEWPARAM(SB_LINEDOWN, 0);
+
+ if (m_hwndIEView == 0 && m_hwndHPP == 0)
+ SendDlgItemMessage(m_hwnd, IDC_LOG, WM_VSCROLL, wp, 0);
+ else
+ SendMessage(m_hwndIWebBrowserControl, WM_VSCROLL, wp, 0);
+ return 0;
+ }
+ }
+
+ case WM_SYSKEYDOWN:
+ m_bkeyProcessed = false;
+ if (ProcessHotkeysByMsgFilter(m_message.GetHwnd(), msg, wParam, lParam, IDC_MESSAGE)) {
+ m_bkeyProcessed = true;
+ return 0;
+ }
+ break;
+
+ case WM_SYSKEYUP:
+ if (wParam == VK_MENU) {
+ ProcessHotkeysByMsgFilter(m_message.GetHwnd(), msg, wParam, lParam, IDC_MESSAGE);
+ return 0;
+ }
+ break;
+
+ case WM_SYSCHAR:
+ if (m_bkeyProcessed) {
+ m_bkeyProcessed = false;
+ return 0;
+ }
+
+ KbdState(isShift, isCtrl, isAlt);
+ if ((wParam >= '0' && wParam <= '9') && isAlt) { // ALT-1 -> ALT-0 direct tab selection
+ BYTE bChar = (BYTE)wParam;
+ int iIndex;
+
+ if (bChar == '0')
+ iIndex = 10;
+ else
+ iIndex = bChar - (BYTE)'0';
+ SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_BY_INDEX, (LPARAM)iIndex);
+ return 0;
+ }
+ break;
+
+ case WM_INPUTLANGCHANGE:
+ if (PluginConfig.m_bAutoLocaleSupport && GetFocus() == m_message.GetHwnd() && m_pContainer->m_hwndActive == m_hwnd && GetForegroundWindow() == m_pContainer->m_hwnd && GetActiveWindow() == m_pContainer->m_hwnd) {
+ DM_SaveLocale(wParam, lParam);
+ m_message.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_message.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
+ return 1;
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ return(CSkin::m_skinEnabled ? 0 : 1);
+
+ // sent by smileyadd when the smiley selection window dies
+ // just grab the focus :)
+ case WM_USER + 100:
+ SetFocus(m_message.GetHwnd());
+ break;
+
+ case WM_CONTEXTMENU:
+ POINT pt;
+ if (lParam == 0xFFFFFFFF) {
+ CHARRANGE sel;
+ m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel);
+ m_message.SendMsg(EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax);
+ ClientToScreen(m_message.GetHwnd(), &pt);
+ }
+ else {
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+ }
+
+ ShowPopupMenu(this, IDC_MESSAGE, m_message.GetHwnd(), pt);
+ return TRUE;
+ }
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
// dialog procedure
INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
diff --git a/plugins/TabSRMM/src/msgs.h b/plugins/TabSRMM/src/msgs.h
index c2f7822141..308429b22c 100644
--- a/plugins/TabSRMM/src/msgs.h
+++ b/plugins/TabSRMM/src/msgs.h
@@ -237,6 +237,7 @@ struct SESSION_INFO;
class CTabBaseDlg : public CSrmmBaseDialog
{
+ typedef CSrmmBaseDialog CSuper;
friend class CInfoPanel;
protected:
@@ -440,11 +441,16 @@ public:
class CSrmmWindow : public CTabBaseDlg
{
+ typedef CTabBaseDlg CSuper;
+
virtual CThumbBase* tabCreateThumb(CProxyWindow *pProxy) const override;
virtual void tabClearLog() override;
CCtrlButton m_btnOk, m_btnAdd, m_btnQuote, m_btnCancelAdd;
+ virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
void LoadContactAvatar();
void LoadOwnAvatar();
void MsgWindowUpdateState(UINT msg);
@@ -482,19 +488,27 @@ public:
class CChatRoomDlg : public CTabBaseDlg
{
+ typedef CTabBaseDlg CSuper;
+
HWND m_hwndFilter;
CCtrlButton m_btnOk;
- static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+ virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ virtual LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
virtual CThumbBase* tabCreateThumb(CProxyWindow *pProxy) const override;
virtual void tabClearLog() override;
-public:
+ bool TabAutoComplete();
+
int m_iSearchItem;
+ BOOL m_iSavedSpaces;
wchar_t m_wszSearch[255];
+ wchar_t *m_wszSearchQuery, *m_wszSearchResult;
+ SESSION_INFO *m_pLastSession;
public:
CChatRoomDlg(SESSION_INFO*);
@@ -661,7 +675,6 @@ struct TIconDescW
#define TM_USER (WM_USER+300)
-#define EM_SUBCLASSED (TM_USER+0x101)
#define EM_SEARCHSCROLLER (TM_USER+0x103)
#define EM_VALIDATEBOTTOM (TM_USER+0x104)
#define EM_THEMECHANGED (TM_USER+0x105)
diff --git a/plugins/TabSRMM/src/themes.cpp b/plugins/TabSRMM/src/themes.cpp
index 112fd63be2..749e08ab01 100644
--- a/plugins/TabSRMM/src/themes.cpp
+++ b/plugins/TabSRMM/src/themes.cpp
@@ -1930,8 +1930,8 @@ UINT CSkin::NcCalcRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID
ShowScrollBar(hwnd, SB_VERT, FALSE);
}
- LRESULT orig = mir_callNextSubclass(hwnd, MyWndProc, msg, wParam, lParam);
- if (0 == mwdat)
+ LRESULT orig = (MyWndProc == nullptr) ? WVR_REDRAW : mir_callNextSubclass(hwnd, MyWndProc, msg, wParam, lParam);
+ if (mwdat == nullptr)
return orig;
if (CSkin::m_skinEnabled) {
@@ -1970,8 +1970,8 @@ UINT CSkin::NcCalcRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID
UINT CSkin::DrawRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc)
{
// do default processing (otherwise, NO scrollbar as it is painted in NC_PAINT)
- LRESULT result = mir_callNextSubclass(hwnd, OldWndProc, msg, wParam, lParam);
- if (0 == mwdat)
+ LRESULT result = (OldWndProc == nullptr) ? 0 : mir_callNextSubclass(hwnd, OldWndProc, msg, wParam, lParam);
+ if (mwdat == nullptr)
return result;
BOOL isEditNotesReason = ((mwdat->m_bEditNotesActive) && (skinID == ID_EXTBKINPUTAREA));
@@ -2023,8 +2023,7 @@ UINT CSkin::DrawRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID,
FillRect(hdc, &rcWindow, br);
DeleteObject(br);
}
- else
- DrawThemeBackground(mwdat->m_hTheme, hdc, 1, 1, &rcWindow, &rcWindow);
+ else DrawThemeBackground(mwdat->m_hTheme, hdc, 1, 1, &rcWindow, &rcWindow);
}
ReleaseDC(hwnd, hdc);
return result;
diff --git a/plugins/TabSRMM/src/utils.cpp b/plugins/TabSRMM/src/utils.cpp
index a2cac5183f..d9dec206a3 100644
--- a/plugins/TabSRMM/src/utils.cpp
+++ b/plugins/TabSRMM/src/utils.cpp
@@ -982,7 +982,7 @@ size_t Utils::CopyToClipBoard(const wchar_t *str, const HWND hwndOwner)
LRESULT Utils::WMCopyHandler(HWND hwnd, WNDPROC oldWndProc, UINT msg, WPARAM wParam, LPARAM lParam)
{
- LRESULT result = mir_callNextSubclass(hwnd, oldWndProc, msg, wParam, lParam);
+ LRESULT result = (oldWndProc == nullptr) ? 0 : mir_callNextSubclass(hwnd, oldWndProc, msg, wParam, lParam);
ptrA szFromStream(Message_GetFromStream(hwnd, SF_TEXT | SFF_SELECTION));
if (szFromStream != nullptr) {