From ee04e9de4bd7c4858de7716868cd6a1aad93b824 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 23 Mar 2017 19:50:37 +0300 Subject: StdMsg: windows procs virtualization --- src/core/stdmsg/src/chat_util.cpp | 22 +- src/core/stdmsg/src/chat_window.cpp | 1673 +++++++++++++++++------------------ src/core/stdmsg/src/msgdialog.cpp | 617 +++++++------ src/core/stdmsg/src/msgs.h | 7 + src/core/stdmsg/src/stdafx.h | 9 +- 5 files changed, 1145 insertions(+), 1183 deletions(-) (limited to 'src/core') diff --git a/src/core/stdmsg/src/chat_util.cpp b/src/core/stdmsg/src/chat_util.cpp index e1ee1b2f96..cdd53ef2cf 100644 --- a/src/core/stdmsg/src/chat_util.cpp +++ b/src/core/stdmsg/src/chat_util.cpp @@ -48,17 +48,17 @@ void CChatRoomDlg::StreamInEvents(LOGINFO *lin, bool bRedraw) GetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll); POINT point = {}; - SendMessage(m_log.GetHwnd(), EM_GETSCROLLPOS, 0, (LPARAM)&point); + m_log.SendMsg(EM_GETSCROLLPOS, 0, (LPARAM)&point); // do not scroll to bottom if there is a selection CHARRANGE oldsel, sel; - SendMessage(m_log.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)&oldsel); + m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&oldsel); if (oldsel.cpMax != oldsel.cpMin) - SendMessage(m_log.GetHwnd(), WM_SETREDRAW, FALSE, 0); + m_log.SendMsg(WM_SETREDRAW, FALSE, 0); //set the insertion point at the bottom sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd()); - SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel); + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); // fix for the indent... must be a M$ bug if (sel.cpMax == 0) @@ -73,14 +73,14 @@ void CChatRoomDlg::StreamInEvents(LOGINFO *lin, bool bRedraw) pci->logPixelSY = GetDeviceCaps(hdc, LOGPIXELSY); pci->logPixelSX = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(NULL, hdc); - SendMessage(m_log.GetHwnd(), WM_SETREDRAW, FALSE, 0); + m_log.SendMsg(WM_SETREDRAW, FALSE, 0); bFlag = TRUE; } // stream in the event(s) streamData.lin = lin; streamData.bRedraw = bRedraw; - SendMessage(m_log.GetHwnd(), EM_STREAMIN, wp, (LPARAM)&stream); + m_log.SendMsg(EM_STREAMIN, wp, (LPARAM)&stream); // do smileys if (SmileyAddInstalled && (bRedraw || (lin->ptszText && lin->iType != GC_EVENT_JOIN && lin->iType != GC_EVENT_NICK && lin->iType != GC_EVENT_ADDSTATUS && lin->iType != GC_EVENT_REMOVESTATUS))) { @@ -104,20 +104,20 @@ void CChatRoomDlg::StreamInEvents(LOGINFO *lin, bool bRedraw) if (bRedraw || (UINT)scroll.nPos >= (UINT)scroll.nMax - scroll.nPage - 5 || scroll.nMax - scroll.nMin - scroll.nPage < 50) ScrollToBottom(); else - SendMessage(m_log.GetHwnd(), EM_SETSCROLLPOS, 0, (LPARAM)&point); + m_log.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&point); // do we need to restore the selection if (oldsel.cpMax != oldsel.cpMin) { - SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&oldsel); - SendMessage(m_log.GetHwnd(), WM_SETREDRAW, TRUE, 0); + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&oldsel); + m_log.SendMsg(WM_SETREDRAW, TRUE, 0); InvalidateRect(m_log.GetHwnd(), NULL, TRUE); } // need to invalidate the window if (bFlag) { sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd()); - SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel); - SendMessage(m_log.GetHwnd(), WM_SETREDRAW, TRUE, 0); + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + m_log.SendMsg(WM_SETREDRAW, TRUE, 0); InvalidateRect(m_log.GetHwnd(), NULL, TRUE); } } diff --git a/src/core/stdmsg/src/chat_window.cpp b/src/core/stdmsg/src/chat_window.cpp index a0fcc6a308..24057875bc 100644 --- a/src/core/stdmsg/src/chat_window.cpp +++ b/src/core/stdmsg/src/chat_window.cpp @@ -24,413 +24,529 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static HKL hkl = nullptr; -struct MESSAGESUBDATA +static wchar_t szTrimString[] = L":;,.!?\'\"><()[]- \r\n"; + +int GetTextPixelSize(wchar_t *pszText, HFONT hFont, BOOL bWidth) { - SESSION_INFO *si; - time_t lastEnterTime; - wchar_t szTabSave[20]; -}; + if (!pszText || !hFont) + return 0; -static wchar_t szTrimString[] = L":;,.!?\'\"><()[]- \r\n"; + HDC hdc = GetDC(nullptr); + HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); + RECT rc = {}; + DrawText(hdc, pszText, -1, &rc, DT_CALCRECT); + SelectObject(hdc, hOldFont); + ReleaseDC(nullptr, hdc); + return bWidth ? rc.right - rc.left : rc.bottom - rc.top; +} -int CChatRoomDlg::Resizer(UTILRESIZECONTROL *urc) +static void __cdecl phase2(void *lParam) { - SESSION_INFO *si = m_si; + SESSION_INFO *si = (SESSION_INFO*)lParam; + Sleep(30); + if (si && si->pDlg) + si->pDlg->RedrawLog2(); +} - RECT rc; - bool bControl = db_get_b(0, CHAT_MODULE, "ShowTopButtons", 1) != 0; - bool bFormat = db_get_b(0, CHAT_MODULE, "ShowFormatButtons", 1) != 0; - bool bToolbar = bFormat || bControl; - bool bSend = db_get_b(0, CHAT_MODULE, "ShowSend", 0) != 0; - bool bNick = si->iType != GCW_SERVER && m_bNicklistEnabled; +///////////////////////////////////////////////////////////////////////////////////////// - switch (urc->wId) { - case IDOK: - GetWindowRect(m_hwndStatus, &rc); - urc->rcItem.left = bSend ? 315 : urc->dlgNewSize.cx; - urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + 23; - urc->rcItem.bottom = urc->dlgNewSize.cy - (rc.bottom - rc.top) - 1; - return RD_ANCHORX_RIGHT | RD_ANCHORY_CUSTOM; +CChatRoomDlg::CChatRoomDlg(SESSION_INFO *si) : + CSrmmBaseDialog(g_hInst, g_Settings.bTabsEnable ? IDD_CHANNEL_TAB : IDD_CHANNEL, si), + m_message(this, IDC_MESSAGE), + m_log(this, IDC_LOG), - case IDC_LOG: - urc->rcItem.top = 2; - urc->rcItem.left = 0; - urc->rcItem.right = bNick ? urc->dlgNewSize.cx - m_iSplitterX : urc->dlgNewSize.cx; -LBL_CalcBottom: - urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; - if (!bToolbar) - urc->rcItem.bottom += 20; - return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; + m_btnOk(this, IDOK), + + m_splitterX(this, IDC_SPLITTERX), + m_splitterY(this, IDC_SPLITTERY) +{ + m_pLog = &m_log; + m_pEntry = &m_message; - case IDC_SRMM_NICKLIST: - urc->rcItem.top = 2; - urc->rcItem.right = urc->dlgNewSize.cx; - urc->rcItem.left = urc->dlgNewSize.cx - m_iSplitterX + 2; - goto LBL_CalcBottom; + m_autoClose = 0; + m_forceResizable = true; - case IDC_SPLITTERX: - urc->rcItem.top = 1; - urc->rcItem.left = urc->dlgNewSize.cx - m_iSplitterX; - urc->rcItem.right = urc->rcItem.left + 2; - goto LBL_CalcBottom; + m_btnOk.OnClick = Callback(this, &CChatRoomDlg::onClick_Ok); - case IDC_SPLITTERY: - urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY; - if (!bToolbar) - urc->rcItem.top += 20; - urc->rcItem.bottom = urc->rcItem.top + 2; - return RD_ANCHORX_WIDTH | RD_ANCHORY_CUSTOM; + m_btnFilter.OnClick = Callback(this, &CChatRoomDlg::onClick_Filter); + m_btnChannelMgr.OnClick = Callback(this, &CChatRoomDlg::onClick_Options); + m_btnNickList.OnClick = Callback(this, &CChatRoomDlg::onClick_NickList); - case IDC_MESSAGE: - GetWindowRect(m_hwndStatus, &rc); - urc->rcItem.right = bSend ? urc->dlgNewSize.cx - 64 : urc->dlgNewSize.cx; - urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + 22; - urc->rcItem.bottom = urc->dlgNewSize.cy - (rc.bottom - rc.top) - 1; - return RD_ANCHORX_LEFT | RD_ANCHORY_CUSTOM; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; + m_splitterX.OnChange = Callback(this, &CChatRoomDlg::onSplitterX); + m_splitterY.OnChange = Callback(this, &CChatRoomDlg::onSplitterY); + + m_iSplitterX = g_Settings.iSplitterX; + m_iSplitterY = g_Settings.iSplitterY; } -LRESULT CALLBACK CChatRoomDlg::MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +void CChatRoomDlg::OnInitDialog() { - MESSAGESUBDATA *dat = (MESSAGESUBDATA*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - HWND hwndDlg = GetParent(hwnd); - CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - CHARRANGE sel; + CSrmmBaseDialog::OnInitDialog(); + m_si->pDlg = this; + SetWindowLongPtr(m_hwnd, GWLP_USERDATA, LPARAM(this)); - switch (msg) { - case EM_SUBCLASSED: - dat = (MESSAGESUBDATA*)mir_alloc(sizeof(MESSAGESUBDATA)); + if (g_Settings.bTabsEnable) + SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, GetWindowLongPtr(m_hwnd, GWL_EXSTYLE) | WS_EX_APPWINDOW); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); - dat->si = (SESSION_INFO*)lParam; - dat->szTabSave[0] = '\0'; - dat->lastEnterTime = 0; - return 0; + // initialize toolbar icons + Srmm_CreateToolbarIcons(m_hwnd, BBBF_ISCHATBUTTON); - case WM_MOUSEWHEEL: - SendDlgItemMessage(hwndDlg, IDC_LOG, WM_MOUSEWHEEL, wParam, lParam); - dat->lastEnterTime = 0; - return TRUE; + WindowList_Add(pci->hWindowList, m_hwnd, m_hContact); - case EM_REPLACESEL: - PostMessage(hwnd, EM_ACTIVATE, 0, 0); - break; + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPENING); - case EM_ACTIVATE: - SetActiveWindow(hwndDlg); - break; + m_log.SendMsg(EM_AUTOURLDETECT, 1, 0); - case WM_CHAR: - { - BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; - BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; + 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); - if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_READONLY) - break; + DWORD dwFlags = WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS; + if (!g_Settings.bTabsEnable) + dwFlags |= SBARS_SIZEGRIP; - if (wParam == 9 && isCtrl && !isAlt) // ctrl-i (italics) - return TRUE; + m_hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, nullptr, dwFlags, 0, 0, 0, 0, m_hwnd, nullptr, g_hInst, nullptr); + SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); - if (wParam == VK_SPACE && isCtrl && !isAlt) // ctrl-space (paste clean text) - return TRUE; + m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - if (wParam == '\n' || wParam == '\r') { - if ((isCtrl != 0) ^ (0 != db_get_b(0, CHAT_MODULE, "SendOnEnter", 1))) { - PostMessage(hwndDlg, WM_COMMAND, IDOK, 0); - return 0; - } - if (db_get_b(0, CHAT_MODULE, "SendOnDblEnter", 0)) { - 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(hwndDlg, WM_COMMAND, IDOK, 0); - return 0; - } - } - } - else dat->lastEnterTime = 0; + UpdateOptions(); + UpdateStatusBar(); + UpdateTitle(); + SetWindowPosition(); - if (wParam == 1 && isCtrl && !isAlt) { //ctrl-a - SendMessage(hwnd, EM_SETSEL, 0, -1); - return 0; - } - } - break; + SendMessage(m_hwnd, WM_SIZE, 0, 0); - case WM_KEYDOWN: - { - static int start, end; - BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; - BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; - BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; - if (wParam == VK_RETURN) { - dat->szTabSave[0] = '\0'; - if ((isCtrl != 0) ^ (0 != db_get_b(0, CHAT_MODULE, "SendOnEnter", 1))) - return 0; + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPEN); +} - if (db_get_b(0, CHAT_MODULE, "SendOnDblEnter", 0)) - if (dat->lastEnterTime + 2 >= time(nullptr)) - return 0; +void CChatRoomDlg::OnDestroy() +{ + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSING); - break; - } + SaveWindowPosition(true); + if (!g_Settings.bTabsEnable) { + if (db_get_b(0, CHAT_MODULE, "SavePosition", 0)) { + db_set_dw(m_hContact, CHAT_MODULE, "roomx", m_si->iX); + db_set_dw(m_hContact, CHAT_MODULE, "roomy", m_si->iY); + db_set_dw(m_hContact, CHAT_MODULE, "roomwidth", m_si->iWidth); + db_set_dw(m_hContact, CHAT_MODULE, "roomheight", m_si->iHeight); + } + } - if (wParam == VK_TAB && isShift && !isCtrl) { // SHIFT-TAB (go to nick list) - SetFocus(pDlg->m_nickList.GetHwnd()); - return TRUE; - } + WindowList_Remove(pci->hWindowList, m_hwnd); - if (wParam == VK_TAB && isCtrl && !isShift) { // CTRL-TAB (switch tab/window) - if (g_Settings.bTabsEnable) - SendMessage(GetParent(GetParent(hwndDlg)), GC_SWITCHNEXTTAB, 0, 0); - else - pci->ShowRoom(SM_GetNextWindow(dat->si)); - return TRUE; - } + m_si->pDlg = nullptr; + m_si->wState &= ~STATE_TALK; + DestroyWindow(m_hwndStatus); m_hwndStatus = nullptr; - if (wParam == VK_TAB && isCtrl && isShift) { // CTRL_SHIFT-TAB (switch tab/window) - if (g_Settings.bTabsEnable) - SendMessage(GetParent(GetParent(hwndDlg)), GC_SWITCHPREVTAB, 0, 0); - else - pci->ShowRoom(SM_GetPrevWindow(dat->si)); - return TRUE; - } + NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE); +} - if (wParam <= '9' && wParam >= '1' && isCtrl && !isAlt) // CTRL + 1 -> 9 (switch tab) - if (g_Settings.bTabsEnable) - SendMessage(hwndDlg, GC_SWITCHTAB, 0, (int)wParam - (int)'1'); +void CChatRoomDlg::onClick_Filter(CCtrlButton *pButton) +{ + if (!pButton->Enabled()) + return; - if (wParam <= VK_NUMPAD9 && wParam >= VK_NUMPAD1 && isCtrl && !isAlt) // CTRL + 1 -> 9 (switch tab) - if (g_Settings.bTabsEnable) - SendMessage(hwndDlg, GC_SWITCHTAB, 0, (int)wParam - (int)VK_NUMPAD1); + m_bFilterEnabled = !m_bFilterEnabled; + m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bFilterEnabled ? "filter" : "filter2", FALSE)); + if (m_bFilterEnabled && db_get_b(0, CHAT_MODULE, "RightClickFilter", 0) == 0) + ShowFilterMenu(); + else + RedrawLog(); +} - if (wParam == VK_TAB && !isCtrl && !isShift) { // tab-autocomplete - LRESULT lResult = (LRESULT)SendMessage(hwnd, EM_GETSEL, 0, 0); +void CChatRoomDlg::onClick_NickList(CCtrlButton *pButton) +{ + if (!pButton->Enabled() || m_si->iType == GCW_SERVER) + return; - SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); - start = LOWORD(lResult); - end = HIWORD(lResult); - SendMessage(hwnd, EM_SETSEL, end, end); + m_bNicklistEnabled = !m_bNicklistEnabled; + pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bNicklistEnabled ? "nicklist" : "nicklist2", FALSE)); - GETTEXTLENGTHEX gtl = {}; - gtl.flags = GTL_PRECISE; - gtl.codepage = CP_ACP; - int iLen = SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0); - if (iLen > 0) { - wchar_t *pszText = (wchar_t *)mir_alloc(sizeof(wchar_t)*(iLen + 100)); + ScrollToBottom(); + SendMessage(m_hwnd, WM_SIZE, 0, 0); +} - GETTEXTEX gt = {}; - gt.cb = iLen + 99; - gt.flags = GT_DEFAULT; - gt.codepage = 1200; - SendMessage(hwnd, EM_GETTEXTEX, (WPARAM)>, (LPARAM)pszText); +void CChatRoomDlg::onClick_Options(CCtrlButton *pButton) +{ + if (pButton->Enabled()) + DoEventHook(GC_USER_CHANMGR, nullptr, nullptr, 0); +} - while (start > 0 && pszText[start - 1] != ' ' && pszText[start - 1] != 13 && pszText[start - 1] != VK_TAB) - start--; - while (end < iLen && pszText[end] != ' ' && pszText[end] != 13 && pszText[end - 1] != VK_TAB) - end++; +void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) +{ + if (!pButton->Enabled()) + return; - if (dat->szTabSave[0] == '\0') - mir_wstrncpy(dat->szTabSave, pszText + start, end - start + 1); + ptrA pszRtf(Message_GetFromStream(m_hwnd, m_si)); + if (pszRtf == nullptr) + return; - wchar_t *pszSelName = (wchar_t *)mir_alloc(sizeof(wchar_t)*(end - start + 1)); - mir_wstrncpy(pszSelName, pszText + start, end - start + 1); + MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); + if (mi == nullptr) + return; - wchar_t *pszName = pci->UM_FindUserAutoComplete(dat->si->pUsers, dat->szTabSave, pszSelName); - if (pszName == nullptr) { - pszName = dat->szTabSave; - SendMessage(hwnd, EM_SETSEL, start, end); - if (end != start) - SendMessage(hwnd, EM_REPLACESEL, FALSE, (LPARAM)pszName); - dat->szTabSave[0] = '\0'; - } - else { - SendMessage(hwnd, EM_SETSEL, start, end); - if (end != start) - SendMessage(hwnd, EM_REPLACESEL, FALSE, (LPARAM)pszName); - } - mir_free(pszText); - mir_free(pszSelName); - } + pci->SM_AddCommand(m_si->ptszID, m_si->pszModule, pszRtf); - SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); - RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE); - return 0; - } + CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf))); + pci->DoRtfToTags(ptszText, mi->nColorCount, mi->crColors); + ptszText.Trim(); + ptszText.Replace(L"%", L"%%"); - if (dat->szTabSave[0] != '\0' && wParam != VK_RIGHT && wParam != VK_LEFT && wParam != VK_SPACE && wParam != VK_RETURN && wParam != VK_BACK && wParam != VK_DELETE) { - if (g_Settings.bAddColonToAutoComplete && start == 0) - SendMessageA(hwnd, EM_REPLACESEL, FALSE, (LPARAM) ": "); + if (mi->bAckMsg) { + EnableWindow(m_message.GetHwnd(), FALSE); + m_message.SendMsg(EM_SETREADONLY, TRUE, 0); + } + else SetDlgItemText(m_hwnd, IDC_MESSAGE, L""); - dat->szTabSave[0] = '\0'; - } + EnableWindow(m_btnOk.GetHwnd(), FALSE); - if (pDlg->ProcessHotkeys(wParam, isShift, isCtrl, isAlt)) - return TRUE; + DoEventHook(GC_USER_MESSAGE, nullptr, ptszText, 0); - if (wParam == 0x46 && isCtrl && !isAlt) { // ctrl-f (paste clean text) - pDlg->onClick_Filter(&pDlg->m_btnFilter); - return TRUE; - } + SetFocus(m_message.GetHwnd()); +} - if (wParam == 0x4e && isCtrl && !isAlt) { // ctrl-n (nicklist) - pDlg->onClick_NickList(&pDlg->m_btnNickList); - return TRUE; - } +void CChatRoomDlg::onSplitterX(CSplitter *pSplitter) +{ + RECT rc; + GetClientRect(m_hwnd, &rc); - if (wParam == 0x4f && isCtrl && !isAlt) { // ctrl-o (options) - pDlg->onClick_Options(&pDlg->m_btnChannelMgr); - return TRUE; - } + m_iSplitterX = rc.right - pSplitter->GetPos() + 1; + if (m_iSplitterX < 35) + m_iSplitterX = 35; + if (m_iSplitterX > rc.right - rc.left - 35) + m_iSplitterX = rc.right - rc.left - 35; + g_Settings.iSplitterX = m_iSplitterX; +} - if ((wParam == 45 && isShift || wParam == 0x56 && isCtrl) && !isAlt) { // ctrl-v (paste clean text) - SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0); - return TRUE; - } +void CChatRoomDlg::onSplitterY(CSplitter *pSplitter) +{ + RECT rc; + GetClientRect(m_hwnd, &rc); - if (wParam == 0x57 && isCtrl && !isAlt) { // ctrl-w (close window) - pDlg->CloseTab(); - return TRUE; - } + m_iSplitterY = rc.bottom - pSplitter->GetPos() + 1; + if (!IsWindowVisible(m_btnBold.GetHwnd())) + m_iSplitterY += 19; - if (wParam == VK_NEXT || wParam == VK_PRIOR) { - HWND htemp = hwndDlg; - SendDlgItemMessage(htemp, IDC_LOG, msg, wParam, lParam); - dat->lastEnterTime = 0; - return TRUE; - } + if (m_iSplitterY < 63) + m_iSplitterY = 63; + if (m_iSplitterY > rc.bottom - rc.top - 40) + m_iSplitterY = rc.bottom - rc.top - 40; + g_Settings.iSplitterY = m_iSplitterY; +} - if (wParam == VK_UP && isCtrl && !isAlt) { - char* lpPrevCmd = pci->SM_GetPrevCommand(dat->si->ptszID, dat->si->pszModule); +void CChatRoomDlg::SetWindowPosition() +{ + if (g_Settings.bTabsEnable) + return; - SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + WINDOWPLACEMENT wp; + wp.length = sizeof(wp); + GetWindowPlacement(m_hwnd, &wp); - if (lpPrevCmd) { - SETTEXTEX ste; - ste.flags = ST_DEFAULT; - ste.codepage = CP_ACP; - SendMessage(hwnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd); - } - else SetWindowText(hwnd, L""); + RECT screen; + SystemParametersInfo(SPI_GETWORKAREA, 0, &screen, 0); - GETTEXTLENGTHEX gtl = {}; - gtl.flags = GTL_PRECISE; - gtl.codepage = CP_ACP; - int iLen = SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0); - SendMessage(hwnd, EM_SCROLLCARET, 0, 0); - SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); - RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE); - SendMessage(hwnd, EM_SETSEL, iLen, iLen); - dat->lastEnterTime = 0; - return TRUE; - } + if (m_si->iX) { + wp.rcNormalPosition.left = m_si->iX; + wp.rcNormalPosition.top = m_si->iY; + wp.rcNormalPosition.right = wp.rcNormalPosition.left + m_si->iWidth; + wp.rcNormalPosition.bottom = wp.rcNormalPosition.top + m_si->iHeight; + wp.showCmd = SW_HIDE; + SetWindowPlacement(m_hwnd, &wp); + return; + } + + if (db_get_b(0, CHAT_MODULE, "SavePosition", 0)) { + if (RestoreWindowPosition(m_hwnd, m_hContact, true)) { + ShowWindow(m_hwnd, SW_HIDE); + return; + } + SetWindowPos(m_hwnd, 0, (screen.right - screen.left) / 2 - (550) / 2, (screen.bottom - screen.top) / 2 - (400) / 2, (550), (400), SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE); + } + else SetWindowPos(m_hwnd, 0, (screen.right - screen.left) / 2 - (550) / 2, (screen.bottom - screen.top) / 2 - (400) / 2, (550), (400), SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE); - if (wParam == VK_DOWN && isCtrl && !isAlt) { - char *lpPrevCmd = pci->SM_GetNextCommand(dat->si->ptszID, dat->si->pszModule); - SendMessage(hwnd, WM_SETREDRAW, FALSE, 0); + SESSION_INFO *pActive = pci->GetActiveSession(); + if (pActive && pActive->pDlg && db_get_b(0, CHAT_MODULE, "CascadeWindows", 1)) { + RECT rcThis, rcNew; + int dwFlag = SWP_NOZORDER | SWP_NOACTIVATE; + if (!IsWindowVisible(m_hwnd)) + dwFlag |= SWP_HIDEWINDOW; - if (lpPrevCmd) { - SETTEXTEX ste; - ste.flags = ST_DEFAULT; - ste.codepage = CP_ACP; - SendMessage(hwnd, EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd); - } - else SetWindowText(hwnd, L""); + GetWindowRect(m_hwnd, &rcThis); + GetWindowRect(pActive->pDlg->GetHwnd(), &rcNew); - GETTEXTLENGTHEX gtl = {}; - gtl.flags = GTL_PRECISE; - gtl.codepage = CP_ACP; - int iLen = SendMessage(hwnd, EM_GETTEXTLENGTHEX, (WPARAM)>l, 0); - SendMessage(hwnd, EM_SCROLLCARET, 0, 0); - SendMessage(hwnd, WM_SETREDRAW, TRUE, 0); - RedrawWindow(hwnd, nullptr, nullptr, RDW_INVALIDATE); - SendMessage(hwnd, EM_SETSEL, iLen, iLen); - dat->lastEnterTime = 0; - return TRUE; + int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); + SetWindowPos(m_hwnd, 0, rcNew.left + offset, rcNew.top + offset, rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, dwFlag); + } +} + +void CChatRoomDlg::SaveWindowPosition(bool bUpdateSession) +{ + WINDOWPLACEMENT wp = {}; + wp.length = sizeof(wp); + GetWindowPlacement(getCaptionWindow(), &wp); + + g_Settings.iX = wp.rcNormalPosition.left; + g_Settings.iY = wp.rcNormalPosition.top; + g_Settings.iWidth = wp.rcNormalPosition.right - wp.rcNormalPosition.left; + g_Settings.iHeight = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; + + if (bUpdateSession) { + m_si->iX = g_Settings.iX; + m_si->iY = g_Settings.iY; + m_si->iWidth = g_Settings.iWidth; + m_si->iHeight = g_Settings.iHeight; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CChatRoomDlg::CloseTab() +{ + if (g_Settings.bTabsEnable) + SendMessage(GetParent(m_hwndParent), GC_REMOVETAB, 0, (LPARAM)this); + Close(); +} + +void CChatRoomDlg::LoadSettings() +{ + m_clrInputBG = db_get_dw(0, CHAT_MODULE, "ColorMessageBG", GetSysColor(COLOR_WINDOW)); + m_clrInputFG = g_Settings.MessageAreaColor; +} + +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; + + pLog = pLog->next; + if (m_si->iType != GCW_CHATROOM || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0) + index++; } + StreamInEvents(pLog, true); + mir_forkthread(phase2, m_si); } - - // fall through - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_KILLFOCUS: - dat->lastEnterTime = 0; - break; + else StreamInEvents(m_si->pLogEnd, true); + } + else ClearLog(); +} - case WM_RBUTTONDOWN: - { - HMENU hSubMenu = GetSubMenu(g_hMenu, 2); - TranslateMenu(hSubMenu); - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); +void CChatRoomDlg::ScrollToBottom() +{ + if ((GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0) + return; - EnableMenuItem(hSubMenu, ID_MESSAGE_UNDO, SendMessage(hwnd, EM_CANUNDO, 0, 0) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hSubMenu, ID_MESSAGE_REDO, SendMessage(hwnd, EM_CANREDO, 0, 0) ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hSubMenu, ID_MESSAGE_COPY, sel.cpMax != sel.cpMin ? MF_ENABLED : MF_GRAYED); - EnableMenuItem(hSubMenu, ID_MESSAGE_CUT, sel.cpMax != sel.cpMin ? MF_ENABLED : MF_GRAYED); + CHARRANGE sel; + SCROLLINFO scroll = {}; + scroll.cbSize = sizeof(scroll); + scroll.fMask = SIF_PAGE | SIF_RANGE; + GetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll); - dat->lastEnterTime = 0; + scroll.fMask = SIF_POS; + scroll.nPos = scroll.nMax - scroll.nPage + 1; + SetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll, TRUE); - POINT pt; - pt.x = (short)LOWORD(lParam); - pt.y = (short)HIWORD(lParam); - ClientToScreen(hwnd, &pt); + sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd()); + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); +} - CHARRANGE all = { 0, -1 }; - UINT uID = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, nullptr); - switch (uID) { - case 0: - break; +void CChatRoomDlg::ShowFilterMenu() +{ + HWND hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)this); + TranslateDialogDefault(hwnd); - case ID_MESSAGE_UNDO: - SendMessage(hwnd, EM_UNDO, 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 ID_MESSAGE_REDO: - SendMessage(hwnd, EM_REDO, 0, 0); - break; +void CChatRoomDlg::UpdateNickList() +{ + int i = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); + m_nickList.SendMsg(LB_SETCOUNT, m_si->nUsersInNicklist, 0); + m_nickList.SendMsg(LB_SETTOPINDEX, i, 0); - case ID_MESSAGE_COPY: - SendMessage(hwnd, WM_COPY, 0, 0); - break; + UpdateTitle(); +} - case ID_MESSAGE_CUT: - SendMessage(hwnd, WM_CUT, 0, 0); - break; +void CChatRoomDlg::UpdateOptions() +{ + m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bNicklistEnabled ? "nicklist" : "nicklist2", FALSE)); + m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bFilterEnabled ? "filter" : "filter2", FALSE)); - case ID_MESSAGE_PASTE: - SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0); - break; + MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); + EnableWindow(m_btnBold.GetHwnd(), mi->bBold); + EnableWindow(m_btnItalic.GetHwnd(), mi->bItalics); + EnableWindow(m_btnUnderline.GetHwnd(), mi->bUnderline); + EnableWindow(m_btnColor.GetHwnd(), mi->bColor); + EnableWindow(m_btnBkColor.GetHwnd(), mi->bBkgColor); + if (m_si->iType == GCW_CHATROOM) + EnableWindow(m_btnChannelMgr.GetHwnd(), mi->bChanMgr); - case ID_MESSAGE_SELECTALL: - SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&all); - break; + HICON hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; + if (!hIcon) { + pci->MM_IconsChanged(); + hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon; + } - case ID_MESSAGE_CLEAR: - SetWindowText(hwnd, L""); - break; - } - PostMessage(hwnd, WM_KEYUP, 0, 0); - } + if (g_Settings.bTabsEnable) + pDialog->FixTabIcons(nullptr); + + SendMessage(m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); + + Window_SetIcon_IcoLib(getCaptionWindow(), GetIconHandle("window")); + + m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); + + CHARFORMAT2 cf; + cf.cbSize = sizeof(CHARFORMAT2); + cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_UNDERLINE | CFM_BACKCOLOR; + cf.dwEffects = 0; + cf.crTextColor = g_Settings.MessageAreaColor; + cf.crBackColor = m_clrInputBG; + + m_message.SendMsg(EM_SETBKGNDCOLOR, 0, m_clrInputBG); + m_message.SendMsg(WM_SETFONT, (WPARAM)g_Settings.MessageAreaFont, MAKELPARAM(TRUE, 0)); + m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); + + // nicklist + int ih = GetTextPixelSize(L"AQGglo", g_Settings.UserListFont, FALSE); + int ih2 = GetTextPixelSize(L"AQGglo", 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 (g_Settings.bShowContactStatus) + font = font > 16 ? font : 16; + + m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font); + InvalidateRect(m_nickList.GetHwnd(), nullptr, TRUE); + + SendMessage(m_hwnd, WM_SIZE, 0, 0); + RedrawLog2(); +} + +void CChatRoomDlg::UpdateStatusBar() +{ + MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); + wchar_t *ptszDispName = mi->ptszModDispName; + int x = 12; + x += GetTextPixelSize(ptszDispName, (HFONT)SendMessage(m_hwndStatus, WM_GETFONT, 0, 0), TRUE); + x += GetSystemMetrics(SM_CXSMICON); + int iStatusbarParts[2] = { x, -1 }; + SendMessage(m_hwndStatus, SB_SETPARTS, 2, (LPARAM)&iStatusbarParts); + + // stupid hack to make icons show. I dunno why this is needed currently + HICON hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; + if (!hIcon) { + pci->MM_IconsChanged(); + hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; + } + + SendMessage(m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); + + if (g_Settings.bTabsEnable) + pDialog->FixTabIcons(nullptr); + + SendMessage(m_hwndStatus, SB_SETTEXT, 0, (LPARAM)ptszDispName); + SendMessage(m_hwndStatus, SB_SETTEXT, 1, (LPARAM)(m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L"")); + SendMessage(m_hwndStatus, SB_SETTIPTEXT, 1, (LPARAM)(m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L"")); +} + +void CChatRoomDlg::UpdateTitle() +{ + wchar_t szTemp[100]; + 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; + } + + SetWindowText(getCaptionWindow(), szTemp); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int CChatRoomDlg::Resizer(UTILRESIZECONTROL *urc) +{ + SESSION_INFO *si = m_si; + + RECT rc; + bool bControl = db_get_b(0, CHAT_MODULE, "ShowTopButtons", 1) != 0; + bool bFormat = db_get_b(0, CHAT_MODULE, "ShowFormatButtons", 1) != 0; + bool bToolbar = bFormat || bControl; + bool bSend = db_get_b(0, CHAT_MODULE, "ShowSend", 0) != 0; + bool bNick = si->iType != GCW_SERVER && m_bNicklistEnabled; + + switch (urc->wId) { + case IDOK: + GetWindowRect(m_hwndStatus, &rc); + urc->rcItem.left = bSend ? 315 : urc->dlgNewSize.cx; + urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + 23; + urc->rcItem.bottom = urc->dlgNewSize.cy - (rc.bottom - rc.top) - 1; + return RD_ANCHORX_RIGHT | RD_ANCHORY_CUSTOM; + + case IDC_LOG: + urc->rcItem.top = 2; + urc->rcItem.left = 0; + urc->rcItem.right = bNick ? urc->dlgNewSize.cx - m_iSplitterX : urc->dlgNewSize.cx; + LBL_CalcBottom: + urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; + if (!bToolbar) + urc->rcItem.bottom += 20; + return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; + + case IDC_SRMM_NICKLIST: + urc->rcItem.top = 2; + urc->rcItem.right = urc->dlgNewSize.cx; + urc->rcItem.left = urc->dlgNewSize.cx - m_iSplitterX + 2; + goto LBL_CalcBottom; + + case IDC_SPLITTERX: + urc->rcItem.top = 1; + urc->rcItem.left = urc->dlgNewSize.cx - m_iSplitterX; + urc->rcItem.right = urc->rcItem.left + 2; + goto LBL_CalcBottom; - case WM_KEYUP: - case WM_LBUTTONUP: - case WM_RBUTTONUP: - case WM_MBUTTONUP: - pDlg->RefreshButtonStatus(); - break; + case IDC_SPLITTERY: + urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY; + if (!bToolbar) + urc->rcItem.top += 20; + urc->rcItem.bottom = urc->rcItem.top + 2; + return RD_ANCHORX_WIDTH | RD_ANCHORY_CUSTOM; - case WM_DESTROY: - mir_free(dat); - return 0; + case IDC_MESSAGE: + GetWindowRect(m_hwndStatus, &rc); + urc->rcItem.right = bSend ? urc->dlgNewSize.cx - 64 : urc->dlgNewSize.cx; + urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + 22; + urc->rcItem.bottom = urc->dlgNewSize.cy - (rc.bottom - rc.top) - 1; + return RD_ANCHORX_LEFT | RD_ANCHORY_CUSTOM; } - - return mir_callNextSubclass(hwnd, MessageSubclassProc, msg, wParam, lParam); + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; } +///////////////////////////////////////////////////////////////////////////////////////// + INT_PTR CALLBACK CChatRoomDlg::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { static CChatRoomDlg *pDlg = nullptr; @@ -501,629 +617,486 @@ INT_PTR CALLBACK CChatRoomDlg::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wPa return(FALSE); } -LRESULT CALLBACK CChatRoomDlg::LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +///////////////////////////////////////////////////////////////////////////////////////// + +LRESULT CChatRoomDlg::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) { CHARRANGE sel; - HWND hwndDlg = GetParent(hwnd); - CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); - switch (msg) { - 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; + case WM_MOUSEWHEEL: + SendDlgItemMessage(m_hwnd, IDC_LOG, WM_MOUSEWHEEL, wParam, lParam); + m_iLastEnterTime = 0; + return TRUE; - case WM_KEYDOWN: - if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window) - pDlg->CloseTab(); - return TRUE; - } + case EM_REPLACESEL: + PostMessage(m_message.GetHwnd(), EM_ACTIVATE, 0, 0); break; - 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); - } - } + case EM_ACTIVATE: + SetActiveWindow(m_hwnd); break; case WM_CHAR: - SetFocus(GetDlgItem(GetParent(hwnd), IDC_MESSAGE)); - SendDlgItemMessage(GetParent(hwnd), IDC_MESSAGE, WM_CHAR, wParam, lParam); - break; - } - - return mir_callNextSubclass(hwnd, LogSubclassProc, msg, wParam, lParam); -} - -LRESULT CALLBACK CChatRoomDlg::NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - SESSION_INFO *si = (SESSION_INFO*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - - switch (msg) { - case WM_ERASEBKGND: { - HDC dc = (HDC)wParam; - if (dc == nullptr) - return 0; + BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; + BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; - int index = SendMessage(hwnd, LB_GETTOPINDEX, 0, 0); - if (index == LB_ERR || si->nUsersInNicklist <= 0) - return 0; + if (GetWindowLongPtr(m_message.GetHwnd(), GWL_STYLE) & ES_READONLY) + break; - int height = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0); - if (height == LB_ERR) - return 0; + if (wParam == 9 && isCtrl && !isAlt) // ctrl-i (italics) + return TRUE; - RECT rc = {}; - GetClientRect(hwnd, &rc); + if (wParam == VK_SPACE && isCtrl && !isAlt) // ctrl-space (paste clean text) + return TRUE; - int items = si->nUsersInNicklist - index; - if (rc.bottom - rc.top > items * height) { - rc.top = items * height; - FillRect(dc, &rc, pci->hListBkgBrush); + if (wParam == '\n' || wParam == '\r') { + if ((isCtrl != 0) ^ (0 != db_get_b(0, CHAT_MODULE, "SendOnEnter", 1))) { + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + return 0; + } + if (db_get_b(0, CHAT_MODULE, "SendOnDblEnter", 0)) { + 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; + } + } } - } - return 1; + else m_iLastEnterTime = 0; - case WM_KEYDOWN: - if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window) - si->pDlg->CloseTab(); - return TRUE; + if (wParam == 1 && isCtrl && !isAlt) { //ctrl-a + m_message.SendMsg(EM_SETSEL, 0, -1); + return 0; + } } break; - case WM_RBUTTONDOWN: - SendMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam); - break; - - case WM_RBUTTONUP: - SendMessage(hwnd, WM_LBUTTONUP, wParam, lParam); - break; - - case WM_MEASUREITEM: + case WM_KEYDOWN: { - MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam; - if (mis->CtlType == ODT_MENU) - return Menu_MeasureItem(lParam); - } - return FALSE; + static int start, end; + BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000; + BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000; + BOOL isAlt = GetKeyState(VK_MENU) & 0x8000; + if (wParam == VK_RETURN) { + szTabSave[0] = '\0'; + if ((isCtrl != 0) ^ (0 != db_get_b(0, CHAT_MODULE, "SendOnEnter", 1))) + return 0; - case WM_DRAWITEM: - { - DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; - if (dis->CtlType == ODT_MENU) - return Menu_DrawItem(lParam); - } - return FALSE; + if (db_get_b(0, CHAT_MODULE, "SendOnDblEnter", 0)) + if (m_iLastEnterTime + 2 >= time(nullptr)) + return 0; - case WM_CONTEXTMENU: - TVHITTESTINFO hti; - { - int height = 0; - 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; + break; } - else ScreenToClient(hwnd, &hti.pt); - - int item = LOWORD(si->pDlg->m_nickList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y))); - USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, item); - if (ui) { - USERINFO uinew; - memcpy(&uinew, ui, sizeof(USERINFO)); - if (hti.pt.x == -1 && hti.pt.y == -1) - hti.pt.y += height - 4; - ClientToScreen(hwnd, &hti.pt); - - HMENU hMenu = 0; - UINT uID = CreateGCMenu(hwnd, &hMenu, 0, hti.pt, si, uinew.pszUID, uinew.pszNick); - switch (uID) { - case 0: - break; - - case ID_MESS: - si->pDlg->DoEventHook(GC_USER_PRIVMESS, ui, nullptr, 0); - break; - default: - si->pDlg->DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID); - break; - } - DestroyGCMenu(&hMenu, 1); + if (wParam == VK_TAB && isShift && !isCtrl) { // SHIFT-TAB (go to nick list) + SetFocus(m_nickList.GetHwnd()); return TRUE; } - } - break; - - case WM_MOUSEMOVE: - Chat_HoverMouse(si, hwnd, lParam, ServiceExists("mToolTip/HideTip")); - break; - } - - return mir_callNextSubclass(hwnd, NicklistSubclassProc, msg, wParam, lParam); -} - -int GetTextPixelSize(wchar_t *pszText, HFONT hFont, BOOL bWidth) -{ - if (!pszText || !hFont) - return 0; - - HDC hdc = GetDC(nullptr); - HFONT hOldFont = (HFONT)SelectObject(hdc, hFont); - RECT rc = {}; - DrawText(hdc, pszText, -1, &rc, DT_CALCRECT); - SelectObject(hdc, hOldFont); - ReleaseDC(nullptr, hdc); - return bWidth ? rc.right - rc.left : rc.bottom - rc.top; -} - -static void __cdecl phase2(void *lParam) -{ - SESSION_INFO *si = (SESSION_INFO*)lParam; - Sleep(30); - if (si && si->pDlg) - si->pDlg->RedrawLog2(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -CChatRoomDlg::CChatRoomDlg(SESSION_INFO *si) : - CSrmmBaseDialog(g_hInst, g_Settings.bTabsEnable ? IDD_CHANNEL_TAB : IDD_CHANNEL, si), - m_message(this, IDC_MESSAGE), - m_log(this, IDC_LOG), - - m_btnOk(this, IDOK), - - m_splitterX(this, IDC_SPLITTERX), - m_splitterY(this, IDC_SPLITTERY) -{ - m_pLog = &m_log; - m_pEntry = &m_message; - - m_autoClose = 0; - m_forceResizable = true; - - m_btnOk.OnClick = Callback(this, &CChatRoomDlg::onClick_Ok); - - m_btnFilter.OnClick = Callback(this, &CChatRoomDlg::onClick_Filter); - m_btnChannelMgr.OnClick = Callback(this, &CChatRoomDlg::onClick_Options); - m_btnNickList.OnClick = Callback(this, &CChatRoomDlg::onClick_NickList); - - m_splitterX.OnChange = Callback(this, &CChatRoomDlg::onSplitterX); - m_splitterY.OnChange = Callback(this, &CChatRoomDlg::onSplitterY); - - m_iSplitterX = g_Settings.iSplitterX; - m_iSplitterY = g_Settings.iSplitterY; -} - -void CChatRoomDlg::OnInitDialog() -{ - CSrmmBaseDialog::OnInitDialog(); - m_si->pDlg = this; - SetWindowLongPtr(m_hwnd, GWLP_USERDATA, LPARAM(this)); - - if (g_Settings.bTabsEnable) - SetWindowLongPtr(m_hwnd, GWL_EXSTYLE, GetWindowLongPtr(m_hwnd, GWL_EXSTYLE) | WS_EX_APPWINDOW); - - // initialize toolbar icons - Srmm_CreateToolbarIcons(m_hwnd, BBBF_ISCHATBUTTON); - - WindowList_Add(pci->hWindowList, m_hwnd, m_hContact); - - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPENING); - - mir_subclassWindow(m_message.GetHwnd(), MessageSubclassProc); - - SetWindowLongPtr(m_log.GetHwnd(), GWLP_USERDATA, LPARAM(this)); - mir_subclassWindow(m_log.GetHwnd(), LogSubclassProc); - - SetWindowLongPtr(m_nickList.GetHwnd(), GWLP_USERDATA, LPARAM(m_si)); - mir_subclassWindow(m_nickList.GetHwnd(), NicklistSubclassProc); - - m_message.SendMsg(EM_SUBCLASSED, 0, LPARAM(m_si)); - m_log.SendMsg(EM_AUTOURLDETECT, 1, 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); - - DWORD dwFlags = WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS; - if (!g_Settings.bTabsEnable) - dwFlags |= SBARS_SIZEGRIP; - - m_hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, nullptr, dwFlags, 0, 0, 0, 0, m_hwnd, nullptr, g_hInst, nullptr); - SendMessage(m_hwndStatus, SB_SETMINHEIGHT, GetSystemMetrics(SM_CYSMICON), 0); - - m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - - UpdateOptions(); - UpdateStatusBar(); - UpdateTitle(); - SetWindowPosition(); - SendMessage(m_hwnd, WM_SIZE, 0, 0); + if (wParam == VK_TAB && isCtrl && !isShift) { // CTRL-TAB (switch tab/window) + if (g_Settings.bTabsEnable) + SendMessage(GetParent(GetParent(m_hwnd)), GC_SWITCHNEXTTAB, 0, 0); + else + pci->ShowRoom(SM_GetNextWindow(m_si)); + return TRUE; + } - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPEN); -} + if (wParam == VK_TAB && isCtrl && isShift) { // CTRL_SHIFT-TAB (switch tab/window) + if (g_Settings.bTabsEnable) + SendMessage(GetParent(GetParent(m_hwnd)), GC_SWITCHPREVTAB, 0, 0); + else + pci->ShowRoom(SM_GetPrevWindow(m_si)); + return TRUE; + } -void CChatRoomDlg::OnDestroy() -{ - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSING); + if (wParam <= '9' && wParam >= '1' && isCtrl && !isAlt) // CTRL + 1 -> 9 (switch tab) + if (g_Settings.bTabsEnable) + SendMessage(m_hwnd, GC_SWITCHTAB, 0, (int)wParam - (int)'1'); - SaveWindowPosition(true); - if (!g_Settings.bTabsEnable) { - if (db_get_b(0, CHAT_MODULE, "SavePosition", 0)) { - db_set_dw(m_hContact, CHAT_MODULE, "roomx", m_si->iX); - db_set_dw(m_hContact, CHAT_MODULE, "roomy", m_si->iY); - db_set_dw(m_hContact, CHAT_MODULE, "roomwidth", m_si->iWidth); - db_set_dw(m_hContact, CHAT_MODULE, "roomheight", m_si->iHeight); - } - } + if (wParam <= VK_NUMPAD9 && wParam >= VK_NUMPAD1 && isCtrl && !isAlt) // CTRL + 1 -> 9 (switch tab) + if (g_Settings.bTabsEnable) + SendMessage(m_hwnd, GC_SWITCHTAB, 0, (int)wParam - (int)VK_NUMPAD1); - WindowList_Remove(pci->hWindowList, m_hwnd); + if (wParam == VK_TAB && !isCtrl && !isShift) { // tab-autocomplete + LRESULT lResult = (LRESULT)m_message.SendMsg(EM_GETSEL, 0, 0); - m_si->pDlg = nullptr; - m_si->wState &= ~STATE_TALK; - DestroyWindow(m_hwndStatus); m_hwndStatus = nullptr; + m_message.SendMsg(WM_SETREDRAW, FALSE, 0); + start = LOWORD(lResult); + end = HIWORD(lResult); + m_message.SendMsg(EM_SETSEL, end, end); - NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE); -} + GETTEXTLENGTHEX gtl = {}; + gtl.flags = GTL_PRECISE; + gtl.codepage = CP_ACP; + int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>l, 0); + if (iLen > 0) { + wchar_t *pszText = (wchar_t *)mir_alloc(sizeof(wchar_t)*(iLen + 100)); -void CChatRoomDlg::onClick_Filter(CCtrlButton *pButton) -{ - if (!pButton->Enabled()) - return; + GETTEXTEX gt = {}; + gt.cb = iLen + 99; + gt.flags = GT_DEFAULT; + gt.codepage = 1200; + m_message.SendMsg(EM_GETTEXTEX, (WPARAM)>, (LPARAM)pszText); - m_bFilterEnabled = !m_bFilterEnabled; - m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bFilterEnabled ? "filter" : "filter2", FALSE)); - if (m_bFilterEnabled && db_get_b(0, CHAT_MODULE, "RightClickFilter", 0) == 0) - ShowFilterMenu(); - else - RedrawLog(); -} + while (start > 0 && pszText[start - 1] != ' ' && pszText[start - 1] != 13 && pszText[start - 1] != VK_TAB) + start--; + while (end < iLen && pszText[end] != ' ' && pszText[end] != 13 && pszText[end - 1] != VK_TAB) + end++; -void CChatRoomDlg::onClick_NickList(CCtrlButton *pButton) -{ - if (!pButton->Enabled() || m_si->iType == GCW_SERVER) - return; + if (szTabSave[0] == '\0') + mir_wstrncpy(szTabSave, pszText + start, end - start + 1); - m_bNicklistEnabled = !m_bNicklistEnabled; - pButton->SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bNicklistEnabled ? "nicklist" : "nicklist2", FALSE)); + wchar_t *pszSelName = (wchar_t *)mir_alloc(sizeof(wchar_t)*(end - start + 1)); + mir_wstrncpy(pszSelName, pszText + start, end - start + 1); - ScrollToBottom(); - SendMessage(m_hwnd, WM_SIZE, 0, 0); -} + wchar_t *pszName = pci->UM_FindUserAutoComplete(m_si->pUsers, szTabSave, pszSelName); + if (pszName == nullptr) { + pszName = szTabSave; + m_message.SendMsg(EM_SETSEL, start, end); + if (end != start) + m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)pszName); + szTabSave[0] = '\0'; + } + else { + m_message.SendMsg(EM_SETSEL, start, end); + if (end != start) + m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)pszName); + } + mir_free(pszText); + mir_free(pszSelName); + } -void CChatRoomDlg::onClick_Options(CCtrlButton *pButton) -{ - if (pButton->Enabled()) - DoEventHook(GC_USER_CHANMGR, nullptr, nullptr, 0); -} + m_message.SendMsg(WM_SETREDRAW, TRUE, 0); + RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + return 0; + } -void CChatRoomDlg::onClick_Ok(CCtrlButton *pButton) -{ - if (!pButton->Enabled()) - return; + if (szTabSave[0] != '\0' && wParam != VK_RIGHT && wParam != VK_LEFT && wParam != VK_SPACE && wParam != VK_RETURN && wParam != VK_BACK && wParam != VK_DELETE) { + if (g_Settings.bAddColonToAutoComplete && start == 0) + SendMessageA(m_message.GetHwnd(), EM_REPLACESEL, FALSE, (LPARAM) ": "); - ptrA pszRtf(Message_GetFromStream(m_hwnd, m_si)); - if (pszRtf == nullptr) - return; + szTabSave[0] = '\0'; + } - MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); - if (mi == nullptr) - return; + if (ProcessHotkeys(wParam, isShift, isCtrl, isAlt)) + return TRUE; - pci->SM_AddCommand(m_si->ptszID, m_si->pszModule, pszRtf); + if (wParam == 0x46 && isCtrl && !isAlt) { // ctrl-f (paste clean text) + onClick_Filter(&m_btnFilter); + return TRUE; + } - CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf))); - pci->DoRtfToTags(ptszText, mi->nColorCount, mi->crColors); - ptszText.Trim(); - ptszText.Replace(L"%", L"%%"); + if (wParam == 0x4e && isCtrl && !isAlt) { // ctrl-n (nicklist) + onClick_NickList(&m_btnNickList); + return TRUE; + } - 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) + onClick_Options(&m_btnChannelMgr); + return TRUE; + } - EnableWindow(m_btnOk.GetHwnd(), FALSE); + if ((wParam == 45 && isShift || wParam == 0x56 && isCtrl) && !isAlt) { // ctrl-v (paste clean text) + m_message.SendMsg(EM_PASTESPECIAL, CF_TEXT, 0); + return TRUE; + } - DoEventHook(GC_USER_MESSAGE, nullptr, ptszText, 0); + if (wParam == 0x57 && isCtrl && !isAlt) { // ctrl-w (close window) + CloseTab(); + return TRUE; + } - SetFocus(m_message.GetHwnd()); -} + if (wParam == VK_NEXT || wParam == VK_PRIOR) { + HWND htemp = m_hwnd; + SendDlgItemMessage(htemp, IDC_LOG, msg, wParam, lParam); + m_iLastEnterTime = 0; + return TRUE; + } -void CChatRoomDlg::onSplitterX(CSplitter *pSplitter) -{ - RECT rc; - GetClientRect(m_hwnd, &rc); + if (wParam == VK_UP && isCtrl && !isAlt) { + char* lpPrevCmd = pci->SM_GetPrevCommand(m_si->ptszID, m_si->pszModule); - m_iSplitterX = rc.right - pSplitter->GetPos() + 1; - if (m_iSplitterX < 35) - m_iSplitterX = 35; - if (m_iSplitterX > rc.right - rc.left - 35) - m_iSplitterX = rc.right - rc.left - 35; - g_Settings.iSplitterX = m_iSplitterX; -} + m_message.SendMsg(WM_SETREDRAW, FALSE, 0); -void CChatRoomDlg::onSplitterY(CSplitter *pSplitter) -{ - RECT rc; - GetClientRect(m_hwnd, &rc); + if (lpPrevCmd) { + SETTEXTEX ste; + ste.flags = ST_DEFAULT; + ste.codepage = CP_ACP; + m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd); + } + else m_message.SetText(L""); - m_iSplitterY = rc.bottom - pSplitter->GetPos() + 1; - if (!IsWindowVisible(m_btnBold.GetHwnd())) - m_iSplitterY += 19; + GETTEXTLENGTHEX gtl = {}; + gtl.flags = GTL_PRECISE; + gtl.codepage = CP_ACP; + int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>l, 0); + m_message.SendMsg(EM_SCROLLCARET, 0, 0); + m_message.SendMsg(WM_SETREDRAW, TRUE, 0); + RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + m_message.SendMsg(EM_SETSEL, iLen, iLen); + m_iLastEnterTime = 0; + return TRUE; + } - if (m_iSplitterY < 63) - m_iSplitterY = 63; - if (m_iSplitterY > rc.bottom - rc.top - 40) - m_iSplitterY = rc.bottom - rc.top - 40; - g_Settings.iSplitterY = m_iSplitterY; -} + if (wParam == VK_DOWN && isCtrl && !isAlt) { + char *lpPrevCmd = pci->SM_GetNextCommand(m_si->ptszID, m_si->pszModule); + m_message.SendMsg(WM_SETREDRAW, FALSE, 0); -void CChatRoomDlg::SetWindowPosition() -{ - if (g_Settings.bTabsEnable) - return; + if (lpPrevCmd) { + SETTEXTEX ste; + ste.flags = ST_DEFAULT; + ste.codepage = CP_ACP; + m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&ste, (LPARAM)lpPrevCmd); + } + else m_message.SetText(L""); - WINDOWPLACEMENT wp; - wp.length = sizeof(wp); - GetWindowPlacement(m_hwnd, &wp); + GETTEXTLENGTHEX gtl = {}; + gtl.flags = GTL_PRECISE; + gtl.codepage = CP_ACP; + int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>l, 0); + m_message.SendMsg(EM_SCROLLCARET, 0, 0); + m_message.SendMsg(WM_SETREDRAW, TRUE, 0); + RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); + m_message.SendMsg(EM_SETSEL, iLen, iLen); + m_iLastEnterTime = 0; + return TRUE; + } + } - RECT screen; - SystemParametersInfo(SPI_GETWORKAREA, 0, &screen, 0); + // fall through + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_KILLFOCUS: + m_iLastEnterTime = 0; + break; - if (m_si->iX) { - wp.rcNormalPosition.left = m_si->iX; - wp.rcNormalPosition.top = m_si->iY; - wp.rcNormalPosition.right = wp.rcNormalPosition.left + m_si->iWidth; - wp.rcNormalPosition.bottom = wp.rcNormalPosition.top + m_si->iHeight; - wp.showCmd = SW_HIDE; - SetWindowPlacement(m_hwnd, &wp); - return; - } - - if (db_get_b(0, CHAT_MODULE, "SavePosition", 0)) { - if (RestoreWindowPosition(m_hwnd, m_hContact, true)) { - ShowWindow(m_hwnd, SW_HIDE); - return; - } - SetWindowPos(m_hwnd, 0, (screen.right - screen.left) / 2 - (550) / 2, (screen.bottom - screen.top) / 2 - (400) / 2, (550), (400), SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE); - } - else SetWindowPos(m_hwnd, 0, (screen.right - screen.left) / 2 - (550) / 2, (screen.bottom - screen.top) / 2 - (400) / 2, (550), (400), SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOACTIVATE); + case WM_RBUTTONDOWN: + { + HMENU hSubMenu = GetSubMenu(g_hMenu, 2); + TranslateMenu(hSubMenu); + m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - SESSION_INFO *pActive = pci->GetActiveSession(); - if (pActive && pActive->pDlg && db_get_b(0, CHAT_MODULE, "CascadeWindows", 1)) { - RECT rcThis, rcNew; - int dwFlag = SWP_NOZORDER | SWP_NOACTIVATE; - if (!IsWindowVisible(m_hwnd)) - dwFlag |= SWP_HIDEWINDOW; + EnableMenuItem(hSubMenu, ID_MESSAGE_UNDO, m_message.SendMsg(EM_CANUNDO, 0, 0) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hSubMenu, ID_MESSAGE_REDO, m_message.SendMsg(EM_CANREDO, 0, 0) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hSubMenu, ID_MESSAGE_COPY, sel.cpMax != sel.cpMin ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hSubMenu, ID_MESSAGE_CUT, sel.cpMax != sel.cpMin ? MF_ENABLED : MF_GRAYED); - GetWindowRect(m_hwnd, &rcThis); - GetWindowRect(pActive->pDlg->GetHwnd(), &rcNew); + m_iLastEnterTime = 0; - int offset = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); - SetWindowPos(m_hwnd, 0, rcNew.left + offset, rcNew.top + offset, rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, dwFlag); - } -} + POINT pt; + pt.x = (short)LOWORD(lParam); + pt.y = (short)HIWORD(lParam); + ClientToScreen(m_message.GetHwnd(), &pt); -void CChatRoomDlg::SaveWindowPosition(bool bUpdateSession) -{ - WINDOWPLACEMENT wp = {}; - wp.length = sizeof(wp); - GetWindowPlacement(getCaptionWindow(), &wp); + CHARRANGE all = { 0, -1 }; + UINT uID = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_message.GetHwnd(), nullptr); + switch (uID) { + case 0: + break; - g_Settings.iX = wp.rcNormalPosition.left; - g_Settings.iY = wp.rcNormalPosition.top; - g_Settings.iWidth = wp.rcNormalPosition.right - wp.rcNormalPosition.left; - g_Settings.iHeight = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; + case ID_MESSAGE_UNDO: + m_message.SendMsg(EM_UNDO, 0, 0); + break; - if (bUpdateSession) { - m_si->iX = g_Settings.iX; - m_si->iY = g_Settings.iY; - m_si->iWidth = g_Settings.iWidth; - m_si->iHeight = g_Settings.iHeight; - } -} + case ID_MESSAGE_REDO: + m_message.SendMsg(EM_REDO, 0, 0); + break; -///////////////////////////////////////////////////////////////////////////////////////// + case ID_MESSAGE_COPY: + m_message.SendMsg(WM_COPY, 0, 0); + break; -void CChatRoomDlg::CloseTab() -{ - if (g_Settings.bTabsEnable) - SendMessage(GetParent(m_hwndParent), GC_REMOVETAB, 0, (LPARAM)this); - Close(); -} + case ID_MESSAGE_CUT: + m_message.SendMsg(WM_CUT, 0, 0); + break; -void CChatRoomDlg::LoadSettings() -{ - m_clrInputBG = db_get_dw(0, CHAT_MODULE, "ColorMessageBG", GetSysColor(COLOR_WINDOW)); - m_clrInputFG = g_Settings.MessageAreaColor; -} + case ID_MESSAGE_PASTE: + m_message.SendMsg(EM_PASTESPECIAL, CF_TEXT, 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 ID_MESSAGE_SELECTALL: + m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + break; - pLog = pLog->next; - if (m_si->iType != GCW_CHATROOM || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0) - index++; + case ID_MESSAGE_CLEAR: + m_message.SetText(L""); + break; } - StreamInEvents(pLog, true); - mir_forkthread(phase2, m_si); + PostMessage(m_message.GetHwnd(), WM_KEYUP, 0, 0); } - else StreamInEvents(m_si->pLogEnd, true); + break; + + case WM_KEYUP: + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + RefreshButtonStatus(); + break; } - else ClearLog(); + + return 0; } -void CChatRoomDlg::ScrollToBottom() -{ - if ((GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0) - return; +///////////////////////////////////////////////////////////////////////////////////////// +LRESULT CChatRoomDlg::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) +{ CHARRANGE sel; - SCROLLINFO scroll = {}; - scroll.cbSize = sizeof(scroll); - scroll.fMask = SIF_PAGE | SIF_RANGE; - GetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll); - - scroll.fMask = SIF_POS; - scroll.nPos = scroll.nMax - scroll.nPage + 1; - SetScrollInfo(m_log.GetHwnd(), SB_VERT, &scroll, TRUE); - sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd()); - m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0); -} + switch (msg) { + case WM_LBUTTONUP: + m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin != sel.cpMax) { + m_log.SendMsg(WM_COPY, 0, 0); + sel.cpMin = sel.cpMax; + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + SetFocus(m_message.GetHwnd()); + break; -void CChatRoomDlg::ShowFilterMenu() -{ - HWND hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)this); - TranslateDialogDefault(hwnd); + case WM_KEYDOWN: + if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window) + CloseTab(); + return TRUE; + } + 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 WM_ACTIVATE: + if (LOWORD(wParam) == WA_INACTIVE) { + m_log.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin != sel.cpMax) { + sel.cpMin = sel.cpMax; + m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); + } + } + break; -void CChatRoomDlg::UpdateNickList() -{ - int i = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); - m_nickList.SendMsg(LB_SETCOUNT, m_si->nUsersInNicklist, 0); - m_nickList.SendMsg(LB_SETTOPINDEX, i, 0); + case WM_CHAR: + SetFocus(m_message.GetHwnd()); + m_message.SendMsg(WM_CHAR, wParam, lParam); + break; + } - UpdateTitle(); + return 0; } -void CChatRoomDlg::UpdateOptions() -{ - m_btnNickList.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bNicklistEnabled ? "nicklist" : "nicklist2", FALSE)); - m_btnFilter.SendMsg(BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadIconEx(m_bFilterEnabled ? "filter" : "filter2", FALSE)); - - MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); - EnableWindow(m_btnBold.GetHwnd(), mi->bBold); - EnableWindow(m_btnItalic.GetHwnd(), mi->bItalics); - EnableWindow(m_btnUnderline.GetHwnd(), mi->bUnderline); - EnableWindow(m_btnColor.GetHwnd(), mi->bColor); - EnableWindow(m_btnBkColor.GetHwnd(), mi->bBkgColor); - if (m_si->iType == GCW_CHATROOM) - EnableWindow(m_btnChannelMgr.GetHwnd(), mi->bChanMgr); - - HICON hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; - if (!hIcon) { - pci->MM_IconsChanged(); - hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon; - } +///////////////////////////////////////////////////////////////////////////////////////// - if (g_Settings.bTabsEnable) - pDialog->FixTabIcons(nullptr); +LRESULT CChatRoomDlg::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_ERASEBKGND: + { + HDC dc = (HDC)wParam; + if (dc == nullptr) + return 0; - SendMessage(m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); + int index = m_nickList.SendMsg(LB_GETTOPINDEX, 0, 0); + if (index == LB_ERR || m_si->nUsersInNicklist <= 0) + return 0; - Window_SetIcon_IcoLib(getCaptionWindow(), GetIconHandle("window")); + int height = m_nickList.SendMsg(LB_GETITEMHEIGHT, 0, 0); + if (height == LB_ERR) + return 0; - m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground); + RECT rc = {}; + GetClientRect(m_nickList.GetHwnd(), &rc); - CHARFORMAT2 cf; - cf.cbSize = sizeof(CHARFORMAT2); - cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_UNDERLINE | CFM_BACKCOLOR; - cf.dwEffects = 0; - cf.crTextColor = g_Settings.MessageAreaColor; - cf.crBackColor = m_clrInputBG; - - m_message.SendMsg(EM_SETBKGNDCOLOR, 0, m_clrInputBG); - m_message.SendMsg(WM_SETFONT, (WPARAM)g_Settings.MessageAreaFont, MAKELPARAM(TRUE, 0)); - m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf); + int items = m_si->nUsersInNicklist - index; + if (rc.bottom - rc.top > items * height) { + rc.top = items * height; + FillRect(dc, &rc, pci->hListBkgBrush); + } + } + return 1; - // nicklist - int ih = GetTextPixelSize(L"AQGglo", g_Settings.UserListFont, FALSE); - int ih2 = GetTextPixelSize(L"AQGglo", g_Settings.UserListHeadingsFont, FALSE); - int height = db_get_b(0, CHAT_MODULE, "NicklistRowDist", 12); - int font = ih > ih2 ? ih : ih2; + case WM_KEYDOWN: + if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window) + CloseTab(); + return TRUE; + } + break; - // make sure we have space for icon! - if (g_Settings.bShowContactStatus) - font = font > 16 ? font : 16; + case WM_RBUTTONDOWN: + m_nickList.SendMsg(WM_LBUTTONDOWN, wParam, lParam); + break; - m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font); - InvalidateRect(m_nickList.GetHwnd(), nullptr, TRUE); + case WM_RBUTTONUP: + m_nickList.SendMsg(WM_LBUTTONUP, wParam, lParam); + break; - SendMessage(m_hwnd, WM_SIZE, 0, 0); - RedrawLog2(); -} + case WM_MEASUREITEM: + { + MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam; + if (mis->CtlType == ODT_MENU) + return Menu_MeasureItem(lParam); + } + return FALSE; -void CChatRoomDlg::UpdateStatusBar() -{ - MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule); - wchar_t *ptszDispName = mi->ptszModDispName; - int x = 12; - x += GetTextPixelSize(ptszDispName, (HFONT)SendMessage(m_hwndStatus, WM_GETFONT, 0, 0), TRUE); - x += GetSystemMetrics(SM_CXSMICON); - int iStatusbarParts[2] = { x, -1 }; - SendMessage(m_hwndStatus, SB_SETPARTS, 2, (LPARAM)&iStatusbarParts); + case WM_DRAWITEM: + { + DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; + if (dis->CtlType == ODT_MENU) + return Menu_DrawItem(lParam); + } + return FALSE; - // stupid hack to make icons show. I dunno why this is needed currently - HICON hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; - if (!hIcon) { - pci->MM_IconsChanged(); - hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon; - } + case WM_CONTEXTMENU: + TVHITTESTINFO hti; + { + int height = 0; + 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); - SendMessage(m_hwndStatus, SB_SETICON, 0, (LPARAM)hIcon); + int item = LOWORD(m_nickList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y))); + USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, item); + if (ui) { + USERINFO uinew; + memcpy(&uinew, ui, sizeof(USERINFO)); + if (hti.pt.x == -1 && hti.pt.y == -1) + hti.pt.y += height - 4; + ClientToScreen(m_nickList.GetHwnd(), &hti.pt); - if (g_Settings.bTabsEnable) - pDialog->FixTabIcons(nullptr); + HMENU hMenu = 0; + UINT uID = CreateGCMenu(m_nickList.GetHwnd(), &hMenu, 0, hti.pt, m_si, uinew.pszUID, uinew.pszNick); + switch (uID) { + case 0: + break; - SendMessage(m_hwndStatus, SB_SETTEXT, 0, (LPARAM)ptszDispName); - SendMessage(m_hwndStatus, SB_SETTEXT, 1, (LPARAM)(m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L"")); - SendMessage(m_hwndStatus, SB_SETTIPTEXT, 1, (LPARAM)(m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L"")); -} + case ID_MESS: + DoEventHook(GC_USER_PRIVMESS, ui, nullptr, 0); + break; -void CChatRoomDlg::UpdateTitle() -{ - wchar_t szTemp[100]; - 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); + default: + DoEventHook(GC_USER_NICKLISTMENU, ui, nullptr, uID); + break; + } + DestroyGCMenu(&hMenu, 1); + return TRUE; + } + } break; - case GCW_SERVER: - mir_snwprintf(szTemp, L"%s: Server", m_si->ptszName); + + case WM_MOUSEMOVE: + Chat_HoverMouse(m_si, m_nickList.GetHwnd(), lParam, ServiceExists("mToolTip/HideTip")); break; } - SetWindowText(getCaptionWindow(), szTemp); + return 0; } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp index 1b3896ee31..506bd38cd3 100644 --- a/src/core/stdmsg/src/msgdialog.cpp +++ b/src/core/stdmsg/src/msgdialog.cpp @@ -31,6 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define SB_GRIP_WIDTH 20 // pixels - buffer used to prevent sizegrip from overwriting statusbar icons #define VALID_AVATAR(x) (x == PA_FORMAT_PNG || x == PA_FORMAT_JPEG || x == PA_FORMAT_ICON || x == PA_FORMAT_BMP || x == PA_FORMAT_GIF) +#define ENTERCLICKTIME 1000 //max time in ms during which a double-tap on enter will cause a send + static const UINT sendControls[] = { IDC_MESSAGE }; void NotifyLocalWinEvent(MCONTACT hContact, HWND hwnd, unsigned int type) @@ -105,280 +107,12 @@ static void AddToFileList(wchar_t ***pppFiles, int *totalCount, const wchar_t* s } } -struct MsgEditSubclassData -{ - DWORD lastEnterTime; -}; - static void SetEditorText(HWND hwnd, const wchar_t* txt) { SetWindowText(hwnd, txt); SendMessage(hwnd, EM_SETSEL, -1, -1); } -#define ENTERCLICKTIME 1000 //max time in ms during which a double-tap on enter will cause a send - -static LRESULT CALLBACK MessageEditSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - CSrmmWindow *pdat = (CSrmmWindow *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA); - struct MsgEditSubclassData *dat = (struct MsgEditSubclassData *) GetWindowLongPtr(hwnd, GWLP_USERDATA); - - switch (msg) { - case WM_DROPFILES: - SendMessage(GetParent(hwnd), WM_DROPFILES, wParam, lParam); - break; - - case EM_SUBCLASSED: - dat = (struct MsgEditSubclassData *) mir_alloc(sizeof(struct MsgEditSubclassData)); - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)dat); - dat->lastEnterTime = 0; - return 0; - - case WM_CHAR: - if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_READONLY) - break; - - if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { //ctrl-a - SendMessage(hwnd, EM_SETSEL, 0, -1); - return 0; - } - - if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w - SendMessage(GetParent(hwnd), WM_CLOSE, 0, 0); - return 0; - } - break; - - case WM_KEYDOWN: - if (wParam == VK_RETURN) { - if (!(GetKeyState(VK_SHIFT) & 0x8000) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0) != g_dat.bSendOnEnter) { - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - if (g_dat.bSendOnDblEnter) { - 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; - - if (((wParam == VK_INSERT && (GetKeyState(VK_SHIFT) & 0x8000)) || (wParam == 'V' && (GetKeyState(VK_CONTROL) & 0x8000))) && - !(GetKeyState(VK_MENU) & 0x8000)) { // ctrl-v (paste clean text) - SendMessage(hwnd, WM_PASTE, 0, 0); - return 0; - } - - if (wParam == VK_UP && (GetKeyState(VK_CONTROL) & 0x8000) && g_dat.bCtrlSupport && !g_dat.bAutoClose) { - if (pdat->m_cmdList.getCount()) { - if (pdat->m_cmdListInd < 0) { - pdat->m_cmdListInd = pdat->m_cmdList.getCount() - 1; - SetEditorText(hwnd, pdat->m_cmdList[pdat->m_cmdListInd]); - } - else if (pdat->m_cmdListInd > 0) { - SetEditorText(hwnd, pdat->m_cmdList[--pdat->m_cmdListInd]); - } - } - EnableWindow(GetDlgItem(GetParent(hwnd), IDOK), GetWindowTextLength(hwnd) != 0); - pdat->UpdateReadChars(); - return 0; - } - - if (wParam == VK_DOWN && (GetKeyState(VK_CONTROL) & 0x8000) && g_dat.bCtrlSupport && !g_dat.bAutoClose) { - if (pdat->m_cmdList.getCount() && pdat->m_cmdListInd >= 0) { - if (pdat->m_cmdListInd < (pdat->m_cmdList.getCount() - 1)) - SetEditorText(hwnd, pdat->m_cmdList[++pdat->m_cmdListInd]); - else { - pdat->m_cmdListInd = -1; - SetEditorText(hwnd, pdat->m_cmdList[pdat->m_cmdList.getCount() - 1]); - } - } - - EnableWindow(GetDlgItem(GetParent(hwnd), IDOK), GetWindowTextLength(hwnd) != 0); - pdat->UpdateReadChars(); - } - break; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_MOUSEWHEEL: - case WM_KILLFOCUS: - dat->lastEnterTime = 0; - break; - - case WM_SYSCHAR: - dat->lastEnterTime = 0; - if ((wParam == 's' || wParam == 'S') && GetKeyState(VK_MENU) & 0x8000) { - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - return 0; - } - break; - - case WM_CONTEXTMENU: - { - static const CHARRANGE all = { 0, -1 }; - - MessageWindowPopupData mwpd = {}; - mwpd.cbSize = sizeof(mwpd); - mwpd.uType = MSG_WINDOWPOPUP_SHOWING; - mwpd.uFlags = MSG_WINDOWPOPUP_INPUT; - mwpd.hContact = pdat->m_hContact; - mwpd.hwnd = hwnd; - - HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - - mwpd.hMenu = GetSubMenu(hMenu, 1); - TranslateMenu(mwpd.hMenu); - - CHARRANGE sel; - SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) { - EnableMenuItem(mwpd.hMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(mwpd.hMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(mwpd.hMenu, IDM_DELETE, MF_BYCOMMAND | MF_GRAYED); - } - if (!SendMessage(hwnd, EM_CANUNDO, 0, 0)) - EnableMenuItem(mwpd.hMenu, IDM_UNDO, MF_BYCOMMAND | MF_GRAYED); - - if (!SendMessage(hwnd, EM_CANREDO, 0, 0)) - EnableMenuItem(mwpd.hMenu, IDM_REDO, MF_BYCOMMAND | MF_GRAYED); - - if (!SendMessage(hwnd, EM_CANPASTE, 0, 0)) { - if (!IsClipboardFormatAvailable(CF_HDROP)) - EnableMenuItem(mwpd.hMenu, IDM_PASTE, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(mwpd.hMenu, IDM_PASTESEND, MF_BYCOMMAND | MF_GRAYED); - } - - if (lParam == 0xFFFFFFFF) { - SendMessage(hwnd, EM_POSFROMCHAR, (WPARAM)&mwpd.pt, sel.cpMax); - ClientToScreen(hwnd, &mwpd.pt); - } - else { - mwpd.pt.x = GET_X_LPARAM(lParam); - mwpd.pt.y = GET_Y_LPARAM(lParam); - } - - - // First notification - NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd); - - // Someone added items? - if (GetMenuItemCount(mwpd.hMenu) > 0) { - SetCursor(LoadCursor(NULL, IDC_ARROW)); - mwpd.selection = TrackPopupMenu(mwpd.hMenu, TPM_RETURNCMD, mwpd.pt.x, mwpd.pt.y, 0, hwnd, NULL); - } - - // Second notification - mwpd.uType = MSG_WINDOWPOPUP_SELECTED; - NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd); - - switch (mwpd.selection) { - case IDM_UNDO: - SendMessage(hwnd, WM_UNDO, 0, 0); - break; - - case IDM_REDO: - SendMessage(hwnd, EM_REDO, 0, 0); - break; - - case IDM_CUT: - SendMessage(hwnd, WM_CUT, 0, 0); - break; - - case IDM_COPY: - SendMessage(hwnd, WM_COPY, 0, 0); - break; - - case IDM_PASTE: - SendMessage(hwnd, WM_PASTE, 0, 0); - break; - - case IDM_PASTESEND: - SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0); - PostMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0); - break; - - case IDM_DELETE: - SendMessage(hwnd, EM_REPLACESEL, TRUE, 0); - break; - - case IDM_SELECTALL: - SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&all); - break; - - case IDM_CLEAR: - SetWindowText(hwnd, L""); - break; - } - DestroyMenu(hMenu); - return 0; - } - - case WM_PASTE: - if (IsClipboardFormatAvailable(CF_HDROP)) { - if (OpenClipboard(hwnd)) { - HANDLE hDrop = GetClipboardData(CF_HDROP); - if (hDrop) - SendMessage(hwnd, WM_DROPFILES, (WPARAM)hDrop, 0); - CloseClipboard(); - } - } - else SendMessage(hwnd, EM_PASTESPECIAL, CF_TEXT, 0); - return 0; - - case WM_DESTROY: - mir_free(dat); - break; - } - return mir_callNextSubclass(hwnd, MessageEditSubclassProc, msg, wParam, lParam); -} - -static int MessageDialogResize(HWND, LPARAM lParam, UTILRESIZECONTROL *urc) -{ - CSrmmWindow *dat = (CSrmmWindow*)lParam; - - switch (urc->wId) { - case IDC_LOG: - if (!g_dat.bShowButtons) - urc->rcItem.top -= dat->m_lineHeight; - urc->rcItem.bottom -= dat->m_splitterPos - dat->m_originalSplitterPos; - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - - case IDC_SPLITTERY: - urc->rcItem.top -= dat->m_splitterPos - dat->m_originalSplitterPos; - urc->rcItem.bottom -= dat->m_splitterPos - dat->m_originalSplitterPos; - return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; - - case IDC_MESSAGE: - if (!g_dat.bSendButton) - urc->rcItem.right = urc->dlgNewSize.cx - urc->rcItem.left; - if (g_dat.bShowAvatar && dat->m_avatarPic) - urc->rcItem.left = dat->m_avatarWidth + 4; - - urc->rcItem.top -= dat->m_splitterPos - dat->m_originalSplitterPos; - if (!g_dat.bSendButton) - return RD_ANCHORX_CUSTOM | RD_ANCHORY_BOTTOM; - return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; - - case IDCANCEL: - case IDOK: - urc->rcItem.top -= dat->m_splitterPos - dat->m_originalSplitterPos; - return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; - - case IDC_AVATAR: - urc->rcItem.top = urc->rcItem.bottom - (dat->m_avatarHeight + 2); - urc->rcItem.right = urc->rcItem.left + (dat->m_avatarWidth + 2); - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; -} - ///////////////////////////////////////////////////////////////////////////////////////// CSrmmWindow::CSrmmWindow(MCONTACT hContact, bool noActivate, const char *szInitialText, bool bIsUnicode) : @@ -386,6 +120,7 @@ CSrmmWindow::CSrmmWindow(MCONTACT hContact, bool noActivate, const char *szIniti m_log(this, IDC_LOG), m_message(this, IDC_MESSAGE), m_splitter(this, IDC_SPLITTERY), + m_btnOk(this, IDOK), m_cmdList(20), m_bNoActivate(noActivate) { @@ -393,6 +128,8 @@ CSrmmWindow::CSrmmWindow(MCONTACT hContact, bool noActivate, const char *szIniti m_pEntry = &m_message; m_hContact = hContact; + m_btnOk.OnClick = Callback(this, &CSrmmWindow::onClick_Ok); + m_wszInitialText = (bIsUnicode) ? mir_wstrdup((wchar_t*)szInitialText) : mir_a2u(szInitialText); m_splitter.OnChange = Callback(this, &CSrmmWindow::OnSplitterMoved); @@ -463,9 +200,6 @@ void CSrmmWindow::OnInitDialog() m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0); } - mir_subclassWindow(m_message.GetHwnd(), MessageEditSubclassProc); - m_message.SendMsg(EM_SUBCLASSED, 0, 0); - if (m_hContact) { int historyMode = db_get_b(NULL, SRMMMOD, SRMSGSET_LOADHISTORY, SRMSGDEFSET_LOADHISTORY); // This finds the first message to display, it works like shit @@ -537,7 +271,7 @@ void CSrmmWindow::OnInitDialog() if (!db_get_ws(m_hContact, SRMSGMOD, DBSAVEDMSG, &dbv)) { if (dbv.ptszVal[0]) { m_message.SetText(dbv.ptszVal); - EnableWindow(GetDlgItem(m_hwnd, IDOK), TRUE); + m_btnOk.Enable(TRUE); UpdateReadChars(); PostMessage(m_message.GetHwnd(), EM_SETSEL, -1, -1); } @@ -625,6 +359,39 @@ void CSrmmWindow::OnDestroy() Window_FreeIcon_IcoLib(m_hwnd); } +///////////////////////////////////////////////////////////////////////////////////////// + +void CSrmmWindow::onClick_Ok(CCtrlButton *pButton) +{ + if (!pButton->Enabled()) + return; + + ptrW temp(m_message.GetText()); + if (!temp[0]) + return; + + int sendId = SendMessageDirect(rtrimw(temp), m_hContact); + if (sendId) { + m_cmdList.insert(temp.detach()); + + m_cmdListInd = -1; + if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON) + NotifyTyping(PROTOTYPE_SELFTYPING_OFF); + + m_btnOk.Enable(FALSE); + SetFocus(m_message.GetHwnd()); + + m_message.SetText(L""); + + if (g_dat.bAutoClose) + DestroyWindow(m_hwnd); + else if (g_dat.bAutoMin) + ShowWindow(m_hwnd, SW_MINIMIZE); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + void CSrmmWindow::OnOptionsApplied(bool bUpdateAvatar) { CustomButtonData *cbd; @@ -653,7 +420,7 @@ void CSrmmWindow::OnOptionsApplied(bool bUpdateAvatar) ShowWindow(GetDlgItem(m_hwnd, IDCANCEL), SW_HIDE); ShowWindow(GetDlgItem(m_hwnd, IDC_SPLITTERY), SW_SHOW); ShowWindow(GetDlgItem(m_hwnd, IDOK), g_dat.bSendButton ? SW_SHOW : SW_HIDE); - EnableWindow(GetDlgItem(m_hwnd, IDOK), GetWindowTextLength(m_message.GetHwnd()) != 0); + m_btnOk.Enable(GetWindowTextLength(m_message.GetHwnd()) != 0); if (m_avatarPic == NULL || !g_dat.bShowAvatar) ShowWindow(GetDlgItem(m_hwnd, IDC_AVATAR), SW_HIDE); SendMessage(m_hwnd, DM_UPDATETITLE, 0, 0); @@ -837,10 +604,263 @@ void CSrmmWindow::UpdateReadChars() } } +///////////////////////////////////////////////////////////////////////////////////////// + +int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc) +{ + switch (urc->wId) { + case IDC_LOG: + if (!g_dat.bShowButtons) + urc->rcItem.top -= m_lineHeight; + urc->rcItem.bottom -= m_splitterPos - m_originalSplitterPos; + return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + + case IDC_SPLITTERY: + urc->rcItem.top -= m_splitterPos - m_originalSplitterPos; + urc->rcItem.bottom -= m_splitterPos - m_originalSplitterPos; + return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; + + case IDC_MESSAGE: + if (!g_dat.bSendButton) + urc->rcItem.right = urc->dlgNewSize.cx - urc->rcItem.left; + if (g_dat.bShowAvatar && m_avatarPic) + urc->rcItem.left = m_avatarWidth + 4; + + urc->rcItem.top -= m_splitterPos - m_originalSplitterPos; + if (!g_dat.bSendButton) + return RD_ANCHORX_CUSTOM | RD_ANCHORY_BOTTOM; + return RD_ANCHORX_WIDTH | RD_ANCHORY_BOTTOM; + + case IDCANCEL: + case IDOK: + urc->rcItem.top -= m_splitterPos - m_originalSplitterPos; + return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM; + + case IDC_AVATAR: + urc->rcItem.top = urc->rcItem.bottom - (m_avatarHeight + 2); + urc->rcItem.right = urc->rcItem.left + (m_avatarWidth + 2); + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; + } + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_DROPFILES: + SendMessage(m_hwnd, WM_DROPFILES, wParam, lParam); + break; + + case WM_CHAR: + if (GetWindowLongPtr(m_message.GetHwnd(), GWL_STYLE) & ES_READONLY) + break; + + if (wParam == 1 && GetKeyState(VK_CONTROL) & 0x8000) { //ctrl-a + m_message.SendMsg(EM_SETSEL, 0, -1); + return 0; + } + + if (wParam == 23 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w + Close(); + return 0; + } + break; + + case WM_KEYDOWN: + if (wParam == VK_RETURN) { + if (!(GetKeyState(VK_SHIFT) & 0x8000) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0) != g_dat.bSendOnEnter) { + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + return 0; + } + if (g_dat.bSendOnDblEnter) { + if (m_iLastEnterTime + ENTERCLICKTIME < GetTickCount()) + m_iLastEnterTime = GetTickCount(); + 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; + + if (((wParam == VK_INSERT && (GetKeyState(VK_SHIFT) & 0x8000)) || (wParam == 'V' && (GetKeyState(VK_CONTROL) & 0x8000))) && + !(GetKeyState(VK_MENU) & 0x8000)) { // ctrl-v (paste clean text) + m_message.SendMsg(WM_PASTE, 0, 0); + return 0; + } + + if (wParam == VK_UP && (GetKeyState(VK_CONTROL) & 0x8000) && g_dat.bCtrlSupport && !g_dat.bAutoClose) { + if (m_cmdList.getCount()) { + if (m_cmdListInd < 0) { + m_cmdListInd = m_cmdList.getCount() - 1; + SetEditorText(m_message.GetHwnd(), m_cmdList[m_cmdListInd]); + } + else if (m_cmdListInd > 0) { + SetEditorText(m_message.GetHwnd(), m_cmdList[--m_cmdListInd]); + } + } + m_btnOk.Enable(GetWindowTextLength(m_message.GetHwnd()) != 0); + UpdateReadChars(); + return 0; + } + + if (wParam == VK_DOWN && (GetKeyState(VK_CONTROL) & 0x8000) && g_dat.bCtrlSupport && !g_dat.bAutoClose) { + if (m_cmdList.getCount() && m_cmdListInd >= 0) { + if (m_cmdListInd < m_cmdList.getCount() - 1) + SetEditorText(m_message.GetHwnd(), m_cmdList[++m_cmdListInd]); + else { + m_cmdListInd = -1; + SetEditorText(m_message.GetHwnd(), m_cmdList[m_cmdList.getCount() - 1]); + } + } + + m_btnOk.Enable(GetWindowTextLength(m_message.GetHwnd()) != 0); + UpdateReadChars(); + } + break; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_MOUSEWHEEL: + case WM_KILLFOCUS: + m_iLastEnterTime = 0; + break; + + case WM_SYSCHAR: + m_iLastEnterTime = 0; + if ((wParam == 's' || wParam == 'S') && GetKeyState(VK_MENU) & 0x8000) { + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + return 0; + } + break; + + case WM_CONTEXTMENU: + { + static const CHARRANGE all = { 0, -1 }; + + MessageWindowPopupData mwpd = {}; + mwpd.cbSize = sizeof(mwpd); + mwpd.uType = MSG_WINDOWPOPUP_SHOWING; + mwpd.uFlags = MSG_WINDOWPOPUP_INPUT; + mwpd.hContact = m_hContact; + mwpd.hwnd = m_message.GetHwnd(); + + HMENU hMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_CONTEXT)); + + mwpd.hMenu = GetSubMenu(hMenu, 1); + TranslateMenu(mwpd.hMenu); + + CHARRANGE sel; + m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin == sel.cpMax) { + EnableMenuItem(mwpd.hMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(mwpd.hMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(mwpd.hMenu, IDM_DELETE, MF_BYCOMMAND | MF_GRAYED); + } + if (!m_message.SendMsg(EM_CANUNDO, 0, 0)) + EnableMenuItem(mwpd.hMenu, IDM_UNDO, MF_BYCOMMAND | MF_GRAYED); + + if (!m_message.SendMsg(EM_CANREDO, 0, 0)) + EnableMenuItem(mwpd.hMenu, IDM_REDO, MF_BYCOMMAND | MF_GRAYED); + + if (!m_message.SendMsg(EM_CANPASTE, 0, 0)) { + if (!IsClipboardFormatAvailable(CF_HDROP)) + EnableMenuItem(mwpd.hMenu, IDM_PASTE, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(mwpd.hMenu, IDM_PASTESEND, MF_BYCOMMAND | MF_GRAYED); + } + + if (lParam == 0xFFFFFFFF) { + m_message.SendMsg(EM_POSFROMCHAR, (WPARAM)&mwpd.pt, sel.cpMax); + ClientToScreen(m_message.GetHwnd(), &mwpd.pt); + } + else { + mwpd.pt.x = GET_X_LPARAM(lParam); + mwpd.pt.y = GET_Y_LPARAM(lParam); + } + + // First notification + NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd); + + // Someone added items? + if (GetMenuItemCount(mwpd.hMenu) > 0) { + SetCursor(LoadCursor(NULL, IDC_ARROW)); + mwpd.selection = TrackPopupMenu(mwpd.hMenu, TPM_RETURNCMD, mwpd.pt.x, mwpd.pt.y, 0, m_message.GetHwnd(), NULL); + } + + // Second notification + mwpd.uType = MSG_WINDOWPOPUP_SELECTED; + NotifyEventHooks(hHookWinPopup, 0, (LPARAM)&mwpd); + + switch (mwpd.selection) { + case IDM_UNDO: + m_message.SendMsg(WM_UNDO, 0, 0); + break; + + case IDM_REDO: + m_message.SendMsg(EM_REDO, 0, 0); + break; + + case IDM_CUT: + m_message.SendMsg(WM_CUT, 0, 0); + break; + + case IDM_COPY: + m_message.SendMsg(WM_COPY, 0, 0); + break; + + case IDM_PASTE: + m_message.SendMsg(WM_PASTE, 0, 0); + break; + + case IDM_PASTESEND: + m_message.SendMsg(EM_PASTESPECIAL, CF_TEXT, 0); + PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); + break; + + case IDM_DELETE: + m_message.SendMsg(EM_REPLACESEL, TRUE, 0); + break; + + case IDM_SELECTALL: + m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); + break; + + case IDM_CLEAR: + m_message.SetText(L""); + break; + } + DestroyMenu(hMenu); + return 0; + } + + case WM_PASTE: + if (IsClipboardFormatAvailable(CF_HDROP)) { + if (OpenClipboard(m_message.GetHwnd())) { + HANDLE hDrop = GetClipboardData(CF_HDROP); + if (hDrop) + m_message.SendMsg(WM_DROPFILES, (WPARAM)hDrop, 0); + CloseClipboard(); + } + } + else m_message.SendMsg(EM_PASTESPECIAL, CF_TEXT, 0); + return 0; + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) { ENLINK *pLink; CHARRANGE sel; + RECT rc; switch (uMsg) { case WM_CONTEXTMENU: @@ -851,7 +871,6 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) ScreenToClient(m_hwndStatus, &pt); // no popup menu for status icons - this is handled via NM_RCLICK notification and the plugins that added the icons - RECT rc; SendMessage(m_hwndStatus, SB_GETRECT, SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); if (pt.x >= rc.left) break; @@ -917,14 +936,11 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) break; case DM_AVATARSIZECHANGE: - { - RECT rc; - GetWindowRect(m_message.GetHwnd(), &rc); - if (rc.bottom - rc.top < m_minEditBoxSize.cy) - m_splitter.OnChange(&m_splitter); + GetWindowRect(m_message.GetHwnd(), &rc); + if (rc.bottom - rc.top < m_minEditBoxSize.cy) + m_splitter.OnChange(&m_splitter); - SendMessage(m_hwnd, WM_SIZE, 0, 0); - } + SendMessage(m_hwnd, WM_SIZE, 0, 0); break; case DM_GETAVATAR: @@ -1093,7 +1109,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) bottomScroll = (si.nPos + (int)si.nPage + 5) >= si.nMax; } - Utils_ResizeDialog(m_hwnd, g_hInst, MAKEINTRESOURCEA(IDD_MSG), MessageDialogResize, (LPARAM)this); + CDlgBase::DlgProc(uMsg, 0, 0); SetButtonsPos(m_hwnd, false); // The statusbar sometimes draws over these 2 controls so @@ -1276,43 +1292,10 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { - case IDOK: - if (IsWindowEnabled(GetDlgItem(m_hwnd, IDOK))) { - ptrW temp(m_message.GetText()); - if (!temp[0]) - break; - - int sendId = SendMessageDirect(rtrimw(temp), m_hContact); - if (sendId) { - m_cmdList.insert(temp.detach()); - - m_cmdListInd = -1; - if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON) - NotifyTyping(PROTOTYPE_SELFTYPING_OFF); - - EnableWindow(GetDlgItem(m_hwnd, IDOK), FALSE); - SetFocus(m_message.GetHwnd()); - - m_message.SetText(L""); - - if (g_dat.bAutoClose) - DestroyWindow(m_hwnd); - else if (g_dat.bAutoMin) - ShowWindow(m_hwnd, SW_MINIMIZE); - } - return TRUE; - } - break; - - case IDCANCEL: - DestroyWindow(m_hwnd); - return TRUE; - case IDC_USERMENU: if (GetKeyState(VK_SHIFT) & 0x8000) // copy user name SendMessage(m_hwnd, DM_USERNAMETOCLIP, 0, 0); else { - RECT rc; HMENU hMenu = Menu_BuildContactMenu(m_hContact); GetWindowRect(GetDlgItem(m_hwnd, LOWORD(wParam)), &rc); TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, m_hwnd, NULL); @@ -1340,7 +1323,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) if (HIWORD(wParam) == EN_CHANGE) { int len = GetWindowTextLength(m_message.GetHwnd()); UpdateReadChars(); - EnableWindow(GetDlgItem(m_hwnd, IDOK), len != 0); + m_btnOk.Enable(len != 0); if (!(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000)) { m_nLastTyping = GetTickCount(); if (len) { @@ -1359,8 +1342,6 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) if (((LPNMHDR)lParam)->hwndFrom == m_hwndStatus) { if (((LPNMHDR)lParam)->code == NM_CLICK || ((LPNMHDR)lParam)->code == NM_RCLICK) { NMMOUSE *nm = (NMMOUSE *)lParam; - RECT rc; - SendMessage(m_hwndStatus, SB_GETRECT, SendMessage(m_hwndStatus, SB_GETPARTS, 0, 0) - 1, (LPARAM)&rc); if (nm->pt.x >= rc.left) CheckStatusIconClick(m_hContact, m_hwndStatus, nm->pt, rc, 2, ((LPNMHDR)lParam)->code == NM_RCLICK ? MBCF_RIGHTBUTTON : 0); diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h index 5d12330fe3..e3dc7252f3 100644 --- a/src/core/stdmsg/src/msgs.h +++ b/src/core/stdmsg/src/msgs.h @@ -50,8 +50,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. class CSrmmWindow : public CSrmmBaseDialog { friend struct CTabbedWindow; + static LRESULT CALLBACK TabSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override; + + CCtrlButton m_btnOk; CCtrlEdit m_log, m_message; CSplitter m_splitter; @@ -101,12 +105,15 @@ public: virtual void OnDestroy() override; virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override; + virtual int Resizer(UTILRESIZECONTROL *urc) override; virtual void LoadSettings() override {} virtual void UpdateTitle() override {} void OnSplitterMoved(CSplitter*); + void onClick_Ok(CCtrlButton*); + void OnOptionsApplied(bool bUpdateAvatar); void SetStatusData(StatusTextData*); diff --git a/src/core/stdmsg/src/stdafx.h b/src/core/stdmsg/src/stdafx.h index aee164620f..5ad8cfb5a5 100644 --- a/src/core/stdmsg/src/stdafx.h +++ b/src/core/stdmsg/src/stdafx.h @@ -74,7 +74,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "richutil.h" #include "version.h" -#define EM_SUBCLASSED (WM_USER+0x101) #define EM_ACTIVATE (WM_USER+0x102) #define GC_SWITCHNEXTTAB (WM_USER+0x103) @@ -210,11 +209,13 @@ class CChatRoomDlg : public CSrmmBaseDialog friend struct CTabbedWindow; static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + + virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override; + virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override; + virtual LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override; HWND m_hwndStatus; + wchar_t szTabSave[20]; CCtrlEdit m_message, m_log; CCtrlButton m_btnOk; -- cgit v1.2.3