summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/TabSRMM/src/TSButton.cpp2
-rw-r--r--plugins/TabSRMM/src/buttonsbar.cpp14
-rw-r--r--plugins/TabSRMM/src/chat_tools.cpp6
-rw-r--r--plugins/TabSRMM/src/chat_window.cpp1786
-rw-r--r--plugins/TabSRMM/src/contactcache.cpp4
-rw-r--r--plugins/TabSRMM/src/contactcache.h6
-rw-r--r--plugins/TabSRMM/src/container.cpp36
-rw-r--r--plugins/TabSRMM/src/controls.cpp18
-rw-r--r--plugins/TabSRMM/src/eventpopups.cpp4
-rw-r--r--plugins/TabSRMM/src/functions.h8
-rw-r--r--plugins/TabSRMM/src/generic_msghandlers.cpp66
-rw-r--r--plugins/TabSRMM/src/globals.cpp8
-rw-r--r--plugins/TabSRMM/src/globals.h2
-rw-r--r--plugins/TabSRMM/src/hotkeyhandler.cpp4
-rw-r--r--plugins/TabSRMM/src/infopanel.cpp4
-rw-r--r--plugins/TabSRMM/src/infopanel.h8
-rw-r--r--plugins/TabSRMM/src/mim.cpp2
-rw-r--r--plugins/TabSRMM/src/msgdialog.cpp1585
-rw-r--r--plugins/TabSRMM/src/msgdlgother.cpp1986
-rw-r--r--plugins/TabSRMM/src/msgdlgutils.cpp1514
-rw-r--r--plugins/TabSRMM/src/msgdlgutils.h5
-rw-r--r--plugins/TabSRMM/src/msglog.cpp14
-rw-r--r--plugins/TabSRMM/src/msgs.cpp235
-rw-r--r--plugins/TabSRMM/src/msgs.h207
-rw-r--r--plugins/TabSRMM/src/selectcontainer.cpp2
-rw-r--r--plugins/TabSRMM/src/sendqueue.cpp24
-rw-r--r--plugins/TabSRMM/src/sendqueue.h22
-rw-r--r--plugins/TabSRMM/src/sidebar.cpp20
-rw-r--r--plugins/TabSRMM/src/sidebar.h20
-rw-r--r--plugins/TabSRMM/src/stdafx.h2
-rw-r--r--plugins/TabSRMM/src/tabctrl.cpp30
-rw-r--r--plugins/TabSRMM/src/taskbar.cpp6
-rw-r--r--plugins/TabSRMM/src/taskbar.h8
-rw-r--r--plugins/TabSRMM/src/themeio.cpp2
-rw-r--r--plugins/TabSRMM/src/themes.cpp8
-rw-r--r--plugins/TabSRMM/src/themes.h14
-rw-r--r--plugins/TabSRMM/src/userprefs.cpp12
-rw-r--r--plugins/TabSRMM/src/utils.cpp10
-rw-r--r--plugins/TabSRMM/src/version.h4
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)&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;
-}
-
-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)&gtxl, 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)&gtxl, 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)&gtxl, 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)&gtxl, 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>