From d7bca8f09327199912bc82f117797c35c34108d6 Mon Sep 17 00:00:00 2001
From: George Hazan <ghazan@miranda.im>
Date: Wed, 11 Sep 2019 13:25:16 +0300
Subject: Scriver: all useless messages converted into methods

---
 plugins/Scriver/src/globals.cpp     |  20 ++-
 plugins/Scriver/src/input.cpp       |  14 +-
 plugins/Scriver/src/msgdialog.cpp   | 312 +++++++++++++++++-------------------
 plugins/Scriver/src/msglog.cpp      |   2 +-
 plugins/Scriver/src/msgs.cpp        |  18 +--
 plugins/Scriver/src/msgs.h          |  51 +++---
 plugins/Scriver/src/msgtimedout.cpp |   6 +-
 plugins/Scriver/src/sendqueue.cpp   |  43 ++---
 plugins/Scriver/src/sendqueue.h     |  12 +-
 plugins/Scriver/src/tabs.cpp        | 258 +++++++++++++++--------------
 plugins/Scriver/src/tabs.h          |   9 +-
 11 files changed, 368 insertions(+), 377 deletions(-)

(limited to 'plugins')

diff --git a/plugins/Scriver/src/globals.cpp b/plugins/Scriver/src/globals.cpp
index bf8c30f6d4..6a3947ab60 100644
--- a/plugins/Scriver/src/globals.cpp
+++ b/plugins/Scriver/src/globals.cpp
@@ -125,17 +125,15 @@ static int ackevent(WPARAM, LPARAM lParam)
 	if (item == nullptr)
 		return 0;
 
-	HWND hwndSender = item->hwndSender;
+	auto *pSender = item->pDlg;
 	if (pAck->result == ACKRESULT_FAILED) {
 		if (item->hwndErrorDlg != nullptr)
-			item = FindOldestPendingSendQueueItem(hwndSender, hContact);
+			item = FindOldestPendingSendQueueItem(pSender, hContact);
 
 		if (item != nullptr && item->hwndErrorDlg == nullptr) {
-			if (hwndSender != nullptr) {
-				SendMessage(hwndSender, DM_STOPMESSAGESENDING, 0, 0);
-
-				CErrorDlg *pDlg = new CErrorDlg((wchar_t*)pAck->lParam, hwndSender, item);
-				SendMessage(hwndSender, DM_SHOWERRORMESSAGE, 0, (LPARAM)pDlg);
+			if (pSender != nullptr) {
+				pSender->StopMessageSending();
+				(new CErrorDlg((wchar_t *)pAck->lParam, pSender, item))->Create();
 			}
 			else RemoveSendQueueItem(item);
 		}
@@ -164,11 +162,11 @@ static int ackevent(WPARAM, LPARAM lParam)
 		DestroyWindow(item->hwndErrorDlg);
 
 	if (RemoveSendQueueItem(item) && g_plugin.bAutoClose) {
-		if (hwndSender != nullptr)
-			DestroyWindow(hwndSender);
+		if (pSender != nullptr)
+			pSender->Close();
 	}
-	else if (hwndSender != nullptr) {
-		SendMessage(hwndSender, DM_STOPMESSAGESENDING, 0, 0);
+	else if (pSender != nullptr) {
+		pSender->StopMessageSending();
 		Skin_PlaySound("SendMsg");
 	}
 
diff --git a/plugins/Scriver/src/input.cpp b/plugins/Scriver/src/input.cpp
index 11f89db265..dac0407d63 100644
--- a/plugins/Scriver/src/input.cpp
+++ b/plugins/Scriver/src/input.cpp
@@ -161,16 +161,16 @@ int CMsgDialog::InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
 		m_pParent->ActivateNextChild(m_hwnd);
 		return FALSE;
 	case KB_SWITCHSTATUSBAR:
-		SendMessage(m_pParent->m_hwnd, DM_SWITCHSTATUSBAR, 0, 0);
+		m_pParent->ToggleStatusBar();
 		return FALSE;
 	case KB_SWITCHTITLEBAR:
-		SendMessage(m_pParent->m_hwnd, DM_SWITCHTITLEBAR, 0, 0);
+		m_pParent->ToggleTitleBar();
 		return FALSE;
 	case KB_SWITCHINFOBAR:
-		SendMessage(m_pParent->m_hwnd, DM_SWITCHINFOBAR, 0, 0);
+		m_pParent->ToggleInfoBar();
 		return FALSE;
 	case KB_SWITCHTOOLBAR:
-		SendMessage(m_pParent->m_hwnd, DM_SWITCHTOOLBAR, 0, 0);
+		m_pParent->ToggleToolBar();
 		return FALSE;
 	case KB_MINIMIZE:
 		ShowWindow(m_pParent->m_hwnd, SW_MINIMIZE);
@@ -179,7 +179,7 @@ int CMsgDialog::InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
 		SendMessage(m_hwnd, WM_CLOSE, 0, 0);
 		return FALSE;
 	case KB_CLEAR_LOG:
-		SendMessage(m_hwnd, DM_CLEARLOG, 0, 0);
+		ClearLog();
 		return FALSE;
 	case KB_TAB1:
 	case KB_TAB2:
@@ -219,8 +219,8 @@ int CMsgDialog::InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
 		if (wParam == VK_SPACE && isCtrl) // ctrl-space (paste clean text)
 			return FALSE;
 
-		if (wParam == 'R' && isCtrl && isShift) {     // ctrl-shift-r
-			SendMessage(m_hwnd, DM_SWITCHRTL, 0, 0);
+		if (wParam == 'R' && isCtrl && isShift) { // ctrl-shift-r
+			ToggleRtl();
 			return FALSE;
 		}
 
diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp
index 685d892e24..ddddc060d0 100644
--- a/plugins/Scriver/src/msgdialog.cpp
+++ b/plugins/Scriver/src/msgdialog.cpp
@@ -332,7 +332,7 @@ bool CMsgDialog::OnInitDialog()
 		UpdateNickList();
 
 		m_pParent->AddChild(this);
-		m_pParent->PopupWindow(m_hwnd, false);
+		PopupWindow(false);
 	}
 	else {
 		m_nickList.Hide();
@@ -410,20 +410,20 @@ bool CMsgDialog::OnInitDialog()
 		}
 
 		SendMessage(m_hwnd, DM_OPTIONSAPPLIED, 0, 0);
-		m_pParent->PopupWindow(m_hwnd, m_bIncoming);
+		PopupWindow(m_bIncoming);
 
 		if (notifyUnread) {
 			if (GetForegroundWindow() != m_hwndParent || m_pParent->m_hwndActive != m_hwnd) {
 				m_iShowUnread = 1;
-				SendMessage(m_hwnd, DM_UPDATEICON, 0, 0);
+				UpdateIcon();
 				SetTimer(m_hwnd, TIMERID_UNREAD, TIMEOUT_UNREAD, nullptr);
 			}
 			StartFlashing();
 		}
 
-		m_iMessagesInProgress = ReattachSendQueueItems(m_hwnd, m_hContact);
+		m_iMessagesInProgress = ReattachSendQueueItems(this, m_hContact);
 		if (m_iMessagesInProgress > 0)
-			SendMessage(m_hwnd, DM_SHOWMESSAGESENDING, 0, 0);
+			ShowMessageSending();
 	}
 
 	NotifyEvent(MSG_WINDOW_EVT_OPEN);
@@ -451,7 +451,7 @@ void CMsgDialog::OnDestroy()
 		m_hStatusIconOverlay = nullptr;
 	}	
 
-	ReleaseSendQueueItems(m_hwnd);
+	ReleaseSendQueueItems(this);
 	if (g_dat.flags.bSaveDrafts) {
 		ptrA szText(m_message.GetRichTextRtf(true));
 		if (szText)
@@ -552,16 +552,27 @@ void CMsgDialog::onClick_Ok(CCtrlButton *pButton)
 	}
 	else {
 		if (pButton == nullptr)
-			SendMessage(m_hwndParent, DM_SENDMESSAGE, 0, (LPARAM)& msi);
+			m_pParent->MessageSend(msi);
 		else
-			SendMessage(m_hwnd, DM_SENDMESSAGE, 0, (LPARAM)& msi);
+			MessageSend(msi);
 	}
 }
 
 void CMsgDialog::onClick_UserMenu(CCtrlButton *pButton)
 {
-	if (GetKeyState(VK_SHIFT) & 0x8000) // copy user name
-		SendMessage(m_hwnd, DM_USERNAMETOCLIP, 0, 0);
+	if (GetKeyState(VK_SHIFT) & 0x8000) { // copy user name
+		char buf[128];
+		GetContactUniqueId(buf, sizeof(buf));
+		if (!OpenClipboard(m_hwnd) || !mir_strlen(buf))
+			return;
+
+		EmptyClipboard();
+		HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, mir_strlen(buf) + 1);
+		mir_strcpy((LPSTR)GlobalLock(hData), buf);
+		GlobalUnlock(hData);
+		SetClipboardData(CF_TEXT, hData);
+		CloseClipboard();
+	}
 	else {
 		RECT rc;
 		HMENU hMenu = Menu_BuildContactMenu(m_hContact);
@@ -703,11 +714,36 @@ void CMsgDialog::onChange_SplitterY(CSplitter *pSplitter)
 
 /////////////////////////////////////////////////////////////////////////////////////////
 
+void CMsgDialog::ClearLog()
+{
+	if (m_hwndIeview != nullptr) {
+		IEVIEWEVENT evt = { sizeof(evt) };
+		evt.iType = IEE_CLEAR_LOG;
+		evt.dwFlags = (m_bUseRtl) ? IEEF_RTL : 0;
+		evt.hwnd = m_hwndIeview;
+		evt.hContact = m_hContact;
+		evt.pszProto = m_szProto;
+		CallService(MS_IEVIEW_EVENT, 0, (LPARAM)& evt);
+	}
+	else CSuper::ClearLog();
+
+	m_hDbEventFirst = 0;
+	m_lastEventType = -1;
+}
+
 void CMsgDialog::CloseTab()
 {
 	Close();
 }
 
+void CMsgDialog::GetAvatar()
+{
+	PROTO_AVATAR_INFORMATION ai = {};
+	ai.hContact = m_hContact;
+	CallProtoService(m_szProto, PS_GETAVATARINFO, GAIF_FORCE, (LPARAM)&ai);
+	ShowAvatar();
+}
+
 HICON CMsgDialog::GetTabIcon()
 {
 	if (m_bShowTyping)
@@ -772,6 +808,19 @@ void CMsgDialog::LoadSettings()
 	LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, nullptr, &m_clrInputFG);
 }
 
+void CMsgDialog::MessageSend(const MessageSendQueueItem &msi)
+{
+	StartMessageSending();
+
+	MessageSendQueueItem *item = CreateSendQueueItem(this);
+	item->hContact = m_hContact;
+	item->proto = mir_strdup(m_szProto);
+	item->flags = msi.flags;
+	item->sendBufferSize = msi.sendBufferSize;
+	item->sendBuffer = mir_strndup(msi.sendBuffer, msi.sendBufferSize);
+	SendSendQueueItem(item);
+}
+
 // Don't send to protocols who don't support typing
 // Don't send to users who are unchecked in the typing notification options
 // Don't send to protocols that are offline
@@ -833,7 +882,7 @@ void CMsgDialog::Reattach(HWND hwndContainer)
 		SendMessage(m_hwnd, DM_SETPARENT, 0, (LPARAM)hParent);
 		m_pParent->AddChild(this);
 		UpdateTabControl();
-		m_pParent->ActivateChild(m_hwnd);
+		m_pParent->ActivateChild(this);
 		NotifyEvent(MSG_WINDOW_EVT_OPENING);
 		NotifyEvent(MSG_WINDOW_EVT_OPEN);
 		ShowWindow(hParent, SW_SHOWNA);
@@ -920,6 +969,75 @@ void CMsgDialog::ShowAvatar()
 	RedrawWindow(GetDlgItem(m_hwnd, IDC_AVATAR), nullptr, nullptr, RDW_INVALIDATE);
 }
 
+void CMsgDialog::ShowMessageSending()
+{
+	SetTimer(m_hwnd, TIMERID_MSGSEND, 1000, nullptr);
+	if (g_dat.flags.bShowProgress)
+		UpdateStatusBar();
+}
+
+void CMsgDialog::StartMessageSending()
+{
+	m_iMessagesInProgress++;
+	ShowMessageSending();
+}
+
+void CMsgDialog::StopMessageSending()
+{
+	if (m_iMessagesInProgress > 0) {
+		m_iMessagesInProgress--;
+		if (g_dat.flags.bShowProgress)
+			UpdateStatusBar();
+	}
+	if (m_iMessagesInProgress == 0)
+		KillTimer(m_hwnd, TIMERID_MSGSEND);
+}
+
+void CMsgDialog::SwitchTyping()
+{
+	if (IsTypingNotificationSupported()) {
+		BYTE typingNotify = (g_plugin.getByte(m_hContact, SRMSGSET_TYPING, g_plugin.bTypingNew));
+		g_plugin.setByte(m_hContact, SRMSGSET_TYPING, (BYTE)!typingNotify);
+		Srmm_SetIconFlags(m_hContact, SRMM_MODULE, 1, typingNotify ? MBF_DISABLED : 0);
+	}
+}
+
+void CMsgDialog::ToggleRtl()
+{
+	PARAFORMAT2 pf2;
+	memset(&pf2, 0, sizeof(pf2));
+	pf2.cbSize = sizeof(pf2);
+	pf2.dwMask = PFM_RTLPARA;
+	m_bUseRtl = !m_bUseRtl;
+	if (m_bUseRtl) {
+		pf2.wEffects = PFE_RTLPARA;
+		SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR);
+		SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) | WS_EX_LEFTSCROLLBAR);
+	}
+	else {
+		pf2.wEffects = 0;
+		SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR));
+		SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) & ~(WS_EX_LEFTSCROLLBAR));
+	}
+	m_message.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+	SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
+}
+
+void CMsgDialog::UpdateIcon()
+{
+	TitleBarData tbd = {};
+	tbd.iFlags = TBDF_ICON;
+	GetTitlebarIcon(&tbd);
+	m_pParent->UpdateTitleBar(tbd, m_hwnd);
+
+	TabControlData tcd;
+	tcd.iFlags = TCDF_ICON;
+	tcd.hIcon = GetTabIcon();
+	m_pParent->UpdateTabControl(tcd, m_hwnd);
+
+	SendDlgItemMessage(m_hwnd, IDC_USERMENU, BM_SETIMAGE, IMAGE_ICON, (LPARAM)m_hStatusIcon);
+}
+
 void CMsgDialog::UpdateStatusBar()
 {
 	if (m_pParent->m_hwndActive != m_hwnd)
@@ -1005,6 +1123,11 @@ void CMsgDialog::UpdateTabControl()
 	m_pParent->UpdateTabControl(tcd, m_hwnd);
 }
 
+void CMsgDialog::UserIsTyping(int iState)
+{
+	m_nTypeSecs = (iState > 0) ? iState : 0;
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////
 
 static const wchar_t *titleTokenNames[] = { L"%name%", L"%status%", L"%statusmsg%", L"%account%" };
@@ -1285,7 +1408,7 @@ LRESULT CMsgDialog::WndProc_Log(UINT msg, WPARAM wParam, LPARAM lParam)
 			break;
 		
 		case IDM_CLEAR:
-			SendMessage(m_hwnd, DM_CLEARLOG, 0, 0);
+			ClearLog();
 			break;
 		
 		case IDM_SEARCH_GOOGLE:
@@ -1515,7 +1638,6 @@ LRESULT CMsgDialog::WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam)
 
 INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 {
-	PARAFORMAT2 pf2;
 	LPNMHDR pNmhdr;
 
 	switch (msg) {
@@ -1566,38 +1688,10 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		ShowAvatar();
 		break;
 
-	case DM_GETAVATAR:
-		{
-			PROTO_AVATAR_INFORMATION ai = { 0 };
-			ai.hContact = m_hContact;
-			CallProtoService(m_szProto, PS_GETAVATARINFO, GAIF_FORCE, (LPARAM)&ai);
-			ShowAvatar();
-		}
-		break;
-
-	case DM_TYPING:
-		m_nTypeSecs = (int)lParam > 0 ? (int)lParam : 0;
-		break;
-
 	case DM_CHANGEICONS:
 		UpdateStatusBar();
 		SetStatusIcon();
-
-	case DM_UPDATEICON:
-		{
-			TitleBarData tbd = { 0 };
-			tbd.iFlags = TBDF_ICON;
-			GetTitlebarIcon(&tbd);
-			m_pParent->UpdateTitleBar(tbd, m_hwnd);
-
-			TabControlData tcd;
-			tcd.iFlags = TCDF_ICON;
-			tcd.hIcon = GetTabIcon();
-			m_pParent->UpdateTabControl(tcd, m_hwnd);
-
-			SendDlgItemMessage(m_hwnd, IDC_USERMENU, BM_SETIMAGE, IMAGE_ICON, (LPARAM)m_hStatusIcon);
-		}
-		break;
+		__fallthrough;
 
 	case DM_CLISTSETTINGSCHANGED:
 		if (wParam == m_hContact && m_hContact && m_szProto) {
@@ -1611,7 +1705,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 				m_wStatus = cws->value.wVal;
 
 			SetStatusIcon();
-			SendMessage(m_hwnd, DM_UPDATEICON, 0, 0);
+			UpdateIcon();
 			UpdateTitle();
 			UpdateTabControl();
 			ShowAvatar();
@@ -1642,7 +1736,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 			m_hwndIeview = nullptr;
 		}
 
-		SendMessage(m_hwnd, DM_GETAVATAR, 0, 0);
+		GetAvatar();
 		SetDialogToType();
 		{
 			COLORREF colour = g_plugin.getDword(SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR);
@@ -1669,14 +1763,14 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 			m_message.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_message.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
 		}
 
+		PARAFORMAT2 pf2;
 		memset(&pf2, 0, sizeof(pf2));
 		pf2.cbSize = sizeof(pf2);
 		pf2.dwMask = PFM_OFFSET;
 		pf2.dxOffset = (g_dat.flags.bIndentText) ? g_dat.indentSize * 1440 / g_dat.logPixelSX : 0;
-
-		ClearLog();
 		m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
 		m_log.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_log.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~(IMF_AUTOKEYBOARD | IMF_AUTOFONTSIZEADJUST));
+		m_log.SetTextA("");
 
 		SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
 		UpdateTitle();
@@ -1686,57 +1780,6 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		SetupInfobar();
 		break;
 
-	case DM_USERNAMETOCLIP:
-		if (m_hContact) {
-			char buf[128];
-			GetContactUniqueId(buf, sizeof(buf));
-			if (!OpenClipboard(m_hwnd) || !mir_strlen(buf))
-				break;
-
-			EmptyClipboard();
-			HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, mir_strlen(buf) + 1);
-			mir_strcpy((LPSTR)GlobalLock(hData), buf);
-			GlobalUnlock(hData);
-			SetClipboardData(CF_TEXT, hData);
-			CloseClipboard();
-		}
-		break;
-
-	case DM_SWITCHINFOBAR:
-	case DM_SWITCHTOOLBAR:
-		if (isChat())
-			Resize();
-		else
-			SetDialogToType();
-		break;
-
-	case DM_SWITCHTYPING:
-		if (IsTypingNotificationSupported()) {
-			BYTE typingNotify = (g_plugin.getByte(m_hContact, SRMSGSET_TYPING, g_plugin.bTypingNew));
-			g_plugin.setByte(m_hContact, SRMSGSET_TYPING, (BYTE)!typingNotify);
-			Srmm_SetIconFlags(m_hContact, SRMM_MODULE, 1, typingNotify ? MBF_DISABLED : 0);
-		}
-		break;
-
-	case DM_SWITCHRTL:
-		memset(&pf2, 0, sizeof(pf2));
-		pf2.cbSize = sizeof(pf2);
-		pf2.dwMask = PFM_RTLPARA;
-		m_bUseRtl = !m_bUseRtl;
-		if (m_bUseRtl) {
-			pf2.wEffects = PFE_RTLPARA;
-			SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR);
-			SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) | WS_EX_LEFTSCROLLBAR);
-		}
-		else {
-			pf2.wEffects = 0;
-			SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) &~(WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR));
-			SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE) &~(WS_EX_LEFTSCROLLBAR));
-		}
-		m_message.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
-		SendMessage(m_hwnd, DM_REMAKELOG, 0, 0);
-		break;
-
 	case DM_ACTIVATE:
 		if (isChat()) {
 			if (m_si->wState & STATE_TALK) {
@@ -1791,7 +1834,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 			if (m_iShowUnread) {
 				m_iShowUnread = 0;
 				KillTimer(m_hwnd, TIMERID_UNREAD);
-				SendMessage(m_hwnd, DM_UPDATEICON, 0, 0);
+				UpdateIcon();
 			}
 		}
 		break;
@@ -1828,7 +1871,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		break;
 
 	case WM_SETFOCUS:
-		m_pParent->ActivateChild(m_hwnd);
+		m_pParent->ActivateChild(this);
 		g_dat.hFocusWnd = m_hwnd;
 		PostMessage(m_hwnd, DM_SETFOCUS, 0, 0);
 		return TRUE;
@@ -1878,9 +1921,9 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 					else
 						Skin_PlaySound("RecvMsgInactive");
 					if (g_dat.flags2.bSwitchToActive && (IsIconic(m_hwndParent) || GetActiveWindow() != m_hwndParent) && IsWindowVisible(m_hwndParent))
-						m_pParent->ActivateChild(m_hwnd);
+						m_pParent->ActivateChild(this);
 					if (IsAutoPopup(m_hContact))
-						m_pParent->PopupWindow(m_hwnd, true);
+						PopupWindow(true);
 				}
 
 				if (hDbEvent != m_hDbEventFirst && db_event_next(m_hContact, hDbEvent) == 0)
@@ -1891,7 +1934,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 				if (!(dbei.flags & DBEF_SENT) && !DbEventIsCustomForMsgWindow(&dbei)) {
 					if (!bIsActive) {
 						m_iShowUnread = 1;
-						SendMessage(m_hwnd, DM_UPDATEICON, 0, 0);
+						UpdateIcon();
 						SetTimer(m_hwnd, TIMERID_UNREAD, TIMEOUT_UNREAD, nullptr);
 					}
 					StartFlashing();
@@ -1900,25 +1943,9 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		}
 		break;
 
-	case DM_CLEARLOG:
-		if (m_hwndIeview != nullptr) {
-			IEVIEWEVENT evt = { sizeof(evt) };
-			evt.iType = IEE_CLEAR_LOG;
-			evt.dwFlags = (m_bUseRtl) ? IEEF_RTL : 0;
-			evt.hwnd = m_hwndIeview;
-			evt.hContact = m_hContact;
-			evt.pszProto = m_szProto;
-			CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&evt);
-		}
-
-		ClearLog();
-		m_hDbEventFirst = 0;
-		m_lastEventType = -1;
-		break;
-
 	case WM_TIMER:
 		if (wParam == TIMERID_MSGSEND)
-			ReportSendQueueTimeouts(m_hwnd);
+			ReportSendQueueTimeouts(this);
 		else if (wParam == TIMERID_TYPE) {
 			if (m_nTypeMode == PROTOTYPE_SELFTYPING_ON && GetTickCount() - m_nLastTyping > TIMEOUT_TYPEOFF)
 				NotifyTyping(PROTOTYPE_SELFTYPING_OFF);
@@ -1929,14 +1956,14 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 				else {
 					m_bShowTyping = false;
 					UpdateStatusBar();
-					SendMessage(m_hwnd, DM_UPDATEICON, 0, 0);
+					UpdateIcon();
 				}
 			}
 			else {
 				if (m_nTypeSecs) {
 					m_bShowTyping = true;
 					UpdateStatusBar();
-					SendMessage(m_hwnd, DM_UPDATEICON, 0, 0);
+					UpdateIcon();
 				}
 			}
 		}
@@ -1951,47 +1978,6 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		}
 		break;
 
-	case DM_SENDMESSAGE:
-		if (lParam) {
-			MessageSendQueueItem *msi = (MessageSendQueueItem *)lParam;
-			SendMessage(m_hwnd, DM_STARTMESSAGESENDING, 0, 0);
-
-			MessageSendQueueItem *item = CreateSendQueueItem(m_hwnd);
-			item->hContact = m_hContact;
-			item->proto = mir_strdup(m_szProto);
-			item->flags = msi->flags;
-			item->sendBufferSize = msi->sendBufferSize;
-			item->sendBuffer = mir_strndup(msi->sendBuffer, msi->sendBufferSize);
-			SendSendQueueItem(item);
-		}
-		break;
-
-	case DM_STARTMESSAGESENDING:
-		m_iMessagesInProgress++;
-	case DM_SHOWMESSAGESENDING:
-		SetTimer(m_hwnd, TIMERID_MSGSEND, 1000, nullptr);
-		if (g_dat.flags.bShowProgress)
-			UpdateStatusBar();
-		break;
-
-	case DM_STOPMESSAGESENDING:
-		if (m_iMessagesInProgress > 0) {
-			m_iMessagesInProgress--;
-			if (g_dat.flags.bShowProgress)
-				UpdateStatusBar();
-		}
-		if (m_iMessagesInProgress == 0)
-			KillTimer(m_hwnd, TIMERID_MSGSEND);
-		break;
-
-	case DM_SHOWERRORMESSAGE:
-		if (lParam) {
-			SendMessage(m_hwnd, DM_STOPMESSAGESENDING, 0, 0);
-			CErrorDlg *pDlg = (CErrorDlg*)lParam;
-			pDlg->Create();
-		}
-		break;
-
 	case DM_ERRORDECIDED:
 		{
 			MessageSendQueueItem *item = (MessageSendQueueItem *)lParam;
@@ -2002,7 +1988,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 				SetFocus(m_message.GetHwnd());
 				break;
 			case MSGERROR_RETRY:
-				SendMessage(m_hwnd, DM_STARTMESSAGESENDING, 0, 0);
+				StartMessageSending();
 				SendSendQueueItem(item);
 				break;
 			}
diff --git a/plugins/Scriver/src/msglog.cpp b/plugins/Scriver/src/msglog.cpp
index 3d9c18238d..f249f03755 100644
--- a/plugins/Scriver/src/msglog.cpp
+++ b/plugins/Scriver/src/msglog.cpp
@@ -698,7 +698,7 @@ void CMsgDialog::StreamInEvents(MEVENT hDbEventFirst, int count, int bAppend)
 	}
 	else {
 		m_log.SendMsg(WM_SETREDRAW, FALSE, 0);
-		ClearLog();
+		m_log.SetTextA("");
 		sel.cpMin = 0;
 		sel.cpMax = m_log.GetRichTextLength();
 		m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel);
diff --git a/plugins/Scriver/src/msgs.cpp b/plugins/Scriver/src/msgs.cpp
index b0d45b1330..c2124f33f4 100644
--- a/plugins/Scriver/src/msgs.cpp
+++ b/plugins/Scriver/src/msgs.cpp
@@ -187,9 +187,9 @@ static int TypingMessage(WPARAM hContact, LPARAM lParam)
 
 	Skin_PlaySound((lParam) ? "TNStart" : "TNStop");
 
-	HWND hwnd = Srmm_FindWindow(hContact);
-	if (hwnd)
-		SendMessage(hwnd, DM_TYPING, 0, lParam);
+	auto *pDlg = Srmm_FindDialog(hContact);
+	if (pDlg != nullptr)
+		pDlg->UserIsTyping(lParam);
 	else if (lParam && g_dat.flags2.bShowTypingTray) {
 		wchar_t szTip[256];
 		mir_snwprintf(szTip, TranslateT("%s is typing a message"), Clist_GetContactDisplayName(hContact));
@@ -339,9 +339,9 @@ int StatusIconPressed(WPARAM wParam, LPARAM lParam)
 	if (mir_strcmp(SRMM_MODULE, sicd->szModule))
 		return 0;
 
-	HWND hwnd = Srmm_FindWindow(wParam);
-	if (hwnd != nullptr)
-		SendMessage(hwnd, DM_SWITCHTYPING, 0, 0);
+	auto *pDlg = Srmm_FindDialog(wParam);
+	if (pDlg != nullptr)
+		pDlg->SwitchTyping();
 	return 0;
 }
 
@@ -471,9 +471,9 @@ static int ModuleLoad(WPARAM, LPARAM)
 static int MetaContactChanged(WPARAM hMeta, LPARAM)
 {
 	if (hMeta) {
-		HWND hwnd = Srmm_FindWindow(hMeta);
-		if (hwnd != nullptr)
-			SendMessage(hwnd, DM_GETAVATAR, 0, 0);
+		auto *pDlg = Srmm_FindDialog(hMeta);
+		if (pDlg != nullptr)
+			pDlg->GetAvatar();
 	}
 	return 0;
 }
diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h
index 5d43bc7ed6..f9c893b528 100644
--- a/plugins/Scriver/src/msgs.h
+++ b/plugins/Scriver/src/msgs.h
@@ -60,19 +60,24 @@ class CMsgDialog : public CSrmmBaseDialog
 {
 	typedef CSrmmBaseDialog CSuper;
 
+	friend struct ParentWindowData;
 	friend INT_PTR CALLBACK InfobarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
 	bool   CheckSend(void);
+	void   ClearLog(void);
 	void   GetContactUniqueId(char *buf, int maxlen);
 	HICON  GetTabIcon(void);
 	void   GetTitlebarIcon(struct TitleBarData *tbd);
 	void   Init(void);
 	int    InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 	void   MessageDialogResize(int w, int h);
+	void   MessageSend(const MessageSendQueueItem &msg);
 	void   ShowAvatar(void);
 	void   SetDialogToType(void);
 	void   SetStatusIcon(void);
 	void   StreamInEvents(MEVENT hDbEventFirst, int count, int fAppend);
+	void   ToggleRtl();
+	void   UpdateIcon(void);
 	void   UpdateReadChars(void);
 
 	bool   IsTypingNotificationEnabled(void);
@@ -156,11 +161,18 @@ public:
 	void UpdateNickList() override;
 	void UpdateOptions() override;
 	void UpdateStatusBar() override;
-	void UpdateTabControl();
 	void UpdateTitle() override;
 
 	void FixTabIcons();
-
+	void GetAvatar();
+	void SwitchTyping(void);
+	void UpdateTabControl(void);
+	void UserIsTyping(int iState);
+
+	void StartMessageSending(void);
+	void StopMessageSending(void);
+	void ShowMessageSending(void);
+	
 	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;
@@ -169,8 +181,8 @@ public:
 	{	return GetActiveWindow() == m_hwndParent && GetForegroundWindow() == m_hwndParent && m_pParent->m_hwndActive == m_hwnd;
 	}
 
-	__forceinline void PopupWindow(bool bIncoming = false) const
-	{	m_pParent->PopupWindow(m_hwnd, bIncoming);
+	__forceinline void PopupWindow(bool bIncoming = false)
+	{	m_pParent->PopupWindow(this, bIncoming);
 	}
 
 	__forceinline void StartFlashing() const
@@ -186,37 +198,16 @@ public:
 };
 
 #define HM_DBEVENTADDED        (WM_USER+10)
-#define DM_REMAKELOG           (WM_USER+11)
+#define HM_ACKEVENT            (WM_USER+11)
+
+#define DM_REMAKELOG           (WM_USER+12)
 #define DM_CASCADENEWWINDOW    (WM_USER+13)
 #define DM_OPTIONSAPPLIED      (WM_USER+14)
-#define DM_APPENDTOLOG         (WM_USER+17)
 #define DM_ERRORDECIDED        (WM_USER+18)
-#define DM_TYPING              (WM_USER+20)
-#define DM_UPDATELASTMESSAGE   (WM_USER+22)
-#define DM_USERNAMETOCLIP      (WM_USER+23)
 #define DM_CHANGEICONS         (WM_USER+24)
-#define DM_UPDATEICON          (WM_USER+25)
-#define DM_GETAVATAR           (WM_USER+27)
-#define HM_ACKEVENT            (WM_USER+29)
-
-#define DM_SENDMESSAGE         (WM_USER+30)
-#define DM_STARTMESSAGESENDING (WM_USER+31)
-#define DM_SHOWMESSAGESENDING  (WM_USER+32)
-#define DM_STOPMESSAGESENDING  (WM_USER+33)
-#define DM_SHOWERRORMESSAGE    (WM_USER+34)
-
-#define DM_CLEARLOG            (WM_USER+46)
-#define DM_SWITCHSTATUSBAR     (WM_USER+47)
-#define DM_SWITCHTOOLBAR       (WM_USER+48)
-#define DM_SWITCHTITLEBAR      (WM_USER+49)
-#define DM_SWITCHINFOBAR       (WM_USER+50)
-#define DM_SWITCHRTL           (WM_USER+51)
-#define DM_SWITCHTYPING        (WM_USER+53)
-#define DM_MESSAGESENDING      (WM_USER+54)
+
 #define DM_STATUSICONCHANGE    (WM_USER+56)
 
-#define DM_MYAVATARCHANGED     (WM_USER+62)
-#define DM_PROTOAVATARCHANGED  (WM_USER+63)
 #define DM_AVATARCHANGED       (WM_USER+64)
 
 #define EM_SUBCLASSED          (WM_USER+0x101)
@@ -237,7 +228,7 @@ protected:
 	bool OnInitDialog() override;
 
 public:
-	CErrorDlg(const wchar_t *pwszDescr, HWND, MessageSendQueueItem*);
+	CErrorDlg(const wchar_t *pwszDescr, CMsgDialog *pDlg, MessageSendQueueItem*);
 
 	void onOk(CCtrlButton*);
 	void onCancel(CCtrlButton*);
diff --git a/plugins/Scriver/src/msgtimedout.cpp b/plugins/Scriver/src/msgtimedout.cpp
index 02a6778fee..6f8e1adae8 100644
--- a/plugins/Scriver/src/msgtimedout.cpp
+++ b/plugins/Scriver/src/msgtimedout.cpp
@@ -23,8 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "stdafx.h"
 
-CErrorDlg::CErrorDlg(const wchar_t *pwszDescr, HWND hWnd, MessageSendQueueItem *pItem)
-	: CDlgBase(g_plugin, IDD_MSGSENDERROR),
+CErrorDlg::CErrorDlg(const wchar_t *pwszDescr, CMsgDialog *pDlg, MessageSendQueueItem *pItem) :
+	CDlgBase(g_plugin, IDD_MSGSENDERROR),
 	m_wszText(mir_utf8decodeW(pItem->sendBuffer)),
 	m_wszDescr(pwszDescr != nullptr ? pwszDescr : TranslateT("An unknown error has occurred.")),
 	m_queueItem(pItem),
@@ -32,7 +32,7 @@ CErrorDlg::CErrorDlg(const wchar_t *pwszDescr, HWND hWnd, MessageSendQueueItem *
 	m_btnOk(this, IDOK),
 	m_btnCancel(this, IDCANCEL)
 {
-	SetParent(hWnd);
+	SetParent(pDlg->GetHwnd());
 
 	const wchar_t *pwszName = Clist_GetContactDisplayName(pItem->hContact);
 	if (pwszName)
diff --git a/plugins/Scriver/src/sendqueue.cpp b/plugins/Scriver/src/sendqueue.cpp
index 1bc40938fc..eb27717760 100644
--- a/plugins/Scriver/src/sendqueue.cpp
+++ b/plugins/Scriver/src/sendqueue.cpp
@@ -26,21 +26,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 static OBJLIST<MessageSendQueueItem> arQueue(1, PtrKeySortT);
 static mir_cs queueMutex;
 
-MessageSendQueueItem* CreateSendQueueItem(HWND hwndSender)
+MessageSendQueueItem* CreateSendQueueItem(CMsgDialog *pDlg)
 {
 	MessageSendQueueItem *item = new MessageSendQueueItem();
-	item->hwndSender = hwndSender;
+	item->pDlg = pDlg;
 
 	mir_cslock lck(queueMutex);
 	arQueue.insert(item);
 	return item;
 }
 
-MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, MCONTACT hContact)
+MessageSendQueueItem* FindOldestPendingSendQueueItem(CMsgDialog *pDlg, MCONTACT hContact)
 {
 	mir_cslock lck(queueMutex);
 	for (auto &it : arQueue)
-		if (it->hwndSender == hwndSender && it->hContact == hContact && it->hwndErrorDlg == nullptr)
+		if (it->pDlg == pDlg && it->hContact == hContact && it->hwndErrorDlg == nullptr)
 			return it;
 
 	return nullptr;
@@ -58,20 +58,20 @@ MessageSendQueueItem* FindSendQueueItem(MCONTACT hContact, HANDLE hSendId)
 
 bool RemoveSendQueueItem(MessageSendQueueItem *item)
 {
-	HWND hwndSender = item->hwndSender;
+	auto *pDlg = item->pDlg;
 	{
 		mir_cslock lock(queueMutex);
 		arQueue.remove(item);
 	}
 
 	for (auto &it : arQueue)
-		if (it->hwndSender == hwndSender)
+		if (it->pDlg == pDlg)
 			return false;
 
 	return true;
 }
 
-void ReportSendQueueTimeouts(HWND hwndSender)
+void ReportSendQueueTimeouts(CMsgDialog *pDlg)
 {
 	int timeout = g_plugin.iMsgTimeout * 1000;
 
@@ -82,41 +82,42 @@ void ReportSendQueueTimeouts(HWND hwndSender)
 			continue;
 			
 		it->timeout += 1000;
-		if (it->timeout < timeout || it->hwndSender != hwndSender || it->hwndErrorDlg != nullptr)
+		if (it->timeout < timeout || it->pDlg != pDlg || it->hwndErrorDlg != nullptr)
 			continue;
 
-		if (hwndSender != nullptr) {
-			CErrorDlg *pDlg = new CErrorDlg(TranslateT("The message send timed out."), hwndSender, it);
-			PostMessage(hwndSender, DM_SHOWERRORMESSAGE, 0, (LPARAM)pDlg);
+		if (pDlg != nullptr) {
+			pDlg->StopMessageSending();
+			(new CErrorDlg(TranslateT("The message send timed out."), pDlg, it))->Create();
 		}
 		else arQueue.remove(arQueue.indexOf(&it));
 	}
 }
 
-void ReleaseSendQueueItems(HWND hwndSender)
+void ReleaseSendQueueItems(CMsgDialog *pDlg)
 {
 	mir_cslock lock(queueMutex);
 
 	for (auto &it : arQueue) {
-		if (it->hwndSender == hwndSender) {
-			it->hwndSender = nullptr;
+		if (it->pDlg != pDlg)
+			continue;
 
-			if (it->hwndErrorDlg != nullptr)
-				DestroyWindow(it->hwndErrorDlg);
-			it->hwndErrorDlg = nullptr;
-		}
+		it->pDlg = nullptr;
+
+		if (it->hwndErrorDlg != nullptr)
+			DestroyWindow(it->hwndErrorDlg);
+		it->hwndErrorDlg = nullptr;
 	}
 }
 
-int ReattachSendQueueItems(HWND hwndSender, MCONTACT hContact)
+int ReattachSendQueueItems(CMsgDialog *pDlg, MCONTACT hContact)
 {
 	int count = 0;
 
 	mir_cslock lock(queueMutex);
 
 	for (auto &it : arQueue) {
-		if (it->hContact == hContact && it->hwndSender == nullptr) {
-			it->hwndSender = hwndSender;
+		if (it->hContact == hContact && it->pDlg == nullptr) {
+			it->pDlg = pDlg;
 			it->timeout = 0;
 			count++;
 		}
diff --git a/plugins/Scriver/src/sendqueue.h b/plugins/Scriver/src/sendqueue.h
index 092d43a602..ea4e7599a4 100644
--- a/plugins/Scriver/src/sendqueue.h
+++ b/plugins/Scriver/src/sendqueue.h
@@ -32,7 +32,7 @@ struct MessageSendQueueItem : public MZeroedObject
 		mir_free(sendBuffer);
 	}
 
-	HWND	hwndSender;
+	CMsgDialog *pDlg;
 	MCONTACT hContact;
 	char  *proto;
 	int    hSendId;
@@ -44,14 +44,14 @@ struct MessageSendQueueItem : public MZeroedObject
 	HWND   hwndErrorDlg;
 };
 
-MessageSendQueueItem* CreateSendQueueItem(HWND hwndSender);
-MessageSendQueueItem* FindOldestPendingSendQueueItem(HWND hwndSender, MCONTACT hContact);
+MessageSendQueueItem* CreateSendQueueItem(CMsgDialog *pDlg);
+MessageSendQueueItem* FindOldestPendingSendQueueItem(CMsgDialog *pDlg, MCONTACT hContact);
 MessageSendQueueItem* FindSendQueueItem(MCONTACT hContact, HANDLE hSendId);
 
 bool RemoveSendQueueItem(MessageSendQueueItem* item);
-void ReportSendQueueTimeouts(HWND hwndSender);
-void ReleaseSendQueueItems(HWND hwndSender);
-int  ReattachSendQueueItems(HWND hwndSender, MCONTACT hContact);
+void ReportSendQueueTimeouts(CMsgDialog *pDlg);
+void ReleaseSendQueueItems(CMsgDialog *pDlg);
+int  ReattachSendQueueItems(CMsgDialog *pDlg, MCONTACT hContact);
 void RemoveAllSendQueueItems();
 void SendSendQueueItem(MessageSendQueueItem* item);
 
diff --git a/plugins/Scriver/src/tabs.cpp b/plugins/Scriver/src/tabs.cpp
index dbeabcd992..f2ea48ab19 100644
--- a/plugins/Scriver/src/tabs.cpp
+++ b/plugins/Scriver/src/tabs.cpp
@@ -174,24 +174,23 @@ static void ReleaseIcon(int index)
 			g_dat.tabIconListUsage[i].used = 0;
 }
 
-void ParentWindowData::ActivateChild(HWND child)
+void ParentWindowData::ActivateChild(CMsgDialog *pDlg)
 {
+	if (pDlg == nullptr)
+		return;
+
 	RECT rcChild;
 	GetChildWindowRect(&rcChild);
-	SetWindowPos(child, HWND_TOP, rcChild.left, rcChild.top, rcChild.right - rcChild.left, rcChild.bottom - rcChild.top, 0);
+	SetWindowPos(pDlg->GetHwnd(), HWND_TOP, rcChild.left, rcChild.top, rcChild.right - rcChild.left, rcChild.bottom - rcChild.top, 0);
 
-	int i = GetTabFromHWND(child);
+	int i = GetTabFromHWND(pDlg->GetHwnd());
 	if (i == -1)
 		return;
 
-	CMsgDialog *pDlg = GetChildFromTab(m_hwndTabs, i);
-	if (pDlg == nullptr)
-		return;
-
 	m_hContact = pDlg->m_hContact;
-	if (child != m_hwndActive) {
+	if (pDlg->GetHwnd() != m_hwndActive) {
 		HWND hwndPrev = m_hwndActive;
-		m_hwndActive = child;
+		m_hwndActive = pDlg->GetHwnd();
 		SetupStatusBar(this);
 		pDlg->UpdateStatusBar();
 		pDlg->UpdateTitle();
@@ -207,50 +206,55 @@ void ParentWindowData::ActivateChild(HWND child)
 	SendMessage(m_hwndActive, DM_ACTIVATE, WA_ACTIVE, 0);
 }
 
-void ParentWindowData::AddChild(CMsgDialog *pDlg)
+void ParentWindowData::ActivateChildByIndex(int index)
 {
-	m_iChildrenCount++;
+	int l = TabCtrl_GetItemCount(m_hwndTabs);
+	if (index < l) {
+		CMsgDialog *pDlg = GetChildFromTab(m_hwndTabs, index);
+		if (pDlg != nullptr)
+			ActivateChild(pDlg);
+	}
+	SetFocus(m_hwndActive);
+}
+
+void ParentWindowData::ActivateNextChild(HWND child)
+{
+	int i = GetTabFromHWND(child);
+	int l = TabCtrl_GetItemCount(m_hwndTabs);
+	i = (i + 1) % l;
+	ActivateChild(GetChildFromTab(m_hwndTabs, i));
+	SetFocus(m_hwndActive);
+}
 
+void ParentWindowData::ActivatePrevChild(HWND child)
+{
+	int i = GetTabFromHWND(child);
+	int l = TabCtrl_GetItemCount(m_hwndTabs);
+	i = (i + l - 1) % l;
+	ActivateChild(GetChildFromTab(m_hwndTabs, i));
+	SetFocus(m_hwndActive);
+}
+
+void ParentWindowData::AddChild(CMsgDialog *pDlg)
+{
 	TCITEM tci;
 	tci.mask = TCIF_PARAM | TCIF_IMAGE | TCIF_TEXT;
 	tci.lParam = (LPARAM)pDlg;
 	tci.iImage = -1;
 	tci.pszText = L"";
-	TabCtrl_InsertItem(m_hwndTabs, m_iChildrenCount - 1, &tci);
+	TabCtrl_InsertItem(m_hwndTabs, m_iChildrenCount, &tci);
+
+	m_iChildrenCount++;
+
 	SetWindowPos(pDlg->GetHwnd(), HWND_TOP, childRect.left, childRect.top, childRect.right - childRect.left, childRect.bottom - childRect.top, SWP_HIDEWINDOW);
 	SendMessage(m_hwnd, WM_SIZE, 0, 0);
 
 	EnableThemeDialogTexture(pDlg->GetHwnd(), ETDT_ENABLETAB);
 }
 
-void ParentWindowData::RemoveChild(HWND child)
-{
-	int tab = GetTabFromHWND(child);
-	if (tab >= 0) {
-		TCITEM tci;
-		tci.mask = TCIF_PARAM | TCIF_IMAGE;
-		TabCtrl_GetItem(m_hwndTabs, tab, &tci);
-		TabCtrl_DeleteItem(m_hwndTabs, tab);
-		m_iChildrenCount--;
-		if (child == m_hwndActive) {
-			if (tab == TabCtrl_GetItemCount(m_hwndTabs)) tab--;
-			if (tab >= 0)
-				ActivateChild(GetChildFromTab(m_hwndTabs, tab)->GetHwnd());
-			else
-				m_hwndActive = nullptr;
-		}
-		ReleaseIcon(tci.iImage);
-	}
-
-	if (m_iChildrenCount != 0)
-		SetFocus(m_hwndActive);
-	else
-		PostMessage(m_hwnd, WM_CLOSE, 0, 0);
-}
-
 void ParentWindowData::CloseOtherChilden(CMsgDialog *pChildDlg)
 {
-	ActivateChild(pChildDlg->GetHwnd());
+	ActivateChild(pChildDlg);
 	
 	for (int i = m_iChildrenCount - 1; i >= 0; i--) {
 		CMsgDialog *pDlg = GetChildFromTab(m_hwndTabs, i);
@@ -258,39 +262,19 @@ void ParentWindowData::CloseOtherChilden(CMsgDialog *pChildDlg)
 			pDlg->Close();
 	}
 	
-	ActivateChild(pChildDlg->GetHwnd());
+	ActivateChild(pChildDlg);
 }
 
-void ParentWindowData::ActivateNextChild(HWND child)
+void ParentWindowData::MessageSend(const MessageSendQueueItem &msg)
 {
-	int i = GetTabFromHWND(child);
-	int l = TabCtrl_GetItemCount(m_hwndTabs);
-	i = (i + 1) % l;
-	ActivateChild(GetChildFromTab(m_hwndTabs, i)->GetHwnd());
-	SetFocus(m_hwndActive);
-}
-
-void ParentWindowData::ActivatePrevChild(HWND child)
-{
-	int i = GetTabFromHWND(child);
-	int l = TabCtrl_GetItemCount(m_hwndTabs);
-	i = (i + l - 1) % l;
-	ActivateChild(GetChildFromTab(m_hwndTabs, i)->GetHwnd());
-	SetFocus(m_hwndActive);
-}
-
-void ParentWindowData::ActivateChildByIndex(int index)
-{
-	int l = TabCtrl_GetItemCount(m_hwndTabs);
-	if (index < l) {
-		CMsgDialog *pDlg = GetChildFromTab(m_hwndTabs, index);
+	for (int i = 0; i < m_iChildrenCount; i++) {
+		CMsgDialog *pDlg = GetChildFromTab(m_hwndTabs, i);
 		if (pDlg != nullptr)
-			ActivateChild(pDlg->GetHwnd());
+			pDlg->MessageSend(msg);
 	}
-	SetFocus(m_hwndActive);
 }
 
-void ParentWindowData::PopupWindow(HWND hwnd, bool bIncoming)
+void ParentWindowData::PopupWindow(CMsgDialog *pDlg, bool bIncoming)
 {
 	EnableWindow(m_hwnd, TRUE);
 	if (bIncoming) { /* incoming message */
@@ -299,13 +283,13 @@ void ParentWindowData::PopupWindow(HWND hwnd, bool bIncoming)
 				ShowWindow(m_hwnd, SW_SHOWMINNOACTIVE);
 
 			if (m_iChildrenCount == 1 || (g_dat.flags2.bSwitchToActive && (IsIconic(m_hwnd) || GetForegroundWindow() != m_hwnd)))
-				ActivateChild(hwnd);
+				ActivateChild(pDlg);
 		}
 		else {
 			ShowWindow(m_hwnd, IsIconic(m_hwnd) ? SW_SHOWNORMAL : SW_SHOWNA);
 
 			if (m_iChildrenCount == 1 || (g_dat.flags2.bSwitchToActive && (IsIconic(m_hwnd) || GetForegroundWindow() != m_hwnd)))
-				ActivateChild(hwnd);
+				ActivateChild(pDlg);
 
 			SetWindowPos(m_hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
 		}
@@ -313,10 +297,35 @@ void ParentWindowData::PopupWindow(HWND hwnd, bool bIncoming)
 	else { /* outgoing message */
 		ShowWindow(m_hwnd, IsIconic(m_hwnd) ? SW_SHOWNORMAL : SW_SHOW);
 		SetForegroundWindow(m_hwnd);
-		SetFocus(hwnd);
+		SetFocus(pDlg->GetHwnd());
 	}
 }
 
+void ParentWindowData::RemoveChild(HWND child)
+{
+	int tab = GetTabFromHWND(child);
+	if (tab >= 0) {
+		TCITEM tci;
+		tci.mask = TCIF_PARAM | TCIF_IMAGE;
+		TabCtrl_GetItem(m_hwndTabs, tab, &tci);
+		TabCtrl_DeleteItem(m_hwndTabs, tab);
+		m_iChildrenCount--;
+		if (child == m_hwndActive) {
+			if (tab == TabCtrl_GetItemCount(m_hwndTabs)) tab--;
+			if (tab >= 0)
+				ActivateChild(GetChildFromTab(m_hwndTabs, tab));
+			else
+				m_hwndActive = nullptr;
+		}
+		ReleaseIcon(tci.iImage);
+	}
+
+	if (m_iChildrenCount != 0)
+		SetFocus(m_hwndActive);
+	else
+		PostMessage(m_hwnd, WM_CLOSE, 0, 0);
+}
+
 void ParentWindowData::SetContainerWindowStyle()
 {
 	ShowWindow(m_hwndStatus, (flags2.bShowStatusBar) ? SW_SHOW : SW_HIDE);
@@ -359,6 +368,54 @@ void ParentWindowData::StartFlashing()
 	}
 }
 
+void ParentWindowData::ToggleInfoBar()
+{
+	flags2.bShowInfoBar = !flags2.bShowInfoBar;
+
+	for (int i = 0; i < m_iChildrenCount; i++) {
+		CMsgDialog *pDlg = GetChildFromTab(m_hwndTabs, i);
+		if (pDlg)
+			pDlg->SetDialogToType();
+	}
+	SendMessage(m_hwnd, WM_SIZE, 0, 0);
+}
+
+void ParentWindowData::ToggleStatusBar()
+{
+	flags2.bShowStatusBar = !flags2.bShowStatusBar;
+	ShowWindow(m_hwndStatus, (flags2.bShowStatusBar) ? SW_SHOW : SW_HIDE);
+	SendMessage(m_hwnd, WM_SIZE, 0, 0);
+}
+
+void ParentWindowData::ToggleTitleBar()
+{
+	flags2.bShowTitleBar = !flags2.bShowTitleBar;
+
+	DWORD ws = GetWindowLongPtr(m_hwnd, GWL_STYLE) & ~(WS_CAPTION);
+	if (flags2.bShowTitleBar)
+		ws |= WS_CAPTION;
+	SetWindowLongPtr(m_hwnd, GWL_STYLE, ws);
+
+	RECT rc;
+	GetWindowRect(m_hwnd, &rc);
+	SetWindowPos(m_hwnd, nullptr, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
+		SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
+	RedrawWindow(m_hwnd, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+}
+
+void ParentWindowData::ToggleToolBar()
+{
+	flags2.bShowToolBar = !flags2.bShowToolBar;
+
+	for (int i = 0; i < m_iChildrenCount; i++) {
+		CMsgDialog *pDlg = GetChildFromTab(m_hwndTabs, i);
+		if (pDlg)
+			pDlg->SetDialogToType();
+	}
+
+	SendMessage(m_hwnd, WM_SIZE, 0, 0);
+}
+
 void ParentWindowData::UpdateStatusBar(const StatusBarData &sbd, HWND hwnd)
 {
 	if (m_hwndActive == hwnd) {
@@ -690,8 +747,6 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 	if (!dat && msg != WM_INITDIALOG)
 		return FALSE;
 
-	DWORD ws;
-
 	switch (msg) {
 	case WM_INITDIALOG:
 		{
@@ -875,8 +930,8 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 						int iSel = TabCtrl_GetCurSel(dat->m_hwndTabs);
 						tci.mask = TCIF_PARAM;
 						if (TabCtrl_GetItem(dat->m_hwndTabs, iSel, &tci)) {
-							CMsgDialog * pDlg = (CMsgDialog *)tci.lParam;
-							dat->ActivateChild(pDlg->GetHwnd());
+							CMsgDialog *pDlg = (CMsgDialog *)tci.lParam;
+							dat->ActivateChild(pDlg);
 							SetFocus(dat->m_hwndActive);
 						}
 					}
@@ -973,7 +1028,7 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 
 	case WM_ACTIVATE:
 		if (LOWORD(wParam) == WA_INACTIVE) {
-			ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED;
+			DWORD ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED;
 			ws |= dat->flags2.bUseTransparency ? WS_EX_LAYERED : 0;
 			SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, ws);
 			if (dat->flags2.bUseTransparency)
@@ -981,7 +1036,7 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 			break;
 		}
 		if (dat->m_hwndActive != nullptr) {
-			dat->ActivateChild(dat->m_hwndActive);
+			dat->ActivateChild(dat->GetChildFromHWND(dat->m_hwndActive));
 			g_dat.hFocusWnd = dat->m_hwndActive;
 			PostMessage(dat->m_hwndActive, DM_SETFOCUS, 0, msg);
 		}
@@ -989,9 +1044,12 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 			FlashWindow(hwndDlg, FALSE);
 			dat->nFlash = 0;
 		}
-		ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED;
-		ws |= dat->flags2.bUseTransparency ? WS_EX_LAYERED : 0;
-		SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, ws);
+
+		{
+			DWORD ws = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_LAYERED;
+			ws |= dat->flags2.bUseTransparency ? WS_EX_LAYERED : 0;
+			SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, ws);
+		}
 		if (dat->flags2.bUseTransparency)
 			SetLayeredWindowAttributes(hwndDlg, RGB(255, 255, 255), (BYTE)(255 - g_dat.activeAlpha), LWA_ALPHA);
 		break;
@@ -1108,13 +1166,6 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 		mir_free(dat);
 		break;
 
-	case DM_SENDMESSAGE:
-		for (int i = 0; i < dat->m_iChildrenCount; i++) {
-			CMsgDialog * pDlg = GetChildFromTab(dat->m_hwndTabs, i);
-			SendMessage(pDlg->GetHwnd(), DM_SENDMESSAGE, wParam, lParam);
-		}
-		break;
-
 	case DM_OPTIONSAPPLIED:
 		dat->flags2 = g_dat.flags2;
 		dat->SetContainerWindowStyle();
@@ -1127,47 +1178,6 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 		RedrawWindow(dat->m_hwndStatus, nullptr, nullptr, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
 		break;
 
-	case DM_SWITCHINFOBAR:
-		dat->flags2.bShowInfoBar = !dat->flags2.bShowInfoBar;
-
-		for (int i = 0; i < dat->m_iChildrenCount; i++) {
-			CMsgDialog * pDlg = GetChildFromTab(dat->m_hwndTabs, i);
-			SendMessage(pDlg->GetHwnd(), DM_SWITCHINFOBAR, 0, 0);
-		}
-		SendMessage(hwndDlg, WM_SIZE, 0, 0);
-		break;
-
-	case DM_SWITCHSTATUSBAR:
-		dat->flags2.bShowStatusBar = !dat->flags2.bShowStatusBar;
-		ShowWindow(dat->m_hwndStatus, (dat->flags2.bShowStatusBar) ? SW_SHOW : SW_HIDE);
-		SendMessage(hwndDlg, WM_SIZE, 0, 0);
-		break;
-
-	case DM_SWITCHTOOLBAR:
-		dat->flags2.bShowToolBar = !dat->flags2.bShowToolBar;
-
-		for (int i = 0; i < dat->m_iChildrenCount; i++) {
-			CMsgDialog * pDlg = GetChildFromTab(dat->m_hwndTabs, i);
-			SendMessage(pDlg->GetHwnd(), DM_SWITCHTOOLBAR, 0, 0);
-		}
-
-		SendMessage(hwndDlg, WM_SIZE, 0, 0);
-		break;
-
-	case DM_SWITCHTITLEBAR:
-		dat->flags2.bShowTitleBar = !dat->flags2.bShowTitleBar;
-		ws = GetWindowLongPtr(hwndDlg, GWL_STYLE) & ~(WS_CAPTION);
-		if (dat->flags2.bShowTitleBar)
-			ws |= WS_CAPTION;
-
-		SetWindowLongPtr(hwndDlg, GWL_STYLE, ws);
-		RECT rc;
-		GetWindowRect(hwndDlg, &rc);
-		SetWindowPos(hwndDlg, nullptr, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
-			SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
-		RedrawWindow(hwndDlg, nullptr, nullptr, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
-		break;
-
 	case DM_CASCADENEWWINDOW:
 		if ((HWND)wParam != hwndDlg) {
 			RECT rcThis, rcNew;
diff --git a/plugins/Scriver/src/tabs.h b/plugins/Scriver/src/tabs.h
index f5f37435d0..41a0de8cb1 100644
--- a/plugins/Scriver/src/tabs.h
+++ b/plugins/Scriver/src/tabs.h
@@ -96,7 +96,7 @@ struct ParentWindowData
 
 	bool bTopmost;
 
-	void ActivateChild(HWND child);
+	void ActivateChild(CMsgDialog *pDlg);
 	void ActivateChildByIndex(int index);
 	void ActivateNextChild(HWND child);
 	void ActivatePrevChild(HWND child);
@@ -106,10 +106,15 @@ struct ParentWindowData
 	void GetChildWindowRect(RECT *rcChild);
 	int  GetTabFromHWND(HWND child);
 	CMsgDialog *GetChildFromHWND(HWND hwnd);
-	void PopupWindow(HWND hwnd, bool bIncoming);
+	void PopupWindow(CMsgDialog *pDlg, bool bIncoming);
 	void RemoveChild(HWND child);
+	void MessageSend(const MessageSendQueueItem &msg);
 	void SetContainerWindowStyle();
 	void StartFlashing();
+	void ToggleInfoBar();
+	void ToggleStatusBar();
+	void ToggleTitleBar();
+	void ToggleToolBar();
 	void UpdateStatusBar(const StatusBarData &sbd, HWND);
 	void UpdateTabControl(const TabControlData &tbd, HWND);
 	void UpdateTitleBar(const TitleBarData &tbd, HWND);
-- 
cgit v1.2.3