From 7d191d7bf8dc09f8484a05d898c8d0971beaa10b Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 23 Mar 2017 20:53:10 +0300 Subject: Scriver: window procedure virtualization --- plugins/Scriver/src/chat_window.cpp | 1732 +++++++++++++++++------------------ plugins/Scriver/src/input.cpp | 62 +- plugins/Scriver/src/input.h | 1 - plugins/Scriver/src/msgdialog.cpp | 859 +++++++++-------- plugins/Scriver/src/msgs.h | 19 +- 5 files changed, 1321 insertions(+), 1352 deletions(-) (limited to 'plugins') diff --git a/plugins/Scriver/src/chat_window.cpp b/plugins/Scriver/src/chat_window.cpp index ea9f20ba37..1dbf67ea87 100644 --- a/plugins/Scriver/src/chat_window.cpp +++ b/plugins/Scriver/src/chat_window.cpp @@ -21,23 +21,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" -struct MESSAGESUBDATA +void CChatRoomDlg::TabAutoComplete() { - time_t lastEnterTime; - wchar_t *szSearchQuery; - wchar_t *szSearchResult; - SESSION_INFO *lastSession; -}; - -static void TabAutoComplete(HWND hwnd, MESSAGESUBDATA *dat, SESSION_INFO *si) -{ - LRESULT lResult = (LRESULT)SendMessage(hwnd, EM_GETSEL, 0, 0); + LRESULT 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; - int iLen = GetRichTextLength(hwnd, gt.codepage, TRUE); + int iLen = GetRichTextLength(m_message.GetHwnd(), gt.codepage, TRUE); if (iLen <= 0) return; @@ -47,13 +39,13 @@ static void TabAutoComplete(HWND hwnd, MESSAGESUBDATA *dat, SESSION_INFO *si) gt.cb = iLen + 99 * sizeof(wchar_t); gt.flags = GT_DEFAULT; - SendMessage(hwnd, EM_GETTEXTEX, (WPARAM)>, (LPARAM)pszText); + m_message.SendMsg(EM_GETTEXTEX, (WPARAM)>, (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; } @@ -76,34 +68,34 @@ LBL_SkipEnd: isTopic = true; } - if (dat->szSearchQuery == nullptr) { - dat->szSearchQuery = (wchar_t*)mir_alloc(sizeof(wchar_t)*(end - start + 1)); - mir_wstrncpy(dat->szSearchQuery, pszText + start, end - start + 1); - dat->szSearchResult = mir_wstrdup(dat->szSearchQuery); - dat->lastSession = nullptr; + if (m_wszSearchQuery == nullptr) { + m_wszSearchQuery = (wchar_t*)mir_alloc(sizeof(wchar_t)*(end - start + 1)); + mir_wstrncpy(m_wszSearchQuery, pszText + start, end - start + 1); + 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); mir_free(pszText); - replaceStrW(dat->szSearchResult, nullptr); + replaceStrW(m_wszSearchResult, nullptr); if (pszName == nullptr) { if (end != start) { - SendMessage(hwnd, EM_SETSEL, start, end); - SendMessage(hwnd, EM_REPLACESEL, FALSE, (LPARAM)dat->szSearchQuery); + m_message.SendMsg(EM_SETSEL, start, end); + m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)m_wszSearchQuery); } - replaceStrW(dat->szSearchQuery, nullptr); + replaceStrW(m_wszSearchQuery, nullptr); } else { - dat->szSearchResult = mir_wstrdup(pszName); + m_wszSearchResult = mir_wstrdup(pszName); if (end != start) { ptrW szReplace; if (!isRoom && !isTopic && g_Settings.bAddColonToAutoComplete && start == 0) { @@ -112,1024 +104,1012 @@ LBL_SkipEnd: mir_wstrcat(szReplace, L": "); pszName = szReplace; } - SendMessage(hwnd, EM_SETSEL, start, end); - SendMessage(hwnd, EM_REPLACESEL, FALSE, (LPARAM)pszName); + m_message.SendMsg(EM_SETSEL, start, end); + m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)pszName); } } } -LRESULT CALLBACK CChatRoomDlg::MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +int GetTextPixelSize(wchar_t* pszText, HFONT hFont, BOOL bWidth) { - BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; - BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; - BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; - - MESSAGESUBDATA *dat = (MESSAGESUBDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA); - CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - - int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, pDlg); - if (result != -1) - return result; - - switch (msg) { - case EM_SUBCLASSED: - dat = (MESSAGESUBDATA*)mir_calloc(sizeof(MESSAGESUBDATA)); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); + if (!pszText || !hFont) return 0; - case WM_MOUSEWHEEL: - if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_VSCROLL) == 0) - SendDlgItemMessage(GetParent(hwnd), IDC_LOG, WM_MOUSEWHEEL, wParam, lParam); - - dat->lastEnterTime = 0; - return TRUE; - - case EM_REPLACESEL: - PostMessage(hwnd, EM_ACTIVATE, 0, 0); - break; + HDC hdc = GetDC(nullptr); + HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); - case EM_ACTIVATE: - SetActiveWindow(GetParent(hwnd)); - break; + RECT rc = { 0 }; + DrawText(hdc, pszText, -1, &rc, DT_CALCRECT); + SelectObject(hdc, hOldFont); + ReleaseDC(nullptr, hdc); + return bWidth ? rc.right - rc.left : rc.bottom - rc.top; +} - case WM_KEYDOWN: - if (wParam == VK_RETURN) { - mir_free(dat->szSearchQuery); - dat->szSearchQuery = nullptr; - mir_free(dat->szSearchResult); - dat->szSearchResult = nullptr; - if ((isCtrl != 0) ^ (0 != db_get_b(0, SRMM_MODULE, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER))) { - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - if (db_get_b(0, SRMM_MODULE, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER)) { - if (dat->lastEnterTime + 2 < time(nullptr)) - dat->lastEnterTime = time(nullptr); - else { - SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 0); - SendMessage(hwnd, WM_KEYUP, VK_BACK, 0); - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - } - } - else dat->lastEnterTime = 0; +static void __cdecl phase2(void *lParam) +{ + Thread_SetName("Scriver: phase2"); - if (wParam == VK_TAB && isShift && !isCtrl) { // SHIFT-TAB (go to nick list) - SetFocus(pDlg->m_nickList.GetHwnd()); - return TRUE; - } + SESSION_INFO *si = (SESSION_INFO*)lParam; + Sleep(30); + if (si && si->pDlg) + si->pDlg->RedrawLog2(); +} - if (wParam == VK_TAB && !isCtrl && !isShift) { //tab-autocomplete - SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); - TabAutoComplete(hwnd, dat, pDlg->m_si); - SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); - RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE); - return 0; - } - if (wParam != VK_RIGHT && wParam != VK_LEFT) { - mir_free(dat->szSearchQuery); - dat->szSearchQuery = nullptr; - mir_free(dat->szSearchResult); - dat->szSearchResult = nullptr; - } +void CChatRoomDlg::FixTabIcons() +{ + HICON hIcon; + if (!(m_si->wState & GC_EVENT_HIGHLIGHT)) { + if (m_si->wState & STATE_TALK) + hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineTalkIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineTalkIcon; + else + hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineIcon; + } + else hIcon = g_dat.hMsgIcon; - if (pDlg->ProcessHotkeys(wParam, isShift, isCtrl, isAlt)) - return TRUE; + TabControlData tcd = {}; + tcd.iFlags = TCDF_ICON; + tcd.hIcon = hIcon; + SendMessage(m_hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)m_hwnd); +} - if (wParam == 0x4e && isCtrl && !isAlt) { // ctrl-n (nicklist) - if (pDlg->m_btnNickList.Enabled()) - pDlg->m_btnNickList.OnClick(&pDlg->m_btnNickList); - return TRUE; - } +///////////////////////////////////////////////////////////////////////////////////////// - if (wParam == 0x48 && isCtrl && !isAlt) { // ctrl-h (history) - pDlg->m_btnHistory.OnClick(&pDlg->m_btnHistory); - return TRUE; - } +void CChatRoomDlg::MessageDialogResize(int w, int h) +{ + bool bNick = m_si->iType != GCW_SERVER && m_bNicklistEnabled; + bool bToolbar = SendMessage(m_hwndParent, CM_GETTOOLBARSTATUS, 0, 0) != 0; + int hSplitterMinTop = TOOLBAR_HEIGHT + m_minLogBoxHeight, hSplitterMinBottom = m_minEditBoxHeight; + int toolbarHeight = bToolbar ? TOOLBAR_HEIGHT : 0; - if (wParam == 0x4f && isCtrl && !isAlt) { // ctrl-o (options) - if (pDlg->m_btnChannelMgr.Enabled()) - pDlg->m_btnChannelMgr.OnClick(&pDlg->m_btnChannelMgr); - return TRUE; - } + if (h - m_pParent->iSplitterY < hSplitterMinTop) + m_pParent->iSplitterY = h - hSplitterMinTop; + if (m_pParent->iSplitterY < hSplitterMinBottom) + m_pParent->iSplitterY = hSplitterMinBottom; - if (((wParam == VK_INSERT && isShift) || (wParam == 'V' && isCtrl)) && !isAlt) { // ctrl-v (paste clean text) - SendMessage(hwnd, EM_PASTESPECIAL, CF_UNICODETEXT, 0); - return TRUE; - } + ShowWindow(m_splitterX.GetHwnd(), bNick ? SW_SHOW : SW_HIDE); + if (m_si->iType != GCW_SERVER) + ShowWindow(m_nickList.GetHwnd(), m_bNicklistEnabled ? SW_SHOW : SW_HIDE); + else + ShowWindow(m_nickList.GetHwnd(), SW_HIDE); - if (wParam == VK_NEXT || wParam == VK_PRIOR) { - HWND htemp = GetParent(hwnd); - SendDlgItemMessage(htemp, IDC_LOG, msg, wParam, lParam); - return TRUE; - } - break; + if (m_si->iType == GCW_SERVER) { + m_btnNickList.Enable(false); + m_btnFilter.Enable(false); + m_btnChannelMgr.Enable(false); + } + else { + m_btnNickList.Enable(true); + m_btnFilter.Enable(true); + if (m_si->iType == GCW_CHATROOM) + m_btnChannelMgr.Enable(pci->MM_FindModule(m_si->pszModule)->bChanMgr); + } - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_KILLFOCUS: - dat->lastEnterTime = 0; - break; + int toolbarTopY = bToolbar ? h - m_pParent->iSplitterY - toolbarHeight : h - m_pParent->iSplitterY; + int logBottom = (m_hwndIeview != nullptr) ? toolbarTopY / 2 : toolbarTopY; - case WM_CONTEXTMENU: - InputAreaContextMenu(hwnd, wParam, lParam, pDlg->m_hContact); - return TRUE; + HDWP hdwp = BeginDeferWindowPos(5); + hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), 0, 1, 0, bNick ? w - m_pParent->iSplitterX - 1 : w - 2, logBottom, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_nickList.GetHwnd(), 0, w - m_pParent->iSplitterX + 2, 0, m_pParent->iSplitterX - 3, toolbarTopY, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_splitterX.GetHwnd(), 0, w - m_pParent->iSplitterX, 1, 2, toolbarTopY - 1, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_splitterY.GetHwnd(), 0, 0, h - m_pParent->iSplitterY, w, SPLITTER_HEIGHT, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_message.GetHwnd(), 0, 1, h - m_pParent->iSplitterY + SPLITTER_HEIGHT, w - 2, m_pParent->iSplitterY - SPLITTER_HEIGHT - 1, SWP_NOZORDER); + EndDeferWindowPos(hdwp); - case WM_KEYUP: - case WM_LBUTTONUP: - case WM_RBUTTONUP: - case WM_MBUTTONUP: - pDlg->RefreshButtonStatus(); - break; + SetButtonsPos(m_hwnd, m_hContact, bToolbar); - case WM_DESTROY: - mir_free(dat->szSearchQuery); - mir_free(dat->szSearchResult); - mir_free(dat); - return 0; + if (m_hwndIeview != nullptr) { + IEVIEWWINDOW ieWindow; + ieWindow.cbSize = sizeof(IEVIEWWINDOW); + ieWindow.iType = IEW_SETPOS; + ieWindow.parent = m_hwnd; + ieWindow.hwnd = m_hwndIeview; + ieWindow.x = 0; + ieWindow.y = logBottom + 1; + ieWindow.cx = bNick ? w - m_pParent->iSplitterX : w; + ieWindow.cy = logBottom; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); } + else RedrawWindow(m_log.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); - return mir_callNextSubclass(hwnd, MessageSubclassProc, msg, wParam, lParam); + RedrawWindow(m_nickList.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); } -INT_PTR CALLBACK CChatRoomDlg::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - static CChatRoomDlg *pDlg = nullptr; - switch (uMsg) { - case WM_INITDIALOG: - pDlg = (CChatRoomDlg*)lParam; - CheckDlgButton(hwndDlg, IDC_CHAT_1, pDlg->m_iLogFilterFlags & GC_EVENT_ACTION ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_2, pDlg->m_iLogFilterFlags & GC_EVENT_MESSAGE ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_3, pDlg->m_iLogFilterFlags & GC_EVENT_NICK ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_4, pDlg->m_iLogFilterFlags & GC_EVENT_JOIN ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_5, pDlg->m_iLogFilterFlags & GC_EVENT_PART ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_6, pDlg->m_iLogFilterFlags & GC_EVENT_TOPIC ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_7, pDlg->m_iLogFilterFlags & GC_EVENT_ADDSTATUS ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_8, pDlg->m_iLogFilterFlags & GC_EVENT_INFORMATION ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_9, pDlg->m_iLogFilterFlags & GC_EVENT_QUIT ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_10, pDlg->m_iLogFilterFlags & GC_EVENT_KICK ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CHAT_11, pDlg->m_iLogFilterFlags & GC_EVENT_NOTICE ? BST_CHECKED : BST_UNCHECKED); - break; - - 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_ACTIVATE: - if (LOWORD(wParam) == WA_INACTIVE) { - int iFlags = 0; +CChatRoomDlg::CChatRoomDlg(SESSION_INFO *si) + : CScriverWindow(IDD_CHANNEL, si), - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_1) == BST_CHECKED) - iFlags |= GC_EVENT_ACTION; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_2) == BST_CHECKED) - iFlags |= GC_EVENT_MESSAGE; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_3) == BST_CHECKED) - iFlags |= GC_EVENT_NICK; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_4) == BST_CHECKED) - iFlags |= GC_EVENT_JOIN; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_5) == BST_CHECKED) - iFlags |= GC_EVENT_PART; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_6) == BST_CHECKED) - iFlags |= GC_EVENT_TOPIC; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_7) == BST_CHECKED) - iFlags |= GC_EVENT_ADDSTATUS; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_8) == BST_CHECKED) - iFlags |= GC_EVENT_INFORMATION; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_9) == BST_CHECKED) - iFlags |= GC_EVENT_QUIT; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_10) == BST_CHECKED) - iFlags |= GC_EVENT_KICK; - if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_11) == BST_CHECKED) - iFlags |= GC_EVENT_NOTICE; + m_log(this, IDC_LOG), + m_message(this, IDC_MESSAGE), - if (iFlags & GC_EVENT_ADDSTATUS) - iFlags |= GC_EVENT_REMOVESTATUS; + m_splitterX(this, IDC_SPLITTERX), + m_splitterY(this, IDC_SPLITTERY), - pDlg->m_iLogFilterFlags = iFlags; - if (pDlg->m_bFilterEnabled) - pDlg->RedrawLog(); - PostMessage(hwndDlg, WM_CLOSE, 0, 0); - } - break; + m_btnOk(this, IDOK) +{ + m_pLog = &m_log; + m_pEntry = &m_message; - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - } + m_btnOk.OnClick = Callback(this, &CChatRoomDlg::onClick_Ok); + m_btnFilter.OnClick = Callback(this, &CChatRoomDlg::onClick_Filter); + m_btnNickList.OnClick = Callback(this, &CChatRoomDlg::onClick_ShowList); - return FALSE; + m_message.OnChange = Callback(this, &CChatRoomDlg::onChange_Message); + + m_splitterX.OnChange = Callback(this, &CChatRoomDlg::OnSplitterX); + m_splitterY.OnChange = Callback(this, &CChatRoomDlg::OnSplitterY); } -LRESULT CALLBACK CChatRoomDlg::LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +void CChatRoomDlg::OnInitDialog() { - static BOOL inMenu = FALSE; - CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); + CScriverWindow::OnInitDialog(); + m_si->pDlg = this; - int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, pDlg); - if (result != -1) - return result; + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPENING); - CHARRANGE sel; + SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this); + m_pParent = (ParentWindowData *)GetWindowLongPtr(m_hwndParent, GWLP_USERDATA); - switch (msg) { - case WM_MEASUREITEM: - MeasureMenuItem(wParam, lParam); - return TRUE; + RichUtil_SubClass(m_message.GetHwnd()); + RichUtil_SubClass(m_log.GetHwnd()); + RichUtil_SubClass(m_nickList.GetHwnd()); - case WM_DRAWITEM: - return DrawMenuItem(wParam, lParam); + Srmm_CreateToolbarIcons(m_hwnd, BBBF_ISCHATBUTTON); - case WM_SETCURSOR: - if (inMenu) { - SetCursor(LoadCursor(nullptr, IDC_ARROW)); - return TRUE; - } - break; + RECT rc; + GetWindowRect(m_message.GetHwnd(), &rc); + m_minLogBoxHeight = m_minEditBoxHeight = rc.bottom - rc.top; + if (m_pParent->iSplitterY == -1) + m_pParent->iSplitterY = m_minEditBoxHeight; - case WM_LBUTTONUP: - 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(GetParent(hwnd), IDC_MESSAGE)); - break; + if (m_pParent->iSplitterX == -1) { + GetWindowRect(m_nickList.GetHwnd(), &rc); + m_pParent->iSplitterX = rc.right - rc.left; + } - case WM_ACTIVATE: - if (LOWORD(wParam) == WA_INACTIVE) { - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin != sel.cpMax) { - sel.cpMin = sel.cpMax; - SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); - } - } - break; + m_message.SendMsg(EM_SUBCLASSED, 0, 0); + m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE); - case WM_CONTEXTMENU: - POINT pt; - POINTL ptl; - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); - if (lParam == 0xFFFFFFFF) { - 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); - } - ptl.x = (LONG)pt.x; - ptl.y = (LONG)pt.y; - ScreenToClient(hwnd, (LPPOINT)&ptl); - { - ptrW pszWord(GetRichTextWord(hwnd, &ptl)); - inMenu = TRUE; + int mask = (int)m_log.SendMsg(EM_GETEVENTMASK, 0, 0); + m_log.SendMsg(EM_SETEVENTMASK, 0, mask | ENM_LINK | ENM_MOUSEEVENTS); + m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); + m_log.SendMsg(EM_SETOLECALLBACK, 0, (LPARAM)&reOleCallback); + m_log.SendMsg(EM_AUTOURLDETECT, 1, 0); - SESSION_INFO *si = pDlg->m_si; - CHARRANGE all = { 0, -1 }; - HMENU hMenu = nullptr; - UINT uID = CreateGCMenu(hwnd, &hMenu, 1, pt, si, nullptr, pszWord); - inMenu = FALSE; - switch (uID) { - case 0: - PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0); - break; + if (db_get_b(0, CHAT_MODULE, "UseIEView", 0)) { + IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; + ieWindow.iType = IEW_CREATE; + ieWindow.dwMode = IEWM_CHAT; + ieWindow.parent = m_hwnd; + ieWindow.cx = 200; + ieWindow.cy = 300; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - case ID_COPYALL: - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); - SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&all); - SendMessage(hwnd, WM_COPY, 0, 0); - SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); - PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0); - break; + m_hwndIeview = ieWindow.hwnd; - case IDM_CLEAR: - if (si) { - SetWindowText(hwnd, L""); - pci->LM_RemoveAll(&si->pLog, &si->pLogEnd); - si->iEventCount = 0; - si->LastTime = 0; - PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0); - } - break; + IEVIEWEVENT iee = { sizeof(iee) }; + iee.iType = IEE_CLEAR_LOG; + iee.hwnd = m_hwndIeview; + iee.hContact = m_hContact; + iee.pszProto = m_si->pszModule; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); + } - case IDM_SEARCH_GOOGLE: - case IDM_SEARCH_BING: - case IDM_SEARCH_YANDEX: - case IDM_SEARCH_YAHOO: - case IDM_SEARCH_WIKIPEDIA: - case IDM_SEARCH_FOODNETWORK: - case IDM_SEARCH_GOOGLE_MAPS: - case IDM_SEARCH_GOOGLE_TRANSLATE: - SearchWord(pszWord, uID - IDM_SEARCH_GOOGLE + SEARCHENGINE_GOOGLE); - PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0); - break; + m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - default: - PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0); - pDlg->DoEventHook(GC_USER_LOGMENU, nullptr, nullptr, uID); - break; - } - DestroyGCMenu(&hMenu, 5); - } - break; + UpdateOptions(); + UpdateStatusBar(); + UpdateTitle(); - case WM_CHAR: - SetFocus(GetDlgItem(GetParent(hwnd), IDC_MESSAGE)); - SendDlgItemMessage(GetParent(hwnd), IDC_MESSAGE, WM_CHAR, wParam, lParam); - break; + SendMessage(m_hwndParent, CM_ADDCHILD, (WPARAM)this, 0); + UpdateNickList(); + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPEN); +} + +void CChatRoomDlg::OnDestroy() +{ + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSING); + + m_si->pDlg = nullptr; + SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); + + SendMessage(m_hwndParent, CM_REMOVECHILD, 0, (LPARAM)m_hwnd); + if (m_hwndIeview != nullptr) { + IEVIEWWINDOW ieWindow; + ieWindow.cbSize = sizeof(IEVIEWWINDOW); + ieWindow.iType = IEW_DESTROY; + ieWindow.hwnd = m_hwndIeview; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); } - return mir_callNextSubclass(hwnd, LogSubclassProc, msg, wParam, lParam); + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE); } -LRESULT CALLBACK CChatRoomDlg::NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +void CChatRoomDlg::OnSplitterX(CSplitter *pSplitter) { - CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); + RECT rc; + GetClientRect(m_hwnd, &rc); - int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, pDlg); - if (result != -1) - return result; + m_pParent->iSplitterX = rc.right - pSplitter->GetPos() + 1; + if (m_pParent->iSplitterX < 35) + m_pParent->iSplitterX = 35; + if (m_pParent->iSplitterX > rc.right - rc.left - 35) + m_pParent->iSplitterX = rc.right - rc.left - 35; +} - switch (msg) { - case WM_ERASEBKGND: - { - HDC dc = (HDC)wParam; - if (dc) { - int index = SendMessage(hwnd, LB_GETTOPINDEX, 0, 0); - if (index == LB_ERR || pDlg->m_si->nUsersInNicklist <= 0) - return 0; +void CChatRoomDlg::OnSplitterY(CSplitter *pSplitter) +{ + RECT rc; + GetClientRect(m_hwnd, &rc); + m_pParent->iSplitterY = rc.bottom - pSplitter->GetPos(); +} - int items = pDlg->m_si->nUsersInNicklist - index; - int height = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0); +void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) +{ + if (!pButton->Enabled()) + return; - if (height != LB_ERR) { - RECT rc = { 0 }; - GetClientRect(hwnd, &rc); + char *pszRtf = GetRichTextRTF(m_message.GetHwnd()); + if (pszRtf == nullptr) + return; - if (rc.bottom - rc.top > items * height) { - rc.top = items*height; - FillRect(dc, &rc, pci->hListBkgBrush); - } - } - } - } - return 1; + MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); + if (mi == nullptr) + return; - case WM_RBUTTONDOWN: - SendMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam); - break; + TCmdList *cmdListNew = tcmdlist_last(cmdList); + while (cmdListNew != nullptr && cmdListNew->temporary) { + cmdList = tcmdlist_remove(cmdList, cmdListNew); + cmdListNew = tcmdlist_last(cmdList); + } - case WM_RBUTTONUP: - SendMessage(hwnd, WM_LBUTTONUP, wParam, lParam); - break; + // takes pszRtf to a queue, no leak here + cmdList = tcmdlist_append(cmdList, pszRtf, 20, FALSE); - case WM_MEASUREITEM: - { - MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam; - if (mis->CtlType == ODT_MENU) - return Menu_MeasureItem(lParam); - } - return FALSE; + CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf))); + pci->DoRtfToTags(ptszText, mi->nColorCount, mi->crColors); + ptszText.Trim(); + ptszText.Replace(L"%", L"%%"); - case WM_DRAWITEM: - { - DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; - if (dis->CtlType == ODT_MENU) - return Menu_DrawItem(lParam); - } - return FALSE; + if (mi->bAckMsg) { + EnableWindow(m_message.GetHwnd(), FALSE); + m_message.SendMsg(EM_SETREADONLY, TRUE, 0); + } + else SetDlgItemText(m_hwnd, IDC_MESSAGE, L""); - case WM_CONTEXTMENU: - { - int height = 0; + EnableWindow(m_btnOk.GetHwnd(), FALSE); - 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); + DoEventHook(GC_USER_MESSAGE, nullptr, ptszText, 0); + SetFocus(m_message.GetHwnd()); +} - DWORD item = (DWORD)(SendMessage(hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y))); - if (HIWORD(item) == 1) - item = (DWORD)(-1); - else - item &= 0xFFFF; +void CChatRoomDlg::onClick_ShowList(CCtrlButton *pButton) +{ + if (!pButton->Enabled() || m_si->iType == GCW_SERVER) + return; - USERINFO *ui = pci->SM_GetUserFromIndex(pDlg->m_si->ptszID, pDlg->m_si->pszModule, (int)item); - if (ui) { - HMENU hMenu = 0; - USERINFO uinew; + m_bNicklistEnabled = !m_bNicklistEnabled; + pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2")); + ScrollToBottom(); + SendMessage(m_hwnd, WM_SIZE, 0, 0); +} - 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, pDlg->m_si, uinew.pszUID, uinew.pszNick); +void CChatRoomDlg::onClick_Filter(CCtrlButton *pButton) +{ + if (!pButton->Enabled()) + return; - switch (uID) { - case 0: - break; + m_bFilterEnabled = !m_bFilterEnabled; + pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bFilterEnabled ? "chat_filter" : "chat_filter2")); + if (m_bFilterEnabled && db_get_b(0, CHAT_MODULE, "RightClickFilter", 0) == 0) + ShowFilterMenu(); + else + RedrawLog(); +} - case ID_MESS: - pDlg->DoEventHook(GC_USER_PRIVMESS, ui, nullptr, 0); - break; +void CChatRoomDlg::onChange_Message(CCtrlEdit *pEdit) +{ + cmdListCurrent = nullptr; + m_btnOk.Enable(GetRichTextLength(pEdit->GetHwnd(), 1200, FALSE) != 0); +} - default: - pDlg->DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID); - break; - } - DestroyGCMenu(&hMenu, 1); - return TRUE; - } - } - break; +///////////////////////////////////////////////////////////////////////////////////////// - case WM_GETDLGCODE: - { - BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; - BOOL isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) && !isAlt; - - LPMSG lpmsg; - if ((lpmsg = (LPMSG)lParam) != nullptr) { - if (lpmsg->message == WM_KEYDOWN - && (lpmsg->wParam == VK_RETURN || lpmsg->wParam == VK_ESCAPE || (lpmsg->wParam == VK_TAB && (isAlt || isCtrl)))) - return DLGC_WANTALLKEYS; - } - } - break; - - case WM_KEYDOWN: - if (wParam == VK_RETURN) { - int index = SendMessage(hwnd, LB_GETCURSEL, 0, 0); - if (index != LB_ERR) { - USERINFO *ui = pci->SM_GetUserFromIndex(pDlg->m_si->ptszID, pDlg->m_si->pszModule, index); - pDlg->DoEventHook(GC_USER_PRIVMESS, ui, nullptr, 0); - } - break; - } - 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) { - pDlg->m_wszSearch[0] = 0; - } - break; +void CChatRoomDlg::RedrawLog() +{ + m_si->LastTime = 0; + if (m_si->pLog) { + LOGINFO *pLog = m_si->pLog; + if (m_si->iEventCount > 60) { + int index = 0; + while (index < 59) { + if (pLog->next == nullptr) + 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 && pDlg->m_wszSearch[0]) { // escape - reset everything - pDlg->m_wszSearch[0] = 0; - break; - } - else if (wParam == '\b' && pDlg->m_wszSearch[0]) // backspace - pDlg->m_wszSearch[mir_wstrlen(pDlg->m_wszSearch) - 1] = '\0'; - else if (wParam < ' ') - break; - else { - wchar_t szNew[2]; - szNew[0] = (wchar_t)wParam; - szNew[1] = '\0'; - if (mir_wstrlen(pDlg->m_wszSearch) >= _countof(pDlg->m_wszSearch) - 2) { - MessageBeep(MB_OK); - break; - } - mir_wstrcat(pDlg->m_wszSearch, szNew); - } - if (pDlg->m_wszSearch[0]) { - // iterate over the (sorted) list of nicknames and search for the - // string we have - int iItems = SendMessage(hwnd, LB_GETCOUNT, 0, 0); - for (int i = 0; i < iItems; i++) { - USERINFO *ui = pci->UM_FindUserFromIndex(pDlg->m_si->pUsers, i); - if (ui) { - if (!wcsnicmp(ui->pszNick, pDlg->m_wszSearch, mir_wstrlen(pDlg->m_wszSearch))) { - SendMessage(hwnd, LB_SETCURSEL, i, 0); - InvalidateRect(hwnd, nullptr, FALSE); - return 0; - } - } + pLog = pLog->next; + if ((m_si->iType != GCW_CHATROOM && m_si->iType != GCW_PRIVMESS) || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0) + index++; } - - MessageBeep(MB_OK); - pDlg->m_wszSearch[mir_wstrlen(pDlg->m_wszSearch) - 1] = '\0'; - return 0; + StreamInEvents(pLog, true); + mir_forkthread(phase2, m_si); } - break; - - case WM_MOUSEMOVE: - Chat_HoverMouse(pDlg->m_si, hwnd, lParam, ServiceExists("mToolTip/HideTip")); - break; + else StreamInEvents(m_si->pLogEnd, true); } - - return mir_callNextSubclass(hwnd, NicklistSubclassProc, msg, wParam, lParam); + else ClearLog(); } -int GetTextPixelSize(wchar_t* pszText, HFONT hFont, BOOL bWidth) +void CChatRoomDlg::ScrollToBottom() { - if (!pszText || !hFont) - return 0; + if ((GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0) + return; - HDC hdc = GetDC(nullptr); - HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); + SCROLLINFO sci = { 0 }; + sci.cbSize = sizeof(sci); + sci.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci); - RECT rc = { 0 }; - DrawText(hdc, pszText, -1, &rc, DT_CALCRECT); - SelectObject(hdc, hOldFont); - ReleaseDC(nullptr, hdc); - return bWidth ? rc.right - rc.left : rc.bottom - rc.top; + sci.fMask = SIF_POS; + sci.nPos = sci.nMax - sci.nPage + 1; + SetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci, TRUE); + + CHARRANGE sel; + sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd(), CP_ACP, FALSE); + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); } -static void __cdecl phase2(void *lParam) +void CChatRoomDlg::ShowFilterMenu() { - Thread_SetName("Scriver: phase2"); + HWND hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)this); + TranslateDialogDefault(hwnd); - SESSION_INFO *si = (SESSION_INFO*)lParam; - Sleep(30); - if (si && si->pDlg) - si->pDlg->RedrawLog2(); + RECT rc; + GetWindowRect(m_btnFilter.GetHwnd(), &rc); + SetWindowPos(hwnd, HWND_TOP, rc.left - 85, (IsWindowVisible(m_btnFilter.GetHwnd()) || IsWindowVisible(m_btnBold.GetHwnd())) ? rc.top - 206 : rc.top - 186, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); } -void CChatRoomDlg::FixTabIcons() +void CChatRoomDlg::UpdateNickList() { - HICON hIcon; - if (!(m_si->wState & GC_EVENT_HIGHLIGHT)) { - if (m_si->wState & STATE_TALK) - hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineTalkIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineTalkIcon; - else - hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineIcon; + m_nickList.SendMsg(WM_SETREDRAW, FALSE, 0); + m_nickList.SendMsg(LB_RESETCONTENT, 0, 0); + for (int index = 0; index < m_si->nUsersInNicklist; index++) { + USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, index); + if (ui) { + char szIndicator = SM_GetStatusIndicator(m_si, ui); + if (szIndicator > '\0') { + static wchar_t ptszBuf[128]; + mir_snwprintf(ptszBuf, L"%c%s", szIndicator, ui->pszNick); + m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ptszBuf); + } + else m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ui->pszNick); + } } - else hIcon = g_dat.hMsgIcon; - - TabControlData tcd = {}; - tcd.iFlags = TCDF_ICON; - tcd.hIcon = hIcon; - SendMessage(m_hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)m_hwnd); + m_nickList.SendMsg(WM_SETREDRAW, TRUE, 0); + InvalidateRect(m_nickList.GetHwnd(), nullptr, FALSE); + UpdateWindow(m_nickList.GetHwnd()); + UpdateTitle(); } -///////////////////////////////////////////////////////////////////////////////////////// - -void CChatRoomDlg::MessageDialogResize(int w, int h) +void CChatRoomDlg::UpdateOptions() { - bool bNick = m_si->iType != GCW_SERVER && m_bNicklistEnabled; - bool bToolbar = SendMessage(m_hwndParent, CM_GETTOOLBARSTATUS, 0, 0) != 0; - int hSplitterMinTop = TOOLBAR_HEIGHT + m_minLogBoxHeight, hSplitterMinBottom = m_minEditBoxHeight; - int toolbarHeight = bToolbar ? TOOLBAR_HEIGHT : 0; - - if (h - m_pParent->iSplitterY < hSplitterMinTop) - m_pParent->iSplitterY = h - hSplitterMinTop; - if (m_pParent->iSplitterY < hSplitterMinBottom) - m_pParent->iSplitterY = hSplitterMinBottom; - - ShowWindow(m_splitterX.GetHwnd(), bNick ? SW_SHOW : SW_HIDE); - if (m_si->iType != GCW_SERVER) - ShowWindow(m_nickList.GetHwnd(), m_bNicklistEnabled ? SW_SHOW : SW_HIDE); - else - ShowWindow(m_nickList.GetHwnd(), SW_HIDE); - - if (m_si->iType == GCW_SERVER) { - m_btnNickList.Enable(false); - m_btnFilter.Enable(false); - m_btnChannelMgr.Enable(false); - } - else { - m_btnNickList.Enable(true); - m_btnFilter.Enable(true); - if (m_si->iType == GCW_CHATROOM) - m_btnChannelMgr.Enable(pci->MM_FindModule(m_si->pszModule)->bChanMgr); + m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2")); + m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bFilterEnabled ? "chat_filter" : "chat_filter2")); + { + MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule); + if (pInfo) { + m_btnBold.Enable(pInfo->bBold); + m_btnItalic.Enable(pInfo->bItalics); + m_btnUnderline.Enable(pInfo->bUnderline); + m_btnColor.Enable(pInfo->bColor); + m_btnBkColor.Enable(pInfo->bBkgColor); + if (m_si->iType == GCW_CHATROOM) + m_btnChannelMgr.Enable(pInfo->bChanMgr); + } } - int toolbarTopY = bToolbar ? h - m_pParent->iSplitterY - toolbarHeight : h - m_pParent->iSplitterY; - int logBottom = (m_hwndIeview != nullptr) ? toolbarTopY / 2 : toolbarTopY; + UpdateStatusBar(); + UpdateTitle(); + FixTabIcons(); - HDWP hdwp = BeginDeferWindowPos(5); - hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), 0, 1, 0, bNick ? w - m_pParent->iSplitterX - 1 : w - 2, logBottom, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_nickList.GetHwnd(), 0, w - m_pParent->iSplitterX + 2, 0, m_pParent->iSplitterX - 3, toolbarTopY, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_splitterX.GetHwnd(), 0, w - m_pParent->iSplitterX, 1, 2, toolbarTopY - 1, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_splitterY.GetHwnd(), 0, 0, h - m_pParent->iSplitterY, w, SPLITTER_HEIGHT, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_message.GetHwnd(), 0, 1, h - m_pParent->iSplitterY + SPLITTER_HEIGHT, w - 2, m_pParent->iSplitterY - SPLITTER_HEIGHT - 1, SWP_NOZORDER); - EndDeferWindowPos(hdwp); + m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); - SetButtonsPos(m_hwnd, m_hContact, bToolbar); + // messagebox + COLORREF crFore; + LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, nullptr, &crFore); - if (m_hwndIeview != nullptr) { - IEVIEWWINDOW ieWindow; - ieWindow.cbSize = sizeof(IEVIEWWINDOW); - ieWindow.iType = IEW_SETPOS; - ieWindow.parent = m_hwnd; - ieWindow.hwnd = m_hwndIeview; - ieWindow.x = 0; - ieWindow.y = logBottom + 1; - ieWindow.cx = bNick ? w - m_pParent->iSplitterX : w; - ieWindow.cy = logBottom; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } - else RedrawWindow(m_log.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + CHARFORMAT2 cf; + cf.cbSize = sizeof(CHARFORMAT2); + cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_UNDERLINE | CFM_BACKCOLOR; + cf.dwEffects = 0; + cf.crTextColor = crFore; + cf.crBackColor = db_get_dw(0, SRMM_MODULE, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR); + m_message.SendMsg(EM_SETBKGNDCOLOR, 0, db_get_dw(0, SRMM_MODULE, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR)); + m_message.SendMsg(WM_SETFONT, (WPARAM)g_Settings.MessageBoxFont, MAKELPARAM(TRUE, 0)); + m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); + { + // nicklist + int ih = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListFont, FALSE); + int ih2 = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListHeadingsFont, FALSE); + int height = db_get_b(0, CHAT_MODULE, "NicklistRowDist", 12); + int font = ih > ih2 ? ih : ih2; + // make sure we have space for icon! + if (db_get_b(0, CHAT_MODULE, "ShowContactStatus", 0)) + font = font > 16 ? font : 16; - RedrawWindow(m_nickList.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); - RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font); + InvalidateRect(m_nickList.GetHwnd(), nullptr, TRUE); + } + m_message.SendMsg(EM_REQUESTRESIZE, 0, 0); + SendMessage(m_hwnd, WM_SIZE, 0, 0); + RedrawLog2(); } -CChatRoomDlg::CChatRoomDlg(SESSION_INFO *si) - : CScriverWindow(IDD_CHANNEL, si), - - m_log(this, IDC_LOG), - m_message(this, IDC_MESSAGE), - - m_splitterX(this, IDC_SPLITTERX), - m_splitterY(this, IDC_SPLITTERY), - - m_btnOk(this, IDOK) +void CChatRoomDlg::UpdateStatusBar() { - m_pLog = &m_log; - m_pEntry = &m_message; + MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); + wchar_t szTemp[512]; + mir_snwprintf(szTemp, L"%s : %s", mi->ptszModDispName, m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L""); - m_btnOk.OnClick = Callback(this, &CChatRoomDlg::onClick_Ok); - m_btnFilter.OnClick = Callback(this, &CChatRoomDlg::onClick_Filter); - m_btnNickList.OnClick = Callback(this, &CChatRoomDlg::onClick_ShowList); + StatusBarData sbd; + sbd.iItem = 0; + sbd.iFlags = SBDF_TEXT | SBDF_ICON; + sbd.hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; + sbd.pszText = szTemp; + SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd); - m_message.OnChange = Callback(this, &CChatRoomDlg::onChange_Message); - - m_splitterX.OnChange = Callback(this, &CChatRoomDlg::OnSplitterX); - m_splitterY.OnChange = Callback(this, &CChatRoomDlg::OnSplitterY); + sbd.iItem = 1; + sbd.hIcon = nullptr; + sbd.pszText = L""; + SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd); + + StatusIconData sid = { sizeof(sid) }; + sid.szModule = SRMM_MODULE; + Srmm_ModifyIcon(m_hContact, &sid); } -void CChatRoomDlg::OnInitDialog() +void CChatRoomDlg::UpdateTitle() { - CScriverWindow::OnInitDialog(); - m_si->pDlg = this; - - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPENING); - - SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this); - m_pParent = (ParentWindowData *)GetWindowLongPtr(m_hwndParent, GWLP_USERDATA); - - RichUtil_SubClass(m_message.GetHwnd()); - RichUtil_SubClass(m_log.GetHwnd()); - RichUtil_SubClass(m_nickList.GetHwnd()); + TitleBarData tbd = {}; + if (g_dat.flags & SMF_STATUSICON) { + MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); + tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon; + tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig; + } + else { + tbd.hIcon = GetCachedIcon("chat_window"); + tbd.hIconBig = g_dat.hIconChatBig; + } + tbd.hIconNot = (m_si->wState & (GC_EVENT_HIGHLIGHT | STATE_TALK)) ? GetCachedIcon("chat_overlay") : nullptr; - mir_subclassWindow(m_log.GetHwnd(), LogSubclassProc); - mir_subclassWindow(m_message.GetHwnd(), MessageSubclassProc); - mir_subclassWindow(m_nickList.GetHwnd(), NicklistSubclassProc); + wchar_t szTemp[512]; + switch (m_si->iType) { + case GCW_CHATROOM: + mir_snwprintf(szTemp, + (m_si->nUsersInNicklist == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"), + m_si->ptszName, m_si->nUsersInNicklist); + break; + case GCW_PRIVMESS: + mir_snwprintf(szTemp, + (m_si->nUsersInNicklist == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"), + m_si->ptszName, m_si->nUsersInNicklist); + break; + case GCW_SERVER: + mir_snwprintf(szTemp, L"%s: Server", m_si->ptszName); + break; + } + tbd.iFlags = TBDF_TEXT | TBDF_ICON; + tbd.pszText = szTemp; + SendMessage(m_hwndParent, CM_UPDATETITLEBAR, (WPARAM)&tbd, (LPARAM)m_hwnd); + SendMessage(m_hwnd, DM_UPDATETABCONTROL, 0, 0); +} - Srmm_CreateToolbarIcons(m_hwnd, BBBF_ISCHATBUTTON); +///////////////////////////////////////////////////////////////////////////////////////// - RECT rc; - GetWindowRect(m_message.GetHwnd(), &rc); - m_minLogBoxHeight = m_minEditBoxHeight = rc.bottom - rc.top; - if (m_pParent->iSplitterY == -1) - m_pParent->iSplitterY = m_minEditBoxHeight; +INT_PTR CALLBACK CChatRoomDlg::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static CChatRoomDlg *pDlg = nullptr; + switch (uMsg) { + case WM_INITDIALOG: + pDlg = (CChatRoomDlg*)lParam; + CheckDlgButton(hwndDlg, IDC_CHAT_1, pDlg->m_iLogFilterFlags & GC_EVENT_ACTION ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_2, pDlg->m_iLogFilterFlags & GC_EVENT_MESSAGE ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_3, pDlg->m_iLogFilterFlags & GC_EVENT_NICK ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_4, pDlg->m_iLogFilterFlags & GC_EVENT_JOIN ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_5, pDlg->m_iLogFilterFlags & GC_EVENT_PART ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_6, pDlg->m_iLogFilterFlags & GC_EVENT_TOPIC ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_7, pDlg->m_iLogFilterFlags & GC_EVENT_ADDSTATUS ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_8, pDlg->m_iLogFilterFlags & GC_EVENT_INFORMATION ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_9, pDlg->m_iLogFilterFlags & GC_EVENT_QUIT ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_10, pDlg->m_iLogFilterFlags & GC_EVENT_KICK ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CHAT_11, pDlg->m_iLogFilterFlags & GC_EVENT_NOTICE ? BST_CHECKED : BST_UNCHECKED); + break; - if (m_pParent->iSplitterX == -1) { - GetWindowRect(m_nickList.GetHwnd(), &rc); - m_pParent->iSplitterX = rc.right - rc.left; - } + 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); - m_message.SendMsg(EM_SUBCLASSED, 0, 0); - m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE); + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) { + int iFlags = 0; - int mask = (int)m_log.SendMsg(EM_GETEVENTMASK, 0, 0); - m_log.SendMsg(EM_SETEVENTMASK, 0, mask | ENM_LINK | ENM_MOUSEEVENTS); - m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); - m_log.SendMsg(EM_SETOLECALLBACK, 0, (LPARAM)&reOleCallback); - m_log.SendMsg(EM_AUTOURLDETECT, 1, 0); + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_1) == BST_CHECKED) + iFlags |= GC_EVENT_ACTION; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_2) == BST_CHECKED) + iFlags |= GC_EVENT_MESSAGE; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_3) == BST_CHECKED) + iFlags |= GC_EVENT_NICK; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_4) == BST_CHECKED) + iFlags |= GC_EVENT_JOIN; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_5) == BST_CHECKED) + iFlags |= GC_EVENT_PART; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_6) == BST_CHECKED) + iFlags |= GC_EVENT_TOPIC; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_7) == BST_CHECKED) + iFlags |= GC_EVENT_ADDSTATUS; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_8) == BST_CHECKED) + iFlags |= GC_EVENT_INFORMATION; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_9) == BST_CHECKED) + iFlags |= GC_EVENT_QUIT; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_10) == BST_CHECKED) + iFlags |= GC_EVENT_KICK; + if (IsDlgButtonChecked(hwndDlg, IDC_CHAT_11) == BST_CHECKED) + iFlags |= GC_EVENT_NOTICE; - if (db_get_b(0, CHAT_MODULE, "UseIEView", 0)) { - IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; - ieWindow.iType = IEW_CREATE; - ieWindow.dwMode = IEWM_CHAT; - ieWindow.parent = m_hwnd; - ieWindow.cx = 200; - ieWindow.cy = 300; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + if (iFlags & GC_EVENT_ADDSTATUS) + iFlags |= GC_EVENT_REMOVESTATUS; - m_hwndIeview = ieWindow.hwnd; + pDlg->m_iLogFilterFlags = iFlags; + if (pDlg->m_bFilterEnabled) + pDlg->RedrawLog(); + PostMessage(hwndDlg, WM_CLOSE, 0, 0); + } + break; - IEVIEWEVENT iee = { sizeof(iee) }; - iee.iType = IEE_CLEAR_LOG; - iee.hwnd = m_hwndIeview; - iee.hContact = m_hContact; - iee.pszProto = m_si->pszModule; - CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee); + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; } - m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - - UpdateOptions(); - UpdateStatusBar(); - UpdateTitle(); - - SendMessage(m_hwndParent, CM_ADDCHILD, (WPARAM)this, 0); - UpdateNickList(); - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPEN); + return FALSE; } -void CChatRoomDlg::OnDestroy() +///////////////////////////////////////////////////////////////////////////////////////// + +LRESULT CChatRoomDlg::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) { - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSING); + BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; + BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; + BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; - m_si->pDlg = nullptr; - SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0); + int result = InputAreaShortcuts(m_message.GetHwnd(), msg, wParam, lParam); + if (result != -1) + return result; - SendMessage(m_hwndParent, CM_REMOVECHILD, 0, (LPARAM)m_hwnd); - if (m_hwndIeview != nullptr) { - IEVIEWWINDOW ieWindow; - ieWindow.cbSize = sizeof(IEVIEWWINDOW); - ieWindow.iType = IEW_DESTROY; - ieWindow.hwnd = m_hwndIeview; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } + switch (msg) { + case WM_MOUSEWHEEL: + if ((GetWindowLongPtr(m_message.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0) + SendDlgItemMessage(m_hwnd, IDC_LOG, WM_MOUSEWHEEL, wParam, lParam); - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE); -} + m_iLastEnterTime = 0; + return TRUE; -void CChatRoomDlg::OnSplitterX(CSplitter *pSplitter) -{ - RECT rc; - GetClientRect(m_hwnd, &rc); + case EM_REPLACESEL: + PostMessage(m_message.GetHwnd(), EM_ACTIVATE, 0, 0); + break; - m_pParent->iSplitterX = rc.right - pSplitter->GetPos() + 1; - if (m_pParent->iSplitterX < 35) - m_pParent->iSplitterX = 35; - if (m_pParent->iSplitterX > rc.right - rc.left - 35) - m_pParent->iSplitterX = rc.right - rc.left - 35; -} + case EM_ACTIVATE: + SetActiveWindow(m_hwnd); + break; -void CChatRoomDlg::OnSplitterY(CSplitter *pSplitter) -{ - RECT rc; - GetClientRect(m_hwnd, &rc); - m_pParent->iSplitterY = rc.bottom - pSplitter->GetPos(); -} + case WM_KEYDOWN: + if (wParam == VK_RETURN) { + replaceStrW(m_wszSearchQuery, nullptr); + replaceStrW(m_wszSearchResult, nullptr); + if ((isCtrl != 0) ^ (0 != db_get_b(0, SRMM_MODULE, SRMSGSET_SENDONENTER, SRMSGDEFSET_SENDONENTER))) { + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + return 0; + } + if (db_get_b(0, SRMM_MODULE, SRMSGSET_SENDONDBLENTER, SRMSGDEFSET_SENDONDBLENTER)) { + if (m_iLastEnterTime + 2 < time(nullptr)) + m_iLastEnterTime = time(nullptr); + 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; + } + } + } + else m_iLastEnterTime = 0; -void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) -{ - if (!pButton->Enabled()) - return; + if (wParam == VK_TAB && isShift && !isCtrl) { // SHIFT-TAB (go to nick list) + SetFocus(m_nickList.GetHwnd()); + return TRUE; + } - char *pszRtf = GetRichTextRTF(m_message.GetHwnd()); - if (pszRtf == nullptr) - return; + if (wParam == VK_TAB && !isCtrl && !isShift) { //tab-autocomplete + m_message.SendMsg(WM_SETREDRAW, FALSE, 0); + TabAutoComplete(); + m_message.SendMsg(WM_SETREDRAW, TRUE, 0); + RedrawWindow(m_nickList.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + return 0; + } + if (wParam != VK_RIGHT && wParam != VK_LEFT) { + mir_free(m_wszSearchQuery); + m_wszSearchQuery = nullptr; + mir_free(m_wszSearchResult); + m_wszSearchResult = nullptr; + } - MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); - if (mi == nullptr) - return; + if (ProcessHotkeys(wParam, isShift, isCtrl, isAlt)) + return TRUE; - TCmdList *cmdListNew = tcmdlist_last(cmdList); - while (cmdListNew != nullptr && cmdListNew->temporary) { - cmdList = tcmdlist_remove(cmdList, cmdListNew); - cmdListNew = tcmdlist_last(cmdList); - } + if (wParam == 0x4e && isCtrl && !isAlt) { // ctrl-n (nicklist) + if (m_btnNickList.Enabled()) + m_btnNickList.OnClick(&m_btnNickList); + return TRUE; + } - // takes pszRtf to a queue, no leak here - cmdList = tcmdlist_append(cmdList, pszRtf, 20, FALSE); + if (wParam == 0x48 && isCtrl && !isAlt) { // ctrl-h (history) + m_btnHistory.OnClick(&m_btnHistory); + return TRUE; + } - CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf))); - pci->DoRtfToTags(ptszText, mi->nColorCount, mi->crColors); - ptszText.Trim(); - ptszText.Replace(L"%", L"%%"); - - if (mi->bAckMsg) { - EnableWindow(m_message.GetHwnd(), FALSE); - m_message.SendMsg(EM_SETREADONLY, TRUE, 0); - } - else SetDlgItemText(m_hwnd, IDC_MESSAGE, L""); + if (wParam == 0x4f && isCtrl && !isAlt) { // ctrl-o (options) + if (m_btnChannelMgr.Enabled()) + m_btnChannelMgr.OnClick(&m_btnChannelMgr); + return TRUE; + } - EnableWindow(m_btnOk.GetHwnd(), FALSE); + if (((wParam == VK_INSERT && isShift) || (wParam == 'V' && isCtrl)) && !isAlt) { // ctrl-v (paste clean text) + m_message.SendMsg(EM_PASTESPECIAL, CF_UNICODETEXT, 0); + return TRUE; + } - DoEventHook(GC_USER_MESSAGE, nullptr, ptszText, 0); - SetFocus(m_message.GetHwnd()); -} + if (wParam == VK_NEXT || wParam == VK_PRIOR) { + SendDlgItemMessage(m_hwnd, IDC_LOG, msg, wParam, lParam); + return TRUE; + } + break; -void CChatRoomDlg::onClick_ShowList(CCtrlButton *pButton) -{ - if (!pButton->Enabled() || m_si->iType == GCW_SERVER) - return; + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_KILLFOCUS: + m_iLastEnterTime = 0; + break; - m_bNicklistEnabled = !m_bNicklistEnabled; - pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2")); - ScrollToBottom(); - SendMessage(m_hwnd, WM_SIZE, 0, 0); -} + case WM_CONTEXTMENU: + InputAreaContextMenu(m_message.GetHwnd(), wParam, lParam, m_hContact); + return TRUE; -void CChatRoomDlg::onClick_Filter(CCtrlButton *pButton) -{ - if (!pButton->Enabled()) - return; + case WM_KEYUP: + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + RefreshButtonStatus(); + break; - m_bFilterEnabled = !m_bFilterEnabled; - pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bFilterEnabled ? "chat_filter" : "chat_filter2")); - if (m_bFilterEnabled && db_get_b(0, CHAT_MODULE, "RightClickFilter", 0) == 0) - ShowFilterMenu(); - else - RedrawLog(); -} + case WM_DESTROY: + mir_free(m_wszSearchQuery); + mir_free(m_wszSearchResult); + return 0; + } -void CChatRoomDlg::onChange_Message(CCtrlEdit *pEdit) -{ - cmdListCurrent = nullptr; - m_btnOk.Enable(GetRichTextLength(pEdit->GetHwnd(), 1200, FALSE) != 0); + return 0; } ///////////////////////////////////////////////////////////////////////////////////////// -void CChatRoomDlg::RedrawLog() +LRESULT CChatRoomDlg::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) { - m_si->LastTime = 0; - if (m_si->pLog) { - LOGINFO *pLog = m_si->pLog; - if (m_si->iEventCount > 60) { - int index = 0; - while (index < 59) { - if (pLog->next == nullptr) - break; + static BOOL inMenu = FALSE; - pLog = pLog->next; - if ((m_si->iType != GCW_CHATROOM && m_si->iType != GCW_PRIVMESS) || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0) - index++; - } - StreamInEvents(pLog, true); - mir_forkthread(phase2, m_si); + int result = InputAreaShortcuts(m_log.GetHwnd(), msg, wParam, lParam); + if (result != -1) + return result; + + CHARRANGE sel; + + switch (msg) { + case WM_MEASUREITEM: + MeasureMenuItem(wParam, lParam); + return TRUE; + + case WM_DRAWITEM: + return DrawMenuItem(wParam, lParam); + + case WM_SETCURSOR: + if (inMenu) { + SetCursor(LoadCursor(nullptr, IDC_ARROW)); + return TRUE; } - else StreamInEvents(m_si->pLogEnd, true); - } - else ClearLog(); -} + break; -void CChatRoomDlg::ScrollToBottom() -{ - if ((GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0) - return; + case WM_LBUTTONUP: + 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(GetDlgItem(m_hwnd, IDC_MESSAGE)); + break; - SCROLLINFO sci = { 0 }; - sci.cbSize = sizeof(sci); - sci.fMask = SIF_PAGE | SIF_RANGE; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci); + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) { + m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin != sel.cpMax) { + sel.cpMin = sel.cpMax; + m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + } + break; - sci.fMask = SIF_POS; - sci.nPos = sci.nMax - sci.nPage + 1; - SetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci, TRUE); + case WM_CONTEXTMENU: + POINT pt; + POINTL ptl; + m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (lParam == 0xFFFFFFFF) { + m_message.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); + } + ptl.x = (LONG)pt.x; + ptl.y = (LONG)pt.y; + ScreenToClient(m_log.GetHwnd(), (LPPOINT)&ptl); + { + ptrW pszWord(GetRichTextWord(m_log.GetHwnd(), &ptl)); + inMenu = TRUE; - CHARRANGE sel; - sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd(), CP_ACP, FALSE); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); -} + SESSION_INFO *si = m_si; + CHARRANGE all = { 0, -1 }; + HMENU hMenu = nullptr; + UINT uID = CreateGCMenu(m_log.GetHwnd(), &hMenu, 1, pt, si, nullptr, pszWord); + inMenu = FALSE; + switch (uID) { + case 0: + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; -void CChatRoomDlg::ShowFilterMenu() -{ - HWND hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)this); - TranslateDialogDefault(hwnd); + case ID_COPYALL: + m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + m_message.SendMsg(WM_COPY, 0, 0); + m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; - RECT rc; - GetWindowRect(m_btnFilter.GetHwnd(), &rc); - SetWindowPos(hwnd, HWND_TOP, rc.left - 85, (IsWindowVisible(m_btnFilter.GetHwnd()) || IsWindowVisible(m_btnBold.GetHwnd())) ? rc.top - 206 : rc.top - 186, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); -} + case IDM_CLEAR: + if (si) { + m_log.SetText(L""); + pci->LM_RemoveAll(&si->pLog, &si->pLogEnd); + si->iEventCount = 0; + si->LastTime = 0; + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + } + break; -void CChatRoomDlg::UpdateNickList() -{ - m_nickList.SendMsg(WM_SETREDRAW, FALSE, 0); - m_nickList.SendMsg(LB_RESETCONTENT, 0, 0); - for (int index = 0; index < m_si->nUsersInNicklist; index++) { - USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, index); - if (ui) { - char szIndicator = SM_GetStatusIndicator(m_si, ui); - if (szIndicator > '\0') { - static wchar_t ptszBuf[128]; - mir_snwprintf(ptszBuf, L"%c%s", szIndicator, ui->pszNick); - m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ptszBuf); + case IDM_SEARCH_GOOGLE: + case IDM_SEARCH_BING: + case IDM_SEARCH_YANDEX: + case IDM_SEARCH_YAHOO: + case IDM_SEARCH_WIKIPEDIA: + case IDM_SEARCH_FOODNETWORK: + case IDM_SEARCH_GOOGLE_MAPS: + case IDM_SEARCH_GOOGLE_TRANSLATE: + SearchWord(pszWord, uID - IDM_SEARCH_GOOGLE + SEARCHENGINE_GOOGLE); + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; + + default: + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + DoEventHook(GC_USER_LOGMENU, nullptr, nullptr, uID); + break; } - else m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ui->pszNick); + DestroyGCMenu(&hMenu, 5); } + break; + + case WM_CHAR: + SetFocus(GetDlgItem(m_hwnd, IDC_MESSAGE)); + SendDlgItemMessage(m_hwnd, IDC_MESSAGE, WM_CHAR, wParam, lParam); + break; } - m_nickList.SendMsg(WM_SETREDRAW, TRUE, 0); - InvalidateRect(m_nickList.GetHwnd(), nullptr, FALSE); - UpdateWindow(m_nickList.GetHwnd()); - UpdateTitle(); + + return 0; } -void CChatRoomDlg::UpdateOptions() +///////////////////////////////////////////////////////////////////////////////////////// + +LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) { - m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2")); - m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_bFilterEnabled ? "chat_filter" : "chat_filter2")); - { - MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule); - if (pInfo) { - m_btnBold.Enable(pInfo->bBold); - m_btnItalic.Enable(pInfo->bItalics); - m_btnUnderline.Enable(pInfo->bUnderline); - m_btnColor.Enable(pInfo->bColor); - m_btnBkColor.Enable(pInfo->bBkgColor); - if (m_si->iType == GCW_CHATROOM) - m_btnChannelMgr.Enable(pInfo->bChanMgr); + int result = InputAreaShortcuts(m_nickList.GetHwnd(), msg, wParam, lParam); + if (result != -1) + return result; + + switch (msg) { + 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; - UpdateStatusBar(); - UpdateTitle(); - FixTabIcons(); + case WM_RBUTTONDOWN: + m_nickList.SendMsg(WM_LBUTTONDOWN, wParam, lParam); + break; - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); + case WM_RBUTTONUP: + m_nickList.SendMsg(WM_LBUTTONUP, wParam, lParam); + break; - // messagebox - COLORREF crFore; - LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, nullptr, &crFore); + case WM_MEASUREITEM: + { + MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam; + if (mis->CtlType == ODT_MENU) + return Menu_MeasureItem(lParam); + } + return FALSE; - CHARFORMAT2 cf; - cf.cbSize = sizeof(CHARFORMAT2); - cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_UNDERLINE | CFM_BACKCOLOR; - cf.dwEffects = 0; - cf.crTextColor = crFore; - cf.crBackColor = db_get_dw(0, SRMM_MODULE, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR); - m_message.SendMsg(EM_SETBKGNDCOLOR, 0, db_get_dw(0, SRMM_MODULE, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR)); - m_message.SendMsg(WM_SETFONT, (WPARAM)g_Settings.MessageBoxFont, MAKELPARAM(TRUE, 0)); - m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); - { - // nicklist - int ih = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListFont, FALSE); - int ih2 = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListHeadingsFont, FALSE); - int height = db_get_b(0, CHAT_MODULE, "NicklistRowDist", 12); - int font = ih > ih2 ? ih : ih2; - // make sure we have space for icon! - if (db_get_b(0, CHAT_MODULE, "ShowContactStatus", 0)) - font = font > 16 ? font : 16; + case WM_DRAWITEM: + { + DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; + if (dis->CtlType == ODT_MENU) + return Menu_DrawItem(lParam); + } + return FALSE; - m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font); - InvalidateRect(m_nickList.GetHwnd(), nullptr, TRUE); - } - m_message.SendMsg(EM_REQUESTRESIZE, 0, 0); - SendMessage(m_hwnd, WM_SIZE, 0, 0); - RedrawLog2(); -} + case WM_CONTEXTMENU: + { + int height = 0; -void CChatRoomDlg::UpdateStatusBar() -{ - MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); - wchar_t szTemp[512]; - mir_snwprintf(szTemp, L"%s : %s", mi->ptszModDispName, m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L""); + 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); - StatusBarData sbd; - sbd.iItem = 0; - sbd.iFlags = SBDF_TEXT | SBDF_ICON; - sbd.hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; - sbd.pszText = szTemp; - SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd); + DWORD 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; - sbd.iItem = 1; - sbd.hIcon = nullptr; - sbd.pszText = L""; - SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd); + USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, (int)item); + if (ui) { + HMENU hMenu = 0; + USERINFO uinew; - StatusIconData sid = { sizeof(sid) }; - sid.szModule = SRMM_MODULE; - Srmm_ModifyIcon(m_hContact, &sid); -} + 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, m_si, uinew.pszUID, uinew.pszNick); -void CChatRoomDlg::UpdateTitle() -{ - TitleBarData tbd = {}; - if (g_dat.flags & SMF_STATUSICON) { - MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); - tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon; - tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig; - } - else { - tbd.hIcon = GetCachedIcon("chat_window"); - tbd.hIconBig = g_dat.hIconChatBig; - } - tbd.hIconNot = (m_si->wState & (GC_EVENT_HIGHLIGHT | STATE_TALK)) ? GetCachedIcon("chat_overlay") : nullptr; + switch (uID) { + case 0: + break; - wchar_t szTemp[512]; - switch (m_si->iType) { - case GCW_CHATROOM: - mir_snwprintf(szTemp, - (m_si->nUsersInNicklist == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"), - m_si->ptszName, m_si->nUsersInNicklist); + 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 GCW_PRIVMESS: - mir_snwprintf(szTemp, - (m_si->nUsersInNicklist == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"), - m_si->ptszName, m_si->nUsersInNicklist); + + case WM_GETDLGCODE: + { + BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; + BOOL isCtrl = (GetKeyState(VK_CONTROL) & 0x8000) && !isAlt; + + LPMSG lpmsg; + if ((lpmsg = (LPMSG)lParam) != nullptr) { + if (lpmsg->message == WM_KEYDOWN + && (lpmsg->wParam == VK_RETURN || lpmsg->wParam == VK_ESCAPE || (lpmsg->wParam == VK_TAB && (isAlt || isCtrl)))) + return DLGC_WANTALLKEYS; + } + } break; - case GCW_SERVER: - mir_snwprintf(szTemp, L"%s: Server", m_si->ptszName); + + case WM_KEYDOWN: + if (wParam == VK_RETURN) { + int index = m_nickList.SendMsg(LB_GETCURSEL, 0, 0); + if (index != LB_ERR) { + USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, index); + DoEventHook(GC_USER_PRIVMESS, ui, nullptr, 0); + } + break; + } + + 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; + 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; + break; + } + else if (wParam == '\b' && m_wszSearch[0]) // backspace + m_wszSearch[mir_wstrlen(m_wszSearch) - 1] = '\0'; + else if (wParam < ' ') + break; + else { + wchar_t szNew[2]; + szNew[0] = (wchar_t)wParam; + szNew[1] = '\0'; + if (mir_wstrlen(m_wszSearch) >= _countof(m_wszSearch) - 2) { + MessageBeep(MB_OK); + break; + } + mir_wstrcat(m_wszSearch, szNew); + } + if (m_wszSearch[0]) { + // iterate over the (sorted) list of nicknames and search for the + // string we have + int iItems = m_nickList.SendMsg(LB_GETCOUNT, 0, 0); + for (int 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_SETCURSEL, i, 0); + InvalidateRect(m_nickList.GetHwnd(), nullptr, FALSE); + return 0; + } + } + } + + MessageBeep(MB_OK); + m_wszSearch[mir_wstrlen(m_wszSearch) - 1] = '\0'; + return 0; + } + break; + + case WM_MOUSEMOVE: + Chat_HoverMouse(m_si, m_nickList.GetHwnd(), lParam, ServiceExists("mToolTip/HideTip")); break; } - tbd.iFlags = TBDF_TEXT | TBDF_ICON; - tbd.pszText = szTemp; - SendMessage(m_hwndParent, CM_UPDATETITLEBAR, (WPARAM)&tbd, (LPARAM)m_hwnd); - SendMessage(m_hwnd, DM_UPDATETABCONTROL, 0, 0); + + return 0; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/plugins/Scriver/src/input.cpp b/plugins/Scriver/src/input.cpp index d73357e656..3ba984c959 100644 --- a/plugins/Scriver/src/input.cpp +++ b/plugins/Scriver/src/input.cpp @@ -115,7 +115,7 @@ void InputAreaContextMenu(HWND hwnd, WPARAM, LPARAM lParam, MCONTACT hContact) DestroyMenu(hMenu); } -int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriverWindow *windowData) +int CScriverWindow::InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; @@ -130,31 +130,31 @@ int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriv switch (action) { case KB_PREV_TAB: - SendMessage(GetParent(windowData->GetHwnd()), CM_ACTIVATEPREV, 0, (LPARAM)windowData->GetHwnd()); + SendMessage(m_pParent->hwnd, CM_ACTIVATEPREV, 0, (LPARAM)m_hwnd); return FALSE; case KB_NEXT_TAB: - SendMessage(GetParent(windowData->GetHwnd()), CM_ACTIVATENEXT, 0, (LPARAM)windowData->GetHwnd()); + SendMessage(m_pParent->hwnd, CM_ACTIVATENEXT, 0, (LPARAM)m_hwnd); return FALSE; case KB_SWITCHSTATUSBAR: - SendMessage(GetParent(windowData->GetHwnd()), DM_SWITCHSTATUSBAR, 0, 0); + SendMessage(m_pParent->hwnd, DM_SWITCHSTATUSBAR, 0, 0); return FALSE; case KB_SWITCHTITLEBAR: - SendMessage(GetParent(windowData->GetHwnd()), DM_SWITCHTITLEBAR, 0, 0); + SendMessage(m_pParent->hwnd, DM_SWITCHTITLEBAR, 0, 0); return FALSE; case KB_SWITCHINFOBAR: - SendMessage(GetParent(windowData->GetHwnd()), DM_SWITCHINFOBAR, 0, 0); + SendMessage(m_pParent->hwnd, DM_SWITCHINFOBAR, 0, 0); return FALSE; case KB_SWITCHTOOLBAR: - SendMessage(GetParent(windowData->GetHwnd()), DM_SWITCHTOOLBAR, 0, 0); + SendMessage(m_pParent->hwnd, DM_SWITCHTOOLBAR, 0, 0); return FALSE; case KB_MINIMIZE: - ShowWindow(GetParent(windowData->GetHwnd()), SW_MINIMIZE); + ShowWindow(m_pParent->hwnd, SW_MINIMIZE); return FALSE; case KB_CLOSE: - SendMessage(windowData->GetHwnd(), WM_CLOSE, 0, 0); + SendMessage(m_hwnd, WM_CLOSE, 0, 0); return FALSE; case KB_CLEAR_LOG: - SendMessage(windowData->GetHwnd(), DM_CLEARLOG, 0, 0); + SendMessage(m_hwnd, DM_CLEARLOG, 0, 0); return FALSE; case KB_TAB1: case KB_TAB2: @@ -165,18 +165,18 @@ int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriv case KB_TAB7: case KB_TAB8: case KB_TAB9: - SendMessage(GetParent(windowData->GetHwnd()), CM_ACTIVATEBYINDEX, 0, action - KB_TAB1); + SendMessage(m_pParent->hwnd, CM_ACTIVATEBYINDEX, 0, action - KB_TAB1); return FALSE; case KB_SEND_ALL: - PostMessage(windowData->GetHwnd(), WM_COMMAND, IDC_SENDALL, 0); + PostMessage(m_hwnd, WM_COMMAND, IDC_SENDALL, 0); return FALSE; case KB_QUOTE: - PostMessage(windowData->GetHwnd(), WM_COMMAND, IDC_QUOTE, 0); + PostMessage(m_hwnd, WM_COMMAND, IDC_QUOTE, 0); return FALSE; case KB_PASTESEND: if (SendMessage(hwnd, EM_CANPASTE, 0, 0)) { SendMessage(hwnd, EM_PASTESPECIAL, CF_UNICODETEXT, 0); - PostMessage(windowData->GetHwnd(), WM_COMMAND, IDOK, 0); + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); } return FALSE; } @@ -184,7 +184,7 @@ int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriv switch (msg) { case WM_KEYDOWN: if (wParam >= '1' && wParam <= '9' && isCtrl) { - SendMessage(GetParent(windowData->GetHwnd()), CM_ACTIVATEBYINDEX, 0, wParam - '1'); + SendMessage(m_pParent->hwnd, CM_ACTIVATEBYINDEX, 0, wParam - '1'); return 0; } @@ -195,35 +195,35 @@ int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriv return FALSE; if (wParam == 'R' && isCtrl && isShift) { // ctrl-shift-r - SendMessage(windowData->GetHwnd(), DM_SWITCHRTL, 0, 0); + SendMessage(m_hwnd, DM_SWITCHRTL, 0, 0); return FALSE; } if ((wParam == VK_UP || wParam == VK_DOWN) && isCtrl && !db_get_b(0, SRMM_MODULE, SRMSGSET_AUTOCLOSE, SRMSGDEFSET_AUTOCLOSE)) { - if (windowData->cmdList) { + if (cmdList) { TCmdList *cmdListNew = nullptr; if (wParam == VK_UP) { - if (windowData->cmdListCurrent == nullptr) { - cmdListNew = tcmdlist_last(windowData->cmdList); + if (cmdListCurrent == nullptr) { + cmdListNew = tcmdlist_last(cmdList); while (cmdListNew != nullptr && cmdListNew->temporary) { - windowData->cmdList = tcmdlist_remove(windowData->cmdList, cmdListNew); - cmdListNew = tcmdlist_last(windowData->cmdList); + cmdList = tcmdlist_remove(cmdList, cmdListNew); + cmdListNew = tcmdlist_last(cmdList); } if (cmdListNew != nullptr) { char *textBuffer = GetRichTextUtf(hwnd); if (textBuffer != nullptr) // takes textBuffer to a queue, no leak here - windowData->cmdList = tcmdlist_append(windowData->cmdList, textBuffer, 20, TRUE); + cmdList = tcmdlist_append(cmdList, textBuffer, 20, TRUE); } } - else if (windowData->cmdListCurrent->prev != nullptr) - cmdListNew = windowData->cmdListCurrent->prev; + else if (cmdListCurrent->prev != nullptr) + cmdListNew = cmdListCurrent->prev; } else { - if (windowData->cmdListCurrent != nullptr) { - if (windowData->cmdListCurrent->next != nullptr) - cmdListNew = windowData->cmdListCurrent->next; - else if (!windowData->cmdListCurrent->temporary) + if (cmdListCurrent != nullptr) { + if (cmdListCurrent->next != nullptr) + cmdListNew = cmdListCurrent->next; + else if (!cmdListCurrent->temporary) SetWindowText(hwnd, L""); } } @@ -236,7 +236,7 @@ int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriv SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE); SendMessage(hwnd, EM_SETSEL, iLen, iLen); - windowData->cmdListCurrent = cmdListNew; + cmdListCurrent = cmdListNew; } } return FALSE; @@ -245,11 +245,11 @@ int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriv case WM_SYSKEYDOWN: if ((wParam == VK_LEFT) && isAlt) { - SendMessage(GetParent(windowData->GetHwnd()), CM_ACTIVATEPREV, 0, (LPARAM)windowData->GetHwnd()); + SendMessage(m_pParent->hwnd, CM_ACTIVATEPREV, 0, (LPARAM)m_hwnd); return 0; } if ((wParam == VK_RIGHT) && isAlt) { - SendMessage(GetParent(windowData->GetHwnd()), CM_ACTIVATENEXT, 0, (LPARAM)windowData->GetHwnd()); + SendMessage(m_pParent->hwnd, CM_ACTIVATENEXT, 0, (LPARAM)m_hwnd); return 0; } break; diff --git a/plugins/Scriver/src/input.h b/plugins/Scriver/src/input.h index 067820a2fe..1f336f75a4 100644 --- a/plugins/Scriver/src/input.h +++ b/plugins/Scriver/src/input.h @@ -25,6 +25,5 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void InputAreaContextMenu(HWND hwnd, WPARAM wParam, LPARAM lParam, MCONTACT hContact); void RegisterKeyBindings(); -int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriverWindow *windowData); #endif diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp index 3684c2c52a..4ff67f7b9a 100644 --- a/plugins/Scriver/src/msgdialog.cpp +++ b/plugins/Scriver/src/msgdialog.cpp @@ -148,440 +148,8 @@ static void AddToFileList(wchar_t ***pppFiles, int *totalCount, const wchar_t* s } } -void CSrmmWindow::SetDialogToType() -{ - BOOL showToolbar = SendMessage(m_hwndParent, CM_GETTOOLBARSTATUS, 0, 0); - if (m_hContact == 0) - showToolbar = false; - - ParentWindowData *pdat = m_pParent; - if (pdat->flags2 & SMF2_SHOWINFOBAR) - ShowWindow(m_hwndInfo, SW_SHOW); - else - ShowWindow(m_hwndInfo, SW_HIDE); - - ShowWindow(m_message.GetHwnd(), SW_SHOW); - if (m_hwndIeview != nullptr) - ShowWindow(m_log.GetHwnd(), SW_HIDE); - else - ShowWindow(m_log.GetHwnd(), SW_SHOW); - - ShowWindow(m_splitter.GetHwnd(), SW_SHOW); - UpdateReadChars(); - EnableWindow(GetDlgItem(m_hwnd, IDOK), GetRichTextLength(m_message.GetHwnd(), 1200, FALSE) ? TRUE : FALSE); - SendMessage(m_hwnd, DM_CLISTSETTINGSCHANGED, 0, 0); - SendMessage(m_hwnd, WM_SIZE, 0, 0); -} - -void CSrmmWindow::SetStatusIcon() -{ - if (m_szProto == nullptr) - return; - - MCONTACT hContact = db_mc_getSrmmSub(m_hContact); - if (hContact == 0) - hContact = m_hContact; - - char *szProto = GetContactProto(hContact); - m_hStatusIcon = Skin_LoadProtoIcon(szProto, m_wStatus, false); - m_hStatusIconBig = Skin_LoadProtoIcon(szProto, m_wStatus, true); - - if (m_hStatusIconOverlay != nullptr) - DestroyIcon(m_hStatusIconOverlay); - - int index = ImageList_ReplaceIcon(g_dat.hHelperIconList, 0, m_hStatusIcon); - m_hStatusIconOverlay = ImageList_GetIcon(g_dat.hHelperIconList, index, ILD_TRANSPARENT | INDEXTOOVERLAYMASK(1)); -} - -void CSrmmWindow::GetTitlebarIcon(TitleBarData *tbd) -{ - if (m_bShowTyping && (g_dat.flags2 & SMF2_SHOWTYPINGWIN)) - tbd->hIconNot = tbd->hIcon = GetCachedIcon("scriver_TYPING"); - else if (m_iShowUnread && (GetActiveWindow() != m_hwndParent || GetForegroundWindow() != m_hwndParent)) { - tbd->hIcon = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIcon : g_dat.hMsgIcon; - tbd->hIconNot = (g_dat.flags & SMF_STATUSICON) ? g_dat.hMsgIcon : GetCachedIcon("scriver_OVERLAY"); - } - else { - tbd->hIcon = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIcon : g_dat.hMsgIcon; - tbd->hIconNot = nullptr; - } - tbd->hIconBig = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIconBig : g_dat.hMsgIconBig; -} - -HICON CSrmmWindow::GetTabIcon() -{ - if (m_bShowTyping) - return GetCachedIcon("scriver_TYPING"); - - if (m_iShowUnread != 0) - return m_hStatusIconOverlay; - - return m_hStatusIcon; -} - -static LRESULT CALLBACK LogEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static BOOL inMenu = FALSE; - switch (msg) { - case WM_MEASUREITEM: - MeasureMenuItem(wParam, lParam); - return TRUE; - - case WM_DRAWITEM: - return DrawMenuItem(wParam, lParam); - - case WM_SETCURSOR: - if (inMenu) { - SetCursor(LoadCursor(nullptr, IDC_ARROW)); - return TRUE; - } - break; - - case WM_CONTEXTMENU: - HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hSubMenu = GetSubMenu(hMenu, 0); - 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); - - POINT pt; - if (lParam == 0xFFFFFFFF) { - 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); - } - - POINTL ptl = { (LONG)pt.x, (LONG)pt.y }; - ScreenToClient(hwnd, (LPPOINT)&ptl); - ptrW pszWord(GetRichTextWord(hwnd, &ptl)); - if (pszWord && pszWord[0]) { - wchar_t szMenuText[4096]; - mir_snwprintf(szMenuText, TranslateT("Look up '%s':"), pszWord); - ModifyMenu(hSubMenu, 5, MF_STRING | MF_BYPOSITION, 5, szMenuText); - SetSearchEngineIcons(hMenu, g_dat.hSearchEngineIconList); - } - else ModifyMenu(hSubMenu, 5, MF_STRING | MF_GRAYED | MF_BYPOSITION, 5, TranslateT("No word to look up")); - - inMenu = TRUE; - int uID = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, nullptr); - inMenu = FALSE; - - switch (uID) { - case IDM_COPY: - SendMessage(hwnd, WM_COPY, 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; - case IDM_CLEAR: - SendMessage(GetParent(hwnd), DM_CLEARLOG, 0, 0); - break; - case IDM_SEARCH_GOOGLE: - case IDM_SEARCH_BING: - case IDM_SEARCH_YANDEX: - case IDM_SEARCH_YAHOO: - case IDM_SEARCH_WIKIPEDIA: - case IDM_SEARCH_FOODNETWORK: - case IDM_SEARCH_GOOGLE_MAPS: - case IDM_SEARCH_GOOGLE_TRANSLATE: - SearchWord(pszWord, uID - IDM_SEARCH_GOOGLE + SEARCHENGINE_GOOGLE); - PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0); - break; - } - DestroyMenu(hMenu); - return TRUE; - } - return mir_callNextSubclass(hwnd, LogEditSubclassProc, msg, wParam, lParam); -} - ///////////////////////////////////////////////////////////////////////////////////////// -struct MsgEditSubclassData -{ - DWORD lastEnterTime; -}; - -static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - MsgEditSubclassData *dat = (MsgEditSubclassData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - CSrmmWindow *pdat = (CSrmmWindow*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - - int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, pdat); - if (result != -1) - return result; - - BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; - BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; - - switch (msg) { - case EM_SUBCLASSED: - dat = (MsgEditSubclassData*)mir_alloc(sizeof(MsgEditSubclassData)); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); - DragAcceptFiles(hwnd, TRUE); - dat->lastEnterTime = 0; - return 0; - - case WM_KEYDOWN: - if (wParam == VK_RETURN) { - if ((isCtrl != 0) ^ (0 != (g_dat.flags & SMF_SENDONENTER))) { - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - if (g_dat.flags & SMF_SENDONDBLENTER) { - if (dat->lastEnterTime + ENTERCLICKTIME < GetTickCount()) - dat->lastEnterTime = GetTickCount(); - else { - SendMessage(hwnd, WM_KEYDOWN, VK_BACK, 0); - SendMessage(hwnd, WM_KEYUP, VK_BACK, 0); - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - } - } - else dat->lastEnterTime = 0; - break; - - case WM_MOUSEWHEEL: - if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_VSCROLL) == 0) - SendDlgItemMessage(GetParent(hwnd), IDC_LOG, WM_MOUSEWHEEL, wParam, lParam); - break; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_KILLFOCUS: - dat->lastEnterTime = 0; - break; - - case WM_SYSCHAR: - dat->lastEnterTime = 0; - if ((wParam == 's' || wParam == 'S') && isAlt) { - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - break; - - case EM_PASTESPECIAL: - case WM_PASTE: - if (IsClipboardFormatAvailable(CF_HDROP)) { - if (OpenClipboard(hwnd)) { - HANDLE hDrop = GetClipboardData(CF_HDROP); - if (hDrop) - SendMessage(GetParent(hwnd), WM_DROPFILES, (WPARAM)hDrop, 0); - CloseClipboard(); - } - return 0; - } - break; - - case WM_DROPFILES: - SendMessage(GetParent(hwnd), WM_DROPFILES, wParam, lParam); - return 0; - - case WM_CONTEXTMENU: - InputAreaContextMenu(hwnd, wParam, lParam, pdat->m_hContact); - return TRUE; - - case WM_DESTROY: - mir_free(dat); - break; - } - return mir_callNextSubclass(hwnd, MessageEditSubclassProc, msg, wParam, lParam); -} - -static void SubclassMessageEdit(HWND hwnd) -{ - RichUtil_SubClass(hwnd); - mir_subclassWindow(hwnd, MessageEditSubclassProc); - SendMessage(hwnd, EM_SUBCLASSED, 0, 0); -} - -static void SubclassLogEdit(HWND hwnd) -{ - RichUtil_SubClass(hwnd); - mir_subclassWindow(hwnd, LogEditSubclassProc); - SendMessage(hwnd, EM_SUBCLASSED, 0, 0); -} - -void CSrmmWindow::MessageDialogResize(int w, int h) -{ - ParentWindowData *pdat = m_pParent; - bool bToolbar = (pdat->flags2 & SMF2_SHOWTOOLBAR) != 0; - int hSplitterPos = pdat->iSplitterY, toolbarHeight = (bToolbar) ? m_toolbarSize.cy : 0; - int hSplitterMinTop = toolbarHeight + m_minLogBoxHeight, hSplitterMinBottom = m_minEditBoxHeight; - int infobarInnerHeight = INFO_BAR_INNER_HEIGHT; - int infobarHeight = INFO_BAR_HEIGHT; - int avatarWidth = 0, avatarHeight = 0; - int toolbarWidth = w; - int messageEditWidth = w - 2; - - if (hSplitterMinBottom < g_dat.minInputAreaHeight) - hSplitterMinBottom = g_dat.minInputAreaHeight; - - if (!(pdat->flags2 & SMF2_SHOWINFOBAR)) { - infobarHeight = 0; - infobarInnerHeight = 0; - } - - if (hSplitterPos > (h - toolbarHeight - infobarHeight + SPLITTER_HEIGHT + 1) / 2) - hSplitterPos = (h - toolbarHeight - infobarHeight + SPLITTER_HEIGHT + 1) / 2; - - if (h - hSplitterPos - infobarHeight < hSplitterMinTop) - hSplitterPos = h - hSplitterMinTop - infobarHeight; - - if (hSplitterPos < avatarHeight) - hSplitterPos = avatarHeight; - - if (hSplitterPos < hSplitterMinBottom) - hSplitterPos = hSplitterMinBottom; - - if (!(pdat->flags2 & SMF2_SHOWINFOBAR)) { - if (m_hbmpAvatarPic && (g_dat.flags & SMF_AVATAR)) { - avatarWidth = BOTTOM_RIGHT_AVATAR_HEIGHT; - avatarHeight = toolbarHeight + hSplitterPos - 2; - if (avatarHeight < BOTTOM_RIGHT_AVATAR_HEIGHT) { - avatarHeight = BOTTOM_RIGHT_AVATAR_HEIGHT; - hSplitterPos = avatarHeight - toolbarHeight + 2; - } - else avatarHeight = BOTTOM_RIGHT_AVATAR_HEIGHT; - - avatarWidth = avatarHeight; - if (avatarWidth > BOTTOM_RIGHT_AVATAR_HEIGHT && avatarWidth > w / 4) - avatarWidth = w / 4; - - if ((toolbarWidth - avatarWidth - 2) < m_toolbarSize.cx) - avatarWidth = toolbarWidth - m_toolbarSize.cx - 2; - - toolbarWidth -= avatarWidth + 2; - messageEditWidth -= avatarWidth + 1; - } - } - - pdat->iSplitterY = hSplitterPos; - - int logY = infobarInnerHeight; - int logH = h - hSplitterPos - toolbarHeight - infobarInnerHeight; - - HDWP hdwp = BeginDeferWindowPos(5); - hdwp = DeferWindowPos(hdwp, m_hwndInfo, 0, 1, 0, w - 2, infobarInnerHeight - 2, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), 0, 1, logY, w - 2, logH, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_message.GetHwnd(), 0, 1, h - hSplitterPos + SPLITTER_HEIGHT, messageEditWidth, hSplitterPos - SPLITTER_HEIGHT - 1, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_AVATAR), 0, w - avatarWidth - 1, h - (avatarHeight + avatarWidth) / 2 - 1, avatarWidth, avatarWidth, SWP_NOZORDER); - hdwp = DeferWindowPos(hdwp, m_splitter.GetHwnd(), 0, 0, h - hSplitterPos - 1, toolbarWidth, SPLITTER_HEIGHT, SWP_NOZORDER); - EndDeferWindowPos(hdwp); - - SetButtonsPos(m_hwnd, m_hContact, bToolbar); - - if (m_hwndIeview != nullptr) { - IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; - ieWindow.iType = IEW_SETPOS; - ieWindow.parent = m_hwnd; - ieWindow.hwnd = m_hwndIeview; - ieWindow.x = 0; - ieWindow.y = logY; - ieWindow.cx = w; - ieWindow.cy = logH; - CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); - } - else RedrawWindow(m_log.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); - - RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); - - RefreshInfobar(); - - RedrawWindow(GetDlgItem(m_hwnd, IDC_AVATAR), nullptr, nullptr, RDW_INVALIDATE); -} - -void CSrmmWindow::UpdateReadChars() -{ - if (m_pParent->hwndActive == m_hwnd) { - wchar_t szText[256]; - int len = GetRichTextLength(m_message.GetHwnd(), 1200, FALSE); - - StatusBarData sbd; - sbd.iItem = 1; - sbd.iFlags = SBDF_TEXT | SBDF_ICON; - sbd.hIcon = nullptr; - sbd.pszText = szText; - mir_snwprintf(szText, L"%d", len); - SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd); - } -} - -void CSrmmWindow::ShowAvatar() -{ - INT_PTR res = CallService(MS_AV_GETAVATARBITMAP, m_hContact, 0); - m_ace = res != CALLSERVICE_NOTFOUND ? (AVATARCACHEENTRY*)res : nullptr; - m_hbmpAvatarPic = (m_ace != nullptr && (m_ace->dwFlags & AVS_HIDEONCLIST) == 0) ? m_ace->hbmPic : nullptr; - SendMessage(m_hwnd, WM_SIZE, 0, 0); - - RefreshInfobar(); - - RedrawWindow(GetDlgItem(m_hwnd, IDC_AVATAR), nullptr, nullptr, RDW_INVALIDATE); -} - -bool CSrmmWindow::IsTypingNotificationSupported() -{ - if (!m_hContact || !m_szProto) - return false; - - DWORD typeCaps = CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_4, 0); - if (!(typeCaps & PF4_SUPPORTTYPING)) - return false; - return true; -} - -bool CSrmmWindow::IsTypingNotificationEnabled() -{ - if (!db_get_b(m_hContact, SRMM_MODULE, SRMSGSET_TYPING, db_get_b(0, SRMM_MODULE, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW))) - return FALSE; - - DWORD protoStatus = CallProtoService(m_szProto, PS_GETSTATUS, 0, 0); - if (protoStatus < ID_STATUS_ONLINE) - return FALSE; - - DWORD protoCaps = CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_1, 0); - if (protoCaps & PF1_VISLIST && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE) - return FALSE; - - if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) != ID_STATUS_ONLINE) - return FALSE; - - if (db_get_b(m_hContact, "CList", "NotOnList", 0) - && !db_get_b(0, SRMM_MODULE, SRMSGSET_TYPINGUNKNOWN, SRMSGDEFSET_TYPINGUNKNOWN)) - return FALSE; - return TRUE; -} - -// Don't send to protocols who don't support typing -// Don't send to users who are unchecked in the typing notification options -// Don't send to protocols that are offline -// Don't send to users who are not visible and -// Don't send to users who are not on the visible list when you are in invisible mode. -void CSrmmWindow::NotifyTyping(int mode) -{ - if (!IsTypingNotificationSupported()) - return; - - if (!IsTypingNotificationEnabled()) - return; - - // End user check - m_nTypeMode = mode; - CallService(MS_PROTO_SELFISTYPING, m_hContact, m_nTypeMode); -} - static INT_PTR CALLBACK ConfirmSendAllDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM) { switch (msg) { @@ -750,8 +318,9 @@ void CSrmmWindow::OnInitDialog() // get around a lame bug in the Windows template resource code where richedits are limited to 0x7FFF m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); - SubclassLogEdit(m_log.GetHwnd()); - SubclassMessageEdit(m_message.GetHwnd()); + ::RichUtil_SubClass(m_log.GetHwnd()); + ::RichUtil_SubClass(m_message.GetHwnd()); + ::DragAcceptFiles(m_message.GetHwnd(), TRUE); CreateInfobar(); if (m_bUseIEView) { @@ -899,6 +468,8 @@ void CSrmmWindow::OnDestroy() NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE); } +///////////////////////////////////////////////////////////////////////////////////////// + void CSrmmWindow::onClick_Ok(CCtrlButton *pButton) { if (!m_btnOk.Enabled() || m_hContact == 0) @@ -1052,11 +623,148 @@ void CSrmmWindow::onChange_Message(CCtrlEdit*) } } -void CSrmmWindow::onChanged_Splitter(CSplitter *pSplitter) +void CSrmmWindow::onChanged_Splitter(CSplitter *pSplitter) +{ + RECT rc; + GetClientRect(m_hwnd, &rc); + m_pParent->iSplitterY = rc.bottom - pSplitter->GetPos(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +HICON CSrmmWindow::GetTabIcon() +{ + if (m_bShowTyping) + return GetCachedIcon("scriver_TYPING"); + + if (m_iShowUnread != 0) + return m_hStatusIconOverlay; + + return m_hStatusIcon; +} + +void CSrmmWindow::GetTitlebarIcon(TitleBarData *tbd) +{ + if (m_bShowTyping && (g_dat.flags2 & SMF2_SHOWTYPINGWIN)) + tbd->hIconNot = tbd->hIcon = GetCachedIcon("scriver_TYPING"); + else if (m_iShowUnread && (GetActiveWindow() != m_hwndParent || GetForegroundWindow() != m_hwndParent)) { + tbd->hIcon = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIcon : g_dat.hMsgIcon; + tbd->hIconNot = (g_dat.flags & SMF_STATUSICON) ? g_dat.hMsgIcon : GetCachedIcon("scriver_OVERLAY"); + } + else { + tbd->hIcon = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIcon : g_dat.hMsgIcon; + tbd->hIconNot = nullptr; + } + tbd->hIconBig = (g_dat.flags & SMF_STATUSICON) ? m_hStatusIconBig : g_dat.hMsgIconBig; +} + +bool CSrmmWindow::IsTypingNotificationSupported() +{ + if (!m_hContact || !m_szProto) + return false; + + DWORD typeCaps = CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_4, 0); + if (!(typeCaps & PF4_SUPPORTTYPING)) + return false; + return true; +} + +bool CSrmmWindow::IsTypingNotificationEnabled() +{ + if (!db_get_b(m_hContact, SRMM_MODULE, SRMSGSET_TYPING, db_get_b(0, SRMM_MODULE, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW))) + return FALSE; + + DWORD protoStatus = CallProtoService(m_szProto, PS_GETSTATUS, 0, 0); + if (protoStatus < ID_STATUS_ONLINE) + return FALSE; + + DWORD protoCaps = CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_1, 0); + if (protoCaps & PF1_VISLIST && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE) + return FALSE; + + if (protoCaps & PF1_INVISLIST && protoStatus == ID_STATUS_INVISIBLE && db_get_w(m_hContact, m_szProto, "ApparentMode", 0) != ID_STATUS_ONLINE) + return FALSE; + + if (db_get_b(m_hContact, "CList", "NotOnList", 0) + && !db_get_b(0, SRMM_MODULE, SRMSGSET_TYPINGUNKNOWN, SRMSGDEFSET_TYPINGUNKNOWN)) + return FALSE; + return TRUE; +} + +// Don't send to protocols who don't support typing +// Don't send to users who are unchecked in the typing notification options +// Don't send to protocols that are offline +// Don't send to users who are not visible and +// Don't send to users who are not on the visible list when you are in invisible mode. + +void CSrmmWindow::NotifyTyping(int mode) +{ + if (!IsTypingNotificationSupported()) + return; + + if (!IsTypingNotificationEnabled()) + return; + + // End user check + m_nTypeMode = mode; + CallService(MS_PROTO_SELFISTYPING, m_hContact, m_nTypeMode); +} + +void CSrmmWindow::SetDialogToType() +{ + BOOL showToolbar = SendMessage(m_hwndParent, CM_GETTOOLBARSTATUS, 0, 0); + if (m_hContact == 0) + showToolbar = false; + + ParentWindowData *pdat = m_pParent; + if (pdat->flags2 & SMF2_SHOWINFOBAR) + ShowWindow(m_hwndInfo, SW_SHOW); + else + ShowWindow(m_hwndInfo, SW_HIDE); + + ShowWindow(m_message.GetHwnd(), SW_SHOW); + if (m_hwndIeview != nullptr) + ShowWindow(m_log.GetHwnd(), SW_HIDE); + else + ShowWindow(m_log.GetHwnd(), SW_SHOW); + + ShowWindow(m_splitter.GetHwnd(), SW_SHOW); + UpdateReadChars(); + EnableWindow(GetDlgItem(m_hwnd, IDOK), GetRichTextLength(m_message.GetHwnd(), 1200, FALSE) ? TRUE : FALSE); + SendMessage(m_hwnd, DM_CLISTSETTINGSCHANGED, 0, 0); + SendMessage(m_hwnd, WM_SIZE, 0, 0); +} + +void CSrmmWindow::SetStatusIcon() +{ + if (m_szProto == nullptr) + return; + + MCONTACT hContact = db_mc_getSrmmSub(m_hContact); + if (hContact == 0) + hContact = m_hContact; + + char *szProto = GetContactProto(hContact); + m_hStatusIcon = Skin_LoadProtoIcon(szProto, m_wStatus, false); + m_hStatusIconBig = Skin_LoadProtoIcon(szProto, m_wStatus, true); + + if (m_hStatusIconOverlay != nullptr) + DestroyIcon(m_hStatusIconOverlay); + + int index = ImageList_ReplaceIcon(g_dat.hHelperIconList, 0, m_hStatusIcon); + m_hStatusIconOverlay = ImageList_GetIcon(g_dat.hHelperIconList, index, ILD_TRANSPARENT | INDEXTOOVERLAYMASK(1)); +} + +void CSrmmWindow::ShowAvatar() { - RECT rc; - GetClientRect(m_hwnd, &rc); - m_pParent->iSplitterY = rc.bottom - pSplitter->GetPos(); + INT_PTR res = CallService(MS_AV_GETAVATARBITMAP, m_hContact, 0); + m_ace = res != CALLSERVICE_NOTFOUND ? (AVATARCACHEENTRY*)res : nullptr; + m_hbmpAvatarPic = (m_ace != nullptr && (m_ace->dwFlags & AVS_HIDEONCLIST) == 0) ? m_ace->hbmPic : nullptr; + SendMessage(m_hwnd, WM_SIZE, 0, 0); + + RefreshInfobar(); + + RedrawWindow(GetDlgItem(m_hwnd, IDC_AVATAR), nullptr, nullptr, RDW_INVALIDATE); } void CSrmmWindow::UpdateStatusBar() @@ -1103,6 +811,22 @@ void CSrmmWindow::UpdateStatusBar() } } +void CSrmmWindow::UpdateReadChars() +{ + if (m_pParent->hwndActive == m_hwnd) { + wchar_t szText[256]; + int len = GetRichTextLength(m_message.GetHwnd(), 1200, FALSE); + + StatusBarData sbd; + sbd.iItem = 1; + sbd.iFlags = SBDF_TEXT | SBDF_ICON; + sbd.hIcon = nullptr; + sbd.pszText = szText; + mir_snwprintf(szText, L"%d", len); + SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd); + } +} + ///////////////////////////////////////////////////////////////////////////////////////// static const wchar_t *titleTokenNames[] = { L"%name%", L"%status%", L"%statusmsg%", L"%account%" }; @@ -1146,6 +870,263 @@ void CSrmmWindow::UpdateTitle() ///////////////////////////////////////////////////////////////////////////////////////// +void CSrmmWindow::MessageDialogResize(int w, int h) +{ + ParentWindowData *pdat = m_pParent; + bool bToolbar = (pdat->flags2 & SMF2_SHOWTOOLBAR) != 0; + int hSplitterPos = pdat->iSplitterY, toolbarHeight = (bToolbar) ? m_toolbarSize.cy : 0; + int hSplitterMinTop = toolbarHeight + m_minLogBoxHeight, hSplitterMinBottom = m_minEditBoxHeight; + int infobarInnerHeight = INFO_BAR_INNER_HEIGHT; + int infobarHeight = INFO_BAR_HEIGHT; + int avatarWidth = 0, avatarHeight = 0; + int toolbarWidth = w; + int messageEditWidth = w - 2; + + if (hSplitterMinBottom < g_dat.minInputAreaHeight) + hSplitterMinBottom = g_dat.minInputAreaHeight; + + if (!(pdat->flags2 & SMF2_SHOWINFOBAR)) { + infobarHeight = 0; + infobarInnerHeight = 0; + } + + if (hSplitterPos >(h - toolbarHeight - infobarHeight + SPLITTER_HEIGHT + 1) / 2) + hSplitterPos = (h - toolbarHeight - infobarHeight + SPLITTER_HEIGHT + 1) / 2; + + if (h - hSplitterPos - infobarHeight < hSplitterMinTop) + hSplitterPos = h - hSplitterMinTop - infobarHeight; + + if (hSplitterPos < avatarHeight) + hSplitterPos = avatarHeight; + + if (hSplitterPos < hSplitterMinBottom) + hSplitterPos = hSplitterMinBottom; + + if (!(pdat->flags2 & SMF2_SHOWINFOBAR)) { + if (m_hbmpAvatarPic && (g_dat.flags & SMF_AVATAR)) { + avatarWidth = BOTTOM_RIGHT_AVATAR_HEIGHT; + avatarHeight = toolbarHeight + hSplitterPos - 2; + if (avatarHeight < BOTTOM_RIGHT_AVATAR_HEIGHT) { + avatarHeight = BOTTOM_RIGHT_AVATAR_HEIGHT; + hSplitterPos = avatarHeight - toolbarHeight + 2; + } + else avatarHeight = BOTTOM_RIGHT_AVATAR_HEIGHT; + + avatarWidth = avatarHeight; + if (avatarWidth > BOTTOM_RIGHT_AVATAR_HEIGHT && avatarWidth > w / 4) + avatarWidth = w / 4; + + if ((toolbarWidth - avatarWidth - 2) < m_toolbarSize.cx) + avatarWidth = toolbarWidth - m_toolbarSize.cx - 2; + + toolbarWidth -= avatarWidth + 2; + messageEditWidth -= avatarWidth + 1; + } + } + + pdat->iSplitterY = hSplitterPos; + + int logY = infobarInnerHeight; + int logH = h - hSplitterPos - toolbarHeight - infobarInnerHeight; + + HDWP hdwp = BeginDeferWindowPos(5); + hdwp = DeferWindowPos(hdwp, m_hwndInfo, 0, 1, 0, w - 2, infobarInnerHeight - 2, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), 0, 1, logY, w - 2, logH, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_message.GetHwnd(), 0, 1, h - hSplitterPos + SPLITTER_HEIGHT, messageEditWidth, hSplitterPos - SPLITTER_HEIGHT - 1, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_AVATAR), 0, w - avatarWidth - 1, h - (avatarHeight + avatarWidth) / 2 - 1, avatarWidth, avatarWidth, SWP_NOZORDER); + hdwp = DeferWindowPos(hdwp, m_splitter.GetHwnd(), 0, 0, h - hSplitterPos - 1, toolbarWidth, SPLITTER_HEIGHT, SWP_NOZORDER); + EndDeferWindowPos(hdwp); + + SetButtonsPos(m_hwnd, m_hContact, bToolbar); + + if (m_hwndIeview != nullptr) { + IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; + ieWindow.iType = IEW_SETPOS; + ieWindow.parent = m_hwnd; + ieWindow.hwnd = m_hwndIeview; + ieWindow.x = 0; + ieWindow.y = logY; + ieWindow.cx = w; + ieWindow.cy = logH; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow); + } + else RedrawWindow(m_log.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + + RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + + RefreshInfobar(); + + RedrawWindow(GetDlgItem(m_hwnd, IDC_AVATAR), nullptr, nullptr, RDW_INVALIDATE); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +LRESULT CSrmmWindow::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL inMenu = FALSE; + switch (msg) { + case WM_MEASUREITEM: + MeasureMenuItem(wParam, lParam); + return TRUE; + + case WM_DRAWITEM: + return DrawMenuItem(wParam, lParam); + + case WM_SETCURSOR: + if (inMenu) { + SetCursor(LoadCursor(nullptr, IDC_ARROW)); + return TRUE; + } + break; + + case WM_CONTEXTMENU: + HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)); + HMENU hSubMenu = GetSubMenu(hMenu, 0); + TranslateMenu(hSubMenu); + + CHARRANGE sel, all = { 0, -1 }; + m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin == sel.cpMax) + EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); + + POINT pt; + if (lParam == 0xFFFFFFFF) { + 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); + } + + POINTL ptl = { (LONG)pt.x, (LONG)pt.y }; + ScreenToClient(m_message.GetHwnd(), (LPPOINT)&ptl); + ptrW pszWord(GetRichTextWord(m_message.GetHwnd(), &ptl)); + if (pszWord && pszWord[0]) { + wchar_t szMenuText[4096]; + mir_snwprintf(szMenuText, TranslateT("Look up '%s':"), pszWord); + ModifyMenu(hSubMenu, 5, MF_STRING | MF_BYPOSITION, 5, szMenuText); + SetSearchEngineIcons(hMenu, g_dat.hSearchEngineIconList); + } + else ModifyMenu(hSubMenu, 5, MF_STRING | MF_GRAYED | MF_BYPOSITION, 5, TranslateT("No word to look up")); + + inMenu = TRUE; + int uID = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_message.GetHwnd(), nullptr); + inMenu = FALSE; + + switch (uID) { + case IDM_COPY: + m_log.SendMsg(WM_COPY, 0, 0); + break; + + case IDM_COPYALL: + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + m_log.SendMsg(WM_COPY, 0, 0); + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + break; + + case IDM_SELECTALL: + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + break; + + case IDM_CLEAR: + SendMessage(m_hwnd, DM_CLEARLOG, 0, 0); + break; + + case IDM_SEARCH_GOOGLE: + case IDM_SEARCH_BING: + case IDM_SEARCH_YANDEX: + case IDM_SEARCH_YAHOO: + case IDM_SEARCH_WIKIPEDIA: + case IDM_SEARCH_FOODNETWORK: + case IDM_SEARCH_GOOGLE_MAPS: + case IDM_SEARCH_GOOGLE_TRANSLATE: + SearchWord(pszWord, uID - IDM_SEARCH_GOOGLE + SEARCHENGINE_GOOGLE); + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + break; + } + DestroyMenu(hMenu); + return TRUE; + } + return 0; +} + +LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) +{ + int result = InputAreaShortcuts(m_message.GetHwnd(), msg, wParam, lParam); + if (result != -1) + return result; + + BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; + BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; + + switch (msg) { + case WM_KEYDOWN: + if (wParam == VK_RETURN) { + if ((isCtrl != 0) ^ (0 != (g_dat.flags & SMF_SENDONENTER))) { + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + return 0; + } + if (g_dat.flags & SMF_SENDONDBLENTER) { + if (m_iLastEnterTime + ENTERCLICKTIME < GetTickCount()) + m_iLastEnterTime = GetTickCount(); + else { + m_log.SendMsg(WM_KEYDOWN, VK_BACK, 0); + m_log.SendMsg(WM_KEYUP, VK_BACK, 0); + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + return 0; + } + } + } + else m_iLastEnterTime = 0; + break; + + case WM_MOUSEWHEEL: + if ((GetWindowLongPtr(m_message.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0) + SendDlgItemMessage(m_hwnd, IDC_LOG, WM_MOUSEWHEEL, wParam, lParam); + break; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_KILLFOCUS: + m_iLastEnterTime = 0; + break; + + case WM_SYSCHAR: + m_iLastEnterTime = 0; + if ((wParam == 's' || wParam == 'S') && isAlt) { + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + return 0; + } + break; + + case EM_PASTESPECIAL: + case WM_PASTE: + if (IsClipboardFormatAvailable(CF_HDROP)) { + if (OpenClipboard(m_message.GetHwnd())) { + HANDLE hDrop = GetClipboardData(CF_HDROP); + if (hDrop) + SendMessage(m_hwnd, WM_DROPFILES, (WPARAM)hDrop, 0); + CloseClipboard(); + } + return 0; + } + break; + + case WM_DROPFILES: + SendMessage(m_hwnd, WM_DROPFILES, wParam, lParam); + return 0; + + case WM_CONTEXTMENU: + InputAreaContextMenu(m_message.GetHwnd(), wParam, lParam, m_hContact); + return TRUE; + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) { PARAFORMAT2 pf2; @@ -1724,7 +1705,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) switch (pNmhdr->code) { case EN_MSGFILTER: { - int result = InputAreaShortcuts(m_message.GetHwnd(), ((MSGFILTER *)lParam)->msg, ((MSGFILTER *)lParam)->wParam, ((MSGFILTER *)lParam)->lParam, this); + int result = InputAreaShortcuts(m_message.GetHwnd(), ((MSGFILTER *)lParam)->msg, ((MSGFILTER *)lParam)->wParam, ((MSGFILTER *)lParam)->lParam); if (result != -1) { SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE); return TRUE; diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h index a160e2c654..7cad122c1f 100644 --- a/plugins/Scriver/src/msgs.h +++ b/plugins/Scriver/src/msgs.h @@ -87,9 +87,12 @@ struct ParentWindowData class CScriverWindow : public CSrmmBaseDialog { + protected: CScriverWindow(int iDialog, SESSION_INFO* = nullptr); + int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + public: virtual void CloseTab() override; virtual void LoadSettings() override; @@ -105,7 +108,10 @@ class CSrmmWindow : public CScriverWindow CCtrlEdit m_log, m_message; CCtrlButton m_btnOk, m_btnAdd, m_btnUserMenu, m_btnQuote, m_btnDetails; CSplitter m_splitter; - + + virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam); + virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam); + wchar_t *m_wszInitialText; bool m_bIncoming, m_bShowTyping; @@ -182,14 +188,17 @@ class CChatRoomDlg : public CScriverWindow CSplitter m_splitterX, m_splitterY; void MessageDialogResize(int w, int h); + void TabAutoComplete(void); + + 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 LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -public: wchar_t m_wszSearch[255]; + wchar_t *m_wszSearchQuery, *m_wszSearchResult; + SESSION_INFO *m_pLastSession; public: CChatRoomDlg(SESSION_INFO *si); -- cgit v1.2.3