diff options
author | George Hazan <ghazan@miranda.im> | 2019-09-12 21:33:28 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2019-09-12 21:33:28 +0300 |
commit | 7b64f8c1aac010e8d2bf865bb649df56388a51b3 (patch) | |
tree | c1900dc291802d15ef21adba550104dcfec51d08 /plugins/TabSRMM/src | |
parent | a40f1f72a0bf581b77ac3d2d348827d77195e24c (diff) |
tabSRMM: single window
Diffstat (limited to 'plugins/TabSRMM/src')
39 files changed, 3430 insertions, 4278 deletions
diff --git a/plugins/TabSRMM/src/TSButton.cpp b/plugins/TabSRMM/src/TSButton.cpp index dbb373f302..1a01eaed14 100644 --- a/plugins/TabSRMM/src/TSButton.cpp +++ b/plugins/TabSRMM/src/TSButton.cpp @@ -97,7 +97,7 @@ static void PaintWorker(TSButtonCtrl *ctl, HDC hdcPaint) if (ctl == nullptr || hdcPaint == nullptr)
return;
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(GetParent(ctl->hwnd), GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(GetParent(ctl->hwnd), GWLP_USERDATA);
if (dat == nullptr)
return;
diff --git a/plugins/TabSRMM/src/buttonsbar.cpp b/plugins/TabSRMM/src/buttonsbar.cpp index be042cfd6b..9406bca6c6 100644 --- a/plugins/TabSRMM/src/buttonsbar.cpp +++ b/plugins/TabSRMM/src/buttonsbar.cpp @@ -139,7 +139,7 @@ static int CB_InitDefaultButtons(WPARAM, LPARAM) return 0; } -void CTabBaseDlg::BB_InitDlgButtons() +void CMsgDialog::BB_InitDlgButtons() { BYTE gap = DPISCALEX_S(g_plugin.getByte("ButtonsBarGap", 1)); @@ -182,7 +182,7 @@ void CTabBaseDlg::BB_InitDlgButtons() } } -void CTabBaseDlg::BB_RedrawButtons() +void CMsgDialog::BB_RedrawButtons() { Srmm_RedrawToolbarIcons(m_hwnd); @@ -191,14 +191,14 @@ void CTabBaseDlg::BB_RedrawButtons() InvalidateRect(hwndToggleSideBar, nullptr, TRUE); } -void CTabBaseDlg::BB_RefreshTheme() +void CMsgDialog::BB_RefreshTheme() { CustomButtonData *cbd; for (int i = 0; cbd = Srmm_GetNthButton(i); i++) SendDlgItemMessage(m_hwnd, cbd->m_dwButtonCID, WM_THEMECHANGED, 0, 0); } -BOOL CTabBaseDlg::BB_SetButtonsPos() +BOOL CMsgDialog::BB_SetButtonsPos() { if (!m_hwnd || !IsWindowVisible(m_hwnd)) return 0; @@ -333,7 +333,7 @@ BOOL CTabBaseDlg::BB_SetButtonsPos() return EndDeferWindowPos(hdwp); } -void CTabBaseDlg::CB_DestroyAllButtons() +void CMsgDialog::CB_DestroyAllButtons() { CustomButtonData *cbd; for (int i = 0; cbd = Srmm_GetNthButton(i); i++) { @@ -343,7 +343,7 @@ void CTabBaseDlg::CB_DestroyAllButtons() } } -void CTabBaseDlg::CB_DestroyButton(DWORD dwButtonCID, DWORD dwFlags) +void CMsgDialog::CB_DestroyButton(DWORD dwButtonCID, DWORD dwFlags) { HWND hwndButton = GetDlgItem(m_hwnd, dwButtonCID); if (hwndButton == nullptr) @@ -360,7 +360,7 @@ void CTabBaseDlg::CB_DestroyButton(DWORD dwButtonCID, DWORD dwFlags) BB_SetButtonsPos(); } -void CTabBaseDlg::CB_ChangeButton(CustomButtonData *cbd) +void CMsgDialog::CB_ChangeButton(CustomButtonData *cbd) { HWND hwndButton = GetDlgItem(m_hwnd, cbd->m_dwButtonCID); if (hwndButton == nullptr) diff --git a/plugins/TabSRMM/src/chat_tools.cpp b/plugins/TabSRMM/src/chat_tools.cpp index 61b2438e16..eb929bd437 100644 --- a/plugins/TabSRMM/src/chat_tools.cpp +++ b/plugins/TabSRMM/src/chat_tools.cpp @@ -133,7 +133,7 @@ BOOL DoPopup(SESSION_INFO *si, GCEVENT *gce) if (si == nullptr || !(iEvent & si->iLogPopupFlags))
return true;
- CTabBaseDlg *dat = si->pDlg;
+ CMsgDialog *dat = si->pDlg;
TContainerData *pContainer = dat ? dat->m_pContainer : nullptr;
wchar_t *bbStart, *bbEnd;
@@ -206,7 +206,7 @@ void DoFlashAndSoundWorker(FLASH_PARAMS *p) if (si == nullptr)
return;
- CTabBaseDlg *dat = nullptr;
+ CMsgDialog *dat = nullptr;
if (si->pDlg) {
dat = si->pDlg;
if (dat) {
@@ -290,7 +290,7 @@ BOOL DoSoundsFlashPopupTrayStuff(SESSION_INFO *si, GCEVENT *gce, BOOL bHighlight if (gce == nullptr || si == nullptr || gce->bIsMe || si->iType == GCW_SERVER)
return FALSE;
- CTabBaseDlg *dat = nullptr;
+ CMsgDialog *dat = nullptr;
FLASH_PARAMS *params = (FLASH_PARAMS*)mir_calloc(sizeof(FLASH_PARAMS));
params->hContact = si->hContact;
params->bInactive = TRUE;
diff --git a/plugins/TabSRMM/src/chat_window.cpp b/plugins/TabSRMM/src/chat_window.cpp index 1372ac2ff8..1b2c830b33 100644 --- a/plugins/TabSRMM/src/chat_window.cpp +++ b/plugins/TabSRMM/src/chat_window.cpp @@ -40,84 +40,6 @@ char szIndicators[] = { 0, '+', '%', '@', '!', '*' }; const CLSID IID_ITextDocument = { 0x8CC497C0, 0xA1DF, 0x11CE, { 0x80, 0x98, 0x00, 0xAA, 0x00, 0x47, 0xBE, 0x5D } }; -///////////////////////////////////////////////////////////////////////////////////////// -// checking if theres's protected text at the point -// emulates EN_LINK WM_NOTIFY to parent to process links - -static BOOL CheckCustomLink(HWND hwndRich, POINT *ptClient, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bUrlNeeded) -{ - long res = 0, cnt = 0; - long cpMin = 0, cpMax = 0; - POINT ptEnd = { 0 }; - IRichEditOle *RichEditOle = nullptr; - ITextDocument *TextDocument = nullptr; - ITextRange *TextRange = nullptr; - ITextFont *TextFont = nullptr; - BOOL bIsCustomLink = FALSE; - - POINT pt = *ptClient; - ClientToScreen(hwndRich, &pt); - - do { - if (!SendMessage(hwndRich, EM_GETOLEINTERFACE, 0, (LPARAM)&RichEditOle)) break; - if (RichEditOle->QueryInterface(IID_ITextDocument, (void**)&TextDocument) != S_OK) break; - if (TextDocument->RangeFromPoint(pt.x, pt.y, &TextRange) != S_OK) break; - - TextRange->GetStart(&cpMin); - cpMax = cpMin + 1; - TextRange->SetEnd(cpMax); - - if (TextRange->GetFont(&TextFont) != S_OK) - break; - - TextFont->GetProtected(&res); - if (res != tomTrue) - break; - - TextRange->GetPoint(tomEnd + TA_BOTTOM + TA_RIGHT, &ptEnd.x, &ptEnd.y); - if (pt.x > ptEnd.x || pt.y > ptEnd.y) - break; - - if (bUrlNeeded) { - TextRange->GetStoryLength(&cnt); - for (; cpMin > 0; cpMin--) { - res = tomTrue; - TextRange->SetIndex(tomCharacter, cpMin + 1, tomTrue); - TextFont->GetProtected(&res); - if (res != tomTrue) { cpMin++; break; } - } - for (cpMax--; cpMax < cnt; cpMax++) { - res = tomTrue; - TextRange->SetIndex(tomCharacter, cpMax + 1, tomTrue); - TextFont->GetProtected(&res); - if (res != tomTrue) - break; - } - } - - bIsCustomLink = (cpMin < cpMax); - } while (FALSE); - - if (TextFont) TextFont->Release(); - if (TextRange) TextRange->Release(); - if (TextDocument) TextDocument->Release(); - if (RichEditOle) RichEditOle->Release(); - - if (bIsCustomLink) { - ENLINK enlink = {}; - enlink.nmhdr.hwndFrom = hwndRich; - enlink.nmhdr.idFrom = IDC_SRMM_LOG; - enlink.nmhdr.code = EN_LINK; - enlink.msg = uMsg; - enlink.wParam = wParam; - enlink.lParam = lParam; - enlink.chrg.cpMin = cpMin; - enlink.chrg.cpMax = cpMax; - SendMessage(GetParent(hwndRich), WM_NOTIFY, IDC_SRMM_LOG, (LPARAM)&enlink); - } - return bIsCustomLink; -} - bool IsStringValidLink(wchar_t *pszText) { if (pszText == nullptr) @@ -230,564 +152,6 @@ void CMsgDialog::UpdateWindowState(UINT msg) } ///////////////////////////////////////////////////////////////////////////////////////// -// resizer callback for the group chat session window.Called from Mirandas dialog -// resizing service - -int CMsgDialog::Resizer(UTILRESIZECONTROL *urc) -{ - bool bToolbar = !(m_pContainer->m_dwFlags & CNT_HIDETOOLBAR); - bool bBottomToolbar = (m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR) != 0; - bool bNick = m_si->iType != GCW_SERVER && m_bNicklistEnabled; - bool bInfoPanel = m_pPanel.isActive(); - int panelHeight = m_pPanel.getHeight() + 1; - int iSplitterX = m_pContainer->m_pSettings->iSplitterX; - - RECT rcTabs; - GetClientRect(m_hwnd, &rcTabs); - - if (m_bIsAutosizingInput) - Utils::showDlgControl(m_hwnd, IDC_SPLITTERY, SW_HIDE); - - if (m_si->iType != GCW_SERVER) { - m_nickList.Show(m_bNicklistEnabled); - Utils::showDlgControl(m_hwnd, IDC_SPLITTERX, m_bNicklistEnabled ? SW_SHOW : SW_HIDE); - - m_btnNickList.Enable(true); - m_btnFilter.Enable(true); - if (m_si->iType == GCW_CHATROOM) - m_btnChannelMgr.Enable(m_si->pMI->bChanMgr); - } - else { - m_nickList.Hide(); - Utils::showDlgControl(m_hwnd, IDC_SPLITTERX, SW_HIDE); - } - - if (m_si->iType == GCW_SERVER) { - m_btnNickList.Enable(false); - m_btnFilter.Enable(false); - m_btnChannelMgr.Enable(false); - } - - switch (urc->wId) { - case IDC_PANELSPLITTER: - urc->rcItem.bottom = panelHeight; - urc->rcItem.top = panelHeight - 2; - return RD_ANCHORX_WIDTH | RD_ANCHORY_TOP; - - case IDC_SRMM_LOG: - urc->rcItem.top = 0; - urc->rcItem.left = 0; - urc->rcItem.right = bNick ? urc->dlgNewSize.cx - iSplitterX : urc->dlgNewSize.cx; - urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; - if (!bToolbar || bBottomToolbar) - urc->rcItem.bottom += DPISCALEY_S(21); - if (bInfoPanel) - urc->rcItem.top += panelHeight; - if (CSkin::m_skinEnabled) { - CSkinItem *item = &SkinItems[ID_EXTBKHISTORY]; - if (!item->IGNORED) { - urc->rcItem.left += item->MARGIN_LEFT; - urc->rcItem.right -= item->MARGIN_RIGHT; - urc->rcItem.top += item->MARGIN_TOP; - urc->rcItem.bottom -= item->MARGIN_BOTTOM; - } - } - return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; - - case IDC_SRMM_NICKLIST: - urc->rcItem.top = 0; - urc->rcItem.right = urc->dlgNewSize.cx; - urc->rcItem.left = urc->dlgNewSize.cx - iSplitterX + 2; - urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; - if (!bToolbar || bBottomToolbar) - urc->rcItem.bottom += DPISCALEY_S(21); - if (bInfoPanel) - urc->rcItem.top += panelHeight; - if (CSkin::m_skinEnabled) { - CSkinItem *item = &SkinItems[ID_EXTBKUSERLIST]; - if (!item->IGNORED) { - urc->rcItem.left += item->MARGIN_LEFT; - urc->rcItem.right -= item->MARGIN_RIGHT; - urc->rcItem.top += item->MARGIN_TOP; - urc->rcItem.bottom -= item->MARGIN_BOTTOM; - } - } - return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; - - case IDC_SPLITTERX: - urc->rcItem.right = urc->dlgNewSize.cx - iSplitterX + 2; - urc->rcItem.left = urc->dlgNewSize.cx - iSplitterX; - urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY; - if (!bToolbar || bBottomToolbar) - urc->rcItem.bottom += DPISCALEY_S(21); - urc->rcItem.top = 0; - if (bInfoPanel) - urc->rcItem.top += panelHeight; - return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; - - case IDC_SPLITTERY: - urc->rcItem.right = urc->dlgNewSize.cx; - urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + DPISCALEY_S(23); - urc->rcItem.bottom = urc->rcItem.top + DPISCALEY_S(2); - urc->rcItem.left = 0; - urc->rcItem.bottom++; - urc->rcItem.top++; - return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; - - case IDC_SRMM_MESSAGE: - urc->rcItem.right = urc->dlgNewSize.cx; - urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + 3 + DPISCALEY_S(23); - urc->rcItem.bottom = urc->dlgNewSize.cy; - if (bBottomToolbar && bToolbar) - urc->rcItem.bottom -= DPISCALEY_S(22); - - if (m_bIsAutosizingInput) - urc->rcItem.top -= DPISCALEY_S(1); - - if (CSkin::m_skinEnabled) { - CSkinItem *item = &SkinItems[ID_EXTBKINPUTAREA]; - if (!item->IGNORED) { - urc->rcItem.left += item->MARGIN_LEFT; - urc->rcItem.right -= item->MARGIN_RIGHT; - urc->rcItem.top += item->MARGIN_TOP; - urc->rcItem.bottom -= item->MARGIN_BOTTOM; - } - } - return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; -} - -bool CMsgDialog::TabAutoComplete() -{ - LRESULT lResult = m_message.SendMsg(EM_GETSEL, 0, 0); - int start = LOWORD(lResult), end = HIWORD(lResult); - m_message.SendMsg(EM_SETSEL, end, end); - - GETTEXTEX gt = { 0 }; - gt.codepage = 1200; - gt.flags = GTL_DEFAULT | GTL_PRECISE; - int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>, 0); - if (iLen <= 0) - return false; - - bool isTopic = false, isRoom = false; - wchar_t *pszName = nullptr; - wchar_t *pszText = (wchar_t*)mir_calloc((iLen + 10) * sizeof(wchar_t)); - - gt.flags = GT_DEFAULT; - gt.cb = (iLen + 9) * sizeof(wchar_t); - m_message.SendMsg(EM_GETTEXTEX, (WPARAM)>, (LPARAM)pszText); - - if (start > 1 && pszText[start - 1] == ' ' && pszText[start - 2] == ':') - start -= 2; - - 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; - } - } - - while (start > 0 && pszText[start - 1] != ' ' && pszText[start - 1] != 13 && pszText[start - 1] != VK_TAB) - start--; - -LBL_SkipEnd: - while (end < iLen && pszText[end] != ' ' && pszText[end] != 13 && pszText[end - 1] != VK_TAB) - end++; - - if (pszText[start] == '#') - isRoom = true; - else { - int topicStart = start; - while (topicStart > 0 && (pszText[topicStart - 1] == ' ' || pszText[topicStart - 1] == 13 || pszText[topicStart - 1] == VK_TAB)) - topicStart--; - if (topicStart > 5 && wcsstr(&pszText[topicStart - 6], L"/topic") == &pszText[topicStart - 6]) - isTopic = true; - } - if (m_wszSearchQuery == nullptr) { - m_wszSearchQuery = mir_wstrndup(pszText + start, end - start); - m_wszSearchResult = mir_wstrdup(m_wszSearchQuery); - m_pLastSession = nullptr; - } - if (isTopic) - pszName = m_si->ptszTopic; - else if (isRoom) { - 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 = g_chatApi.UM_FindUserAutoComplete(m_si, m_wszSearchQuery, m_wszSearchResult); - - replaceStrW(m_wszSearchResult, nullptr); - - if (pszName != nullptr) { - m_wszSearchResult = mir_wstrdup(pszName); - if (end != start) { - ptrW szReplace; - if (!isRoom && !isTopic && g_Settings.bAddColonToAutoComplete && start == 0) { - szReplace = (wchar_t*)mir_alloc((mir_wstrlen(pszName) + 4) * sizeof(wchar_t)); - mir_wstrcpy(szReplace, pszName); - mir_wstrcat(szReplace, g_Settings.bUseCommaAsColon ? L", " : L": "); - pszName = szReplace; - } - m_message.SendMsg(EM_SETSEL, start, end); - m_message.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)pszName); - } - return true; - } - - if (end != start) { - m_message.SendMsg(EM_SETSEL, start, end); - m_message.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)m_wszSearchQuery); - } - replaceStrW(m_wszSearchQuery, nullptr); - return false; -} - -static void __cdecl phase2(SESSION_INFO *si) -{ - Thread_SetName("TabSRMM: phase2"); - - Sleep(30); - if (si && si->pDlg) - si->pDlg->RedrawLog2(); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// the actual group chat session window procedure.Handles the entire chat session window -// which is usually a (tabbed) child of a container class window. - -CMsgDialog::CMsgDialog(SESSION_INFO *si) - : CSuper(IDD_CHANNEL, si), - m_btnOk(this, IDOK) -{ - m_szProto = GetContactProto(m_hContact); - m_bFilterEnabled = db_get_b(m_hContact, CHAT_MODULE, "FilterEnabled", m_bFilterEnabled) != 0; - - m_btnOk.OnClick = Callback(this, &CMsgDialog::onClick_OK); - m_btnFilter.OnClick = Callback(this, &CMsgDialog::onClick_Filter); - m_btnNickList.OnClick = Callback(this, &CMsgDialog::onClick_ShowNickList); - - m_nickList.OnDblClick = Callback(this, &CMsgDialog::onDblClick_List); - - m_message.OnChange = Callback(this, &CMsgDialog::onChange_Message); -} - -CThumbBase* CMsgDialog::tabCreateThumb(CProxyWindow *pProxy) const -{ - return new CThumbMUC(pProxy, m_si); -} - -void CMsgDialog::tabClearLog() -{ - SESSION_INFO *s = g_chatApi.SM_FindSession(m_si->ptszID, m_si->pszModule); - if (s) { - ClearLog(); - g_chatApi.LM_RemoveAll(&s->pLog, &s->pLogEnd); - s->iEventCount = 0; - s->LastTime = 0; - m_si->iEventCount = 0; - m_si->LastTime = 0; - m_si->pLog = s->pLog; - m_si->pLogEnd = s->pLogEnd; - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - } -} - -bool CMsgDialog::OnInitDialog() -{ - CSuper::OnInitDialog(); - - m_si->pDlg = this; - - Chat_SetFilters(m_si); - - m_iSplitterY = m_pContainer->m_pSettings->iSplitterY; - if (m_bIsAutosizingInput) - m_iSplitterY = GetDefaultMinimumInputHeight(); - - // Typing support for GCW_PRIVMESS sessions - if (m_si->iType == GCW_PRIVMESS) { - m_nTypeMode = PROTOTYPE_SELFTYPING_OFF; - SetTimer(m_hwnd, TIMERID_TYPE, 1000, nullptr); - } - - m_pPanel.getVisibility(); - m_pPanel.Configure(); - - SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_PANELSPLITTER), GWLP_WNDPROC, (LONG_PTR)SplitterSubclassProc); - NotifyEvent(MSG_WINDOW_EVT_OPENING); - - m_log.SendMsg(EM_AUTOURLDETECT, 1, 0); - m_log.SendMsg(EM_SETEVENTMASK, 0, m_log.SendMsg(EM_GETEVENTMASK, 0, 0) | ENM_LINK | ENM_MOUSEEVENTS | ENM_KEYEVENTS); - m_log.SendMsg(EM_LIMITTEXT, 0x7FFFFFFF, 0); - m_log.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3)); - - m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_REQUESTRESIZE | ENM_MOUSEEVENTS | ENM_SCROLL | ENM_KEYEVENTS | ENM_CHANGE); - m_message.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3)); - - m_pPanel.loadHeight(); - - if (PluginConfig.g_hMenuTrayUnread != nullptr && m_hContact != 0 && m_szProto != nullptr) - UpdateTrayMenu(nullptr, m_wStatus, m_szProto, m_wszStatus, m_hContact, 0); - - m_log.SendMsg(EM_HIDESELECTION, TRUE, 0); - - GetMYUIN(); - GetMyNick(); - - HWND hwndBtn = CreateWindowEx(0, L"MButtonClass", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0, 0, 6, DPISCALEY_S(20), m_hwnd, (HMENU)IDC_TOGGLESIDEBAR, g_plugin.getInst(), nullptr); - CustomizeButton(hwndBtn); - SendMessage(hwndBtn, BUTTONSETASTHEMEDBTN, 1, 0); - SendMessage(hwndBtn, BUTTONSETCONTAINER, (LPARAM)m_pContainer, 0); - SendMessage(hwndBtn, BUTTONSETASFLATBTN, FALSE, 0); - SendMessage(hwndBtn, BUTTONSETASTOOLBARBUTTON, TRUE, 0); - SendMessage(hwndBtn, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Expand or collapse the side bar"), BATF_UNICODE); - - DM_InitTip(); - BB_InitDlgButtons(); - SendMessage(m_hwnd, WM_CBD_LOADICONS, 0, 0); - - mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERX), SplitterSubclassProc); - mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERY), SplitterSubclassProc); - - UpdateOptions(); - UpdateStatusBar(); - UpdateTitle(); - m_hTabIcon = m_hTabStatusIcon; - - RECT rc; - SendMessage(m_pContainer->m_hwnd, DM_QUERYCLIENTAREA, 0, (LPARAM)&rc); - SetWindowPos(m_hwnd, HWND_TOP, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), 0); - ShowWindow(m_hwnd, SW_SHOW); - UpdateNickList(); - m_pContainer->m_hwndActive = m_hwnd; - NotifyEvent(MSG_WINDOW_EVT_OPEN); - return true; -} - -void CMsgDialog::OnDestroy() -{ - // Typing support for GCW_PRIVMESS sessions - if (m_si->iType == GCW_PRIVMESS) - if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON) - DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF); - - if (g_clistApi.pfnGetEvent(m_si->hContact, 0)) - g_clistApi.pfnRemoveEvent(m_si->hContact, GC_FAKE_EVENT); - m_si->wState &= ~STATE_TALK; - m_si->pDlg = nullptr; - m_si = nullptr; - - NotifyEvent(MSG_WINDOW_EVT_CLOSING); - - DM_FreeTheme(); - - UpdateTrayMenuState(this, FALSE); // remove me from the tray menu (if still there) - if (PluginConfig.g_hMenuTrayUnread) - DeleteMenu(PluginConfig.g_hMenuTrayUnread, (UINT_PTR)m_hContact, MF_BYCOMMAND); - - if (m_hwndTip) - DestroyWindow(m_hwndTip); - - int i = GetTabIndexFromHWND(m_hwndParent, m_hwnd); - if (i >= 0) { - SendMessage(m_hwndParent, WM_USER + 100, 0, 0); // clean up tooltip - TabCtrl_DeleteItem(m_hwndParent, i); - m_pContainer->UpdateTabs(); - m_iTabID = -1; - } - - if (m_pWnd) { - delete m_pWnd; - m_pWnd = nullptr; - } - - NotifyEvent(MSG_WINDOW_EVT_CLOSE); - - m_pContainer->ClearMargins(); - PostMessage(m_pContainer->m_hwnd, WM_SIZE, 0, 1); - - if (m_pContainer->m_dwFlags & CNT_SIDEBAR) - m_pContainer->m_pSideBar->removeSession(this); - - CSuper::OnDestroy(); -} - -void CMsgDialog::onClick_OK(CCtrlButton*) -{ - if (GetSendButtonState(m_hwnd) == PBS_DISABLED) - return; - - ptrA pszRtf(m_message.GetRichTextRtf()); - if (pszRtf == nullptr) - return; - - CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf))); - if (ptszText.IsEmpty()) - return; - - m_cache->saveHistory(); - DoRtfToTags(ptszText); - ptszText.Trim(); - - if (m_si->pMI->bAckMsg) { - m_message.Enable(false); - m_message.SendMsg(EM_SETREADONLY, TRUE, 0); - } - else m_message.SetText(L""); - - Utils::enableDlgControl(m_hwnd, IDOK, false); - - // Typing support for GCW_PRIVMESS sessions - if (m_si->iType == GCW_PRIVMESS) - if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON) - DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF); - - bool fSound = true; - if (ptszText[0] == '/' || m_si->iType == GCW_SERVER) - fSound = false; - Chat_DoEventHook(m_si, GC_USER_MESSAGE, nullptr, ptszText, 0); - m_si->pMI->idleTimeStamp = time(0); - UpdateStatusBar(); - if (m_pContainer) - if (fSound && !nen_options.iNoSounds && !(m_pContainer->m_dwFlags & CNT_NOSOUND)) - Skin_PlaySound("ChatSent"); - - SetFocus(m_message.GetHwnd()); -} - -void CMsgDialog::onClick_Filter(CCtrlButton *pButton) -{ - if (!pButton->Enabled()) - return; - - if (m_iLogFilterFlags == 0 && !m_bFilterEnabled) { - MessageBox(nullptr, TranslateT("The filter cannot be enabled, because there are no event types selected either global or for this chat room"), TranslateT("Event filter error"), MB_OK); - m_bFilterEnabled = false; - } - else m_bFilterEnabled = !m_bFilterEnabled; - - m_btnFilter.SendMsg(BUTTONSETOVERLAYICON, (LPARAM)(m_bFilterEnabled ? PluginConfig.g_iconOverlayEnabled : PluginConfig.g_iconOverlayDisabled), 0); - - if (m_bFilterEnabled && db_get_b(0, CHAT_MODULE, "RightClickFilter", 1) == 0) { - ShowFilterMenu(); - return; - } - RedrawLog(); - UpdateTitle(); - db_set_b(m_si->hContact, CHAT_MODULE, "FilterEnabled", m_bFilterEnabled); -} - -void CMsgDialog::onClick_ShowNickList(CCtrlButton *pButton) -{ - if (!pButton->Enabled() || m_si->iType == GCW_SERVER) - return; - - m_bNicklistEnabled = !m_bNicklistEnabled; - - Resize(); - if (CSkin::m_skinEnabled) - InvalidateRect(m_hwnd, nullptr, TRUE); - ScrollToBottom(); -} - -void CMsgDialog::onChange_Message(CCtrlEdit*) -{ - if (m_pContainer->m_hwndActive == m_hwnd) - UpdateReadChars(); - m_dwLastActivity = GetTickCount(); - m_pContainer->m_dwLastActivity = m_dwLastActivity; - m_btnOk.SendMsg(BUTTONSETASNORMAL, m_message.GetRichTextLength() != 0, 0); - m_btnOk.Enable(m_message.GetRichTextLength() != 0); - - // Typing support for GCW_PRIVMESS sessions - if (m_si->iType == GCW_PRIVMESS) { - if (!(GetKeyState(VK_CONTROL) & 0x8000)) { - m_nLastTyping = GetTickCount(); - if (GetWindowTextLength(m_message.GetHwnd())) { - if (m_nTypeMode == PROTOTYPE_SELFTYPING_OFF) { - if (!(m_dwFlags & MWF_INITMODE)) - DM_NotifyTyping(PROTOTYPE_SELFTYPING_ON); - } - } - else if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON) - DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF); - } - } -} - -void CMsgDialog::onDblClick_List(CCtrlListBox *pList) -{ - TVHITTESTINFO hti; - hti.pt.x = (short)LOWORD(GetMessagePos()); - hti.pt.y = (short)HIWORD(GetMessagePos()); - ScreenToClient(pList->GetHwnd(), &hti.pt); - - int item = LOWORD(pList->SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y))); - USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, item); - if (ui == nullptr) - return; - - bool bShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; - if (g_Settings.bDoubleClick4Privat ? bShift : !bShift) { - int selStart = LOWORD(m_message.SendMsg(EM_GETSEL, 0, 0)); - CMStringW tszName(ui->pszNick); - if (selStart == 0) - tszName.AppendChar(g_Settings.bUseCommaAsColon ? ',' : ':'); - tszName.AppendChar(' '); - - m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)tszName.GetString()); - PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); - SetFocus(m_message.GetHwnd()); - } - else Chat_DoEventHook(m_si, GC_USER_PRIVMESS, ui, nullptr, 0); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CMsgDialog::AddLog() -{ - if (PluginConfig.m_bUseDividers) { - if (PluginConfig.m_bDividersUsePopupConfig) { - if (!MessageWindowOpened(0, m_hwnd)) - DM_AddDivider(); - } - else { - bool bInactive = !IsActive(); - if (bInactive) - DM_AddDivider(); - else if (m_pContainer->m_hwndActive != m_hwnd) - DM_AddDivider(); - } - } - - CSrmmBaseDialog::AddLog(); -} - -void CMsgDialog::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_si->iType != GCW_PRIVMESS) || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0) - index++; - } - StreamInEvents(pLog, TRUE); - mir_forkThread<SESSION_INFO>(phase2, m_si); - } - else StreamInEvents(m_si->pLogEnd, TRUE); - } - else ClearLog(); -} void CMsgDialog::ScrollToBottom() { @@ -892,433 +256,6 @@ void CMsgDialog::UpdateStatusBar() m_pWnd->Invalidate(); } -void CMsgDialog::UpdateTitle() -{ - m_wStatus = m_si->wStatus; - - const wchar_t *szNick = m_cache->getNick(); - if (mir_wstrlen(szNick) > 0) { - if (M.GetByte("cuttitle", 0)) - CutContactName(szNick, m_wszTitle, _countof(m_wszTitle)); - else - wcsncpy_s(m_wszTitle, szNick, _TRUNCATE); - } - - CMStringW wszTitle; - HICON hIcon = nullptr; - int nUsers = m_si->getUserList().getCount(); - - switch (m_si->iType) { - case GCW_CHATROOM: - hIcon = Skin_LoadProtoIcon(m_si->pszModule, (m_wStatus <= ID_STATUS_OFFLINE) ? ID_STATUS_OFFLINE : m_wStatus); - wszTitle.Format((nUsers == 1) ? TranslateT("%s: chat room (%u user%s)") : TranslateT("%s: chat room (%u users%s)"), - szNick, nUsers, m_bFilterEnabled ? TranslateT(", event filter active") : L""); - break; - - case GCW_PRIVMESS: - hIcon = Skin_LoadProtoIcon(m_si->pszModule, (m_wStatus <= ID_STATUS_OFFLINE) ? ID_STATUS_OFFLINE : m_wStatus); - if (nUsers == 1) - wszTitle.Format(TranslateT("%s: message session"), szNick); - else - wszTitle.Format(TranslateT("%s: message session (%u users)"), szNick, nUsers); - break; - - case GCW_SERVER: - wszTitle.Format(L"%s: Server", szNick); - hIcon = LoadIconEx("window"); - break; - - default: - return; - } - - if (m_pWnd) { - m_pWnd->updateTitle(m_wszTitle); - m_pWnd->updateIcon(hIcon); - } - m_hTabStatusIcon = hIcon; - - if (m_cache->getStatus() != m_cache->getOldStatus()) { - wcsncpy_s(m_wszStatus, Clist_GetStatusModeDescription(m_wStatus, 0), _TRUNCATE); - - TCITEM item = {}; - item.mask = TCIF_TEXT; - item.pszText = m_wszTitle; - TabCtrl_SetItem(m_hwndParent, m_iTabID, &item); - } - SetWindowText(m_hwnd, wszTitle); - if (m_pContainer->m_hwndActive == m_hwnd) { - m_pContainer->UpdateTitle(0, this); - UpdateStatusBar(); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// subclassing for the message history display(rich edit control in which the chat history appears) - -LRESULT CMsgDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_NCCALCSIZE: - return CSkin::NcCalcRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, stubLogProc); - - case WM_NCPAINT: - return CSkin::DrawRichEditFrame(m_log.GetHwnd(), this, ID_EXTBKHISTORY, msg, wParam, lParam, stubLogProc); - - case WM_COPY: - return WMCopyHandler(msg, wParam, lParam); - - case WM_SETCURSOR: - if (g_Settings.bClickableNicks && (LOWORD(lParam) == HTCLIENT)) { - POINT pt; - GetCursorPos(&pt); - ScreenToClient(m_log.GetHwnd(), &pt); - if (CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, FALSE)) return TRUE; - } - break; - - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_RBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - if (g_Settings.bClickableNicks) { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE); - } - break; - - case WM_LBUTTONUP: - if (g_Settings.bClickableNicks) { - POINT pt = { LOWORD(lParam), HIWORD(lParam) }; - CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE); - } - if (M.GetByte("autocopy", 1)) { - CHARRANGE sel; - SendMessage(m_log.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin != sel.cpMax) { - SendMessage(m_log.GetHwnd(), WM_COPY, 0, 0); - sel.cpMin = sel.cpMax; - SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)&sel); - SetFocus(m_message.GetHwnd()); - } - } - break; - - case WM_KEYDOWN: - if (wParam == 0x57 && GetKeyState(VK_CONTROL) & 0x8000) { // ctrl-w (close window) - PostMessage(m_hwnd, WM_CLOSE, 0, 1); - return TRUE; - } - if (wParam == VK_INSERT && GetKeyState(VK_CONTROL) & 0x8000) - return WMCopyHandler(msg, wParam, lParam); - break; - - case WM_SYSKEYUP: - if (wParam == VK_MENU) { - ProcessHotkeysByMsgFilter(m_log, msg, wParam, lParam); - return 0; - } - break; - - case WM_SYSKEYDOWN: - m_bkeyProcessed = false; - if (ProcessHotkeysByMsgFilter(m_log, msg, wParam, lParam)) { - m_bkeyProcessed = true; - return 0; - } - break; - - case WM_SYSCHAR: - if (m_bkeyProcessed) { - m_bkeyProcessed = false; - return 0; - } - break; - - case WM_CHAR: - bool isCtrl, isShift, isAlt; - KbdState(isShift, isCtrl, isAlt); - if (wParam == 0x03 && isCtrl) // Ctrl+C - return WMCopyHandler(msg, wParam, lParam); - break; - } - - return CSuper::WndProc_Log(msg, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// subclassing for the message input control(a richedit text control) - -LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (m_bkeyProcessed && (msg == WM_KEYUP)) { - GetKeyboardState(kstate); - if (!(kstate[VK_CONTROL] & 0x80) && !(kstate[VK_SHIFT] & 0x80)) - m_bkeyProcessed = false; - return 0; - } - - switch (msg) { - case WM_NCCALCSIZE: - return CSkin::NcCalcRichEditFrame(m_message.GetHwnd(), this, ID_EXTBKINPUTAREA, msg, wParam, lParam, stubMessageProc); - - case WM_NCPAINT: - return CSkin::DrawRichEditFrame(m_message.GetHwnd(), this, ID_EXTBKINPUTAREA, msg, wParam, lParam, stubMessageProc); - - case WM_CONTEXTMENU: - POINT pt; - GetCursorPos(&pt); - { - HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hSubMenu = GetSubMenu(hMenu, 2); - RemoveMenu(hSubMenu, 9, MF_BYPOSITION); - RemoveMenu(hSubMenu, 8, MF_BYPOSITION); - RemoveMenu(hSubMenu, 4, MF_BYPOSITION); - - EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | (m_si->pMI->bBold ? MF_ENABLED : MF_GRAYED)); - TranslateMenu(hSubMenu); - - CHARRANGE sel, all = { 0, -1 }; - m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) { - EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(hSubMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED); - } - - MessageWindowPopupData mwpd = { sizeof(mwpd) }; - mwpd.uType = MSG_WINDOWPOPUP_SHOWING; - mwpd.uFlags = MSG_WINDOWPOPUP_INPUT; - mwpd.hContact = m_hContact; - mwpd.hwnd = m_message.GetHwnd(); - mwpd.hMenu = hSubMenu; - mwpd.pt = pt; - NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)&mwpd); - - int iSelection = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr); - - mwpd.selection = iSelection; - mwpd.uType = MSG_WINDOWPOPUP_SELECTED; - NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)&mwpd); - - switch (iSelection) { - case IDM_COPY: - m_message.SendMsg(WM_COPY, 0, 0); - break; - case IDM_CUT: - m_message.SendMsg(WM_CUT, 0, 0); - break; - case IDM_PASTE: - case IDM_PASTEFORMATTED: - m_message.SendMsg(EM_PASTESPECIAL, (iSelection == IDM_PASTE) ? CF_UNICODETEXT : 0, 0); - break; - case IDM_COPYALL: - m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); - m_message.SendMsg(WM_COPY, 0, 0); - m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel); - break; - case IDM_SELECTALL: - m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all); - break; - } - DestroyMenu(hMenu); - } - return TRUE; - - case WM_MOUSEWHEEL: - if (DM_MouseWheelHandler(wParam, lParam) == 0) - return 0; - - m_iLastEnterTime = 0; - break; - - case WM_SYSKEYUP: - if (wParam == VK_MENU) { - ProcessHotkeysByMsgFilter(m_message, msg, wParam, lParam); - return 0; - } - break; - - case WM_SYSKEYDOWN: - m_bkeyProcessed = false; - if (ProcessHotkeysByMsgFilter(m_message, msg, wParam, lParam)) { - m_bkeyProcessed = true; - return 0; - } - break; - - case WM_SYSCHAR: - if (m_bkeyProcessed) { - m_bkeyProcessed = false; // preceeding key event has been processed by miranda hotkey service - return 0; - } - - if ((wParam >= '0' && wParam <= '9') && (GetKeyState(VK_MENU) & 0x8000)) { // ALT-1 -> ALT-0 direct tab selection - BYTE bChar = (BYTE)wParam; - int iIndex = (bChar == '0') ? 10 : bChar - (BYTE)'0'; - SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_BY_INDEX, (LPARAM)iIndex); - return 0; - } - break; - - case WM_CHAR: - bool isShift, isAlt, isCtrl; - KbdState(isShift, isCtrl, isAlt); - - if (!isAlt && !isCtrl && !(m_pContainer->m_dwFlags & CNT_NOSOUND) && wParam != VK_ESCAPE && !(wParam == VK_TAB && PluginConfig.m_bAllowTab)) - Skin_PlaySound("SoundOnTyping"); - - if (isCtrl && !isAlt && !isShift) - switch (wParam) { - case 0x17: - PostMessage(m_hwnd, WM_CLOSE, 0, 1); - return 0; - } - - break; - - case WM_KEYDOWN: - KbdState(isShift, isCtrl, isAlt); - - // sound on typing.. - if (!isAlt && wParam == VK_DELETE) - Skin_PlaySound("SoundOnTyping"); - - if (wParam != VK_ESCAPE) - if (ProcessHotkeys(wParam, isShift, isCtrl, isAlt)) - return true; - - if (wParam == VK_INSERT && !isShift && !isCtrl && !isAlt) { - m_bInsertMode = !m_bInsertMode; - m_message.OnChange(&m_message); - } - if (wParam == VK_CAPITAL || wParam == VK_NUMLOCK) - m_message.OnChange(&m_message); - - if (isCtrl && isAlt && !isShift) { - switch (wParam) { - case VK_UP: - case VK_DOWN: - case VK_PRIOR: - case VK_NEXT: - case VK_HOME: - case VK_END: - WPARAM wp = 0; - - if (wParam == VK_UP) - wp = MAKEWPARAM(SB_LINEUP, 0); - else if (wParam == VK_PRIOR) - wp = MAKEWPARAM(SB_PAGEUP, 0); - else if (wParam == VK_NEXT) - wp = MAKEWPARAM(SB_PAGEDOWN, 0); - else if (wParam == VK_HOME) - wp = MAKEWPARAM(SB_TOP, 0); - else if (wParam == VK_END) { - DM_ScrollToBottom(0, 0); - return 0; - } - else if (wParam == VK_DOWN) - wp = MAKEWPARAM(SB_LINEDOWN, 0); - - m_log.SendMsg(WM_VSCROLL, wp, 0); - return 0; - } - } - - if (wParam == VK_RETURN) { - if (isShift) { - if (PluginConfig.m_bSendOnShiftEnter) { - PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); - return 0; - } - break; - } - if ((isCtrl && !isShift) ^ (0 != PluginConfig.m_bSendOnEnter)) { - PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); - return 0; - } - if (!PluginConfig.m_bSendOnEnter && !PluginConfig.m_bSendOnDblEnter) - break; - if (isCtrl) - break; - - if (PluginConfig.m_bSendOnDblEnter) { - if (m_iLastEnterTime + 2 < time(0)) { - m_iLastEnterTime = time(0); - break; - } - - m_message.SendMsg(WM_KEYDOWN, VK_BACK, 0); - m_message.SendMsg(WM_KEYUP, VK_BACK, 0); - PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); - return 0; - } - PostMessage(m_hwnd, WM_COMMAND, IDOK, 0); - return 0; - } - else m_iLastEnterTime = 0; - - if ((wParam == VK_NEXT && isCtrl && !isShift) || (wParam == VK_TAB && isCtrl && !isShift)) { // CTRL-TAB (switch tab/window) - SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_NEXT, 0); - return TRUE; - } - - if ((wParam == VK_PRIOR && isCtrl && !isShift) || (wParam == VK_TAB && isCtrl && isShift)) { // CTRL_SHIFT-TAB (switch tab/window) - SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_PREV, 0); - return TRUE; - } - if (wParam == VK_TAB && !isCtrl && !isShift) { // tab-autocomplete - m_message.SendMsg(WM_SETREDRAW, FALSE, 0); - bool fCompleted = TabAutoComplete(); - m_message.SendMsg(WM_SETREDRAW, TRUE, 0); - RedrawWindow(m_message.GetHwnd(), nullptr, nullptr, RDW_INVALIDATE); - if (!fCompleted && !PluginConfig.m_bAllowTab) { - if ((GetSendButtonState(GetHwnd()) != PBS_DISABLED)) - SetFocus(m_btnOk.GetHwnd()); - else - SetFocus(m_log.GetHwnd()); - } - return 0; - } - - if (wParam != VK_RIGHT && wParam != VK_LEFT) { - replaceStrW(m_wszSearchQuery, nullptr); - replaceStrW(m_wszSearchResult, nullptr); - } - - if (wParam == VK_F4 && isCtrl && !isAlt) { // ctrl-F4 (close tab) - CloseTab(); - return 0; - } - - if (wParam == VK_NEXT || wParam == VK_PRIOR) { - m_log.SendMsg(msg, wParam, lParam); - m_iLastEnterTime = 0; - return 0; - } - - // input history scrolling (ctrl-up / down) - if (isCtrl && !isAlt && !isShift && (wParam == VK_UP || wParam == VK_DOWN)) { - m_iLastEnterTime = 0; - m_cache->inputHistoryEvent(wParam); - return 0; - } - - __fallthrough; - - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_KILLFOCUS: - m_iLastEnterTime = 0; - break; - - case WM_ERASEBKGND: - return !CSkin::m_skinEnabled; - } - - return CSuper::WndProc_Message(msg, wParam, lParam); -} - ///////////////////////////////////////////////////////////////////////////////////////// // subclassing for the nickname list control.It is an ownerdrawn listbox @@ -1577,725 +514,6 @@ INT_PTR CALLBACK CMsgDialog::FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wPara } ///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - POINT pt, tmp, cur; - RECT rc; - - switch (uMsg) { - case WM_SETFOCUS: - if (CMimAPI::m_shutDown) - break; - - UpdateWindowState(WM_SETFOCUS); - SetFocus(m_message.GetHwnd()); - return 1; - - case WM_TIMECHANGE: - RedrawLog(); - break; - - case WM_CBD_LOADICONS: - Srmm_UpdateToolbarIcons(m_hwnd); - return 0; - - case WM_SIZE: - if (m_ipFieldHeight == 0) - m_ipFieldHeight = CInfoPanel::m_ipConfig.height1; - - if (wParam == SIZE_MAXIMIZED) - ScrollToBottom(); - - if (!IsIconic(m_hwnd)) { - int panelHeight = m_pPanel.getHeight() + 1; - - GetClientRect(m_hwnd, &rc); - int cx = rc.right; - - CSuper::DlgProc(uMsg, 0, 0); // call basic window resizer - - BB_SetButtonsPos(); - - rc.left = panelHeight <= CInfoPanel::LEFT_OFFSET_LOGO ? panelHeight : CInfoPanel::LEFT_OFFSET_LOGO; - rc.right = cx; - rc.top = 1; - rc.bottom = (panelHeight > CInfoPanel::DEGRADE_THRESHOLD ? rc.top + m_ipFieldHeight - 2 : panelHeight - 1); - m_rcNick = rc; - - rc.left = panelHeight <= CInfoPanel::LEFT_OFFSET_LOGO ? panelHeight : CInfoPanel::LEFT_OFFSET_LOGO; - rc.right = cx; - rc.bottom = panelHeight - 2; - rc.top = m_rcNick.bottom + 1; - m_rcUIN = rc; - - if (m_hwndIEView || m_hwndHPP) - ResizeIeView(); - DetermineMinHeight(); - } - return 0; - - case DM_TYPING: - // Typing support for GCW_PRIVMESS sessions - if (m_si->iType == GCW_PRIVMESS) { - int preTyping = m_nTypeSecs != 0; - m_nTypeSecs = (int)lParam > 0 ? (int)lParam : 0; - - if (m_nTypeSecs) - m_bShowTyping = 0; - - SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, preTyping); - } - return TRUE; - - case WM_CTLCOLORLISTBOX: - SetBkColor((HDC)wParam, g_Settings.crUserListBGColor); - return (INT_PTR)g_chatApi.hListBkgBrush; - - case WM_MEASUREITEM: - { - MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam; - if (mis->CtlType == ODT_MENU) { - if (m_pPanel.isHovered()) { - mis->itemHeight = 0; - mis->itemWidth = 6; - return TRUE; - } - return Menu_MeasureItem(lParam); - } - mis->itemHeight = g_Settings.iNickListFontHeight; - } - return TRUE; - - case WM_DRAWITEM: - { - DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; - if (dis->CtlType == ODT_MENU) { - if (m_pPanel.isHovered()) { - DrawMenuItem(dis, (HICON)dis->itemData, 0); - return TRUE; - } - return Menu_DrawItem(lParam); - } - - if (dis->CtlID == IDC_SRMM_NICKLIST) { - int x_offset = 0; - int index = dis->itemID; - - USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, index); - if (ui == nullptr) - return TRUE; - - int height = dis->rcItem.bottom - dis->rcItem.top; - if (height & 1) - height++; - int offset = (height == 10) ? 0 : height / 2; - - HICON hIcon = g_chatApi.SM_GetStatusIcon(m_si, ui); - HFONT hFont = g_Settings.UserListFonts[ui->iStatusEx]; - HFONT hOldFont = (HFONT)SelectObject(dis->hDC, hFont); - SetBkMode(dis->hDC, TRANSPARENT); - - int nickIndex = 0; - for (int i = 0; i < STATUSICONCOUNT; i++) { - if (hIcon == g_chatApi.hIcons[ICON_STATUS0 + i]) { - nickIndex = i; - break; - } - } - - if (dis->itemState & ODS_SELECTED) { - FillRect(dis->hDC, &dis->rcItem, g_Settings.SelectionBGBrush); - SetTextColor(dis->hDC, g_Settings.nickColors[6]); - } - else { - FillRect(dis->hDC, &dis->rcItem, g_chatApi.hListBkgBrush); - if (g_Settings.bColorizeNicks && nickIndex != 0) - SetTextColor(dis->hDC, g_Settings.nickColors[nickIndex - 1]); - else - SetTextColor(dis->hDC, g_Settings.UserListColors[ui->iStatusEx]); - } - x_offset = 2; - - if (g_Settings.bShowContactStatus && g_Settings.bContactStatusFirst && ui->ContactStatus) { - HICON icon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus); - DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 8, icon, 16, 16, 0, nullptr, DI_NORMAL); - IcoLib_ReleaseIcon(icon); - x_offset += 18; - } - - if (g_Settings.bClassicIndicators) { - char szTemp[3]; - szTemp[1] = 0; - szTemp[0] = szIndicators[nickIndex]; - if (szTemp[0]) { - SIZE szUmode; - GetTextExtentPoint32A(dis->hDC, szTemp, 1, &szUmode); - TextOutA(dis->hDC, x_offset, dis->rcItem.top, szTemp, 1); - x_offset += szUmode.cx + 2; - } - else x_offset += 8; - } - else { - DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 5, hIcon, 10, 10, 0, nullptr, DI_NORMAL); - x_offset += 12; - } - - if (g_Settings.bShowContactStatus && !g_Settings.bContactStatusFirst && ui->ContactStatus) { - HICON icon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus); - DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 8, icon, 16, 16, 0, nullptr, DI_NORMAL); - IcoLib_ReleaseIcon(icon); - x_offset += 18; - } - - SIZE sz; - if (m_iSearchItem != -1 && m_iSearchItem == index && m_wszSearch[0]) { - COLORREF clr_orig = GetTextColor(dis->hDC); - GetTextExtentPoint32(dis->hDC, ui->pszNick, (int)mir_wstrlen(m_wszSearch), &sz); - SetTextColor(dis->hDC, RGB(250, 250, 0)); - TextOut(dis->hDC, x_offset, (dis->rcItem.top + dis->rcItem.bottom - sz.cy) / 2, ui->pszNick, (int)mir_wstrlen(m_wszSearch)); - SetTextColor(dis->hDC, clr_orig); - x_offset += sz.cx; - TextOut(dis->hDC, x_offset, (dis->rcItem.top + dis->rcItem.bottom - sz.cy) / 2, ui->pszNick + mir_wstrlen(m_wszSearch), int(mir_wstrlen(ui->pszNick) - mir_wstrlen(m_wszSearch))); - } - else { - GetTextExtentPoint32(dis->hDC, ui->pszNick, (int)mir_wstrlen(ui->pszNick), &sz); - TextOut(dis->hDC, x_offset, (dis->rcItem.top + dis->rcItem.bottom - sz.cy) / 2, ui->pszNick, (int)mir_wstrlen(ui->pszNick)); - SelectObject(dis->hDC, hOldFont); - } - return TRUE; - } - } - break; - - case WM_CONTEXTMENU: - { - DWORD idFrom = GetDlgCtrlID((HWND)wParam); - if (idFrom >= MIN_CBUTTONID && idFrom <= MAX_CBUTTONID) - Srmm_ClickToolbarIcon(m_hContact, idFrom, m_hwnd, 1); - } - break; - - case DM_SPLITTERMOVED: - RECT rcLog; - GetWindowRect(m_log.GetHwnd(), &rcLog); - - if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERX)) { - GetClientRect(m_hwnd, &rc); - pt.x = wParam, pt.y = 0; - ScreenToClient(m_hwnd, &pt); - - int iSplitterX = rc.right - pt.x + 1; - if (iSplitterX < 35) - iSplitterX = 35; - if (iSplitterX > rc.right - rc.left - 35) - iSplitterX = rc.right - rc.left - 35; - m_pContainer->m_pSettings->iSplitterX = iSplitterX; - Resize(); - } - else if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERY) || lParam == -1) { - GetClientRect(m_hwnd, &rc); - rc.top += (m_pPanel.isActive() ? m_pPanel.getHeight() + 40 : 30); - pt.x = 0, pt.y = wParam; - ScreenToClient(m_hwnd, &pt); - - m_iSplitterY = rc.bottom - pt.y + 3 + DPISCALEY_S(23); - int iMinHeight = DPISCALEY_S(23) + ((m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR) ? 21 : 0); - if (m_iSplitterY < iMinHeight) - m_iSplitterY = iMinHeight; - if (m_iSplitterY > rc.bottom - rc.top - DPISCALEY_S(40)) - m_iSplitterY = rc.bottom - rc.top - DPISCALEY_S(40); - m_pContainer->m_pSettings->iSplitterY = m_iSplitterY; - UpdateToolbarBG(); - Resize(); - } - else if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_PANELSPLITTER)) { - pt.x = 0, pt.y = wParam; - ScreenToClient(m_hwnd, &pt); - GetClientRect(m_log.GetHwnd(), &rc); - if ((pt.y + 2 >= MIN_PANELHEIGHT + 2) && (pt.y + 2 < 100) && (pt.y + 2 < rc.bottom - 30)) - m_pPanel.setHeight(pt.y + 2); - RedrawWindow(m_hwnd, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE); - if (M.isAero()) - InvalidateRect(m_hwndParent, nullptr, FALSE); - SendMessage(m_hwnd, WM_SIZE, DM_SPLITTERMOVED, 0); - break; - } - break; - - case WM_TIMER: - if (wParam == TIMERID_FLASHWND) - if (m_bCanFlashTab) - FlashTab(true); - - // Typing support for GCW_PRIVMESS sessions - if (m_si->iType == GCW_PRIVMESS && wParam == TIMERID_TYPE) - DM_Typing(false); - break; - - case WM_ACTIVATE: - case WM_MOUSEACTIVATE: - if (LOWORD(wParam) != WA_ACTIVE) { - m_pContainer->m_hwndSaved = nullptr; - break; - } - - UpdateWindowState(WM_ACTIVATE); - return 1; - - case WM_NOTIFY: - switch (((LPNMHDR)lParam)->code) { - case EN_MSGFILTER: - bool isShift, isCtrl, isMenu; - { - UINT msg = ((MSGFILTER *)lParam)->msg; - WPARAM wp = ((MSGFILTER *)lParam)->wParam; - LPARAM lp = ((MSGFILTER *)lParam)->lParam; - - KbdState(isShift, isCtrl, isMenu); - - MSG message; - message.hwnd = m_hwnd; - message.message = msg; - message.lParam = lp; - message.wParam = wp; - - if (msg == WM_SYSKEYUP) { - if (wp == VK_MENU) - if (!m_bkeyProcessed && !(GetKeyState(VK_CONTROL) & 0x8000) && !(GetKeyState(VK_SHIFT) & 0x8000) && !(lp & (1 << 24))) - m_pContainer->m_pMenuBar->autoShow(); - - return _dlgReturn(m_hwnd, 0); - } - - if (msg == WM_MOUSEMOVE) { - GetCursorPos(&pt); - DM_DismissTip(pt); - m_pPanel.trackMouse(pt); - break; - } - if (msg == WM_KEYDOWN) { - if ((wp == VK_INSERT && isShift && !isCtrl && !isMenu) || (wp == 'V' && !isShift && !isMenu && isCtrl)) { - m_message.SendMsg(EM_PASTESPECIAL, CF_UNICODETEXT, 0); - ((MSGFILTER*)lParam)->msg = WM_NULL; - ((MSGFILTER*)lParam)->wParam = 0; - ((MSGFILTER*)lParam)->lParam = 0; - return _dlgReturn(m_hwnd, 1); - } - } - - if (msg == WM_LBUTTONDOWN || msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN) - m_pContainer->m_pMenuBar->Cancel(); - - if ((msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) && !(GetKeyState(VK_RMENU) & 0x8000)) { - if (DM_GenericHotkeysCheck(&message)) { - m_bkeyProcessed = true; - return _dlgReturn(m_hwnd, 1); - } - - LRESULT mim_hotkey_check = Hotkey_Check(&message, TABSRMM_HK_SECTION_GC); - if (mim_hotkey_check) - m_bkeyProcessed = true; - - switch (mim_hotkey_check) { - case TABSRMM_HK_CHANNELMGR: - onClick_ChanMgr(&m_btnChannelMgr); - return _dlgReturn(m_hwnd, 1); - case TABSRMM_HK_FILTERTOGGLE: - onClick_Filter(&m_btnFilter); - InvalidateRect(m_btnFilter.GetHwnd(), nullptr, TRUE); - return _dlgReturn(m_hwnd, 1); - case TABSRMM_HK_LISTTOGGLE: - onClick_ShowNickList(&m_btnNickList); - return _dlgReturn(m_hwnd, 1); - case TABSRMM_HK_MUC_SHOWSERVER: - if (m_si->iType != GCW_SERVER) - Chat_DoEventHook(m_si, GC_USER_MESSAGE, nullptr, L"/servershow", 0); - return _dlgReturn(m_hwnd, 1); - } - } - - if (msg == WM_KEYDOWN && ((NMHDR*)lParam)->idFrom != IDC_SRMM_MESSAGE) { - if ((wp == VK_NEXT && isCtrl && !isShift) || (wp == VK_TAB && isCtrl && !isShift)) // CTRL-TAB (switch tab/window) - SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_NEXT, 0); - else if ((wp == VK_PRIOR && isCtrl && !isShift) || (wp == VK_TAB && isCtrl && isShift)) // CTRL_SHIFT-TAB (switch tab/window) - SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, DM_SELECT_PREV, 0); - } - - if (msg == WM_KEYDOWN && wp == VK_TAB) { - if (((NMHDR*)lParam)->idFrom == IDC_SRMM_LOG) { - SetFocus(m_message.GetHwnd()); - return _dlgReturn(m_hwnd, 1); - } - } - - if (((LPNMHDR)lParam)->idFrom == IDC_SRMM_LOG && ((MSGFILTER *)lParam)->msg == WM_RBUTTONUP) - return _dlgReturn(m_hwnd, 1); - } - break; - - case EN_REQUESTRESIZE: - if (((LPNMHDR)lParam)->idFrom == IDC_SRMM_MESSAGE) - DM_HandleAutoSizeRequest((REQRESIZE *)lParam); - break; - - case EN_LINK: - if (((LPNMHDR)lParam)->idFrom == IDC_SRMM_LOG) { - switch (((ENLINK*)lParam)->msg) { - case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - case WM_LBUTTONDBLCLK: - CHARRANGE sel; - SendMessage(((LPNMHDR)lParam)->hwndFrom, EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) { - UINT msg = ((ENLINK*)lParam)->msg; - m_pContainer->m_pMenuBar->Cancel(); - - TEXTRANGE tr; - tr.lpstrText = nullptr; - tr.chrg = ((ENLINK*)lParam)->chrg; - tr.lpstrText = (wchar_t*)mir_alloc(sizeof(wchar_t) * (tr.chrg.cpMax - tr.chrg.cpMin + 2)); - SendMessage(((LPNMHDR)lParam)->hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)&tr); - - BOOL isLink = IsStringValidLink(tr.lpstrText); - if (isLink) // handled by core - break; - - // clicked a nick name - if (g_Settings.bClickableNicks) { - if (msg == WM_RBUTTONDOWN) { - for (auto &ui : m_si->getUserList()) { - if (mir_wstrcmp(ui->pszNick, tr.lpstrText)) - continue; - - pt.x = (short)LOWORD(((ENLINK*)lParam)->lParam); - pt.y = (short)HIWORD(((ENLINK*)lParam)->lParam); - ClientToScreen(((NMHDR*)lParam)->hwndFrom, &pt); - RunUserMenu(m_hwnd, ui, pt); - break; - } - return TRUE; - } - - if (msg == WM_LBUTTONUP) { - CHARRANGE chr; - m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&chr); - - wchar_t tszAplTmpl[] = L"%s:"; - size_t bufSize = mir_wstrlen(tr.lpstrText) + mir_wstrlen(tszAplTmpl) + 3; - wchar_t *tszTmp = (wchar_t*)mir_alloc(bufSize * sizeof(wchar_t)), *tszAppeal = tszTmp; - - TEXTRANGE tr2; - tr2.lpstrText = (LPTSTR)mir_alloc(sizeof(wchar_t) * 2); - if (chr.cpMin) { - // prepend nick with space if needed - tr2.chrg.cpMin = chr.cpMin - 1; - tr2.chrg.cpMax = chr.cpMin; - m_message.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr2); - if (!iswspace(*tr2.lpstrText)) - *tszTmp++ = ' '; - mir_wstrcpy(tszTmp, tr.lpstrText); - } - else // in the beginning of the message window - mir_snwprintf(tszAppeal, bufSize, tszAplTmpl, tr.lpstrText); - - size_t st = mir_wstrlen(tszAppeal); - if (chr.cpMax != -1) { - tr2.chrg.cpMin = chr.cpMax; - tr2.chrg.cpMax = chr.cpMax + 1; - // if there is no space after selection, - // or there is nothing after selection at all... - if (!m_message.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)&tr2) || !iswspace(*tr2.lpstrText)) { - tszAppeal[st++] = ' '; - tszAppeal[st++] = '\0'; - } - } - else { - tszAppeal[st++] = ' '; - tszAppeal[st++] = '\0'; - } - m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)tszAppeal); - mir_free((void*)tr2.lpstrText); - mir_free((void*)tszAppeal); - } - } - SetFocus(m_message.GetHwnd()); - mir_free(tr.lpstrText); - return TRUE; - } - } - break; - } - break; - } - break; - - case WM_LBUTTONDOWN: - GetCursorPos(&tmp); - if (!m_pPanel.isHovered()) { - cur.x = (SHORT)tmp.x; - cur.y = (SHORT)tmp.y; - SendMessage(m_pContainer->m_hwnd, WM_NCLBUTTONDOWN, HTCAPTION, *((LPARAM*)(&cur))); - } - break; - - case WM_LBUTTONUP: - GetCursorPos(&tmp); - if (m_pPanel.isHovered()) - m_pPanel.handleClick(tmp); - else { - cur.x = (SHORT)tmp.x; - cur.y = (SHORT)tmp.y; - SendMessage(m_pContainer->m_hwnd, WM_NCLBUTTONUP, HTCAPTION, *((LPARAM*)(&cur))); - } - break; - - case WM_MOUSEMOVE: - GetCursorPos(&pt); - DM_DismissTip(pt); - m_pPanel.trackMouse(pt); - break; - - case WM_APPCOMMAND: - { - DWORD cmd = GET_APPCOMMAND_LPARAM(lParam); - if (cmd == APPCOMMAND_BROWSER_BACKWARD || cmd == APPCOMMAND_BROWSER_FORWARD) { - SendMessage(m_pContainer->m_hwnd, DM_SELECTTAB, cmd == APPCOMMAND_BROWSER_BACKWARD ? DM_SELECT_PREV : DM_SELECT_NEXT, 0); - return 1; - } - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_TOGGLESIDEBAR: - SendMessage(m_pContainer->m_hwnd, WM_COMMAND, IDC_TOGGLESIDEBAR, 0); - break; - - case IDCANCEL: - ShowWindow(m_pContainer->m_hwnd, SW_MINIMIZE); - return FALSE; - - case IDC_CLOSE: - CloseTab(); - break; - - case IDC_SELFTYPING: - // Typing support for GCW_PRIVMESS sessions - if (m_si->iType == GCW_PRIVMESS) { - if (m_hContact) { - int iCurrentTypingMode = g_plugin.getByte(m_hContact, SRMSGSET_TYPING, g_plugin.getByte(SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)); - - if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON && iCurrentTypingMode) { - DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF); - m_nTypeMode = PROTOTYPE_SELFTYPING_OFF; - } - g_plugin.setByte(m_hContact, SRMSGSET_TYPING, (BYTE)!iCurrentTypingMode); - } - } - break; - } - break; - - case WM_KEYDOWN: - SetFocus(m_message.GetHwnd()); - break; - - case WM_ERASEBKGND: - RECT rcClient, rcWindow; - { - HDC hdc = (HDC)wParam; - UINT item_ids[3] = { ID_EXTBKUSERLIST, ID_EXTBKHISTORY, ID_EXTBKINPUTAREA }; - UINT ctl_ids[3] = { IDC_SRMM_NICKLIST, IDC_SRMM_LOG, IDC_SRMM_MESSAGE }; - HANDLE hbp = nullptr; - HDC hdcMem = nullptr; - HBITMAP hbm, hbmOld; - - GetClientRect(m_hwnd, &rcClient); - LONG cx = rcClient.right - rcClient.left; - LONG cy = rcClient.bottom - rcClient.top; - - if (CMimAPI::m_haveBufferedPaint) { - hbp = CSkin::InitiateBufferedPaint(hdc, rcClient, hdcMem); - hbm = hbmOld = nullptr; - } - else { - hdcMem = CreateCompatibleDC(hdc); - hbm = CSkin::CreateAeroCompatibleBitmap(rcClient, hdc); - hbmOld = (HBITMAP)SelectObject(hdcMem, hbm); - } - - if (CSkin::m_skinEnabled && !M.isAero()) { - CSkin::SkinDrawBG(m_hwnd, m_pContainer->m_hwnd, m_pContainer, &rcClient, hdcMem); - for (int i = 0; i < 3; i++) { - CSkinItem *item = &SkinItems[item_ids[i]]; - if (!item->IGNORED) { - GetWindowRect(GetDlgItem(m_hwnd, ctl_ids[i]), &rcWindow); - pt.x = rcWindow.left; - pt.y = rcWindow.top; - ScreenToClient(m_hwnd, &pt); - rc.left = pt.x - item->MARGIN_LEFT; - rc.top = pt.y - item->MARGIN_TOP; - rc.right = rc.left + item->MARGIN_RIGHT + (rcWindow.right - rcWindow.left) + item->MARGIN_LEFT; - rc.bottom = rc.top + item->MARGIN_BOTTOM + (rcWindow.bottom - rcWindow.top) + item->MARGIN_TOP; - CSkin::DrawItem(hdcMem, &rc, item); - } - } - } - else { - CSkin::FillBack(hdcMem, &rcClient); - - if (M.isAero()) { - LONG temp = rcClient.bottom; - rcClient.bottom = m_pPanel.isActive() ? m_pPanel.getHeight() + 5 : 5; - FillRect(hdcMem, &rcClient, (HBRUSH)GetStockObject(BLACK_BRUSH)); - rcClient.bottom = temp; - } - } - - GetClientRect(m_hwnd, &rc); - m_pPanel.renderBG(hdcMem, rc, &SkinItems[ID_EXTBKINFOPANELBG], M.isAero()); - m_pPanel.renderContent(hdcMem); - - if (!CSkin::m_skinEnabled) - RenderToolbarBG(hdcMem, rcClient); - - if (hbp) - CSkin::FinalizeBufferedPaint(hbp, &rcClient); - else { - BitBlt(hdc, 0, 0, cx, cy, hdcMem, 0, 0, SRCCOPY); - SelectObject(hdcMem, hbmOld); - DeleteObject(hbm); - DeleteDC(hdcMem); - } - if (!m_fLimitedUpdate) - SetAeroMargins(m_pContainer); - } - return TRUE; - - case WM_NCPAINT: - if (CSkin::m_skinEnabled) - return 0; - break; - - case WM_PAINT: - PAINTSTRUCT ps; - BeginPaint(m_hwnd, &ps); - EndPaint(m_hwnd, &ps); - return 0; - - case WM_RBUTTONUP: - GetCursorPos(&pt); - if (!m_pPanel.invokeConfigDialog(pt)) { - HMENU subMenu = GetSubMenu(PluginConfig.g_hMenuContext, 0); - - MsgWindowUpdateMenu(subMenu, MENU_TABCONTEXT); - - int iSelection = TrackPopupMenu(subMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr); - if (iSelection >= IDM_CONTAINERMENU) { - char szIndex[10]; - _itoa_s(iSelection - IDM_CONTAINERMENU, szIndex, 10); - ptrW wszContainer(db_get_wsa(0, "TAB_ContainersW", szIndex)); - if (wszContainer != nullptr) - SendMessage(m_hwnd, DM_CONTAINERSELECTED, 0, wszContainer); - break; - } - MsgWindowMenuHandler(iSelection, MENU_TABCONTEXT); - } - break; - - case WM_LBUTTONDBLCLK: - if (LOWORD(lParam) < 30) - ScrollToBottom(); - break; - - case WM_CLOSE: - if (wParam == 0 && lParam == 0) { - switch (PluginConfig.m_EscapeCloses) { - case 1: // minimize container - SendMessage(m_pContainer->m_hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); - return TRUE; - - case 2: // close or hide, optionally - if (PluginConfig.m_bHideOnClose) { - ShowWindow(m_pContainer->m_hwnd, SW_HIDE); - return TRUE; - } - break; - - case 3: // does nothing - _dlgReturn(m_hwnd, FALSE); - return TRUE; - } - _dlgReturn(m_hwnd, TRUE); - } - CloseTab(); - return 0; - - case DM_SAVESIZE: - if (m_dwFlags & MWF_NEEDCHECKSIZE) - lParam = 0; - - m_dwFlags &= ~MWF_NEEDCHECKSIZE; - if (m_dwFlags & MWF_WASBACKGROUNDCREATE) - m_dwFlags &= ~MWF_INITMODE; - - SendMessage(m_pContainer->m_hwnd, DM_QUERYCLIENTAREA, 0, (LPARAM)&rcClient); - MoveWindow(m_hwnd, rcClient.left, rcClient.top, (rcClient.right - rcClient.left), (rcClient.bottom - rcClient.top), TRUE); - - if (m_dwFlags & MWF_WASBACKGROUNDCREATE) { - m_dwFlags &= ~MWF_WASBACKGROUNDCREATE; - Resize(); - - pt.x = pt.y = 0; - m_log.SendMsg(EM_SETSCROLLPOS, 0, (LPARAM)&pt); - } - else { - Resize(); - if (lParam == 0) - DM_ScrollToBottom(1, 1); - } - return 0; - - case WM_CBD_UPDATED: - if (lParam) - CB_ChangeButton((CustomButtonData*)lParam); - else - BB_InitDlgButtons(); - - BB_SetButtonsPos(); - return 0; - - case WM_CBD_REMOVED: - if (lParam) - CB_DestroyButton((DWORD)wParam, (DWORD)lParam); - else - CB_DestroyAllButtons(); - break; - - case DM_CONFIGURETOOLBAR: - Resize(); - break; - - case DM_SMILEYOPTIONSCHANGED: - RedrawLog(); - break; - - case EM_THEMECHANGED: - DM_FreeTheme(); - DM_ThemeChanged(); - return 0; - - case WM_DWMCOMPOSITIONCHANGED: - BB_RefreshTheme(); - m_pContainer->ClearMargins(); - VerifyProxy(); - break; - } - return CSuper::DlgProc(uMsg, wParam, lParam); -} - -///////////////////////////////////////////////////////////////////////////////////////// // chat session creator void ShowRoom(TContainerData *pContainer, SESSION_INFO *si) @@ -2361,7 +579,7 @@ void ShowRoom(TContainerData *pContainer, SESSION_INFO *si) if (iCount > 0) { for (int i = iCount - 1; i >= 0; i--) { HWND hwnd = GetTabWindow(hwndTab, i); - CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (dat) { int relPos = M.GetDword(dat->m_hContact, "tabindex", i * 100); if (iTabIndex_wanted <= relPos) @@ -2379,7 +597,7 @@ void ShowRoom(TContainerData *pContainer, SESSION_INFO *si) TabCtrl_SetCurSel(hwndTab, iTabId); pContainer->m_iChilds++; - CMsgDialog *pDlg = new CMsgDialog(si); + CMsgDialog *pDlg = new CMsgDialog(IDD_CHANNEL, si); pDlg->m_iTabID = iTabId; pDlg->m_pContainer = pContainer; pDlg->SetParent(hwndTab); diff --git a/plugins/TabSRMM/src/contactcache.cpp b/plugins/TabSRMM/src/contactcache.cpp index 790f7c197b..ed30fba4b9 100644 --- a/plugins/TabSRMM/src/contactcache.cpp +++ b/plugins/TabSRMM/src/contactcache.cpp @@ -198,9 +198,9 @@ void CContactCache::updateStats(int iType, size_t value) // dialog will use this in WM_INITDIALOG and WM_DESTROY to tell the cache // that a message window is open for this contact. // -// @param dat: CSrmmWindow* - window data structure +// @param dat: CMsgDialog* - window data structure -void CContactCache::setWindowData(CTabBaseDlg *dat) +void CContactCache::setWindowData(CMsgDialog *dat) { m_dat = dat; diff --git a/plugins/TabSRMM/src/contactcache.h b/plugins/TabSRMM/src/contactcache.h index aeafd8f1e2..afd5aca0d4 100644 --- a/plugins/TabSRMM/src/contactcache.h +++ b/plugins/TabSRMM/src/contactcache.h @@ -65,7 +65,7 @@ class CContactCache : public MZeroedObject bool m_isValid;
int m_nMax;
- CTabBaseDlg *m_dat;
+ CMsgDialog *m_dat;
TSessionStats *m_stats;
DBCachedContact *cc;
@@ -106,7 +106,7 @@ public: __forceinline DWORD getSessionStart() const { return m_stats->started; }
__forceinline int getSessionMsgCount() const { return (int)m_stats->messageCount; }
- __forceinline CTabBaseDlg* getDat() const { return m_dat; }
+ __forceinline CMsgDialog* getDat() const { return m_dat; }
size_t getMaxMessageLength();
void updateStats(int iType, size_t value = 0);
@@ -118,7 +118,7 @@ public: void updateMeta();
bool updateUIN();
void updateStatusMsg(const char *szKey = nullptr);
- void setWindowData(CTabBaseDlg *dat = nullptr);
+ void setWindowData(CMsgDialog *dat = nullptr);
void resetMeta();
void closeWindow();
void deletedHandler();
diff --git a/plugins/TabSRMM/src/container.cpp b/plugins/TabSRMM/src/container.cpp index f4ecb7ac67..1b8bfd118b 100644 --- a/plugins/TabSRMM/src/container.cpp +++ b/plugins/TabSRMM/src/container.cpp @@ -57,7 +57,7 @@ void TContainerData::InitRedraw() ::SetTimer(m_hwnd, (UINT_PTR)this, 100, nullptr);
}
-void TContainerData::SetIcon(CTabBaseDlg *pDlg, HICON hIcon)
+void TContainerData::SetIcon(CMsgDialog *pDlg, HICON hIcon)
{
HICON hIconMsg = PluginConfig.g_IconMsgEvent;
HICON hIconBig = (pDlg && pDlg->m_cache) ? Skin_LoadProtoIcon(pDlg->m_cache->getProto(), pDlg->m_cache->getStatus(), true) : nullptr;
@@ -130,13 +130,13 @@ void TContainerData::UpdateTabs() if (!hDlg)
continue;
- CTabBaseDlg *dat = (CTabBaseDlg*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
if (dat)
dat->m_iTabID = i;
}
}
-void TContainerData::UpdateTitle(MCONTACT hContact, CTabBaseDlg *pDlg)
+void TContainerData::UpdateTitle(MCONTACT hContact, CMsgDialog *pDlg)
{
// pDlg != 0 means sent by a chat window
if (pDlg) {
@@ -151,12 +151,12 @@ void TContainerData::UpdateTitle(MCONTACT hContact, CTabBaseDlg *pDlg) // no hContact given - obtain the hContact for the active tab
if (hContact == 0) {
if (m_hwndActive && IsWindow(m_hwndActive))
- pDlg = (CTabBaseDlg*)GetWindowLongPtr(m_hwndActive, GWLP_USERDATA);
+ pDlg = (CMsgDialog*)GetWindowLongPtr(m_hwndActive, GWLP_USERDATA);
}
else {
HWND hwnd = Srmm_FindWindow(hContact);
if (hwnd != nullptr)
- pDlg = (CTabBaseDlg*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ pDlg = (CMsgDialog*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
}
if (pDlg) {
@@ -181,7 +181,7 @@ void TSAPI SetAeroMargins(TContainerData *pContainer) return;
}
- CTabBaseDlg *dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
if (!dat)
return;
@@ -573,7 +573,7 @@ static INT_PTR CALLBACK DlgProcContainer(HWND hwndDlg, UINT msg, WPARAM wParam, RECT rc;
POINT pt;
MCONTACT hContact;
- CTabBaseDlg *dat;
+ CMsgDialog *dat;
TContainerData *pContainer = (TContainerData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
BOOL bSkinned = CSkin::m_skinEnabled ? TRUE : FALSE;
@@ -738,7 +738,7 @@ static INT_PTR CALLBACK DlgProcContainer(HWND hwndDlg, UINT msg, WPARAM wParam, pContainer->m_pMenuBar->getClientRect();
if (pContainer->m_hwndStatus) {
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
SendMessage(pContainer->m_hwndStatus, WM_USER + 101, 0, (LPARAM)dat);
RECT rcs;
@@ -788,7 +788,7 @@ static INT_PTR CALLBACK DlgProcContainer(HWND hwndDlg, UINT msg, WPARAM wParam, SetWindowPos(hDlg, nullptr, rcClient.left, rcClient.top, (rcClient.right - rcClient.left), (rcClient.bottom - rcClient.top),
SWP_NOSENDCHANGING | SWP_NOACTIVATE/*|SWP_NOCOPYBITS*/);
if (!pContainer->m_bSizingLoop && sizeChanged) {
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
if (dat)
dat->DM_ScrollToBottom(0, 1);
}
@@ -853,7 +853,7 @@ static INT_PTR CALLBACK DlgProcContainer(HWND hwndDlg, UINT msg, WPARAM wParam, else nPanel = nm->dwItemSpec;
panel_found:
if (nPanel == 2) {
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
SendMessage(pContainer->m_hwndStatus, SB_GETRECT, nPanel, (LPARAM)&rc);
if (dat)
dat->CheckStatusIconClick(nm->pt, rc, 2, ((LPNMHDR)lParam)->code);
@@ -904,7 +904,7 @@ panel_found: if (((LPNMHDR)lParam)->idFrom == IDC_MSGTABS) {
hDlg = GetTabWindow(hwndTab, GetTabItemFromMouse(hwndTab, &pt));
if (hDlg && IsWindow(hDlg))
- dat = (CTabBaseDlg*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
}
// sent from a sidebar button (RMB click) instead of the tab control
else if (((LPNMHDR)lParam)->idFrom == 5000) {
@@ -978,7 +978,7 @@ panel_found: bool fProcessMainMenu = pContainer->m_pMenuBar->isMainMenu();
pContainer->m_pMenuBar->Cancel();
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
DWORD dwOldFlags = pContainer->m_dwFlags;
if (dat) {
@@ -1181,7 +1181,7 @@ panel_found: case WM_EXITSIZEMOVE:
GetClientRect(hwndTab, &rc);
if (!((rc.right - rc.left) == pContainer->m_oldSize.cx && (rc.bottom - rc.top) == pContainer->m_oldSize.cy)) {
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
if (dat)
dat->DM_ScrollToBottom(0, 0);
SendMessage(pContainer->m_hwndActive, WM_SIZE, 0, 0);
@@ -1261,7 +1261,7 @@ panel_found: PostMessage(hwndDlg, WM_CLOSE, 1, 0);
}
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
if (dat && !dat->isChat()) {
if (dat->m_idle && pContainer->m_hwndActive && IsWindow(pContainer->m_hwndActive))
dat->m_pPanel.Invalidate(TRUE);
@@ -1299,7 +1299,7 @@ panel_found: pContainer->ClearMargins();
break;
case SC_MINIMIZE:
- dat = (CTabBaseDlg*)(GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA));
+ dat = (CMsgDialog*)(GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA));
if (dat) {
GetWindowRect(pContainer->m_hwndActive, &pContainer->m_rcLogSaved);
pContainer->m_ptLogSaved.x = pContainer->m_rcLogSaved.left;
@@ -1594,7 +1594,7 @@ panel_found: SetWindowPos(hwndDlg, nullptr, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCOPYBITS);
RedrawWindow(hwndDlg, nullptr, nullptr, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
if (pContainer->m_hwndActive != nullptr) {
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
dat->DM_ScrollToBottom(0, 0);
}
}
@@ -1694,7 +1694,7 @@ panel_found: {
DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
if (dis->hwndItem == pContainer->m_hwndStatus && !(pContainer->m_dwFlags & CNT_NOSTATUSBAR)) {
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
if (dat)
dat->DrawStatusIcons(dis->hDC, dis->rcItem, 2);
return TRUE;
@@ -1964,7 +1964,7 @@ int TSAPI ActivateTabFromHWND(HWND hwndTab, HWND hwnd) }
// enumerates tabs and closes all of them, but the one in dat
-void TSAPI CloseOtherTabs(HWND hwndTab, CTabBaseDlg &dat)
+void TSAPI CloseOtherTabs(HWND hwndTab, CMsgDialog &dat)
{
for (int idxt = 0; idxt < dat.m_pContainer->m_iChilds;) {
HWND otherTab = GetTabWindow(hwndTab, idxt);
diff --git a/plugins/TabSRMM/src/controls.cpp b/plugins/TabSRMM/src/controls.cpp index 5d0a735fd5..8dd9fb01e8 100644 --- a/plugins/TabSRMM/src/controls.cpp +++ b/plugins/TabSRMM/src/controls.cpp @@ -384,7 +384,7 @@ void CMenuBar::invoke(const int id) m_isContactMenu = m_isMainMenu = false;
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA);
MCONTACT hContact = dat ? dat->m_hContact : 0;
@@ -438,7 +438,7 @@ void CMenuBar::Cancel(void) void CMenuBar::updateState(const HMENU hMenu) const
{
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA);
if (dat) {
::CheckMenuItem(hMenu, ID_VIEW_SHOWMENUBAR, MF_BYCOMMAND | m_pContainer->m_dwFlags & CNT_NOMENUBAR ? MF_UNCHECKED : MF_CHECKED);
::CheckMenuItem(hMenu, ID_VIEW_SHOWSTATUSBAR, MF_BYCOMMAND | m_pContainer->m_dwFlags & CNT_NOSTATUSBAR ? MF_UNCHECKED : MF_CHECKED);
@@ -477,7 +477,7 @@ void CMenuBar::updateState(const HMENU hMenu) const void CMenuBar::configureMenu() const
{
- CSrmmWindow *dat = (CSrmmWindow*)::GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)::GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA);
if (dat) {
bool fChat = dat->isChat();
@@ -663,10 +663,10 @@ static int tooltip_active = FALSE; static POINT ptMouse = { 0 };
RECT rcLastStatusBarClick; // remembers click (down event) point for status bar clicks
-LONG_PTR CALLBACK CTabBaseDlg::StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+LONG_PTR CALLBACK CMsgDialog::StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
TContainerData *pContainer = (TContainerData*)GetWindowLongPtr(GetParent(hWnd), GWLP_USERDATA);
- CTabBaseDlg *dat = nullptr;
+ CMsgDialog *dat = nullptr;
POINT pt;
if (OldStatusBarproc == nullptr) {
@@ -725,7 +725,7 @@ LONG_PTR CALLBACK CTabBaseDlg::StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM HANDLE hTheme = bAero ? OpenThemeData(hWnd, L"ButtonStyle") : nullptr;
if (pContainer)
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
RECT rcClient;
GetClientRect(hWnd, &rcClient);
@@ -830,7 +830,7 @@ LONG_PTR CALLBACK CTabBaseDlg::StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wchar_t szText[1024]; szText[0] = 0;
LRESULT result = SendMessage(hWnd, SB_GETTEXT, i, (LPARAM)szText);
if (i == 2 && pContainer) {
- CSrmmWindow *pDat = (CSrmmWindow*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ CMsgDialog *pDat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
if (pDat)
pDat->DrawStatusIcons(hdcMem, itemRect, 2);
}
@@ -878,7 +878,7 @@ LONG_PTR CALLBACK CTabBaseDlg::StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM // needed when an icon is added to or removed from the icon area
{
int list_icons = 0;
- dat = (CTabBaseDlg*)lParam;
+ dat = (CMsgDialog*)lParam;
if (dat)
while (Srmm_GetNthIcon(dat->m_hContact, list_icons))
list_icons++;
@@ -941,7 +941,7 @@ LONG_PTR CALLBACK CTabBaseDlg::StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM GetCursorPos(&pt);
if (pt.x != ptMouse.x || pt.y != ptMouse.y)
break;
- dat = (CTabBaseDlg*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(pContainer->m_hwndActive, GWLP_USERDATA);
if (dat != nullptr) {
RECT rc;
SIZE size;
diff --git a/plugins/TabSRMM/src/eventpopups.cpp b/plugins/TabSRMM/src/eventpopups.cpp index 548bd5653a..9f0c80364e 100644 --- a/plugins/TabSRMM/src/eventpopups.cpp +++ b/plugins/TabSRMM/src/eventpopups.cpp @@ -664,7 +664,7 @@ void Popup_Options(WPARAM wParam) // updates the menu entry...
// bForced is used to only update the status, nickname etc. and does NOT update the unread count
-void TSAPI UpdateTrayMenuState(CTabBaseDlg *dat, BOOL bForced)
+void TSAPI UpdateTrayMenuState(CMsgDialog *dat, BOOL bForced)
{
if (PluginConfig.g_hMenuTrayUnread == nullptr || dat->m_hContact == 0)
return;
@@ -694,7 +694,7 @@ void TSAPI UpdateTrayMenuState(CTabBaseDlg *dat, BOOL bForced) }
// if we want tray support, add the contact to the list of unread sessions in the tray menu
-int TSAPI UpdateTrayMenu(const CTabBaseDlg *dat, WORD wStatus, const char *szProto, const wchar_t *szStatus, MCONTACT hContact, DWORD fromEvent)
+int TSAPI UpdateTrayMenu(const CMsgDialog *dat, WORD wStatus, const char *szProto, const wchar_t *szStatus, MCONTACT hContact, DWORD fromEvent)
{
if (!PluginConfig.g_hMenuTrayUnread || hContact == 0 || szProto == nullptr)
return 0;
diff --git a/plugins/TabSRMM/src/functions.h b/plugins/TabSRMM/src/functions.h index 2de544eb2b..bac6bf1110 100644 --- a/plugins/TabSRMM/src/functions.h +++ b/plugins/TabSRMM/src/functions.h @@ -50,7 +50,7 @@ LONG_PTR CALLBACK HotkeyHandlerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP int TSAPI NEN_ReadOptions(NEN_OPTIONS *options);
int TSAPI NEN_WriteOptions(NEN_OPTIONS *options);
-int TSAPI UpdateTrayMenu(const CTabBaseDlg *dat, WORD wStatus, const char *szProto, const wchar_t *szStatus, MCONTACT hContact, DWORD fromEvent);
+int TSAPI UpdateTrayMenu(const CMsgDialog *dat, WORD wStatus, const char *szProto, const wchar_t *szStatus, MCONTACT hContact, DWORD fromEvent);
void TSAPI DeletePopupsForContact(MCONTACT hContact, DWORD dwMask);
/*
@@ -59,7 +59,7 @@ void TSAPI DeletePopupsForContact(MCONTACT hContact, DWORD dwMask); void TSAPI CreateSystrayIcon(int create);
void TSAPI FlashTrayIcon(HICON hIcon);
-void TSAPI UpdateTrayMenuState(CTabBaseDlg *dat, BOOL bForced);
+void TSAPI UpdateTrayMenuState(CMsgDialog *dat, BOOL bForced);
void TSAPI LoadFavoritesAndRecent();
void TSAPI AddContactToFavorites(MCONTACT hContact, const wchar_t *szNickname, const char *szProto, wchar_t *szStatus,
WORD wStatus, HICON hIcon, BOOL mode, HMENU hMenu);
@@ -82,7 +82,7 @@ TContainerData* TSAPI FindContainerByName(const wchar_t *name); int TSAPI GetTabIndexFromHWND(HWND hwndTab, HWND hwnd);
HWND TSAPI GetTabWindow(HWND hwndTab, int idx);
int TSAPI GetTabItemFromMouse(HWND hwndTab, POINT *pt);
-void TSAPI CloseOtherTabs(HWND hwndTab, CTabBaseDlg &dat);
+void TSAPI CloseOtherTabs(HWND hwndTab, CMsgDialog &dat);
int TSAPI ActivateTabFromHWND(HWND hwndTab, HWND hwnd);
void TSAPI AdjustTabClientRect(TContainerData *pContainer, RECT *rc);
void TSAPI ReflashContainer(TContainerData *pContainer);
@@ -135,7 +135,7 @@ int _DebugPopup(MCONTACT hContact, const wchar_t *fmt, ...); const wchar_t* TSAPI GetThemeFileName(int iMode);
int TSAPI CheckThemeVersion(const wchar_t *szIniFilename);
-void TSAPI WriteThemeToINI(const wchar_t *szIniFilename, CSrmmWindow *dat);
+void TSAPI WriteThemeToINI(const wchar_t *szIniFilename, CMsgDialog *dat);
void TSAPI ReadThemeFromINI(const wchar_t *szIniFilename, TContainerData *dat, int noAdvanced, DWORD dwFlags);
// TypingNotify
diff --git a/plugins/TabSRMM/src/generic_msghandlers.cpp b/plugins/TabSRMM/src/generic_msghandlers.cpp index c825414a33..7b2f90c0e9 100644 --- a/plugins/TabSRMM/src/generic_msghandlers.cpp +++ b/plugins/TabSRMM/src/generic_msghandlers.cpp @@ -33,7 +33,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// // Save message log for given session as RTF document -void CTabBaseDlg::DM_SaveLogAsRTF() const +void CMsgDialog::DM_SaveLogAsRTF() const { if (m_hwndIEView != nullptr) { IEVIEWEVENT event = { sizeof(event) }; @@ -75,7 +75,7 @@ void CTabBaseDlg::DM_SaveLogAsRTF() const ///////////////////////////////////////////////////////////////////////////////////////// // checks if the balloon tooltip can be dismissed (usually called by WM_MOUSEMOVE events) -void CTabBaseDlg::DM_DismissTip(const POINT& pt) +void CMsgDialog::DM_DismissTip(const POINT& pt) { if (!IsWindowVisible(m_hwndTip)) return; @@ -94,7 +94,7 @@ void CTabBaseDlg::DM_DismissTip(const POINT& pt) ///////////////////////////////////////////////////////////////////////////////////////// // initialize the balloon tooltip for message window notifications -void CTabBaseDlg::DM_InitTip() +void CMsgDialog::DM_InitTip() { m_hwndTip = CreateWindowEx(0, TOOLTIPS_CLASS, nullptr, WS_POPUP | TTS_NOPREFIX | TTS_BALLOON, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, m_hwnd, nullptr, g_plugin.getInst(), (LPVOID)nullptr); @@ -116,7 +116,7 @@ void CTabBaseDlg::DM_InitTip() // // returns 1 for handled hotkeys, 0 otherwise. -bool CTabBaseDlg::DM_GenericHotkeysCheck(MSG *message) +bool CMsgDialog::DM_GenericHotkeysCheck(MSG *message) { LRESULT mim_hotkey_check = Hotkey_Check(message, TABSRMM_HK_SECTION_GENERIC); @@ -166,7 +166,7 @@ bool CTabBaseDlg::DM_GenericHotkeysCheck(MSG *message) return false; } -LRESULT CTabBaseDlg::DM_MsgWindowCmdHandler(UINT cmd, WPARAM wParam, LPARAM lParam) +LRESULT CMsgDialog::DM_MsgWindowCmdHandler(UINT cmd, WPARAM wParam, LPARAM lParam) { RECT rc; int iSelection; @@ -499,14 +499,16 @@ LRESULT CTabBaseDlg::DM_MsgWindowCmdHandler(UINT cmd, WPARAM wParam, LPARAM lPar break; case IDC_SELFTYPING: - if (m_hContact) { - int iCurrentTypingMode = g_plugin.getByte(m_hContact, SRMSGSET_TYPING, g_plugin.getByte(SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)); + if (m_si == nullptr || m_si->iType == GCW_PRIVMESS) { + if (m_hContact) { + int iCurrentTypingMode = g_plugin.getByte(m_hContact, SRMSGSET_TYPING, g_plugin.getByte(SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)); - if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON && iCurrentTypingMode) { - DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF); - m_nTypeMode = PROTOTYPE_SELFTYPING_OFF; + if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON && iCurrentTypingMode) { + DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF); + m_nTypeMode = PROTOTYPE_SELFTYPING_OFF; + } + g_plugin.setByte(m_hContact, SRMSGSET_TYPING, (BYTE)!iCurrentTypingMode); } - g_plugin.setByte(m_hContact, SRMSGSET_TYPING, (BYTE)!iCurrentTypingMode); } break; @@ -520,7 +522,7 @@ LRESULT CTabBaseDlg::DM_MsgWindowCmdHandler(UINT cmd, WPARAM wParam, LPARAM lPar // initialize rich edit control (log and edit control) for both MUC and // standard IM session windows. -void CTabBaseDlg::DM_InitRichEdit() +void CMsgDialog::DM_InitRichEdit() { bool fIsChat = isChat(); @@ -623,7 +625,7 @@ void CTabBaseDlg::DM_InitRichEdit() ///////////////////////////////////////////////////////////////////////////////////////// // set the states of defined database action buttons(only if button is a toggle) -void CTabBaseDlg::DM_SetDBButtonStates() +void CMsgDialog::DM_SetDBButtonStates() { ButtonItem *buttonItem = m_pContainer->m_buttonItems; MCONTACT hFinalContact = 0; @@ -676,7 +678,7 @@ void CTabBaseDlg::DM_SetDBButtonStates() } } -void CTabBaseDlg::DM_ScrollToBottom(WPARAM wParam, LPARAM lParam) +void CMsgDialog::DM_ScrollToBottom(WPARAM wParam, LPARAM lParam) { if (m_dwFlagsEx & MWF_SHOW_SCROLLINGDISABLED) return; @@ -710,7 +712,7 @@ void CTabBaseDlg::DM_ScrollToBottom(WPARAM wParam, LPARAM lParam) InvalidateRect(m_log.GetHwnd(), nullptr, FALSE); } -void CTabBaseDlg::DM_RecalcPictureSize() +void CMsgDialog::DM_RecalcPictureSize() { HBITMAP hbm = ((m_pPanel.isActive()) && m_pContainer->m_avatarMode != 3) ? m_hOwnPic : (m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown); if (hbm) { @@ -722,7 +724,7 @@ void CTabBaseDlg::DM_RecalcPictureSize() else m_pic.cy = m_pic.cx = 60; } -void CTabBaseDlg::DM_UpdateLastMessage() const +void CMsgDialog::DM_UpdateLastMessage() const { if (m_pContainer->m_hwndStatus == nullptr || m_pContainer->m_hwndActive != m_hwnd) return; @@ -759,7 +761,7 @@ void CTabBaseDlg::DM_UpdateLastMessage() const ///////////////////////////////////////////////////////////////////////////////////////// // create embedded contact list control -HWND CTabBaseDlg::DM_CreateClist() +HWND CMsgDialog::DM_CreateClist() { if (!sendLater->isAvail()) { CWarning::show(CWarning::WARN_NO_SENDLATER, MB_OK | MB_ICONINFORMATION); @@ -789,7 +791,7 @@ HWND CTabBaseDlg::DM_CreateClist() return hwndClist; } -LRESULT CTabBaseDlg::DM_MouseWheelHandler(WPARAM wParam, LPARAM lParam) +LRESULT CMsgDialog::DM_MouseWheelHandler(WPARAM wParam, LPARAM lParam) { POINT pt; GetCursorPos(&pt); @@ -848,7 +850,7 @@ LRESULT CTabBaseDlg::DM_MouseWheelHandler(WPARAM wParam, LPARAM lParam) return 1; } -void CTabBaseDlg::DM_FreeTheme() +void CMsgDialog::DM_FreeTheme() { if (m_hTheme) { CloseThemeData(m_hTheme); @@ -864,7 +866,7 @@ void CTabBaseDlg::DM_FreeTheme() } } -void CTabBaseDlg::DM_ThemeChanged() +void CMsgDialog::DM_ThemeChanged() { CSkinItem *item_log = &SkinItems[ID_EXTBKHISTORY]; CSkinItem *item_msg = &SkinItems[ID_EXTBKINPUTAREA]; @@ -888,7 +890,7 @@ void CTabBaseDlg::DM_ThemeChanged() // send out message typing notifications (MTN) when the // user is typing/editing text in the message input area. -void CTabBaseDlg::DM_NotifyTyping(int mode) +void CMsgDialog::DM_NotifyTyping(int mode) { if (!m_hContact) return; @@ -937,7 +939,7 @@ void CTabBaseDlg::DM_NotifyTyping(int mode) CallService(MS_PROTO_SELFISTYPING, hContact, m_nTypeMode); } -void CSrmmWindow::DM_OptionsApplied(WPARAM, LPARAM lParam) +void CMsgDialog::DM_OptionsApplied(WPARAM, LPARAM lParam) { m_szMicroLf[0] = 0; if (!(m_pContainer->m_theme.isPrivate)) { @@ -978,7 +980,7 @@ void CSrmmWindow::DM_OptionsApplied(WPARAM, LPARAM lParam) SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0); } -void CTabBaseDlg::DM_Typing(bool fForceOff) +void CMsgDialog::DM_Typing(bool fForceOff) { HWND hwndContainer = m_pContainer->m_hwnd; HWND hwndStatus = m_pContainer->m_hwndStatus; @@ -1003,7 +1005,7 @@ void CTabBaseDlg::DM_Typing(bool fForceOff) } SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0); HandleIconFeedback(this, (HICON)-1); - CTabBaseDlg *dat_active = (CTabBaseDlg*)GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA); + CMsgDialog *dat_active = (CMsgDialog*)GetWindowLongPtr(m_pContainer->m_hwndActive, GWLP_USERDATA); if (dat_active && !dat_active->isChat()) m_pContainer->UpdateTitle(0); else @@ -1059,9 +1061,9 @@ void CTabBaseDlg::DM_Typing(bool fForceOff) // This cares about private / per container / MUC <> IM splitter syncing and everything. // called from IM and MUC windows via DM_SPLITTERGLOBALEVENT -int CTabBaseDlg::DM_SplitterGlobalEvent(WPARAM wParam, LPARAM lParam) +int CMsgDialog::DM_SplitterGlobalEvent(WPARAM wParam, LPARAM lParam) { - CTabBaseDlg *srcDat = PluginConfig.lastSPlitterPos.pSrcDat; + CMsgDialog *srcDat = PluginConfig.lastSPlitterPos.pSrcDat; TContainerData *srcCnt = PluginConfig.lastSPlitterPos.pSrcContainer; bool fCntGlobal = (!m_pContainer->m_pSettings->fPrivate ? true : false); @@ -1118,7 +1120,7 @@ int CTabBaseDlg::DM_SplitterGlobalEvent(WPARAM wParam, LPARAM lParam) return 0; } -void CTabBaseDlg::DM_AddDivider() +void CMsgDialog::DM_AddDivider() { if (!(m_dwFlags & MWF_DIVIDERSET) && PluginConfig.m_bUseDividers) { if (GetWindowTextLength(m_log.GetHwnd()) > 0) @@ -1129,7 +1131,7 @@ void CTabBaseDlg::DM_AddDivider() ///////////////////////////////////////////////////////////////////////////////////////// // incoming event handler -void CTabBaseDlg::DM_EventAdded(WPARAM hContact, LPARAM lParam) +void CMsgDialog::DM_EventAdded(WPARAM hContact, LPARAM lParam) { MEVENT hDbEvent = (MEVENT)lParam; @@ -1251,7 +1253,7 @@ void CTabBaseDlg::DM_EventAdded(WPARAM hContact, LPARAM lParam) m_pWnd->Invalidate(); } -void CTabBaseDlg::DM_HandleAutoSizeRequest(REQRESIZE* rr) +void CMsgDialog::DM_HandleAutoSizeRequest(REQRESIZE* rr) { if (rr == nullptr || GetForegroundWindow() != m_pContainer->m_hwnd) return; @@ -1307,7 +1309,7 @@ static int OnSrmmIconChanged(WPARAM hContact, LPARAM) return 0; } -void CTabBaseDlg::DrawStatusIcons(HDC hDC, const RECT &rc, int gap) +void CMsgDialog::DrawStatusIcons(HDC hDC, const RECT &rc, int gap) { int x = rc.left; int y = (rc.top + rc.bottom - PluginConfig.m_smcxicon) >> 1; @@ -1355,7 +1357,7 @@ void CTabBaseDlg::DrawStatusIcons(HDC hDC, const RECT &rc, int gap) } } -void CTabBaseDlg::CheckStatusIconClick(POINT pt, const RECT &rc, int gap, int code) +void CMsgDialog::CheckStatusIconClick(POINT pt, const RECT &rc, int gap, int code) { if (code == NM_CLICK || code == NM_RCLICK) { POINT ptScreen; @@ -1405,7 +1407,7 @@ void CTabBaseDlg::CheckStatusIconClick(POINT pt, const RECT &rc, int gap, int co } } -void CTabBaseDlg::DM_ErrorDetected(int type, int flag) +void CMsgDialog::DM_ErrorDetected(int type, int flag) { switch (type) { case MSGERROR_CANCEL: diff --git a/plugins/TabSRMM/src/globals.cpp b/plugins/TabSRMM/src/globals.cpp index 60d681e88d..59fb381a43 100644 --- a/plugins/TabSRMM/src/globals.cpp +++ b/plugins/TabSRMM/src/globals.cpp @@ -380,12 +380,12 @@ int CGlobals::DBSettingChanged(WPARAM hContact, LPARAM lParam) }
if (hwnd != nullptr) {
- CTabBaseDlg *dat = c->getDat();
+ CMsgDialog *dat = c->getDat();
if (!strcmp(setting, "MirVer"))
PostMessage(hwnd, DM_CLIENTCHANGED, 0, 0);
if (dat && !strcmp(setting, "NotOnList") && (cws->value.type == DBVT_DELETED || cws->value.bVal == 0))
- ((CSrmmWindow*)dat)->onClick_CancelAdd(0);
+ ((CMsgDialog*)dat)->onClick_CancelAdd(0);
if (dat && (fChanged || fExtendedStatusChange))
dat->UpdateTitle();
@@ -429,7 +429,7 @@ int CGlobals::MetaContactEvent(WPARAM hContact, LPARAM) if (hContact) {
CContactCache *c = CContactCache::getContactCache(hContact);
c->updateMeta();
- CTabBaseDlg *pDlg = c->getDat();
+ CMsgDialog *pDlg = c->getDat();
if (pDlg) {
pDlg->UpdateTitle();
pDlg->GetClientIcon();
@@ -530,7 +530,7 @@ void CGlobals::logStatusChange(WPARAM wParam, const CContactCache *c) if (c == nullptr)
return;
- CTabBaseDlg *dat = c->getDat();
+ CMsgDialog *dat = c->getDat();
if (dat == nullptr || !c->isValid())
return;
diff --git a/plugins/TabSRMM/src/globals.h b/plugins/TabSRMM/src/globals.h index bb8f583bd9..ae2e6bdd7b 100644 --- a/plugins/TabSRMM/src/globals.h +++ b/plugins/TabSRMM/src/globals.h @@ -32,7 +32,7 @@ struct TSplitterBroadCast {
TContainerData *pSrcContainer;
- CTabBaseDlg *pSrcDat;
+ CMsgDialog *pSrcDat;
LONG pos, pos_chat;
LONG off_chat, off_im;
LPARAM lParam;
diff --git a/plugins/TabSRMM/src/hotkeyhandler.cpp b/plugins/TabSRMM/src/hotkeyhandler.cpp index f6e53d3a23..b32cf7abea 100644 --- a/plugins/TabSRMM/src/hotkeyhandler.cpp +++ b/plugins/TabSRMM/src/hotkeyhandler.cpp @@ -183,9 +183,9 @@ LONG_PTR CALLBACK HotkeyHandlerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP hWnd = si ? si->pDlg->GetHwnd() : nullptr;
}
- CSrmmWindow *dat = nullptr;
+ CMsgDialog *dat = nullptr;
if (hWnd)
- dat = (CSrmmWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
{
HICON hIcon;
diff --git a/plugins/TabSRMM/src/infopanel.cpp b/plugins/TabSRMM/src/infopanel.cpp index 3c3684dc8b..434b097b2a 100644 --- a/plugins/TabSRMM/src/infopanel.cpp +++ b/plugins/TabSRMM/src/infopanel.cpp @@ -42,7 +42,7 @@ TInfoPanelConfig CInfoPanel::m_ipConfig = {}; /////////////////////////////////////////////////////////////////////////////////////////
-CInfoPanel::CInfoPanel(CTabBaseDlg *dat)
+CInfoPanel::CInfoPanel(CMsgDialog *dat)
{
if (dat) {
m_dat = dat;
@@ -962,7 +962,7 @@ LRESULT CALLBACK CInfoPanel::avatarParentSubclass(HWND hwnd, UINT msg, WPARAM wP case WM_ERASEBKGND:
// parent window of the infopanel ACC control
RECT rc, rcItem;
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
if (dat == nullptr)
break;
diff --git a/plugins/TabSRMM/src/infopanel.h b/plugins/TabSRMM/src/infopanel.h index a4a2a04819..9e925ba511 100644 --- a/plugins/TabSRMM/src/infopanel.h +++ b/plugins/TabSRMM/src/infopanel.h @@ -30,7 +30,7 @@ #define __INFOPANEL_H
class CInfoPanel;
-class CTabBaseDlg;
+class CMsgDialog;
struct CSkinItem;
/*
@@ -129,14 +129,14 @@ public: HTNIRVANA = 0
};
- CInfoPanel(CTabBaseDlg *dat);
+ CInfoPanel(CMsgDialog *dat);
~CInfoPanel();
__forceinline const LONG getHeight() const { return m_height; }
__forceinline bool isActive() const { return m_active; }
__forceinline bool isPrivateHeight() const { return m_fPrivateHeight; }
__forceinline DWORD isHovered() const { return m_active ? m_hoverFlags : 0; }
- __forceinline const CTabBaseDlg* getDat() const { return m_dat; }
+ __forceinline const CMsgDialog* getDat() const { return m_dat; }
void setHeight(LONG newHeight, bool fBroadcast = false);
void setActive(const int newActive);
@@ -180,7 +180,7 @@ private: bool m_active; // panel active and visible
bool m_fPrivateHeight;
bool m_fDialogCreated;
- CTabBaseDlg *m_dat; // this one OWNS us...
+ CMsgDialog *m_dat; // this one OWNS us...
LONG m_height; // height (determined by position of IDC_PANELSPLITTER)
LONG m_defaultHeight,
m_defaultMUCHeight; // global values for the info bar height
diff --git a/plugins/TabSRMM/src/mim.cpp b/plugins/TabSRMM/src/mim.cpp index 9ce2123785..5b3258ea7d 100644 --- a/plugins/TabSRMM/src/mim.cpp +++ b/plugins/TabSRMM/src/mim.cpp @@ -306,7 +306,7 @@ int CMimAPI::ProtoAck(WPARAM, LPARAM lParam) for (int j = 0; j < SendQueue::NR_SENDJOBS; j++) { SendJob &p = jobs[j]; if (pAck->hProcess == (HANDLE)p.iSendId && pAck->hContact == p.hContact) { - CSrmmWindow *dat = p.hOwnerWnd ? (CSrmmWindow*)GetWindowLongPtr(p.hOwnerWnd, GWLP_USERDATA) : nullptr; + CMsgDialog *dat = p.hOwnerWnd ? (CMsgDialog*)GetWindowLongPtr(p.hOwnerWnd, GWLP_USERDATA) : nullptr; if (dat == nullptr) { sendQueue->ackMessage(nullptr, (WPARAM)MAKELONG(j, i), lParam); return 0; diff --git a/plugins/TabSRMM/src/msgdialog.cpp b/plugins/TabSRMM/src/msgdialog.cpp index 5f57d9b34e..84c7db6689 100644 --- a/plugins/TabSRMM/src/msgdialog.cpp +++ b/plugins/TabSRMM/src/msgdialog.cpp @@ -69,124 +69,11 @@ static void _clrMsgFilter(MSGFILTER *m) }
/////////////////////////////////////////////////////////////////////////////////////////
-// show a modified context menu for the richedit control(s)
-
-void CTabBaseDlg::ShowPopupMenu(const CCtrlBase &pCtrl, POINT pt)
-{
- CHARRANGE sel, all = { 0, -1 };
-
- HMENU hSubMenu, hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT));
- if (pCtrl.GetCtrlId() == IDC_SRMM_LOG)
- hSubMenu = GetSubMenu(hMenu, 0);
- else {
- hSubMenu = GetSubMenu(hMenu, 2);
- EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | (m_SendFormat != 0 ? MF_ENABLED : MF_GRAYED));
- EnableMenuItem(hSubMenu, ID_EDITOR_PASTEANDSENDIMMEDIATELY, MF_BYCOMMAND | (PluginConfig.m_PasteAndSend ? MF_ENABLED : MF_GRAYED));
- CheckMenuItem(hSubMenu, ID_EDITOR_SHOWMESSAGELENGTHINDICATOR, MF_BYCOMMAND | (PluginConfig.m_visualMessageSizeIndicator ? MF_CHECKED : MF_UNCHECKED));
- EnableMenuItem(hSubMenu, ID_EDITOR_SHOWMESSAGELENGTHINDICATOR, MF_BYCOMMAND | (m_pContainer->m_hwndStatus ? MF_ENABLED : MF_GRAYED));
- }
- TranslateMenu(hSubMenu);
- pCtrl.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel);
- if (sel.cpMin == sel.cpMax) {
- EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
- EnableMenuItem(hSubMenu, IDM_QUOTE, MF_BYCOMMAND | MF_GRAYED);
- if (pCtrl.GetCtrlId() == IDC_SRMM_MESSAGE)
- EnableMenuItem(hSubMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED);
- }
-
- if (pCtrl.GetCtrlId() == IDC_SRMM_LOG) {
- InsertMenuA(hSubMenu, 6, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
- CheckMenuItem(hSubMenu, ID_LOG_FREEZELOG, MF_BYCOMMAND | (m_dwFlagsEx & MWF_SHOW_SCROLLINGDISABLED ? MF_CHECKED : MF_UNCHECKED));
- }
-
- MessageWindowPopupData mwpd;
- // First notification
- mwpd.uType = MSG_WINDOWPOPUP_SHOWING;
- mwpd.uFlags = (pCtrl.GetCtrlId() == IDC_SRMM_LOG ? MSG_WINDOWPOPUP_LOG : MSG_WINDOWPOPUP_INPUT);
- mwpd.hContact = m_hContact;
- mwpd.hwnd = pCtrl.GetHwnd();
- mwpd.hMenu = hSubMenu;
- mwpd.selection = 0;
- mwpd.pt = pt;
- NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)&mwpd);
-
- int iSelection = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr);
-
- // Second notification
- mwpd.selection = iSelection;
- mwpd.uType = MSG_WINDOWPOPUP_SELECTED;
- NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)&mwpd);
-
- switch (iSelection) {
- case IDM_COPY:
- pCtrl.SendMsg(WM_COPY, 0, 0);
- break;
- case IDM_CUT:
- pCtrl.SendMsg(WM_CUT, 0, 0);
- break;
- case IDM_PASTE:
- case IDM_PASTEFORMATTED:
- if (pCtrl.GetCtrlId() == IDC_SRMM_MESSAGE)
- pCtrl.SendMsg(EM_PASTESPECIAL, (iSelection == IDM_PASTE) ? CF_UNICODETEXT : 0, 0);
- break;
- case IDM_COPYALL:
- pCtrl.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all);
- pCtrl.SendMsg(WM_COPY, 0, 0);
- pCtrl.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel);
- break;
- case IDM_QUOTE:
- SendMessage(m_hwnd, WM_COMMAND, IDC_QUOTE, 0);
- break;
- case IDM_SELECTALL:
- pCtrl.SendMsg(EM_EXSETSEL, 0, (LPARAM)&all);
- break;
- case IDM_CLEAR:
- tabClearLog();
- break;
- case ID_LOG_FREEZELOG:
- SendDlgItemMessage(m_hwnd, IDC_SRMM_LOG, WM_KEYDOWN, VK_F12, 0);
- break;
- case ID_EDITOR_SHOWMESSAGELENGTHINDICATOR:
- PluginConfig.m_visualMessageSizeIndicator = !PluginConfig.m_visualMessageSizeIndicator;
- db_set_b(0, SRMSGMOD_T, "msgsizebar", (BYTE)PluginConfig.m_visualMessageSizeIndicator);
- Srmm_Broadcast(DM_CONFIGURETOOLBAR, 0, 0);
- Resize();
- if (m_pContainer->m_hwndStatus)
- RedrawWindow(m_pContainer->m_hwndStatus, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
- break;
- case ID_EDITOR_PASTEANDSENDIMMEDIATELY:
- HandlePasteAndSend();
- break;
- }
-
- if (pCtrl.GetCtrlId() == IDC_SRMM_LOG)
- RemoveMenu(hSubMenu, 7, MF_BYPOSITION);
- DestroyMenu(hMenu);
-}
-
-void CTabBaseDlg::ResizeIeView()
-{
- RECT rcRichEdit;
- GetWindowRect(m_log.GetHwnd(), &rcRichEdit);
-
- POINT pt = { rcRichEdit.left, rcRichEdit.top };
- ScreenToClient(m_hwnd, &pt);
-
- IEVIEWWINDOW ieWindow = { sizeof(ieWindow) };
- ieWindow.iType = IEW_SETPOS;
- ieWindow.parent = m_hwnd;
- ieWindow.hwnd = m_hwndIEView ? m_hwndIEView : m_hwndHPP;
- ieWindow.x = pt.x;
- ieWindow.y = pt.y;
- ieWindow.cx = rcRichEdit.right - rcRichEdit.left;
- ieWindow.cy = rcRichEdit.bottom - rcRichEdit.top;
- if (ieWindow.cx != 0 && ieWindow.cy != 0)
- CallService(m_hwndIEView ? MS_IEVIEW_WINDOW : MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow);
-}
+// sublassing procedure for the h++ based message log viewer
LRESULT CALLBACK IEViewSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- CSrmmWindow *mwdat = (CSrmmWindow*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+ CMsgDialog *mwdat = (CMsgDialog*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
switch (msg) {
case WM_NCCALCSIZE:
@@ -197,12 +84,9 @@ LRESULT CALLBACK IEViewSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM l return mir_callNextSubclass(hwnd, IEViewSubclassProc, msg, wParam, lParam);
}
-/////////////////////////////////////////////////////////////////////////////////////////
-// sublassing procedure for the h++ based message log viewer
-
LRESULT CALLBACK HPPKFSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- CSrmmWindow *mwdat = (CSrmmWindow*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+ CMsgDialog *mwdat = (CMsgDialog*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
if (mwdat) {
bool isCtrl, isShift, isAlt;
mwdat->KbdState(isShift, isCtrl, isAlt);
@@ -230,134 +114,13 @@ LRESULT CALLBACK HPPKFSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP return mir_callNextSubclass(hwnd, HPPKFSubclassProc, msg, wParam, lParam);
}
-/////////////////////////////////////////////////////////////////////////////////////////
-// update state of the container - this is called whenever a tab becomes active, no matter how and
-// deals with various things like updating the title bar, removing flashing icons, updating the
-// session list, switching the keyboard layout (autolocale active) and the general container status.
-//
-// it protects itself from being called more than once per session activation and is valid for
-// normal IM sessions *only*. Group chat sessions have their own activation handler (see chat/window.c)
-
-void CSrmmWindow::MsgWindowUpdateState(UINT msg)
-{
- if (m_iTabID < 0)
- return;
-
- if (msg == WM_ACTIVATE) {
- if (m_pContainer->m_dwFlags & CNT_TRANSPARENCY) {
- DWORD trans = LOWORD(m_pContainer->m_pSettings->dwTransparency);
- SetLayeredWindowAttributes(m_pContainer->m_hwnd, 0, (BYTE)trans, (m_pContainer->m_dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0));
- }
- }
-
- if (m_bIsAutosizingInput && m_iInputAreaHeight == -1) {
- m_iInputAreaHeight = 0;
- m_message.SendMsg(EM_REQUESTRESIZE, 0, 0);
- }
-
- if (m_pWnd)
- m_pWnd->activateTab();
- m_pPanel.dismissConfig();
- m_dwUnread = 0;
- if (m_pContainer->m_hwndSaved == m_hwnd)
- return;
-
- m_pContainer->m_hwndSaved = m_hwnd;
-
- m_dwTickLastEvent = 0;
- m_dwFlags &= ~MWF_DIVIDERSET;
- if (KillTimer(m_hwnd, TIMERID_FLASHWND)) {
- FlashTab(false);
- m_bCanFlashTab = false;
- }
- if (m_pContainer->m_dwFlashingStarted != 0) {
- FlashContainer(m_pContainer, 0, 0);
- m_pContainer->m_dwFlashingStarted = 0;
- }
- if (m_dwFlagsEx & MWF_SHOW_FLASHCLIST) {
- m_dwFlagsEx &= ~MWF_SHOW_FLASHCLIST;
- if (m_hFlashingEvent != 0)
- g_clistApi.pfnRemoveEvent(m_hContact, m_hFlashingEvent);
- m_hFlashingEvent = 0;
- }
- m_pContainer->m_dwFlags &= ~CNT_NEED_UPDATETITLE;
-
- if ((m_dwFlags & MWF_DEFERREDREMAKELOG) && !IsIconic(m_pContainer->m_hwnd)) {
- SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
- m_dwFlags &= ~MWF_DEFERREDREMAKELOG;
- }
-
- if (m_dwFlags & MWF_NEEDCHECKSIZE)
- PostMessage(m_hwnd, DM_SAVESIZE, 0, 0);
-
- m_pContainer->m_hIconTaskbarOverlay = nullptr;
- m_pContainer->UpdateTitle(m_hContact);
-
- tabUpdateStatusBar();
- m_dwLastActivity = GetTickCount();
- m_pContainer->m_dwLastActivity = m_dwLastActivity;
-
- m_pContainer->m_pMenuBar->configureMenu();
- UpdateTrayMenuState(this, FALSE);
-
- if (m_pContainer->m_hwndActive == m_hwnd)
- DeletePopupsForContact(m_hContact, PU_REMOVE_ON_FOCUS);
-
- m_pPanel.Invalidate();
-
- if (m_dwFlags & MWF_DEFERREDSCROLL && m_hwndIEView == nullptr && m_hwndHPP == nullptr) {
- m_dwFlags &= ~MWF_DEFERREDSCROLL;
- DM_ScrollToBottom(0, 1);
- }
-
- DM_SetDBButtonStates();
-
- if (m_hwndIEView) {
- RECT rcRTF;
- POINT pt;
-
- GetWindowRect(m_log.GetHwnd(), &rcRTF);
- rcRTF.left += 20;
- rcRTF.top += 20;
- pt.x = rcRTF.left;
- pt.y = rcRTF.top;
- if (m_hwndIEView) {
- if (M.GetByte("subclassIEView", 0)) {
- mir_subclassWindow(m_hwndIEView, IEViewSubclassProc);
- SetWindowPos(m_hwndIEView, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME);
- RedrawWindow(m_hwndIEView, nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW);
- }
- }
- m_hwndIWebBrowserControl = WindowFromPoint(pt);
- }
-
- if (m_dwFlagsEx & MWF_EX_DELAYEDSPLITTER) {
- m_dwFlagsEx &= ~MWF_EX_DELAYEDSPLITTER;
- ShowWindow(m_pContainer->m_hwnd, SW_RESTORE);
- PostMessage(m_hwnd, DM_SPLITTERGLOBALEVENT, m_wParam, m_lParam);
- m_wParam = m_lParam = 0;
- }
- if (m_dwFlagsEx & MWF_EX_AVATARCHANGED) {
- m_dwFlagsEx &= ~MWF_EX_AVATARCHANGED;
- PostMessage(m_hwnd, DM_UPDATEPICLAYOUT, 0, 0);
- }
- BB_SetButtonsPos();
- if (M.isAero())
- InvalidateRect(m_hwndParent, nullptr, FALSE);
- if (m_pContainer->m_dwFlags & CNT_SIDEBAR)
- m_pContainer->m_pSideBar->setActiveItem(this);
-
- if (m_pWnd)
- m_pWnd->Invalidate();
-}
-
static void ShowMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state)
{
for (int i = 0; i < cControls; i++)
Utils::showDlgControl(hwndDlg, controls[i], state);
}
-void CTabBaseDlg::SetDialogToType()
+void CMsgDialog::SetDialogToType()
{
if (m_hContact) {
if (db_get_b(m_hContact, "CList", "NotOnList", 0)) {
@@ -432,7 +195,7 @@ LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM {
RECT rc;
HWND hwndParent = GetParent(hwnd);
- CTabBaseDlg *dat = (CTabBaseDlg*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hwndParent, GWLP_USERDATA);
switch (msg) {
case WM_NCHITTEST:
@@ -562,56 +325,99 @@ LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM /////////////////////////////////////////////////////////////////////////////////////////
-CSrmmWindow::CSrmmWindow()
- : CSuper(IDD_MSGSPLITNEW),
+CMsgDialog::CMsgDialog(int iDlgId, SESSION_INFO *si) :
+ CSuper(g_plugin, iDlgId, si),
+ m_pPanel(this),
+ m_dwFlags(MWF_INITMODE),
m_btnOk(this, IDOK),
m_btnAdd(this, IDC_ADD),
m_btnQuote(this, IDC_QUOTE),
m_btnCancelAdd(this, IDC_CANCELADD)
{
- m_btnOk.OnClick = Callback(this, &CSrmmWindow::onClick_Ok);
- m_btnAdd.OnClick = Callback(this, &CSrmmWindow::onClick_Add);
- m_btnQuote.OnClick = Callback(this, &CSrmmWindow::onClick_Quote);
- m_btnCancelAdd.OnClick = Callback(this, &CSrmmWindow::onClick_CancelAdd);
+ m_autoClose = CLOSE_ON_CANCEL;
+ m_forceResizable = true;
- m_message.OnChange = Callback(this, &CSrmmWindow::onChange_Message);
-}
+ m_szProto = GetContactProto(m_hContact);
+ m_bFilterEnabled = db_get_b(m_hContact, CHAT_MODULE, "FilterEnabled", m_bFilterEnabled) != 0;
-void CSrmmWindow::tabClearLog()
-{
- if (m_hwndIEView || m_hwndHPP) {
- IEVIEWEVENT event;
- event.cbSize = sizeof(IEVIEWEVENT);
- event.iType = IEE_CLEAR_LOG;
- event.dwFlags = (m_dwFlags & MWF_LOG_RTL) ? IEEF_RTL : 0;
- event.hContact = m_hContact;
- if (m_hwndIEView) {
- event.hwnd = m_hwndIEView;
- CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&event);
- }
- else {
- event.hwnd = m_hwndHPP;
- CallService(MS_HPP_EG_EVENT, 0, (LPARAM)&event);
- }
- }
- m_log.SetText(L"");
- m_hDbEventFirst = 0;
+ m_btnOk.OnClick = Callback(this, &CMsgDialog::onClick_Ok);
+ m_btnAdd.OnClick = Callback(this, &CMsgDialog::onClick_Add);
+ m_btnQuote.OnClick = Callback(this, &CMsgDialog::onClick_Quote);
+ m_btnFilter.OnClick = Callback(this, &CMsgDialog::onClick_Filter);
+ m_btnNickList.OnClick = Callback(this, &CMsgDialog::onClick_ShowNickList);
+ m_btnCancelAdd.OnClick = Callback(this, &CMsgDialog::onClick_CancelAdd);
+
+ m_nickList.OnDblClick = Callback(this, &CMsgDialog::onDblClick_List);
+
+ m_message.OnChange = Callback(this, &CMsgDialog::onChange_Message);
}
-CThumbBase* CSrmmWindow::tabCreateThumb(CProxyWindow *pProxy) const
+CMsgDialog::~CMsgDialog()
{
- return new CThumbIM(pProxy);
+ delete m_pWnd;
+
+ mir_free(m_sendBuffer);
+ mir_free(m_hHistoryEvents);
+ mir_free(m_hQueuedEvents);
+
+ if (m_hClientIcon) DestroyIcon(m_hClientIcon);
+ if (m_hSmileyIcon) DestroyIcon(m_hSmileyIcon);
+ if (m_hXStatusIcon) DestroyIcon(m_hXStatusIcon);
+ if (m_hTaskbarIcon) DestroyIcon(m_hTaskbarIcon);
}
-bool CSrmmWindow::OnInitDialog()
+bool CMsgDialog::OnInitDialog()
{
CSuper::OnInitDialog();
+ // m_hwnd is valid, pass it to the tab control
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ tci.lParam = (LPARAM)m_hwnd;
+ TabCtrl_SetItem(m_hwndParent, m_iTabID, &tci);
+
+ // update another tab ids
+ m_pContainer->UpdateTabs();
+
+ // add this window to window list & proxy
+ if (IsWinVer7Plus() && PluginConfig.m_useAeroPeek)
+ m_pWnd = new CProxyWindow(this);
+ else
+ m_pWnd = nullptr;
+
+ // set up Windows themes
+ DM_ThemeChanged();
+
+ // refresh cache data for this contact
+ m_cache = CContactCache::getContactCache(m_hContact);
+ m_cache->updateNick();
+ m_cache->updateUIN();
+ m_cache->setWindowData(this);
+
+ m_bIsAutosizingInput = IsAutoSplitEnabled();
m_szProto = const_cast<char *>(m_cache->getProto());
m_bIsMeta = m_cache->isMeta();
if (m_bIsMeta)
m_cache->updateMeta();
+ if (m_si) {
+ m_si->pDlg = this;
+ Chat_SetFilters(m_si);
+ + m_pPanel.getVisibility(); + m_pPanel.Configure(); +
+ for (auto &it : btnControls)
+ ShowWindow(GetDlgItem(m_hwnd,it), SW_HIDE);
+ }
+ else {
+ ShowWindow(GetDlgItem(m_hwnd, IDC_SPLITTERX), SW_HIDE);
+ m_nickList.Hide();
+
+ for (auto &it : btnControls)
+ CustomizeButton(GetDlgItem(m_hwnd, it));
+ }
+
// show a popup if wanted...
if (m_bWantPopup) {
DBEVENTINFO dbei = {};
@@ -627,14 +433,17 @@ bool CSrmmWindow::OnInitDialog() }
else m_wStatus = ID_STATUS_OFFLINE;
- for (auto &it : btnControls)
- CustomizeButton(GetDlgItem(m_hwnd, it));
-
GetMYUIN();
GetClientIcon();
- CustomizeButton(CreateWindowEx(0, L"MButtonClass", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0, 0, 6, DPISCALEY_S(20),
- m_hwnd, (HMENU)IDC_TOGGLESIDEBAR, g_plugin.getInst(), nullptr));
+ HWND hwndBtn = CreateWindowEx(0, L"MButtonClass", L"", WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0, 0, 6, DPISCALEY_S(20), m_hwnd, (HMENU)IDC_TOGGLESIDEBAR, g_plugin.getInst(), nullptr);
+ CustomizeButton(hwndBtn);
+ SendMessage(hwndBtn, BUTTONSETASTHEMEDBTN, 1, 0);
+ SendMessage(hwndBtn, BUTTONSETCONTAINER, (LPARAM)m_pContainer, 0);
+ SendMessage(hwndBtn, BUTTONSETASFLATBTN, FALSE, 0);
+ SendMessage(hwndBtn, BUTTONSETASTOOLBARBUTTON, TRUE, 0);
+ SendMessage(hwndBtn, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Expand or collapse the side bar"), BATF_UNICODE);
+
m_hwndPanelPicParent = CreateWindowEx(WS_EX_TOPMOST, L"Static", L"", SS_OWNERDRAW | WS_VISIBLE | WS_CHILD, 1, 1, 1, 1, m_hwnd, (HMENU)6000, nullptr, nullptr);
mir_subclassWindow(m_hwndPanelPicParent, CInfoPanel::avatarParentSubclass);
@@ -661,8 +470,10 @@ bool CSrmmWindow::OnInitDialog() GetMyNick();
m_iMultiSplit = g_plugin.getDword("multisplit", 150);
- m_nTypeMode = PROTOTYPE_SELFTYPING_OFF;
- SetTimer(m_hwnd, TIMERID_TYPE, 1000, nullptr);
+ if (m_si == nullptr || m_si->iType == GCW_PRIVMESS) {
+ m_nTypeMode = PROTOTYPE_SELFTYPING_OFF;
+ SetTimer(m_hwnd, TIMERID_TYPE, 1000, nullptr);
+ }
m_iLastEventType = 0xffffffff;
// load log option flags...
@@ -734,68 +545,81 @@ bool CSrmmWindow::OnInitDialog() SetDlgItemText(m_hwnd, IDC_CANCELSEND, TranslateT("Cancel"));
SetDlgItemText(m_hwnd, IDC_MSGSENDLATER, TranslateT("Send later"));
+ m_log.SendMsg(EM_AUTOURLDETECT, TRUE, 0);
+ m_log.SendMsg(EM_EXLIMITTEXT, 0, 0x7FFFFFFF);
m_log.SendMsg(EM_SETUNDOLIMIT, 0, 0);
+ m_log.SendMsg(EM_HIDESELECTION, TRUE, 0);
m_log.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_LINK);
+ m_log.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR);
+ m_log.SendMsg(EM_SETLANGOPTIONS, 0, m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONTSIZEADJUST);
+ m_log.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3));
m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_REQUESTRESIZE | ENM_MOUSEEVENTS | ENM_SCROLL | ENM_KEYEVENTS | ENM_CHANGE);
+ m_message.SendMsg(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(3, 3));
m_message.SetReadOnly(false);
m_bActualHistory = M.GetByte(m_hContact, "ActualHistory", 0) != 0;
- /* OnO: higligh lines to their end */
- m_log.SendMsg(EM_SETEDITSTYLE, SES_EXTENDBACKCOLOR, SES_EXTENDBACKCOLOR);
-
- m_log.SendMsg(EM_SETLANGOPTIONS, 0, m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOFONTSIZEADJUST);
-
// add us to the tray list (if it exists)
UpdateTrayMenu(nullptr, m_wStatus, m_szProto, m_wszStatus, m_hContact, 0);
- m_log.SendMsg(EM_AUTOURLDETECT, TRUE, 0);
- m_log.SendMsg(EM_EXLIMITTEXT, 0, 0x80000000);
-
// subclassing stuff
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CONTACTPIC), AvatarSubclassProc);
+ mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERX), SplitterSubclassProc);
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERY), SplitterSubclassProc);
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_MULTISPLITTER), SplitterSubclassProc);
mir_subclassWindow(GetDlgItem(m_hwnd, IDC_PANELSPLITTER), SplitterSubclassProc);
// load old messages from history (if wanted...)
+
m_cache->updateStats(TSessionStats::INIT_TIMER);
- if (m_hContact) {
- FindFirstEvent();
- m_nMax = (int)m_cache->getMaxMessageLength();
- }
+
LoadContactAvatar();
- DM_OptionsApplied(0, 0);
LoadOwnAvatar();
- // restore saved msg if any...
- if (m_hContact) {
- ptrW tszSavedMsg(g_plugin.getWStringA(m_hContact, "SavedMsg"));
- if (tszSavedMsg != 0) {
- SETTEXTEX stx = { ST_DEFAULT, 1200 };
- m_message.SendMsg(EM_SETTEXTEX, (WPARAM)&stx, tszSavedMsg);
- UpdateSaveAndSendButton();
- if (m_pContainer->m_hwndActive == m_hwnd)
- UpdateReadChars();
- }
- }
- if (wszInitialText) {
- m_message.SetText(wszInitialText);
- int len = GetWindowTextLength(m_message.GetHwnd());
- PostMessage(m_message.GetHwnd(), EM_SETSEL, len, len);
- if (len)
- EnableSendButton(true);
- mir_free(wszInitialText);
+ if (isChat()) {
+ UpdateOptions();
+ UpdateStatusBar();
+ UpdateTitle();
+ m_hTabIcon = m_hTabStatusIcon;
+
+ UpdateNickList();
}
+ else {
+ if (m_hContact) {
+ FindFirstEvent();
+ m_nMax = (int)m_cache->getMaxMessageLength();
+ }
+ DM_OptionsApplied(0, 0);
- for (MEVENT hdbEvent = db_event_last(m_hContact); hdbEvent; hdbEvent = db_event_prev(m_hContact, hdbEvent)) {
- DBEVENTINFO dbei = {};
- db_event_get(hdbEvent, &dbei);
- if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
- m_lastMessage = dbei.timestamp;
- DM_UpdateLastMessage();
- break;
+ // restore saved msg if any...
+ if (m_hContact) {
+ ptrW tszSavedMsg(g_plugin.getWStringA(m_hContact, "SavedMsg"));
+ if (tszSavedMsg != 0) {
+ SETTEXTEX stx = { ST_DEFAULT, 1200 };
+ m_message.SendMsg(EM_SETTEXTEX, (WPARAM)& stx, tszSavedMsg);
+ UpdateSaveAndSendButton();
+ if (m_pContainer->m_hwndActive == m_hwnd)
+ UpdateReadChars();
+ }
+ }
+ if (wszInitialText) {
+ m_message.SetText(wszInitialText);
+ int len = GetWindowTextLength(m_message.GetHwnd());
+ PostMessage(m_message.GetHwnd(), EM_SETSEL, len, len);
+ if (len)
+ EnableSendButton(true);
+ mir_free(wszInitialText);
+ }
+
+ for (MEVENT hdbEvent = db_event_last(m_hContact); hdbEvent; hdbEvent = db_event_prev(m_hContact, hdbEvent)) {
+ DBEVENTINFO dbei = {};
+ db_event_get(hdbEvent, &dbei);
+ if (dbei.eventType == EVENTTYPE_MESSAGE && !(dbei.flags & DBEF_SENT)) {
+ m_lastMessage = dbei.timestamp;
+ DM_UpdateLastMessage();
+ break;
+ }
}
}
@@ -819,7 +643,11 @@ bool CSrmmWindow::OnInitDialog() m_dwFlags |= MWF_NEEDCHECKSIZE | MWF_WASBACKGROUNDCREATE | MWF_DEFERREDSCROLL;
}
- if (m_bActivate) {
+ if (isChat()) {
+ m_pContainer->m_hwndActive = m_hwnd;
+ ShowWindow(m_hwnd, SW_SHOW);
+ }
+ else if (m_bActivate) {
m_pContainer->m_hwndActive = m_hwnd;
ShowWindow(m_hwnd, SW_SHOW);
SetActiveWindow(m_hwnd);
@@ -850,8 +678,11 @@ bool CSrmmWindow::OnInitDialog() return true;
}
-void CSrmmWindow::OnDestroy()
+void CMsgDialog::OnDestroy()
{
+ NotifyEvent(MSG_WINDOW_EVT_CLOSING);
+
+ m_cache->setWindowData();
m_pContainer->ClearMargins();
PostMessage(m_pContainer->m_hwnd, WM_SIZE, 0, 1);
if (m_pContainer->m_dwFlags & CNT_SIDEBAR)
@@ -870,8 +701,15 @@ void CSrmmWindow::OnDestroy() if (m_hwndPanelPicParent)
DestroyWindow(m_hwndPanelPicParent);
+ if (m_si) {
+ if (g_clistApi.pfnGetEvent(m_si->hContact, 0))
+ g_clistApi.pfnRemoveEvent(m_si->hContact, GC_FAKE_EVENT);
+ m_si->wState &= ~STATE_TALK;
+ m_si->pDlg = nullptr;
+ m_si = nullptr;
+ }
+
if (m_cache->isValid()) { // not valid means the contact was deleted
- NotifyEvent(MSG_WINDOW_EVT_CLOSING);
AddContactToFavorites(m_hContact, m_cache->getNick(), m_cache->getActiveProto(), m_wszStatus, m_wStatus,
Skin_LoadProtoIcon(m_cache->getActiveProto(), m_cache->getActiveStatus()), 1, PluginConfig.g_hMenuRecent);
if (m_hContact) {
@@ -887,8 +725,9 @@ void CSrmmWindow::OnDestroy() }
}
- if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON)
- DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
+ if (m_si == nullptr || m_si->iType == GCW_PRIVMESS)
+ if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON)
+ DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
DM_FreeTheme();
@@ -911,6 +750,11 @@ void CSrmmWindow::OnDestroy() }
}
+ if (m_pWnd) {
+ delete m_pWnd;
+ m_pWnd = nullptr;
+ }
+
if (m_hwndTip)
DestroyWindow(m_hwndTip);
@@ -950,7 +794,7 @@ void CSrmmWindow::OnDestroy() CSuper::OnDestroy();
}
-void CSrmmWindow::ReplayQueue()
+void CMsgDialog::ReplayQueue()
{
for (int i = 0; i < m_iNextQueuedEvent; i++)
if (m_hQueuedEvents[i] != 0)
@@ -961,107 +805,168 @@ void CSrmmWindow::ReplayQueue() TranslateT("Auto scrolling is disabled (press F12 to enable it)"));
}
-void CSrmmWindow::UpdateTitle()
+void CMsgDialog::UpdateTitle()
{
- DWORD dwOldIdle = m_idle;
- const char *szActProto = nullptr;
+ if (isChat()) {
+ m_wStatus = m_si->wStatus;
- m_wszStatus[0] = 0;
+ const wchar_t *szNick = m_cache->getNick();
+ if (mir_wstrlen(szNick) > 0) {
+ if (M.GetByte("cuttitle", 0))
+ CutContactName(szNick, m_wszTitle, _countof(m_wszTitle));
+ else
+ wcsncpy_s(m_wszTitle, szNick, _TRUNCATE);
+ }
- if (m_iTabID == -1)
- return;
+ CMStringW wszTitle;
+ HICON hIcon = nullptr;
+ int nUsers = m_si->getUserList().getCount();
- TCITEM item = {};
+ switch (m_si->iType) {
+ case GCW_CHATROOM:
+ hIcon = Skin_LoadProtoIcon(m_si->pszModule, (m_wStatus <= ID_STATUS_OFFLINE) ? ID_STATUS_OFFLINE : m_wStatus);
+ wszTitle.Format((nUsers == 1) ? TranslateT("%s: chat room (%u user%s)") : TranslateT("%s: chat room (%u users%s)"),
+ szNick, nUsers, m_bFilterEnabled ? TranslateT(", event filter active") : L"");
+ break;
- bool bChanged = false;
- wchar_t newtitle[128];
- if (m_hContact) {
- if (m_szProto) {
- szActProto = m_cache->getProto();
+ case GCW_PRIVMESS:
+ hIcon = Skin_LoadProtoIcon(m_si->pszModule, (m_wStatus <= ID_STATUS_OFFLINE) ? ID_STATUS_OFFLINE : m_wStatus);
+ if (nUsers == 1)
+ wszTitle.Format(TranslateT("%s: message session"), szNick);
+ else
+ wszTitle.Format(TranslateT("%s: message session (%u users)"), szNick, nUsers);
+ break;
- bool bHasName = (m_cache->getUIN()[0] != 0);
- m_idle = m_cache->getIdleTS();
- m_dwFlagsEx = m_idle ? m_dwFlagsEx | MWF_SHOW_ISIDLE : m_dwFlagsEx & ~MWF_SHOW_ISIDLE;
+ case GCW_SERVER:
+ wszTitle.Format(L"%s: Server", szNick);
+ hIcon = LoadIconEx("window");
+ break;
- m_wStatus = m_cache->getStatus();
- wcsncpy_s(m_wszStatus, Clist_GetStatusModeDescription(m_szProto == nullptr ? ID_STATUS_OFFLINE : m_wStatus, 0), _TRUNCATE);
+ default:
+ return;
+ }
- wchar_t newcontactname[128]; newcontactname[0] = 0;
- if (PluginConfig.m_bCutContactNameOnTabs)
- CutContactName(m_cache->getNick(), newcontactname, _countof(newcontactname));
- else
- wcsncpy_s(newcontactname, m_cache->getNick(), _TRUNCATE);
+ if (m_pWnd) {
+ m_pWnd->updateTitle(m_wszTitle);
+ m_pWnd->updateIcon(hIcon);
+ }
+ m_hTabStatusIcon = hIcon;
+
+ if (m_cache->getStatus() != m_cache->getOldStatus()) {
+ wcsncpy_s(m_wszStatus, Clist_GetStatusModeDescription(m_wStatus, 0), _TRUNCATE);
+
+ TCITEM item = {};
+ item.mask = TCIF_TEXT;
+ item.pszText = m_wszTitle;
+ TabCtrl_SetItem(m_hwndParent, m_iTabID, &item);
+ }
+ SetWindowText(m_hwnd, wszTitle);
+ if (m_pContainer->m_hwndActive == m_hwnd) {
+ m_pContainer->UpdateTitle(0, this);
+ UpdateStatusBar();
+ }
+ }
+ else {
+ DWORD dwOldIdle = m_idle;
+ const char *szActProto = nullptr;
- Utils::DoubleAmpersands(newcontactname, _countof(newcontactname));
+ m_wszStatus[0] = 0;
- if (newcontactname[0] != 0) {
- if (PluginConfig.m_bStatusOnTabs)
- mir_snwprintf(newtitle, L"%s (%s)", newcontactname, m_wszStatus);
+ if (m_iTabID == -1)
+ return;
+
+ TCITEM item = {};
+
+ bool bChanged = false;
+ wchar_t newtitle[128];
+ if (m_hContact) {
+ if (m_szProto) {
+ szActProto = m_cache->getProto();
+
+ bool bHasName = (m_cache->getUIN()[0] != 0);
+ m_idle = m_cache->getIdleTS();
+ m_dwFlagsEx = m_idle ? m_dwFlagsEx | MWF_SHOW_ISIDLE : m_dwFlagsEx & ~MWF_SHOW_ISIDLE;
+
+ m_wStatus = m_cache->getStatus();
+ wcsncpy_s(m_wszStatus, Clist_GetStatusModeDescription(m_szProto == nullptr ? ID_STATUS_OFFLINE : m_wStatus, 0), _TRUNCATE);
+
+ wchar_t newcontactname[128]; newcontactname[0] = 0;
+ if (PluginConfig.m_bCutContactNameOnTabs)
+ CutContactName(m_cache->getNick(), newcontactname, _countof(newcontactname));
else
- wcsncpy_s(newtitle, newcontactname, _TRUNCATE);
- }
- else wcsncpy_s(newtitle, L"Forward", _TRUNCATE);
+ wcsncpy_s(newcontactname, m_cache->getNick(), _TRUNCATE);
+
+ Utils::DoubleAmpersands(newcontactname, _countof(newcontactname));
+
+ if (newcontactname[0] != 0) {
+ if (PluginConfig.m_bStatusOnTabs)
+ mir_snwprintf(newtitle, L"%s (%s)", newcontactname, m_wszStatus);
+ else
+ wcsncpy_s(newtitle, newcontactname, _TRUNCATE);
+ }
+ else wcsncpy_s(newtitle, L"Forward", _TRUNCATE);
- if (mir_wstrcmp(newtitle, m_wszTitle))
- bChanged = true;
- else if (m_wStatus != m_wOldStatus)
- bChanged = true;
+ if (mir_wstrcmp(newtitle, m_wszTitle))
+ bChanged = true;
+ else if (m_wStatus != m_wOldStatus)
+ bChanged = true;
- SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0);
+ SendMessage(m_hwnd, DM_UPDATEWINICON, 0, 0);
- wchar_t fulluin[256];
- if (m_bIsMeta)
- mir_snwprintf(fulluin,
+ wchar_t fulluin[256];
+ if (m_bIsMeta)
+ mir_snwprintf(fulluin,
TranslateT("UID: %s (Shift+click -> copy to clipboard)\nClick for user's details\nRight click for metacontact control\nClick dropdown to add or remove user from your favorites."),
bHasName ? m_cache->getUIN() : TranslateT("No UID"));
- else
- mir_snwprintf(fulluin,
+ else
+ mir_snwprintf(fulluin,
TranslateT("UID: %s (Shift+click -> copy to clipboard)\nClick for user's details\nClick dropdown to change this contact's favorite status."),
bHasName ? m_cache->getUIN() : TranslateT("No UID"));
- SendDlgItemMessage(m_hwnd, IDC_NAME, BUTTONADDTOOLTIP, (WPARAM)fulluin, BATF_UNICODE);
+ SendDlgItemMessage(m_hwnd, IDC_NAME, BUTTONADDTOOLTIP, (WPARAM)fulluin, BATF_UNICODE);
+ }
}
- }
- else wcsncpy_s(newtitle, L"Message Session", _TRUNCATE);
+ else wcsncpy_s(newtitle, L"Message Session", _TRUNCATE);
- m_wOldStatus = m_wStatus;
- if (m_idle != dwOldIdle || bChanged) {
- if (bChanged) {
- item.mask |= TCIF_TEXT;
- item.pszText = m_wszTitle;
- wcsncpy_s(m_wszTitle, newtitle, _TRUNCATE);
- if (m_pWnd)
- m_pWnd->updateTitle(m_cache->getNick());
- }
- if (m_iTabID >= 0) {
- TabCtrl_SetItem(m_hwndParent, m_iTabID, &item);
- if (m_pContainer->m_dwFlags & CNT_SIDEBAR)
- m_pContainer->m_pSideBar->updateSession(this);
- }
- if (m_pContainer->m_hwndActive == m_hwnd && bChanged)
- m_pContainer->UpdateTitle(m_hContact);
+ m_wOldStatus = m_wStatus;
+ if (m_idle != dwOldIdle || bChanged) {
+ if (bChanged) {
+ item.mask |= TCIF_TEXT;
+ item.pszText = m_wszTitle;
+ wcsncpy_s(m_wszTitle, newtitle, _TRUNCATE);
+ if (m_pWnd)
+ m_pWnd->updateTitle(m_cache->getNick());
+ }
+ if (m_iTabID >= 0) {
+ TabCtrl_SetItem(m_hwndParent, m_iTabID, &item);
+ if (m_pContainer->m_dwFlags & CNT_SIDEBAR)
+ m_pContainer->m_pSideBar->updateSession(this);
+ }
+ if (m_pContainer->m_hwndActive == m_hwnd && bChanged)
+ m_pContainer->UpdateTitle(m_hContact);
- UpdateTrayMenuState(this, TRUE);
- if (M.IsFavorite(m_hContact))
- AddContactToFavorites(m_hContact, m_cache->getNick(), szActProto, m_wszStatus, m_wStatus, Skin_LoadProtoIcon(m_cache->getProto(), m_cache->getStatus()), 0, PluginConfig.g_hMenuFavorites);
+ UpdateTrayMenuState(this, TRUE);
+ if (M.IsFavorite(m_hContact))
+ AddContactToFavorites(m_hContact, m_cache->getNick(), szActProto, m_wszStatus, m_wStatus, Skin_LoadProtoIcon(m_cache->getProto(), m_cache->getStatus()), 0, PluginConfig.g_hMenuFavorites);
- if (M.IsRecent(m_hContact))
- AddContactToFavorites(m_hContact, m_cache->getNick(), szActProto, m_wszStatus, m_wStatus, Skin_LoadProtoIcon(m_cache->getProto(), m_cache->getStatus()), 0, PluginConfig.g_hMenuRecent);
+ if (M.IsRecent(m_hContact))
+ AddContactToFavorites(m_hContact, m_cache->getNick(), szActProto, m_wszStatus, m_wStatus, Skin_LoadProtoIcon(m_cache->getProto(), m_cache->getStatus()), 0, PluginConfig.g_hMenuRecent);
- m_pPanel.Invalidate();
- if (m_pWnd)
- m_pWnd->Invalidate();
- }
+ m_pPanel.Invalidate();
+ if (m_pWnd)
+ m_pWnd->Invalidate();
+ }
- // care about MetaContacts and update the statusbar icon with the currently "most online" contact...
- if (m_bIsMeta) {
- PostMessage(m_hwnd, DM_OWNNICKCHANGED, 0, 0);
- if (m_pContainer->m_dwFlags & CNT_UINSTATUSBAR)
- DM_UpdateLastMessage();
+ // care about MetaContacts and update the statusbar icon with the currently "most online" contact...
+ if (m_bIsMeta) {
+ PostMessage(m_hwnd, DM_OWNNICKCHANGED, 0, 0);
+ if (m_pContainer->m_dwFlags & CNT_UINSTATUSBAR)
+ DM_UpdateLastMessage();
+ }
}
}
-void CSrmmWindow::onClick_Ok(CCtrlButton*)
+void CMsgDialog::onClick_Ok(CCtrlButton *)
{
if (m_bEditNotesActive) {
SendMessage(m_hwnd, DM_ACTIVATETOOLTIP, IDC_PIC, (LPARAM)TranslateT("You are editing the user notes. Click the button again or use the hotkey (default: Alt+N) to save the notes and return to normal messaging mode"));
@@ -1074,9 +979,9 @@ void CSrmmWindow::onClick_Ok(CCtrlButton*) fi.chrg.cpMin = 0;
fi.chrg.cpMax = -1;
fi.lpstrText = L"{";
- int final_sendformat = m_message.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) == -1 ? m_SendFormat : 0;
+ int final_sendformat = m_message.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)& fi) == -1 ? m_SendFormat : 0;
fi.lpstrText = L"}";
- final_sendformat = m_message.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)&fi) == -1 ? final_sendformat : 0;
+ final_sendformat = m_message.SendMsg(EM_FINDTEXTEX, FR_DOWN, (LPARAM)& fi) == -1 ? final_sendformat : 0;
if (GetSendButtonState(m_hwnd) == PBS_DISABLED)
return;
@@ -1089,70 +994,102 @@ void CSrmmWindow::onClick_Ok(CCtrlButton*) if (decoded.IsEmpty())
return;
- if (final_sendformat)
+ if (isChat()) {
+ m_cache->saveHistory();
DoRtfToTags(decoded);
- decoded.TrimRight();
-
- T2Utf utfResult(decoded);
- size_t memRequired = mir_strlen(utfResult) + 1;
-
- // try to detect RTL
- HWND hwndEdit = m_message.GetHwnd();
- SendMessage(hwndEdit, WM_SETREDRAW, FALSE, 0);
-
- PARAFORMAT2 pf2;
- memset(&pf2, 0, sizeof(PARAFORMAT2));
- pf2.cbSize = sizeof(pf2);
- pf2.dwMask = PFM_RTLPARA;
- SendMessage(hwndEdit, EM_SETSEL, 0, -1);
- SendMessage(hwndEdit, EM_GETPARAFORMAT, 0, (LPARAM)&pf2);
-
- int flags = 0;
- if (pf2.wEffects & PFE_RTLPARA)
- if (Utils_IsRtl(decoded))
- flags |= PREF_RTL;
-
- SendMessage(hwndEdit, WM_SETREDRAW, TRUE, 0);
- SendMessage(hwndEdit, EM_SETSEL, -1, -1);
- InvalidateRect(hwndEdit, nullptr, FALSE);
-
- if (memRequired > m_iSendBufferSize) {
- m_sendBuffer = (char *)mir_realloc(m_sendBuffer, memRequired);
- m_iSendBufferSize = memRequired;
+ decoded.Trim();
+
+ if (m_si->pMI->bAckMsg) {
+ m_message.Enable(false);
+ m_message.SendMsg(EM_SETREADONLY, TRUE, 0);
+ }
+ else m_message.SetText(L"");
+
+ Utils::enableDlgControl(m_hwnd, IDOK, false);
+
+ // Typing support for GCW_PRIVMESS sessions
+ if (m_si->iType == GCW_PRIVMESS)
+ if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON)
+ DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
+
+ bool fSound = true;
+ if (decoded[0] == '/' || m_si->iType == GCW_SERVER)
+ fSound = false;
+ Chat_DoEventHook(m_si, GC_USER_MESSAGE, nullptr, decoded, 0);
+ m_si->pMI->idleTimeStamp = time(0);
+ UpdateStatusBar();
+ if (m_pContainer)
+ if (fSound && !nen_options.iNoSounds && !(m_pContainer->m_dwFlags & CNT_NOSOUND))
+ Skin_PlaySound("ChatSent");
}
+ else {
+ if (final_sendformat)
+ DoRtfToTags(decoded);
+ decoded.TrimRight();
- memcpy(m_sendBuffer, (char*)utfResult, memRequired);
+ T2Utf utfResult(decoded);
+ size_t memRequired = mir_strlen(utfResult) + 1;
- if (memRequired == 0 || m_sendBuffer[0] == 0)
- return;
+ // try to detect RTL
+ HWND hwndEdit = m_message.GetHwnd();
+ SendMessage(hwndEdit, WM_SETREDRAW, FALSE, 0);
+
+ PARAFORMAT2 pf2;
+ memset(&pf2, 0, sizeof(PARAFORMAT2));
+ pf2.cbSize = sizeof(pf2);
+ pf2.dwMask = PFM_RTLPARA;
+ SendMessage(hwndEdit, EM_SETSEL, 0, -1);
+ SendMessage(hwndEdit, EM_GETPARAFORMAT, 0, (LPARAM)& pf2);
+
+ int flags = 0;
+ if (pf2.wEffects & PFE_RTLPARA)
+ if (Utils_IsRtl(decoded))
+ flags |= PREF_RTL;
- if (m_sendMode & SMODE_CONTAINER && m_pContainer->m_hwndActive == m_hwnd && GetForegroundWindow() == m_pContainer->m_hwnd) {
- int tabCount = TabCtrl_GetItemCount(m_hwndParent);
- ptrA szFromStream(m_message.GetRichTextRtf(!m_SendFormat));
-
- for (int i = 0; i < tabCount; i++) {
- // get the contact from the tabs lparam which hopefully is the tabs hwnd so we can get its userdata.... hopefully
- HWND contacthwnd = GetTabWindow(m_hwndParent, i);
- if (IsWindow(contacthwnd)) {
- // if the contact hwnd is the current contact then ignore it and let the normal code deal with the msg
- if (contacthwnd != m_hwnd) {
- SETTEXTEX stx = { ST_DEFAULT, CP_UTF8 };
- // send the buffer to the contacts msg typing area
- SendDlgItemMessage(contacthwnd, IDC_SRMM_MESSAGE, EM_SETTEXTEX, (WPARAM)&stx, (LPARAM)szFromStream);
- SendMessage(contacthwnd, WM_COMMAND, IDOK, 0);
+ SendMessage(hwndEdit, WM_SETREDRAW, TRUE, 0);
+ SendMessage(hwndEdit, EM_SETSEL, -1, -1);
+ InvalidateRect(hwndEdit, nullptr, FALSE);
+
+ if (memRequired > m_iSendBufferSize) {
+ m_sendBuffer = (char *)mir_realloc(m_sendBuffer, memRequired);
+ m_iSendBufferSize = memRequired;
+ }
+
+ memcpy(m_sendBuffer, (char *)utfResult, memRequired);
+
+ if (memRequired == 0 || m_sendBuffer[0] == 0)
+ return;
+
+ if (m_sendMode & SMODE_CONTAINER && m_pContainer->m_hwndActive == m_hwnd && GetForegroundWindow() == m_pContainer->m_hwnd) {
+ int tabCount = TabCtrl_GetItemCount(m_hwndParent);
+ ptrA szFromStream(m_message.GetRichTextRtf(!m_SendFormat));
+
+ for (int i = 0; i < tabCount; i++) {
+ // get the contact from the tabs lparam which hopefully is the tabs hwnd so we can get its userdata.... hopefully
+ HWND contacthwnd = GetTabWindow(m_hwndParent, i);
+ if (IsWindow(contacthwnd)) {
+ // if the contact hwnd is the current contact then ignore it and let the normal code deal with the msg
+ if (contacthwnd != m_hwnd) {
+ SETTEXTEX stx = { ST_DEFAULT, CP_UTF8 };
+ // send the buffer to the contacts msg typing area
+ SendDlgItemMessage(contacthwnd, IDC_SRMM_MESSAGE, EM_SETTEXTEX, (WPARAM)& stx, (LPARAM)szFromStream);
+ SendMessage(contacthwnd, WM_COMMAND, IDOK, 0);
+ }
}
}
}
+ // END /all /MOD
+ if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON)
+ DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
+
+ DeletePopupsForContact(m_hContact, PU_REMOVE_ON_SEND);
+ sendQueue->addTo(this, memRequired, flags);
}
- // END /all /MOD
- if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON)
- DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
- DeletePopupsForContact(m_hContact, PU_REMOVE_ON_SEND);
- sendQueue->addTo(this, memRequired, flags);
+ SetFocus(m_message.GetHwnd());
}
-void CSrmmWindow::onClick_Add(CCtrlButton*)
+void CMsgDialog::onClick_Add(CCtrlButton*)
{
Contact_Add(m_hContact, m_hwnd);
@@ -1165,7 +1102,7 @@ void CSrmmWindow::onClick_Add(CCtrlButton*) }
}
-void CSrmmWindow::onClick_Quote(CCtrlButton*)
+void CMsgDialog::onClick_Quote(CCtrlButton*)
{
CHARRANGE sel;
SETTEXTEX stx = { ST_SELECTION, 1200 };
@@ -1253,7 +1190,7 @@ void CSrmmWindow::onClick_Quote(CCtrlButton*) SetFocus(m_message.GetHwnd());
}
-void CSrmmWindow::onClick_CancelAdd(CCtrlButton*)
+void CMsgDialog::onClick_CancelAdd(CCtrlButton*)
{
m_bNotOnList = false;
ShowMultipleControls(m_hwnd, addControls, _countof(addControls), SW_HIDE);
@@ -1262,7 +1199,69 @@ void CSrmmWindow::onClick_CancelAdd(CCtrlButton*) Resize();
}
-void CSrmmWindow::onChange_Message(CCtrlEdit*)
+void CMsgDialog::onClick_Filter(CCtrlButton *pButton)
+{
+ if (!pButton->Enabled())
+ return;
+
+ if (m_iLogFilterFlags == 0 && !m_bFilterEnabled) {
+ MessageBox(nullptr, TranslateT("The filter cannot be enabled, because there are no event types selected either global or for this chat room"), TranslateT("Event filter error"), MB_OK);
+ m_bFilterEnabled = false;
+ }
+ else m_bFilterEnabled = !m_bFilterEnabled;
+
+ m_btnFilter.SendMsg(BUTTONSETOVERLAYICON, (LPARAM)(m_bFilterEnabled ? PluginConfig.g_iconOverlayEnabled : PluginConfig.g_iconOverlayDisabled), 0);
+
+ if (m_bFilterEnabled && db_get_b(0, CHAT_MODULE, "RightClickFilter", 1) == 0) {
+ ShowFilterMenu();
+ return;
+ }
+ RedrawLog();
+ UpdateTitle();
+ db_set_b(m_si->hContact, CHAT_MODULE, "FilterEnabled", m_bFilterEnabled);
+}
+
+void CMsgDialog::onClick_ShowNickList(CCtrlButton *pButton)
+{
+ if (!pButton->Enabled() || m_si->iType == GCW_SERVER)
+ return;
+
+ m_bNicklistEnabled = !m_bNicklistEnabled;
+
+ Resize();
+ if (CSkin::m_skinEnabled)
+ InvalidateRect(m_hwnd, nullptr, TRUE);
+ ScrollToBottom();
+}
+
+void CMsgDialog::onDblClick_List(CCtrlListBox *pList)
+{
+ TVHITTESTINFO hti;
+ hti.pt.x = (short)LOWORD(GetMessagePos());
+ hti.pt.y = (short)HIWORD(GetMessagePos());
+ ScreenToClient(pList->GetHwnd(), &hti.pt);
+
+ int item = LOWORD(pList->SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y)));
+ USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, item);
+ if (ui == nullptr)
+ return;
+
+ bool bShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
+ if (g_Settings.bDoubleClick4Privat ? bShift : !bShift) {
+ int selStart = LOWORD(m_message.SendMsg(EM_GETSEL, 0, 0));
+ CMStringW tszName(ui->pszNick);
+ if (selStart == 0)
+ tszName.AppendChar(g_Settings.bUseCommaAsColon ? ',' : ':');
+ tszName.AppendChar(' ');
+
+ m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)tszName.GetString());
+ PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0);
+ SetFocus(m_message.GetHwnd());
+ }
+ else Chat_DoEventHook(m_si, GC_USER_PRIVMESS, ui, nullptr, 0);
+}
+
+void CMsgDialog::onChange_Message(CCtrlEdit*)
{
if (m_pContainer->m_hwndActive == m_hwnd)
UpdateReadChars();
@@ -1270,38 +1269,75 @@ void CSrmmWindow::onChange_Message(CCtrlEdit*) m_dwLastActivity = GetTickCount();
m_pContainer->m_dwLastActivity = m_dwLastActivity;
UpdateSaveAndSendButton();
- if (!(GetKeyState(VK_CONTROL) & 0x8000)) {
- m_nLastTyping = GetTickCount();
- if (GetWindowTextLength(m_message.GetHwnd())) {
- if (m_nTypeMode == PROTOTYPE_SELFTYPING_OFF) {
- if (!(m_dwFlags & MWF_INITMODE))
- DM_NotifyTyping(PROTOTYPE_SELFTYPING_ON);
+
+ m_btnOk.SendMsg(BUTTONSETASNORMAL, m_message.GetRichTextLength() != 0, 0);
+ m_btnOk.Enable(m_message.GetRichTextLength() != 0);
+
+ // Typing support for GCW_PRIVMESS sessions
+ if (m_si == nullptr || m_si->iType == GCW_PRIVMESS) {
+ if (!(GetKeyState(VK_CONTROL) & 0x8000)) {
+ m_nLastTyping = GetTickCount();
+ if (GetWindowTextLength(m_message.GetHwnd())) {
+ if (m_nTypeMode == PROTOTYPE_SELFTYPING_OFF) {
+ if (!(m_dwFlags & MWF_INITMODE))
+ DM_NotifyTyping(PROTOTYPE_SELFTYPING_ON);
+ }
}
+ else if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON)
+ DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
}
- else if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON)
- DM_NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// resizer proc for the "new" layout.
-int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc)
+int CMsgDialog::Resizer(UTILRESIZECONTROL *urc)
{
int panelHeight = m_pPanel.getHeight() + 1;
-
+
+ bool bNick = false;
bool bInfoPanel = m_pPanel.isActive();
bool bErrorState = (m_dwFlags & MWF_ERRORSTATE) != 0;
bool bShowToolbar = (m_pContainer->m_dwFlags & CNT_HIDETOOLBAR) == 0;
bool bBottomToolbar = (m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR) != 0;
+ int iSplitterX = m_pContainer->m_pSettings->iSplitterX;
+
RECT rc, rcButton;
GetClientRect(m_log.GetHwnd(), &rc);
GetClientRect(GetDlgItem(m_hwnd, IDC_PROTOCOL), &rcButton);
+ if (m_bIsAutosizingInput)
+ Utils::showDlgControl(m_hwnd, IDC_SPLITTERY, SW_HIDE);
+
if (m_panelStatusCX == 0)
m_panelStatusCX = 80;
+ if (m_si) {
+ if (m_si->iType != GCW_SERVER) {
+ m_nickList.Show(m_bNicklistEnabled);
+ Utils::showDlgControl(m_hwnd, IDC_SPLITTERX, m_bNicklistEnabled ? SW_SHOW : SW_HIDE);
+
+ m_btnNickList.Enable(true);
+ m_btnFilter.Enable(true);
+ if (m_si->iType == GCW_CHATROOM)
+ m_btnChannelMgr.Enable(m_si->pMI->bChanMgr);
+ }
+ else {
+ m_nickList.Hide();
+ Utils::showDlgControl(m_hwnd, IDC_SPLITTERX, SW_HIDE);
+ }
+
+ if (m_si->iType == GCW_SERVER) {
+ m_btnNickList.Enable(false);
+ m_btnFilter.Enable(false);
+ m_btnChannelMgr.Enable(false);
+ }
+
+ bNick = m_si->iType != GCW_SERVER && m_bNicklistEnabled;
+ }
+
switch (urc->wId) {
case IDC_PANELSPLITTER:
urc->rcItem.bottom = panelHeight;
@@ -1309,6 +1345,27 @@ int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc) return RD_ANCHORX_WIDTH | RD_ANCHORY_TOP;
case IDC_SRMM_LOG:
+ if (isChat()) {
+ urc->rcItem.top = 0;
+ urc->rcItem.left = 0;
+ urc->rcItem.right = bNick ? urc->dlgNewSize.cx - iSplitterX : urc->dlgNewSize.cx;
+ urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY;
+ if (!bShowToolbar || bBottomToolbar)
+ urc->rcItem.bottom += DPISCALEY_S(21);
+ if (bInfoPanel)
+ urc->rcItem.top += panelHeight;
+ if (CSkin::m_skinEnabled) {
+ CSkinItem *item = &SkinItems[ID_EXTBKHISTORY];
+ if (!item->IGNORED) {
+ urc->rcItem.left += item->MARGIN_LEFT;
+ urc->rcItem.right -= item->MARGIN_RIGHT;
+ urc->rcItem.top += item->MARGIN_TOP;
+ urc->rcItem.bottom -= item->MARGIN_BOTTOM;
+ }
+ }
+ return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM;
+ }
+
if (m_dwFlags & MWF_ERRORSTATE)
urc->rcItem.bottom -= ERRORPANEL_HEIGHT;
if (m_dwFlagsEx & MWF_SHOW_SCROLLINGDISABLED || m_bNotOnList)
@@ -1333,6 +1390,26 @@ int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc) rcLogBottom = urc->rcItem.bottom;
return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;
+ case IDC_SRMM_NICKLIST:
+ urc->rcItem.top = 0;
+ urc->rcItem.right = urc->dlgNewSize.cx;
+ urc->rcItem.left = urc->dlgNewSize.cx - iSplitterX + 2;
+ urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY;
+ if (!bShowToolbar || bBottomToolbar)
+ urc->rcItem.bottom += DPISCALEY_S(21);
+ if (bInfoPanel)
+ urc->rcItem.top += panelHeight;
+ if (CSkin::m_skinEnabled) {
+ CSkinItem *item = &SkinItems[ID_EXTBKUSERLIST];
+ if (!item->IGNORED) {
+ urc->rcItem.left += item->MARGIN_LEFT;
+ urc->rcItem.right -= item->MARGIN_RIGHT;
+ urc->rcItem.top += item->MARGIN_TOP;
+ urc->rcItem.bottom -= item->MARGIN_BOTTOM;
+ }
+ }
+ return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM;
+
case IDC_CONTACTPIC:
GetClientRect(m_message.GetHwnd(), &rc);
urc->rcItem.top -= m_iSplitterY - m_originalSplitterY;
@@ -1357,10 +1434,28 @@ int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc) return RD_ANCHORX_RIGHT | RD_ANCHORY_BOTTOM;
+ case IDC_SPLITTERX:
+ urc->rcItem.right = urc->dlgNewSize.cx - iSplitterX + 2;
+ urc->rcItem.left = urc->dlgNewSize.cx - iSplitterX;
+ urc->rcItem.bottom = urc->dlgNewSize.cy - m_iSplitterY;
+ if (!bShowToolbar || bBottomToolbar)
+ urc->rcItem.bottom += DPISCALEY_S(21);
+ urc->rcItem.top = 0;
+ if (bInfoPanel)
+ urc->rcItem.top += panelHeight;
+ return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM;
+
case IDC_SPLITTERY:
urc->rcItem.right = urc->dlgNewSize.cx;
+ urc->rcItem.bottom = urc->rcItem.top + DPISCALEY_S(2);
+ if (isChat()) {
+ urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + DPISCALEY_S(23);
+ urc->rcItem.left = 0;
+ urc->rcItem.bottom++;
+ urc->rcItem.top++;
+ return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM;
+ }
urc->rcItem.top -= m_iSplitterY - m_originalSplitterY;
- urc->rcItem.bottom = urc->rcItem.top + 2;
OffsetRect(&urc->rcItem, 0, 1);
urc->rcItem.left = 0;
@@ -1372,7 +1467,14 @@ int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc) urc->rcItem.right = urc->dlgNewSize.cx;
if (m_bShowAvatar)
urc->rcItem.right -= m_pic.cx + 2;
- urc->rcItem.top -= m_iSplitterY - m_originalSplitterY;
+ if (isChat()) {
+ urc->rcItem.bottom = urc->dlgNewSize.cy;
+ urc->rcItem.top = urc->dlgNewSize.cy - m_iSplitterY + 3 + DPISCALEY_S(23);
+ }
+ else {
+ urc->rcItem.top -= m_iSplitterY - m_originalSplitterY;
+ }
+
if (bBottomToolbar && bShowToolbar)
urc->rcItem.bottom -= DPISCALEY_S(22);
@@ -1389,6 +1491,8 @@ int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc) urc->rcItem.bottom -= item->MARGIN_BOTTOM;
}
}
+ if (isChat())
+ return RD_ANCHORX_CUSTOM | RD_ANCHORY_CUSTOM;
return RD_ANCHORX_CUSTOM | RD_ANCHORY_BOTTOM;
case IDC_MULTISPLITTER:
@@ -1465,7 +1569,7 @@ int CSrmmWindow::Resizer(UTILRESIZECONTROL *urc) /////////////////////////////////////////////////////////////////////////////////////////
// message filter
-int CSrmmWindow::OnFilter(MSGFILTER *pFilter)
+int CMsgDialog::OnFilter(MSGFILTER *pFilter)
{
RECT rc;
POINT pt;
@@ -1486,11 +1590,25 @@ int CSrmmWindow::OnFilter(MSGFILTER *pFilter) if ((msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN) && !(GetKeyState(VK_RMENU) & 0x8000)) {
MSG message = { m_hwnd, msg, wp, lp };
- LRESULT mim_hotkey_check = Hotkey_Check(&message, TABSRMM_HK_SECTION_IM);
+ LRESULT mim_hotkey_check = Hotkey_Check(&message, isChat() ? TABSRMM_HK_SECTION_GC : TABSRMM_HK_SECTION_IM);
if (mim_hotkey_check)
m_bkeyProcessed = true;
switch (mim_hotkey_check) {
+ case TABSRMM_HK_CHANNELMGR:
+ onClick_ChanMgr(&m_btnChannelMgr);
+ return _dlgReturn(m_hwnd, 1);
+ case TABSRMM_HK_FILTERTOGGLE:
+ onClick_Filter(&m_btnFilter);
+ InvalidateRect(m_btnFilter.GetHwnd(), nullptr, TRUE);
+ return _dlgReturn(m_hwnd, 1);
+ case TABSRMM_HK_LISTTOGGLE:
+ onClick_ShowNickList(&m_btnNickList);
+ return _dlgReturn(m_hwnd, 1);
+ case TABSRMM_HK_MUC_SHOWSERVER:
+ if (m_si->iType != GCW_SERVER)
+ Chat_DoEventHook(m_si, GC_USER_MESSAGE, nullptr, L"/servershow", 0);
+ return _dlgReturn(m_hwnd, 1);
case TABSRMM_HK_SETUSERPREFS:
CallService(MS_TABMSG_SETUSERPREFS, m_hContact, 0);
return _dlgReturn(m_hwnd, 1);
@@ -1817,7 +1935,7 @@ int CSrmmWindow::OnFilter(MSGFILTER *pFilter) /////////////////////////////////////////////////////////////////////////////////////////
-LRESULT CSrmmWindow::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam)
+LRESULT CMsgDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam)
{
bool isCtrl, isShift, isAlt;
@@ -1841,6 +1959,44 @@ LRESULT CSrmmWindow::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) m_btnQuote.Click();
break;
+ case WM_LBUTTONUP:
+ if (isChat() && g_Settings.bClickableNicks) {
+ POINT pt = { LOWORD(lParam), HIWORD(lParam) };
+ CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE);
+ }
+ if (M.GetByte("autocopy", 1)) {
+ CHARRANGE sel;
+ SendMessage(m_log.GetHwnd(), EM_EXGETSEL, 0, (LPARAM)& sel);
+ if (sel.cpMin != sel.cpMax) {
+ SendMessage(m_log.GetHwnd(), WM_COPY, 0, 0);
+ sel.cpMin = sel.cpMax;
+ SendMessage(m_log.GetHwnd(), EM_EXSETSEL, 0, (LPARAM)& sel);
+ SetFocus(m_message.GetHwnd());
+ }
+ }
+ break;
+
+ case WM_LBUTTONDOWN:
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDOWN:
+ case WM_RBUTTONDBLCLK:
+ if (isChat() && g_Settings.bClickableNicks) {
+ POINT pt = { LOWORD(lParam), HIWORD(lParam) };
+ CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, TRUE);
+ }
+ break;
+
+ case WM_SETCURSOR:
+ if (g_Settings.bClickableNicks && isChat() && (LOWORD(lParam) == HTCLIENT)) {
+ POINT pt;
+ GetCursorPos(&pt);
+ ScreenToClient(m_log.GetHwnd(), &pt);
+ if (CheckCustomLink(m_log.GetHwnd(), &pt, msg, wParam, lParam, FALSE))
+ return TRUE;
+ }
+ break;
+
case WM_SYSKEYUP:
if (wParam == VK_MENU) {
ProcessHotkeysByMsgFilter(m_log, msg, wParam, lParam);
@@ -1867,6 +2023,12 @@ LRESULT CSrmmWindow::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) KbdState(isShift, isCtrl, isAlt);
if (wParam == VK_INSERT && isCtrl)
return WMCopyHandler(msg, wParam, lParam);
+
+ if (wParam == 0x57 && isCtrl) { // ctrl-w (close window)
+ PostMessage(m_hwnd, WM_CLOSE, 0, 1);
+ return TRUE;
+ }
+
break;
case WM_COPY:
@@ -1901,7 +2063,7 @@ LRESULT CSrmmWindow::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) /////////////////////////////////////////////////////////////////////////////////////////
-LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
+LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
{
bool isCtrl, isShift, isAlt;
@@ -1957,6 +2119,8 @@ LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) case WM_MOUSEWHEEL:
if (DM_MouseWheelHandler(wParam, lParam) == 0)
return 0;
+
+ m_iLastEnterTime = 0;
break;
case EM_PASTESPECIAL:
@@ -1993,6 +2157,11 @@ LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) if (wParam == VK_CAPITAL || wParam == VK_NUMLOCK)
m_message.OnChange(&m_message);
+ if (wParam != VK_RIGHT && wParam != VK_LEFT) {
+ replaceStrW(m_wszSearchQuery, nullptr);
+ replaceStrW(m_wszSearchResult, nullptr);
+ }
+
if (wParam == VK_RETURN) {
if (m_bEditNotesActive)
break;
@@ -2108,7 +2277,7 @@ LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) break;
case WM_ERASEBKGND:
- return(CSkin::m_skinEnabled ? 0 : 1);
+ return !CSkin::m_skinEnabled;
// sent by smileyadd when the smiley selection window dies
// just grab the focus :)
@@ -2118,18 +2287,76 @@ LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) case WM_CONTEXTMENU:
POINT pt;
- if (lParam == 0xFFFFFFFF) {
- CHARRANGE sel;
- m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)&sel);
- m_message.SendMsg(EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)sel.cpMax);
- ClientToScreen(m_message.GetHwnd(), &pt);
+ if (isChat()) {
+ GetCursorPos(&pt);
+
+ HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT));
+ HMENU hSubMenu = GetSubMenu(hMenu, 2);
+ RemoveMenu(hSubMenu, 9, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 8, MF_BYPOSITION);
+ RemoveMenu(hSubMenu, 4, MF_BYPOSITION);
+
+ EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | (m_si->pMI->bBold ? MF_ENABLED : MF_GRAYED));
+ TranslateMenu(hSubMenu);
+
+ CHARRANGE sel, all = { 0, -1 };
+ m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)& sel);
+ if (sel.cpMin == sel.cpMax) {
+ EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(hSubMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED);
+ }
+
+ MessageWindowPopupData mwpd = { sizeof(mwpd) };
+ mwpd.uType = MSG_WINDOWPOPUP_SHOWING;
+ mwpd.uFlags = MSG_WINDOWPOPUP_INPUT;
+ mwpd.hContact = m_hContact;
+ mwpd.hwnd = m_message.GetHwnd();
+ mwpd.hMenu = hSubMenu;
+ mwpd.pt = pt;
+ NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)& mwpd);
+
+ int iSelection = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr);
+
+ mwpd.selection = iSelection;
+ mwpd.uType = MSG_WINDOWPOPUP_SELECTED;
+ NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)& mwpd);
+
+ switch (iSelection) {
+ case IDM_COPY:
+ m_message.SendMsg(WM_COPY, 0, 0);
+ break;
+ case IDM_CUT:
+ m_message.SendMsg(WM_CUT, 0, 0);
+ break;
+ case IDM_PASTE:
+ case IDM_PASTEFORMATTED:
+ m_message.SendMsg(EM_PASTESPECIAL, (iSelection == IDM_PASTE) ? CF_UNICODETEXT : 0, 0);
+ break;
+ case IDM_COPYALL:
+ m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)& all);
+ m_message.SendMsg(WM_COPY, 0, 0);
+ m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)& sel);
+ break;
+ case IDM_SELECTALL:
+ m_message.SendMsg(EM_EXSETSEL, 0, (LPARAM)& all);
+ break;
+ }
+ DestroyMenu(hMenu);
}
else {
- pt.x = GET_X_LPARAM(lParam);
- pt.y = GET_Y_LPARAM(lParam);
- }
+ if (lParam == 0xFFFFFFFF) {
+ CHARRANGE sel;
+ m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)& sel);
+ m_message.SendMsg(EM_POSFROMCHAR, (WPARAM)& pt, (LPARAM)sel.cpMax);
+ ClientToScreen(m_message.GetHwnd(), &pt);
+ }
+ else {
+ pt.x = GET_X_LPARAM(lParam);
+ pt.y = GET_Y_LPARAM(lParam);
+ }
- ShowPopupMenu(m_message, pt);
+ ShowPopupMenu(m_message, pt);
+ }
return TRUE;
}
@@ -2139,7 +2366,7 @@ LRESULT CSrmmWindow::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) /////////////////////////////////////////////////////////////////////////////////////////
// dialog procedure
-INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
POINT pt, tmp, cur;
RECT rc;
@@ -2170,15 +2397,15 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) bool bAero = M.isAero();
if (CSkin::m_skinEnabled) {
- UINT item_ids[2] = { ID_EXTBKHISTORY, ID_EXTBKINPUTAREA };
- UINT ctl_ids[2] = { IDC_SRMM_LOG, IDC_SRMM_MESSAGE };
+ UINT item_ids[] = { ID_EXTBKUSERLIST, ID_EXTBKHISTORY, ID_EXTBKINPUTAREA };
+ UINT ctl_ids[] = { IDC_SRMM_NICKLIST, IDC_SRMM_LOG, IDC_SRMM_MESSAGE };
BOOL isEditNotesReason = m_bEditNotesActive;
BOOL isSendLaterReason = (m_sendMode & SMODE_SENDLATER);
BOOL isMultipleReason = (m_sendMode & SMODE_MULTIPLE || m_sendMode & SMODE_CONTAINER);
CSkin::SkinDrawBG(m_hwnd, m_pContainer->m_hwnd, m_pContainer, &rcClient, hdcMem);
- for (int i = 0; i < 2; i++) {
+ for (int i = 0; i < _countof(item_ids); i++) {
CSkinItem *item = &SkinItems[item_ids[i]];
if (!item->IGNORED) {
GetWindowRect(GetDlgItem(m_hwnd, ctl_ids[i]), &rcWindow);
@@ -2245,6 +2472,9 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) return 0;
case WM_SIZE:
+ if (wParam == SIZE_MAXIMIZED)
+ ScrollToBottom();
+
if (!IsIconic(m_hwnd)) {
if (m_ipFieldHeight == 0)
m_ipFieldHeight = CInfoPanel::m_ipConfig.height2;
@@ -2259,11 +2489,13 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) LoadSplitter();
}
- HBITMAP hbm = ((m_pPanel.isActive()) && m_pContainer->m_avatarMode != 3) ? m_hOwnPic : (m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown);
- if (hbm != nullptr) {
- BITMAP bminfo;
- GetObject(hbm, sizeof(bminfo), &bminfo);
- CalcDynamicAvatarSize(&bminfo);
+ if (m_si == nullptr) {
+ HBITMAP hbm = ((m_pPanel.isActive()) && m_pContainer->m_avatarMode != 3) ? m_hOwnPic : (m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown);
+ if (hbm != nullptr) {
+ BITMAP bminfo;
+ GetObject(hbm, sizeof(bminfo), &bminfo);
+ CalcDynamicAvatarSize(&bminfo);
+ }
}
GetClientRect(m_hwnd, &rc);
@@ -2277,7 +2509,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) LONG cx = rc.right;
LONG panelHeight = m_pPanel.getHeight();
- hbm = (m_pContainer->m_avatarMode == 3) ? m_hOwnPic : (m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown);
+ HBITMAP hbm = (m_pContainer->m_avatarMode == 3) ? m_hOwnPic : (m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown);
double dHeight = 0, dWidth = 0;
Utils::scaleAvatarHeightLimited(hbm, dWidth, dHeight, panelHeight - 2);
m_iPanelAvatarX = (int)dWidth;
@@ -2340,7 +2572,10 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) return 0;
case WM_TIMECHANGE:
- DM_OptionsApplied(0, 0);
+ if (isChat())
+ RedrawLog();
+ else
+ DM_OptionsApplied(0, 0);
break;
case WM_NOTIFY:
@@ -2362,12 +2597,105 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case EN_REQUESTRESIZE:
DM_HandleAutoSizeRequest((REQRESIZE *)lParam);
break;
+
+ case EN_LINK:
+ if (((LPNMHDR)lParam)->idFrom == IDC_SRMM_LOG) {
+ switch (((ENLINK *)lParam)->msg) {
+ case WM_RBUTTONDOWN:
+ case WM_LBUTTONUP:
+ case WM_LBUTTONDBLCLK:
+ CHARRANGE sel;
+ SendMessage(((LPNMHDR)lParam)->hwndFrom, EM_EXGETSEL, 0, (LPARAM)& sel);
+ if (sel.cpMin == sel.cpMax) {
+ UINT msg = ((ENLINK *)lParam)->msg;
+ m_pContainer->m_pMenuBar->Cancel();
+
+ TEXTRANGE tr;
+ tr.lpstrText = nullptr;
+ tr.chrg = ((ENLINK *)lParam)->chrg;
+ tr.lpstrText = (wchar_t *)mir_alloc(sizeof(wchar_t) * (tr.chrg.cpMax - tr.chrg.cpMin + 2));
+ SendMessage(((LPNMHDR)lParam)->hwndFrom, EM_GETTEXTRANGE, 0, (LPARAM)& tr);
+
+ BOOL isLink = IsStringValidLink(tr.lpstrText);
+ if (isLink) // handled by core
+ break;
+
+ // clicked a nick name
+ if (g_Settings.bClickableNicks) {
+ if (msg == WM_RBUTTONDOWN) {
+ for (auto &ui : m_si->getUserList()) {
+ if (mir_wstrcmp(ui->pszNick, tr.lpstrText))
+ continue;
+
+ pt.x = (short)LOWORD(((ENLINK *)lParam)->lParam);
+ pt.y = (short)HIWORD(((ENLINK *)lParam)->lParam);
+ ClientToScreen(((NMHDR *)lParam)->hwndFrom, &pt);
+ RunUserMenu(m_hwnd, ui, pt);
+ break;
+ }
+ return TRUE;
+ }
+
+ if (msg == WM_LBUTTONUP) {
+ CHARRANGE chr;
+ m_message.SendMsg(EM_EXGETSEL, 0, (LPARAM)& chr);
+
+ wchar_t tszAplTmpl[] = L"%s:";
+ size_t bufSize = mir_wstrlen(tr.lpstrText) + mir_wstrlen(tszAplTmpl) + 3;
+ wchar_t *tszTmp = (wchar_t *)mir_alloc(bufSize * sizeof(wchar_t)), *tszAppeal = tszTmp;
+
+ TEXTRANGE tr2;
+ tr2.lpstrText = (LPTSTR)mir_alloc(sizeof(wchar_t) * 2);
+ if (chr.cpMin) {
+ // prepend nick with space if needed
+ tr2.chrg.cpMin = chr.cpMin - 1;
+ tr2.chrg.cpMax = chr.cpMin;
+ m_message.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)& tr2);
+ if (!iswspace(*tr2.lpstrText))
+ *tszTmp++ = ' ';
+ mir_wstrcpy(tszTmp, tr.lpstrText);
+ }
+ else // in the beginning of the message window
+ mir_snwprintf(tszAppeal, bufSize, tszAplTmpl, tr.lpstrText);
+
+ size_t st = mir_wstrlen(tszAppeal);
+ if (chr.cpMax != -1) {
+ tr2.chrg.cpMin = chr.cpMax;
+ tr2.chrg.cpMax = chr.cpMax + 1;
+ // if there is no space after selection,
+ // or there is nothing after selection at all...
+ if (!m_message.SendMsg(EM_GETTEXTRANGE, 0, (LPARAM)& tr2) || !iswspace(*tr2.lpstrText)) {
+ tszAppeal[st++] = ' ';
+ tszAppeal[st++] = '\0';
+ }
+ }
+ else {
+ tszAppeal[st++] = ' ';
+ tszAppeal[st++] = '\0';
+ }
+ m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)tszAppeal);
+ mir_free((void *)tr2.lpstrText);
+ mir_free((void *)tszAppeal);
+ }
+ }
+ SetFocus(m_message.GetHwnd());
+ mir_free(tr.lpstrText);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
}
}
break;
+ case WM_CTLCOLORLISTBOX:
+ SetBkColor((HDC)wParam, g_Settings.crUserListBGColor);
+ return (INT_PTR)g_chatApi.hListBkgBrush;
+
case DM_TYPING:
- {
+ if (m_si == nullptr || m_si->iType == GCW_PRIVMESS) {
int preTyping = m_nTypeSecs != 0;
m_nTypeSecs = (int)lParam > 0 ? (int)lParam : 0;
@@ -2438,18 +2766,33 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) GetMyNick();
return 0;
+ case WM_KEYDOWN:
+ SetFocus(m_message.GetHwnd());
+ break;
+
case WM_SETFOCUS:
- MsgWindowUpdateState(WM_SETFOCUS);
+ if (CMimAPI::m_shutDown)
+ break;
+
+ if (isChat())
+ UpdateWindowState(WM_SETFOCUS);
+ else
+ MsgWindowUpdateState(WM_SETFOCUS);
SetFocus(m_message.GetHwnd());
return 1;
case WM_ACTIVATE:
- if (LOWORD(wParam) != WA_ACTIVE)
+ if (LOWORD(wParam) != WA_ACTIVE) {
+ m_pContainer->m_hwndSaved = nullptr;
break;
+ }
__fallthrough;
case WM_MOUSEACTIVATE:
- MsgWindowUpdateState(WM_ACTIVATE);
+ if (isChat())
+ UpdateWindowState(WM_ACTIVATE);
+ else
+ MsgWindowUpdateState(WM_ACTIVATE);
return 1;
case DM_UPDATEPICLAYOUT:
@@ -2474,7 +2817,20 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) m_iMultiSplit = oldSplitterX;
Resize();
}
- else if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERY)) {
+ else if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERX)) {
+ GetClientRect(m_hwnd, &rc);
+ pt.x = wParam, pt.y = 0;
+ ScreenToClient(m_hwnd, &pt);
+
+ int iSplitterX = rc.right - pt.x + 1;
+ if (iSplitterX < 35)
+ iSplitterX = 35;
+ if (iSplitterX > rc.right - rc.left - 35)
+ iSplitterX = rc.right - rc.left - 35;
+ m_pContainer->m_pSettings->iSplitterX = iSplitterX;
+ Resize();
+ }
+ else if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERY) || lParam == -1) {
GetClientRect(m_hwnd, &rc);
rc.top += (m_pPanel.isActive() ? m_pPanel.getHeight() + 40 : 30);
pt.x = 0;
@@ -2622,7 +2978,8 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) break;
}
else if (wParam == TIMERID_TYPE) {
- DM_Typing(false);
+ if (m_si == nullptr || m_si->iType == GCW_PRIVMESS)
+ DM_Typing(false);
break;
}
break;
@@ -2752,22 +3109,124 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_MEASUREITEM:
{
- LPMEASUREITEMSTRUCT lpmi = (LPMEASUREITEMSTRUCT)lParam;
- if (m_pPanel.isHovered()) {
- lpmi->itemHeight = 0;
- lpmi->itemWidth = 6;
+ MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
+ if (mis->CtlType == ODT_MENU) {
+ if (m_pPanel.isHovered()) {
+ mis->itemHeight = 0;
+ mis->itemWidth = 6;
+ return TRUE;
+ }
+ return Menu_MeasureItem(lParam);
+ }
+ mis->itemHeight = g_Settings.iNickListFontHeight;
+ }
+ return TRUE;
+
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
+ if (dis->CtlType == ODT_MENU) {
+ if (m_pPanel.isHovered()) {
+ DrawMenuItem(dis, (HICON)dis->itemData, 0);
+ return TRUE;
+ }
+ return Menu_DrawItem(lParam);
+ }
+
+ if (dis->CtlID == IDC_SRMM_NICKLIST) {
+ int x_offset = 0;
+ int index = dis->itemID;
+
+ USERINFO *ui = g_chatApi.UM_FindUserFromIndex(m_si, index);
+ if (ui == nullptr)
+ return TRUE;
+
+ int height = dis->rcItem.bottom - dis->rcItem.top;
+ if (height & 1)
+ height++;
+ int offset = (height == 10) ? 0 : height / 2;
+
+ HICON hIcon = g_chatApi.SM_GetStatusIcon(m_si, ui);
+ HFONT hFont = g_Settings.UserListFonts[ui->iStatusEx];
+ HFONT hOldFont = (HFONT)SelectObject(dis->hDC, hFont);
+ SetBkMode(dis->hDC, TRANSPARENT);
+
+ int nickIndex = 0;
+ for (int i = 0; i < STATUSICONCOUNT; i++) {
+ if (hIcon == g_chatApi.hIcons[ICON_STATUS0 + i]) {
+ nickIndex = i;
+ break;
+ }
+ }
+
+ if (dis->itemState & ODS_SELECTED) {
+ FillRect(dis->hDC, &dis->rcItem, g_Settings.SelectionBGBrush);
+ SetTextColor(dis->hDC, g_Settings.nickColors[6]);
+ }
+ else {
+ FillRect(dis->hDC, &dis->rcItem, g_chatApi.hListBkgBrush);
+ if (g_Settings.bColorizeNicks && nickIndex != 0)
+ SetTextColor(dis->hDC, g_Settings.nickColors[nickIndex - 1]);
+ else
+ SetTextColor(dis->hDC, g_Settings.UserListColors[ui->iStatusEx]);
+ }
+ x_offset = 2;
+
+ if (g_Settings.bShowContactStatus && g_Settings.bContactStatusFirst && ui->ContactStatus) {
+ HICON icon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus);
+ DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 8, icon, 16, 16, 0, nullptr, DI_NORMAL);
+ IcoLib_ReleaseIcon(icon);
+ x_offset += 18;
+ }
+
+ if (g_Settings.bClassicIndicators) {
+ char szTemp[3];
+ szTemp[1] = 0;
+ szTemp[0] = szIndicators[nickIndex];
+ if (szTemp[0]) {
+ SIZE szUmode;
+ GetTextExtentPoint32A(dis->hDC, szTemp, 1, &szUmode);
+ TextOutA(dis->hDC, x_offset, dis->rcItem.top, szTemp, 1);
+ x_offset += szUmode.cx + 2;
+ }
+ else x_offset += 8;
+ }
+ else {
+ DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 5, hIcon, 10, 10, 0, nullptr, DI_NORMAL);
+ x_offset += 12;
+ }
+
+ if (g_Settings.bShowContactStatus && !g_Settings.bContactStatusFirst && ui->ContactStatus) {
+ HICON icon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus);
+ DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 8, icon, 16, 16, 0, nullptr, DI_NORMAL);
+ IcoLib_ReleaseIcon(icon);
+ x_offset += 18;
+ }
+
+ SIZE sz;
+ if (m_iSearchItem != -1 && m_iSearchItem == index && m_wszSearch[0]) {
+ COLORREF clr_orig = GetTextColor(dis->hDC);
+ GetTextExtentPoint32(dis->hDC, ui->pszNick, (int)mir_wstrlen(m_wszSearch), &sz);
+ SetTextColor(dis->hDC, RGB(250, 250, 0));
+ TextOut(dis->hDC, x_offset, (dis->rcItem.top + dis->rcItem.bottom - sz.cy) / 2, ui->pszNick, (int)mir_wstrlen(m_wszSearch));
+ SetTextColor(dis->hDC, clr_orig);
+ x_offset += sz.cx;
+ TextOut(dis->hDC, x_offset, (dis->rcItem.top + dis->rcItem.bottom - sz.cy) / 2, ui->pszNick + mir_wstrlen(m_wszSearch), int(mir_wstrlen(ui->pszNick) - mir_wstrlen(m_wszSearch)));
+ }
+ else {
+ GetTextExtentPoint32(dis->hDC, ui->pszNick, (int)mir_wstrlen(ui->pszNick), &sz);
+ TextOut(dis->hDC, x_offset, (dis->rcItem.top + dis->rcItem.bottom - sz.cy) / 2, ui->pszNick, (int)mir_wstrlen(ui->pszNick));
+ SelectObject(dis->hDC, hOldFont);
+ }
return TRUE;
}
}
- return Menu_MeasureItem(lParam);
+ break;
case WM_NCHITTEST:
SendMessage(m_pContainer->m_hwnd, WM_NCHITTEST, wParam, lParam);
break;
- case WM_DRAWITEM:
- return MsgWindowDrawHandler((DRAWITEMSTRUCT*)lParam);
-
case WM_APPCOMMAND:
{
DWORD cmd = GET_APPCOMMAND_LPARAM(lParam);
@@ -2819,7 +3278,10 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) break;
case DM_SMILEYOPTIONSCHANGED:
- SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
+ if (isChat())
+ RedrawLog();
+ else
+ SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
break;
case DM_MYAVATARCHANGED:
@@ -2982,6 +3444,119 @@ INT_PTR CSrmmWindow::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) case DM_CHECKINFOTIP:
m_pPanel.hideTip(reinterpret_cast<HWND>(lParam));
return 0;
+
+ case DM_SETINFOPANEL: // broadcasted when global info panel setting changes
+ if (wParam == 0 && lParam == 0) {
+ m_pPanel.getVisibility();
+ m_pPanel.loadHeight();
+ m_pPanel.showHide();
+ }
+ else {
+ CMsgDialog *srcDat = (CMsgDialog *)wParam;
+ if (lParam == 0)
+ m_pPanel.loadHeight();
+ else {
+ if (srcDat && lParam && this != srcDat && !m_pPanel.isPrivateHeight()) {
+ if (srcDat->isChat() != isChat() && M.GetByte("syncAllPanels", 0) == 0)
+ return 0;
+
+ if (m_pContainer->m_pSettings->fPrivate && srcDat->m_pContainer != m_pContainer)
+ return 0;
+
+ m_pPanel.setHeight((LONG)lParam);
+ }
+ }
+ Resize();
+ }
+ return 0;
+
+ case DM_STATUSICONCHANGE:
+ m_pContainer->InitRedraw();
+ return 0;
+
+ case DM_ACTIVATEME: // the child window will activate itself
+ ActivateExistingTab(m_pContainer, m_hwnd);
+ return 0;
+
+ case DM_QUERYCONTAINER: // container API support functions
+ if (lParam)
+ *(TContainerData **)lParam = m_pContainer;
+ return 0;
+
+ case DM_QUERYHCONTACT:
+ if (lParam)
+ *(MCONTACT *)lParam = m_hContact;
+ return 0;
+
+ case DM_CHECKSIZE:
+ m_dwFlags |= MWF_NEEDCHECKSIZE;
+ return 0;
+
+ case DM_CONTAINERSELECTED:
+ // sent by the select container dialog box when a container was selected...
+ // lParam = (wchar_t*)selected name...
+ {
+ wchar_t *szNewName = (wchar_t *)lParam;
+ if (!mir_wstrcmp(szNewName, TranslateT("Default container")))
+ szNewName = CGlobals::m_default_container_name;
+
+ int iOldItems = TabCtrl_GetItemCount(m_hwndParent);
+ if (!wcsncmp(m_pContainer->m_wszName, szNewName, CONTAINER_NAMELEN))
+ break;
+
+ TContainerData *pNewContainer = FindContainerByName(szNewName);
+ if (pNewContainer == nullptr)
+ if ((pNewContainer = CreateContainer(szNewName, FALSE, m_hContact)) == nullptr)
+ break;
+
+ db_set_ws(m_hContact, SRMSGMOD_T, "containerW", szNewName);
+ PostMessage(PluginConfig.g_hwndHotkeyHandler, DM_DOCREATETAB, (WPARAM)pNewContainer, m_hContact);
+ if (iOldItems > 1) // there were more than 1 tab, container is still valid
+ SendMessage(m_pContainer->m_hwndActive, WM_SIZE, 0, 0);
+ SetForegroundWindow(pNewContainer->m_hwnd);
+ SetActiveWindow(pNewContainer->m_hwnd);
+ }
+ return 0;
+
+ case DM_ACTIVATETOOLTIP:
+ // show the balloon tooltip control.
+ // wParam == id of the "anchor" element, defaults to the panel status field (for away msg retrieval)
+ // lParam == new text to show
+ if (!IsIconic(m_pContainer->m_hwnd) && m_pContainer->m_hwndActive == m_hwnd)
+ m_pPanel.showTip(wParam, lParam);
+ return 0;
+
+ case DM_STATUSBARCHANGED:
+ tabUpdateStatusBar();
+ break;
+
+ case DM_CHECKAUTOHIDE:
+ // This is broadcasted by the container to all child windows to check if the
+ // container can be autohidden or -closed.
+ //
+ // wParam is the autohide timeout (in seconds)
+ // lParam points to a BOOL and a session which wants to prevent auto-hiding
+ // the container must set it to FALSE.
+ //
+ // If no session in the container disagrees, the container will be hidden.
+
+ if (lParam) {
+ BOOL *fResult = (BOOL *)lParam;
+ // text entered in the input area -> prevent autohide/cose
+ if (GetWindowTextLength(m_message.GetHwnd()) > 0)
+ *fResult = FALSE;
+ // unread events, do not hide or close the container
+ else if (m_dwUnread)
+ *fResult = FALSE;
+ // time since last activity did not yet reach the threshold.
+ else if (((GetTickCount() - m_dwLastActivity) / 1000) <= wParam)
+ *fResult = FALSE;
+ }
+ return 0;
+
+ case DM_SPLITTERGLOBALEVENT:
+ DM_SplitterGlobalEvent(wParam, lParam);
+ return 0;
}
return CSuper::DlgProc(uMsg, wParam, lParam);
diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp new file mode 100644 index 0000000000..7a24071d4d --- /dev/null +++ b/plugins/TabSRMM/src/msgdlgother.cpp @@ -0,0 +1,1986 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Miranda NG: the free IM client for Microsoft* Windows* +// +// Copyright (C) 2012-19 Miranda NG team, +// Copyright (c) 2000-09 Miranda ICQ/IM project, +// all portions of this codebase are copyrighted to the people +// listed in contributors.txt. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// you should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// part of tabSRMM messaging plugin for Miranda. +// +// (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors +// +// Helper functions for the message dialog. + +#include "stdafx.h" + +UINT_PTR CALLBACK OpenFileSubclass(HWND hwnd, UINT msg, WPARAM, LPARAM lParam); + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::AddLog() +{ + if (PluginConfig.m_bUseDividers) { + if (PluginConfig.m_bDividersUsePopupConfig) { + if (!MessageWindowOpened(0, m_hwnd)) + DM_AddDivider(); + } + else { + bool bInactive = !IsActive(); + if (bInactive) + DM_AddDivider(); + else if (m_pContainer->m_hwndActive != m_hwnd) + DM_AddDivider(); + } + } + + CSrmmBaseDialog::AddLog(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::AdjustBottomAvatarDisplay() +{ + GetAvatarVisibility(); + + bool bInfoPanel = m_pPanel.isActive(); + HBITMAP hbm = (bInfoPanel && m_pContainer->m_avatarMode != 3) ? m_hOwnPic : (m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown); + if (hbm) { + if (m_dynaSplitter == 0 || m_iSplitterY == 0) + LoadSplitter(); + m_dynaSplitter = m_iSplitterY - DPISCALEY_S(34); + DM_RecalcPictureSize(); + Utils::showDlgControl(m_hwnd, IDC_CONTACTPIC, m_bShowAvatar ? SW_SHOW : SW_HIDE); + InvalidateRect(GetDlgItem(m_hwnd, IDC_CONTACTPIC), nullptr, TRUE); + } + else { + Utils::showDlgControl(m_hwnd, IDC_CONTACTPIC, m_bShowAvatar ? SW_SHOW : SW_HIDE); + m_pic.cy = m_pic.cx = DPISCALEY_S(60); + InvalidateRect(GetDlgItem(m_hwnd, IDC_CONTACTPIC), nullptr, TRUE); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// calculates avatar layouting, based on splitter position to find the optimal size +// for the avatar w/o disturbing the toolbar too much. + +void CMsgDialog::CalcDynamicAvatarSize(BITMAP *bminfo) +{ + if (m_dwFlags & MWF_WASBACKGROUNDCREATE || m_pContainer->m_dwFlags & CNT_DEFERREDCONFIGURE || m_pContainer->m_dwFlags & CNT_CREATE_MINIMIZED || IsIconic(m_pContainer->m_hwnd)) + return; // at this stage, the layout is not yet ready... + + RECT rc; + GetClientRect(m_hwnd, &rc); + + BOOL bBottomToolBar = m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR; + BOOL bToolBar = m_pContainer->m_dwFlags & CNT_HIDETOOLBAR ? 0 : 1; + int iSplitOffset = m_bIsAutosizingInput ? 1 : 0; + + double picAspect = (bminfo->bmWidth == 0 || bminfo->bmHeight == 0) ? 1.0 : (double)(bminfo->bmWidth / (double)bminfo->bmHeight); + double picProjectedWidth = (double)((m_dynaSplitter - ((bBottomToolBar && bToolBar) ? DPISCALEX_S(24) : 0) + ((m_bShowUIElements) ? DPISCALEX_S(28) : DPISCALEX_S(2)))) * picAspect; + + if ((rc.right - (int)picProjectedWidth) > (m_iButtonBarReallyNeeds) && !PluginConfig.m_bAlwaysFullToolbarWidth && bToolBar) + m_iRealAvatarHeight = m_dynaSplitter + 3 + (m_bShowUIElements ? DPISCALEY_S(28) : DPISCALEY_S(2)); + else + m_iRealAvatarHeight = m_dynaSplitter + DPISCALEY_S(6) + DPISCALEY_S(iSplitOffset); + + m_iRealAvatarHeight -= ((bBottomToolBar && bToolBar) ? DPISCALEY_S(22) : 0); + + if (PluginConfig.m_LimitStaticAvatarHeight > 0) + m_iRealAvatarHeight = min(m_iRealAvatarHeight, PluginConfig.m_LimitStaticAvatarHeight); + + if (M.GetByte(m_hContact, "dontscaleavatars", M.GetByte("dontscaleavatars", 0))) + m_iRealAvatarHeight = min(bminfo->bmHeight, m_iRealAvatarHeight); + + double aspect = (bminfo->bmHeight != 0) ? (double)m_iRealAvatarHeight / (double)bminfo->bmHeight : 1.0; + double newWidth = (double)bminfo->bmWidth * aspect; + if (newWidth > (double)(rc.right) * 0.8) + newWidth = (double)(rc.right) * 0.8; + m_pic.cy = m_iRealAvatarHeight + 2; + m_pic.cx = (int)newWidth + 2; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::CloseTab() +{ + int iTabs = TabCtrl_GetItemCount(m_hwndParent); + if (iTabs == 1) { + SendMessage(m_pContainer->m_hwnd, WM_CLOSE, 0, 1); + return; + } + + m_pContainer->m_iChilds--; + int i = GetTabIndexFromHWND(m_hwndParent, m_hwnd); + + // after closing a tab, we need to activate the tab to the left side of + // the previously open tab. + // normally, this tab has the same index after the deletion of the formerly active tab + // unless, of course, we closed the last (rightmost) tab. + if (!m_pContainer->m_bDontSmartClose && iTabs > 1) { + if (i == iTabs - 1) + i--; + else + i++; + TabCtrl_SetCurSel(m_hwndParent, i); + + m_pContainer->m_hwndActive = GetTabWindow(m_hwndParent, i); + + RECT rc; + SendMessage(m_pContainer->m_hwnd, DM_QUERYCLIENTAREA, 0, (LPARAM)& rc); + SetWindowPos(m_pContainer->m_hwndActive, HWND_TOP, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), SWP_SHOWWINDOW); + ShowWindow(m_pContainer->m_hwndActive, SW_SHOW); + SetForegroundWindow(m_pContainer->m_hwndActive); + SetFocus(m_pContainer->m_hwndActive); + } + + SendMessage(m_pContainer->m_hwnd, WM_SIZE, 0, 0); + DestroyWindow(m_hwnd); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// calculate the minimum required client height for the given message +// window layout +// +// the container will use this in its WM_GETMINMAXINFO handler to set +// minimum tracking height. + +void CMsgDialog::DetermineMinHeight() +{ + RECT rc; + LONG height = (m_pPanel.isActive() ? m_pPanel.getHeight() + 2 : 0); + if (!(m_pContainer->m_dwFlags & CNT_HIDETOOLBAR)) + height += DPISCALEY_S(24); // toolbar + GetClientRect(m_message.GetHwnd(), &rc); + height += rc.bottom; // input area + height += 40; // min space for log area and some padding + + m_pContainer->m_uChildMinHeight = height; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// convert rich edit code to bbcode (if wanted). Otherwise, strip all RTF formatting +// tags and return plain text + +static wchar_t tszRtfBreaks[] = L" \\\n\r"; + +static void CreateColorMap(CMStringW &Text, int iCount, COLORREF *pSrc, int *pDst) +{ + const wchar_t *pszText = Text; + int iIndex = 1; + + static const wchar_t *lpszFmt = L"\\red%[^ \x5b\\]\\green%[^ \x5b\\]\\blue%[^ \x5b;];"; + wchar_t szRed[10], szGreen[10], szBlue[10]; + + const wchar_t *p1 = wcsstr(pszText, L"\\colortbl"); + if (!p1) + return; + + const wchar_t *pEnd = wcschr(p1, '}'); + + const wchar_t *p2 = wcsstr(p1, L"\\red"); + + for (int i = 0; i < iCount; i++) + pDst[i] = -1; + + while (p2 && p2 < pEnd) { + if (swscanf(p2, lpszFmt, &szRed, &szGreen, &szBlue) > 0) { + for (int i = 0; i < iCount; i++) { + if (pSrc[i] == RGB(_wtoi(szRed), _wtoi(szGreen), _wtoi(szBlue))) + pDst[i] = iIndex; + } + } + iIndex++; + p1 = p2; + p1++; + + p2 = wcsstr(p1, L"\\red"); + } +} + +static int RtfColorToIndex(int iNumColors, int *pIndex, int iCol) +{ + for (int i = 0; i < iNumColors; i++) + if (pIndex[i] == iCol) + return i; + + return -1; +} + +BOOL CMsgDialog::DoRtfToTags(CMStringW &pszText) const +{ + if (pszText.IsEmpty()) + return FALSE; + + // used to filter out attributes which are already set for the default message input area font + LOGFONTA lf = m_pContainer->m_theme.logFonts[MSGFONTID_MESSAGEAREA]; + + // create an index of colors in the module and map them to + // corresponding colors in the RTF color table + int iNumColors = Utils::rtf_clrs.getCount(); + int *pIndex = (int *)_alloca(iNumColors * sizeof(int)); + COLORREF *pColors = (COLORREF *)_alloca(iNumColors * sizeof(COLORREF)); + for (int i = 0; i < iNumColors; i++) + pColors[i] = Utils::rtf_clrs[i].clr; + CreateColorMap(pszText, iNumColors, pColors, pIndex); + + // scan the file for rtf commands and remove or parse them + int idx = pszText.Find(L"\\pard"); + if (idx == -1) { + if ((idx = pszText.Find(L"\\ltrpar")) == -1) + return FALSE; + idx += 7; + } + else idx += 5; + + MODULEINFO *mi = (isChat()) ? m_si->pMI : nullptr; + + bool bInsideColor = false, bInsideUl = false; + CMStringW res; + + // iterate through all characters, if rtf control character found then take action + for (const wchar_t *p = pszText.GetString() + idx; *p;) { + switch (*p) { + case '\\': + if (p[1] == '\\' || p[1] == '{' || p[1] == '}') { // escaped characters + res.AppendChar(p[1]); + p += 2; break; + } + if (p[1] == '~') { // non-breaking space + res.AppendChar(0xA0); + p += 2; break; + } + + if (!wcsncmp(p, L"\\cf", 3)) { // foreground color + int iCol = _wtoi(p + 3); + int iInd = RtfColorToIndex(iNumColors, pIndex, iCol); + + if (iCol > 0) { + if (isChat()) { + if (mi && mi->bColor) { + if (iInd >= 0) { + if (!(res.IsEmpty() && m_pContainer->m_theme.fontColors[MSGFONTID_MESSAGEAREA] == pColors[iInd])) + res.AppendFormat(L"%%c%u", iInd); + } + else if (!res.IsEmpty()) + res.Append(L"%%C"); + } + } + else res.AppendFormat((iInd >= 0) ? (bInsideColor ? L"[/color][color=%s]" : L"[color=%s]") : (bInsideColor ? L"[/color]" : L""), Utils::rtf_clrs[iInd].szName); + } + + bInsideColor = iInd >= 0; + } + else if (!wcsncmp(p, L"\\highlight", 10)) { // background color + if (isChat()) { + if (mi && mi->bBkgColor) { + int iInd = RtfColorToIndex(iNumColors, pIndex, _wtoi(p + 10)); + if (iInd >= 0) { + // if the entry field is empty & the color passed is the back color, skip it + if (!(res.IsEmpty() && m_pContainer->m_theme.inputbg == pColors[iInd])) + res.AppendFormat(L"%%f%u", iInd); + } + else if (!res.IsEmpty()) + res.AppendFormat(L"%%F"); + } + } + } + else if (!wcsncmp(p, L"\\line", 5)) { // soft line break; + res.AppendChar('\n'); + } + else if (!wcsncmp(p, L"\\endash", 7)) { + res.AppendChar(0x2013); + } + else if (!wcsncmp(p, L"\\emdash", 7)) { + res.AppendChar(0x2014); + } + else if (!wcsncmp(p, L"\\bullet", 7)) { + res.AppendChar(0x2022); + } + else if (!wcsncmp(p, L"\\ldblquote", 10)) { + res.AppendChar(0x201C); + } + else if (!wcsncmp(p, L"\\rdblquote", 10)) { + res.AppendChar(0x201D); + } + else if (!wcsncmp(p, L"\\lquote", 7)) { + res.AppendChar(0x2018); + } + else if (!wcsncmp(p, L"\\rquote", 7)) { + res.AppendChar(0x2019); + } + else if (!wcsncmp(p, L"\\b", 2)) { //bold + if (isChat()) { + if (mi && mi->bBold) + res.Append((p[2] != '0') ? L"%b" : L"%B"); + } + else { + if (!(lf.lfWeight == FW_BOLD)) // only allow bold if the font itself isn't a bold one, otherwise just strip it.. + if (m_SendFormat) + res.Append((p[2] != '0') ? L"[b]" : L"[/b]"); + } + } + else if (!wcsncmp(p, L"\\i", 2)) { // italics + if (isChat()) { + if (mi && mi->bItalics) + res.Append((p[2] != '0') ? L"%i" : L"%I"); + } + else { + if (!lf.lfItalic && m_SendFormat) + res.Append((p[2] != '0') ? L"[i]" : L"[/i]"); + } + } + else if (!wcsncmp(p, L"\\strike", 7)) { // strike-out + if (!lf.lfStrikeOut && m_SendFormat) + res.Append((p[7] != '0') ? L"[s]" : L"[/s]"); + } + else if (!wcsncmp(p, L"\\ul", 3)) { // underlined + if (isChat()) { + if (mi && mi->bUnderline) + res.Append((p[3] != '0') ? L"%u" : L"%U"); + } + else { + if (!lf.lfUnderline && m_SendFormat) { + if (p[3] == 0 || wcschr(tszRtfBreaks, p[3])) { + res.Append(L"[u]"); + bInsideUl = true; + } + else if (!wcsncmp(p + 3, L"none", 4)) { + if (bInsideUl) + res.Append(L"[/u]"); + bInsideUl = false; + } + } + } + } + else if (!wcsncmp(p, L"\\tab", 4)) { // tab + res.AppendChar('\t'); + } + else if (p[1] == '\'') { // special character + if (p[2] != ' ' && p[2] != '\\') { + wchar_t tmp[10]; + + if (p[3] != ' ' && p[3] != '\\') { + wcsncpy(tmp, p + 2, 3); + tmp[3] = 0; + } + else { + wcsncpy(tmp, p + 2, 2); + tmp[2] = 0; + } + + // convert string containing char in hex format to int. + wchar_t *stoppedHere; + res.AppendChar(wcstol(tmp, &stoppedHere, 16)); + } + } + + p++; // skip initial slash + p += wcscspn(p, tszRtfBreaks); + if (*p == ' ') + p++; + break; + + case '{': // other RTF control characters + case '}': + p++; + break; + + case '%': // double % for stupid chat engine + if (isChat()) + res.Append(L"%%"); + else + res.AppendChar(*p); + p++; + break; + + default: // other text that should not be touched + res.AppendChar(*p++); + break; + } + } + + if (bInsideColor && !isChat()) + res.Append(L"[/color]"); + if (bInsideUl) + res.Append(L"[/u]"); + + pszText = res; + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::EnableSendButton(bool bMode) const +{ + SendDlgItemMessage(m_hwnd, IDOK, BUTTONSETASNORMAL, bMode, 0); + SendDlgItemMessage(m_hwnd, IDC_PIC, BUTTONSETASNORMAL, m_bEditNotesActive ? TRUE : (!bMode && m_iOpenJobs == 0) ? TRUE : FALSE, 0); + + HWND hwndOK = GetDlgItem(GetParent(GetParent(m_hwnd)), IDOK); + if (IsWindow(hwndOK)) + SendMessage(hwndOK, BUTTONSETASNORMAL, bMode, 0); +} + +void CMsgDialog::EnableSending(bool bMode) const +{ + m_message.SendMsg(EM_SETREADONLY, !bMode, 0); + Utils::enableDlgControl(m_hwnd, IDC_CLIST, bMode); + EnableSendButton(bMode); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::FindFirstEvent() +{ + int historyMode = g_plugin.getByte(m_hContact, SRMSGSET_LOADHISTORY, -1); + if (historyMode == -1) + historyMode = (int)g_plugin.getByte(SRMSGSET_LOADHISTORY, SRMSGDEFSET_LOADHISTORY); + + m_hDbEventFirst = db_event_firstUnread(m_hContact); + + if (m_bActualHistory) + historyMode = LOADHISTORY_COUNT; + + switch (historyMode) { + case LOADHISTORY_COUNT: + int i; + MEVENT hPrevEvent; + { + DBEVENTINFO dbei = {}; + // ability to load only current session's history + if (m_bActualHistory) + i = m_cache->getSessionMsgCount(); + else + i = g_plugin.getWord(SRMSGSET_LOADCOUNT, SRMSGDEFSET_LOADCOUNT); + + for (; i > 0; i--) { + if (m_hDbEventFirst == 0) + hPrevEvent = db_event_last(m_hContact); + else + hPrevEvent = db_event_prev(m_hContact, m_hDbEventFirst); + if (hPrevEvent == 0) + break; + dbei.cbBlob = 0; + m_hDbEventFirst = hPrevEvent; + db_event_get(m_hDbEventFirst, &dbei); + if (!DbEventIsShown(&dbei)) + i++; + } + } + break; + + case LOADHISTORY_TIME: + DBEVENTINFO dbei = {}; + if (m_hDbEventFirst == 0) + dbei.timestamp = time(0); + else + db_event_get(m_hDbEventFirst, &dbei); + + DWORD firstTime = dbei.timestamp - 60 * g_plugin.getWord(SRMSGSET_LOADTIME, SRMSGDEFSET_LOADTIME); + for (;;) { + if (m_hDbEventFirst == 0) + hPrevEvent = db_event_last(m_hContact); + else + hPrevEvent = db_event_prev(m_hContact, m_hDbEventFirst); + if (hPrevEvent == 0) + break; + dbei.cbBlob = 0; + db_event_get(hPrevEvent, &dbei); + if (dbei.timestamp < firstTime) + break; + m_hDbEventFirst = hPrevEvent; + } + break; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::FlashOnClist(MEVENT hEvent, DBEVENTINFO *dbei) +{ + m_dwTickLastEvent = GetTickCount(); + + if ((GetForegroundWindow() != m_pContainer->m_hwnd || m_pContainer->m_hwndActive != m_hwnd) && !(dbei->flags & DBEF_SENT) && dbei->eventType == EVENTTYPE_MESSAGE) { + m_dwUnread++; + UpdateTrayMenu(this, (WORD)(m_cache->getActiveStatus()), m_cache->getActiveProto(), m_wszStatus, m_hContact, 0); + if (nen_options.bTraySupport) + return; + } + if (hEvent == 0) + return; + + if (!PluginConfig.m_bFlashOnClist) + return; + + if ((GetForegroundWindow() != m_pContainer->m_hwnd || m_pContainer->m_hwndActive != m_hwnd) && !(dbei->flags & DBEF_SENT) && dbei->eventType == EVENTTYPE_MESSAGE && !(m_dwFlagsEx & MWF_SHOW_FLASHCLIST)) { + CLISTEVENT cle = {}; + cle.hContact = m_hContact; + cle.hDbEvent = hEvent; + cle.hIcon = Skin_LoadIcon(SKINICON_EVENT_MESSAGE); + cle.pszService = MS_MSG_READMESSAGE; + g_clistApi.pfnAddEvent(&cle); + + m_dwFlagsEx |= MWF_SHOW_FLASHCLIST; + m_hFlashingEvent = hEvent; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// flash a tab icon if mode = true, otherwise restore default icon +// store flashing state into bState + +void CMsgDialog::FlashTab(bool bInvertMode) +{ + if (bInvertMode) + m_bTabFlash = !m_bTabFlash; + + TCITEM item = {}; + item.mask = TCIF_IMAGE; + TabCtrl_SetItem(m_hwndParent, m_iTabID, &item); + if (m_pContainer->m_dwFlags & CNT_SIDEBAR) + m_pContainer->m_pSideBar->updateSession(this); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// retrieve the visiblity of the avatar window, depending on the global setting +// and local mode + +bool CMsgDialog::GetAvatarVisibility() +{ + BYTE bAvatarMode = m_pContainer->m_avatarMode; + BYTE bOwnAvatarMode = m_pContainer->m_ownAvatarMode; + char hideOverride = (char)M.GetByte(m_hContact, "hideavatar", -1); + + // infopanel visible, consider own avatar display + m_bShowAvatar = false; + if (m_si) + return false; + + if (m_pPanel.isActive() && bAvatarMode != 3) { + if (!bOwnAvatarMode) { + m_bShowAvatar = (m_hOwnPic && m_hOwnPic != PluginConfig.g_hbmUnknown); + if (!m_hwndContactPic) + m_hwndContactPic = CreateWindowEx(WS_EX_TOPMOST, AVATAR_CONTROL_CLASS, L"", WS_VISIBLE | WS_CHILD, 1, 1, 1, 1, GetDlgItem(m_hwnd, IDC_CONTACTPIC), (HMENU)nullptr, nullptr, nullptr); + } + + switch (bAvatarMode) { + case 2: + m_bShowInfoAvatar = false; + break; + case 0: + m_bShowInfoAvatar = true; + case 1: + HBITMAP hbm = ((m_ace && !(m_ace->dwFlags & AVS_HIDEONCLIST)) ? m_ace->hbmPic : nullptr); + if (hbm == nullptr && !bAvatarMode) { + m_bShowInfoAvatar = false; + break; + } + + if (!m_hwndPanelPic) { + m_hwndPanelPic = CreateWindowEx(WS_EX_TOPMOST, AVATAR_CONTROL_CLASS, L"", WS_VISIBLE | WS_CHILD, 1, 1, 1, 1, m_hwndPanelPicParent, (HMENU)7000, nullptr, nullptr); + if (m_hwndPanelPic) + SendMessage(m_hwndPanelPic, AVATAR_SETAEROCOMPATDRAWING, 0, TRUE); + } + + if (bAvatarMode != 0) + m_bShowInfoAvatar = (hbm && hbm != PluginConfig.g_hbmUnknown); + break; + } + + if (m_bShowInfoAvatar) + m_bShowInfoAvatar = hideOverride == 0 ? false : m_bShowInfoAvatar; + else + m_bShowInfoAvatar = hideOverride == 1 ? true : m_bShowInfoAvatar; + + Utils::setAvatarContact(m_hwndPanelPic, m_hContact); + SendMessage(m_hwndContactPic, AVATAR_SETPROTOCOL, 0, (LPARAM)m_cache->getActiveProto()); + } + else { + m_bShowInfoAvatar = false; + + switch (bAvatarMode) { + case 0: // globally on + m_bShowAvatar = true; + LBL_Check: + if (!m_hwndContactPic) + m_hwndContactPic = CreateWindowEx(WS_EX_TOPMOST, AVATAR_CONTROL_CLASS, L"", WS_VISIBLE | WS_CHILD, 1, 1, 1, 1, GetDlgItem(m_hwnd, IDC_CONTACTPIC), (HMENU)nullptr, nullptr, nullptr); + break; + case 2: // globally OFF + m_bShowAvatar = false; + break; + case 3: // on, if present + case 1: + HBITMAP hbm = (m_ace && !(m_ace->dwFlags & AVS_HIDEONCLIST)) ? m_ace->hbmPic : nullptr; + m_bShowAvatar = (hbm && hbm != PluginConfig.g_hbmUnknown); + goto LBL_Check; + } + + if (m_bShowAvatar) + m_bShowAvatar = hideOverride == 0 ? 0 : m_bShowAvatar; + else + m_bShowAvatar = hideOverride == 1 ? 1 : m_bShowAvatar; + + // reloads avatars + if (m_hwndPanelPic) { // shows contact or user picture, depending on panel visibility + SendMessage(m_hwndContactPic, AVATAR_SETPROTOCOL, 0, (LPARAM)m_cache->getActiveProto()); + Utils::setAvatarContact(m_hwndPanelPic, m_hContact); + } + else Utils::setAvatarContact(m_hwndContactPic, m_hContact); + } + return m_bShowAvatar; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::GetClientIcon() +{ + if (m_hClientIcon) + DestroyIcon(m_hClientIcon); + + m_hClientIcon = nullptr; + if (ServiceExists(MS_FP_GETCLIENTICONT)) { + ptrW tszMirver(db_get_wsa(m_cache->getActiveContact(), m_cache->getActiveProto(), "MirVer")); + if (tszMirver) + m_hClientIcon = Finger_GetClientIcon(tszMirver, 1); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +LONG CMsgDialog::GetDefaultMinimumInputHeight() const +{ + LONG height = (m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR) ? DPISCALEY_S(46 + 22) : DPISCALEY_S(46); + + if (CSkin::m_skinEnabled && !SkinItems[ID_EXTBKINPUTAREA].IGNORED) + height += (SkinItems[ID_EXTBKINPUTAREA].MARGIN_BOTTOM + SkinItems[ID_EXTBKINPUTAREA].MARGIN_TOP - 2); + + return height; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +HICON CMsgDialog::GetMyContactIcon(LPCSTR szSetting) +{ + int bUseMeta = (szSetting == nullptr) ? false : M.GetByte(szSetting, mir_strcmp(szSetting, "MetaiconTab") == 0); + if (bUseMeta) + return Skin_LoadProtoIcon(m_cache->getProto(), m_cache->getStatus()); + return Skin_LoadProtoIcon(m_cache->getActiveProto(), m_cache->getActiveStatus()); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::GetMyNick() +{ + ptrW tszNick(Contact_GetInfo(CNF_CUSTOMNICK, 0, m_cache->getActiveProto())); + if (tszNick == nullptr) + tszNick = Contact_GetInfo(CNF_NICK, 0, m_cache->getActiveProto()); + if (tszNick != nullptr) { + if (mir_wstrlen(tszNick) == 0 || !mir_wstrcmp(tszNick, TranslateT("'(Unknown contact)'"))) + wcsncpy_s(m_wszMyNickname, (m_myUin[0] ? m_myUin : TranslateT("'(Unknown contact)'")), _TRUNCATE); + else + wcsncpy_s(m_wszMyNickname, tszNick, _TRUNCATE); + } + else wcsncpy_s(m_wszMyNickname, L"<undef>", _TRUNCATE); // same here +} + +///////////////////////////////////////////////////////////////////////////////////////// +// retrieve both buddys and my own UIN for a message session and store them in the message window *dat +// respects metacontacts and uses the current protocol if the contact is a MC + +void CMsgDialog::GetMYUIN() +{ + ptrW uid(Contact_GetInfo(CNF_DISPLAYUID, 0, m_cache->getActiveProto())); + if (uid != nullptr) + wcsncpy_s(m_myUin, uid, _TRUNCATE); + else + m_myUin[0] = 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// reads send format and configures the toolbar buttons +// if mode == 0, int only configures the buttons and does not change send format + +void CMsgDialog::GetSendFormat() +{ + m_SendFormat = M.GetDword(m_hContact, "sendformat", PluginConfig.m_SendFormat); + if (m_SendFormat == -1) // per contact override to disable it.. + m_SendFormat = 0; + else if (m_SendFormat == 0) + m_SendFormat = PluginConfig.m_SendFormat ? 1 : 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +HICON CMsgDialog::GetXStatusIcon() const +{ + BYTE xStatus = m_cache->getXStatusId(); + if (xStatus == 0) + return nullptr; + + if (!ProtoServiceExists(m_cache->getActiveProto(), PS_GETCUSTOMSTATUSICON)) + return nullptr; + + return (HICON)(CallProtoService(m_cache->getActiveProto(), PS_GETCUSTOMSTATUSICON, xStatus, 0)); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// paste contents of the clipboard into the message input area and send it immediately + +void CMsgDialog::HandlePasteAndSend() +{ + // is feature disabled? + if (!PluginConfig.m_PasteAndSend) { + SendMessage(m_hwnd, DM_ACTIVATETOOLTIP, IDC_SRMM_MESSAGE, (LPARAM)TranslateT("The 'paste and send' feature is disabled. You can enable it on the 'General' options page in the 'Sending messages' section")); + return; + } + + m_message.SendMsg(EM_PASTESPECIAL, CF_UNICODETEXT, 0); + if (GetWindowTextLength(m_message.GetHwnd()) > 0) + SendMessage(m_hwnd, WM_COMMAND, IDOK, 0); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +bool CMsgDialog::IsAutoSplitEnabled() const +{ + return (m_pContainer->m_dwFlags & CNT_AUTOSPLITTER) && !(m_dwFlagsEx & MWF_SHOW_SPLITTEROVERRIDE); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// read keyboard state and return the state of the modifier keys + +void CMsgDialog::KbdState(bool &isShift, bool &isControl, bool &isAlt) +{ + GetKeyboardState(kstate); + isShift = (kstate[VK_SHIFT] & 0x80) != 0; + isControl = (kstate[VK_CONTROL] & 0x80) != 0; + isAlt = (kstate[VK_MENU] & 0x80) != 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::LimitMessageText(int iLen) +{ + if (this != nullptr) + m_message.SendMsg(EM_EXLIMITTEXT, 0, iLen); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::LoadContactAvatar() +{ + m_ace = Utils::loadAvatarFromAVS(m_bIsMeta ? db_mc_getSrmmSub(m_hContact) : m_hContact); + + BITMAP bm; + if (m_ace && m_ace->hbmPic) + GetObject(m_ace->hbmPic, sizeof(bm), &bm); + else if (m_ace == nullptr) + GetObject(PluginConfig.g_hbmUnknown, sizeof(bm), &bm); + else + return; + + AdjustBottomAvatarDisplay(); + CalcDynamicAvatarSize(&bm); + + if (!m_pPanel.isActive() || m_pContainer->m_avatarMode == 3) { + m_iRealAvatarHeight = 0; + PostMessage(m_hwnd, WM_SIZE, 0, 0); + } + else if (m_pPanel.isActive()) + GetAvatarVisibility(); + + if (m_pWnd != nullptr) + m_pWnd->verifyDwmState(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::LoadOwnAvatar() +{ + if (ServiceExists(MS_AV_GETMYAVATAR)) + m_ownAce = (AVATARCACHEENTRY *)CallService(MS_AV_GETMYAVATAR, 0, (LPARAM)(m_cache->getActiveProto())); + else + m_ownAce = nullptr; + + if (m_ownAce) + m_hOwnPic = m_ownAce->hbmPic; + else + m_hOwnPic = PluginConfig.g_hbmUnknown; + + if (m_pPanel.isActive() && m_pContainer->m_avatarMode != 3) { + BITMAP bm; + + m_iRealAvatarHeight = 0; + AdjustBottomAvatarDisplay(); + GetObject(m_hOwnPic, sizeof(bm), &bm); + CalcDynamicAvatarSize(&bm); + Resize(); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::LoadSettings() +{ + m_clrInputBG = m_pContainer->m_theme.inputbg; + LoadLogfont(FONTSECTION_IM, MSGFONTID_MESSAGEAREA, nullptr, &m_clrInputFG, FONTMODULE); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::LoadSplitter() +{ + if (m_bIsAutosizingInput) { + m_iSplitterY = GetDefaultMinimumInputHeight(); + return; + } + + if (!(m_dwFlagsEx & MWF_SHOW_SPLITTEROVERRIDE)) { + if (!m_pContainer->m_pSettings->fPrivate) + m_iSplitterY = (int)M.GetDword("splitsplity", 60); + else + m_iSplitterY = m_pContainer->m_pSettings->iSplitterY; + } + else m_iSplitterY = (int)M.GetDword(m_hContact, "splitsplity", M.GetDword("splitsplity", 60)); + + if (m_iSplitterY < MINSPLITTERY) + m_iSplitterY = 150; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// draw various elements of the message window, like avatar(s), info panel fields +// and the color formatting menu + +int CMsgDialog::MsgWindowDrawHandler(DRAWITEMSTRUCT *dis) +{ + HBITMAP hbmAvatar = m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown; + if ((dis->hwndItem == GetDlgItem(m_hwnd, IDC_CONTACTPIC) && m_bShowAvatar) || (dis->hwndItem == m_hwnd && m_pPanel.isActive())) { + if (hbmAvatar == nullptr) + return TRUE; + + int top, cx, cy; + RECT rcClient, rcFrame; + bool bPanelPic = (dis->hwndItem == m_hwnd); + if (bPanelPic && !m_bShowInfoAvatar) + return TRUE; + + RECT rc; + GetClientRect(m_hwnd, &rc); + if (bPanelPic) { + rcClient = dis->rcItem; + cx = (rcClient.right - rcClient.left); + cy = (rcClient.bottom - rcClient.top) + 1; + } + else { + GetClientRect(dis->hwndItem, &rcClient); + cx = rcClient.right; + cy = rcClient.bottom; + } + + if (cx < 5 || cy < 5) + return TRUE; + + HDC hdcDraw = CreateCompatibleDC(dis->hDC); + HBITMAP hbmDraw = CreateCompatibleBitmap(dis->hDC, cx, cy); + HBITMAP hbmOld = (HBITMAP)SelectObject(hdcDraw, hbmDraw); + + bool bAero = M.isAero(); + + HRGN clipRgn = nullptr; + HBRUSH hOldBrush = (HBRUSH)SelectObject(hdcDraw, bAero ? (HBRUSH)GetStockObject(HOLLOW_BRUSH) : GetSysColorBrush(COLOR_3DFACE)); + rcFrame = rcClient; + + if (!bPanelPic) { + top = (cy - m_pic.cy) / 2; + RECT rcEdge = { 0, top, m_pic.cx, top + m_pic.cy }; + if (CSkin::m_skinEnabled) + CSkin::SkinDrawBG(dis->hwndItem, m_pContainer->m_hwnd, m_pContainer, &dis->rcItem, hdcDraw); + else if (PluginConfig.m_fillColor) { + HBRUSH br = CreateSolidBrush(PluginConfig.m_fillColor); + FillRect(hdcDraw, &rcFrame, br); + DeleteObject(br); + } + else if (bAero && CSkin::m_pCurrentAeroEffect) { + COLORREF clr = PluginConfig.m_tbBackgroundHigh ? PluginConfig.m_tbBackgroundHigh : + (CSkin::m_pCurrentAeroEffect ? CSkin::m_pCurrentAeroEffect->m_clrToolbar : 0xf0f0f0); + + HBRUSH br = CreateSolidBrush(clr); + FillRect(hdcDraw, &rcFrame, br); + DeleteObject(br); + } + else FillRect(hdcDraw, &rcFrame, GetSysColorBrush(COLOR_3DFACE)); + + HPEN hPenBorder = CreatePen(PS_SOLID, 1, CSkin::m_avatarBorderClr); + HPEN hPenOld = (HPEN)SelectObject(hdcDraw, hPenBorder); + + if (CSkin::m_bAvatarBorderType == 1) + Rectangle(hdcDraw, rcEdge.left, rcEdge.top, rcEdge.right, rcEdge.bottom); + else if (CSkin::m_bAvatarBorderType == 2) { + clipRgn = CreateRoundRectRgn(rcEdge.left, rcEdge.top, rcEdge.right + 1, rcEdge.bottom + 1, 6, 6); + SelectClipRgn(hdcDraw, clipRgn); + + HBRUSH hbr = CreateSolidBrush(CSkin::m_avatarBorderClr); + FrameRgn(hdcDraw, clipRgn, hbr, 1, 1); + DeleteObject(hbr); + DeleteObject(clipRgn); + } + + SelectObject(hdcDraw, hPenOld); + DeleteObject(hPenBorder); + } + + if (bPanelPic) { + bool bBorder = (CSkin::m_bAvatarBorderType ? true : false); + + int border_off = bBorder ? 1 : 0; + int iMaxHeight = m_iPanelAvatarY - (bBorder ? 2 : 0); + int iMaxWidth = m_iPanelAvatarX - (bBorder ? 2 : 0); + + rcFrame.left = rcFrame.top = 0; + rcFrame.right = (rcClient.right - rcClient.left); + rcFrame.bottom = (rcClient.bottom - rcClient.top); + + rcFrame.left = rcFrame.right - (LONG)m_iPanelAvatarX; + rcFrame.bottom = (LONG)m_iPanelAvatarY; + + int height_off = (cy - iMaxHeight - (bBorder ? 2 : 0)) / 2; + rcFrame.top += height_off; + rcFrame.bottom += height_off; + + SendMessage(m_hwndPanelPic, AVATAR_SETAEROCOMPATDRAWING, 0, bAero ? TRUE : FALSE); + SetWindowPos(m_hwndPanelPic, HWND_TOP, rcFrame.left + border_off, rcFrame.top + border_off, + iMaxWidth, iMaxHeight, SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS | SWP_DEFERERASE | SWP_NOSENDCHANGING); + } + + SelectObject(hdcDraw, hOldBrush); + if (!bPanelPic) + BitBlt(dis->hDC, 0, 0, cx, cy, hdcDraw, 0, 0, SRCCOPY); + SelectObject(hdcDraw, hbmOld); + DeleteObject(hbmDraw); + DeleteDC(hdcDraw); + return TRUE; + } + + if (dis->hwndItem == GetDlgItem(m_hwnd, IDC_STATICTEXT) || dis->hwndItem == GetDlgItem(m_hwnd, IDC_LOGFROZENTEXT)) { + wchar_t szWindowText[256]; + if (CSkin::m_skinEnabled) { + SetTextColor(dis->hDC, CSkin::m_DefaultFontColor); + CSkin::SkinDrawBG(dis->hwndItem, m_pContainer->m_hwnd, m_pContainer, &dis->rcItem, dis->hDC); + } + else { + SetTextColor(dis->hDC, GetSysColor(COLOR_BTNTEXT)); + CSkin::FillBack(dis->hDC, &dis->rcItem); + } + GetWindowText(dis->hwndItem, szWindowText, _countof(szWindowText)); + szWindowText[255] = 0; + SetBkMode(dis->hDC, TRANSPARENT); + DrawText(dis->hDC, szWindowText, -1, &dis->rcItem, DT_SINGLELINE | DT_VCENTER | DT_NOCLIP | DT_END_ELLIPSIS); + return TRUE; + } + + if (dis->hwndItem == GetDlgItem(m_hwnd, IDC_STATICERRORICON)) { + if (CSkin::m_skinEnabled) + CSkin::SkinDrawBG(dis->hwndItem, m_pContainer->m_hwnd, m_pContainer, &dis->rcItem, dis->hDC); + else + CSkin::FillBack(dis->hDC, &dis->rcItem); + DrawIconEx(dis->hDC, (dis->rcItem.right - dis->rcItem.left) / 2 - 8, (dis->rcItem.bottom - dis->rcItem.top) / 2 - 8, + PluginConfig.g_iconErr, 16, 16, 0, nullptr, DI_NORMAL); + return TRUE; + } + + if (dis->CtlType == ODT_MENU && m_pPanel.isHovered()) { + DrawMenuItem(dis, (HICON)dis->itemData, 0); + return TRUE; + } + + return Menu_DrawItem((LPARAM)dis); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int CMsgDialog::MsgWindowUpdateMenu(HMENU submenu, int menuID) +{ + bool bInfoPanel = m_pPanel.isActive(); + + if (menuID == MENU_TABCONTEXT) { + EnableMenuItem(submenu, ID_TABMENU_LEAVECHATROOM, (isChat() && ProtoServiceExists(m_szProto, PS_LEAVECHAT)) ? MF_ENABLED : MF_DISABLED); + EnableMenuItem(submenu, ID_TABMENU_ATTACHTOCONTAINER, (M.GetByte("useclistgroups", 0) || M.GetByte("singlewinmode", 0)) ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(submenu, ID_TABMENU_CLEARSAVEDTABPOSITION, (M.GetDword(m_hContact, "tabindex", -1) != -1) ? MF_ENABLED : MF_GRAYED); + } + else if (menuID == MENU_PICMENU) { + wchar_t *szText = nullptr; + char avOverride = (char)M.GetByte(m_hContact, "hideavatar", -1); + HMENU visMenu = GetSubMenu(submenu, 0); + BOOL picValid = bInfoPanel ? (m_hOwnPic != nullptr) : (m_ace && m_ace->hbmPic && m_ace->hbmPic != PluginConfig.g_hbmUnknown); + + MENUITEMINFO mii = { 0 }; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_STRING; + + EnableMenuItem(submenu, ID_PICMENU_SAVETHISPICTUREAS, MF_BYCOMMAND | (picValid ? MF_ENABLED : MF_GRAYED)); + + CheckMenuItem(visMenu, ID_VISIBILITY_DEFAULT, MF_BYCOMMAND | (avOverride == -1 ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(visMenu, ID_VISIBILITY_HIDDENFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 0 ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(visMenu, ID_VISIBILITY_VISIBLEFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 1 ? MF_CHECKED : MF_UNCHECKED)); + + CheckMenuItem(submenu, ID_PICMENU_ALWAYSKEEPTHEBUTTONBARATFULLWIDTH, MF_BYCOMMAND | (PluginConfig.m_bAlwaysFullToolbarWidth ? MF_CHECKED : MF_UNCHECKED)); + if (!bInfoPanel) { + EnableMenuItem(submenu, ID_PICMENU_SETTINGS, MF_BYCOMMAND | (ServiceExists(MS_AV_GETAVATARBITMAP) ? MF_ENABLED : MF_GRAYED)); + szText = TranslateT("Contact picture settings..."); + EnableMenuItem(submenu, 0, MF_BYPOSITION | MF_ENABLED); + } + else { + EnableMenuItem(submenu, 0, MF_BYPOSITION | MF_GRAYED); + EnableMenuItem(submenu, ID_PICMENU_SETTINGS, MF_BYCOMMAND | ((ServiceExists(MS_AV_SETMYAVATARW) && CallService(MS_AV_CANSETMYAVATAR, (WPARAM)(m_cache->getActiveProto()), 0)) ? MF_ENABLED : MF_GRAYED)); + szText = TranslateT("Set your avatar..."); + } + mii.dwTypeData = szText; + mii.cch = (int)mir_wstrlen(szText) + 1; + SetMenuItemInfo(submenu, ID_PICMENU_SETTINGS, FALSE, &mii); + } + else if (menuID == MENU_PANELPICMENU) { + HMENU visMenu = GetSubMenu(submenu, 0); + char avOverride = (char)M.GetByte(m_hContact, "hideavatar", -1); + + CheckMenuItem(visMenu, ID_VISIBILITY_DEFAULT, MF_BYCOMMAND | (avOverride == -1 ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(visMenu, ID_VISIBILITY_HIDDENFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 0 ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(visMenu, ID_VISIBILITY_VISIBLEFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 1 ? MF_CHECKED : MF_UNCHECKED)); + + EnableMenuItem(submenu, ID_PICMENU_SETTINGS, MF_BYCOMMAND | (ServiceExists(MS_AV_GETAVATARBITMAP) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(submenu, ID_PANELPICMENU_SAVETHISPICTUREAS, MF_BYCOMMAND | ((m_ace && m_ace->hbmPic && m_ace->hbmPic != PluginConfig.g_hbmUnknown) ? MF_ENABLED : MF_GRAYED)); + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// update state of the container - this is called whenever a tab becomes active, no matter how and +// deals with various things like updating the title bar, removing flashing icons, updating the +// session list, switching the keyboard layout (autolocale active) and the general container status. +// +// it protects itself from being called more than once per session activation and is valid for +// normal IM sessions *only*. Group chat sessions have their own activation handler (see chat/window.c) + +void CMsgDialog::MsgWindowUpdateState(UINT msg) +{ + if (m_iTabID < 0) + return; + + if (msg == WM_ACTIVATE) { + if (m_pContainer->m_dwFlags & CNT_TRANSPARENCY) { + DWORD trans = LOWORD(m_pContainer->m_pSettings->dwTransparency); + SetLayeredWindowAttributes(m_pContainer->m_hwnd, 0, (BYTE)trans, (m_pContainer->m_dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0)); + } + } + + if (m_bIsAutosizingInput && m_iInputAreaHeight == -1) { + m_iInputAreaHeight = 0; + m_message.SendMsg(EM_REQUESTRESIZE, 0, 0); + } + + if (m_pWnd) + m_pWnd->activateTab(); + m_pPanel.dismissConfig(); + m_dwUnread = 0; + if (m_pContainer->m_hwndSaved == m_hwnd) + return; + + m_pContainer->m_hwndSaved = m_hwnd; + + m_dwTickLastEvent = 0; + m_dwFlags &= ~MWF_DIVIDERSET; + if (KillTimer(m_hwnd, TIMERID_FLASHWND)) { + FlashTab(false); + m_bCanFlashTab = false; + } + if (m_pContainer->m_dwFlashingStarted != 0) { + FlashContainer(m_pContainer, 0, 0); + m_pContainer->m_dwFlashingStarted = 0; + } + if (m_dwFlagsEx & MWF_SHOW_FLASHCLIST) { + m_dwFlagsEx &= ~MWF_SHOW_FLASHCLIST; + if (m_hFlashingEvent != 0) + g_clistApi.pfnRemoveEvent(m_hContact, m_hFlashingEvent); + m_hFlashingEvent = 0; + } + m_pContainer->m_dwFlags &= ~CNT_NEED_UPDATETITLE; + + if ((m_dwFlags & MWF_DEFERREDREMAKELOG) && !IsIconic(m_pContainer->m_hwnd)) { + SendMessage(m_hwnd, DM_REMAKELOG, 0, 0); + m_dwFlags &= ~MWF_DEFERREDREMAKELOG; + } + + if (m_dwFlags & MWF_NEEDCHECKSIZE) + PostMessage(m_hwnd, DM_SAVESIZE, 0, 0); + + m_pContainer->m_hIconTaskbarOverlay = nullptr; + m_pContainer->UpdateTitle(m_hContact); + + tabUpdateStatusBar(); + m_dwLastActivity = GetTickCount(); + m_pContainer->m_dwLastActivity = m_dwLastActivity; + + m_pContainer->m_pMenuBar->configureMenu(); + UpdateTrayMenuState(this, FALSE); + + if (m_pContainer->m_hwndActive == m_hwnd) + DeletePopupsForContact(m_hContact, PU_REMOVE_ON_FOCUS); + + m_pPanel.Invalidate(); + + if (m_dwFlags & MWF_DEFERREDSCROLL && m_hwndIEView == nullptr && m_hwndHPP == nullptr) { + m_dwFlags &= ~MWF_DEFERREDSCROLL; + DM_ScrollToBottom(0, 1); + } + + DM_SetDBButtonStates(); + + if (m_hwndIEView) { + RECT rcRTF; + POINT pt; + + GetWindowRect(m_log.GetHwnd(), &rcRTF); + rcRTF.left += 20; + rcRTF.top += 20; + pt.x = rcRTF.left; + pt.y = rcRTF.top; + if (m_hwndIEView) { + if (M.GetByte("subclassIEView", 0)) { + mir_subclassWindow(m_hwndIEView, IEViewSubclassProc); + SetWindowPos(m_hwndIEView, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_DRAWFRAME); + RedrawWindow(m_hwndIEView, nullptr, nullptr, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); + } + } + m_hwndIWebBrowserControl = WindowFromPoint(pt); + } + + if (m_dwFlagsEx & MWF_EX_DELAYEDSPLITTER) { + m_dwFlagsEx &= ~MWF_EX_DELAYEDSPLITTER; + ShowWindow(m_pContainer->m_hwnd, SW_RESTORE); + PostMessage(m_hwnd, DM_SPLITTERGLOBALEVENT, m_wParam, m_lParam); + m_wParam = m_lParam = 0; + } + if (m_dwFlagsEx & MWF_EX_AVATARCHANGED) { + m_dwFlagsEx &= ~MWF_EX_AVATARCHANGED; + PostMessage(m_hwnd, DM_UPDATEPICLAYOUT, 0, 0); + } + BB_SetButtonsPos(); + if (M.isAero()) + InvalidateRect(m_hwndParent, nullptr, FALSE); + if (m_pContainer->m_dwFlags & CNT_SIDEBAR) + m_pContainer->m_pSideBar->setActiveItem(this); + + if (m_pWnd) + m_pWnd->Invalidate(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +int CMsgDialog::MsgWindowMenuHandler(int selection, int menuId) +{ + if (menuId == MENU_PICMENU || menuId == MENU_PANELPICMENU || menuId == MENU_TABCONTEXT) { + switch (selection) { + case ID_TABMENU_ATTACHTOCONTAINER: + CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SELECTCONTAINER), m_hwnd, SelectContainerDlgProc, (LPARAM)m_hwnd); + return 1; + case ID_TABMENU_CONTAINEROPTIONS: + if (m_pContainer->m_hWndOptions == nullptr) + CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_CONTAINEROPTIONS), m_hwnd, DlgProcContainerOptions, (LPARAM)m_pContainer); + return 1; + case ID_TABMENU_CLOSECONTAINER: + SendMessage(m_pContainer->m_hwnd, WM_CLOSE, 0, 0); + return 1; + case ID_TABMENU_CLOSETAB: + PostMessage(m_hwnd, WM_CLOSE, 1, 0); + return 1; + case ID_TABMENU_SAVETABPOSITION: + db_set_dw(m_hContact, SRMSGMOD_T, "tabindex", m_iTabID * 100); + break; + case ID_TABMENU_CLEARSAVEDTABPOSITION: + db_unset(m_hContact, SRMSGMOD_T, "tabindex"); + break; + case ID_TABMENU_LEAVECHATROOM: + if (isChat() && m_hContact != 0) { + char *szProto = GetContactProto(m_hContact); + if (szProto) + CallProtoService(szProto, PS_LEAVECHAT, m_hContact, 0); + } + return 1; + + case ID_VISIBILITY_DEFAULT: + case ID_VISIBILITY_HIDDENFORTHISCONTACT: + case ID_VISIBILITY_VISIBLEFORTHISCONTACT: + { + BYTE avOverrideMode; + if (selection == ID_VISIBILITY_DEFAULT) + avOverrideMode = -1; + else if (selection == ID_VISIBILITY_VISIBLEFORTHISCONTACT) + avOverrideMode = 1; + else + avOverrideMode = 0; + db_set_b(m_hContact, SRMSGMOD_T, "hideavatar", avOverrideMode); + } + + ShowPicture(false); + Resize(); + DM_ScrollToBottom(0, 1); + return 1; + + case ID_PICMENU_ALWAYSKEEPTHEBUTTONBARATFULLWIDTH: + PluginConfig.m_bAlwaysFullToolbarWidth = !PluginConfig.m_bAlwaysFullToolbarWidth; + db_set_b(0, SRMSGMOD_T, "alwaysfulltoolbar", (BYTE)PluginConfig.m_bAlwaysFullToolbarWidth); + Srmm_Broadcast(DM_CONFIGURETOOLBAR, 0, 1); + break; + + case ID_PICMENU_SAVETHISPICTUREAS: + if (m_pPanel.isActive()) + SaveAvatarToFile(m_hOwnPic, 1); + else if (m_ace) + SaveAvatarToFile(m_ace->hbmPic, 0); + break; + + case ID_PANELPICMENU_SAVETHISPICTUREAS: + if (m_ace) + SaveAvatarToFile(m_ace->hbmPic, 0); + break; + + case ID_PICMENU_SETTINGS: + if (menuId == MENU_PANELPICMENU) + CallService(MS_AV_CONTACTOPTIONS, m_hContact, 0); + else if (menuId == MENU_PICMENU) { + if (m_pPanel.isActive()) { + if (ServiceExists(MS_AV_SETMYAVATARW) && CallService(MS_AV_CANSETMYAVATAR, (WPARAM)(m_cache->getActiveProto()), 0)) + CallService(MS_AV_SETMYAVATARW, (WPARAM)(m_cache->getActiveProto()), 0); + } + else + CallService(MS_AV_CONTACTOPTIONS, m_hContact, 0); + } + return 1; + } + } + else if (menuId == MENU_LOGMENU) { + switch (selection) { + case ID_MESSAGELOGSETTINGS_GLOBAL: + g_plugin.openOptions(nullptr, L"Message sessions", L"Message log"); + return 1; + + case ID_MESSAGELOGSETTINGS_FORTHISCONTACT: + CallService(MS_TABMSG_SETUSERPREFS, m_hContact, 0); + return 1; + } + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::PlayIncomingSound() const +{ + int iPlay = MustPlaySound(); + if (iPlay) { + if (GetForegroundWindow() == m_pContainer->m_hwnd && m_pContainer->m_hwndActive == m_hwnd) + Skin_PlaySound("RecvMsgActive"); + else + Skin_PlaySound("RecvMsgInactive"); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static void __cdecl phase2(SESSION_INFO *si) +{ + Thread_SetName("TabSRMM: phase2"); + + Sleep(30); + if (si && si->pDlg) + si->pDlg->RedrawLog2(); +} + +void CMsgDialog::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_si->iType != GCW_PRIVMESS) || !m_bFilterEnabled || (m_iLogFilterFlags & pLog->iType) != 0) + index++; + } + StreamInEvents(pLog, TRUE); + mir_forkThread<SESSION_INFO>(phase2, m_si); + } + else StreamInEvents(m_si->pLogEnd, TRUE); + } + else ClearLog(); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::ResizeIeView() +{ + RECT rcRichEdit; + GetWindowRect(m_log.GetHwnd(), &rcRichEdit); + + POINT pt = { rcRichEdit.left, rcRichEdit.top }; + ScreenToClient(m_hwnd, &pt); + + IEVIEWWINDOW ieWindow = { sizeof(ieWindow) }; + ieWindow.iType = IEW_SETPOS; + ieWindow.parent = m_hwnd; + ieWindow.hwnd = m_hwndIEView ? m_hwndIEView : m_hwndHPP; + ieWindow.x = pt.x; + ieWindow.y = pt.y; + ieWindow.cx = rcRichEdit.right - rcRichEdit.left; + ieWindow.cy = rcRichEdit.bottom - rcRichEdit.top; + if (ieWindow.cx != 0 && ieWindow.cy != 0) + CallService(m_hwndIEView ? MS_IEVIEW_WINDOW : MS_HPP_EG_WINDOW, 0, (LPARAM)& ieWindow); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// saves a contact picture to disk +// takes hbm (bitmap handle) and bool isOwnPic (1 == save the picture as your own avatar) +// requires AVS service (Miranda 0.7+) + +void CMsgDialog::SaveAvatarToFile(HBITMAP hbm, int isOwnPic) +{ + wchar_t szFinalFilename[MAX_PATH]; + time_t t = time(0); + struct tm *lt = localtime(&t); + DWORD setView = 1; + + wchar_t szTimestamp[100]; + mir_snwprintf(szTimestamp, L"%04u %02u %02u_%02u%02u", lt->tm_year + 1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min); + + wchar_t *szProto = mir_a2u(m_cache->getActiveProto()); + + wchar_t szFinalPath[MAX_PATH]; + mir_snwprintf(szFinalPath, L"%s\\%s", M.getSavedAvatarPath(), szProto); + mir_free(szProto); + + if (CreateDirectory(szFinalPath, nullptr) == 0) { + if (GetLastError() != ERROR_ALREADY_EXISTS) { + MessageBox(nullptr, TranslateT("Error creating destination directory"), + TranslateT("Save contact picture"), MB_OK | MB_ICONSTOP); + return; + } + } + + wchar_t szBaseName[MAX_PATH]; + if (isOwnPic) + mir_snwprintf(szBaseName, L"My Avatar_%s", szTimestamp); + else + mir_snwprintf(szBaseName, L"%s_%s", m_cache->getNick(), szTimestamp); + + mir_snwprintf(szFinalFilename, L"%s.png", szBaseName); + + // do not allow / or \ or % in the filename + Utils::sanitizeFilename(szFinalFilename); + + wchar_t filter[MAX_PATH]; + mir_snwprintf(filter, L"%s%c*.bmp;*.png;*.jpg;*.gif%c%c", TranslateT("Image files"), 0, 0, 0); + + OPENFILENAME ofn = { 0 }; + ofn.lpstrDefExt = L"png"; + ofn.lpstrFilter = filter; + ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING | OFN_ENABLEHOOK; + ofn.lpfnHook = OpenFileSubclass; + ofn.lStructSize = sizeof(ofn); + ofn.lpstrFile = szFinalFilename; + ofn.lpstrInitialDir = szFinalPath; + ofn.nMaxFile = MAX_PATH; + ofn.nMaxFileTitle = MAX_PATH; + ofn.lCustData = (LPARAM)& setView; + if (GetSaveFileName(&ofn)) { + if (PathFileExists(szFinalFilename)) + if (MessageBox(nullptr, TranslateT("The file exists. Do you want to overwrite it?"), TranslateT("Save contact picture"), MB_YESNO | MB_ICONQUESTION) == IDNO) + return; + + IMGSRVC_INFO ii; + ii.cbSize = sizeof(ii); + ii.pwszName = szFinalFilename; + ii.hbm = hbm; + ii.dwMask = IMGI_HBITMAP; + ii.fif = FIF_UNKNOWN; // get the format from the filename extension. png is default. + Image_Save(&ii); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::SaveSplitter() +{ + if (m_bIsAutosizingInput) + return; + + if (m_iSplitterY < DPISCALEY_S(MINSPLITTERY) || m_iSplitterY < 0) + m_iSplitterY = DPISCALEY_S(MINSPLITTERY); + + if (m_dwFlagsEx & MWF_SHOW_SPLITTEROVERRIDE) + db_set_dw(m_hContact, SRMSGMOD_T, "splitsplity", m_iSplitterY); + else { + if (m_pContainer->m_pSettings->fPrivate) + m_pContainer->m_pSettings->iSplitterY = m_iSplitterY; + else + db_set_dw(0, SRMSGMOD_T, "splitsplity", m_iSplitterY); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// send a pasted bitmap by file transfer. + +static LIST<wchar_t> vTempFilenames(5); + +void CMsgDialog::SendHBitmapAsFile(HBITMAP hbmp) const +{ + const wchar_t *mirandatempdir = L"Miranda"; + const wchar_t *filenametemplate = L"\\clp-%Y%m%d-%H%M%S0.jpg"; + wchar_t filename[MAX_PATH]; + size_t tempdirlen = GetTempPath(MAX_PATH, filename); + bool fSend = true; + + const char *szProto = m_cache->getActiveProto(); + int wMyStatus = Proto_GetStatus(szProto); + + DWORD protoCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0); + DWORD typeCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0); + + // check protocol capabilities, status modes and visibility lists (privacy) + // to determine whether the file can be sent. Throw a warning if any of + // these checks fails. + if (!(protoCaps & PF1_FILESEND)) + fSend = false; + + if ((ID_STATUS_OFFLINE == wMyStatus) || (ID_STATUS_OFFLINE == m_cache->getActiveStatus() && !(typeCaps & PF4_OFFLINEFILES))) + fSend = false; + + if (protoCaps & PF1_VISLIST && db_get_w(m_cache->getActiveContact(), szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE) + fSend = false; + + if (protoCaps & PF1_INVISLIST && wMyStatus == ID_STATUS_INVISIBLE && db_get_w(m_cache->getActiveContact(), szProto, "ApparentMode", 0) != ID_STATUS_ONLINE) + fSend = false; + + if (!fSend) { + CWarning::show(CWarning::WARN_SENDFILE, MB_OK | MB_ICONEXCLAMATION | CWarning::CWF_NOALLOWHIDE); + return; + } + + if (tempdirlen <= 0 || tempdirlen >= MAX_PATH - mir_wstrlen(mirandatempdir) - mir_wstrlen(filenametemplate) - 2) // -2 is because %Y takes 4 symbols + filename[0] = 0; // prompt for a new name + else { + mir_wstrcpy(filename + tempdirlen, mirandatempdir); + if ((GetFileAttributes(filename) == INVALID_FILE_ATTRIBUTES || ((GetFileAttributes(filename) & FILE_ATTRIBUTE_DIRECTORY) == 0)) && CreateDirectory(filename, nullptr) == 0) + filename[0] = 0; + else { + tempdirlen = mir_wstrlen(filename); + + time_t rawtime; + time(&rawtime); + const tm *timeinfo; + timeinfo = _localtime32((__time32_t *)& rawtime); + wcsftime(filename + tempdirlen, MAX_PATH - tempdirlen, filenametemplate, timeinfo); + size_t firstnumberpos = tempdirlen + 14; + size_t lastnumberpos = tempdirlen + 20; + while (GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES) { // while it exists + for (size_t pos = lastnumberpos; pos >= firstnumberpos; pos--) + if (filename[pos]++ != '9') + break; + else + if (pos == firstnumberpos) + filename[0] = 0; // all filenames exist => prompt for a new name + else + filename[pos] = '0'; + } + } + } + + if (filename[0] == 0) { // prompting to save + wchar_t filter[MAX_PATH]; + mir_snwprintf(filter, L"%s%c*.jpg%c%c", TranslateT("JPEG-compressed images"), 0, 0, 0); + + OPENFILENAME dlg; + dlg.lStructSize = sizeof(dlg); + dlg.lpstrFilter = filter; + dlg.nFilterIndex = 1; + dlg.lpstrFile = filename; + dlg.nMaxFile = MAX_PATH; + dlg.Flags = OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; + dlg.lpstrDefExt = L"jpg"; + if (!GetSaveFileName(&dlg)) + return; + } + + IMGSRVC_INFO ii; + ii.cbSize = sizeof(ii); + ii.hbm = hbmp; + ii.pwszName = filename; + ii.dwMask = IMGI_HBITMAP; + ii.fif = FIF_JPEG; + Image_Save(&ii); + + int totalCount = 0; + wchar_t **ppFiles = nullptr; + Utils::AddToFileList(&ppFiles, &totalCount, filename); + + wchar_t *_t = mir_wstrdup(filename); + vTempFilenames.insert(_t); + + CallService(MS_FILE_SENDSPECIFICFILEST, m_cache->getActiveContact(), (LPARAM)ppFiles); + + mir_free(ppFiles[0]); + mir_free(ppFiles); +} + +// remove all temporary files created by the "send clipboard as file" feature. +void TSAPI CleanTempFiles() +{ + for (auto &it : vTempFilenames) { + DeleteFileW(it); + mir_free(it); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::SetMessageLog() +{ + if (isChat()) + return; + + unsigned int iLogMode = GetIEViewMode(m_hContact); + + if (iLogMode == WANT_IEVIEW_LOG && m_hwndIEView == nullptr) { + IEVIEWWINDOW ieWindow = {}; + ieWindow.cbSize = sizeof(IEVIEWWINDOW); + ieWindow.iType = IEW_CREATE; + ieWindow.dwMode = IEWM_TABSRMM; + ieWindow.parent = m_hwnd; + ieWindow.cx = 200; + ieWindow.cy = 200; + CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)& ieWindow); + m_hwndIEView = ieWindow.hwnd; + m_log.Hide(); + m_log.Enable(false); + } + else if (iLogMode == WANT_HPP_LOG && m_hwndHPP == nullptr) { + IEVIEWWINDOW ieWindow = {}; + ieWindow.cbSize = sizeof(IEVIEWWINDOW); + ieWindow.iType = IEW_CREATE; + ieWindow.dwMode = IEWM_TABSRMM; + ieWindow.parent = m_hwnd; + ieWindow.cx = 10; + ieWindow.cy = 10; + CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)& ieWindow); + m_hwndHPP = ieWindow.hwnd; + m_log.Hide(); + m_log.Enable(false); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::ShowPicture(bool showNewPic) +{ + if (!m_pPanel.isActive()) + m_pic.cy = m_pic.cx = DPISCALEY_S(60); + + if (showNewPic) { + if (m_pPanel.isActive() && m_pContainer->m_avatarMode != 3) { + if (!m_hwndPanelPic) { + InvalidateRect(m_hwnd, nullptr, TRUE); + UpdateWindow(m_hwnd); + Resize(); + } + return; + } + AdjustBottomAvatarDisplay(); + } + else { + m_bShowAvatar = !m_bShowAvatar; + db_set_b(m_hContact, SRMSGMOD_T, "MOD_ShowPic", m_bShowAvatar); + } + + RECT rc; + GetWindowRect(GetDlgItem(m_hwnd, IDC_CONTACTPIC), &rc); + if (m_minEditBoxSize.cy + DPISCALEY_S(3) > m_iSplitterY) + SendMessage(m_hwnd, DM_SPLITTERMOVED, (WPARAM)rc.bottom - m_minEditBoxSize.cy, (LPARAM)GetDlgItem(m_hwnd, IDC_SPLITTERY)); + if (!showNewPic) + SetDialogToType(); + else + Resize(); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// show a modified context menu for the richedit control(s) + +void CMsgDialog::ShowPopupMenu(const CCtrlBase &pCtrl, POINT pt) +{ + CHARRANGE sel, all = { 0, -1 }; + + HMENU hSubMenu, hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT)); + if (pCtrl.GetCtrlId() == IDC_SRMM_LOG) + hSubMenu = GetSubMenu(hMenu, 0); + else { + hSubMenu = GetSubMenu(hMenu, 2); + EnableMenuItem(hSubMenu, IDM_PASTEFORMATTED, MF_BYCOMMAND | (m_SendFormat != 0 ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(hSubMenu, ID_EDITOR_PASTEANDSENDIMMEDIATELY, MF_BYCOMMAND | (PluginConfig.m_PasteAndSend ? MF_ENABLED : MF_GRAYED)); + CheckMenuItem(hSubMenu, ID_EDITOR_SHOWMESSAGELENGTHINDICATOR, MF_BYCOMMAND | (PluginConfig.m_visualMessageSizeIndicator ? MF_CHECKED : MF_UNCHECKED)); + EnableMenuItem(hSubMenu, ID_EDITOR_SHOWMESSAGELENGTHINDICATOR, MF_BYCOMMAND | (m_pContainer->m_hwndStatus ? MF_ENABLED : MF_GRAYED)); + } + TranslateMenu(hSubMenu); + pCtrl.SendMsg(EM_EXGETSEL, 0, (LPARAM)& sel); + if (sel.cpMin == sel.cpMax) { + EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(hSubMenu, IDM_QUOTE, MF_BYCOMMAND | MF_GRAYED); + if (pCtrl.GetCtrlId() == IDC_SRMM_MESSAGE) + EnableMenuItem(hSubMenu, IDM_CUT, MF_BYCOMMAND | MF_GRAYED); + } + + if (pCtrl.GetCtrlId() == IDC_SRMM_LOG) { + InsertMenuA(hSubMenu, 6, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr); + CheckMenuItem(hSubMenu, ID_LOG_FREEZELOG, MF_BYCOMMAND | (m_dwFlagsEx & MWF_SHOW_SCROLLINGDISABLED ? MF_CHECKED : MF_UNCHECKED)); + } + + MessageWindowPopupData mwpd; + // First notification + mwpd.uType = MSG_WINDOWPOPUP_SHOWING; + mwpd.uFlags = (pCtrl.GetCtrlId() == IDC_SRMM_LOG ? MSG_WINDOWPOPUP_LOG : MSG_WINDOWPOPUP_INPUT); + mwpd.hContact = m_hContact; + mwpd.hwnd = pCtrl.GetHwnd(); + mwpd.hMenu = hSubMenu; + mwpd.selection = 0; + mwpd.pt = pt; + NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)& mwpd); + + int iSelection = TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr); + + // Second notification + mwpd.selection = iSelection; + mwpd.uType = MSG_WINDOWPOPUP_SELECTED; + NotifyEventHooks(g_chatApi.hevWinPopup, 0, (LPARAM)& mwpd); + + switch (iSelection) { + case IDM_COPY: + pCtrl.SendMsg(WM_COPY, 0, 0); + break; + case IDM_CUT: + pCtrl.SendMsg(WM_CUT, 0, 0); + break; + case IDM_PASTE: + case IDM_PASTEFORMATTED: + if (pCtrl.GetCtrlId() == IDC_SRMM_MESSAGE) + pCtrl.SendMsg(EM_PASTESPECIAL, (iSelection == IDM_PASTE) ? CF_UNICODETEXT : 0, 0); + break; + case IDM_COPYALL: + pCtrl.SendMsg(EM_EXSETSEL, 0, (LPARAM)& all); + pCtrl.SendMsg(WM_COPY, 0, 0); + pCtrl.SendMsg(EM_EXSETSEL, 0, (LPARAM)& sel); + break; + case IDM_QUOTE: + SendMessage(m_hwnd, WM_COMMAND, IDC_QUOTE, 0); + break; + case IDM_SELECTALL: + pCtrl.SendMsg(EM_EXSETSEL, 0, (LPARAM)& all); + break; + case IDM_CLEAR: + tabClearLog(); + break; + case ID_LOG_FREEZELOG: + SendDlgItemMessage(m_hwnd, IDC_SRMM_LOG, WM_KEYDOWN, VK_F12, 0); + break; + case ID_EDITOR_SHOWMESSAGELENGTHINDICATOR: + PluginConfig.m_visualMessageSizeIndicator = !PluginConfig.m_visualMessageSizeIndicator; + db_set_b(0, SRMSGMOD_T, "msgsizebar", (BYTE)PluginConfig.m_visualMessageSizeIndicator); + Srmm_Broadcast(DM_CONFIGURETOOLBAR, 0, 0); + Resize(); + if (m_pContainer->m_hwndStatus) + RedrawWindow(m_pContainer->m_hwndStatus, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW); + break; + case ID_EDITOR_PASTEANDSENDIMMEDIATELY: + HandlePasteAndSend(); + break; + } + + if (pCtrl.GetCtrlId() == IDC_SRMM_LOG) + RemoveMenu(hSubMenu, 7, MF_BYPOSITION); + DestroyMenu(hMenu); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +bool CMsgDialog::TabAutoComplete() +{ + LRESULT lResult = m_message.SendMsg(EM_GETSEL, 0, 0); + int start = LOWORD(lResult), end = HIWORD(lResult); + m_message.SendMsg(EM_SETSEL, end, end); + + GETTEXTEX gt = { 0 }; + gt.codepage = 1200; + gt.flags = GTL_DEFAULT | GTL_PRECISE; + int iLen = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)& gt, 0); + if (iLen <= 0) + return false; + + bool isTopic = false, isRoom = false; + wchar_t *pszName = nullptr; + wchar_t *pszText = (wchar_t *)mir_calloc((iLen + 10) * sizeof(wchar_t)); + + gt.flags = GT_DEFAULT; + gt.cb = (iLen + 9) * sizeof(wchar_t); + m_message.SendMsg(EM_GETTEXTEX, (WPARAM)& gt, (LPARAM)pszText); + + if (start > 1 && pszText[start - 1] == ' ' && pszText[start - 2] == ':') + start -= 2; + + 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; + } + } + + while (start > 0 && pszText[start - 1] != ' ' && pszText[start - 1] != 13 && pszText[start - 1] != VK_TAB) + start--; + +LBL_SkipEnd: + while (end < iLen && pszText[end] != ' ' && pszText[end] != 13 && pszText[end - 1] != VK_TAB) + end++; + + if (pszText[start] == '#') + isRoom = true; + else { + int topicStart = start; + while (topicStart > 0 && (pszText[topicStart - 1] == ' ' || pszText[topicStart - 1] == 13 || pszText[topicStart - 1] == VK_TAB)) + topicStart--; + if (topicStart > 5 && wcsstr(&pszText[topicStart - 6], L"/topic") == &pszText[topicStart - 6]) + isTopic = true; + } + if (m_wszSearchQuery == nullptr) { + m_wszSearchQuery = mir_wstrndup(pszText + start, end - start); + m_wszSearchResult = mir_wstrdup(m_wszSearchQuery); + m_pLastSession = nullptr; + } + if (isTopic) + pszName = m_si->ptszTopic; + else if (isRoom) { + 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 = g_chatApi.UM_FindUserAutoComplete(m_si, m_wszSearchQuery, m_wszSearchResult); + + replaceStrW(m_wszSearchResult, nullptr); + + if (pszName != nullptr) { + m_wszSearchResult = mir_wstrdup(pszName); + if (end != start) { + ptrW szReplace; + if (!isRoom && !isTopic && g_Settings.bAddColonToAutoComplete && start == 0) { + szReplace = (wchar_t *)mir_alloc((mir_wstrlen(pszName) + 4) * sizeof(wchar_t)); + mir_wstrcpy(szReplace, pszName); + mir_wstrcat(szReplace, g_Settings.bUseCommaAsColon ? L", " : L": "); + pszName = szReplace; + } + m_message.SendMsg(EM_SETSEL, start, end); + m_message.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)pszName); + } + return true; + } + + if (end != start) { + m_message.SendMsg(EM_SETSEL, start, end); + m_message.SendMsg(EM_REPLACESEL, TRUE, (LPARAM)m_wszSearchQuery); + } + replaceStrW(m_wszSearchQuery, nullptr); + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::tabClearLog() +{ + if (isChat()) { + SESSION_INFO *s = g_chatApi.SM_FindSession(m_si->ptszID, m_si->pszModule); + if (s) { + ClearLog(); + g_chatApi.LM_RemoveAll(&s->pLog, &s->pLogEnd); + s->iEventCount = 0; + s->LastTime = 0; + m_si->iEventCount = 0; + m_si->LastTime = 0; + m_si->pLog = s->pLog; + m_si->pLogEnd = s->pLogEnd; + PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0); + } + } + else { + if (m_hwndIEView || m_hwndHPP) { + IEVIEWEVENT event; + event.cbSize = sizeof(IEVIEWEVENT); + event.iType = IEE_CLEAR_LOG; + event.dwFlags = (m_dwFlags & MWF_LOG_RTL) ? IEEF_RTL : 0; + event.hContact = m_hContact; + if (m_hwndIEView) { + event.hwnd = m_hwndIEView; + CallService(MS_IEVIEW_EVENT, 0, (LPARAM) & event); + } + else { + event.hwnd = m_hwndHPP; + CallService(MS_HPP_EG_EVENT, 0, (LPARAM) & event); + } + } + m_log.SetText(L""); + m_hDbEventFirst = 0; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +CThumbBase *CMsgDialog::tabCreateThumb(CProxyWindow *pProxy) const +{ + if (isChat()) + return new CThumbMUC(pProxy, m_si); + + return new CThumbIM(pProxy); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// update all status bar fields and force a redraw of the status bar. + +void CMsgDialog::tabUpdateStatusBar() const +{ + if (m_pContainer->m_hwndStatus && m_pContainer->m_hwndActive == m_hwnd) { + if (!isChat()) { + if (m_wszStatusBar[0]) { + SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, (LPARAM)PluginConfig.g_buttonBarIcons[ICON_DEFAULT_TYPING]); + SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)m_wszStatusBar); + } + else if (m_bStatusSet) { + SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, (LPARAM)m_szStatusIcon); + SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)m_szStatusText.c_str()); + } + else { + SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, 0); + DM_UpdateLastMessage(); + } + } + else { + if (m_bStatusSet) { + SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, (LPARAM)m_szStatusIcon); + SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)m_szStatusText.c_str()); + } + else SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, 0); + } + UpdateReadChars(); + InvalidateRect(m_pContainer->m_hwndStatus, nullptr, TRUE); + SendMessage(m_pContainer->m_hwndStatus, WM_USER + 101, 0, (LPARAM)this); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// update the status bar field which displays the number of characters in the input area +// and various indicators (caps lock, num lock, insert mode). + +void CMsgDialog::UpdateReadChars() const +{ + if (!m_pContainer->m_hwndStatus || m_pContainer->m_hwndActive != m_hwnd) + return; + + int len; + if (isChat()) + len = GetWindowTextLength(m_message.GetHwnd()); + else { + // retrieve text length in UTF8 bytes, because this is the relevant length for most protocols + GETTEXTLENGTHEX gtxl = { 0 }; + gtxl.codepage = CP_UTF8; + gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMBYTES; + + len = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); + } + + BOOL fCaps = (GetKeyState(VK_CAPITAL) & 1); + BOOL fNum = (GetKeyState(VK_NUMLOCK) & 1); + + wchar_t szBuf[20]; szBuf[0] = 0; + if (m_bInsertMode) + mir_wstrcat(szBuf, L"O"); + if (fCaps) + mir_wstrcat(szBuf, L"C"); + if (fNum) + mir_wstrcat(szBuf, L"N"); + if (m_bInsertMode || fCaps || fNum) + mir_wstrcat(szBuf, L" | "); + + wchar_t buf[128]; + mir_snwprintf(buf, L"%s%s %d/%d", szBuf, m_lcID, m_iOpenJobs, len); + SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 1, (LPARAM)buf); + if (PluginConfig.m_visualMessageSizeIndicator) + InvalidateRect(m_pContainer->m_hwndStatus, nullptr, FALSE); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +void CMsgDialog::UpdateSaveAndSendButton() +{ + GETTEXTLENGTHEX gtxl = { 0 }; + gtxl.codepage = CP_UTF8; + gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMBYTES; + + int len = SendDlgItemMessage(m_hwnd, IDC_SRMM_MESSAGE, EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0); + if (len && GetSendButtonState(m_hwnd) == PBS_DISABLED) + EnableSendButton(true); + else if (len == 0 && GetSendButtonState(m_hwnd) != PBS_DISABLED) + EnableSendButton(false); + + if (len) { // looks complex but avoids flickering on the button while typing. + if (!(m_dwFlags & MWF_SAVEBTN_SAV)) { + SendDlgItemMessage(m_hwnd, IDC_CLOSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)PluginConfig.g_buttonBarIcons[ICON_BUTTON_SAVE]); + SendDlgItemMessage(m_hwnd, IDC_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Save and close session"), BATF_UNICODE); + m_dwFlags |= MWF_SAVEBTN_SAV; + } + } + else { + SendDlgItemMessage(m_hwnd, IDC_CLOSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)PluginConfig.g_buttonBarIcons[ICON_BUTTON_CANCEL]); + SendDlgItemMessage(m_hwnd, IDC_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Close session"), BATF_UNICODE); + m_dwFlags &= ~MWF_SAVEBTN_SAV; + } + m_textLen = len; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// generic handler for the WM_COPY message in message log/chat history richedit control(s). +// it filters out the invisible event boundary markers from the text copied to the clipboard. +// WINE Fix: overwrite clippboad data from original control data + +LRESULT CMsgDialog::WMCopyHandler(UINT msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result = mir_callNextSubclass(m_log.GetHwnd(), stubLogProc, msg, wParam, lParam); + + ptrA szFromStream(m_log.GetRichTextRtf(true, true)); + if (szFromStream != nullptr) { + ptrW converted(mir_utf8decodeW(szFromStream)); + if (converted != nullptr) { + Utils::FilterEventMarkers(converted); + Utils::CopyToClipBoard(converted, m_log.GetHwnd()); + } + } + + return result; +} diff --git a/plugins/TabSRMM/src/msgdlgutils.cpp b/plugins/TabSRMM/src/msgdlgutils.cpp index 02a7fdeb0f..17ff931222 100644 --- a/plugins/TabSRMM/src/msgdlgutils.cpp +++ b/plugins/TabSRMM/src/msgdlgutils.cpp @@ -66,11 +66,89 @@ bool TSAPI IsCustomEvent(int eventType) }
/////////////////////////////////////////////////////////////////////////////////////////
+// checking if theres's protected text at the point
+// emulates EN_LINK WM_NOTIFY to parent to process links
+
+BOOL TSAPI CheckCustomLink(HWND hwndRich, POINT *ptClient, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bUrlNeeded)
+{
+ long res = 0, cnt = 0;
+ long cpMin = 0, cpMax = 0;
+ POINT ptEnd = { 0 };
+ IRichEditOle *RichEditOle = nullptr;
+ ITextDocument *TextDocument = nullptr;
+ ITextRange *TextRange = nullptr;
+ ITextFont *TextFont = nullptr;
+ BOOL bIsCustomLink = FALSE;
+
+ POINT pt = *ptClient;
+ ClientToScreen(hwndRich, &pt);
+
+ do {
+ if (!SendMessage(hwndRich, EM_GETOLEINTERFACE, 0, (LPARAM)& RichEditOle)) break;
+ if (RichEditOle->QueryInterface(IID_ITextDocument, (void **)& TextDocument) != S_OK) break;
+ if (TextDocument->RangeFromPoint(pt.x, pt.y, &TextRange) != S_OK) break;
+
+ TextRange->GetStart(&cpMin);
+ cpMax = cpMin + 1;
+ TextRange->SetEnd(cpMax);
+
+ if (TextRange->GetFont(&TextFont) != S_OK)
+ break;
+
+ TextFont->GetProtected(&res);
+ if (res != tomTrue)
+ break;
+
+ TextRange->GetPoint(tomEnd + TA_BOTTOM + TA_RIGHT, &ptEnd.x, &ptEnd.y);
+ if (pt.x > ptEnd.x || pt.y > ptEnd.y)
+ break;
+
+ if (bUrlNeeded) {
+ TextRange->GetStoryLength(&cnt);
+ for (; cpMin > 0; cpMin--) {
+ res = tomTrue;
+ TextRange->SetIndex(tomCharacter, cpMin + 1, tomTrue);
+ TextFont->GetProtected(&res);
+ if (res != tomTrue) { cpMin++; break; }
+ }
+ for (cpMax--; cpMax < cnt; cpMax++) {
+ res = tomTrue;
+ TextRange->SetIndex(tomCharacter, cpMax + 1, tomTrue);
+ TextFont->GetProtected(&res);
+ if (res != tomTrue)
+ break;
+ }
+ }
+
+ bIsCustomLink = (cpMin < cpMax);
+ } while (FALSE);
+
+ if (TextFont) TextFont->Release();
+ if (TextRange) TextRange->Release();
+ if (TextDocument) TextDocument->Release();
+ if (RichEditOle) RichEditOle->Release();
+
+ if (bIsCustomLink) {
+ ENLINK enlink = {};
+ enlink.nmhdr.hwndFrom = hwndRich;
+ enlink.nmhdr.idFrom = IDC_SRMM_LOG;
+ enlink.nmhdr.code = EN_LINK;
+ enlink.msg = uMsg;
+ enlink.wParam = wParam;
+ enlink.lParam = lParam;
+ enlink.chrg.cpMin = cpMin;
+ enlink.chrg.cpMax = cpMax;
+ SendMessage(GetParent(hwndRich), WM_NOTIFY, IDC_SRMM_LOG, (LPARAM)& enlink);
+ }
+ return bIsCustomLink;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
// reorder tabs within a container. bSavePos indicates whether the new position should
// be saved to the contacts db record (if so, the container will try to open the tab
// at the saved position later)
-void TSAPI RearrangeTab(HWND hwndDlg, const CTabBaseDlg *dat, int iMode, BOOL bSavePos)
+void TSAPI RearrangeTab(HWND hwndDlg, const CMsgDialog *dat, int iMode, BOOL bSavePos)
{
if (dat == nullptr || !IsWindow(hwndDlg))
return;
@@ -100,7 +178,7 @@ void TSAPI RearrangeTab(HWND hwndDlg, const CTabBaseDlg *dat, int iMode, BOOL bS // subclassing for the save as file dialog (needed to set it to thumbnail view on Windows 2000
// or later
-static UINT_PTR CALLBACK OpenFileSubclass(HWND hwnd, UINT msg, WPARAM, LPARAM lParam)
+UINT_PTR CALLBACK OpenFileSubclass(HWND hwnd, UINT msg, WPARAM, LPARAM lParam)
{
switch (msg) {
case WM_INITDIALOG:
@@ -122,389 +200,13 @@ static UINT_PTR CALLBACK OpenFileSubclass(HWND hwnd, UINT msg, WPARAM, LPARAM lP }
/////////////////////////////////////////////////////////////////////////////////////////
-// saves a contact picture to disk
-// takes hbm (bitmap handle) and bool isOwnPic (1 == save the picture as your own avatar)
-// requires AVS service (Miranda 0.7+)
-
-static void SaveAvatarToFile(CTabBaseDlg *dat, HBITMAP hbm, int isOwnPic)
-{
- wchar_t szFinalFilename[MAX_PATH];
- time_t t = time(0);
- struct tm *lt = localtime(&t);
- DWORD setView = 1;
-
- wchar_t szTimestamp[100];
- mir_snwprintf(szTimestamp, L"%04u %02u %02u_%02u%02u", lt->tm_year + 1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min);
-
- wchar_t *szProto = mir_a2u(dat->m_cache->getActiveProto());
-
- wchar_t szFinalPath[MAX_PATH];
- mir_snwprintf(szFinalPath, L"%s\\%s", M.getSavedAvatarPath(), szProto);
- mir_free(szProto);
-
- if (CreateDirectory(szFinalPath, nullptr) == 0) {
- if (GetLastError() != ERROR_ALREADY_EXISTS) {
- MessageBox(nullptr, TranslateT("Error creating destination directory"),
- TranslateT("Save contact picture"), MB_OK | MB_ICONSTOP);
- return;
- }
- }
-
- wchar_t szBaseName[MAX_PATH];
- if (isOwnPic)
- mir_snwprintf(szBaseName, L"My Avatar_%s", szTimestamp);
- else
- mir_snwprintf(szBaseName, L"%s_%s", dat->m_cache->getNick(), szTimestamp);
-
- mir_snwprintf(szFinalFilename, L"%s.png", szBaseName);
-
- // do not allow / or \ or % in the filename
- Utils::sanitizeFilename(szFinalFilename);
-
- wchar_t filter[MAX_PATH];
- mir_snwprintf(filter, L"%s%c*.bmp;*.png;*.jpg;*.gif%c%c", TranslateT("Image files"), 0, 0, 0);
-
- OPENFILENAME ofn = { 0 };
- ofn.lpstrDefExt = L"png";
- ofn.lpstrFilter = filter;
- ofn.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLESIZING | OFN_ENABLEHOOK;
- ofn.lpfnHook = OpenFileSubclass;
- ofn.lStructSize = sizeof(ofn);
- ofn.lpstrFile = szFinalFilename;
- ofn.lpstrInitialDir = szFinalPath;
- ofn.nMaxFile = MAX_PATH;
- ofn.nMaxFileTitle = MAX_PATH;
- ofn.lCustData = (LPARAM)&setView;
- if (GetSaveFileName(&ofn)) {
- if (PathFileExists(szFinalFilename))
- if (MessageBox(nullptr, TranslateT("The file exists. Do you want to overwrite it?"), TranslateT("Save contact picture"), MB_YESNO | MB_ICONQUESTION) == IDNO)
- return;
-
- IMGSRVC_INFO ii;
- ii.cbSize = sizeof(ii);
- ii.pwszName = szFinalFilename;
- ii.hbm = hbm;
- ii.dwMask = IMGI_HBITMAP;
- ii.fif = FIF_UNKNOWN; // get the format from the filename extension. png is default.
- Image_Save(&ii);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// flash a tab icon if mode = true, otherwise restore default icon
-// store flashing state into bState
-
-void CTabBaseDlg::FlashTab(bool bInvertMode)
-{
- if (bInvertMode)
- m_bTabFlash = !m_bTabFlash;
-
- TCITEM item = {};
- item.mask = TCIF_IMAGE;
- TabCtrl_SetItem(m_hwndParent, m_iTabID, &item);
- if (m_pContainer->m_dwFlags & CNT_SIDEBAR)
- m_pContainer->m_pSideBar->updateSession(this);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// calculates avatar layouting, based on splitter position to find the optimal size
-// for the avatar w/o disturbing the toolbar too much.
-
-void CTabBaseDlg::CalcDynamicAvatarSize(BITMAP *bminfo)
-{
- if (m_dwFlags & MWF_WASBACKGROUNDCREATE || m_pContainer->m_dwFlags & CNT_DEFERREDCONFIGURE || m_pContainer->m_dwFlags & CNT_CREATE_MINIMIZED || IsIconic(m_pContainer->m_hwnd))
- return; // at this stage, the layout is not yet ready...
-
- RECT rc;
- GetClientRect(m_hwnd, &rc);
-
- BOOL bBottomToolBar = m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR;
- BOOL bToolBar = m_pContainer->m_dwFlags & CNT_HIDETOOLBAR ? 0 : 1;
- int iSplitOffset = m_bIsAutosizingInput ? 1 : 0;
-
- double picAspect = (bminfo->bmWidth == 0 || bminfo->bmHeight == 0) ? 1.0 : (double)(bminfo->bmWidth / (double)bminfo->bmHeight);
- double picProjectedWidth = (double)((m_dynaSplitter - ((bBottomToolBar && bToolBar) ? DPISCALEX_S(24) : 0) + ((m_bShowUIElements) ? DPISCALEX_S(28) : DPISCALEX_S(2)))) * picAspect;
-
- if ((rc.right - (int)picProjectedWidth) > (m_iButtonBarReallyNeeds) && !PluginConfig.m_bAlwaysFullToolbarWidth && bToolBar)
- m_iRealAvatarHeight = m_dynaSplitter + 3 + (m_bShowUIElements ? DPISCALEY_S(28) : DPISCALEY_S(2));
- else
- m_iRealAvatarHeight = m_dynaSplitter + DPISCALEY_S(6) + DPISCALEY_S(iSplitOffset);
-
- m_iRealAvatarHeight -= ((bBottomToolBar&&bToolBar) ? DPISCALEY_S(22) : 0);
-
- if (PluginConfig.m_LimitStaticAvatarHeight > 0)
- m_iRealAvatarHeight = min(m_iRealAvatarHeight, PluginConfig.m_LimitStaticAvatarHeight);
-
- if (M.GetByte(m_hContact, "dontscaleavatars", M.GetByte("dontscaleavatars", 0)))
- m_iRealAvatarHeight = min(bminfo->bmHeight, m_iRealAvatarHeight);
-
- double aspect = (bminfo->bmHeight != 0) ? (double)m_iRealAvatarHeight / (double)bminfo->bmHeight : 1.0;
- double newWidth = (double)bminfo->bmWidth * aspect;
- if (newWidth > (double)(rc.right) * 0.8)
- newWidth = (double)(rc.right) * 0.8;
- m_pic.cy = m_iRealAvatarHeight + 2;
- m_pic.cx = (int)newWidth + 2;
-}
-
-int CTabBaseDlg::MsgWindowUpdateMenu(HMENU submenu, int menuID)
-{
- bool bInfoPanel = m_pPanel.isActive();
-
- if (menuID == MENU_TABCONTEXT) {
- EnableMenuItem(submenu, ID_TABMENU_LEAVECHATROOM, (isChat() && ProtoServiceExists(m_szProto, PS_LEAVECHAT)) ? MF_ENABLED : MF_DISABLED);
- EnableMenuItem(submenu, ID_TABMENU_ATTACHTOCONTAINER, (M.GetByte("useclistgroups", 0) || M.GetByte("singlewinmode", 0)) ? MF_GRAYED : MF_ENABLED);
- EnableMenuItem(submenu, ID_TABMENU_CLEARSAVEDTABPOSITION, (M.GetDword(m_hContact, "tabindex", -1) != -1) ? MF_ENABLED : MF_GRAYED);
- }
- else if (menuID == MENU_PICMENU) {
- wchar_t *szText = nullptr;
- char avOverride = (char)M.GetByte(m_hContact, "hideavatar", -1);
- HMENU visMenu = GetSubMenu(submenu, 0);
- BOOL picValid = bInfoPanel ? (m_hOwnPic != nullptr) : (m_ace && m_ace->hbmPic && m_ace->hbmPic != PluginConfig.g_hbmUnknown);
-
- MENUITEMINFO mii = { 0 };
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STRING;
-
- EnableMenuItem(submenu, ID_PICMENU_SAVETHISPICTUREAS, MF_BYCOMMAND | (picValid ? MF_ENABLED : MF_GRAYED));
-
- CheckMenuItem(visMenu, ID_VISIBILITY_DEFAULT, MF_BYCOMMAND | (avOverride == -1 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(visMenu, ID_VISIBILITY_HIDDENFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 0 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(visMenu, ID_VISIBILITY_VISIBLEFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 1 ? MF_CHECKED : MF_UNCHECKED));
-
- CheckMenuItem(submenu, ID_PICMENU_ALWAYSKEEPTHEBUTTONBARATFULLWIDTH, MF_BYCOMMAND | (PluginConfig.m_bAlwaysFullToolbarWidth ? MF_CHECKED : MF_UNCHECKED));
- if (!bInfoPanel) {
- EnableMenuItem(submenu, ID_PICMENU_SETTINGS, MF_BYCOMMAND | (ServiceExists(MS_AV_GETAVATARBITMAP) ? MF_ENABLED : MF_GRAYED));
- szText = TranslateT("Contact picture settings...");
- EnableMenuItem(submenu, 0, MF_BYPOSITION | MF_ENABLED);
- }
- else {
- EnableMenuItem(submenu, 0, MF_BYPOSITION | MF_GRAYED);
- EnableMenuItem(submenu, ID_PICMENU_SETTINGS, MF_BYCOMMAND | ((ServiceExists(MS_AV_SETMYAVATARW) && CallService(MS_AV_CANSETMYAVATAR, (WPARAM)(m_cache->getActiveProto()), 0)) ? MF_ENABLED : MF_GRAYED));
- szText = TranslateT("Set your avatar...");
- }
- mii.dwTypeData = szText;
- mii.cch = (int)mir_wstrlen(szText) + 1;
- SetMenuItemInfo(submenu, ID_PICMENU_SETTINGS, FALSE, &mii);
- }
- else if (menuID == MENU_PANELPICMENU) {
- HMENU visMenu = GetSubMenu(submenu, 0);
- char avOverride = (char)M.GetByte(m_hContact, "hideavatar", -1);
-
- CheckMenuItem(visMenu, ID_VISIBILITY_DEFAULT, MF_BYCOMMAND | (avOverride == -1 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(visMenu, ID_VISIBILITY_HIDDENFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 0 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(visMenu, ID_VISIBILITY_VISIBLEFORTHISCONTACT, MF_BYCOMMAND | (avOverride == 1 ? MF_CHECKED : MF_UNCHECKED));
-
- EnableMenuItem(submenu, ID_PICMENU_SETTINGS, MF_BYCOMMAND | (ServiceExists(MS_AV_GETAVATARBITMAP) ? MF_ENABLED : MF_GRAYED));
- EnableMenuItem(submenu, ID_PANELPICMENU_SAVETHISPICTUREAS, MF_BYCOMMAND | ((m_ace && m_ace->hbmPic && m_ace->hbmPic != PluginConfig.g_hbmUnknown) ? MF_ENABLED : MF_GRAYED));
- }
- return 0;
-}
-
-int CTabBaseDlg::MsgWindowMenuHandler(int selection, int menuId)
-{
- if (menuId == MENU_PICMENU || menuId == MENU_PANELPICMENU || menuId == MENU_TABCONTEXT) {
- switch (selection) {
- case ID_TABMENU_ATTACHTOCONTAINER:
- CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_SELECTCONTAINER), m_hwnd, SelectContainerDlgProc, (LPARAM)m_hwnd);
- return 1;
- case ID_TABMENU_CONTAINEROPTIONS:
- if (m_pContainer->m_hWndOptions == nullptr)
- CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_CONTAINEROPTIONS), m_hwnd, DlgProcContainerOptions, (LPARAM)m_pContainer);
- return 1;
- case ID_TABMENU_CLOSECONTAINER:
- SendMessage(m_pContainer->m_hwnd, WM_CLOSE, 0, 0);
- return 1;
- case ID_TABMENU_CLOSETAB:
- PostMessage(m_hwnd, WM_CLOSE, 1, 0);
- return 1;
- case ID_TABMENU_SAVETABPOSITION:
- db_set_dw(m_hContact, SRMSGMOD_T, "tabindex", m_iTabID * 100);
- break;
- case ID_TABMENU_CLEARSAVEDTABPOSITION:
- db_unset(m_hContact, SRMSGMOD_T, "tabindex");
- break;
- case ID_TABMENU_LEAVECHATROOM:
- if (isChat() && m_hContact != 0) {
- char *szProto = GetContactProto(m_hContact);
- if (szProto)
- CallProtoService(szProto, PS_LEAVECHAT, m_hContact, 0);
- }
- return 1;
-
- case ID_VISIBILITY_DEFAULT:
- case ID_VISIBILITY_HIDDENFORTHISCONTACT:
- case ID_VISIBILITY_VISIBLEFORTHISCONTACT:
- {
- BYTE avOverrideMode;
- if (selection == ID_VISIBILITY_DEFAULT)
- avOverrideMode = -1;
- else if (selection == ID_VISIBILITY_VISIBLEFORTHISCONTACT)
- avOverrideMode = 1;
- else
- avOverrideMode = 0;
- db_set_b(m_hContact, SRMSGMOD_T, "hideavatar", avOverrideMode);
- }
-
- ShowPicture(false);
- Resize();
- DM_ScrollToBottom(0, 1);
- return 1;
-
- case ID_PICMENU_ALWAYSKEEPTHEBUTTONBARATFULLWIDTH:
- PluginConfig.m_bAlwaysFullToolbarWidth = !PluginConfig.m_bAlwaysFullToolbarWidth;
- db_set_b(0, SRMSGMOD_T, "alwaysfulltoolbar", (BYTE)PluginConfig.m_bAlwaysFullToolbarWidth);
- Srmm_Broadcast(DM_CONFIGURETOOLBAR, 0, 1);
- break;
-
- case ID_PICMENU_SAVETHISPICTUREAS:
- if (m_pPanel.isActive())
- SaveAvatarToFile(this, m_hOwnPic, 1);
- else if (m_ace)
- SaveAvatarToFile(this, m_ace->hbmPic, 0);
- break;
-
- case ID_PANELPICMENU_SAVETHISPICTUREAS:
- if (m_ace)
- SaveAvatarToFile(this, m_ace->hbmPic, 0);
- break;
-
- case ID_PICMENU_SETTINGS:
- if (menuId == MENU_PANELPICMENU)
- CallService(MS_AV_CONTACTOPTIONS, m_hContact, 0);
- else if (menuId == MENU_PICMENU) {
- if (m_pPanel.isActive()) {
- if (ServiceExists(MS_AV_SETMYAVATARW) && CallService(MS_AV_CANSETMYAVATAR, (WPARAM)(m_cache->getActiveProto()), 0))
- CallService(MS_AV_SETMYAVATARW, (WPARAM)(m_cache->getActiveProto()), 0);
- }
- else
- CallService(MS_AV_CONTACTOPTIONS, m_hContact, 0);
- }
- return 1;
- }
- }
- else if (menuId == MENU_LOGMENU) {
- switch (selection) {
- case ID_MESSAGELOGSETTINGS_GLOBAL:
- g_plugin.openOptions(nullptr, L"Message sessions", L"Message log");
- return 1;
-
- case ID_MESSAGELOGSETTINGS_FORTHISCONTACT:
- CallService(MS_TABMSG_SETUSERPREFS, m_hContact, 0);
- return 1;
- }
- }
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// update the status bar field which displays the number of characters in the input area
-// and various indicators (caps lock, num lock, insert mode).
-
-void CTabBaseDlg::UpdateReadChars() const
-{
- if (!m_pContainer->m_hwndStatus || m_pContainer->m_hwndActive != m_hwnd)
- return;
-
- int len;
- if (isChat())
- len = GetWindowTextLength(m_message.GetHwnd());
- else {
- // retrieve text length in UTF8 bytes, because this is the relevant length for most protocols
- GETTEXTLENGTHEX gtxl = { 0 };
- gtxl.codepage = CP_UTF8;
- gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMBYTES;
-
- len = m_message.SendMsg(EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0);
- }
-
- BOOL fCaps = (GetKeyState(VK_CAPITAL) & 1);
- BOOL fNum = (GetKeyState(VK_NUMLOCK) & 1);
-
- wchar_t szBuf[20]; szBuf[0] = 0;
- if (m_bInsertMode)
- mir_wstrcat(szBuf, L"O");
- if (fCaps)
- mir_wstrcat(szBuf, L"C");
- if (fNum)
- mir_wstrcat(szBuf, L"N");
- if (m_bInsertMode || fCaps || fNum)
- mir_wstrcat(szBuf, L" | ");
-
- wchar_t buf[128];
- mir_snwprintf(buf, L"%s%s %d/%d", szBuf, m_lcID, m_iOpenJobs, len);
- SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 1, (LPARAM)buf);
- if (PluginConfig.m_visualMessageSizeIndicator)
- InvalidateRect(m_pContainer->m_hwndStatus, nullptr, FALSE);
-}
-
-void CTabBaseDlg::UpdateSaveAndSendButton()
-{
- GETTEXTLENGTHEX gtxl = { 0 };
- gtxl.codepage = CP_UTF8;
- gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMBYTES;
-
- int len = SendDlgItemMessage(m_hwnd, IDC_SRMM_MESSAGE, EM_GETTEXTLENGTHEX, (WPARAM)>xl, 0);
- if (len && GetSendButtonState(m_hwnd) == PBS_DISABLED)
- EnableSendButton(true);
- else if (len == 0 && GetSendButtonState(m_hwnd) != PBS_DISABLED)
- EnableSendButton(false);
-
- if (len) { // looks complex but avoids flickering on the button while typing.
- if (!(m_dwFlags & MWF_SAVEBTN_SAV)) {
- SendDlgItemMessage(m_hwnd, IDC_CLOSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)PluginConfig.g_buttonBarIcons[ICON_BUTTON_SAVE]);
- SendDlgItemMessage(m_hwnd, IDC_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Save and close session"), BATF_UNICODE);
- m_dwFlags |= MWF_SAVEBTN_SAV;
- }
- }
- else {
- SendDlgItemMessage(m_hwnd, IDC_CLOSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)PluginConfig.g_buttonBarIcons[ICON_BUTTON_CANCEL]);
- SendDlgItemMessage(m_hwnd, IDC_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Close session"), BATF_UNICODE);
- m_dwFlags &= ~MWF_SAVEBTN_SAV;
- }
- m_textLen = len;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// update all status bar fields and force a redraw of the status bar.
-
-void CTabBaseDlg::tabUpdateStatusBar() const
-{
- if (m_pContainer->m_hwndStatus && m_pContainer->m_hwndActive == m_hwnd) {
- if (!isChat()) {
- if (m_wszStatusBar[0]) {
- SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, (LPARAM)PluginConfig.g_buttonBarIcons[ICON_DEFAULT_TYPING]);
- SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)m_wszStatusBar);
- }
- else if (m_bStatusSet) {
- SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, (LPARAM)m_szStatusIcon);
- SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)m_szStatusText.c_str());
- }
- else {
- SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, 0);
- DM_UpdateLastMessage();
- }
- }
- else {
- if (m_bStatusSet) {
- SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, (LPARAM)m_szStatusIcon);
- SendMessage(m_pContainer->m_hwndStatus, SB_SETTEXT, 0, (LPARAM)m_szStatusText.c_str());
- }
- else SendMessage(m_pContainer->m_hwndStatus, SB_SETICON, 0, 0);
- }
- UpdateReadChars();
- InvalidateRect(m_pContainer->m_hwndStatus, nullptr, TRUE);
- SendMessage(m_pContainer->m_hwndStatus, WM_USER + 101, 0, (LPARAM)this);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
// provide user feedback via icons on tabs.Used to indicate "send in progress" or
// any error state.
//
// NOT used for typing notification feedback as this is handled directly from the
// MTN handler.
-void TSAPI HandleIconFeedback(CTabBaseDlg *dat, HICON iIcon)
+void TSAPI HandleIconFeedback(CMsgDialog *dat, HICON iIcon)
{
TCITEM item = {};
@@ -531,7 +233,7 @@ void TSAPI ProcessAvatarChange(HWND hwnd, LPARAM lParam) {
if (((LPNMHDR)lParam)->code == NM_AVATAR_CHANGED) {
HWND hwndDlg = GetParent(hwnd);
- CTabBaseDlg *dat = (CTabBaseDlg*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
if (!dat)
return;
@@ -545,93 +247,6 @@ void TSAPI ProcessAvatarChange(HWND hwnd, LPARAM lParam) }
/////////////////////////////////////////////////////////////////////////////////////////
-// retrieve the visiblity of the avatar window, depending on the global setting
-// and local mode
-
-bool CTabBaseDlg::GetAvatarVisibility()
-{
- BYTE bAvatarMode = m_pContainer->m_avatarMode;
- BYTE bOwnAvatarMode = m_pContainer->m_ownAvatarMode;
- char hideOverride = (char)M.GetByte(m_hContact, "hideavatar", -1);
-
- // infopanel visible, consider own avatar display
- m_bShowAvatar = false;
-
- if (m_pPanel.isActive() && bAvatarMode != 3) {
- if (!bOwnAvatarMode) {
- m_bShowAvatar = (m_hOwnPic && m_hOwnPic != PluginConfig.g_hbmUnknown);
- if (!m_hwndContactPic)
- m_hwndContactPic = CreateWindowEx(WS_EX_TOPMOST, AVATAR_CONTROL_CLASS, L"", WS_VISIBLE | WS_CHILD, 1, 1, 1, 1, GetDlgItem(m_hwnd, IDC_CONTACTPIC), (HMENU)nullptr, nullptr, nullptr);
- }
-
- switch (bAvatarMode) {
- case 2:
- m_bShowInfoAvatar = false;
- break;
- case 0:
- m_bShowInfoAvatar = true;
- case 1:
- HBITMAP hbm = ((m_ace && !(m_ace->dwFlags & AVS_HIDEONCLIST)) ? m_ace->hbmPic : nullptr);
- if (hbm == nullptr && !bAvatarMode) {
- m_bShowInfoAvatar = false;
- break;
- }
-
- if (!m_hwndPanelPic) {
- m_hwndPanelPic = CreateWindowEx(WS_EX_TOPMOST, AVATAR_CONTROL_CLASS, L"", WS_VISIBLE | WS_CHILD, 1, 1, 1, 1, m_hwndPanelPicParent, (HMENU)7000, nullptr, nullptr);
- if (m_hwndPanelPic)
- SendMessage(m_hwndPanelPic, AVATAR_SETAEROCOMPATDRAWING, 0, TRUE);
- }
-
- if (bAvatarMode != 0)
- m_bShowInfoAvatar = (hbm && hbm != PluginConfig.g_hbmUnknown);
- break;
- }
-
- if (m_bShowInfoAvatar)
- m_bShowInfoAvatar = hideOverride == 0 ? false : m_bShowInfoAvatar;
- else
- m_bShowInfoAvatar = hideOverride == 1 ? true : m_bShowInfoAvatar;
-
- Utils::setAvatarContact(m_hwndPanelPic, m_hContact);
- SendMessage(m_hwndContactPic, AVATAR_SETPROTOCOL, 0, (LPARAM)m_cache->getActiveProto());
- }
- else {
- m_bShowInfoAvatar = false;
-
- switch (bAvatarMode) {
- case 0: // globally on
- m_bShowAvatar = true;
-LBL_Check:
- if (!m_hwndContactPic)
- m_hwndContactPic = CreateWindowEx(WS_EX_TOPMOST, AVATAR_CONTROL_CLASS, L"", WS_VISIBLE | WS_CHILD, 1, 1, 1, 1, GetDlgItem(m_hwnd, IDC_CONTACTPIC), (HMENU)nullptr, nullptr, nullptr);
- break;
- case 2: // globally OFF
- m_bShowAvatar = false;
- break;
- case 3: // on, if present
- case 1:
- HBITMAP hbm = (m_ace && !(m_ace->dwFlags & AVS_HIDEONCLIST)) ? m_ace->hbmPic : nullptr;
- m_bShowAvatar = (hbm && hbm != PluginConfig.g_hbmUnknown);
- goto LBL_Check;
- }
-
- if (m_bShowAvatar)
- m_bShowAvatar = hideOverride == 0 ? 0 : m_bShowAvatar;
- else
- m_bShowAvatar = hideOverride == 1 ? 1 : m_bShowAvatar;
-
- // reloads avatars
- if (m_hwndPanelPic) { // shows contact or user picture, depending on panel visibility
- SendMessage(m_hwndContactPic, AVATAR_SETPROTOCOL, 0, (LPARAM)m_cache->getActiveProto());
- Utils::setAvatarContact(m_hwndPanelPic, m_hContact);
- }
- else Utils::setAvatarContact(m_hwndContactPic, m_hContact);
- }
- return m_bShowAvatar;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
// checks, if there is a valid smileypack installed for the given protocol
int TSAPI CheckValidSmileyPack(const char *szProto, MCONTACT hContact)
@@ -703,353 +318,6 @@ wchar_t* TSAPI QuoteText(const wchar_t *text) return strout;
}
-void CTabBaseDlg::AdjustBottomAvatarDisplay()
-{
- GetAvatarVisibility();
-
- bool bInfoPanel = m_pPanel.isActive();
- HBITMAP hbm = (bInfoPanel && m_pContainer->m_avatarMode != 3) ? m_hOwnPic : (m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown);
- if (hbm) {
- if (m_dynaSplitter == 0 || m_iSplitterY == 0)
- LoadSplitter();
- m_dynaSplitter = m_iSplitterY - DPISCALEY_S(34);
- DM_RecalcPictureSize();
- Utils::showDlgControl(m_hwnd, IDC_CONTACTPIC, m_bShowAvatar ? SW_SHOW : SW_HIDE);
- InvalidateRect(GetDlgItem(m_hwnd, IDC_CONTACTPIC), nullptr, TRUE);
- }
- else {
- Utils::showDlgControl(m_hwnd, IDC_CONTACTPIC, m_bShowAvatar ? SW_SHOW : SW_HIDE);
- m_pic.cy = m_pic.cx = DPISCALEY_S(60);
- InvalidateRect(GetDlgItem(m_hwnd, IDC_CONTACTPIC), nullptr, TRUE);
- }
-}
-
-void CTabBaseDlg::ShowPicture(bool showNewPic)
-{
- if (!m_pPanel.isActive())
- m_pic.cy = m_pic.cx = DPISCALEY_S(60);
-
- if (showNewPic) {
- if (m_pPanel.isActive() && m_pContainer->m_avatarMode != 3) {
- if (!m_hwndPanelPic) {
- InvalidateRect(m_hwnd, nullptr, TRUE);
- UpdateWindow(m_hwnd);
- Resize();
- }
- return;
- }
- AdjustBottomAvatarDisplay();
- }
- else {
- m_bShowAvatar = !m_bShowAvatar;
- db_set_b(m_hContact, SRMSGMOD_T, "MOD_ShowPic", m_bShowAvatar);
- }
-
- RECT rc;
- GetWindowRect(GetDlgItem(m_hwnd, IDC_CONTACTPIC), &rc);
- if (m_minEditBoxSize.cy + DPISCALEY_S(3) > m_iSplitterY)
- SendMessage(m_hwnd, DM_SPLITTERMOVED, (WPARAM)rc.bottom - m_minEditBoxSize.cy, (LPARAM)GetDlgItem(m_hwnd, IDC_SPLITTERY));
- if (!showNewPic)
- SetDialogToType();
- else
- Resize();
-}
-
-void CTabBaseDlg::FlashOnClist(MEVENT hEvent, DBEVENTINFO *dbei)
-{
- m_dwTickLastEvent = GetTickCount();
-
- if ((GetForegroundWindow() != m_pContainer->m_hwnd || m_pContainer->m_hwndActive != m_hwnd) && !(dbei->flags & DBEF_SENT) && dbei->eventType == EVENTTYPE_MESSAGE) {
- m_dwUnread++;
- UpdateTrayMenu(this, (WORD)(m_cache->getActiveStatus()), m_cache->getActiveProto(), m_wszStatus, m_hContact, 0);
- if (nen_options.bTraySupport)
- return;
- }
- if (hEvent == 0)
- return;
-
- if (!PluginConfig.m_bFlashOnClist)
- return;
-
- if ((GetForegroundWindow() != m_pContainer->m_hwnd || m_pContainer->m_hwndActive != m_hwnd) && !(dbei->flags & DBEF_SENT) && dbei->eventType == EVENTTYPE_MESSAGE && !(m_dwFlagsEx & MWF_SHOW_FLASHCLIST)) {
- CLISTEVENT cle = {};
- cle.hContact = m_hContact;
- cle.hDbEvent = hEvent;
- cle.hIcon = Skin_LoadIcon(SKINICON_EVENT_MESSAGE);
- cle.pszService = MS_MSG_READMESSAGE;
- g_clistApi.pfnAddEvent(&cle);
-
- m_dwFlagsEx |= MWF_SHOW_FLASHCLIST;
- m_hFlashingEvent = hEvent;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static wchar_t tszRtfBreaks[] = L" \\\n\r";
-
-static void CreateColorMap(CMStringW &Text, int iCount, COLORREF *pSrc, int *pDst)
-{
- const wchar_t *pszText = Text;
- int iIndex = 1;
-
- static const wchar_t *lpszFmt = L"\\red%[^ \x5b\\]\\green%[^ \x5b\\]\\blue%[^ \x5b;];";
- wchar_t szRed[10], szGreen[10], szBlue[10];
-
- const wchar_t *p1 = wcsstr(pszText, L"\\colortbl");
- if (!p1)
- return;
-
- const wchar_t *pEnd = wcschr(p1, '}');
-
- const wchar_t *p2 = wcsstr(p1, L"\\red");
-
- for (int i = 0; i < iCount; i++)
- pDst[i] = -1;
-
- while (p2 && p2 < pEnd) {
- if (swscanf(p2, lpszFmt, &szRed, &szGreen, &szBlue) > 0) {
- for (int i = 0; i < iCount; i++) {
- if (pSrc[i] == RGB(_wtoi(szRed), _wtoi(szGreen), _wtoi(szBlue)))
- pDst[i] = iIndex;
- }
- }
- iIndex++;
- p1 = p2;
- p1++;
-
- p2 = wcsstr(p1, L"\\red");
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// convert rich edit code to bbcode (if wanted). Otherwise, strip all RTF formatting
-// tags and return plain text
-
-static int RtfColorToIndex(int iNumColors, int *pIndex, int iCol)
-{
- for (int i = 0; i < iNumColors; i++)
- if (pIndex[i] == iCol)
- return i;
-
- return -1;
-}
-
-BOOL CTabBaseDlg::DoRtfToTags(CMStringW &pszText) const
-{
- if (pszText.IsEmpty())
- return FALSE;
-
- // used to filter out attributes which are already set for the default message input area font
- LOGFONTA lf = m_pContainer->m_theme.logFonts[MSGFONTID_MESSAGEAREA];
-
- // create an index of colors in the module and map them to
- // corresponding colors in the RTF color table
- int iNumColors = Utils::rtf_clrs.getCount();
- int *pIndex = (int*)_alloca(iNumColors * sizeof(int));
- COLORREF *pColors = (COLORREF*)_alloca(iNumColors * sizeof(COLORREF));
- for (int i = 0; i < iNumColors; i++)
- pColors[i] = Utils::rtf_clrs[i].clr;
- CreateColorMap(pszText, iNumColors, pColors, pIndex);
-
- // scan the file for rtf commands and remove or parse them
- int idx = pszText.Find(L"\\pard");
- if (idx == -1) {
- if ((idx = pszText.Find(L"\\ltrpar")) == -1)
- return FALSE;
- idx += 7;
- }
- else idx += 5;
-
- MODULEINFO *mi = (isChat()) ? m_si->pMI : nullptr;
-
- bool bInsideColor = false, bInsideUl = false;
- CMStringW res;
-
- // iterate through all characters, if rtf control character found then take action
- for (const wchar_t *p = pszText.GetString() + idx; *p;) {
- switch (*p) {
- case '\\':
- if (p[1] == '\\' || p[1] == '{' || p[1] == '}') { // escaped characters
- res.AppendChar(p[1]);
- p += 2; break;
- }
- if (p[1] == '~') { // non-breaking space
- res.AppendChar(0xA0);
- p += 2; break;
- }
-
- if (!wcsncmp(p, L"\\cf", 3)) { // foreground color
- int iCol = _wtoi(p + 3);
- int iInd = RtfColorToIndex(iNumColors, pIndex, iCol);
-
- if (iCol > 0) {
- if (isChat()) {
- if (mi && mi->bColor) {
- if (iInd >= 0) {
- if (!(res.IsEmpty() && m_pContainer->m_theme.fontColors[MSGFONTID_MESSAGEAREA] == pColors[iInd]))
- res.AppendFormat(L"%%c%u", iInd);
- }
- else if (!res.IsEmpty())
- res.Append(L"%%C");
- }
- }
- else res.AppendFormat((iInd >= 0) ? (bInsideColor ? L"[/color][color=%s]" : L"[color=%s]") : (bInsideColor ? L"[/color]" : L""), Utils::rtf_clrs[iInd].szName);
- }
-
- bInsideColor = iInd >= 0;
- }
- else if (!wcsncmp(p, L"\\highlight", 10)) { // background color
- if (isChat()) {
- if (mi && mi->bBkgColor) {
- int iInd = RtfColorToIndex(iNumColors, pIndex, _wtoi(p + 10));
- if (iInd >= 0) {
- // if the entry field is empty & the color passed is the back color, skip it
- if (!(res.IsEmpty() && m_pContainer->m_theme.inputbg == pColors[iInd]))
- res.AppendFormat(L"%%f%u", iInd);
- }
- else if (!res.IsEmpty())
- res.AppendFormat(L"%%F");
- }
- }
- }
- else if (!wcsncmp(p, L"\\line", 5)) { // soft line break;
- res.AppendChar('\n');
- }
- else if (!wcsncmp(p, L"\\endash", 7)) {
- res.AppendChar(0x2013);
- }
- else if (!wcsncmp(p, L"\\emdash", 7)) {
- res.AppendChar(0x2014);
- }
- else if (!wcsncmp(p, L"\\bullet", 7)) {
- res.AppendChar(0x2022);
- }
- else if (!wcsncmp(p, L"\\ldblquote", 10)) {
- res.AppendChar(0x201C);
- }
- else if (!wcsncmp(p, L"\\rdblquote", 10)) {
- res.AppendChar(0x201D);
- }
- else if (!wcsncmp(p, L"\\lquote", 7)) {
- res.AppendChar(0x2018);
- }
- else if (!wcsncmp(p, L"\\rquote", 7)) {
- res.AppendChar(0x2019);
- }
- else if (!wcsncmp(p, L"\\b", 2)) { //bold
- if (isChat()) {
- if (mi && mi->bBold)
- res.Append((p[2] != '0') ? L"%b" : L"%B");
- }
- else {
- if (!(lf.lfWeight == FW_BOLD)) // only allow bold if the font itself isn't a bold one, otherwise just strip it..
- if (m_SendFormat)
- res.Append((p[2] != '0') ? L"[b]" : L"[/b]");
- }
- }
- else if (!wcsncmp(p, L"\\i", 2)) { // italics
- if (isChat()) {
- if (mi && mi->bItalics)
- res.Append((p[2] != '0') ? L"%i" : L"%I");
- }
- else {
- if (!lf.lfItalic && m_SendFormat)
- res.Append((p[2] != '0') ? L"[i]" : L"[/i]");
- }
- }
- else if (!wcsncmp(p, L"\\strike", 7)) { // strike-out
- if (!lf.lfStrikeOut && m_SendFormat)
- res.Append((p[7] != '0') ? L"[s]" : L"[/s]");
- }
- else if (!wcsncmp(p, L"\\ul", 3)) { // underlined
- if (isChat()) {
- if (mi && mi->bUnderline)
- res.Append((p[3] != '0') ? L"%u" : L"%U");
- }
- else {
- if (!lf.lfUnderline && m_SendFormat) {
- if (p[3] == 0 || wcschr(tszRtfBreaks, p[3])) {
- res.Append(L"[u]");
- bInsideUl = true;
- }
- else if (!wcsncmp(p + 3, L"none", 4)) {
- if (bInsideUl)
- res.Append(L"[/u]");
- bInsideUl = false;
- }
- }
- }
- }
- else if (!wcsncmp(p, L"\\tab", 4)) { // tab
- res.AppendChar('\t');
- }
- else if (p[1] == '\'') { // special character
- if (p[2] != ' ' && p[2] != '\\') {
- wchar_t tmp[10];
-
- if (p[3] != ' ' && p[3] != '\\') {
- wcsncpy(tmp, p + 2, 3);
- tmp[3] = 0;
- }
- else {
- wcsncpy(tmp, p + 2, 2);
- tmp[2] = 0;
- }
-
- // convert string containing char in hex format to int.
- wchar_t *stoppedHere;
- res.AppendChar(wcstol(tmp, &stoppedHere, 16));
- }
- }
-
- p++; // skip initial slash
- p += wcscspn(p, tszRtfBreaks);
- if (*p == ' ')
- p++;
- break;
-
- case '{': // other RTF control characters
- case '}':
- p++;
- break;
-
- case '%': // double % for stupid chat engine
- if (isChat())
- res.Append(L"%%");
- else
- res.AppendChar(*p);
- p++;
- break;
-
- default: // other text that should not be touched
- res.AppendChar(*p++);
- break;
- }
- }
-
- if (bInsideColor && !isChat())
- res.Append(L"[/color]");
- if (bInsideUl)
- res.Append(L"[/u]");
-
- pszText = res;
- return TRUE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// retrieve both buddys and my own UIN for a message session and store them in the message window *dat
-// respects metacontacts and uses the current protocol if the contact is a MC
-
-void CTabBaseDlg::GetMYUIN()
-{
- ptrW uid(Contact_GetInfo(CNF_DISPLAYUID, 0, m_cache->getActiveProto()));
- if (uid != nullptr)
- wcsncpy_s(m_myUin, uid, _TRUNCATE);
- else
- m_myUin[0] = 0;
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
static int g_IEViewAvail = -1;
@@ -1079,375 +347,6 @@ UINT TSAPI GetIEViewMode(MCONTACT hContact) /////////////////////////////////////////////////////////////////////////////////////////
-void CTabBaseDlg::SetMessageLog()
-{
- unsigned int iLogMode = GetIEViewMode(m_hContact);
-
- if (iLogMode == WANT_IEVIEW_LOG && m_hwndIEView == nullptr) {
- IEVIEWWINDOW ieWindow = {};
- ieWindow.cbSize = sizeof(IEVIEWWINDOW);
- ieWindow.iType = IEW_CREATE;
- ieWindow.dwMode = IEWM_TABSRMM;
- ieWindow.parent = m_hwnd;
- ieWindow.cx = 200;
- ieWindow.cy = 200;
- CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
- m_hwndIEView = ieWindow.hwnd;
- m_log.Hide();
- m_log.Enable(false);
- }
- else if (iLogMode == WANT_HPP_LOG && m_hwndHPP == nullptr) {
- IEVIEWWINDOW ieWindow = {};
- ieWindow.cbSize = sizeof(IEVIEWWINDOW);
- ieWindow.iType = IEW_CREATE;
- ieWindow.dwMode = IEWM_TABSRMM;
- ieWindow.parent = m_hwnd;
- ieWindow.cx = 10;
- ieWindow.cy = 10;
- CallService(MS_HPP_EG_WINDOW, 0, (LPARAM)&ieWindow);
- m_hwndHPP = ieWindow.hwnd;
- m_log.Hide();
- m_log.Enable(false);
- }
-}
-
-void CTabBaseDlg::FindFirstEvent()
-{
- int historyMode = g_plugin.getByte(m_hContact, SRMSGSET_LOADHISTORY, -1);
- if (historyMode == -1)
- historyMode = (int)g_plugin.getByte(SRMSGSET_LOADHISTORY, SRMSGDEFSET_LOADHISTORY);
-
- m_hDbEventFirst = db_event_firstUnread(m_hContact);
-
- if (m_bActualHistory)
- historyMode = LOADHISTORY_COUNT;
-
- switch (historyMode) {
- case LOADHISTORY_COUNT:
- int i;
- MEVENT hPrevEvent;
- {
- DBEVENTINFO dbei = {};
- // ability to load only current session's history
- if (m_bActualHistory)
- i = m_cache->getSessionMsgCount();
- else
- i = g_plugin.getWord(SRMSGSET_LOADCOUNT, SRMSGDEFSET_LOADCOUNT);
-
- for (; i > 0; i--) {
- if (m_hDbEventFirst == 0)
- hPrevEvent = db_event_last(m_hContact);
- else
- hPrevEvent = db_event_prev(m_hContact, m_hDbEventFirst);
- if (hPrevEvent == 0)
- break;
- dbei.cbBlob = 0;
- m_hDbEventFirst = hPrevEvent;
- db_event_get(m_hDbEventFirst, &dbei);
- if (!DbEventIsShown(&dbei))
- i++;
- }
- }
- break;
-
- case LOADHISTORY_TIME:
- DBEVENTINFO dbei = {};
- if (m_hDbEventFirst == 0)
- dbei.timestamp = time(0);
- else
- db_event_get(m_hDbEventFirst, &dbei);
-
- DWORD firstTime = dbei.timestamp - 60 * g_plugin.getWord(SRMSGSET_LOADTIME, SRMSGDEFSET_LOADTIME);
- for (;;) {
- if (m_hDbEventFirst == 0)
- hPrevEvent = db_event_last(m_hContact);
- else
- hPrevEvent = db_event_prev(m_hContact, m_hDbEventFirst);
- if (hPrevEvent == 0)
- break;
- dbei.cbBlob = 0;
- db_event_get(hPrevEvent, &dbei);
- if (dbei.timestamp < firstTime)
- break;
- m_hDbEventFirst = hPrevEvent;
- }
- break;
- }
-}
-
-void CTabBaseDlg::SaveSplitter()
-{
- if (m_bIsAutosizingInput)
- return;
-
- if (m_iSplitterY < DPISCALEY_S(MINSPLITTERY) || m_iSplitterY < 0)
- m_iSplitterY = DPISCALEY_S(MINSPLITTERY);
-
- if (m_dwFlagsEx & MWF_SHOW_SPLITTEROVERRIDE)
- db_set_dw(m_hContact, SRMSGMOD_T, "splitsplity", m_iSplitterY);
- else {
- if (m_pContainer->m_pSettings->fPrivate)
- m_pContainer->m_pSettings->iSplitterY = m_iSplitterY;
- else
- db_set_dw(0, SRMSGMOD_T, "splitsplity", m_iSplitterY);
- }
-}
-
-void CTabBaseDlg::LoadSplitter()
-{
- if (m_bIsAutosizingInput) {
- m_iSplitterY = GetDefaultMinimumInputHeight();
- return;
- }
-
- if (!(m_dwFlagsEx & MWF_SHOW_SPLITTEROVERRIDE)) {
- if (!m_pContainer->m_pSettings->fPrivate)
- m_iSplitterY = (int)M.GetDword("splitsplity", 60);
- else
- m_iSplitterY = m_pContainer->m_pSettings->iSplitterY;
- }
- else m_iSplitterY = (int)M.GetDword(m_hContact, "splitsplity", M.GetDword("splitsplity", 60));
-
- if (m_iSplitterY < MINSPLITTERY)
- m_iSplitterY = 150;
-}
-
-void CTabBaseDlg::PlayIncomingSound() const
-{
- int iPlay = MustPlaySound();
- if (iPlay) {
- if (GetForegroundWindow() == m_pContainer->m_hwnd && m_pContainer->m_hwndActive == m_hwnd)
- Skin_PlaySound("RecvMsgActive");
- else
- Skin_PlaySound("RecvMsgInactive");
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// reads send format and configures the toolbar buttons
-// if mode == 0, int only configures the buttons and does not change send format
-
-void CTabBaseDlg::GetSendFormat()
-{
- m_SendFormat = M.GetDword(m_hContact, "sendformat", PluginConfig.m_SendFormat);
- if (m_SendFormat == -1) // per contact override to disable it..
- m_SendFormat = 0;
- else if (m_SendFormat == 0)
- m_SendFormat = PluginConfig.m_SendFormat ? 1 : 0;
-}
-
-void CSrmmWindow::LoadContactAvatar()
-{
- m_ace = Utils::loadAvatarFromAVS(m_bIsMeta ? db_mc_getSrmmSub(m_hContact) : m_hContact);
-
- BITMAP bm;
- if (m_ace && m_ace->hbmPic)
- GetObject(m_ace->hbmPic, sizeof(bm), &bm);
- else if (m_ace == nullptr)
- GetObject(PluginConfig.g_hbmUnknown, sizeof(bm), &bm);
- else
- return;
-
- AdjustBottomAvatarDisplay();
- CalcDynamicAvatarSize(&bm);
-
- if (!m_pPanel.isActive() || m_pContainer->m_avatarMode == 3) {
- m_iRealAvatarHeight = 0;
- PostMessage(m_hwnd, WM_SIZE, 0, 0);
- }
- else if (m_pPanel.isActive())
- GetAvatarVisibility();
-
- if (m_pWnd != nullptr)
- m_pWnd->verifyDwmState();
-}
-
-void CSrmmWindow::LoadOwnAvatar()
-{
- if (ServiceExists(MS_AV_GETMYAVATAR))
- m_ownAce = (AVATARCACHEENTRY *)CallService(MS_AV_GETMYAVATAR, 0, (LPARAM)(m_cache->getActiveProto()));
- else
- m_ownAce = nullptr;
-
- if (m_ownAce)
- m_hOwnPic = m_ownAce->hbmPic;
- else
- m_hOwnPic = PluginConfig.g_hbmUnknown;
-
- if (m_pPanel.isActive() && m_pContainer->m_avatarMode != 3) {
- BITMAP bm;
-
- m_iRealAvatarHeight = 0;
- AdjustBottomAvatarDisplay();
- GetObject(m_hOwnPic, sizeof(bm), &bm);
- CalcDynamicAvatarSize(&bm);
- Resize();
- }
-}
-
-// paste contents of the clipboard into the message input area and send it immediately
-void CTabBaseDlg::HandlePasteAndSend()
-{
- // is feature disabled?
- if (!PluginConfig.m_PasteAndSend) {
- SendMessage(m_hwnd, DM_ACTIVATETOOLTIP, IDC_SRMM_MESSAGE, (LPARAM)TranslateT("The 'paste and send' feature is disabled. You can enable it on the 'General' options page in the 'Sending messages' section"));
- return;
- }
-
- m_message.SendMsg(EM_PASTESPECIAL, CF_UNICODETEXT, 0);
- if (GetWindowTextLength(m_message.GetHwnd()) > 0)
- SendMessage(m_hwnd, WM_COMMAND, IDOK, 0);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// draw various elements of the message window, like avatar(s), info panel fields
-// and the color formatting menu
-
-int CTabBaseDlg::MsgWindowDrawHandler(DRAWITEMSTRUCT *dis)
-{
- HBITMAP hbmAvatar = m_ace ? m_ace->hbmPic : PluginConfig.g_hbmUnknown;
- if ((dis->hwndItem == GetDlgItem(m_hwnd, IDC_CONTACTPIC) && m_bShowAvatar) || (dis->hwndItem == m_hwnd && m_pPanel.isActive())) {
- if (hbmAvatar == nullptr)
- return TRUE;
-
- int top, cx, cy;
- RECT rcClient, rcFrame;
- bool bPanelPic = (dis->hwndItem == m_hwnd);
- if (bPanelPic && !m_bShowInfoAvatar)
- return TRUE;
-
- RECT rc;
- GetClientRect(m_hwnd, &rc);
- if (bPanelPic) {
- rcClient = dis->rcItem;
- cx = (rcClient.right - rcClient.left);
- cy = (rcClient.bottom - rcClient.top) + 1;
- }
- else {
- GetClientRect(dis->hwndItem, &rcClient);
- cx = rcClient.right;
- cy = rcClient.bottom;
- }
-
- if (cx < 5 || cy < 5)
- return TRUE;
-
- HDC hdcDraw = CreateCompatibleDC(dis->hDC);
- HBITMAP hbmDraw = CreateCompatibleBitmap(dis->hDC, cx, cy);
- HBITMAP hbmOld = (HBITMAP)SelectObject(hdcDraw, hbmDraw);
-
- bool bAero = M.isAero();
-
- HRGN clipRgn = nullptr;
- HBRUSH hOldBrush = (HBRUSH)SelectObject(hdcDraw, bAero ? (HBRUSH)GetStockObject(HOLLOW_BRUSH) : GetSysColorBrush(COLOR_3DFACE));
- rcFrame = rcClient;
-
- if (!bPanelPic) {
- top = (cy - m_pic.cy) / 2;
- RECT rcEdge = { 0, top, m_pic.cx, top + m_pic.cy };
- if (CSkin::m_skinEnabled)
- CSkin::SkinDrawBG(dis->hwndItem, m_pContainer->m_hwnd, m_pContainer, &dis->rcItem, hdcDraw);
- else if (PluginConfig.m_fillColor) {
- HBRUSH br = CreateSolidBrush(PluginConfig.m_fillColor);
- FillRect(hdcDraw, &rcFrame, br);
- DeleteObject(br);
- }
- else if (bAero && CSkin::m_pCurrentAeroEffect) {
- COLORREF clr = PluginConfig.m_tbBackgroundHigh ? PluginConfig.m_tbBackgroundHigh :
- (CSkin::m_pCurrentAeroEffect ? CSkin::m_pCurrentAeroEffect->m_clrToolbar : 0xf0f0f0);
-
- HBRUSH br = CreateSolidBrush(clr);
- FillRect(hdcDraw, &rcFrame, br);
- DeleteObject(br);
- }
- else FillRect(hdcDraw, &rcFrame, GetSysColorBrush(COLOR_3DFACE));
-
- HPEN hPenBorder = CreatePen(PS_SOLID, 1, CSkin::m_avatarBorderClr);
- HPEN hPenOld = (HPEN)SelectObject(hdcDraw, hPenBorder);
-
- if (CSkin::m_bAvatarBorderType == 1)
- Rectangle(hdcDraw, rcEdge.left, rcEdge.top, rcEdge.right, rcEdge.bottom);
- else if (CSkin::m_bAvatarBorderType == 2) {
- clipRgn = CreateRoundRectRgn(rcEdge.left, rcEdge.top, rcEdge.right + 1, rcEdge.bottom + 1, 6, 6);
- SelectClipRgn(hdcDraw, clipRgn);
-
- HBRUSH hbr = CreateSolidBrush(CSkin::m_avatarBorderClr);
- FrameRgn(hdcDraw, clipRgn, hbr, 1, 1);
- DeleteObject(hbr);
- DeleteObject(clipRgn);
- }
-
- SelectObject(hdcDraw, hPenOld);
- DeleteObject(hPenBorder);
- }
-
- if (bPanelPic) {
- bool bBorder = (CSkin::m_bAvatarBorderType ? true : false);
-
- int border_off = bBorder ? 1 : 0;
- int iMaxHeight = m_iPanelAvatarY - (bBorder ? 2 : 0);
- int iMaxWidth = m_iPanelAvatarX - (bBorder ? 2 : 0);
-
- rcFrame.left = rcFrame.top = 0;
- rcFrame.right = (rcClient.right - rcClient.left);
- rcFrame.bottom = (rcClient.bottom - rcClient.top);
-
- rcFrame.left = rcFrame.right - (LONG)m_iPanelAvatarX;
- rcFrame.bottom = (LONG)m_iPanelAvatarY;
-
- int height_off = (cy - iMaxHeight - (bBorder ? 2 : 0)) / 2;
- rcFrame.top += height_off;
- rcFrame.bottom += height_off;
-
- SendMessage(m_hwndPanelPic, AVATAR_SETAEROCOMPATDRAWING, 0, bAero ? TRUE : FALSE);
- SetWindowPos(m_hwndPanelPic, HWND_TOP, rcFrame.left + border_off, rcFrame.top + border_off,
- iMaxWidth, iMaxHeight, SWP_SHOWWINDOW | SWP_ASYNCWINDOWPOS | SWP_DEFERERASE | SWP_NOSENDCHANGING);
- }
-
- SelectObject(hdcDraw, hOldBrush);
- if (!bPanelPic)
- BitBlt(dis->hDC, 0, 0, cx, cy, hdcDraw, 0, 0, SRCCOPY);
- SelectObject(hdcDraw, hbmOld);
- DeleteObject(hbmDraw);
- DeleteDC(hdcDraw);
- return TRUE;
- }
-
- if (dis->hwndItem == GetDlgItem(m_hwnd, IDC_STATICTEXT) || dis->hwndItem == GetDlgItem(m_hwnd, IDC_LOGFROZENTEXT)) {
- wchar_t szWindowText[256];
- if (CSkin::m_skinEnabled) {
- SetTextColor(dis->hDC, CSkin::m_DefaultFontColor);
- CSkin::SkinDrawBG(dis->hwndItem, m_pContainer->m_hwnd, m_pContainer, &dis->rcItem, dis->hDC);
- }
- else {
- SetTextColor(dis->hDC, GetSysColor(COLOR_BTNTEXT));
- CSkin::FillBack(dis->hDC, &dis->rcItem);
- }
- GetWindowText(dis->hwndItem, szWindowText, _countof(szWindowText));
- szWindowText[255] = 0;
- SetBkMode(dis->hDC, TRANSPARENT);
- DrawText(dis->hDC, szWindowText, -1, &dis->rcItem, DT_SINGLELINE | DT_VCENTER | DT_NOCLIP | DT_END_ELLIPSIS);
- return TRUE;
- }
-
- if (dis->hwndItem == GetDlgItem(m_hwnd, IDC_STATICERRORICON)) {
- if (CSkin::m_skinEnabled)
- CSkin::SkinDrawBG(dis->hwndItem, m_pContainer->m_hwnd, m_pContainer, &dis->rcItem, dis->hDC);
- else
- CSkin::FillBack(dis->hDC, &dis->rcItem);
- DrawIconEx(dis->hDC, (dis->rcItem.right - dis->rcItem.left) / 2 - 8, (dis->rcItem.bottom - dis->rcItem.top) / 2 - 8,
- PluginConfig.g_iconErr, 16, 16, 0, nullptr, DI_NORMAL);
- return TRUE;
- }
-
- if (dis->CtlType == ODT_MENU && m_pPanel.isHovered()) {
- DrawMenuItem(dis, (HICON)dis->itemData, 0);
- return TRUE;
- }
-
- return Menu_DrawItem((LPARAM)dis);
-}
-
void TSAPI LoadThemeDefaults(TContainerData *pContainer)
{
memset(&pContainer->m_theme, 0, sizeof(TLogTheme));
@@ -1515,18 +414,6 @@ void TSAPI LoadOverrideTheme(TContainerData *pContainer) LoadThemeDefaults(pContainer);
}
-HICON CTabBaseDlg::GetXStatusIcon() const
-{
- BYTE xStatus = m_cache->getXStatusId();
- if (xStatus == 0)
- return nullptr;
-
- if (!ProtoServiceExists(m_cache->getActiveProto(), PS_GETCUSTOMSTATUSICON))
- return nullptr;
-
- return (HICON)(CallProtoService(m_cache->getActiveProto(), PS_GETCUSTOMSTATUSICON, xStatus, 0));
-}
-
LRESULT TSAPI GetSendButtonState(HWND hwnd)
{
HWND hwndIDok = GetDlgItem(hwnd, IDOK);
@@ -1534,240 +421,3 @@ LRESULT TSAPI GetSendButtonState(HWND hwnd) return SendMessage(hwndIDok, BUTTONGETSTATEID, TRUE, 0);
return 0;
}
-
-void CTabBaseDlg::EnableSendButton(bool bMode) const
-{
- SendDlgItemMessage(m_hwnd, IDOK, BUTTONSETASNORMAL, bMode, 0);
- SendDlgItemMessage(m_hwnd, IDC_PIC, BUTTONSETASNORMAL, m_bEditNotesActive ? TRUE : (!bMode && m_iOpenJobs == 0) ? TRUE : FALSE, 0);
-
- HWND hwndOK = GetDlgItem(GetParent(GetParent(m_hwnd)), IDOK);
- if (IsWindow(hwndOK))
- SendMessage(hwndOK, BUTTONSETASNORMAL, bMode, 0);
-}
-
-void CTabBaseDlg::EnableSending(bool bMode) const
-{
- m_message.SendMsg(EM_SETREADONLY, !bMode, 0);
- Utils::enableDlgControl(m_hwnd, IDC_CLIST, bMode);
- EnableSendButton(bMode);
-}
-
-void CTabBaseDlg::GetClientIcon()
-{
- if (m_hClientIcon)
- DestroyIcon(m_hClientIcon);
-
- m_hClientIcon = nullptr;
- if (ServiceExists(MS_FP_GETCLIENTICONT)) {
- ptrW tszMirver(db_get_wsa(m_cache->getActiveContact(), m_cache->getActiveProto(), "MirVer"));
- if (tszMirver)
- m_hClientIcon = Finger_GetClientIcon(tszMirver, 1);
- }
-}
-
-void CTabBaseDlg::GetMyNick()
-{
- ptrW tszNick(Contact_GetInfo(CNF_CUSTOMNICK, 0, m_cache->getActiveProto()));
- if (tszNick == nullptr)
- tszNick = Contact_GetInfo(CNF_NICK, 0, m_cache->getActiveProto());
- if (tszNick != nullptr) {
- if (mir_wstrlen(tszNick) == 0 || !mir_wstrcmp(tszNick, TranslateT("'(Unknown contact)'")))
- wcsncpy_s(m_wszMyNickname, (m_myUin[0] ? m_myUin : TranslateT("'(Unknown contact)'")), _TRUNCATE);
- else
- wcsncpy_s(m_wszMyNickname, tszNick, _TRUNCATE);
- }
- else wcsncpy_s(m_wszMyNickname, L"<undef>", _TRUNCATE); // same here
-}
-
-HICON CTabBaseDlg::GetMyContactIcon(LPCSTR szSetting)
-{
- int bUseMeta = (szSetting == nullptr) ? false : M.GetByte(szSetting, mir_strcmp(szSetting, "MetaiconTab") == 0);
- if (bUseMeta)
- return Skin_LoadProtoIcon(m_cache->getProto(), m_cache->getStatus());
- return Skin_LoadProtoIcon(m_cache->getActiveProto(), m_cache->getActiveStatus());
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// read keyboard state and return the state of the modifier keys
-
-void CTabBaseDlg::KbdState(bool &isShift, bool &isControl, bool &isAlt)
-{
- GetKeyboardState(kstate);
- isShift = (kstate[VK_SHIFT] & 0x80) != 0;
- isControl = (kstate[VK_CONTROL] & 0x80) != 0;
- isAlt = (kstate[VK_MENU] & 0x80) != 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// generic handler for the WM_COPY message in message log/chat history richedit control(s).
-// it filters out the invisible event boundary markers from the text copied to the clipboard.
-// WINE Fix: overwrite clippboad data from original control data
-
-LRESULT CTabBaseDlg::WMCopyHandler(UINT msg, WPARAM wParam, LPARAM lParam)
-{
- LRESULT result = mir_callNextSubclass(m_log.GetHwnd(), stubLogProc, msg, wParam, lParam);
-
- ptrA szFromStream(m_log.GetRichTextRtf(true, true));
- if (szFromStream != nullptr) {
- ptrW converted(mir_utf8decodeW(szFromStream));
- if (converted != nullptr) {
- Utils::FilterEventMarkers(converted);
- Utils::CopyToClipBoard(converted, m_log.GetHwnd());
- }
- }
-
- return result;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// calculate the minimum required client height for the given message
-// window layout
-//
-// the container will use this in its WM_GETMINMAXINFO handler to set
-// minimum tracking height.
-
-void CTabBaseDlg::DetermineMinHeight()
-{
- RECT rc;
- LONG height = (m_pPanel.isActive() ? m_pPanel.getHeight() + 2 : 0);
- if (!(m_pContainer->m_dwFlags & CNT_HIDETOOLBAR))
- height += DPISCALEY_S(24); // toolbar
- GetClientRect(m_message.GetHwnd(), &rc);
- height += rc.bottom; // input area
- height += 40; // min space for log area and some padding
-
- m_pContainer->m_uChildMinHeight = height;
-}
-
-LONG CTabBaseDlg::GetDefaultMinimumInputHeight() const
-{
- LONG height = (m_pContainer->m_dwFlags & CNT_BOTTOMTOOLBAR) ? DPISCALEY_S(46 + 22) : DPISCALEY_S(46);
-
- if (CSkin::m_skinEnabled && !SkinItems[ID_EXTBKINPUTAREA].IGNORED)
- height += (SkinItems[ID_EXTBKINPUTAREA].MARGIN_BOTTOM + SkinItems[ID_EXTBKINPUTAREA].MARGIN_TOP - 2);
-
- return height;
-}
-
-bool CTabBaseDlg::IsAutoSplitEnabled() const
-{
- return (m_pContainer->m_dwFlags & CNT_AUTOSPLITTER) && !(m_dwFlagsEx & MWF_SHOW_SPLITTEROVERRIDE);
-}
-
-void CTabBaseDlg::LimitMessageText(int iLen)
-{
- if (this != nullptr)
- m_message.SendMsg(EM_EXLIMITTEXT, 0, iLen);
-}
-
-static LIST<wchar_t> vTempFilenames(5);
-
-// send a pasted bitmap by file transfer.
-void CTabBaseDlg::SendHBitmapAsFile(HBITMAP hbmp) const
-{
- const wchar_t *mirandatempdir = L"Miranda";
- const wchar_t *filenametemplate = L"\\clp-%Y%m%d-%H%M%S0.jpg";
- wchar_t filename[MAX_PATH];
- size_t tempdirlen = GetTempPath(MAX_PATH, filename);
- bool fSend = true;
-
- const char *szProto = m_cache->getActiveProto();
- int wMyStatus = Proto_GetStatus(szProto);
-
- DWORD protoCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0);
- DWORD typeCaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0);
-
- // check protocol capabilities, status modes and visibility lists (privacy)
- // to determine whether the file can be sent. Throw a warning if any of
- // these checks fails.
- if (!(protoCaps & PF1_FILESEND))
- fSend = false;
-
- if ((ID_STATUS_OFFLINE == wMyStatus) || (ID_STATUS_OFFLINE == m_cache->getActiveStatus() && !(typeCaps & PF4_OFFLINEFILES)))
- fSend = false;
-
- if (protoCaps & PF1_VISLIST && db_get_w(m_cache->getActiveContact(), szProto, "ApparentMode", 0) == ID_STATUS_OFFLINE)
- fSend = false;
-
- if (protoCaps & PF1_INVISLIST && wMyStatus == ID_STATUS_INVISIBLE && db_get_w(m_cache->getActiveContact(), szProto, "ApparentMode", 0) != ID_STATUS_ONLINE)
- fSend = false;
-
- if (!fSend) {
- CWarning::show(CWarning::WARN_SENDFILE, MB_OK | MB_ICONEXCLAMATION | CWarning::CWF_NOALLOWHIDE);
- return;
- }
-
- if (tempdirlen <= 0 || tempdirlen >= MAX_PATH - mir_wstrlen(mirandatempdir) - mir_wstrlen(filenametemplate) - 2) // -2 is because %Y takes 4 symbols
- filename[0] = 0; // prompt for a new name
- else {
- mir_wstrcpy(filename + tempdirlen, mirandatempdir);
- if ((GetFileAttributes(filename) == INVALID_FILE_ATTRIBUTES || ((GetFileAttributes(filename) & FILE_ATTRIBUTE_DIRECTORY) == 0)) && CreateDirectory(filename, nullptr) == 0)
- filename[0] = 0;
- else {
- tempdirlen = mir_wstrlen(filename);
-
- time_t rawtime;
- time(&rawtime);
- const tm* timeinfo;
- timeinfo = _localtime32((__time32_t *)&rawtime);
- wcsftime(filename + tempdirlen, MAX_PATH - tempdirlen, filenametemplate, timeinfo);
- size_t firstnumberpos = tempdirlen + 14;
- size_t lastnumberpos = tempdirlen + 20;
- while (GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES) { // while it exists
- for (size_t pos = lastnumberpos; pos >= firstnumberpos; pos--)
- if (filename[pos]++ != '9')
- break;
- else
- if (pos == firstnumberpos)
- filename[0] = 0; // all filenames exist => prompt for a new name
- else
- filename[pos] = '0';
- }
- }
- }
-
- if (filename[0] == 0) { // prompting to save
- wchar_t filter[MAX_PATH];
- mir_snwprintf(filter, L"%s%c*.jpg%c%c", TranslateT("JPEG-compressed images"), 0, 0, 0);
-
- OPENFILENAME dlg;
- dlg.lStructSize = sizeof(dlg);
- dlg.lpstrFilter = filter;
- dlg.nFilterIndex = 1;
- dlg.lpstrFile = filename;
- dlg.nMaxFile = MAX_PATH;
- dlg.Flags = OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
- dlg.lpstrDefExt = L"jpg";
- if (!GetSaveFileName(&dlg))
- return;
- }
-
- IMGSRVC_INFO ii;
- ii.cbSize = sizeof(ii);
- ii.hbm = hbmp;
- ii.pwszName = filename;
- ii.dwMask = IMGI_HBITMAP;
- ii.fif = FIF_JPEG;
- Image_Save(&ii);
-
- int totalCount = 0;
- wchar_t **ppFiles = nullptr;
- Utils::AddToFileList(&ppFiles, &totalCount, filename);
-
- wchar_t* _t = mir_wstrdup(filename);
- vTempFilenames.insert(_t);
-
- CallService(MS_FILE_SENDSPECIFICFILEST, m_cache->getActiveContact(), (LPARAM)ppFiles);
-
- mir_free(ppFiles[0]);
- mir_free(ppFiles);
-}
-
-// remove all temporary files created by the "send clipboard as file" feature.
-void TSAPI CleanTempFiles()
-{
- for (auto &it : vTempFilenames) {
- DeleteFileW(it);
- mir_free(it);
- }
-}
diff --git a/plugins/TabSRMM/src/msgdlgutils.h b/plugins/TabSRMM/src/msgdlgutils.h index 3b71b5acb9..1766826cfe 100644 --- a/plugins/TabSRMM/src/msgdlgutils.h +++ b/plugins/TabSRMM/src/msgdlgutils.h @@ -31,6 +31,7 @@ #define WANT_HPP_LOG 2
void TSAPI ProcessAvatarChange(HWND hwnd, LPARAM lParam);
+BOOL TSAPI CheckCustomLink(HWND hwndRich, POINT *ptClient, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bUrlNeeded);
int TSAPI CheckValidSmileyPack(const char *szProto, MCONTACT hContact);
wchar_t* TSAPI QuoteText(const wchar_t *text);
UINT TSAPI GetIEViewMode(MCONTACT hContact);
@@ -38,10 +39,10 @@ void TSAPI LoadOverrideTheme(TContainerData *pContainer); void TSAPI LoadThemeDefaults(TContainerData *pContainer);
int TSAPI CutContactName(const wchar_t *szold, wchar_t *sznew, size_t size);
LRESULT TSAPI GetSendButtonState(HWND hwnd);
-void TSAPI RearrangeTab(HWND hwndDlg, const CTabBaseDlg *dat, int iMode, BOOL bSavePos);
+void TSAPI RearrangeTab(HWND hwndDlg, const CMsgDialog *dat, int iMode, BOOL bSavePos);
bool TSAPI IsStatusEvent(int eventType);
bool TSAPI IsCustomEvent(int eventType);
-
+
void TSAPI CleanTempFiles();
extern INT_PTR CALLBACK SelectContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
diff --git a/plugins/TabSRMM/src/msglog.cpp b/plugins/TabSRMM/src/msglog.cpp index e8a22c1536..dfbf83e653 100644 --- a/plugins/TabSRMM/src/msglog.cpp +++ b/plugins/TabSRMM/src/msglog.cpp @@ -93,7 +93,7 @@ struct LogStreamData { int eventsToInsert;
int isEmpty;
int isAppend;
- CTabBaseDlg *dlgDat;
+ CMsgDialog *dlgDat;
DBEVENTINFO *dbei;
};
@@ -306,7 +306,7 @@ static int AppendUnicodeToBuffer(CMStringA &str, const wchar_t *line, int mode) /////////////////////////////////////////////////////////////////////////////////////////
-static void Build_RTF_Header(CMStringA &str, CTabBaseDlg *dat)
+static void Build_RTF_Header(CMStringA &str, CMsgDialog *dat)
{
int i;
LOGFONTA *logFonts = dat->m_pContainer->m_theme.logFonts;
@@ -364,14 +364,14 @@ static void Build_RTF_Header(CMStringA &str, CTabBaseDlg *dat) }
// mir_free() the return value
-static char* CreateRTFHeader(CTabBaseDlg *dat)
+static char* CreateRTFHeader(CMsgDialog *dat)
{
CMStringA str;
Build_RTF_Header(str, dat);
return str.Detach();
}
-static void AppendTimeStamp(wchar_t *szFinalTimestamp, int isSent, CMStringA &str, int skipFont, CTabBaseDlg *dat, int iFontIDOffset)
+static void AppendTimeStamp(wchar_t *szFinalTimestamp, int isSent, CMStringA &str, int skipFont, CMsgDialog *dat, int iFontIDOffset)
{
if (skipFont)
AppendUnicodeToBuffer(str, szFinalTimestamp, MAKELONG(isSent, dat->m_bIsHistory));
@@ -426,7 +426,7 @@ int DbEventIsForMsgWindow(DBEVENTINFO *dbei) return et && (et->flags & DETF_MSGWINDOW);
}
-static char* Template_CreateRTFFromDbEvent(CTabBaseDlg *dat, MCONTACT hContact, MEVENT hDbEvent, LogStreamData *streamData)
+static char* Template_CreateRTFFromDbEvent(CMsgDialog *dat, MCONTACT hContact, MEVENT hDbEvent, LogStreamData *streamData)
{
HANDLE hTimeZone = nullptr;
BOOL skipToNext = FALSE, skipFont = FALSE;
@@ -1054,7 +1054,7 @@ static DWORD CALLBACK LogStreamInEvents(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG return 0;
}
-void CTabBaseDlg::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent)
+void CMsgDialog::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent)
{
wchar_t trbuffer[40];
TEXTRANGE tr;
@@ -1176,7 +1176,7 @@ void CTabBaseDlg::ReplaceIcons(LONG startAt, int fAppend, BOOL isSent) }
}
-void CTabBaseDlg::StreamInEvents(MEVENT hDbEventFirst, int count, int fAppend, DBEVENTINFO *dbei_s)
+void CMsgDialog::StreamInEvents(MEVENT hDbEventFirst, int count, int fAppend, DBEVENTINFO *dbei_s)
{
CHARRANGE oldSel, sel;
diff --git a/plugins/TabSRMM/src/msgs.cpp b/plugins/TabSRMM/src/msgs.cpp index e3f1619744..565b0bbfa7 100644 --- a/plugins/TabSRMM/src/msgs.cpp +++ b/plugins/TabSRMM/src/msgs.cpp @@ -62,232 +62,7 @@ int SmileyAddOptionsChanged(WPARAM, LPARAM) /////////////////////////////////////////////////////////////////////////////////////////
// basic window class
-CTabBaseDlg::CTabBaseDlg(int iResource, SESSION_INFO *si)
- : CSrmmBaseDialog(g_plugin, iResource, si),
- m_pPanel(this),
- m_dwFlags(MWF_INITMODE),
- m_iInputAreaHeight(-1)
-{
- m_autoClose = CLOSE_ON_CANCEL;
- m_forceResizable = true;
-}
-
-CTabBaseDlg::~CTabBaseDlg()
-{
- delete m_pWnd;
-
- mir_free(m_sendBuffer);
- mir_free(m_hHistoryEvents);
- mir_free(m_hQueuedEvents);
-
- if (m_hClientIcon) DestroyIcon(m_hClientIcon);
- if (m_hSmileyIcon) DestroyIcon(m_hSmileyIcon);
- if (m_hXStatusIcon) DestroyIcon(m_hXStatusIcon);
- if (m_hTaskbarIcon) DestroyIcon(m_hTaskbarIcon);
-}
-
-void CTabBaseDlg::CloseTab()
-{
- int iTabs = TabCtrl_GetItemCount(m_hwndParent);
- if (iTabs == 1) {
- SendMessage(m_pContainer->m_hwnd, WM_CLOSE, 0, 1);
- return;
- }
-
- m_pContainer->m_iChilds--;
- int i = GetTabIndexFromHWND(m_hwndParent, m_hwnd);
-
- // after closing a tab, we need to activate the tab to the left side of
- // the previously open tab.
- // normally, this tab has the same index after the deletion of the formerly active tab
- // unless, of course, we closed the last (rightmost) tab.
- if (!m_pContainer->m_bDontSmartClose && iTabs > 1) {
- if (i == iTabs - 1)
- i--;
- else
- i++;
- TabCtrl_SetCurSel(m_hwndParent, i);
-
- m_pContainer->m_hwndActive = GetTabWindow(m_hwndParent, i);
-
- RECT rc;
- SendMessage(m_pContainer->m_hwnd, DM_QUERYCLIENTAREA, 0, (LPARAM)& rc);
- SetWindowPos(m_pContainer->m_hwndActive, HWND_TOP, rc.left, rc.top, (rc.right - rc.left), (rc.bottom - rc.top), SWP_SHOWWINDOW);
- ShowWindow(m_pContainer->m_hwndActive, SW_SHOW);
- SetForegroundWindow(m_pContainer->m_hwndActive);
- SetFocus(m_pContainer->m_hwndActive);
- }
-
- SendMessage(m_pContainer->m_hwnd, WM_SIZE, 0, 0);
- DestroyWindow(m_hwnd);
-}
-
-void CTabBaseDlg::LoadSettings()
-{
- m_clrInputBG = m_pContainer->m_theme.inputbg;
- LoadLogfont(FONTSECTION_IM, MSGFONTID_MESSAGEAREA, nullptr, &m_clrInputFG, FONTMODULE);
-}
-
-bool CTabBaseDlg::OnInitDialog()
-{
- CSrmmBaseDialog::OnInitDialog();
-
- // m_hwnd is valid, pass it to the tab control
- TCITEM tci;
- tci.mask = TCIF_PARAM;
- tci.lParam = (LPARAM)m_hwnd;
- TabCtrl_SetItem(m_hwndParent, m_iTabID, &tci);
-
- // update another tab ids
- m_pContainer->UpdateTabs();
-
- // add this window to window list & proxy
- if (IsWinVer7Plus() && PluginConfig.m_useAeroPeek)
- m_pWnd = new CProxyWindow(this);
- else
- m_pWnd = nullptr;
-
- // set up Windows themes
- DM_ThemeChanged();
-
- // refresh cache data for this contact
- m_cache = CContactCache::getContactCache(m_hContact);
- m_cache->updateNick();
- m_cache->updateUIN();
- m_cache->setWindowData(this);
-
- m_bIsAutosizingInput = IsAutoSplitEnabled();
- return true;
-}
-
-void CTabBaseDlg::OnDestroy()
-{
- m_cache->setWindowData();
-
- CSuper::OnDestroy();
-}
-
-INT_PTR CTabBaseDlg::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch (msg) {
- case DM_SETINFOPANEL: // broadcasted when global info panel setting changes
- if (wParam == 0 && lParam == 0) {
- m_pPanel.getVisibility();
- m_pPanel.loadHeight();
- m_pPanel.showHide();
- }
- else {
- CTabBaseDlg *srcDat = (CTabBaseDlg*)wParam;
- if (lParam == 0)
- m_pPanel.loadHeight();
- else {
- if (srcDat && lParam && this != srcDat && !m_pPanel.isPrivateHeight()) {
- if (srcDat->isChat() != isChat() && M.GetByte("syncAllPanels", 0) == 0)
- return 0;
-
- if (m_pContainer->m_pSettings->fPrivate && srcDat->m_pContainer != m_pContainer)
- return 0;
-
- m_pPanel.setHeight((LONG)lParam);
- }
- }
- Resize();
- }
- return 0;
-
- case DM_STATUSICONCHANGE:
- m_pContainer->InitRedraw();
- return 0;
-
- case DM_ACTIVATEME: // the child window will activate itself
- ActivateExistingTab(m_pContainer, m_hwnd);
- return 0;
-
- case DM_QUERYCONTAINER: // container API support functions
- if (lParam)
- *(TContainerData**)lParam = m_pContainer;
- return 0;
-
- case DM_QUERYHCONTACT:
- if (lParam)
- *(MCONTACT*)lParam = m_hContact;
- return 0;
-
- case DM_CHECKSIZE:
- m_dwFlags |= MWF_NEEDCHECKSIZE;
- return 0;
-
- case DM_CONTAINERSELECTED:
- // sent by the select container dialog box when a container was selected...
- // lParam = (wchar_t*)selected name...
- {
- wchar_t *szNewName = (wchar_t*)lParam;
- if (!mir_wstrcmp(szNewName, TranslateT("Default container")))
- szNewName = CGlobals::m_default_container_name;
-
- int iOldItems = TabCtrl_GetItemCount(m_hwndParent);
- if (!wcsncmp(m_pContainer->m_wszName, szNewName, CONTAINER_NAMELEN))
- break;
-
- TContainerData *pNewContainer = FindContainerByName(szNewName);
- if (pNewContainer == nullptr)
- if ((pNewContainer = CreateContainer(szNewName, FALSE, m_hContact)) == nullptr)
- break;
-
- db_set_ws(m_hContact, SRMSGMOD_T, "containerW", szNewName);
- PostMessage(PluginConfig.g_hwndHotkeyHandler, DM_DOCREATETAB, (WPARAM)pNewContainer, m_hContact);
- if (iOldItems > 1) // there were more than 1 tab, container is still valid
- SendMessage(m_pContainer->m_hwndActive, WM_SIZE, 0, 0);
- SetForegroundWindow(pNewContainer->m_hwnd);
- SetActiveWindow(pNewContainer->m_hwnd);
- }
- return 0;
-
- case DM_ACTIVATETOOLTIP:
- // show the balloon tooltip control.
- // wParam == id of the "anchor" element, defaults to the panel status field (for away msg retrieval)
- // lParam == new text to show
- if (!IsIconic(m_pContainer->m_hwnd) && m_pContainer->m_hwndActive == m_hwnd)
- m_pPanel.showTip(wParam, lParam);
- return 0;
-
- case DM_STATUSBARCHANGED:
- tabUpdateStatusBar();
- break;
-
- case DM_CHECKAUTOHIDE:
- // This is broadcasted by the container to all child windows to check if the
- // container can be autohidden or -closed.
- //
- // wParam is the autohide timeout (in seconds)
- // lParam points to a BOOL and a session which wants to prevent auto-hiding
- // the container must set it to FALSE.
- //
- // If no session in the container disagrees, the container will be hidden.
-
- if (lParam) {
- BOOL *fResult = (BOOL*)lParam;
- // text entered in the input area -> prevent autohide/cose
- if (GetWindowTextLength(m_message.GetHwnd()) > 0)
- *fResult = FALSE;
- // unread events, do not hide or close the container
- else if (m_dwUnread)
- *fResult = FALSE;
- // time since last activity did not yet reach the threshold.
- else if (((GetTickCount() - m_dwLastActivity) / 1000) <= wParam)
- *fResult = FALSE;
- }
- return 0;
-
- case DM_SPLITTERGLOBALEVENT:
- DM_SplitterGlobalEvent(wParam, lParam);
- return 0;
- }
-
- return CSrmmBaseDialog::DlgProc(msg, wParam, lParam);
-}
-
-void CTabBaseDlg::NotifyDeliveryFailure() const
+void CMsgDialog::NotifyDeliveryFailure() const
{
if (M.GetByte("adv_noErrorPopups", 0))
return;
@@ -316,7 +91,7 @@ void CTabBaseDlg::NotifyDeliveryFailure() const /////////////////////////////////////////////////////////////////////////////////////////
// Sets a status bar text for a contact
-void CTabBaseDlg::SetStatusText(const wchar_t *wszText, HICON hIcon)
+void CMsgDialog::SetStatusText(const wchar_t *wszText, HICON hIcon)
{
if (wszText != nullptr) {
m_bStatusSet = true;
@@ -538,7 +313,7 @@ int MyAvatarChanged(WPARAM wParam, LPARAM lParam) int TSAPI ActivateExistingTab(TContainerData *pContainer, HWND hwndChild)
{
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(hwndChild, GWLP_USERDATA); // needed to obtain the hContact for the message window
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hwndChild, GWLP_USERDATA); // needed to obtain the hContact for the message window
if (!dat || !pContainer)
return FALSE;
@@ -634,7 +409,7 @@ HWND TSAPI CreateNewTabForContact(TContainerData *pContainer, MCONTACT hContact, if (iCount > 0) {
for (int i = iCount - 1; i >= 0; i--) {
HWND hwnd = GetTabWindow(hwndTab, i);
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (dat) {
int relPos = M.GetDword(dat->m_hContact, "tabindex", i * 100);
if (iTabIndex_wanted <= relPos)
@@ -654,7 +429,7 @@ HWND TSAPI CreateNewTabForContact(TContainerData *pContainer, MCONTACT hContact, if (bActivateTab)
TabCtrl_SetCurSel(hwndTab, iTabId);
- CSrmmWindow *pWindow = new CSrmmWindow();
+ CMsgDialog *pWindow = new CMsgDialog(IDD_MSGSPLITNEW);
pWindow->m_hContact = hContact;
pWindow->m_iTabID = iTabId;
pWindow->m_pContainer = pContainer;
diff --git a/plugins/TabSRMM/src/msgs.h b/plugins/TabSRMM/src/msgs.h index 1604b40ec6..27e7ba9d38 100644 --- a/plugins/TabSRMM/src/msgs.h +++ b/plugins/TabSRMM/src/msgs.h @@ -226,9 +226,9 @@ struct TContainerData CSideBar *m_pSideBar;
void InitRedraw();
- void SetIcon(CTabBaseDlg *pDlg, HICON hIcon);
+ void SetIcon(CMsgDialog *pDlg, HICON hIcon);
void UpdateTabs();
- void UpdateTitle(MCONTACT, class CTabBaseDlg* = nullptr);
+ void UpdateTitle(MCONTACT, class CMsgDialog* = nullptr);
void ClearMargins()
{ memset(&m_mOld, 0xfe, sizeof(m_mOld));
@@ -239,30 +239,30 @@ struct TContainerData }
};
-class CTabBaseDlg : public CSrmmBaseDialog
+class CMsgDialog : public CSrmmBaseDialog
{
typedef CSrmmBaseDialog CSuper;
friend class CInfoPanel;
-protected:
- void CloseTab() override;
- void LoadSettings() override;
- void SetStatusText(const wchar_t*, HICON) override;
-
void DM_AddDivider();
void DM_DismissTip(const POINT& pt);
void DM_ErrorDetected(int type, int flag);
bool DM_GenericHotkeysCheck(MSG *message);
int DM_SplitterGlobalEvent(WPARAM wParam, LPARAM lParam);
void DM_UpdateLastMessage() const;
-
+
void DetermineMinHeight();
void FindFirstEvent();
int FindRTLLocale();
void GetSendFormat();
bool IsAutoSplitEnabled() const;
+ void LoadContactAvatar();
+ void LoadOwnAvatar();
+ void MsgWindowUpdateState(UINT msg);
void ReplaceIcons(LONG startAt, int fAppend, BOOL isSent);
+ void ReplayQueue();
void ResizeIeView();
+ void SaveAvatarToFile(HBITMAP hbm, int isOwnPic);
void ShowPopupMenu(const CCtrlBase&, POINT pt);
void VerifyProxy();
LRESULT WMCopyHandler(UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -346,7 +346,7 @@ public: int m_iLastEventType;
int m_nTypeSecs;
int m_iOpenJobs;
- int m_iInputAreaHeight;
+ int m_iInputAreaHeight = -1;
int m_maxHistory, m_curHistory;
int m_iCurrentQueueError;
int m_iSplitterY, m_dynaSplitter;
@@ -361,23 +361,72 @@ public: wchar_t m_wszStatusBar[100];
char m_szMicroLf[128];
+ int m_iMultiSplit;
+ int msgTop, rcLogBottom;
+ wchar_t *wszInitialText;
+ bool m_bActivate, m_bWantPopup, m_bIsMeta;
+
CInfoPanel m_pPanel;
+ CProxyWindow *m_pWnd; // proxy window object (win7+, for taskbar support).
CContactCache *m_cache;
TContainerData *m_pContainer; // parent container description structure
AVATARCACHEENTRY *m_ace, *m_ownAce;
- CProxyWindow *m_pWnd; // proxy window object (win7+, for taskbar support).
- // ALWAYS check this pointer before using it, it is not guaranteed to exist.
+
+ static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ bool TabAutoComplete();
+
+ HWND m_hwndFilter;
+ int m_iSearchItem;
+ BOOL m_iSavedSpaces;
+ wchar_t m_wszSearch[255];
+ wchar_t *m_wszSearchQuery, *m_wszSearchResult;
+ SESSION_INFO *m_pLastSession;
+
+ CCtrlButton m_btnOk, m_btnAdd, m_btnQuote, m_btnCancelAdd;
public:
- CTabBaseDlg(int iDialogId, SESSION_INFO* = nullptr);
- virtual ~CTabBaseDlg();
+ CMsgDialog(int dlgId, SESSION_INFO* = nullptr);
+ ~CMsgDialog();
+
+ void onClick_Ok(CCtrlButton *);
+ void onClick_Add(CCtrlButton *);
+ void onClick_Quote(CCtrlButton *);
+ void onClick_Filter(CCtrlButton *);
+ void onClick_CancelAdd(CCtrlButton *);
+ void onClick_ShowNickList(CCtrlButton *);
+
+ void onChange_Message(CCtrlEdit *);
+
+ void onDblClick_List(CCtrlListBox *);
+
+ int OnFilter(MSGFILTER *);
bool OnInitDialog() override;
void OnDestroy() override;
- INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ int Resizer(UTILRESIZECONTROL *urc) override;
+
+ void UpdateWindowState(UINT msg);
+
+ LRESULT DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
+ LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
+ void AddLog() override;
+ void CloseTab() override;
+ void LoadSettings() override;
+ void RedrawLog() override;
+ void ScrollToBottom() override;
+ void SetStatusText(const wchar_t *, HICON) override;
+ void ShowFilterMenu() override;
+ void StreamInEvents(LOGINFO *lin, bool bRedraw) override;
+ void UpdateNickList() override;
+ void UpdateOptions() override;
+ void UpdateStatusBar() override;
+ void UpdateTitle() override;
- virtual CThumbBase* tabCreateThumb(CProxyWindow*) const = 0;
- virtual void tabClearLog() = 0;
+ CThumbBase* tabCreateThumb(CProxyWindow*) const;
+ void tabClearLog();
void tabUpdateStatusBar() const;
static LONG_PTR CALLBACK StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
@@ -394,6 +443,7 @@ public: void DM_InitRichEdit();
void DM_InitTip();
void DM_NotifyTyping(int mode);
+ void DM_OptionsApplied(WPARAM wParam, LPARAM lParam);
void DM_RecalcPictureSize();
void DM_SaveLogAsRTF() const;
void DM_ScrollToBottom(WPARAM wParam, LPARAM lParam);
@@ -461,111 +511,9 @@ public: void UpdateToolbarBG();
};
-class CSrmmWindow : public CTabBaseDlg
+class CTemplateEditDlg : public CMsgDialog
{
- typedef CTabBaseDlg CSuper;
-
- virtual CThumbBase* tabCreateThumb(CProxyWindow *pProxy) const override;
- virtual void tabClearLog() override;
-
- CCtrlButton m_btnOk, m_btnAdd, m_btnQuote, m_btnCancelAdd;
-
- virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
-
- void LoadContactAvatar();
- void LoadOwnAvatar();
- void MsgWindowUpdateState(UINT msg);
- void ReplayQueue();
-
-public:
- int m_iMultiSplit;
- int msgTop, rcLogBottom;
- wchar_t *wszInitialText;
- bool m_bActivate, m_bWantPopup, m_bIsMeta;
-
-public:
- CSrmmWindow();
-
- bool OnInitDialog() override;
- void OnDestroy() override;
-
- int Resizer(UTILRESIZECONTROL *urc) override;
-
- void UpdateTitle() override;
-
- INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
-
- void onClick_Ok(CCtrlButton*);
- void onClick_Add(CCtrlButton*);
- void onClick_Quote(CCtrlButton*);
- void onClick_CancelAdd(CCtrlButton*);
-
- void onChange_Message(CCtrlEdit*);
-
- int OnFilter(MSGFILTER*);
-
- void DM_OptionsApplied(WPARAM wParam, LPARAM lParam);
-};
-
-class CMsgDialog : public CTabBaseDlg
-{
- typedef CTabBaseDlg CSuper;
-
- HWND m_hwndFilter;
- CCtrlButton m_btnOk;
-
- virtual LRESULT WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam) override;
- virtual LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam) override;
-
- static INT_PTR CALLBACK FilterWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
-
- virtual CThumbBase* tabCreateThumb(CProxyWindow *pProxy) const override;
- virtual void tabClearLog() override;
-
- bool TabAutoComplete();
-
- int m_iSearchItem;
- BOOL m_iSavedSpaces;
- wchar_t m_wszSearch[255];
- wchar_t *m_wszSearchQuery, *m_wszSearchResult;
- SESSION_INFO *m_pLastSession;
-
-public:
- CMsgDialog(SESSION_INFO*);
-
- bool OnInitDialog() override;
- void OnDestroy() override;
-
- int Resizer(UTILRESIZECONTROL *urc) override;
-
- void AddLog() override;
- void RedrawLog() override;
- void ScrollToBottom() override;
- void ShowFilterMenu() override;
- void StreamInEvents(LOGINFO* lin, bool bRedraw) override;
- void UpdateNickList() override;
- void UpdateOptions() override;
- void UpdateStatusBar() override;
- void UpdateTitle() override;
-
- INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
-
- void onClick_OK(CCtrlButton*);
- void onClick_Filter(CCtrlButton*);
- void onClick_ShowNickList(CCtrlButton*);
-
- void onDblClick_List(CCtrlListBox*);
-
- void onChange_Message(CCtrlEdit*);
-
- void UpdateWindowState(UINT msg);
-};
-
-class CTemplateEditDlg : public CTabBaseDlg
-{
- typedef CTabBaseDlg CSuper;
+ typedef CMsgDialog CSuper;
BOOL rtl;
BOOL changed; // template in edit field is changed
@@ -580,10 +528,6 @@ class CTemplateEditDlg : public CTabBaseDlg CCtrlListBox listTemplates;
CCtrlHyperlink urlHelp;
- virtual CThumbBase* tabCreateThumb(CProxyWindow*) const override { return nullptr; }
- virtual void tabClearLog() override {}
- virtual void UpdateTitle() override {};
-
public:
CTemplateEditDlg(BOOL rtl, HWND hwndParent);
@@ -977,14 +921,15 @@ struct TOptionListItem #define IDC_SBAR_TOGGLEFORMAT 1117
#define IDC_SBAR_CANCEL 1118
-struct SIDEBARITEM {
+struct SIDEBARITEM
+{
UINT uId;
DWORD dwFlags;
- HICON *hIcon, *hIconPressed, *hIconHover;
- wchar_t *szName;
- void(*pfnAction)(ButtonItem *item, HWND hwndDlg, CSrmmWindow *dat, HWND hwndItem);
- void(*pfnCallback)(ButtonItem *item, HWND hwndDlg, CSrmmWindow *dat, HWND hwndItem);
- wchar_t *tszTip;
+ HICON *hIcon, *hIconPressed, *hIconHover;
+ wchar_t *szName;
+ void (*pfnAction)(ButtonItem *item, HWND hwndDlg, CMsgDialog *dat, HWND hwndItem);
+ void (*pfnCallback)(ButtonItem *item, HWND hwndDlg, CMsgDialog *dat, HWND hwndItem);
+ wchar_t *tszTip;
};
#define FONTF_BOLD 1
diff --git a/plugins/TabSRMM/src/selectcontainer.cpp b/plugins/TabSRMM/src/selectcontainer.cpp index 04e5685b2c..b925a97dc5 100644 --- a/plugins/TabSRMM/src/selectcontainer.cpp +++ b/plugins/TabSRMM/src/selectcontainer.cpp @@ -45,7 +45,7 @@ INT_PTR CALLBACK SelectContainerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, L TranslateDialogDefault(hwndDlg);
if (lParam) {
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr((HWND)lParam, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr((HWND)lParam, GWLP_USERDATA);
if (dat) {
mir_snwprintf(szNewTitle, TranslateT("Select container for %s"), dat->m_cache->getNick());
SetWindowText(hwndDlg, szNewTitle);
diff --git a/plugins/TabSRMM/src/sendqueue.cpp b/plugins/TabSRMM/src/sendqueue.cpp index b43c0b1c8a..c09dbcff03 100644 --- a/plugins/TabSRMM/src/sendqueue.cpp +++ b/plugins/TabSRMM/src/sendqueue.cpp @@ -35,7 +35,7 @@ SendQueue *sendQueue = nullptr; // as "failed" by either the ACKRESULT_FAILED or a timeout handler // returns: zero-based queue index or -1 if none was found -int SendQueue::findNextFailed(const CTabBaseDlg *dat) const +int SendQueue::findNextFailed(const CMsgDialog *dat) const { if (dat) for (int i = 0; i < NR_SENDJOBS; i++) @@ -45,7 +45,7 @@ int SendQueue::findNextFailed(const CTabBaseDlg *dat) const return -1; } -void SendQueue::handleError(CTabBaseDlg *dat, const int iEntry) const +void SendQueue::handleError(CMsgDialog *dat, const int iEntry) const { if (!dat) return; @@ -63,7 +63,7 @@ void SendQueue::handleError(CTabBaseDlg *dat, const int iEntry) const //add a message to the sending queue. // iLen = required size of the memory block to hold the message -int SendQueue::addTo(CTabBaseDlg *dat, size_t iLen, int dwFlags) +int SendQueue::addTo(CMsgDialog *dat, size_t iLen, int dwFlags) { int i; int iFound = NR_SENDJOBS; @@ -190,7 +190,7 @@ size_t SendQueue::getSendLength(const int iEntry) return p.iSendLength; } -int SendQueue::sendQueued(CTabBaseDlg *dat, const int iEntry) +int SendQueue::sendQueued(CMsgDialog *dat, const int iEntry) { HWND hwndDlg = dat->GetHwnd(); CContactCache *ccActive = CContactCache::getContactCache(dat->m_hContact); @@ -321,15 +321,15 @@ void SendQueue::clearJob(const int iIndex) // ) user decided to cancel a failed send // it removes the completed / canceled send job from the queue and schedules the next job to send (if any) -void SendQueue::checkQueue(const CTabBaseDlg *dat) const +void SendQueue::checkQueue(const CMsgDialog *dat) const { if (dat) { HWND hwndDlg = dat->GetHwnd(); if (dat->m_iOpenJobs == 0) - ::HandleIconFeedback(const_cast<CTabBaseDlg*>(dat), (HICON)INVALID_HANDLE_VALUE); + ::HandleIconFeedback(const_cast<CMsgDialog*>(dat), (HICON)INVALID_HANDLE_VALUE); else if (!(dat->m_sendMode & SMODE_NOACK)) - ::HandleIconFeedback(const_cast<CTabBaseDlg*>(dat), PluginConfig.g_IconSend); + ::HandleIconFeedback(const_cast<CMsgDialog*>(dat), PluginConfig.g_IconSend); if (dat->m_pContainer->m_hwndActive == hwndDlg) dat->UpdateReadChars(); @@ -340,7 +340,7 @@ void SendQueue::checkQueue(const CTabBaseDlg *dat) const // logs an error message to the message window.Optionally, appends the original message // from the given sendJob (queue index) -void SendQueue::logError(CTabBaseDlg *dat, int iSendJobIndex, const wchar_t *szErrMsg) const +void SendQueue::logError(CMsgDialog *dat, int iSendJobIndex, const wchar_t *szErrMsg) const { if (dat == nullptr) return; @@ -367,7 +367,7 @@ void SendQueue::logError(CTabBaseDlg *dat, int iSendJobIndex, const wchar_t *szE ///////////////////////////////////////////////////////////////////////////////////////// // show or hide the error control button bar on top of the window -void SendQueue::showErrorControls(CTabBaseDlg *dat, const int showCmd) const +void SendQueue::showErrorControls(CMsgDialog *dat, const int showCmd) const { UINT myerrorControls[] = { IDC_STATICERRORICON, IDC_STATICTEXT, IDC_RETRY, IDC_CANCELSEND, IDC_MSGSENDLATER }; HWND hwndDlg = dat->GetHwnd(); @@ -395,7 +395,7 @@ void SendQueue::showErrorControls(CTabBaseDlg *dat, const int showCmd) const dat->EnableSending(TRUE); } -void SendQueue::recallFailed(CTabBaseDlg *dat, int iEntry) const +void SendQueue::recallFailed(CMsgDialog *dat, int iEntry) const { if (dat == nullptr) return; @@ -412,7 +412,7 @@ void SendQueue::recallFailed(CTabBaseDlg *dat, int iEntry) const SendDlgItemMessage(dat->GetHwnd(), IDC_SRMM_MESSAGE, EM_SETSEL, -1, -1); } -int SendQueue::ackMessage(CTabBaseDlg *dat, WPARAM wParam, LPARAM lParam) +int SendQueue::ackMessage(CMsgDialog *dat, WPARAM wParam, LPARAM lParam) { ACKDATA *ack = (ACKDATA *)lParam; @@ -537,7 +537,7 @@ LRESULT SendQueue::WarnPendingJobs(unsigned int) // // @return the index on success, -1 on failure -int SendQueue::doSendLater(int iJobIndex, CTabBaseDlg *dat, MCONTACT hContact, bool fIsSendLater) +int SendQueue::doSendLater(int iJobIndex, CMsgDialog *dat, MCONTACT hContact, bool fIsSendLater) { bool fAvail = sendLater->isAvail(); diff --git a/plugins/TabSRMM/src/sendqueue.h b/plugins/TabSRMM/src/sendqueue.h index 2235168ba4..d7c797c5f9 100644 --- a/plugins/TabSRMM/src/sendqueue.h +++ b/plugins/TabSRMM/src/sendqueue.h @@ -85,17 +85,17 @@ public: SendJob *getJobByIndex(const int index) { return(&m_jobs[index]); }
void clearJob(const int index);
- int findNextFailed(const CTabBaseDlg *dat) const;
- void handleError(CTabBaseDlg *dat, const int iEntry) const;
- int addTo(CTabBaseDlg *dat, size_t iLen, int dwFlags);
- int sendQueued(CTabBaseDlg *dat, const int iEntry);
+ int findNextFailed(const CMsgDialog *dat) const;
+ void handleError(CMsgDialog *dat, const int iEntry) const;
+ int addTo(CMsgDialog *dat, size_t iLen, int dwFlags);
+ int sendQueued(CMsgDialog *dat, const int iEntry);
size_t getSendLength(const int iEntry);
- void checkQueue(const CTabBaseDlg *dat) const;
- void logError(CTabBaseDlg *dat, int iSendJobIndex, const wchar_t *szErrMsg) const;
- void recallFailed(CTabBaseDlg *dat, int iEntry) const;
- void showErrorControls(CTabBaseDlg *dat, const int showCmd) const;
- int ackMessage(CTabBaseDlg *dat, WPARAM wParam, LPARAM lParam);
- int doSendLater(int iIndex, CTabBaseDlg *dat, MCONTACT hContact = 0, bool fIsSendLater = true);
+ void checkQueue(const CMsgDialog *dat) const;
+ void logError(CMsgDialog *dat, int iSendJobIndex, const wchar_t *szErrMsg) const;
+ void recallFailed(CMsgDialog *dat, int iEntry) const;
+ void showErrorControls(CMsgDialog *dat, const int showCmd) const;
+ int ackMessage(CMsgDialog *dat, WPARAM wParam, LPARAM lParam);
+ int doSendLater(int iIndex, CMsgDialog *dat, MCONTACT hContact = 0, bool fIsSendLater = true);
// static members
static LRESULT TSAPI WarnPendingJobs(unsigned int uNrMessages);
@@ -108,6 +108,6 @@ private: extern SendQueue *sendQueue;
int TSAPI ActivateExistingTab(TContainerData *pContainer, HWND hwndChild);
-void TSAPI HandleIconFeedback(CTabBaseDlg *dat, HICON iIcon);
+void TSAPI HandleIconFeedback(CMsgDialog *dat, HICON iIcon);
#endif /* __SENDQUEUE_H */
diff --git a/plugins/TabSRMM/src/sidebar.cpp b/plugins/TabSRMM/src/sidebar.cpp index 5f43e104c4..6b77165c6f 100644 --- a/plugins/TabSRMM/src/sidebar.cpp +++ b/plugins/TabSRMM/src/sidebar.cpp @@ -71,7 +71,7 @@ TSideBarLayout CSideBar::m_layouts[CSideBar::NR_LAYOUTS] = { }
};
-CSideBarButton::CSideBarButton(CTabBaseDlg *dat, CSideBar *sideBar)
+CSideBarButton::CSideBarButton(CMsgDialog *dat, CSideBar *sideBar)
{
m_dat = dat;
m_id = UINT(dat->m_hContact); // set the control id
@@ -503,7 +503,7 @@ void CSideBar::populateAll() if (hDlg == 0 || !IsWindow(hDlg))
continue;
- CSrmmWindow *dat = (CSrmmWindow*)::GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)::GetWindowLongPtr(hDlg, GWLP_USERDATA);
if (dat == nullptr)
continue;
@@ -528,7 +528,7 @@ void CSideBar::populateAll() * (that is, it can only be used after WM_INITIALOG completed).
*position: -1 = append, otherwise insert it at the given position
*/
-void CSideBar::addSession(CTabBaseDlg *dat, int position)
+void CSideBar::addSession(CMsgDialog *dat, int position)
{
if (!m_isActive)
return;
@@ -561,7 +561,7 @@ void CSideBar::addSession(CTabBaseDlg *dat, int position) *
* @param dat _MessageWindowData *: session data for a client session.
*/
-HRESULT CSideBar::removeSession(CTabBaseDlg *dat)
+HRESULT CSideBar::removeSession(CMsgDialog *dat)
{
if (dat) {
CSideBarButton *item = findSession(dat);
@@ -638,7 +638,7 @@ void CSideBar::scrollIntoView(const CSideBarButton *item) *
* @param dat _MessageWindowData*: Session data
*/
-void CSideBar::updateSession(CTabBaseDlg *dat)
+void CSideBar::updateSession(CMsgDialog *dat)
{
if (!m_isVisible || !m_isActive)
return;
@@ -670,7 +670,7 @@ void CSideBar::updateSession(CTabBaseDlg *dat) *
* @return The previously active item (that can be zero)
*/
-const CSideBarButton* CSideBar::setActiveItem(const CTabBaseDlg *dat)
+const CSideBarButton* CSideBar::setActiveItem(const CMsgDialog *dat)
{
CSideBarButton *item = findSession(dat);
if (item != nullptr)
@@ -789,7 +789,7 @@ void CSideBar::showAll(int showCmd) * @return CSideBarButtonItem*: pointer to the found item. Zero, if none was found
*/
-CSideBarButton* CSideBar::findSession(const CTabBaseDlg *dat)
+CSideBarButton* CSideBar::findSession(const CMsgDialog *dat)
{
if (dat == nullptr)
return nullptr;
@@ -845,7 +845,7 @@ void CSideBar::resizeScrollWnd(LONG x, LONG y, LONG, LONG height) const SWP_NOCOPYBITS | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSENDCHANGING | SWP_DEFERERASE | SWP_ASYNCWINDOWPOS);
}
-void CSideBar::invalidateButton(CTabBaseDlg *dat)
+void CSideBar::invalidateButton(CMsgDialog *dat)
{
if (m_isActive && m_isVisible) {
CSideBarButton *item = findSession(dat);
@@ -1041,7 +1041,7 @@ void __fastcall CSideBar::m_DefaultContentRenderer(const HDC hdc, const RECT *rc void __fastcall CSideBar::m_AdvancedContentRenderer(const HDC hdc, const RECT *rcBox,
const CSideBarButton *item)
{
- const CTabBaseDlg *dat = item->getDat();
+ const CMsgDialog *dat = item->getDat();
UINT id = item->getID();
LONG cx = rcBox->right - rcBox->left;
@@ -1119,7 +1119,7 @@ const SIZE& __fastcall CSideBar::m_measureAdvancedVertical(CSideBarButton* item) {
SIZE sz = { 0 };
- const CTabBaseDlg *dat = item->getDat();
+ const CMsgDialog *dat = item->getDat();
if (dat) {
SIZE szFirstLine, szSecondLine;
diff --git a/plugins/TabSRMM/src/sidebar.h b/plugins/TabSRMM/src/sidebar.h index 424cfd0269..c8fa3e472f 100644 --- a/plugins/TabSRMM/src/sidebar.h +++ b/plugins/TabSRMM/src/sidebar.h @@ -32,7 +32,7 @@ struct TSideBarNotify
{
NMHDR nmHdr;
- CTabBaseDlg *dat;
+ CMsgDialog *dat;
};
/* layout description structure */
@@ -61,7 +61,7 @@ class CSideBarButton {
public:
CSideBarButton(const UINT id, CSideBar *sideBar);
- CSideBarButton(CTabBaseDlg *dat, CSideBar *sideBar);
+ CSideBarButton(CMsgDialog *dat, CSideBar *sideBar);
~CSideBarButton();
LONG getHeight() const { return(m_sz.cy); }
@@ -71,7 +71,7 @@ public: const HWND getHwnd() const { return(m_hwnd); }
const UINT getID() const { return(m_id); }
const MCONTACT getContactHandle() const { return(m_dat->m_hContact); }
- const CTabBaseDlg* getDat() const { return(m_dat); }
+ const CMsgDialog* getDat() const { return(m_dat); }
const TSideBarLayout* getLayout() const { return(m_sideBarLayout); }
void RenderThis(const HDC hdc) const;
@@ -91,7 +91,7 @@ private: private:
const TSideBarLayout* m_sideBarLayout;
HWND m_hwnd; // window handle for the TSButton object
- CTabBaseDlg *m_dat; // session data
+ CMsgDialog *m_dat; // session data
UINT m_id; // control id
bool m_isTopAligned;
SIZE m_sz;
@@ -130,9 +130,9 @@ public: ~CSideBar();
void Init();
- void addSession(CTabBaseDlg *dat, int position);
- HRESULT removeSession(CTabBaseDlg *dat);
- void updateSession(CTabBaseDlg *dat);
+ void addSession(CMsgDialog *dat, int position);
+ HRESULT removeSession(CMsgDialog *dat);
+ void updateSession(CMsgDialog *dat);
void processScrollerButtons(UINT cmd);
void Layout();
@@ -149,7 +149,7 @@ public: const CSideBarButton* getScrollDown() const { return(m_down); }
bool isSkinnedContainer() const { return(CSkin::m_skinEnabled ? true : false); }
const UINT getLayoutId() const { return(m_uLayout); }
- void invalidateButton(CTabBaseDlg *dat);
+ void invalidateButton(CMsgDialog *dat);
const CSideBarButton* setActiveItem(const CSideBarButton *newItem)
{
@@ -171,7 +171,7 @@ public: }
HWND getScrollWnd() const { return(m_hwndScrollWnd); }
const CSideBarButton* getHoveredClose() const { return(m_hoveredClose); }
- const CSideBarButton* setActiveItem(const CTabBaseDlg *dat);
+ const CSideBarButton* setActiveItem(const CMsgDialog *dat);
static LRESULT CALLBACK wndProcStub(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
@@ -189,7 +189,7 @@ private: void populateAll();
void removeAll();
void Invalidate();
- CSideBarButton* findSession(const CTabBaseDlg *dat);
+ CSideBarButton* findSession(const CMsgDialog *dat);
CSideBarButton* findSession(const MCONTACT hContact);
LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
diff --git a/plugins/TabSRMM/src/stdafx.h b/plugins/TabSRMM/src/stdafx.h index 551630bf7f..8aef3fe071 100644 --- a/plugins/TabSRMM/src/stdafx.h +++ b/plugins/TabSRMM/src/stdafx.h @@ -248,6 +248,6 @@ INT_PTR CALLBACK DlgProcSetupStatusModes(HWND hwndDlg, UINT msg, WPARAM wParam, int TSAPI TBStateConvert2Flat(int state);
int TSAPI RBStateConvert2Flat(int state);
-void TSAPI FillTabBackground(const HDC hdc, int iStateId, const CTabBaseDlg *dat, RECT* rc);
+void TSAPI FillTabBackground(const HDC hdc, int iStateId, const CMsgDialog *dat, RECT* rc);
#define IS_EXTKEY(a) (a & (1 << 24))
diff --git a/plugins/TabSRMM/src/tabctrl.cpp b/plugins/TabSRMM/src/tabctrl.cpp index 5a89e6031d..ca32820cb6 100644 --- a/plugins/TabSRMM/src/tabctrl.cpp +++ b/plugins/TabSRMM/src/tabctrl.cpp @@ -139,7 +139,7 @@ static void TSAPI DrawCustomTabPage(HDC hdc, RECT& rcClient) ::DeleteObject(hPen);
}
-void TSAPI FillTabBackground(const HDC hdc, int iStateId, const CTabBaseDlg *dat, RECT* rc)
+void TSAPI FillTabBackground(const HDC hdc, int iStateId, const CMsgDialog *dat, RECT* rc)
{
unsigned clrIndex;
@@ -160,7 +160,7 @@ void TSAPI FillTabBackground(const HDC hdc, int iStateId, const CTabBaseDlg *dat // no image list is used and necessary, the message window dialog procedure has to provide a valid
// icon handle in dat->hTabIcon
-static void DrawItem(TabControlData *tabdat, HDC dc, RECT *rcItem, int nHint, int nItem, CSrmmWindow *dat)
+static void DrawItem(TabControlData *tabdat, HDC dc, RECT *rcItem, int nHint, int nItem, CMsgDialog *dat)
{
if (dat == nullptr)
return;
@@ -235,7 +235,7 @@ static void DrawItem(TabControlData *tabdat, HDC dc, RECT *rcItem, int nHint, in static RECT rcTabPage = { 0 };
-static void DrawItemRect(TabControlData *tabdat, HDC dc, RECT *rcItem, int nHint, const CSrmmWindow *dat)
+static void DrawItemRect(TabControlData *tabdat, HDC dc, RECT *rcItem, int nHint, const CMsgDialog *dat)
{
POINT pt;
DWORD dwStyle = tabdat->dwStyle;
@@ -393,7 +393,7 @@ static int DWordAlign(int n) return n;
}
-static HRESULT DrawThemesPartWithAero(const TabControlData *tabdat, HDC hDC, int iPartId, int iStateId, LPRECT prcBox, CSrmmWindow *dat)
+static HRESULT DrawThemesPartWithAero(const TabControlData *tabdat, HDC hDC, int iPartId, int iStateId, LPRECT prcBox, CMsgDialog *dat)
{
HRESULT hResult = 0;
bool bAero = M.isAero();
@@ -440,7 +440,7 @@ static HRESULT DrawThemesPart(const TabControlData *tabdat, HDC hDC, int iPartId // draw a themed tab item. either a tab or the body pane
// handles image mirroring for tabs at the bottom
-static void DrawThemesXpTabItem(HDC pDC, RECT *rcItem, UINT uiFlag, TabControlData *tabdat, CSrmmWindow *dat)
+static void DrawThemesXpTabItem(HDC pDC, RECT *rcItem, UINT uiFlag, TabControlData *tabdat, CMsgDialog *dat)
{
BOOL bBody = (uiFlag & 1) ? TRUE : FALSE;
BOOL bSel = (uiFlag & 2) ? TRUE : FALSE;
@@ -614,7 +614,7 @@ static void PaintWorker(HWND hwnd, TabControlData *tabdat) tabdat->helperDat = nullptr;
if (tabdat->bAeroTabs) {
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(tabdat->pContainer->m_hwndActive, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(tabdat->pContainer->m_hwndActive, GWLP_USERDATA);
if (dat)
tabdat->helperDat = dat;
else
@@ -841,9 +841,9 @@ page_done: if (i == iActive)
continue;
- CSrmmWindow *dat = nullptr;
+ CMsgDialog *dat = nullptr;
if (HWND hDlg = GetTabWindow(hwnd, i))
- dat = (CSrmmWindow*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
TabCtrl_GetItemRect(hwnd, i, &rcItem);
if (!bClassicDraw && uiBottom) {
rcItem.top -= PluginConfig.tabConfig.m_bottomAdjust;
@@ -871,12 +871,12 @@ page_done: rctActive.bottom -= PluginConfig.tabConfig.m_bottomAdjust;
}
if (rctActive.left >= 0) {
- CSrmmWindow *dat = nullptr;
+ CMsgDialog *dat = nullptr;
int nHint = 0;
rcItem = rctActive;
if (HWND hDlg = GetTabWindow(hwnd, iActive))
- dat = (CSrmmWindow*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
if (!bClassicDraw && !(dwStyle & TCS_BUTTONS)) {
InflateRect(&rcItem, 2, 2);
@@ -1104,7 +1104,7 @@ static LRESULT CALLBACK TabControlSubclassProc(HWND hwnd, UINT msg, WPARAM wPara int i = GetTabItemFromMouse(hwnd, &pt);
if (i != -1) {
HWND hDlg = GetTabWindow(hwnd, i);
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
if (dat) {
tabdat->bDragging = true;
tabdat->iBeginIndex = i;
@@ -1129,7 +1129,7 @@ static LRESULT CALLBACK TabControlSubclassProc(HWND hwnd, UINT msg, WPARAM wPara int i = GetTabItemFromMouse(hwnd, &pt);
if (i != -1) {
HWND hDlg = GetTabWindow(hwnd, i);
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
if (dat) {
tabdat->bDragging = true;
tabdat->iBeginIndex = i;
@@ -1249,9 +1249,9 @@ static LRESULT CALLBACK TabControlSubclassProc(HWND hwnd, UINT msg, WPARAM wPara if (nItem >= 0 && nItem < TabCtrl_GetItemCount(hwnd)) {
// get the message window data for the session to which this tab item belongs
HWND hDlg = GetTabWindow(hwnd, nItem);
- CSrmmWindow *dat = nullptr;
+ CMsgDialog *dat = nullptr;
if (IsWindow(hDlg) && hDlg != 0)
- dat = (CSrmmWindow*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(hDlg, GWLP_USERDATA);
if (dat) {
tabdat->bTipActive = true;
ti.isGroup = 0;
@@ -1351,7 +1351,7 @@ int TSAPI RegisterTabCtrlClass(void) RegisterClassEx(&wc);
wc.lpszClassName = L"TSStatusBarClass";
- wc.lpfnWndProc = &CTabBaseDlg::StatusBarSubclassProc;
+ wc.lpfnWndProc = &CMsgDialog::StatusBarSubclassProc;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.cbWndExtra = sizeof(void*);
wc.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_PARENTDC;
diff --git a/plugins/TabSRMM/src/taskbar.cpp b/plugins/TabSRMM/src/taskbar.cpp index 1fe035bc38..7f8d9ab86c 100644 --- a/plugins/TabSRMM/src/taskbar.cpp +++ b/plugins/TabSRMM/src/taskbar.cpp @@ -179,7 +179,7 @@ void CTaskbarInteract::SetTabActive(const HWND hwndTab, const HWND hwndGroup) co *
* static member function
*/
-void CTabBaseDlg::VerifyProxy()
+void CMsgDialog::VerifyProxy()
{
if (IsWinVer7Plus() && PluginConfig.m_useAeroPeek) {
if (nullptr == m_pWnd) {
@@ -207,7 +207,7 @@ void CTabBaseDlg::VerifyProxy() * and previews for a message session.
* each tab has one invisible proxy window
*/
-CProxyWindow::CProxyWindow(CTabBaseDlg *dat) :
+CProxyWindow::CProxyWindow(CMsgDialog *dat) :
m_dat(dat)
{
m_hwndProxy = ::CreateWindowEx(/*WS_EX_TOOLWINDOW | */WS_EX_NOACTIVATE, PROXYCLASSNAME, L"",
@@ -288,7 +288,7 @@ void CProxyWindow::sendPreview() if (m_dat->m_pContainer == nullptr)
return;
- CSrmmWindow *dat_active = reinterpret_cast<CSrmmWindow *>(::GetWindowLongPtr(m_dat->m_pContainer->m_hwndActive, GWLP_USERDATA));
+ CMsgDialog *dat_active = reinterpret_cast<CMsgDialog *>(::GetWindowLongPtr(m_dat->m_pContainer->m_hwndActive, GWLP_USERDATA));
if (!m_thumb || !dat_active)
return;
diff --git a/plugins/TabSRMM/src/taskbar.h b/plugins/TabSRMM/src/taskbar.h index 9da6ab0d0d..622ec3cff9 100644 --- a/plugins/TabSRMM/src/taskbar.h +++ b/plugins/TabSRMM/src/taskbar.h @@ -49,7 +49,7 @@ public: virtual void update() = 0;
protected:
- const CTabBaseDlg *m_dat;
+ const CMsgDialog *m_dat;
const CProxyWindow *m_pWnd;
HBITMAP m_hbmThumb, m_hbmOld;
@@ -98,7 +98,7 @@ private: class CProxyWindow
{
public:
- CProxyWindow(CTabBaseDlg *dat);
+ CProxyWindow(CMsgDialog *dat);
~CProxyWindow();
void updateIcon(const HICON hIcon) const;
@@ -109,7 +109,7 @@ public: void Invalidate() const;
void verifyDwmState();
- __inline const CTabBaseDlg* getDat() const { return m_dat; }
+ __inline const CMsgDialog* getDat() const { return m_dat; }
__inline const LONG getWidth() const { return m_width; }
__inline const LONG getHeight() const { return m_height; }
__inline const HWND getHwnd() const { return m_hwndProxy; }
@@ -119,7 +119,7 @@ public: static LRESULT CALLBACK stubWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
- CTabBaseDlg *m_dat;
+ CMsgDialog *m_dat;
HWND m_hwndProxy = nullptr;
LONG m_width, m_height;
diff --git a/plugins/TabSRMM/src/themeio.cpp b/plugins/TabSRMM/src/themeio.cpp index 5b0bf7c027..abf9af9021 100644 --- a/plugins/TabSRMM/src/themeio.cpp +++ b/plugins/TabSRMM/src/themeio.cpp @@ -176,7 +176,7 @@ int TSAPI CheckThemeVersion(const wchar_t *szIniFilename) return 0;
}
-void TSAPI WriteThemeToINI(const wchar_t *szIniFilenameT, CSrmmWindow *dat)
+void TSAPI WriteThemeToINI(const wchar_t *szIniFilenameT, CMsgDialog *dat)
{
int i, n = 0;
DBVARIANT dbv;
diff --git a/plugins/TabSRMM/src/themes.cpp b/plugins/TabSRMM/src/themes.cpp index 48584e43e0..a1b2368a04 100644 --- a/plugins/TabSRMM/src/themes.cpp +++ b/plugins/TabSRMM/src/themes.cpp @@ -1911,7 +1911,7 @@ void CSkin::DrawDimmedIcon(HDC hdc, LONG left, LONG top, LONG dx, LONG dy, HICON DeleteDC(dcMem);
}
-UINT CSkin::NcCalcRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC MyWndProc)
+UINT CSkin::NcCalcRichEditFrame(HWND hwnd, const CMsgDialog *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC MyWndProc)
{
NCCALCSIZE_PARAMS *nccp = (NCCALCSIZE_PARAMS *)lParam;
BOOL bReturn = FALSE;
@@ -1956,7 +1956,7 @@ UINT CSkin::NcCalcRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID // process WM_NCPAINT for the rich edit control. Draws a visual style border and avoid
// classic static edge / client edge may also draw a colorized border around the control
-UINT CSkin::DrawRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc)
+UINT CSkin::DrawRichEditFrame(HWND hwnd, const CMsgDialog *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc)
{
// do default processing (otherwise, NO scrollbar as it is painted in NC_PAINT)
LRESULT result = (OldWndProc == nullptr) ? 0 : mir_callNextSubclass(hwnd, OldWndProc, msg, wParam, lParam);
@@ -2142,7 +2142,7 @@ void CSkin::MapClientToParent(HWND hwndClient, HWND hwndParent, RECT &rc) // @param hdc HDC: handle to the device context in which painting should occur.
// @param rcWindow RECT &: The window rectangle of the message dialog window
-void CTabBaseDlg::RenderToolbarBG(HDC hdc, const RECT &rcWindow) const
+void CMsgDialog::RenderToolbarBG(HDC hdc, const RECT &rcWindow) const
{
if (m_pContainer->m_dwFlags & CNT_HIDETOOLBAR)
return;
@@ -2401,7 +2401,7 @@ void CSkin::extractSkinsAndLogo(bool fForceOverwrite) const /////////////////////////////////////////////////////////////////////////////////////////
// redraw the splitter area between the message input and message log area only
-void CTabBaseDlg::UpdateToolbarBG()
+void CMsgDialog::UpdateToolbarBG()
{
RECT rcUpdate, rcTmp;
::GetWindowRect(m_log.GetHwnd(), &rcTmp);
diff --git a/plugins/TabSRMM/src/themes.h b/plugins/TabSRMM/src/themes.h index 96233533a4..1f11390521 100644 --- a/plugins/TabSRMM/src/themes.h +++ b/plugins/TabSRMM/src/themes.h @@ -370,8 +370,8 @@ public: static void TSAPI SkinDrawBG(HWND hwndClient, HWND hwnd, TContainerData *pContainer, RECT *rcClient, HDC hdcTarget);
static void TSAPI DrawDimmedIcon(HDC hdc, LONG left, LONG top, LONG dx, LONG dy, HICON hIcon, BYTE alpha);
static DWORD TSAPI HexStringToLong(const wchar_t *szSource);
- static UINT TSAPI DrawRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc);
- static UINT TSAPI NcCalcRichEditFrame(HWND hwnd, const CTabBaseDlg *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc);
+ static UINT TSAPI DrawRichEditFrame(HWND hwnd, const CMsgDialog *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc);
+ static UINT TSAPI NcCalcRichEditFrame(HWND hwnd, const CMsgDialog *mwdat, UINT skinID, UINT msg, WPARAM wParam, LPARAM lParam, WNDPROC OldWndProc);
static HBITMAP TSAPI CreateAeroCompatibleBitmap(const RECT &rc, HDC dc);
static int TSAPI RenderText(HDC hdc, HANDLE hTheme, const wchar_t *szText, RECT *rc, DWORD dtFlags, const int iGlowSize = DEFAULT_GLOW_SIZE, COLORREF clr = 0, bool fForceAero = false);
static void TSAPI MapClientToParent(HWND hwndClient, HWND hwndParent, RECT &rc);
@@ -470,8 +470,8 @@ struct TabControlData HIMAGELIST himlDrag;
TContainerData *pContainer;
- CSrmmWindow *dragDat;
- CSrmmWindow *helperDat; // points to the client data of the active tab
+ CMsgDialog *dragDat;
+ CMsgDialog *helperDat; // points to the client data of the active tab
CImageItem *helperItem, *helperGlowItem; // aero ui, holding the skin image for the tabs
};
@@ -497,12 +497,12 @@ struct ButtonItem { char szModule[256], szSetting[256];
BYTE bValuePush[256], bValueRelease[256];
DWORD type;
- void(*pfnAction)(ButtonItem *item, HWND hwndDlg, CTabBaseDlg *dat, HWND hwndItem);
- void(*pfnCallback)(ButtonItem *item, HWND hwndDlg, CTabBaseDlg *dat, HWND hwndItem);
+ void(*pfnAction)(ButtonItem *item, HWND hwndDlg, CMsgDialog *dat, HWND hwndItem);
+ void(*pfnCallback)(ButtonItem *item, HWND hwndDlg, CMsgDialog *dat, HWND hwndItem);
wchar_t tszLabel[40];
ButtonItem* nextItem;
HANDLE hContact;
- CSrmmWindow *dat;
+ CMsgDialog *dat;
};
typedef struct _tagButtonSet {
diff --git a/plugins/TabSRMM/src/userprefs.cpp b/plugins/TabSRMM/src/userprefs.cpp index d8c947e8f8..71603c5833 100644 --- a/plugins/TabSRMM/src/userprefs.cpp +++ b/plugins/TabSRMM/src/userprefs.cpp @@ -132,14 +132,14 @@ static INT_PTR CALLBACK DlgProcUserPrefs(HWND hwndDlg, UINT msg, WPARAM wParam, break;
case WM_USER + 100:
- CSrmmWindow *dat = nullptr;
+ CMsgDialog *dat = nullptr;
DWORD *pdwActionToTake = (DWORD *)lParam;
unsigned int iOldIEView = 0;
HWND hWnd = Srmm_FindWindow(hContact);
BYTE bOldInfoPanel = M.GetByte(hContact, "infopanel", 0);
if (hWnd) {
- dat = (CSrmmWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (dat)
iOldIEView = GetIEViewMode(dat->m_hContact);
}
@@ -274,7 +274,7 @@ checkboxes[] = { 0, 0
};
-int CTabBaseDlg::LoadLocalFlags()
+int CMsgDialog::LoadLocalFlags()
{
DWORD dwMask = M.GetDword(m_hContact, "mwmask", 0);
DWORD dwLocal = M.GetDword(m_hContact, "mwflags", 0);
@@ -343,9 +343,9 @@ static INT_PTR CALLBACK DlgProcUserPrefsLogOptions(HWND hwndDlg, UINT msg, WPARA HWND hwnd = Srmm_FindWindow(hContact);
DWORD *dwActionToTake = (DWORD *)lParam, dwMask = 0, dwFlags = 0, maskval;
- CSrmmWindow *dat = nullptr;
+ CMsgDialog *dat = nullptr;
if (hwnd)
- dat = (CSrmmWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ dat = (CMsgDialog*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
while (checkboxes[i].uId) {
maskval = checkboxes[i].uFlag;
@@ -469,7 +469,7 @@ static INT_PTR CALLBACK DlgProcUserPrefsFrame(HWND hwndDlg, UINT msg, WPARAM wPa SendMessage(GetTabWindow(hwndTab, i), WM_COMMAND, WM_USER + 100, (LPARAM)&dwActionToTake);
if (hwnd) {
- CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ CMsgDialog *dat = (CMsgDialog*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (dat) {
DWORD dwOldFlags = (dat->m_dwFlags & MWF_LOG_ALL);
dat->SetDialogToType();
diff --git a/plugins/TabSRMM/src/utils.cpp b/plugins/TabSRMM/src/utils.cpp index eb39976b8f..a3f75b02a4 100644 --- a/plugins/TabSRMM/src/utils.cpp +++ b/plugins/TabSRMM/src/utils.cpp @@ -49,7 +49,7 @@ static wchar_t *formatting_strings_end[] = { L"b0 ", L"i0 ", L"u0 ", L"s0 ", // flags: loword = words only for simple * /_ formatting
// hiword = bbcode support (strip bbcodes if 0)
-void CTabBaseDlg::FormatRaw(CMStringW &msg, int flags, bool isSent)
+void CMsgDialog::FormatRaw(CMStringW &msg, int flags, bool isSent)
{
bool clr_was_added = false, was_added;
int beginmark = 0, endmark = 0, tempmark = 0, index;
@@ -221,7 +221,7 @@ static wchar_t* Trunc500(wchar_t *str) return str;
}
-bool CTabBaseDlg::FormatTitleBar(const wchar_t *szFormat, CMStringW &dest)
+bool CMsgDialog::FormatTitleBar(const wchar_t *szFormat, CMStringW &dest)
{
for (const wchar_t *src = szFormat; *src; src++) {
if (*src != '%') {
@@ -388,7 +388,7 @@ wchar_t* Utils::GetPreviewWithEllipsis(wchar_t *szText, size_t iMaxLen) // returns != 0 when one of the installed keyboard layouts belongs to an rtl language
// used to find out whether we need to configure the message input box for bidirectional mode
-int CTabBaseDlg::FindRTLLocale()
+int CMsgDialog::FindRTLLocale()
{
HKL layouts[20];
int i, result = 0;
@@ -639,7 +639,7 @@ void Utils::scaleAvatarHeightLimited(const HBITMAP hBm, double& dNewWidth, doubl // @param dat: _MessageWindowData* pointer to the window data
// @return HICON: the icon handle
-HICON CTabBaseDlg::IconFromAvatar() const
+HICON CMsgDialog::IconFromAvatar() const
{
if (!ServiceExists(MS_AV_GETAVATARBITMAP))
return nullptr;
@@ -741,7 +741,7 @@ void Utils::addMenuItem(const HMENU& m, MENUITEMINFO &mii, HICON hIcon, const wc // return != 0 when the sound effect must be played for the given
// session. Uses container sound settings
-int CTabBaseDlg::MustPlaySound() const
+int CMsgDialog::MustPlaySound() const
{
if (m_pContainer->m_bHidden) // hidden container is treated as closed, so play the sound
return 1;
diff --git a/plugins/TabSRMM/src/version.h b/plugins/TabSRMM/src/version.h index 30740a8842..c77447f4ae 100644 --- a/plugins/TabSRMM/src/version.h +++ b/plugins/TabSRMM/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 3
-#define __MINOR_VERSION 5
+#define __MINOR_VERSION 6
#define __RELEASE_NUM 0
-#define __BUILD_NUM 14
+#define __BUILD_NUM 1
#include <stdver.h>
|