From 7e71db53bdd51a213e9262723d52957a0961793d Mon Sep 17 00:00:00 2001
From: George Hazan <ghazan@miranda.im>
Date: Sun, 5 Mar 2017 20:20:14 +0300
Subject: Scriver -> core splitters

also:
- structure of Scriver SRMM classes redesigned to avoid problems with MS compilers;
- unused cursors removed;
- now splitter position is being saved & restored;
---
 plugins/Scriver/src/chat/chat.h     |    4 +-
 plugins/Scriver/src/chat/window.cpp | 1712 +++++++++++++++++------------------
 plugins/Scriver/src/input.cpp       |    2 +-
 plugins/Scriver/src/input.h         |    6 +-
 plugins/Scriver/src/msgdialog.cpp   |  136 +--
 plugins/Scriver/src/msgs.cpp        |   34 +-
 plugins/Scriver/src/msgs.h          |   43 +-
 plugins/Scriver/src/stdafx.h        |   35 +-
 plugins/Scriver/src/tabs.cpp        |    6 +
 plugins/Scriver/src/version.h       |    2 +-
 10 files changed, 950 insertions(+), 1030 deletions(-)

(limited to 'plugins/Scriver')

diff --git a/plugins/Scriver/src/chat/chat.h b/plugins/Scriver/src/chat/chat.h
index b9cb61f0dd..02764be9a0 100644
--- a/plugins/Scriver/src/chat/chat.h
+++ b/plugins/Scriver/src/chat/chat.h
@@ -56,10 +56,8 @@ struct LOGSTREAMDATA : public GCLogStreamDataBase
 	BOOL isFirst;
 };
 
-struct SESSION_INFO : public GCSessionInfoBase, public CommonWindowData
+struct SESSION_INFO : public GCSessionInfoBase
 {
-	wchar_t szSearch[255];
-	int   desiredInputAreaHeight;
 };
 
 struct GlobalLogSettings : public GlobalLogSettingsBase
diff --git a/plugins/Scriver/src/chat/window.cpp b/plugins/Scriver/src/chat/window.cpp
index 3655e3c4b7..6536ecf89b 100644
--- a/plugins/Scriver/src/chat/window.cpp
+++ b/plugins/Scriver/src/chat/window.cpp
@@ -29,38 +29,6 @@ struct MESSAGESUBDATA
 	SESSION_INFO *lastSession;
 };
 
-static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-	RECT rc;
-
-	switch (msg) {
-	case WM_NCHITTEST:
-		return HTCLIENT;
-
-	case WM_SETCURSOR:
-		GetClientRect(hwnd, &rc);
-		SetCursor(rc.right > rc.bottom ? hCurSplitNS : hCurSplitWE);
-		return TRUE;
-
-	case WM_LBUTTONDOWN:
-		SetCapture(hwnd);
-		return 0;
-
-	case WM_MOUSEMOVE:
-		if (GetCapture() == hwnd) {
-			GetClientRect(hwnd, &rc);
-			SendMessage(GetParent(hwnd), GC_SPLITTERMOVED, rc.right > rc.bottom ? (short)HIWORD(GetMessagePos()) + rc.bottom / 2 : (short)LOWORD(GetMessagePos()) + rc.right / 2, (LPARAM)hwnd);
-		}
-		return 0;
-
-	case WM_LBUTTONUP:
-		ReleaseCapture();
-		PostMessage(GetParent(hwnd), WM_SIZE, 0, 0);
-		return 0;
-	}
-	return mir_callNextSubclass(hwnd, SplitterSubclassProc, msg, wParam, lParam);
-}
-
 static void InitButtons(HWND hwndDlg, SESSION_INFO *si)
 {
 	SendDlgItemMessage(hwndDlg, IDC_CHAT_SHOWNICKLIST, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(si->bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2"));
@@ -173,10 +141,10 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 	BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000;
 	BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
 
-	SESSION_INFO *si = (SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
 	MESSAGESUBDATA *dat = (MESSAGESUBDATA *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+	CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
 
-	int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, si);
+	int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, pDlg);
 	if (result != -1)
 		return result;
 
@@ -231,7 +199,7 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 
 		if (wParam == VK_TAB && !isCtrl && !isShift) {    //tab-autocomplete
 			SendMessage(hwnd, WM_SETREDRAW, FALSE, 0);
-			TabAutoComplete(hwnd, dat, si);
+			TabAutoComplete(hwnd, dat, pDlg->m_si);
 			SendMessage(hwnd, WM_SETREDRAW, TRUE, 0);
 			RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
 			return 0;
@@ -328,7 +296,7 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 		break;
 
 	case WM_CONTEXTMENU:
-		InputAreaContextMenu(hwnd, wParam, lParam, si->hContact);
+		InputAreaContextMenu(hwnd, wParam, lParam, pDlg->m_hContact);
 		return TRUE;
 
 	case WM_KEYUP:
@@ -347,13 +315,13 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 			cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_BACKCOLOR | CFM_COLOR;
 			SendMessage(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
 
-			if (pci->MM_FindModule(si->pszModule) && pci->MM_FindModule(si->pszModule)->bColor) {
-				int index = pci->GetColorIndex(si->pszModule, cf.crTextColor);
+			if (pci->MM_FindModule(pDlg->m_si->pszModule) && pci->MM_FindModule(pDlg->m_si->pszModule)->bColor) {
+				int index = pci->GetColorIndex(pDlg->m_si->pszModule, cf.crTextColor);
 				u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_COLOR);
 
 				if (index >= 0) {
-					si->bFGSet = TRUE;
-					si->iFG = index;
+					pDlg->m_si->bFGSet = TRUE;
+					pDlg->m_si->iFG = index;
 				}
 
 				if (u == BST_UNCHECKED && cf.crTextColor != cr)
@@ -362,14 +330,14 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 					CheckDlgButton(GetParent(hwnd), IDC_CHAT_COLOR, BST_UNCHECKED);
 			}
 
-			if (pci->MM_FindModule(si->pszModule) && pci->MM_FindModule(si->pszModule)->bBkgColor) {
-				int index = pci->GetColorIndex(si->pszModule, cf.crBackColor);
+			if (pci->MM_FindModule(pDlg->m_si->pszModule) && pci->MM_FindModule(pDlg->m_si->pszModule)->bBkgColor) {
+				int index = pci->GetColorIndex(pDlg->m_si->pszModule, cf.crBackColor);
 				COLORREF crB = db_get_dw(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
 				u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_BKGCOLOR);
 
 				if (index >= 0) {
-					si->bBGSet = TRUE;
-					si->iBG = index;
+					pDlg->m_si->bBGSet = TRUE;
+					pDlg->m_si->iBG = index;
 				}
 				if (u == BST_UNCHECKED && cf.crBackColor != crB)
 					CheckDlgButton(GetParent(hwnd), IDC_CHAT_BKGCOLOR, BST_CHECKED);
@@ -377,7 +345,7 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 					CheckDlgButton(GetParent(hwnd), IDC_CHAT_BKGCOLOR, BST_UNCHECKED);
 			}
 
-			if (pci->MM_FindModule(si->pszModule) && pci->MM_FindModule(si->pszModule)->bBold) {
+			if (pci->MM_FindModule(pDlg->m_si->pszModule) && pci->MM_FindModule(pDlg->m_si->pszModule)->bBold) {
 				u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_BOLD);
 				u2 = cf.dwEffects;
 				u2 &= CFE_BOLD;
@@ -387,7 +355,7 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 					CheckDlgButton(GetParent(hwnd), IDC_CHAT_BOLD, BST_UNCHECKED);
 			}
 
-			if (pci->MM_FindModule(si->pszModule) && pci->MM_FindModule(si->pszModule)->bItalics) {
+			if (pci->MM_FindModule(pDlg->m_si->pszModule) && pci->MM_FindModule(pDlg->m_si->pszModule)->bItalics) {
 				u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_ITALICS);
 				u2 = cf.dwEffects;
 				u2 &= CFE_ITALIC;
@@ -397,7 +365,7 @@ static LRESULT CALLBACK MessageSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 					CheckDlgButton(GetParent(hwnd), IDC_CHAT_ITALICS, BST_UNCHECKED);
 			}
 
-			if (pci->MM_FindModule(si->pszModule) && pci->MM_FindModule(si->pszModule)->bUnderline) {
+			if (pci->MM_FindModule(pDlg->m_si->pszModule) && pci->MM_FindModule(pDlg->m_si->pszModule)->bUnderline) {
 				u = IsDlgButtonChecked(GetParent(hwnd), IDC_CHAT_UNDERLINE);
 				u2 = cf.dwEffects;
 				u2 &= CFE_UNDERLINE;
@@ -510,8 +478,9 @@ static LRESULT CALLBACK ButtonSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, L
 static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 	static BOOL inMenu = FALSE;
-	SESSION_INFO *si = (SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
-	int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, si);
+	CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+
+	int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, pDlg);
 	if (result != -1)
 		return result;
 
@@ -573,7 +542,7 @@ static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
 
 			CHARRANGE all = { 0, -1 };
 			HMENU hMenu = NULL;
-			UINT uID = CreateGCMenu(hwnd, &hMenu, 1, pt, si, NULL, pszWord);
+			UINT uID = CreateGCMenu(hwnd, &hMenu, 1, pt, pDlg->m_si, NULL, pszWord);
 			inMenu = FALSE;
 			switch (uID) {
 			case 0:
@@ -589,11 +558,11 @@ static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
 				break;
 
 			case IDM_CLEAR:
-				if (si) {
+				if (pDlg->m_si) {
 					SetWindowText(hwnd, L"");
-					pci->LM_RemoveAll(&si->pLog, &si->pLogEnd);
-					si->iEventCount = 0;
-					si->LastTime = 0;
+					pci->LM_RemoveAll(&pDlg->m_si->pLog, &pDlg->m_si->pLogEnd);
+					pDlg->m_si->iEventCount = 0;
+					pDlg->m_si->LastTime = 0;
 					PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0);
 				}
 				break;
@@ -612,7 +581,7 @@ static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
 
 			default:
 				PostMessage(GetParent(hwnd), WM_MOUSEACTIVATE, 0, 0);
-				pci->DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_LOGMENU, NULL, NULL, uID);
+				pci->DoEventHookAsync(GetParent(hwnd), pDlg->m_si->ptszID, pDlg->m_si->pszModule, GC_USER_LOGMENU, NULL, NULL, uID);
 				break;
 			}
 			DestroyGCMenu(&hMenu, 5);
@@ -630,8 +599,9 @@ static LRESULT CALLBACK LogSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
 
 static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-	SESSION_INFO *si = (SESSION_INFO*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
-	int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, si);
+	CChatRoomDlg *pDlg = (CChatRoomDlg*)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+
+	int result = InputAreaShortcuts(hwnd, msg, wParam, lParam, pDlg);
 	if (result != -1)
 		return result;
 
@@ -641,10 +611,10 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 			HDC dc = (HDC)wParam;
 			if (dc) {
 				int index = SendMessage(hwnd, LB_GETTOPINDEX, 0, 0);
-				if (index == LB_ERR || si->nUsersInNicklist <= 0)
+				if (index == LB_ERR || pDlg->m_si->nUsersInNicklist <= 0)
 					return 0;
 
-				int items = si->nUsersInNicklist - index;
+				int items = pDlg->m_si->nUsersInNicklist - index;
 				int height = SendMessage(hwnd, LB_GETITEMHEIGHT, 0, 0);
 
 				if (height != LB_ERR) {
@@ -706,7 +676,7 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 			else
 				item &= 0xFFFF;
 
-			USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, (int)item);
+			USERINFO *ui = pci->SM_GetUserFromIndex(pDlg->m_si->ptszID, pDlg->m_si->pszModule, (int)item);
 			if (ui) {
 				HMENU hMenu = 0;
 				UINT uID;
@@ -716,18 +686,18 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 				if (hti.pt.x == -1 && hti.pt.y == -1)
 					hti.pt.y += height - 4;
 				ClientToScreen(hwnd, &hti.pt);
-				uID = CreateGCMenu(hwnd, &hMenu, 0, hti.pt, si, uinew.pszUID, uinew.pszNick);
+				uID = CreateGCMenu(hwnd, &hMenu, 0, hti.pt, pDlg->m_si, uinew.pszUID, uinew.pszNick);
 
 				switch (uID) {
 				case 0:
 					break;
 
 				case ID_MESS:
-					pci->DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_PRIVMESS, ui, nullptr, 0);
+					pci->DoEventHookAsync(GetParent(hwnd), pDlg->m_si->ptszID, pDlg->m_si->pszModule, GC_USER_PRIVMESS, ui, nullptr, 0);
 					break;
 
 				default:
-					pci->DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_NICKLISTMENU, ui, nullptr, uID);
+					pci->DoEventHookAsync(GetParent(hwnd), pDlg->m_si->ptszID, pDlg->m_si->pszModule, GC_USER_NICKLISTMENU, ui, nullptr, uID);
 					break;
 				}
 				DestroyGCMenu(&hMenu, 1);
@@ -754,14 +724,14 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 		if (wParam == VK_RETURN) {
 			int index = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
 			if (index != LB_ERR) {
-				USERINFO *ui = pci->SM_GetUserFromIndex(si->ptszID, si->pszModule, index);
-				pci->DoEventHookAsync(GetParent(hwnd), si->ptszID, si->pszModule, GC_USER_PRIVMESS, ui, nullptr, 0);
+				USERINFO *ui = pci->SM_GetUserFromIndex(pDlg->m_si->ptszID, pDlg->m_si->pszModule, index);
+				pci->DoEventHookAsync(GetParent(hwnd), pDlg->m_si->ptszID, pDlg->m_si->pszModule, GC_USER_PRIVMESS, ui, nullptr, 0);
 			}
 			break;
 		}
 		if (wParam == VK_ESCAPE || wParam == VK_UP || wParam == VK_DOWN || wParam == VK_NEXT ||
 			wParam == VK_PRIOR || wParam == VK_TAB || wParam == VK_HOME || wParam == VK_END) {
-			si->szSearch[0] = 0;
+			pDlg->m_wszSearch[0] = 0;
 		}
 		break;
 
@@ -771,32 +741,32 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 		* simple incremental search for the user (nick) - list control
 		* typing esc or movement keys will clear the current search string
 		*/
-		if (wParam == 27 && si->szSearch[0]) {						// escape - reset everything
-			si->szSearch[0] = 0;
+		if (wParam == 27 && pDlg->m_wszSearch[0]) {						// escape - reset everything
+			pDlg->m_wszSearch[0] = 0;
 			break;
 		}
-		else if (wParam == '\b' && si->szSearch[0])					// backspace
-			si->szSearch[mir_wstrlen(si->szSearch) - 1] = '\0';
+		else if (wParam == '\b' && pDlg->m_wszSearch[0])					// backspace
+			pDlg->m_wszSearch[mir_wstrlen(pDlg->m_wszSearch) - 1] = '\0';
 		else if (wParam < ' ')
 			break;
 		else {
 			wchar_t szNew[2];
 			szNew[0] = (wchar_t)wParam;
 			szNew[1] = '\0';
-			if (mir_wstrlen(si->szSearch) >= _countof(si->szSearch) - 2) {
+			if (mir_wstrlen(pDlg->m_wszSearch) >= _countof(pDlg->m_wszSearch) - 2) {
 				MessageBeep(MB_OK);
 				break;
 			}
-			mir_wstrcat(si->szSearch, szNew);
+			mir_wstrcat(pDlg->m_wszSearch, szNew);
 		}
-		if (si->szSearch[0]) {
+		if (pDlg->m_wszSearch[0]) {
 			// iterate over the (sorted) list of nicknames and search for the
 			// string we have
 			int iItems = SendMessage(hwnd, LB_GETCOUNT, 0, 0);
 			for (int i = 0; i < iItems; i++) {
-				USERINFO *ui = pci->UM_FindUserFromIndex(si->pUsers, i);
+				USERINFO *ui = pci->UM_FindUserFromIndex(pDlg->m_si->pUsers, i);
 				if (ui) {
-					if (!wcsnicmp(ui->pszNick, si->szSearch, mir_wstrlen(si->szSearch))) {
+					if (!wcsnicmp(ui->pszNick, pDlg->m_wszSearch, mir_wstrlen(pDlg->m_wszSearch))) {
 						SendMessage(hwnd, LB_SETCURSEL, i, 0);
 						InvalidateRect(hwnd, NULL, FALSE);
 						return 0;
@@ -805,13 +775,13 @@ static LRESULT CALLBACK NicklistSubclassProc(HWND hwnd, UINT msg, WPARAM wParam,
 			}
 
 			MessageBeep(MB_OK);
-			si->szSearch[mir_wstrlen(si->szSearch) - 1] = '\0';
+			pDlg->m_wszSearch[mir_wstrlen(pDlg->m_wszSearch) - 1] = '\0';
 			return 0;
 		}
 		break;
 
 	case WM_MOUSEMOVE:
-		Chat_HoverMouse(si, hwnd, lParam, ServiceExists("mToolTip/HideTip"));
+		Chat_HoverMouse(pDlg->m_si, hwnd, lParam, ServiceExists("mToolTip/HideTip"));
 		break;
 	}
 
@@ -845,952 +815,928 @@ static void __cdecl phase2(void *lParam)
 
 /////////////////////////////////////////////////////////////////////////////////////////
 
-class CChatRoomDlg : public CSrmmBaseDialog
+void CChatRoomDlg::MessageDialogResize(int w, int h)
 {
-	SESSION_INFO *m_si;
-
-	CCtrlEdit m_message, m_log;
-	CCtrlListBox m_nickList;
-
-	void MessageDialogResize(int w, int h)
-	{
-		bool bNick = m_si->iType != GCW_SERVER && m_si->bNicklistEnabled;
-		bool bToolbar = SendMessage(m_hwndParent, CM_GETTOOLBARSTATUS, 0, 0) != 0;
-		int  hSplitterMinTop = TOOLBAR_HEIGHT + m_si->m_minLogBoxHeight, hSplitterMinBottom = m_si->m_minEditBoxHeight;
-		int  toolbarHeight = bToolbar ? TOOLBAR_HEIGHT : 0;
-
-		m_si->iSplitterY = m_si->desiredInputAreaHeight + SPLITTER_HEIGHT + 3;
-
-		if (h - m_si->iSplitterY < hSplitterMinTop)
-			m_si->iSplitterY = h - hSplitterMinTop;
-		if (m_si->iSplitterY < hSplitterMinBottom)
-			m_si->iSplitterY = hSplitterMinBottom;
+	bool bNick = m_si->iType != GCW_SERVER && m_si->bNicklistEnabled;
+	bool bToolbar = SendMessage(m_hwndParent, CM_GETTOOLBARSTATUS, 0, 0) != 0;
+	int  hSplitterMinTop = TOOLBAR_HEIGHT + m_minLogBoxHeight, hSplitterMinBottom = m_minEditBoxHeight;
+	int  toolbarHeight = bToolbar ? TOOLBAR_HEIGHT : 0;
+
+	if (h - m_si->iSplitterY < hSplitterMinTop)
+		m_si->iSplitterY = h - hSplitterMinTop;
+	if (m_si->iSplitterY < hSplitterMinBottom)
+		m_si->iSplitterY = hSplitterMinBottom;
+
+	ShowWindow(m_splitterX.GetHwnd(), bNick ? SW_SHOW : SW_HIDE);
+	if (m_si->iType != GCW_SERVER)
+		ShowWindow(m_nickList.GetHwnd(), m_si->bNicklistEnabled ? SW_SHOW : SW_HIDE);
+	else
+		ShowWindow(m_nickList.GetHwnd(), SW_HIDE);
+
+	if (m_si->iType == GCW_SERVER) {
+		EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_SHOWNICKLIST), FALSE);
+		EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), FALSE);
+		EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_CHANMGR), FALSE);
+	}
+	else {
+		EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_SHOWNICKLIST), TRUE);
+		EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), TRUE);
+		if (m_si->iType == GCW_CHATROOM)
+			EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_CHANMGR), pci->MM_FindModule(m_si->pszModule)->bChanMgr);
+	}
 
-		ShowWindow(GetDlgItem(m_hwnd, IDC_SPLITTERX), bNick ? SW_SHOW : SW_HIDE);
-		if (m_si->iType != GCW_SERVER)
-			ShowWindow(GetDlgItem(m_hwnd, IDC_CHAT_LIST), m_si->bNicklistEnabled ? SW_SHOW : SW_HIDE);
-		else
-			ShowWindow(GetDlgItem(m_hwnd, IDC_CHAT_LIST), SW_HIDE);
+	HDWP hdwp = BeginDeferWindowPos(5);
+	int toolbarTopY = bToolbar ? h - m_si->iSplitterY - toolbarHeight : h - m_si->iSplitterY;
+	int logBottom = (m_hwndIeview != NULL) ? toolbarTopY / 2 : toolbarTopY;
+
+	hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), 0, 1, 0, bNick ? w - m_si->iSplitterX - 1 : w - 2, logBottom, SWP_NOZORDER);
+	hdwp = DeferWindowPos(hdwp, m_nickList.GetHwnd(), 0, w - m_si->iSplitterX + 2, 0, m_si->iSplitterX - 3, toolbarTopY, SWP_NOZORDER);
+	hdwp = DeferWindowPos(hdwp, m_splitterX.GetHwnd(), 0, w - m_si->iSplitterX, 1, 2, toolbarTopY - 1, SWP_NOZORDER);
+	hdwp = DeferWindowPos(hdwp, m_splitterY.GetHwnd(), 0, 0, h - m_si->iSplitterY, w, SPLITTER_HEIGHT, SWP_NOZORDER);
+	hdwp = DeferWindowPos(hdwp, m_message.GetHwnd(), 0, 1, h - m_si->iSplitterY + SPLITTER_HEIGHT, w - 2, m_si->iSplitterY - SPLITTER_HEIGHT - 1, SWP_NOZORDER);
+	EndDeferWindowPos(hdwp);
+
+	SetButtonsPos(m_hwnd, m_hContact, bToolbar);
+
+	if (m_hwndIeview != NULL) {
+		IEVIEWWINDOW ieWindow;
+		ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+		ieWindow.iType = IEW_SETPOS;
+		ieWindow.parent = m_hwnd;
+		ieWindow.hwnd = m_hwndIeview;
+		ieWindow.x = 0;
+		ieWindow.y = logBottom + 1;
+		ieWindow.cx = bNick ? w - m_si->iSplitterX : w;
+		ieWindow.cy = logBottom;
+		CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+	}
+	else RedrawWindow(m_log.GetHwnd(), NULL, NULL, RDW_INVALIDATE);
 
-		if (m_si->iType == GCW_SERVER) {
-			EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_SHOWNICKLIST), FALSE);
-			EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), FALSE);
-			EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_CHANMGR), FALSE);
-		}
-		else {
-			EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_SHOWNICKLIST), TRUE);
-			EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), TRUE);
-			if (m_si->iType == GCW_CHATROOM)
-				EnableWindow(GetDlgItem(m_hwnd, IDC_CHAT_CHANMGR), pci->MM_FindModule(m_si->pszModule)->bChanMgr);
-		}
+	RedrawWindow(m_nickList.GetHwnd(), NULL, NULL, RDW_INVALIDATE);
+	RedrawWindow(m_message.GetHwnd(), NULL, NULL, RDW_INVALIDATE);
+}
 
-		HDWP hdwp = BeginDeferWindowPos(5);
-		int toolbarTopY = bToolbar ? h - m_si->iSplitterY - toolbarHeight : h - m_si->iSplitterY;
-		int logBottom = (m_si->m_hwndIeview != NULL) ? toolbarTopY / 2 : toolbarTopY;
-
-		hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_LOG), 0, 1, 0, bNick ? w - m_si->iSplitterX - 1 : w - 2, logBottom, SWP_NOZORDER);
-		hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_CHAT_LIST), 0, w - m_si->iSplitterX + 2, 0, m_si->iSplitterX - 3, toolbarTopY, SWP_NOZORDER);
-		hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_SPLITTERX), 0, w - m_si->iSplitterX, 1, 2, toolbarTopY - 1, SWP_NOZORDER);
-		hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_SPLITTERY), 0, 0, h - m_si->iSplitterY, w, SPLITTER_HEIGHT, SWP_NOZORDER);
-		hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_MESSAGE), 0, 1, h - m_si->iSplitterY + SPLITTER_HEIGHT, w - 2, m_si->iSplitterY - SPLITTER_HEIGHT - 1, SWP_NOZORDER);
-		EndDeferWindowPos(hdwp);
-
-		SetButtonsPos(m_hwnd, m_hContact, bToolbar);
-
-		if (m_si->m_hwndIeview != NULL) {
-			IEVIEWWINDOW ieWindow;
-			ieWindow.cbSize = sizeof(IEVIEWWINDOW);
-			ieWindow.iType = IEW_SETPOS;
-			ieWindow.parent = m_hwnd;
-			ieWindow.hwnd = m_si->m_hwndIeview;
-			ieWindow.x = 0;
-			ieWindow.y = logBottom + 1;
-			ieWindow.cx = bNick ? w - m_si->iSplitterX : w;
-			ieWindow.cy = logBottom;
-			CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
-		}
-		else RedrawWindow(GetDlgItem(m_hwnd, IDC_LOG), NULL, NULL, RDW_INVALIDATE);
+CChatRoomDlg::CChatRoomDlg(SESSION_INFO *si)
+	: CScriverWindow(IDD_CHANNEL),
+	m_si(si),
+	m_log(this, IDC_LOG),
+	m_message(this, IDC_MESSAGE),
+	m_nickList(this, IDC_CHAT_LIST),
+	m_splitterX(this, IDC_SPLITTERX),
+	m_splitterY(this, IDC_SPLITTERY)
+{
+	m_pLog = &m_log;
+	m_pEntry = &m_message;
+	m_autoClose = 0;
+	m_hContact = si->hContact;
 
-		RedrawWindow(GetDlgItem(m_hwnd, IDC_CHAT_LIST), NULL, NULL, RDW_INVALIDATE);
-		RedrawWindow(GetDlgItem(m_hwnd, IDC_MESSAGE), NULL, NULL, RDW_INVALIDATE);
-	}
+	m_splitterX.OnChange = Callback(this, &CChatRoomDlg::OnSplitterX);
+	m_splitterY.OnChange = Callback(this, &CChatRoomDlg::OnSplitterY);
+}
 
-public:
-	CChatRoomDlg(SESSION_INFO *si)
-		: CSrmmBaseDialog(g_hInst, IDD_CHANNEL),
-		m_si(si),
-		m_log(this, IDC_LOG),
-		m_message(this, IDC_MESSAGE),
-		m_nickList(this, IDC_CHAT_LIST)
-	{
-		m_pLog = &m_log;
-		m_pEntry = &m_message;
-		m_autoClose = 0;
-		m_hContact = si->hContact;
+void CChatRoomDlg::OnInitDialog()
+{
+	NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPENING);
+
+	SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)this);
+
+	RichUtil_SubClass(m_message.GetHwnd());
+	RichUtil_SubClass(m_log.GetHwnd());
+	RichUtil_SubClass(m_nickList.GetHwnd());
+
+	mir_subclassWindow(m_nickList.GetHwnd(), NicklistSubclassProc);
+	mir_subclassWindow(m_log.GetHwnd(), LogSubclassProc);
+	mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), ButtonSubclassProc);
+	mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CHAT_COLOR), ButtonSubclassProc);
+	mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CHAT_BKGCOLOR), ButtonSubclassProc);
+	mir_subclassWindow(m_message.GetHwnd(), MessageSubclassProc);
+
+	Srmm_CreateToolbarIcons(m_hwnd, BBBF_ISCHATBUTTON);
+
+	RECT minEditInit;
+	GetWindowRect(m_message.GetHwnd(), &minEditInit);
+	m_minEditBoxHeight = minEditInit.bottom - minEditInit.top;
+	m_minLogBoxHeight = m_minEditBoxHeight;
+
+	m_message.SendMsg(EM_SUBCLASSED, 0, 0);
+	m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE);
+
+	int mask = (int)m_log.SendMsg(EM_GETEVENTMASK, 0, 0);
+	m_log.SendMsg(EM_SETEVENTMASK, 0, mask | ENM_LINK | ENM_MOUSEEVENTS);
+	m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0);
+	m_log.SendMsg(EM_SETOLECALLBACK, 0, (LPARAM)&reOleCallback);
+	m_log.SendMsg(EM_AUTOURLDETECT, 1, 0);
+
+	if (db_get_b(NULL, CHAT_MODULE, "UseIEView", 0)) {
+		IEVIEWWINDOW ieWindow = { sizeof(ieWindow) };
+		ieWindow.iType = IEW_CREATE;
+		ieWindow.dwMode = IEWM_CHAT;
+		ieWindow.parent = m_hwnd;
+		ieWindow.cx = 200;
+		ieWindow.cy = 300;
+		CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
+
+		m_hwndIeview = ieWindow.hwnd;
+
+		IEVIEWEVENT iee = { sizeof(iee) };
+		iee.iType = IEE_CLEAR_LOG;
+		iee.hwnd = m_hwndIeview;
+		iee.hContact = m_hContact;
+		iee.pszProto = m_si->pszModule;
+		CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee);
 	}
 
-	virtual void OnInitDialog() override
-	{
-		NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPENING);
-
-		SetWindowLongPtr(m_hwnd, GWLP_USERDATA, (LONG_PTR)m_si);
-
-		RichUtil_SubClass(m_message.GetHwnd());
-		RichUtil_SubClass(m_log.GetHwnd());
-		RichUtil_SubClass(m_nickList.GetHwnd());
-		mir_subclassWindow(GetDlgItem(m_hwnd, IDC_SPLITTERX), SplitterSubclassProc);
-		mir_subclassWindow(m_nickList.GetHwnd(), NicklistSubclassProc);
-		mir_subclassWindow(m_log.GetHwnd(), LogSubclassProc);
-		mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), ButtonSubclassProc);
-		mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CHAT_COLOR), ButtonSubclassProc);
-		mir_subclassWindow(GetDlgItem(m_hwnd, IDC_CHAT_BKGCOLOR), ButtonSubclassProc);
-		mir_subclassWindow(m_message.GetHwnd(), MessageSubclassProc);
-
-		Srmm_CreateToolbarIcons(m_hwnd, BBBF_ISCHATBUTTON);
-
-		RECT minEditInit;
-		GetWindowRect(m_message.GetHwnd(), &minEditInit);
-		m_si->m_minEditBoxHeight = minEditInit.bottom - minEditInit.top;
-		m_si->m_minLogBoxHeight = m_si->m_minEditBoxHeight;
-
-		m_message.SendMsg(EM_SUBCLASSED, 0, 0);
-		m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE);
-
-		int mask = (int)m_log.SendMsg(EM_GETEVENTMASK, 0, 0);
-		m_log.SendMsg(EM_SETEVENTMASK, 0, mask | ENM_LINK | ENM_MOUSEEVENTS);
-		m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0);
-		m_log.SendMsg(EM_SETOLECALLBACK, 0, (LPARAM)&reOleCallback);
-		m_log.SendMsg(EM_AUTOURLDETECT, 1, 0);
-
-		if (db_get_b(NULL, CHAT_MODULE, "UseIEView", 0)) {
-			IEVIEWWINDOW ieWindow = { sizeof(ieWindow) };
-			ieWindow.iType = IEW_CREATE;
-			ieWindow.dwMode = IEWM_CHAT;
-			ieWindow.parent = m_hwnd;
-			ieWindow.cx = 200;
-			ieWindow.cy = 300;
-			CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
-
-			m_si->m_hwndIeview = ieWindow.hwnd;
-
-			IEVIEWEVENT iee = { sizeof(iee) };
-			iee.iType = IEE_CLEAR_LOG;
-			iee.hwnd = m_si->m_hwndIeview;
-			iee.hContact = m_hContact;
-			iee.pszProto = m_si->pszModule;
-			CallService(MS_IEVIEW_EVENT, 0, (LPARAM)&iee);
-		}
+	m_log.SendMsg(EM_HIDESELECTION, TRUE, 0);
 
-		m_log.SendMsg(EM_HIDESELECTION, TRUE, 0);
+	SendMessage(m_hwnd, GC_SETWNDPROPS, 0, 0);
+	SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
+	SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
 
-		SendMessage(m_hwnd, GC_SETWNDPROPS, 0, 0);
-		SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
-		SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
+	SendMessage(m_hwndParent, CM_ADDCHILD, (WPARAM)m_hwnd, m_hContact);
+	PostMessage(m_hwnd, GC_UPDATENICKLIST, 0, 0);
+	NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPEN);
+}
 
-		SendMessage(m_hwndParent, CM_ADDCHILD, (WPARAM)m_hwnd, m_hContact);
-		PostMessage(m_hwnd, GC_UPDATENICKLIST, 0, 0);
-		NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_OPEN);
+void CChatRoomDlg::OnDestroy()
+{
+	NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSING);
+
+	m_si->hWnd = NULL;
+	SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
+
+	SendMessage(m_hwndParent, CM_REMOVECHILD, 0, (LPARAM)m_hwnd);
+	if (m_hwndIeview != NULL) {
+		IEVIEWWINDOW ieWindow;
+		ieWindow.cbSize = sizeof(IEVIEWWINDOW);
+		ieWindow.iType = IEW_DESTROY;
+		ieWindow.hwnd = m_hwndIeview;
+		CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
 	}
 
-	virtual void OnDestroy() override
-	{
-		NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSING);
+	NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE);
+}
 
-		m_si->hWnd = NULL;
-		SetWindowLongPtr(m_hwnd, GWLP_USERDATA, 0);
+void CChatRoomDlg::OnSplitterX(CSplitter *pSplitter)
+{
+	RECT rc;
+	GetClientRect(m_hwnd, &rc);
+
+	m_si->iSplitterX = rc.right - pSplitter->GetPos() + 1;
+	if (m_si->iSplitterX < 35)
+		m_si->iSplitterX = 35;
+	if (m_si->iSplitterX > rc.right - rc.left - 35)
+		m_si->iSplitterX = rc.right - rc.left - 35;
+	g_Settings.iSplitterX = m_si->iSplitterX;
+}
 
-		SendMessage(m_hwndParent, CM_REMOVECHILD, 0, (LPARAM)m_hwnd);
-		if (m_si->m_hwndIeview != NULL) {
-			IEVIEWWINDOW ieWindow;
-			ieWindow.cbSize = sizeof(IEVIEWWINDOW);
-			ieWindow.iType = IEW_DESTROY;
-			ieWindow.hwnd = m_si->m_hwndIeview;
-			CallService(MS_IEVIEW_WINDOW, 0, (LPARAM)&ieWindow);
-		}
+void CChatRoomDlg::OnSplitterY(CSplitter *pSplitter)
+{
+	RECT rc;
+	GetClientRect(m_hwnd, &rc);
 
-		NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE);
-	}
+	m_si->iSplitterY = rc.bottom - pSplitter->GetPos();
+	g_Settings.iSplitterY = m_si->iSplitterY;
+}
 
-	virtual INT_PTR DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) override
-	{
-		static HMENU hToolbarMenu;
-		RECT rc;
-		POINT pt;
-		HICON hIcon;
-		TabControlData tcd;
-		TitleBarData tbd;
-		wchar_t szTemp[512];
+INT_PTR CChatRoomDlg::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+	static HMENU hToolbarMenu;
+	RECT rc;
+	POINT pt;
+	HICON hIcon;
+	TabControlData tcd;
+	TitleBarData tbd;
+	wchar_t szTemp[512];
 
-		switch (uMsg) {
-		case GC_SETWNDPROPS:
-			// LoadGlobalSettings();
-			InitButtons(m_hwnd, m_si);
+	switch (uMsg) {
+	case GC_SETWNDPROPS:
+		// LoadGlobalSettings();
+		InitButtons(m_hwnd, m_si);
 
-			SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
-			SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
-			SendMessage(m_hwnd, GC_FIXTABICONS, 0, 0);
+		SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
+		SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
+		SendMessage(m_hwnd, GC_FIXTABICONS, 0, 0);
+
+		m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground);
+
+		// messagebox
+		COLORREF crFore;
+		LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &crFore);
+
+		CHARFORMAT2 cf;
+		cf.cbSize = sizeof(CHARFORMAT2);
+		cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_UNDERLINE | CFM_BACKCOLOR;
+		cf.dwEffects = 0;
+		cf.crTextColor = crFore;
+		cf.crBackColor = db_get_dw(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+		m_message.SendMsg(EM_SETBKGNDCOLOR, 0, db_get_dw(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR));
+		m_message.SendMsg(WM_SETFONT, (WPARAM)g_Settings.MessageBoxFont, MAKELPARAM(TRUE, 0));
+		m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+		{
+			// nicklist
+			int ih = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListFont, FALSE);
+			int ih2 = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListHeadingsFont, FALSE);
+			int height = db_get_b(NULL, CHAT_MODULE, "NicklistRowDist", 12);
+			int font = ih > ih2 ? ih : ih2;
+			// make sure we have space for icon!
+			if (db_get_b(NULL, CHAT_MODULE, "ShowContactStatus", 0))
+				font = font > 16 ? font : 16;
+
+			m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font);
+			InvalidateRect(m_nickList.GetHwnd(), NULL, TRUE);
+		}
+		m_message.SendMsg(EM_REQUESTRESIZE, 0, 0);
+		SendMessage(m_hwnd, WM_SIZE, 0, 0);
+		SendMessage(m_hwnd, GC_REDRAWLOG2, 0, 0);
+		break;
 
-			m_log.SendMsg(EM_SETBKGNDCOLOR, 0, g_Settings.crLogBackground);
-			{
-				// messagebox
-				COLORREF crFore;
-				LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &crFore);
+	case DM_UPDATETITLEBAR:
+		if (g_dat.flags & SMF_STATUSICON) {
+			MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
+			tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon;
+			tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig;
+		}
+		else {
+			tbd.hIcon = GetCachedIcon("chat_window");
+			tbd.hIconBig = g_dat.hIconChatBig;
+		}
+		tbd.hIconNot = (m_si->wState & (GC_EVENT_HIGHLIGHT | STATE_TALK)) ? GetCachedIcon("chat_overlay") : NULL;
 
-				CHARFORMAT2 cf;
-				cf.cbSize = sizeof(CHARFORMAT2);
-				cf.dwMask = CFM_COLOR | CFM_BOLD | CFM_UNDERLINE | CFM_BACKCOLOR;
-				cf.dwEffects = 0;
-				cf.crTextColor = crFore;
-				cf.crBackColor = db_get_dw(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
-				m_message.SendMsg(EM_SETBKGNDCOLOR, 0, db_get_dw(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR));
-				m_message.SendMsg(WM_SETFONT, (WPARAM)g_Settings.MessageBoxFont, MAKELPARAM(TRUE, 0));
-				m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
-
-				// nicklist
-				int ih = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListFont, FALSE);
-				int ih2 = GetTextPixelSize(L"AQG_glo'", g_Settings.UserListHeadingsFont, FALSE);
-				int height = db_get_b(NULL, CHAT_MODULE, "NicklistRowDist", 12);
-				int font = ih > ih2 ? ih : ih2;
-				// make sure we have space for icon!
-				if (db_get_b(NULL, CHAT_MODULE, "ShowContactStatus", 0))
-					font = font > 16 ? font : 16;
-
-				m_nickList.SendMsg(LB_SETITEMHEIGHT, 0, height > font ? height : font);
-				InvalidateRect(m_nickList.GetHwnd(), NULL, TRUE);
-			}
-			m_message.SendMsg(EM_REQUESTRESIZE, 0, 0);
-			SendMessage(m_hwnd, WM_SIZE, 0, 0);
-			SendMessage(m_hwnd, GC_REDRAWLOG2, 0, 0);
+		switch (m_si->iType) {
+		case GCW_CHATROOM:
+			mir_snwprintf(szTemp,
+				(m_si->nUsersInNicklist == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"),
+				m_si->ptszName, m_si->nUsersInNicklist);
 			break;
-
-		case DM_UPDATETITLEBAR:
-			if (g_dat.flags & SMF_STATUSICON) {
-				MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
-				tbd.hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIcon : mi->hOfflineIcon;
-				tbd.hIconBig = (m_si->wStatus == ID_STATUS_ONLINE) ? mi->hOnlineIconBig : mi->hOfflineIconBig;
-			}
-			else {
-				tbd.hIcon = GetCachedIcon("chat_window");
-				tbd.hIconBig = g_dat.hIconChatBig;
-			}
-			tbd.hIconNot = (m_si->wState & (GC_EVENT_HIGHLIGHT | STATE_TALK)) ? GetCachedIcon("chat_overlay") : NULL;
-
-			switch (m_si->iType) {
-			case GCW_CHATROOM:
-				mir_snwprintf(szTemp,
-					(m_si->nUsersInNicklist == 1) ? TranslateT("%s: chat room (%u user)") : TranslateT("%s: chat room (%u users)"),
-					m_si->ptszName, m_si->nUsersInNicklist);
-				break;
-			case GCW_PRIVMESS:
-				mir_snwprintf(szTemp,
-					(m_si->nUsersInNicklist == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"),
-					m_si->ptszName, m_si->nUsersInNicklist);
-				break;
-			case GCW_SERVER:
-				mir_snwprintf(szTemp, L"%s: Server", m_si->ptszName);
-				break;
-			}
-			tbd.iFlags = TBDF_TEXT | TBDF_ICON;
-			tbd.pszText = szTemp;
-			SendMessage(m_hwndParent, CM_UPDATETITLEBAR, (WPARAM)&tbd, (LPARAM)m_hwnd);
-			SendMessage(m_hwnd, DM_UPDATETABCONTROL, 0, 0);
+		case GCW_PRIVMESS:
+			mir_snwprintf(szTemp,
+				(m_si->nUsersInNicklist == 1) ? TranslateT("%s: message session") : TranslateT("%s: message session (%u users)"),
+				m_si->ptszName, m_si->nUsersInNicklist);
 			break;
-
-		case GC_UPDATESTATUSBAR:
-			{
-				MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
-				hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon;
-				mir_snwprintf(szTemp, L"%s : %s", mi->ptszModDispName, m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L"");
-
-				StatusBarData sbd;
-				sbd.iItem = 0;
-				sbd.iFlags = SBDF_TEXT | SBDF_ICON;
-				sbd.hIcon = hIcon;
-				sbd.pszText = szTemp;
-				SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd);
-
-				sbd.iItem = 1;
-				sbd.hIcon = NULL;
-				sbd.pszText = L"";
-				SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd);
-
-				StatusIconData sid = { sizeof(sid) };
-				sid.szModule = SRMMMOD;
-				Srmm_ModifyIcon(m_hContact, &sid);
-			}
+		case GCW_SERVER:
+			mir_snwprintf(szTemp, L"%s: Server", m_si->ptszName);
 			break;
+		}
+		tbd.iFlags = TBDF_TEXT | TBDF_ICON;
+		tbd.pszText = szTemp;
+		SendMessage(m_hwndParent, CM_UPDATETITLEBAR, (WPARAM)&tbd, (LPARAM)m_hwnd);
+		SendMessage(m_hwnd, DM_UPDATETABCONTROL, 0, 0);
+		break;
 
-		case DM_SWITCHINFOBAR:
-		case DM_SWITCHTOOLBAR:
-			SendMessage(m_hwnd, WM_SIZE, 0, 0);
-			break;
+	case GC_UPDATESTATUSBAR:
+		{
+			MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
+			hIcon = m_si->wStatus == ID_STATUS_ONLINE ? mi->hOnlineIcon : mi->hOfflineIcon;
+			mir_snwprintf(szTemp, L"%s : %s", mi->ptszModDispName, m_si->ptszStatusbarText ? m_si->ptszStatusbarText : L"");
+
+			StatusBarData sbd;
+			sbd.iItem = 0;
+			sbd.iFlags = SBDF_TEXT | SBDF_ICON;
+			sbd.hIcon = hIcon;
+			sbd.pszText = szTemp;
+			SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd);
+
+			sbd.iItem = 1;
+			sbd.hIcon = NULL;
+			sbd.pszText = L"";
+			SendMessage(m_hwndParent, CM_UPDATESTATUSBAR, (WPARAM)&sbd, (LPARAM)m_hwnd);
+
+			StatusIconData sid = { sizeof(sid) };
+			sid.szModule = SRMMMOD;
+			Srmm_ModifyIcon(m_hContact, &sid);
+		}
+		break;
 
-		case WM_SIZE:
-			if (wParam == SIZE_MAXIMIZED)
-				PostMessage(m_hwnd, GC_SCROLLTOBOTTOM, 0, 0);
+	case DM_SWITCHINFOBAR:
+	case DM_SWITCHTOOLBAR:
+		SendMessage(m_hwnd, WM_SIZE, 0, 0);
+		break;
 
-			if (IsIconic(m_hwnd)) break;
+	case WM_SIZE:
+		if (wParam == SIZE_MAXIMIZED)
+			PostMessage(m_hwnd, GC_SCROLLTOBOTTOM, 0, 0);
 
-			if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED) {
-				GetClientRect(m_hwnd, &rc);
-				MessageDialogResize(rc.right - rc.left, rc.bottom - rc.top);
-			}
-			break;
+		if (IsIconic(m_hwnd)) break;
 
-		case GC_REDRAWWINDOW:
-			InvalidateRect(m_hwnd, NULL, TRUE);
-			break;
+		if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED) {
+			GetClientRect(m_hwnd, &rc);
+			MessageDialogResize(rc.right - rc.left, rc.bottom - rc.top);
+		}
+		break;
 
-		case GC_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 == NULL)
-							break;
-
-						pLog = pLog->next;
-						if ((m_si->iType != GCW_CHATROOM && m_si->iType != GCW_PRIVMESS) || !m_si->bFilterEnabled || (m_si->iLogFilterFlags&pLog->iType) != 0)
-							index++;
-					}
-					Log_StreamInEvent(m_hwnd, pLog, m_si, TRUE);
-					mir_forkthread(phase2, m_si);
+	case GC_REDRAWWINDOW:
+		InvalidateRect(m_hwnd, NULL, TRUE);
+		break;
+
+	case GC_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 == NULL)
+						break;
+
+					pLog = pLog->next;
+					if ((m_si->iType != GCW_CHATROOM && m_si->iType != GCW_PRIVMESS) || !m_si->bFilterEnabled || (m_si->iLogFilterFlags&pLog->iType) != 0)
+						index++;
 				}
-				else Log_StreamInEvent(m_hwnd, m_si->pLogEnd, m_si, TRUE);
+				Log_StreamInEvent(m_hwnd, pLog, m_si, TRUE);
+				mir_forkthread(phase2, m_si);
 			}
-			else SendMessage(m_hwnd, GC_CONTROL_MSG, WINDOW_CLEARLOG, 0);
-			break;
+			else Log_StreamInEvent(m_hwnd, m_si->pLogEnd, m_si, TRUE);
+		}
+		else SendMessage(m_hwnd, GC_CONTROL_MSG, WINDOW_CLEARLOG, 0);
+		break;
 
-		case GC_REDRAWLOG2:
-			m_si->LastTime = 0;
-			if (m_si->pLog)
-				Log_StreamInEvent(m_hwnd, m_si->pLogEnd, m_si, TRUE);
-			break;
+	case GC_REDRAWLOG2:
+		m_si->LastTime = 0;
+		if (m_si->pLog)
+			Log_StreamInEvent(m_hwnd, m_si->pLogEnd, m_si, TRUE);
+		break;
 
-		case GC_ADDLOG:
-			if (m_si->pLogEnd)
-				Log_StreamInEvent(m_hwnd, m_si->pLog, m_si, FALSE);
+	case GC_ADDLOG:
+		if (m_si->pLogEnd)
+			Log_StreamInEvent(m_hwnd, m_si->pLog, m_si, FALSE);
+		else
+			SendMessage(m_hwnd, GC_CONTROL_MSG, WINDOW_CLEARLOG, 0);
+		break;
+
+	case DM_UPDATETABCONTROL:
+		tcd.iFlags = TCDF_TEXT;
+		tcd.pszText = m_si->ptszName;
+		SendMessage(m_hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)m_hwnd);
+		// fall through
+
+	case GC_FIXTABICONS:
+		if (!(m_si->wState & GC_EVENT_HIGHLIGHT)) {
+			if (m_si->wState & STATE_TALK)
+				hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineTalkIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineTalkIcon;
 			else
-				SendMessage(m_hwnd, GC_CONTROL_MSG, WINDOW_CLEARLOG, 0);
-			break;
+				hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineIcon;
+		}
+		else hIcon = g_dat.hMsgIcon;
 
-		case DM_UPDATETABCONTROL:
-			tcd.iFlags = TCDF_TEXT;
-			tcd.pszText = m_si->ptszName;
-			SendMessage(m_hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)m_hwnd);
-			// fall through
+		tcd.iFlags = TCDF_ICON;
+		tcd.hIcon = hIcon;
+		SendMessage(m_hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)m_hwnd);
+		break;
 
-		case GC_FIXTABICONS:
-			if (!(m_si->wState & GC_EVENT_HIGHLIGHT)) {
-				if (m_si->wState & STATE_TALK)
-					hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineTalkIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineTalkIcon;
-				else
-					hIcon = (m_si->wStatus == ID_STATUS_ONLINE) ? pci->MM_FindModule(m_si->pszModule)->hOnlineIcon : pci->MM_FindModule(m_si->pszModule)->hOfflineIcon;
-			}
-			else hIcon = g_dat.hMsgIcon;
+	case GC_SETMESSAGEHIGHLIGHT:
+		m_si->wState |= GC_EVENT_HIGHLIGHT;
+		SendMessage(m_si->hWnd, GC_FIXTABICONS, 0, 0);
+		SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
+		if (g_Settings.bFlashWindowHighlight && GetActiveWindow() != m_hwnd && GetForegroundWindow() != m_hwndParent)
+			SendMessage(GetParent(m_si->hWnd), CM_STARTFLASHING, 0, 0);
+		break;
 
-			tcd.iFlags = TCDF_ICON;
-			tcd.hIcon = hIcon;
-			SendMessage(m_hwndParent, CM_UPDATETABCONTROL, (WPARAM)&tcd, (LPARAM)m_hwnd);
-			break;
+	case GC_SETTABHIGHLIGHT:
+		SendMessage(m_si->hWnd, GC_FIXTABICONS, 0, 0);
+		SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
+		if (g_Settings.bFlashWindow && GetActiveWindow() != m_hwndParent && GetForegroundWindow() != m_hwndParent)
+			SendMessage(GetParent(m_si->hWnd), CM_STARTFLASHING, 0, 0);
+		break;
 
-		case GC_SETMESSAGEHIGHLIGHT:
-			m_si->wState |= GC_EVENT_HIGHLIGHT;
-			SendMessage(m_si->hWnd, GC_FIXTABICONS, 0, 0);
-			SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
-			if (g_Settings.bFlashWindowHighlight && GetActiveWindow() != m_hwnd && GetForegroundWindow() != m_hwndParent)
-				SendMessage(GetParent(m_si->hWnd), CM_STARTFLASHING, 0, 0);
-			break;
+	case DM_ACTIVATE:
+		if (m_si->wState & STATE_TALK) {
+			m_si->wState &= ~STATE_TALK;
+			db_set_w(m_hContact, m_si->pszModule, "ApparentMode", 0);
+		}
 
-		case GC_SETTABHIGHLIGHT:
-			SendMessage(m_si->hWnd, GC_FIXTABICONS, 0, 0);
-			SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
-			if (g_Settings.bFlashWindow && GetActiveWindow() != m_hwndParent && GetForegroundWindow() != m_hwndParent)
-				SendMessage(GetParent(m_si->hWnd), CM_STARTFLASHING, 0, 0);
-			break;
+		if (m_si->wState & GC_EVENT_HIGHLIGHT) {
+			m_si->wState &= ~GC_EVENT_HIGHLIGHT;
 
-		case DM_ACTIVATE:
-			if (m_si->wState & STATE_TALK) {
-				m_si->wState &= ~STATE_TALK;
-				db_set_w(m_hContact, m_si->pszModule, "ApparentMode", 0);
-			}
+			if (pcli->pfnGetEvent(m_hContact, 0))
+				pcli->pfnRemoveEvent(m_hContact, GC_FAKE_EVENT);
+		}
 
-			if (m_si->wState & GC_EVENT_HIGHLIGHT) {
-				m_si->wState &= ~GC_EVENT_HIGHLIGHT;
+		SendMessage(m_hwnd, GC_FIXTABICONS, 0, 0);
+		if (!m_si->hWnd) {
+			ShowRoom(m_si);
+			SendMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0);
+		}
+		break;
 
-				if (pcli->pfnGetEvent(m_hContact, 0))
-					pcli->pfnRemoveEvent(m_hContact, GC_FAKE_EVENT);
-			}
+	case WM_CTLCOLORLISTBOX:
+		SetBkColor((HDC)wParam, g_Settings.crUserListBGColor);
+		return (INT_PTR)pci->hListBkgBrush;
 
-			SendMessage(m_hwnd, GC_FIXTABICONS, 0, 0);
-			if (!m_si->hWnd) {
-				ShowRoom(m_si);
-				SendMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0);
-			}
-			break;
+	case WM_MEASUREITEM:
+		if (!MeasureMenuItem(wParam, lParam)) {
+			MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
+			if (mis->CtlType == ODT_MENU)
+				return Menu_MeasureItem(lParam);
 
-		case WM_CTLCOLORLISTBOX:
-			SetBkColor((HDC)wParam, g_Settings.crUserListBGColor);
-			return (INT_PTR)pci->hListBkgBrush;
-
-		case WM_MEASUREITEM:
-			if (!MeasureMenuItem(wParam, lParam)) {
-				MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
-				if (mis->CtlType == ODT_MENU)
-					return Menu_MeasureItem(lParam);
-
-				int ih = GetTextPixelSize(L"AQGgl'", g_Settings.UserListFont, FALSE);
-				int ih2 = GetTextPixelSize(L"AQGg'", g_Settings.UserListHeadingsFont, FALSE);
-				int font = ih > ih2 ? ih : ih2;
-				int height = db_get_b(NULL, CHAT_MODULE, "NicklistRowDist", 12);
-				// make sure we have space for icon!
-				if (db_get_b(NULL, CHAT_MODULE, "ShowContactStatus", 0))
-					font = font > 16 ? font : 16;
-				mis->itemHeight = height > font ? height : font;
-			}
-			return TRUE;
+			int ih = GetTextPixelSize(L"AQGgl'", g_Settings.UserListFont, FALSE);
+			int ih2 = GetTextPixelSize(L"AQGg'", g_Settings.UserListHeadingsFont, FALSE);
+			int font = ih > ih2 ? ih : ih2;
+			int height = db_get_b(NULL, CHAT_MODULE, "NicklistRowDist", 12);
+			// make sure we have space for icon!
+			if (db_get_b(NULL, CHAT_MODULE, "ShowContactStatus", 0))
+				font = font > 16 ? font : 16;
+			mis->itemHeight = height > font ? height : font;
+		}
+		return TRUE;
 
-		case WM_DRAWITEM:
-			if (!DrawMenuItem(wParam, lParam)) {
-				DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
-				if (dis->CtlType == ODT_MENU)
-					return Menu_DrawItem(lParam);
-
-				if (dis->CtlID == IDC_CHAT_LIST) {
-					int index = dis->itemID;
-					USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, index);
-					if (ui) {
-						int x_offset = 2;
-
-						int height = dis->rcItem.bottom - dis->rcItem.top;
-						if (height & 1)
-							height++;
-
-						int offset = (height == 10) ? 0 : height / 2 - 5;
-						HFONT hFont = (ui->iStatusEx == 0) ? g_Settings.UserListFont : g_Settings.UserListHeadingsFont;
-						HFONT hOldFont = (HFONT)SelectObject(dis->hDC, hFont);
-						SetBkMode(dis->hDC, TRANSPARENT);
-
-						if (dis->itemAction == ODA_FOCUS && dis->itemState & ODS_SELECTED)
-							FillRect(dis->hDC, &dis->rcItem, pci->hListSelectedBkgBrush);
-						else //if (dis->itemState & ODS_INACTIVE)
-							FillRect(dis->hDC, &dis->rcItem, pci->hListBkgBrush);
-
-						if (g_Settings.bShowContactStatus && g_Settings.bContactStatusFirst && ui->ContactStatus) {
-							hIcon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus);
-							DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 3, hIcon, 16, 16, 0, NULL, DI_NORMAL);
-							IcoLib_ReleaseIcon(hIcon);
-							x_offset += 18;
-						}
-						DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset, pci->SM_GetStatusIcon(m_si, ui), 10, 10, 0, NULL, DI_NORMAL);
-						x_offset += 12;
-						if (g_Settings.bShowContactStatus && !g_Settings.bContactStatusFirst && ui->ContactStatus) {
-							hIcon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus);
-							DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 3, hIcon, 16, 16, 0, NULL, DI_NORMAL);
-							IcoLib_ReleaseIcon(hIcon);
-							x_offset += 18;
-						}
-
-						SetTextColor(dis->hDC, ui->iStatusEx == 0 ? g_Settings.crUserListColor : g_Settings.crUserListHeadingsColor);
-						TextOut(dis->hDC, dis->rcItem.left + x_offset, dis->rcItem.top, ui->pszNick, (int)mir_wstrlen(ui->pszNick));
-						SelectObject(dis->hDC, hOldFont);
-					}
-					return TRUE;
-				}
-			}
-			break;
+	case WM_DRAWITEM:
+		if (!DrawMenuItem(wParam, lParam)) {
+			DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
+			if (dis->CtlType == ODT_MENU)
+				return Menu_DrawItem(lParam);
 
-		case GC_UPDATENICKLIST:
-			m_nickList.SendMsg(WM_SETREDRAW, FALSE, 0);
-			m_nickList.SendMsg(LB_RESETCONTENT, 0, 0);
-			for (int index = 0; index < m_si->nUsersInNicklist; index++) {
+			if (dis->CtlID == IDC_CHAT_LIST) {
+				int index = dis->itemID;
 				USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, index);
 				if (ui) {
-					char szIndicator = SM_GetStatusIndicator(m_si, ui);
-					if (szIndicator > '\0') {
-						static wchar_t ptszBuf[128];
-						mir_snwprintf(ptszBuf, L"%c%s", szIndicator, ui->pszNick);
-						m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ptszBuf);
+					int x_offset = 2;
+
+					int height = dis->rcItem.bottom - dis->rcItem.top;
+					if (height & 1)
+						height++;
+
+					int offset = (height == 10) ? 0 : height / 2 - 5;
+					HFONT hFont = (ui->iStatusEx == 0) ? g_Settings.UserListFont : g_Settings.UserListHeadingsFont;
+					HFONT hOldFont = (HFONT)SelectObject(dis->hDC, hFont);
+					SetBkMode(dis->hDC, TRANSPARENT);
+
+					if (dis->itemAction == ODA_FOCUS && dis->itemState & ODS_SELECTED)
+						FillRect(dis->hDC, &dis->rcItem, pci->hListSelectedBkgBrush);
+					else //if (dis->itemState & ODS_INACTIVE)
+						FillRect(dis->hDC, &dis->rcItem, pci->hListBkgBrush);
+
+					if (g_Settings.bShowContactStatus && g_Settings.bContactStatusFirst && ui->ContactStatus) {
+						hIcon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus);
+						DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 3, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+						IcoLib_ReleaseIcon(hIcon);
+						x_offset += 18;
 					}
-					else m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ui->pszNick);
+					DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset, pci->SM_GetStatusIcon(m_si, ui), 10, 10, 0, NULL, DI_NORMAL);
+					x_offset += 12;
+					if (g_Settings.bShowContactStatus && !g_Settings.bContactStatusFirst && ui->ContactStatus) {
+						hIcon = Skin_LoadProtoIcon(m_si->pszModule, ui->ContactStatus);
+						DrawIconEx(dis->hDC, x_offset, dis->rcItem.top + offset - 3, hIcon, 16, 16, 0, NULL, DI_NORMAL);
+						IcoLib_ReleaseIcon(hIcon);
+						x_offset += 18;
+					}
+
+					SetTextColor(dis->hDC, ui->iStatusEx == 0 ? g_Settings.crUserListColor : g_Settings.crUserListHeadingsColor);
+					TextOut(dis->hDC, dis->rcItem.left + x_offset, dis->rcItem.top, ui->pszNick, (int)mir_wstrlen(ui->pszNick));
+					SelectObject(dis->hDC, hOldFont);
 				}
+				return TRUE;
 			}
-			m_nickList.SendMsg(WM_SETREDRAW, TRUE, 0);
-			InvalidateRect(m_nickList.GetHwnd(), NULL, FALSE);
-			UpdateWindow(m_nickList.GetHwnd());
-			SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
-			break;
+		}
+		break;
 
-		case GC_CONTROL_MSG:
-			switch (wParam) {
-			case SESSION_OFFLINE:
-				SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
-				SendMessage(m_si->hWnd, GC_UPDATENICKLIST, 0, 0);
-				return TRUE;
+	case GC_UPDATENICKLIST:
+		m_nickList.SendMsg(WM_SETREDRAW, FALSE, 0);
+		m_nickList.SendMsg(LB_RESETCONTENT, 0, 0);
+		for (int index = 0; index < m_si->nUsersInNicklist; index++) {
+			USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, index);
+			if (ui) {
+				char szIndicator = SM_GetStatusIndicator(m_si, ui);
+				if (szIndicator > '\0') {
+					static wchar_t ptszBuf[128];
+					mir_snwprintf(ptszBuf, L"%c%s", szIndicator, ui->pszNick);
+					m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ptszBuf);
+				}
+				else m_nickList.SendMsg(LB_ADDSTRING, 0, (LPARAM)ui->pszNick);
+			}
+		}
+		m_nickList.SendMsg(WM_SETREDRAW, TRUE, 0);
+		InvalidateRect(m_nickList.GetHwnd(), NULL, FALSE);
+		UpdateWindow(m_nickList.GetHwnd());
+		SendMessage(m_hwnd, DM_UPDATETITLEBAR, 0, 0);
+		break;
 
-			case SESSION_ONLINE:
-				SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
-				return TRUE;
+	case GC_CONTROL_MSG:
+		switch (wParam) {
+		case SESSION_OFFLINE:
+			SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
+			SendMessage(m_si->hWnd, GC_UPDATENICKLIST, 0, 0);
+			return TRUE;
 
-			case WINDOW_HIDDEN:
-				SendMessage(m_hwnd, GC_CLOSEWINDOW, 0, 0);
-				return TRUE;
+		case SESSION_ONLINE:
+			SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
+			return TRUE;
 
-			case WINDOW_CLEARLOG:
-				m_log.SetText(L"");
-				return TRUE;
+		case WINDOW_HIDDEN:
+			SendMessage(m_hwnd, GC_CLOSEWINDOW, 0, 0);
+			return TRUE;
 
-			case SESSION_TERMINATE:
-				if (pcli->pfnGetEvent(m_hContact, 0))
-					pcli->pfnRemoveEvent(m_hContact, GC_FAKE_EVENT);
-				m_si->wState &= ~STATE_TALK;
-				db_set_w(m_hContact, m_si->pszModule, "ApparentMode", 0);
-				SendMessage(m_hwnd, GC_CLOSEWINDOW, 0, 0);
-				return TRUE;
+		case WINDOW_CLEARLOG:
+			m_log.SetText(L"");
+			return TRUE;
 
-			case WINDOW_MINIMIZE:
-				ShowWindow(m_hwnd, SW_MINIMIZE);
-				goto LABEL_SHOWWINDOW;
+		case SESSION_TERMINATE:
+			if (pcli->pfnGetEvent(m_hContact, 0))
+				pcli->pfnRemoveEvent(m_hContact, GC_FAKE_EVENT);
+			m_si->wState &= ~STATE_TALK;
+			db_set_w(m_hContact, m_si->pszModule, "ApparentMode", 0);
+			SendMessage(m_hwnd, GC_CLOSEWINDOW, 0, 0);
+			return TRUE;
 
-			case WINDOW_MAXIMIZE:
-				ShowWindow(m_hwnd, SW_MAXIMIZE);
-				goto LABEL_SHOWWINDOW;
+		case WINDOW_MINIMIZE:
+			ShowWindow(m_hwnd, SW_MINIMIZE);
+			goto LABEL_SHOWWINDOW;
 
-			case SESSION_INITDONE:
-				if (db_get_b(NULL, CHAT_MODULE, "PopupOnJoin", 0) != 0)
-					return TRUE;
-				// fall through
-			case WINDOW_VISIBLE:
-				if (IsIconic(m_hwnd))
-					ShowWindow(m_hwnd, SW_NORMAL);
-			LABEL_SHOWWINDOW:
-				SendMessage(m_hwnd, WM_SIZE, 0, 0);
-				SendMessage(m_hwnd, GC_REDRAWLOG, 0, 0);
-				SendMessage(m_hwnd, GC_UPDATENICKLIST, 0, 0);
-				SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
-				ShowWindow(m_hwnd, SW_SHOW);
-				SendMessage(m_hwnd, WM_SIZE, 0, 0);
-				SetForegroundWindow(m_hwnd);
+		case WINDOW_MAXIMIZE:
+			ShowWindow(m_hwnd, SW_MAXIMIZE);
+			goto LABEL_SHOWWINDOW;
+
+		case SESSION_INITDONE:
+			if (db_get_b(NULL, CHAT_MODULE, "PopupOnJoin", 0) != 0)
 				return TRUE;
-			}
-			break;
+			// fall through
+		case WINDOW_VISIBLE:
+			if (IsIconic(m_hwnd))
+				ShowWindow(m_hwnd, SW_NORMAL);
+		LABEL_SHOWWINDOW:
+			SendMessage(m_hwnd, WM_SIZE, 0, 0);
+			SendMessage(m_hwnd, GC_REDRAWLOG, 0, 0);
+			SendMessage(m_hwnd, GC_UPDATENICKLIST, 0, 0);
+			SendMessage(m_hwnd, GC_UPDATESTATUSBAR, 0, 0);
+			ShowWindow(m_hwnd, SW_SHOW);
+			SendMessage(m_hwnd, WM_SIZE, 0, 0);
+			SetForegroundWindow(m_hwnd);
+			return TRUE;
+		}
+		break;
 
-		case GC_SPLITTERMOVED:
-			if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERX)) {
-				GetClientRect(m_hwnd, &rc);
-				pt.x = wParam; pt.y = 0;
-				ScreenToClient(m_hwnd, &pt);
-
-				m_si->iSplitterX = rc.right - pt.x + 1;
-				if (m_si->iSplitterX < 35)
-					m_si->iSplitterX = 35;
-				if (m_si->iSplitterX > rc.right - rc.left - 35)
-					m_si->iSplitterX = rc.right - rc.left - 35;
-				g_Settings.iSplitterX = m_si->iSplitterX;
-			}
-			else if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERY)) {
-				GetClientRect(m_hwnd, &rc);
-				pt.x = 0; pt.y = wParam;
-				ScreenToClient(m_hwnd, &pt);
-				m_si->iSplitterY = rc.bottom - pt.y;
-				g_Settings.iSplitterY = m_si->iSplitterY;
+	case GC_FIREHOOK:
+		if (lParam) {
+			NotifyEventHooks(pci->hSendEvent, 0, lParam);
+			GCHOOK *gch = (GCHOOK*)lParam;
+			if (gch->pDest) {
+				mir_free((void*)gch->pDest->ptszID);
+				mir_free((void*)gch->pDest->pszModule);
+				mir_free(gch->pDest);
 			}
-			PostMessage(m_hwnd, WM_SIZE, 0, 0);
-			break;
+			mir_free(gch->ptszText);
+			mir_free(gch->ptszUID);
+			mir_free(gch->ptszNick);
+			mir_free(gch);
+		}
+		break;
 
-		case GC_FIREHOOK:
-			if (lParam) {
-				NotifyEventHooks(pci->hSendEvent, 0, lParam);
-				GCHOOK *gch = (GCHOOK*)lParam;
-				if (gch->pDest) {
-					mir_free((void*)gch->pDest->ptszID);
-					mir_free((void*)gch->pDest->pszModule);
-					mir_free(gch->pDest);
-				}
-				mir_free(gch->ptszText);
-				mir_free(gch->ptszUID);
-				mir_free(gch->ptszNick);
-				mir_free(gch);
-			}
-			break;
+	case GC_CHANGEFILTERFLAG:
+		m_si->iLogFilterFlags = lParam;
+		break;
 
-		case GC_CHANGEFILTERFLAG:
-			m_si->iLogFilterFlags = lParam;
-			break;
+	case GC_SHOWFILTERMENU:
+		{
+			HWND hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)m_si);
+			TranslateDialogDefault(hwnd);
+			GetWindowRect(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), &rc);
+			SetWindowPos(hwnd, HWND_TOP, rc.left - 85, (IsWindowVisible(GetDlgItem(m_hwnd, IDC_CHAT_FILTER)) || IsWindowVisible(GetDlgItem(m_hwnd, IDC_CHAT_BOLD))) ? rc.top - 206 : rc.top - 186, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
+		}
+		break;
 
-		case GC_SHOWFILTERMENU:
-			{
-				HWND hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_FILTER), m_hwnd, FilterWndProc, (LPARAM)m_si);
-				TranslateDialogDefault(hwnd);
-				GetWindowRect(GetDlgItem(m_hwnd, IDC_CHAT_FILTER), &rc);
-				SetWindowPos(hwnd, HWND_TOP, rc.left - 85, (IsWindowVisible(GetDlgItem(m_hwnd, IDC_CHAT_FILTER)) || IsWindowVisible(GetDlgItem(m_hwnd, IDC_CHAT_BOLD))) ? rc.top - 206 : rc.top - 186, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
-			}
-			break;
+	case GC_SHOWCOLORCHOOSER:
+		pci->ColorChooser(m_si, lParam == IDC_CHAT_COLOR, m_hwnd, m_message.GetHwnd(), GetDlgItem(m_hwnd, lParam));
+		break;
 
-		case GC_SHOWCOLORCHOOSER:
-			pci->ColorChooser(m_si, lParam == IDC_CHAT_COLOR, m_hwnd, m_message.GetHwnd(), GetDlgItem(m_hwnd, lParam));
-			break;
+	case GC_SCROLLTOBOTTOM:
+		if ((GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) != 0) {
+			SCROLLINFO sci = { 0 };
+			sci.cbSize = sizeof(sci);
+			sci.fMask = SIF_PAGE | SIF_RANGE;
+			GetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci);
+
+			sci.fMask = SIF_POS;
+			sci.nPos = sci.nMax - sci.nPage + 1;
+			SetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci, TRUE);
+
+			CHARRANGE sel;
+			sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd(), CP_ACP, FALSE);
+			m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel);
+			PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
+		}
+		break;
 
-		case GC_SCROLLTOBOTTOM:
-			if ((GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) != 0) {
-				SCROLLINFO sci = { 0 };
-				sci.cbSize = sizeof(sci);
-				sci.fMask = SIF_PAGE | SIF_RANGE;
-				GetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci);
-
-				sci.fMask = SIF_POS;
-				sci.nPos = sci.nMax - sci.nPage + 1;
-				SetScrollInfo(m_log.GetHwnd(), SB_VERT, &sci, TRUE);
-
-				CHARRANGE sel;
-				sel.cpMin = sel.cpMax = GetRichTextLength(m_log.GetHwnd(), CP_ACP, FALSE);
-				m_log.SendMsg(EM_EXSETSEL, 0, (LPARAM)&sel);
-				PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
-			}
+	case WM_ACTIVATE:
+		if (LOWORD(wParam) != WA_ACTIVE)
 			break;
 
-		case WM_ACTIVATE:
-			if (LOWORD(wParam) != WA_ACTIVE)
-				break;
-
-			//fall through
-		case WM_MOUSEACTIVATE:
-			if (uMsg != WM_ACTIVATE)
-				SetFocus(m_message.GetHwnd());
+		//fall through
+	case WM_MOUSEACTIVATE:
+		if (uMsg != WM_ACTIVATE)
+			SetFocus(m_message.GetHwnd());
 
-			pci->SetActiveSession(m_si->ptszID, m_si->pszModule);
+		pci->SetActiveSession(m_si->ptszID, m_si->pszModule);
 
-			if (db_get_w(m_hContact, m_si->pszModule, "ApparentMode", 0) != 0)
-				db_set_w(m_hContact, m_si->pszModule, "ApparentMode", 0);
-			if (pcli->pfnGetEvent(m_hContact, 0))
-				pcli->pfnRemoveEvent(m_hContact, GC_FAKE_EVENT);
-			break;
-
-		case WM_NOTIFY:
-			{
-				LPNMHDR pNmhdr = (LPNMHDR)lParam;
-				switch (pNmhdr->code) {
-				case EN_REQUESTRESIZE:
-					if (pNmhdr->idFrom == IDC_MESSAGE) {
-						REQRESIZE *rr = (REQRESIZE *)lParam;
-						int height = rr->rc.bottom - rr->rc.top + 1;
-						if (height < g_dat.minInputAreaHeight)
-							height = g_dat.minInputAreaHeight;
-
-						if (m_si->desiredInputAreaHeight != height) {
-							m_si->desiredInputAreaHeight = height;
-							SendMessage(m_hwnd, WM_SIZE, 0, 0);
-							PostMessage(m_hwnd, GC_SCROLLTOBOTTOM, 0, 0);
-						}
-					}
-					break;
+		if (db_get_w(m_hContact, m_si->pszModule, "ApparentMode", 0) != 0)
+			db_set_w(m_hContact, m_si->pszModule, "ApparentMode", 0);
+		if (pcli->pfnGetEvent(m_hContact, 0))
+			pcli->pfnRemoveEvent(m_hContact, GC_FAKE_EVENT);
+		break;
 
-				case EN_MSGFILTER:
-					if (pNmhdr->idFrom == IDC_LOG && ((MSGFILTER *)lParam)->msg == WM_RBUTTONUP) {
-						SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE);
-						return TRUE;
-					}
-					break;
+	case WM_NOTIFY:
+		{
+			LPNMHDR pNmhdr = (LPNMHDR)lParam;
+			switch (pNmhdr->code) {
+			case EN_MSGFILTER:
+				if (pNmhdr->idFrom == IDC_LOG && ((MSGFILTER *)lParam)->msg == WM_RBUTTONUP) {
+					SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE);
+					return TRUE;
+				}
+				break;
 
-				case TTN_NEEDTEXT:
-					if (pNmhdr->idFrom == (UINT_PTR)m_nickList.GetHwnd()) {
-						LPNMTTDISPINFO lpttd = (LPNMTTDISPINFO)lParam;
-						SESSION_INFO* parentdat = (SESSION_INFO*)GetWindowLongPtr(m_hwnd, GWLP_USERDATA);
-
-						POINT p;
-						GetCursorPos(&p);
-						ScreenToClient(m_nickList.GetHwnd(), &p);
-						int item = LOWORD(m_nickList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(p.x, p.y)));
-						USERINFO *ui = pci->SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, item);
-						if (ui != NULL) {
-							static wchar_t ptszBuf[1024];
-							mir_snwprintf(ptszBuf, L"%s: %s\r\n%s: %s\r\n%s: %s",
-								TranslateT("Nickname"), ui->pszNick,
-								TranslateT("Unique ID"), ui->pszUID,
-								TranslateT("Status"), pci->TM_WordToString(parentdat->pStatuses, ui->Status));
-							lpttd->lpszText = ptszBuf;
-						}
+			case TTN_NEEDTEXT:
+				if (pNmhdr->idFrom == (UINT_PTR)m_nickList.GetHwnd()) {
+					LPNMTTDISPINFO lpttd = (LPNMTTDISPINFO)lParam;
+					SESSION_INFO* parentdat = (SESSION_INFO*)GetWindowLongPtr(m_hwnd, GWLP_USERDATA);
+
+					POINT p;
+					GetCursorPos(&p);
+					ScreenToClient(m_nickList.GetHwnd(), &p);
+					int item = LOWORD(m_nickList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(p.x, p.y)));
+					USERINFO *ui = pci->SM_GetUserFromIndex(parentdat->ptszID, parentdat->pszModule, item);
+					if (ui != NULL) {
+						static wchar_t ptszBuf[1024];
+						mir_snwprintf(ptszBuf, L"%s: %s\r\n%s: %s\r\n%s: %s",
+							TranslateT("Nickname"), ui->pszNick,
+							TranslateT("Unique ID"), ui->pszUID,
+							TranslateT("Status"), pci->TM_WordToString(parentdat->pStatuses, ui->Status));
+						lpttd->lpszText = ptszBuf;
 					}
-					break;
 				}
+				break;
 			}
+		}
+		break;
+
+	case WM_COMMAND:
+		if (!lParam && Clist_MenuProcessCommand(LOWORD(wParam), MPCF_CONTACTMENU, m_hContact))
 			break;
 
-		case WM_COMMAND:
-			if (!lParam && Clist_MenuProcessCommand(LOWORD(wParam), MPCF_CONTACTMENU, m_hContact))
+		if (HIWORD(wParam) == BN_CLICKED)
+			if (LOWORD(wParam) >= MIN_CBUTTONID && LOWORD(wParam) <= MAX_CBUTTONID) {
+				Srmm_ClickToolbarIcon(m_hContact, LOWORD(wParam), GetDlgItem(m_hwnd, LOWORD(wParam)), 0);
 				break;
+			}
 
-			if (HIWORD(wParam) == BN_CLICKED)
-				if (LOWORD(wParam) >= MIN_CBUTTONID && LOWORD(wParam) <= MAX_CBUTTONID) {
-					Srmm_ClickToolbarIcon(m_hContact, LOWORD(wParam), GetDlgItem(m_hwnd, LOWORD(wParam)), 0);
-					break;
-				}
+		switch (LOWORD(wParam)) {
+		case IDC_CHAT_LIST:
+			if (HIWORD(wParam) == LBN_DBLCLK) {
+				TVHITTESTINFO hti;
+				hti.pt.x = (short)LOWORD(GetMessagePos());
+				hti.pt.y = (short)HIWORD(GetMessagePos());
+				ScreenToClient(m_nickList.GetHwnd(), &hti.pt);
 
-			switch (LOWORD(wParam)) {
-			case IDC_CHAT_LIST:
-				if (HIWORD(wParam) == LBN_DBLCLK) {
-					TVHITTESTINFO hti;
-					hti.pt.x = (short)LOWORD(GetMessagePos());
-					hti.pt.y = (short)HIWORD(GetMessagePos());
-					ScreenToClient(m_nickList.GetHwnd(), &hti.pt);
-
-					int item = LOWORD(m_nickList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y)));
-					USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, item);
-					if (ui) {
-						if (GetKeyState(VK_SHIFT) & 0x8000) {
-							LRESULT lResult = (LRESULT)m_message.SendMsg(EM_GETSEL, 0, 0);
-							int start = LOWORD(lResult);
-							size_t dwNameLenMax = (mir_wstrlen(ui->pszUID) + 4);
-							wchar_t* pszName = (wchar_t*)alloca(sizeof(wchar_t) * dwNameLenMax);
-							if (start == 0)
-								mir_snwprintf(pszName, dwNameLenMax, L"%s: ", ui->pszUID);
-							else
-								mir_snwprintf(pszName, dwNameLenMax, L"%s ", ui->pszUID);
-
-							m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)pszName);
-							PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0);
-						}
-						else pci->DoEventHookAsync(m_hwnd, m_si->ptszID, m_si->pszModule, GC_USER_PRIVMESS, ui, nullptr, 0);
-					}
+				int item = LOWORD(m_nickList.SendMsg(LB_ITEMFROMPOINT, 0, MAKELPARAM(hti.pt.x, hti.pt.y)));
+				USERINFO *ui = pci->SM_GetUserFromIndex(m_si->ptszID, m_si->pszModule, item);
+				if (ui) {
+					if (GetKeyState(VK_SHIFT) & 0x8000) {
+						LRESULT lResult = (LRESULT)m_message.SendMsg(EM_GETSEL, 0, 0);
+						int start = LOWORD(lResult);
+						size_t dwNameLenMax = (mir_wstrlen(ui->pszUID) + 4);
+						wchar_t* pszName = (wchar_t*)alloca(sizeof(wchar_t) * dwNameLenMax);
+						if (start == 0)
+							mir_snwprintf(pszName, dwNameLenMax, L"%s: ", ui->pszUID);
+						else
+							mir_snwprintf(pszName, dwNameLenMax, L"%s ", ui->pszUID);
 
-					return TRUE;
+						m_message.SendMsg(EM_REPLACESEL, FALSE, (LPARAM)pszName);
+						PostMessage(m_hwnd, WM_MOUSEACTIVATE, 0, 0);
+					}
+					else pci->DoEventHookAsync(m_hwnd, m_si->ptszID, m_si->pszModule, GC_USER_PRIVMESS, ui, nullptr, 0);
 				}
 
-				if (HIWORD(wParam) == LBN_KILLFOCUS)
-					RedrawWindow(m_nickList.GetHwnd(), NULL, NULL, RDW_INVALIDATE);
-				break;
-
-			case IDOK:
-				if (IsWindowEnabled(GetDlgItem(m_hwnd, IDOK))) {
-					char *pszRtf = GetRichTextRTF(m_message.GetHwnd());
-					if (pszRtf == NULL)
-						break;
+				return TRUE;
+			}
 
-					MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
-					if (mi == NULL)
-						break;
+			if (HIWORD(wParam) == LBN_KILLFOCUS)
+				RedrawWindow(m_nickList.GetHwnd(), NULL, NULL, RDW_INVALIDATE);
+			break;
 
-					TCmdList *cmdListNew = tcmdlist_last(m_si->cmdList);
-					while (cmdListNew != NULL && cmdListNew->temporary) {
-						m_si->cmdList = tcmdlist_remove(m_si->cmdList, cmdListNew);
-						cmdListNew = tcmdlist_last(m_si->cmdList);
-					}
+		case IDOK:
+			if (IsWindowEnabled(GetDlgItem(m_hwnd, IDOK))) {
+				char *pszRtf = GetRichTextRTF(m_message.GetHwnd());
+				if (pszRtf == NULL)
+					break;
 
-					// takes pszRtf to a queue, no leak here
-					m_si->cmdList = tcmdlist_append(m_si->cmdList, pszRtf, 20, FALSE);
+				MODULEINFO *mi = pci->MM_FindModule(m_si->pszModule);
+				if (mi == NULL)
+					break;
 
-					CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf)));
-					pci->DoRtfToTags(ptszText, mi->nColorCount, mi->crColors);
-					ptszText.Trim();
-					ptszText.Replace(L"%", L"%%");
+				TCmdList *cmdListNew = tcmdlist_last(cmdList);
+				while (cmdListNew != NULL && cmdListNew->temporary) {
+					cmdList = tcmdlist_remove(cmdList, cmdListNew);
+					cmdListNew = tcmdlist_last(cmdList);
+				}
 
-					if (mi->bAckMsg) {
-						EnableWindow(m_message.GetHwnd(), FALSE);
-						m_message.SendMsg(EM_SETREADONLY, TRUE, 0);
-					}
-					else SetDlgItemText(m_hwnd, IDC_MESSAGE, L"");
+				// takes pszRtf to a queue, no leak here
+				cmdList = tcmdlist_append(cmdList, pszRtf, 20, FALSE);
 
-					EnableWindow(GetDlgItem(m_hwnd, IDOK), FALSE);
+				CMStringW ptszText(ptrW(mir_utf8decodeW(pszRtf)));
+				pci->DoRtfToTags(ptszText, mi->nColorCount, mi->crColors);
+				ptszText.Trim();
+				ptszText.Replace(L"%", L"%%");
 
-					pci->DoEventHookAsync(m_hwnd, m_si->ptszID, m_si->pszModule, GC_USER_MESSAGE, NULL, ptszText, 0);
-					SetFocus(m_message.GetHwnd());
+				if (mi->bAckMsg) {
+					EnableWindow(m_message.GetHwnd(), FALSE);
+					m_message.SendMsg(EM_SETREADONLY, TRUE, 0);
 				}
-				break;
+				else SetDlgItemText(m_hwnd, IDC_MESSAGE, L"");
 
-			case IDC_CHAT_SHOWNICKLIST:
-				if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_SHOWNICKLIST)))
-					break;
-				if (m_si->iType == GCW_SERVER)
-					break;
+				EnableWindow(GetDlgItem(m_hwnd, IDOK), FALSE);
 
-				m_si->bNicklistEnabled = !m_si->bNicklistEnabled;
+				pci->DoEventHookAsync(m_hwnd, m_si->ptszID, m_si->pszModule, GC_USER_MESSAGE, NULL, ptszText, 0);
+				SetFocus(m_message.GetHwnd());
+			}
+			break;
 
-				SendDlgItemMessage(m_hwnd, IDC_CHAT_SHOWNICKLIST, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_si->bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2"));
-				SendMessage(m_hwnd, GC_SCROLLTOBOTTOM, 0, 0);
-				SendMessage(m_hwnd, WM_SIZE, 0, 0);
+		case IDC_CHAT_SHOWNICKLIST:
+			if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_SHOWNICKLIST)))
 				break;
-
-			case IDC_MESSAGE:
-				if (HIWORD(wParam) == EN_CHANGE) {
-					m_si->cmdListCurrent = NULL;
-					EnableWindow(GetDlgItem(m_hwnd, IDOK), GetRichTextLength(m_message.GetHwnd(), 1200, FALSE) != 0);
-				}
+			if (m_si->iType == GCW_SERVER)
 				break;
 
-			case IDC_HISTORY:
-				if (IsWindowEnabled(GetDlgItem(m_hwnd, IDC_HISTORY))) {
-					MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
-					if (pInfo)
-						ShellExecute(m_hwnd, NULL, pci->GetChatLogsFilename(m_si, 0), NULL, NULL, SW_SHOW);
-				}
-				break;
+			m_si->bNicklistEnabled = !m_si->bNicklistEnabled;
 
-			case IDC_CHAT_CHANMGR:
-				if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_CHANMGR)))
-					break;
-				pci->DoEventHookAsync(m_hwnd, m_si->ptszID, m_si->pszModule, GC_USER_CHANMGR, NULL, NULL, 0);
+			SendDlgItemMessage(m_hwnd, IDC_CHAT_SHOWNICKLIST, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_si->bNicklistEnabled ? "chat_nicklist" : "chat_nicklist2"));
+			SendMessage(m_hwnd, GC_SCROLLTOBOTTOM, 0, 0);
+			SendMessage(m_hwnd, WM_SIZE, 0, 0);
+			break;
+
+		case IDC_MESSAGE:
+			if (HIWORD(wParam) == EN_CHANGE) {
+				cmdListCurrent = NULL;
+				EnableWindow(GetDlgItem(m_hwnd, IDOK), GetRichTextLength(m_message.GetHwnd(), 1200, FALSE) != 0);
+			}
+			break;
+
+		case IDC_HISTORY:
+			if (IsWindowEnabled(GetDlgItem(m_hwnd, IDC_HISTORY))) {
+				MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
+				if (pInfo)
+					ShellExecute(m_hwnd, NULL, pci->GetChatLogsFilename(m_si, 0), NULL, NULL, SW_SHOW);
+			}
+			break;
+
+		case IDC_CHAT_CHANMGR:
+			if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_CHANMGR)))
 				break;
+			pci->DoEventHookAsync(m_hwnd, m_si->ptszID, m_si->pszModule, GC_USER_CHANMGR, NULL, NULL, 0);
+			break;
 
-			case IDC_CHAT_FILTER:
-				if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_FILTER)))
-					break;
+		case IDC_CHAT_FILTER:
+			if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_FILTER)))
+				break;
 
-				m_si->bFilterEnabled = !m_si->bFilterEnabled;
-				SendDlgItemMessage(m_hwnd, IDC_CHAT_FILTER, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_si->bFilterEnabled ? "chat_filter" : "chat_filter2"));
-				if (m_si->bFilterEnabled && db_get_b(NULL, CHAT_MODULE, "RightClickFilter", 0) == 0) {
-					SendMessage(m_hwnd, GC_SHOWFILTERMENU, 0, 0);
-					break;
-				}
-				SendMessage(m_hwnd, GC_REDRAWLOG, 0, 0);
+			m_si->bFilterEnabled = !m_si->bFilterEnabled;
+			SendDlgItemMessage(m_hwnd, IDC_CHAT_FILTER, BM_SETIMAGE, IMAGE_ICON, (LPARAM)GetCachedIcon(m_si->bFilterEnabled ? "chat_filter" : "chat_filter2"));
+			if (m_si->bFilterEnabled && db_get_b(NULL, CHAT_MODULE, "RightClickFilter", 0) == 0) {
+				SendMessage(m_hwnd, GC_SHOWFILTERMENU, 0, 0);
 				break;
+			}
+			SendMessage(m_hwnd, GC_REDRAWLOG, 0, 0);
+			break;
 
-			case IDC_CHAT_BKGCOLOR:
-				if (IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_BKGCOLOR))) {
-					MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
-					CHARFORMAT2 cf;
-					cf.cbSize = sizeof(CHARFORMAT2);
-					cf.dwEffects = 0;
-
-					if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_BKGCOLOR)) {
-						if (db_get_b(NULL, CHAT_MODULE, "RightClickFilter", 0) == 0)
-							SendMessage(m_hwnd, GC_SHOWCOLORCHOOSER, 0, IDC_CHAT_BKGCOLOR);
-						else if (m_si->bBGSet) {
-							cf.dwMask = CFM_BACKCOLOR;
-							cf.crBackColor = pInfo->crColors[m_si->iBG];
-							if (pInfo->bSingleFormat)
-								m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
-							else
-								m_message.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
-						}
-					}
-					else {
+		case IDC_CHAT_BKGCOLOR:
+			if (IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_BKGCOLOR))) {
+				MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
+				cf.cbSize = sizeof(CHARFORMAT2);
+				cf.dwEffects = 0;
+
+				if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_BKGCOLOR)) {
+					if (db_get_b(NULL, CHAT_MODULE, "RightClickFilter", 0) == 0)
+						SendMessage(m_hwnd, GC_SHOWCOLORCHOOSER, 0, IDC_CHAT_BKGCOLOR);
+					else if (m_si->bBGSet) {
 						cf.dwMask = CFM_BACKCOLOR;
-						cf.crBackColor = (COLORREF)db_get_dw(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+						cf.crBackColor = pInfo->crColors[m_si->iBG];
 						if (pInfo->bSingleFormat)
 							m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
 						else
 							m_message.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
 					}
 				}
-				break;
+				else {
+					cf.dwMask = CFM_BACKCOLOR;
+					cf.crBackColor = (COLORREF)db_get_dw(NULL, SRMMMOD, SRMSGSET_INPUTBKGCOLOUR, SRMSGDEFSET_INPUTBKGCOLOUR);
+					if (pInfo->bSingleFormat)
+						m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+					else
+						m_message.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
+				}
+			}
+			break;
 
-			case IDC_CHAT_COLOR:
-				{
-					MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
-					CHARFORMAT2 cf;
-					cf.cbSize = sizeof(CHARFORMAT2);
-					cf.dwEffects = 0;
+		case IDC_CHAT_COLOR:
+			{
+				MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
+				cf.cbSize = sizeof(CHARFORMAT2);
+				cf.dwEffects = 0;
 
-					if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_COLOR)))
-						break;
+				if (!IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_COLOR)))
+					break;
 
-					if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_COLOR)) {
-						if (db_get_b(NULL, CHAT_MODULE, "RightClickFilter", 0) == 0)
-							SendMessage(m_hwnd, GC_SHOWCOLORCHOOSER, 0, IDC_CHAT_COLOR);
-						else if (m_si->bFGSet) {
-							cf.dwMask = CFM_COLOR;
-							cf.crTextColor = pInfo->crColors[m_si->iFG];
-							if (pInfo->bSingleFormat)
-								m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
-							else
-								m_message.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
-						}
-					}
-					else {
-						COLORREF cr;
-						LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &cr);
+				if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_COLOR)) {
+					if (db_get_b(NULL, CHAT_MODULE, "RightClickFilter", 0) == 0)
+						SendMessage(m_hwnd, GC_SHOWCOLORCHOOSER, 0, IDC_CHAT_COLOR);
+					else if (m_si->bFGSet) {
 						cf.dwMask = CFM_COLOR;
-						cf.crTextColor = cr;
+						cf.crTextColor = pInfo->crColors[m_si->iFG];
 						if (pInfo->bSingleFormat)
 							m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
 						else
 							m_message.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
 					}
 				}
-				break;
-
-			case IDC_CHAT_BOLD:
-			case IDC_CHAT_ITALICS:
-			case IDC_CHAT_UNDERLINE:
-				{
-					MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
-					CHARFORMAT2 cf;
-					cf.cbSize = sizeof(CHARFORMAT2);
-					cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
-					cf.dwEffects = 0;
-
-					if (LOWORD(wParam) == IDC_CHAT_BOLD && !IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_BOLD)))
-						break;
-					if (LOWORD(wParam) == IDC_CHAT_ITALICS && !IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_ITALICS)))
-						break;
-					if (LOWORD(wParam) == IDC_CHAT_UNDERLINE && !IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_UNDERLINE)))
-						break;
-					if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_BOLD))
-						cf.dwEffects |= CFE_BOLD;
-					if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_ITALICS))
-						cf.dwEffects |= CFE_ITALIC;
-					if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_UNDERLINE))
-						cf.dwEffects |= CFE_UNDERLINE;
+				else {
+					COLORREF cr;
+					LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, NULL, &cr);
+					cf.dwMask = CFM_COLOR;
+					cf.crTextColor = cr;
 					if (pInfo->bSingleFormat)
 						m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
 					else
 						m_message.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
 				}
-				break;
-
-			case IDCANCEL:
-				PostMessage(m_hwnd, WM_CLOSE, 0, 0);
 			}
 			break;
 
-		case WM_KEYDOWN:
-			SetFocus(m_message.GetHwnd());
-			break;
-
-		case WM_GETMINMAXINFO:
+		case IDC_CHAT_BOLD:
+		case IDC_CHAT_ITALICS:
+		case IDC_CHAT_UNDERLINE:
 			{
-				MINMAXINFO* mmi = (MINMAXINFO*)lParam;
-				mmi->ptMinTrackSize.x = m_si->iSplitterX + 43;
-				if (mmi->ptMinTrackSize.x < 350)
-					mmi->ptMinTrackSize.x = 350;
+				MODULEINFO *pInfo = pci->MM_FindModule(m_si->pszModule);
+				CHARFORMAT2 cf;
+				cf.cbSize = sizeof(CHARFORMAT2);
+				cf.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
+				cf.dwEffects = 0;
 
-				mmi->ptMinTrackSize.y = m_si->m_minLogBoxHeight + TOOLBAR_HEIGHT + m_si->m_minEditBoxHeight + 5;
+				if (LOWORD(wParam) == IDC_CHAT_BOLD && !IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_BOLD)))
+					break;
+				if (LOWORD(wParam) == IDC_CHAT_ITALICS && !IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_ITALICS)))
+					break;
+				if (LOWORD(wParam) == IDC_CHAT_UNDERLINE && !IsWindowEnabled(GetDlgItem(m_hwnd, IDC_CHAT_UNDERLINE)))
+					break;
+				if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_BOLD))
+					cf.dwEffects |= CFE_BOLD;
+				if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_ITALICS))
+					cf.dwEffects |= CFE_ITALIC;
+				if (IsDlgButtonChecked(m_hwnd, IDC_CHAT_UNDERLINE))
+					cf.dwEffects |= CFE_UNDERLINE;
+				if (pInfo->bSingleFormat)
+					m_message.SendMsg(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
+				else
+					m_message.SendMsg(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
 			}
 			break;
 
-		case WM_LBUTTONDBLCLK:
-			if (LOWORD(lParam) < 30)
-				PostMessage(m_hwnd, GC_SCROLLTOBOTTOM, 0, 0);
-			else
-				SendMessage(m_hwndParent, WM_SYSCOMMAND, SC_MINIMIZE, 0);
-			break;
+		case IDCANCEL:
+			PostMessage(m_hwnd, WM_CLOSE, 0, 0);
+		}
+		break;
 
-		case WM_LBUTTONDOWN:
-			SendMessage(m_hwndParent, WM_LBUTTONDOWN, wParam, lParam);
-			return TRUE;
+	case WM_KEYDOWN:
+		SetFocus(m_message.GetHwnd());
+		break;
 
-		case DM_GETCONTEXTMENU:
-			SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, (LPARAM)Menu_BuildContactMenu(m_hContact));
-			return TRUE;
+	case WM_GETMINMAXINFO:
+		{
+			MINMAXINFO *mmi = (MINMAXINFO*)lParam;
+			mmi->ptMinTrackSize.x = m_si->iSplitterX + 43;
+			if (mmi->ptMinTrackSize.x < 350)
+				mmi->ptMinTrackSize.x = 350;
 
-		case WM_CONTEXTMENU:
-			if (m_hwndParent == (HWND)wParam) {
-				HMENU hMenu = Menu_BuildContactMenu(m_hContact);
-				GetCursorPos(&pt);
-				TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, m_hwnd, NULL);
-				DestroyMenu(hMenu);
-			}
-			break;
+			mmi->ptMinTrackSize.y = m_minLogBoxHeight + TOOLBAR_HEIGHT + m_minEditBoxHeight + 5;
+		}
+		break;
 
-		case GC_CLOSEWINDOW:
-			Close();
-			break;
+	case WM_LBUTTONDBLCLK:
+		if (LOWORD(lParam) < 30)
+			PostMessage(m_hwnd, GC_SCROLLTOBOTTOM, 0, 0);
+		else
+			SendMessage(m_hwndParent, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+		break;
+
+	case WM_LBUTTONDOWN:
+		SendMessage(m_hwndParent, WM_LBUTTONDOWN, wParam, lParam);
+		return TRUE;
+
+	case DM_GETCONTEXTMENU:
+		SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, (LPARAM)Menu_BuildContactMenu(m_hContact));
+		return TRUE;
+
+	case WM_CONTEXTMENU:
+		if (m_hwndParent == (HWND)wParam) {
+			HMENU hMenu = Menu_BuildContactMenu(m_hContact);
+			GetCursorPos(&pt);
+			TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, m_hwnd, NULL);
+			DestroyMenu(hMenu);
 		}
-		return CSrmmBaseDialog::DlgProc(uMsg, wParam, lParam);
+		break;
+
+	case GC_CLOSEWINDOW:
+		Close();
+		break;
 	}
-};
+	return CSrmmBaseDialog::DlgProc(uMsg, wParam, lParam);
+}
 
 void ShowRoom(SESSION_INFO *si)
 {
@@ -1805,7 +1751,7 @@ void ShowRoom(SESSION_INFO *si)
 		pDlg->SetParent(hParent);
 		pDlg->Show();
 		
-		si->m_pParent = (ParentWindowData*)GetWindowLongPtr(hParent, GWLP_USERDATA);
+		pDlg->m_pParent = (ParentWindowData*)GetWindowLongPtr(hParent, GWLP_USERDATA);
 		si->hWnd = pDlg->GetHwnd();
 	}
 	SendMessage(si->hWnd, DM_UPDATETABCONTROL, -1, (LPARAM)si);
diff --git a/plugins/Scriver/src/input.cpp b/plugins/Scriver/src/input.cpp
index 8fe400cdd9..9f5881fa6d 100644
--- a/plugins/Scriver/src/input.cpp
+++ b/plugins/Scriver/src/input.cpp
@@ -115,7 +115,7 @@ void InputAreaContextMenu(HWND hwnd, WPARAM, LPARAM lParam, MCONTACT hContact)
 	DestroyMenu(hMenu);
 }
 
-int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CommonWindowData *windowData)
+int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriverWindow *windowData)
 {
 	BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000;
 	BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
diff --git a/plugins/Scriver/src/input.h b/plugins/Scriver/src/input.h
index 0761140346..067820a2fe 100644
--- a/plugins/Scriver/src/input.h
+++ b/plugins/Scriver/src/input.h
@@ -23,8 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #ifndef INPUT_H
 #define INPUT_H
 
-extern void InputAreaContextMenu(HWND hwnd, WPARAM wParam, LPARAM lParam, MCONTACT hContact);
-extern void RegisterKeyBindings();
-extern int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CommonWindowData *windowData);
+void InputAreaContextMenu(HWND hwnd, WPARAM wParam, LPARAM lParam, MCONTACT hContact);
+void RegisterKeyBindings();
+int InputAreaShortcuts(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, CScriverWindow *windowData);
 
 #endif
diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp
index 0b8fb28a86..f14ce90112 100644
--- a/plugins/Scriver/src/msgdialog.cpp
+++ b/plugins/Scriver/src/msgdialog.cpp
@@ -27,9 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #define ENTERCLICKTIME   1000   //max time in ms during which a double-tap on enter will cause a send
 
-extern HCURSOR hCurSplitNS, hCurSplitWE, hCurHyperlinkHand, hDragCursor;
-extern HANDLE hHookWinEvt;
-
 wchar_t* CSrmmWindow::GetIEViewSelection()
 {
 	IEVIEWEVENT evt = { sizeof(evt) };
@@ -178,7 +175,7 @@ void CSrmmWindow::SetDialogToType()
 	else
 		ShowWindow(m_log.GetHwnd(), SW_SHOW);
 
-	ShowWindow(GetDlgItem(m_hwnd, IDC_SPLITTERY), SW_SHOW);
+	ShowWindow(m_splitter.GetHwnd(), SW_SHOW);
 	UpdateReadChars();
 	EnableWindow(GetDlgItem(m_hwnd, IDOK), GetRichTextLength(m_message.GetHwnd(), 1200, FALSE) ? TRUE : FALSE);
 	SendMessage(m_hwnd, DM_CLISTSETTINGSCHANGED, 0, 0);
@@ -433,20 +430,18 @@ void CSrmmWindow::MessageDialogResize(int w, int h)
 
 	ParentWindowData *pdat = m_pParent;
 	bool bToolbar = (pdat->flags2 & SMF2_SHOWTOOLBAR) != 0;
-	int hSplitterPos = m_iSplitterPos, toolbarHeight = (bToolbar) ? m_toolbarSize.cy : 0;
+	int hSplitterPos = m_pParent->iSplitterY, toolbarHeight = (bToolbar) ? m_toolbarSize.cy : 0;
 	int hSplitterMinTop = toolbarHeight + m_minLogBoxHeight, hSplitterMinBottom = m_minEditBoxHeight;
 	int infobarInnerHeight = INFO_BAR_INNER_HEIGHT;
 	int infobarHeight = INFO_BAR_HEIGHT;
 	int avatarWidth = 0, avatarHeight = 0;
 	int toolbarWidth = w;
 	int messageEditWidth = w - 2;
-	int logY, logH;
 
 	if (!(pdat->flags2 & SMF2_SHOWINFOBAR)) {
 		infobarHeight = 0;
 		infobarInnerHeight = 0;
 	}
-	hSplitterPos = m_iDesiredInputAreaHeight + SPLITTER_HEIGHT + 3;
 
 	if (hSplitterPos > (h - toolbarHeight - infobarHeight + SPLITTER_HEIGHT + 1) / 2)
 		hSplitterPos = (h - toolbarHeight - infobarHeight + SPLITTER_HEIGHT + 1) / 2;
@@ -482,17 +477,17 @@ void CSrmmWindow::MessageDialogResize(int w, int h)
 		}
 	}
 
-	m_iSplitterPos = hSplitterPos;
+	m_pParent->iSplitterY = hSplitterPos;
 
-	logY = infobarInnerHeight;
-	logH = h - hSplitterPos - toolbarHeight - infobarInnerHeight;
+	int logY = infobarInnerHeight;
+	int logH = h - hSplitterPos - toolbarHeight - infobarInnerHeight;
 
 	HDWP hdwp = BeginDeferWindowPos(5);
 	hdwp = DeferWindowPos(hdwp, m_pInfobarData->hWnd, 0, 1, 0, w - 2, infobarInnerHeight - 2, SWP_NOZORDER);
 	hdwp = DeferWindowPos(hdwp, m_log.GetHwnd(), 0, 1, logY, w - 2, logH, SWP_NOZORDER);
 	hdwp = DeferWindowPos(hdwp, m_message.GetHwnd(), 0, 1, h - hSplitterPos + SPLITTER_HEIGHT, messageEditWidth, hSplitterPos - SPLITTER_HEIGHT - 1, SWP_NOZORDER);
 	hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_AVATAR), 0, w - avatarWidth - 1, h - (avatarHeight + avatarWidth) / 2 - 1, avatarWidth, avatarWidth, SWP_NOZORDER);
-	hdwp = DeferWindowPos(hdwp, GetDlgItem(m_hwnd, IDC_SPLITTERY), 0, 0, h - hSplitterPos - 1, toolbarWidth, SPLITTER_HEIGHT, SWP_NOZORDER);
+	hdwp = DeferWindowPos(hdwp, m_splitter.GetHwnd(), 0, 0, h - hSplitterPos - 1, toolbarWidth, SPLITTER_HEIGHT, SWP_NOZORDER);
 	EndDeferWindowPos(hdwp);
 
 	SetButtonsPos(m_hwnd, m_hContact, bToolbar);
@@ -633,9 +628,10 @@ static INT_PTR CALLBACK ConfirmSendAllDlgProc(HWND hwndDlg, UINT msg, WPARAM wPa
 /////////////////////////////////////////////////////////////////////////////////////////
 
 CSrmmWindow::CSrmmWindow(MCONTACT hContact, bool bIncoming, const char *szInitialText, bool bIsUnicode)
-	: CSrmmBaseDialog(g_hInst, IDD_MSG),
+	: CScriverWindow(IDD_MSG),
 	m_log(this, IDC_LOG),
 	m_message(this, IDC_MESSAGE),
+	m_splitter(this, IDC_SPLITTERY),
 	m_bIncoming(bIncoming)
 {
 	m_pLog = &m_log;
@@ -644,6 +640,8 @@ CSrmmWindow::CSrmmWindow(MCONTACT hContact, bool bIncoming, const char *szInitia
 
 	m_hwndParent = GetParentWindow(hContact, FALSE);
 	m_wszInitialText = (bIsUnicode) ? mir_wstrdup((wchar_t*)szInitialText) : mir_a2u(szInitialText);
+
+	m_splitter.OnChange = Callback(this, &CSrmmWindow::OnSplitterMoved);
 }
 
 void CSrmmWindow::OnInitDialog()
@@ -684,7 +682,8 @@ void CSrmmWindow::OnInitDialog()
 		SetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_message.GetHwnd(), GWL_EXSTYLE) | WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR);
 	}
 	m_message.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
-	/* Workaround to make Richedit display RTL messages correctly */
+	
+	// Workaround to make Richedit display RTL messages correctly
 	memset(&pf2, 0, sizeof(pf2));
 	pf2.cbSize = sizeof(pf2);
 	pf2.dwMask = PFM_RTLPARA | PFM_OFFSETINDENT | PFM_RIGHTINDENT;
@@ -692,22 +691,22 @@ void CSrmmWindow::OnInitDialog()
 	pf2.dxStartIndent = 30;
 	pf2.dxRightIndent = 30;
 	m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
+
 	pf2.dwMask = PFM_RTLPARA;
 	pf2.wEffects = 0;
 	m_log.SendMsg(EM_SETPARAFORMAT, 0, (LPARAM)&pf2);
-	if (m_bUseRtl)
-		SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE, GetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE) | WS_EX_LEFTSCROLLBAR);
-	else
-		SetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE, GetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE) & ~WS_EX_LEFTSCROLLBAR);
+	
+	DWORD dwExStyle = GetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE);
+	SetWindowLongPtr(m_log.GetHwnd(), GWL_EXSTYLE, (m_bUseRtl) ? dwExStyle | WS_EX_LEFTSCROLLBAR :dwExStyle & ~WS_EX_LEFTSCROLLBAR);
 
-	RECT minEditInit;
-	GetWindowRect(m_message.GetHwnd(), &minEditInit);
-	m_minEditBoxHeight = minEditInit.bottom - minEditInit.top;
-	m_minLogBoxHeight = m_minEditBoxHeight;
 	m_toolbarSize.cy = TOOLBAR_HEIGHT;
 	m_toolbarSize.cx = 0;
-	if (m_iSplitterPos == -1)
-		m_iSplitterPos = m_minEditBoxHeight;
+
+	RECT rc;
+	GetWindowRect(m_message.GetHwnd(), &rc);
+	m_minLogBoxHeight = m_minEditBoxHeight = rc.bottom - rc.top;
+	if (m_pParent->iSplitterY == -1)
+		m_pParent->iSplitterY = m_minEditBoxHeight;
 
 	if (m_wszInitialText) {
 		m_message.SetText(m_wszInitialText);
@@ -733,7 +732,7 @@ void CSrmmWindow::OnInitDialog()
 
 	m_message.SendMsg(EM_SETLANGOPTIONS, 0, (LPARAM)m_message.SendMsg(EM_GETLANGOPTIONS, 0, 0) & ~IMF_AUTOKEYBOARD);
 	m_message.SendMsg(EM_SETOLECALLBACK, 0, (LPARAM)&reOleCallback2);
-	m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE | ENM_REQUESTRESIZE);
+	m_message.SendMsg(EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS | ENM_CHANGE);
 	if (m_hContact && m_szProto) {
 		int nMax = CallProtoService(m_szProto, PS_GETCAPS, PFLAG_MAXLENOFMESSAGE, m_hContact);
 		if (nMax)
@@ -742,7 +741,7 @@ void CSrmmWindow::OnInitDialog()
 
 	// get around a lame bug in the Windows template resource code where richedits are limited to 0x7FFF
 	m_log.SendMsg(EM_LIMITTEXT, sizeof(wchar_t) * 0x7FFFFFFF, 0);
-	SubclassLogEdit(GetDlgItem(m_hwnd, IDC_LOG));
+	SubclassLogEdit(m_log.GetHwnd());
 	SubclassMessageEdit(m_message.GetHwnd());
 	m_pInfobarData = CreateInfobar(m_hwnd, this);
 	if (m_bUseIEView) {
@@ -857,7 +856,7 @@ void CSrmmWindow::OnDestroy()
 		DestroyIcon(m_hStatusIconOverlay);
 		m_hStatusIconOverlay = NULL;
 	}	
-	
+
 	ReleaseSendQueueItems(m_hwnd);
 	if (g_dat.flags & SMF_SAVEDRAFTS) {
 		ptrA szText(GetRichTextUtf(m_message.GetHwnd()));
@@ -890,12 +889,17 @@ void CSrmmWindow::OnDestroy()
 	NotifyLocalWinEvent(m_hContact, m_hwnd, MSG_WINDOW_EVT_CLOSE);
 }
 
+void CSrmmWindow::OnSplitterMoved(CSplitter *pSplitter)
+{
+	RECT rc;
+	GetClientRect(m_hwnd, &rc);
+	m_pParent->iSplitterY = rc.bottom - pSplitter->GetPos();
+}
+
 INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 {
 	PARAFORMAT2 pf2;
-	CHARFORMAT2 cf2;
 	LPNMHDR pNmhdr;
-	HCURSOR hCur;
 
 	switch (msg) {
 	case DM_GETCONTEXTMENU:
@@ -1050,6 +1054,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 			LOGFONT lf;
 			LoadMsgDlgFont(MSGFONTID_MESSAGEAREA, &lf, &colour);
 
+			CHARFORMAT2 cf2;
 			memset(&cf2, 0, sizeof(cf2));
 			cf2.cbSize = sizeof(cf2);
 			cf2.dwMask = CFM_COLOR | CFM_FACE | CFM_CHARSET | CFM_SIZE | CFM_WEIGHT | CFM_BOLD | CFM_ITALIC;
@@ -1068,6 +1073,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		pf2.cbSize = sizeof(pf2);
 		pf2.dwMask = PFM_OFFSET;
 		pf2.dxOffset = (g_dat.flags & SMF_INDENTTEXT) ? g_dat.indentSize * 1440 / g_dat.logPixelSX : 0;
+
 		SetDlgItemText(m_hwnd, IDC_LOG, L"");
 		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));
@@ -1123,12 +1129,12 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		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(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE, GetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE) | 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(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE, GetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LOG), GWL_EXSTYLE) &~(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);
@@ -1222,25 +1228,12 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 		}
 		return TRUE;
 
-	case DM_SPLITTERMOVED:
-		if ((HWND)lParam == GetDlgItem(m_hwnd, IDC_SPLITTERY)) {
-			RECT rc, rcLog;
-			GetWindowRect(GetDlgItem(m_hwnd, IDC_LOG), &rcLog);
-			GetClientRect(m_hwnd, &rc);
-
-			POINT pt = { 0, (int)wParam };
-			ScreenToClient(m_hwnd, &pt);
-			m_iSplitterPos = rc.bottom - pt.y;
-			SendMessage(m_hwnd, WM_SIZE, 0, 0);
-		}
-		break;
-
 	case DM_REMAKELOG:
 		m_lastEventType = -1;
 		if (wParam == 0 || wParam == m_hContact)
 			StreamInEvents(m_hDbEventFirst, -1, 0);
 
-		InvalidateRect(GetDlgItem(m_hwnd, IDC_LOG), NULL, FALSE);
+		InvalidateRect(m_log.GetHwnd(), NULL, FALSE);
 		break;
 
 	case DM_APPENDTOLOG:   //takes wParam=hDbEvent
@@ -1249,20 +1242,20 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 
 	case DM_SCROLLLOGTOBOTTOM:
 		if (m_hwndIeview == NULL) {
-			if ((GetWindowLongPtr(GetDlgItem(m_hwnd, IDC_LOG), GWL_STYLE) & WS_VSCROLL) == 0)
+			if ((GetWindowLongPtr(m_log.GetHwnd(), GWL_STYLE) & WS_VSCROLL) == 0)
 				break;
 
 			SCROLLINFO si = { sizeof(si) };
 			si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
-			if (GetScrollInfo(GetDlgItem(m_hwnd, IDC_LOG), SB_VERT, &si)) {
-				if (GetDlgItem(m_hwnd, IDC_LOG) != GetFocus()) {
+			if (GetScrollInfo(m_log.GetHwnd(), SB_VERT, &si)) {
+				if (m_log.GetHwnd() != GetFocus()) {
 					si.fMask = SIF_POS;
 					si.nPos = si.nMax - si.nPage + 1;
-					SetScrollInfo(GetDlgItem(m_hwnd, IDC_LOG), SB_VERT, &si, TRUE);
-					PostMessage(GetDlgItem(m_hwnd, IDC_LOG), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
+					SetScrollInfo(m_log.GetHwnd(), SB_VERT, &si, TRUE);
+					PostMessage(m_log.GetHwnd(), WM_VSCROLL, MAKEWPARAM(SB_BOTTOM, 0), 0);
 				}
 			}
-			RedrawWindow(GetDlgItem(m_hwnd, IDC_LOG), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+			RedrawWindow(m_log.GetHwnd(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
 		}
 		else {
 			IEVIEWWINDOW ieWindow;
@@ -1628,7 +1621,7 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 				if (m_hwndIeview != NULL)
 					buffer = GetIEViewSelection();
 				else
-					buffer = GetRichEditSelection(GetDlgItem(m_hwnd, IDC_LOG));
+					buffer = GetRichEditSelection(m_log.GetHwnd());
 
 				if (buffer != NULL) {
 					wchar_t *quotedBuffer = GetQuotedTextW(buffer);
@@ -1711,51 +1704,10 @@ INT_PTR CSrmmWindow::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
 						SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE);
 					}
 					return TRUE;
-
-				case WM_LBUTTONDOWN:
-					hCur = GetCursor();
-					if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE) || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE)) {
-						SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE);
-						return TRUE;
-					}
-					break;
-
-				case WM_MOUSEMOVE:
-					hCur = GetCursor();
-					if (hCur == LoadCursor(NULL, IDC_SIZENS) || hCur == LoadCursor(NULL, IDC_SIZEWE) || hCur == LoadCursor(NULL, IDC_SIZENESW) || hCur == LoadCursor(NULL, IDC_SIZENWSE))
-						SetCursor(LoadCursor(NULL, IDC_ARROW));
-					break;
-
-				case WM_RBUTTONUP:
-					SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE);
-					return TRUE;
 				}
 				break;
 			}
 			break;
-
-		case IDC_MESSAGE:
-			switch (((NMHDR *)lParam)->code) {
-			case EN_MSGFILTER:
-				switch (((MSGFILTER *)lParam)->msg) {
-				case WM_RBUTTONUP:
-					SetWindowLongPtr(m_hwnd, DWLP_MSGRESULT, TRUE);
-					return TRUE;
-				}
-				break;
-			case EN_REQUESTRESIZE:
-				REQRESIZE *rr = (REQRESIZE *)lParam;
-				int height = rr->rc.bottom - rr->rc.top + 1;
-				if (height < g_dat.minInputAreaHeight)
-					height = g_dat.minInputAreaHeight;
-
-				if (m_iDesiredInputAreaHeight != height) {
-					m_iDesiredInputAreaHeight = height;
-					SendMessage(m_hwnd, WM_SIZE, 0, 0);
-					PostMessage(m_hwnd, DM_SCROLLLOGTOBOTTOM, 0, 0);
-				}
-				break;
-			}
 		}
 		break;
 
diff --git a/plugins/Scriver/src/msgs.cpp b/plugins/Scriver/src/msgs.cpp
index 579f63e7a0..4bfc584182 100644
--- a/plugins/Scriver/src/msgs.cpp
+++ b/plugins/Scriver/src/msgs.cpp
@@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "stdafx.h"
 
-HCURSOR  hCurSplitNS, hCurSplitWE, hCurHyperlinkHand, hDragCursor;
+HCURSOR  hDragCursor;
 HANDLE   hHookWinEvt, hHookWinPopup, hHookWinWrite;
 HGENMENU hMsgMenuItem;
 HMODULE hMsftEdit;
@@ -307,29 +307,21 @@ static INT_PTR GetWindowData(WPARAM wParam, LPARAM lParam)
 static INT_PTR SetStatusText(WPARAM hContact, LPARAM lParam)
 {
 	StatusTextData *st = (StatusTextData*)lParam;
-	if (st != NULL && st->cbSize != sizeof(StatusTextData))
+	if (st != nullptr && st->cbSize != sizeof(StatusTextData))
 		return 1;
 
-	ParentWindowData *pdat;
 	HWND hwnd = WindowList_Find(pci->hWindowList, hContact);
-	if (hwnd == NULL) {
+	if (hwnd == nullptr) {
 		hwnd = SM_FindWindowByContact(hContact);
-		if (hwnd == NULL)
-			return 1;
-
-		SESSION_INFO *si = (SESSION_INFO*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-		if (si == NULL || si->m_pParent == NULL)
+		if (hwnd == nullptr)
 			return 1;
-
-		pdat = si->m_pParent;
 	}
-	else {
-		CSrmmWindow *dat = (CSrmmWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-		if (dat == NULL || dat->m_pParent == NULL)
-			return 1;
 
-		pdat = dat->m_pParent;
-	}
+	CScriverWindow *dat = (CScriverWindow*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+	if (dat == nullptr || dat->m_pParent == nullptr)
+		return 1;
+
+	ParentWindowData *pdat = dat->m_pParent;
 
 	SendMessage(pdat->hwndStatus, SB_SETICON, 0, (LPARAM)(st == NULL ? 0 : st->hIcon));
 	SendMessage(pdat->hwndStatus, SB_SETTEXT, 0, (LPARAM)(st == NULL ? L"" : st->tszText));
@@ -581,9 +573,6 @@ int OnUnloadModule(void)
 {
 	Chat_Unload();
 
-	DestroyCursor(hCurSplitNS);
-	DestroyCursor(hCurHyperlinkHand);
-	DestroyCursor(hCurSplitWE);
 	DestroyCursor(hDragCursor);
 
 	DestroyHookableEvent(hHookWinEvt);
@@ -648,11 +637,6 @@ int OnLoadModule(void)
 	SkinAddNewSoundEx("TNStart", LPGEN("Instant messages"), LPGEN("Contact started typing"));
 	SkinAddNewSoundEx("TNStop", LPGEN("Instant messages"), LPGEN("Contact stopped typing"));
 
-	hCurSplitNS = LoadCursor(NULL, IDC_SIZENS);
-	hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE);
-	hCurHyperlinkHand = LoadCursor(NULL, IDC_HAND);
-	if (hCurHyperlinkHand == NULL)
-		hCurHyperlinkHand = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_HYPERLINKHAND));
 	hDragCursor = LoadCursor(g_hInst, MAKEINTRESOURCE(IDC_DRAGCURSOR));
 
 	Chat_Load();
diff --git a/plugins/Scriver/src/msgs.h b/plugins/Scriver/src/msgs.h
index a9a0e996dd..276959c0e8 100644
--- a/plugins/Scriver/src/msgs.h
+++ b/plugins/Scriver/src/msgs.h
@@ -75,6 +75,8 @@ struct ParentWindowData
 	int bMinimized;
 	int bVMaximized;
 	int bTopmost;
+	int iSplitterX, iSplitterY;
+
 	int windowWasCascaded;
 	TabCtrlData *tabCtrlDat;
 	BOOL isChat;
@@ -92,24 +94,29 @@ struct MessageWindowTabData
 
 #define NMWLP_INCOMING 1
 
-struct CommonWindowData
+class CScriverWindow : public CSrmmBaseDialog
 {
+protected:
+	CScriverWindow(int iDialog) :
+		CSrmmBaseDialog(g_hInst, iDialog)
+	{}
+
+public:
 	ParentWindowData *m_pParent;
 	int m_minLogBoxHeight, m_minEditBoxHeight;
 	HWND m_hwndIeview;
 	TCmdList *cmdList, *cmdListCurrent;
 };
 
-class CSrmmWindow : public CSrmmBaseDialog, public CommonWindowData
+class CSrmmWindow : public CScriverWindow
 {
 	CCtrlEdit m_log, m_message;
+	CSplitter m_splitter;
 	
 	wchar_t *m_wszInitialText;
 	bool   m_bIncoming, m_bShowTyping;
 	
 	MEVENT m_hDbEventFirst, m_hDbEventLast, m_hDbUnreadEventFirst;
-	int    m_iSplitterPos;
-	int    m_iDesiredInputAreaHeight;
 	SIZE   m_toolbarSize;
 	int    m_iWindowWasCascaded;
 	int    m_nTypeSecs, m_nTypeMode, m_nLastTyping;
@@ -154,13 +161,39 @@ public:
 	virtual void OnDestroy() override;
 
 	virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
+	void OnSplitterMoved(CSplitter *pSplitter);
+};
+
+class CChatRoomDlg : public CScriverWindow
+{
+	CCtrlEdit m_message, m_log;
+	CCtrlListBox m_nickList;
+	CSplitter m_splitterX, m_splitterY;
+
+	void MessageDialogResize(int w, int h);
+
+public:
+	SESSION_INFO *m_si;
+	wchar_t m_wszSearch[255];
+
+public:
+	CChatRoomDlg(SESSION_INFO *si);
+
+	virtual void OnInitDialog() override;
+	virtual void OnDestroy() override;
+
+	virtual INT_PTR DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam) override;
+
+	void OnSplitterX(CSplitter *pSplitter);
+	void OnSplitterY(CSplitter *pSplitter);
+
 };
 
 #define HM_DBEVENTADDED        (WM_USER+10)
 #define DM_REMAKELOG           (WM_USER+11)
 #define DM_CASCADENEWWINDOW    (WM_USER+13)
 #define DM_OPTIONSAPPLIED      (WM_USER+14)
-#define DM_SPLITTERMOVED       (WM_USER+15)
 #define DM_APPENDTOLOG         (WM_USER+17)
 #define DM_ERRORDECIDED        (WM_USER+18)
 #define DM_SCROLLLOGTOBOTTOM   (WM_USER+19)
diff --git a/plugins/Scriver/src/stdafx.h b/plugins/Scriver/src/stdafx.h
index 3a2a74d140..0305e13fe7 100644
--- a/plugins/Scriver/src/stdafx.h
+++ b/plugins/Scriver/src/stdafx.h
@@ -70,17 +70,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "resource.h"
 #include "version.h"
-#include "infobar.h"
-#include "cmdlist.h"
-#include "sendqueue.h"
-#include "msgs.h"
-#include "globals.h"
-#include "tabs.h"
-#include "utils.h"
-#include "input.h"
-#include "richutil.h"
-#include "statusicon.h"
-#include "chat/chat.h"
 
 #ifndef IMF_AUTOFONTSIZEADJUST
 #define IMF_AUTOFONTSIZEADJUST	0x0010
@@ -104,13 +93,8 @@ extern void ChangeStatusIcons();
 extern void LoadInfobarFonts();
 extern HCURSOR hDragCursor;
 extern ITaskbarList3 *pTaskbarInterface;
-extern GlobalMessageData g_dat;
 extern HMENU  g_hMenu;
-extern HANDLE hHookWinPopup, hHookWinWrite;
-extern HCURSOR hCurSplitNS, hCurSplitWE;
-
-extern CREOleCallback reOleCallback;
-extern CREOleCallback2 reOleCallback2;
+extern HANDLE hHookWinPopup, hHookWinWrite, hHookWinEvt;
 
 #define SPLITTER_HEIGHT   4
 #define TOOLBAR_HEIGHT   24
@@ -126,4 +110,21 @@ int OptInitialise(WPARAM wParam, LPARAM lParam);
 int FontServiceFontsChanged(WPARAM wParam, LPARAM lParam);
 int StatusIconPressed(WPARAM wParam, LPARAM lParam);
 
+#include "infobar.h"
+#include "cmdlist.h"
+#include "sendqueue.h"
+#include "msgs.h"
+#include "globals.h"
+#include "tabs.h"
+#include "utils.h"
+#include "input.h"
+#include "richutil.h"
+#include "statusicon.h"
+#include "chat/chat.h"
+
+extern GlobalMessageData g_dat;
+
+extern CREOleCallback reOleCallback;
+extern CREOleCallback2 reOleCallback2;
+
 #endif
diff --git a/plugins/Scriver/src/tabs.cpp b/plugins/Scriver/src/tabs.cpp
index c3d6c11947..858e191cd1 100644
--- a/plugins/Scriver/src/tabs.cpp
+++ b/plugins/Scriver/src/tabs.cpp
@@ -748,6 +748,8 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 			dat->windowWasCascaded = 0;
 			dat->bMinimized = 0;
 			dat->bVMaximized = 0;
+			dat->iSplitterX = db_get_dw(NULL, SRMMMOD, "splitterx", -1);
+			dat->iSplitterY = db_get_dw(NULL, SRMMMOD, "splittery", -1);
 			dat->flags2 = g_dat.flags2;
 			dat->hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL);
 			dat->isChat = newData->isChat;
@@ -1118,6 +1120,10 @@ static INT_PTR CALLBACK DlgProcParentWindow(HWND hwndDlg, UINT msg, WPARAM wPara
 				TabCtrl_DeleteItem(dat->hwndTabs, i);
 			}
 		}
+
+		db_set_dw(NULL, SRMMMOD, "splitterx", dat->iSplitterX);
+		db_set_dw(NULL, SRMMMOD, "splittery", dat->iSplitterY);
+
 		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
 		WindowList_Remove(g_dat.hParentWindowList, hwndDlg);
 		{
diff --git a/plugins/Scriver/src/version.h b/plugins/Scriver/src/version.h
index d3a60aa1f5..e65689c9c6 100644
--- a/plugins/Scriver/src/version.h
+++ b/plugins/Scriver/src/version.h
@@ -1,7 +1,7 @@
 #define __MAJOR_VERSION          3
 #define __MINOR_VERSION          0
 #define __RELEASE_NUM            1
-#define __BUILD_NUM              2
+#define __BUILD_NUM              3
 
 #include <stdver.h>
 
-- 
cgit v1.2.3