diff options
Diffstat (limited to 'plugins/TabSRMM/src/container.cpp')
| -rw-r--r-- | plugins/TabSRMM/src/container.cpp | 4490 | 
1 files changed, 2245 insertions, 2245 deletions
diff --git a/plugins/TabSRMM/src/container.cpp b/plugins/TabSRMM/src/container.cpp index c80af6993f..96d552094b 100644 --- a/plugins/TabSRMM/src/container.cpp +++ b/plugins/TabSRMM/src/container.cpp @@ -1,1266 +1,1266 @@ -///////////////////////////////////////////////////////////////////////////////////////// -// Miranda NG: the free IM client for Microsoft* Windows* -// -// Copyright (ñ) 2012-15 Miranda NG project, -// Copyright (c) 2000-09 Miranda ICQ/IM project, -// all portions of this codebase are copyrighted to the people -// listed in contributors.txt. -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -// GNU General Public License for more details. -// -// you should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. -// -// part of tabSRMM messaging plugin for Miranda. -// -// (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors -// -// implements the "Container" window which acts as a toplevel window -// for message sessions. - -#include "commonheaders.h" - -#define CONTAINER_KEY "TAB_ContainersW" -#define CONTAINER_SUBKEY "containerW" -#define CONTAINER_PREFIX "CNTW_" - -TContainerData *pFirstContainer = 0;        // the linked list of struct ContainerWindowData -TContainerData *pLastActiveContainer = NULL; - -static TContainerData* TSAPI AppendToContainerList(TContainerData*); -static TContainerData* TSAPI RemoveContainerFromList(TContainerData*); - -static bool fForceOverlayIcons = false; - -// Windows Vista+ -// extend the glassy area to get aero look for the status bar, tab bar, info panel -// and outer margins. - -void TSAPI SetAeroMargins(TContainerData *pContainer) -{ -	if (!pContainer) -		return; - -	if (!M.isAero() || CSkin::m_skinEnabled) { -		pContainer->MenuBar->setAero(false); -		return; -	} - -	TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -	if (!dat) -		return; - -	RECT	rcWnd; -	if (dat->bType == SESSIONTYPE_IM) { -		if (dat->Panel->isActive()) -			GetWindowRect(GetDlgItem(dat->hwnd, IDC_LOG), &rcWnd); -		else -			GetWindowRect(dat->hwnd, &rcWnd); -	} -	else { -		if (dat->Panel->isActive()) -			GetWindowRect(GetDlgItem(dat->hwnd, IDC_CHAT_LOG), &rcWnd); -		else -			GetWindowRect(dat->hwnd, &rcWnd); -	} - -	POINT	pt = { rcWnd.left, rcWnd.top }; -	ScreenToClient(pContainer->hwnd, &pt); - -	MARGINS m; -	m.cyTopHeight = pt.y; -	pContainer->MenuBar->setAero(true); - -	// bottom part -	GetWindowRect(dat->hwnd, &rcWnd); -	pt.x = rcWnd.left; - -	LONG sbar_left, sbar_right; -	if (!pContainer->SideBar->isActive()) { -		pt.y = rcWnd.bottom + ((pContainer->iChilds > 1 || !(pContainer->dwFlags & CNT_HIDETABS)) ? pContainer->tBorder : 0); -		sbar_left = 0, sbar_right = 0; -	} -	else { -		pt.y = rcWnd.bottom; -		sbar_left = (pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_LEFT ? pContainer->SideBar->getWidth() : 0); -		sbar_right = (pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_RIGHT ? pContainer->SideBar->getWidth() : 0); -	} -	ScreenToClient(pContainer->hwnd, &pt); -	GetClientRect(pContainer->hwnd, &rcWnd); -	m.cyBottomHeight = (rcWnd.bottom - pt.y); - -	if (m.cyBottomHeight < 0 || m.cyBottomHeight >= rcWnd.bottom) -		m.cyBottomHeight = 0; - -	m.cxLeftWidth = pContainer->tBorder_outer_left; -	m.cxRightWidth = pContainer->tBorder_outer_right; -	m.cxLeftWidth += sbar_left; -	m.cxRightWidth += sbar_right; - -	if (memcmp(&m, &pContainer->mOld, sizeof(MARGINS)) != 0) { -		pContainer->mOld = m; -		CMimAPI::m_pfnDwmExtendFrameIntoClientArea(pContainer->hwnd, &m); -	} -} - -static LRESULT CALLBACK ContainerWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ -	TContainerData *pContainer = (TContainerData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); -	BOOL bSkinned = CSkin::m_skinEnabled ? TRUE : FALSE; - -	switch (msg) { -	case WM_NCPAINT: { -		PAINTSTRUCT ps; -		HDC hdcReal; -		RECT rcClient; -		LONG width, height; -		HDC hdc; -		CSkinItem *item = &SkinItems[0], *item_normal, *item_pressed, *item_hot; -		HICON hIcon; -		HFONT hOldFont = 0; -		TEXTMETRIC tm; - -		if (!pContainer || !bSkinned) -			break; - -		if (CSkin::m_frameSkins) { -			HDC dcFrame = GetDCEx(hwndDlg, 0, DCX_WINDOW |/*DCX_INTERSECTRGN|*/0x10000); // GetWindowDC(hwndDlg); -			LONG clip_top, clip_left; -			RECT rcText; -			HDC dcMem = CreateCompatibleDC(pContainer->cachedDC ? pContainer->cachedDC : dcFrame); -			int i; - -			RECT rcWindow, rcClient; -			POINT pt, pt1; -			GetWindowRect(hwndDlg, &rcWindow); -			GetClientRect(hwndDlg, &rcClient); -			pt.y = 0; -			pt.x = 0; -			ClientToScreen(hwndDlg, &pt); -			pt1.x = rcClient.right; -			pt1.y = rcClient.bottom; -			ClientToScreen(hwndDlg, &pt1); -			clip_top = pt.y - rcWindow.top; -			clip_left = pt.x - rcWindow.left; - -			rcWindow.right = rcWindow.right - rcWindow.left; -			rcWindow.bottom = rcWindow.bottom - rcWindow.top; -			rcWindow.left = rcWindow.top = 0; - -			HBITMAP hbmMem = CreateCompatibleBitmap(dcFrame, rcWindow.right, rcWindow.bottom); -			HBITMAP hbmOld = (HBITMAP)SelectObject(dcMem, hbmMem); - -			ExcludeClipRect(dcFrame, clip_left, clip_top, clip_left + (pt1.x - pt.x), clip_top + (pt1.y - pt.y)); -			ExcludeClipRect(dcMem, clip_left, clip_top, clip_left + (pt1.x - pt.x), clip_top + (pt1.y - pt.y)); -			CSkinItem *item = pContainer->ncActive ? &SkinItems[ID_EXTBKFRAME] : &SkinItems[ID_EXTBKFRAMEINACTIVE]; - -			CSkin::DrawItem(dcMem, &rcWindow, item); - -			TCHAR szWindowText[512]; -			GetWindowText(hwndDlg, szWindowText, SIZEOF(szWindowText)); -			szWindowText[511] = 0; -			hOldFont = (HFONT)SelectObject(dcMem, PluginConfig.hFontCaption); -			GetTextMetrics(dcMem, &tm); -			SetTextColor(dcMem, CInfoPanel::m_ipConfig.clrs[IPFONTCOUNT - 1]); -			SetBkMode(dcMem, TRANSPARENT); -			rcText.left = 20 + CSkin::m_SkinnedFrame_left + CSkin::m_bClipBorder + CSkin::m_titleBarLeftOff;//26; -			rcText.right = rcWindow.right - 3 * CSkin::m_titleBarButtonSize.cx - 11 - CSkin::m_titleBarRightOff; -			rcText.top = CSkin::m_captionOffset + CSkin::m_bClipBorder; -			rcText.bottom = rcText.top + tm.tmHeight; -			rcText.left += CSkin::m_captionPadding; -			DrawText(dcMem, szWindowText, -1, &rcText, DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX); -			SelectObject(dcMem, hOldFont); - -			// icon -			hIcon = (HICON)SendMessage(hwndDlg, WM_GETICON, ICON_SMALL, 0); -			DrawIconEx(dcMem, 4 + CSkin::m_SkinnedFrame_left + CSkin::m_bClipBorder + CSkin::m_titleBarLeftOff, rcText.top + (rcText.bottom - rcText.top) / 2 - 8, hIcon, 16, 16, 0, 0, DI_NORMAL); - -			// title buttons -			pContainer->rcClose.top = pContainer->rcMin.top = pContainer->rcMax.top = CSkin::m_titleButtonTopOff; -			pContainer->rcClose.bottom = pContainer->rcMin.bottom = pContainer->rcMax.bottom = CSkin::m_titleButtonTopOff + CSkin::m_titleBarButtonSize.cy; - -			pContainer->rcClose.right = rcWindow.right - 10 - CSkin::m_titleBarRightOff; -			pContainer->rcClose.left = pContainer->rcClose.right - CSkin::m_titleBarButtonSize.cx; - -			pContainer->rcMax.right = pContainer->rcClose.left - 2; -			pContainer->rcMax.left = pContainer->rcMax.right - CSkin::m_titleBarButtonSize.cx; - -			pContainer->rcMin.right = pContainer->rcMax.left - 2; -			pContainer->rcMin.left = pContainer->rcMin.right - CSkin::m_titleBarButtonSize.cx; - -			item_normal = &SkinItems[ID_EXTBKTITLEBUTTON]; -			item_hot = &SkinItems[ID_EXTBKTITLEBUTTONMOUSEOVER]; -			item_pressed = &SkinItems[ID_EXTBKTITLEBUTTONPRESSED]; - -			for (i = 0; i < 3; i++) { -				RECT *rc = 0; -				HICON hIcon = 0; - -				switch (i) { -				case 0: -					rc = &pContainer->rcMin; -					hIcon = CSkin::m_minIcon; -					break; -				case 1: -					rc = &pContainer->rcMax; -					hIcon = CSkin::m_maxIcon; -					break; -				case 2: -					rc = &pContainer->rcClose; -					hIcon = CSkin::m_closeIcon; -					break; -				} -				if (rc) { -					item = pContainer->buttons[i].isPressed ? item_pressed : (pContainer->buttons[i].isHot ? item_hot : item_normal); -					CSkin::DrawItem(dcMem, rc, item); -					DrawIconEx(dcMem, rc->left + ((rc->right - rc->left) / 2 - 8), rc->top + ((rc->bottom - rc->top) / 2 - 8), hIcon, 16, 16, 0, 0, DI_NORMAL); -				} -			} -			SetBkMode(dcMem, TRANSPARENT); -			BitBlt(dcFrame, 0, 0, rcWindow.right, rcWindow.bottom, dcMem, 0, 0, SRCCOPY); -			SelectObject(dcMem, hbmOld); -			DeleteObject(hbmMem); -			DeleteDC(dcMem); -			ReleaseDC(hwndDlg, dcFrame); -		} -		else mir_callNextSubclass(hwndDlg, ContainerWndProc, msg, wParam, lParam); - -		hdcReal = BeginPaint(hwndDlg, &ps); - -		GetClientRect(hwndDlg, &rcClient); -		width = rcClient.right - rcClient.left; -		height = rcClient.bottom - rcClient.top; -		if (width != pContainer->oldDCSize.cx || height != pContainer->oldDCSize.cy) { -			CSkinItem *sbaritem = &SkinItems[ID_EXTBKSTATUSBAR]; -			BOOL statusBarSkinnd = !(pContainer->dwFlags & CNT_NOSTATUSBAR) && !sbaritem->IGNORED; -			LONG sbarDelta = statusBarSkinnd ? pContainer->statusBarHeight : 0; - -			pContainer->oldDCSize.cx = width; -			pContainer->oldDCSize.cy = height; - -			if (pContainer->cachedDC) { -				SelectObject(pContainer->cachedDC, pContainer->oldHBM); -				DeleteObject(pContainer->cachedHBM); -				DeleteDC(pContainer->cachedDC); -			} -			pContainer->cachedDC = CreateCompatibleDC(hdcReal); -			pContainer->cachedHBM = CreateCompatibleBitmap(hdcReal, width, height); -			pContainer->oldHBM = (HBITMAP)SelectObject(pContainer->cachedDC, pContainer->cachedHBM); - -			hdc = pContainer->cachedDC; - -			if (!CSkin::DrawItem(hdc, &rcClient, item)) -				FillRect(hdc, &rcClient, GetSysColorBrush(COLOR_3DFACE)); - -			if (sbarDelta) { -				rcClient.top = rcClient.bottom - sbarDelta; -				CSkin::DrawItem(hdc, &rcClient, sbaritem); -			} -		} -		BitBlt(hdcReal, 0, 0, width, height, pContainer->cachedDC, 0, 0, SRCCOPY); -		EndPaint(hwndDlg, &ps); -		return 0; -	} -	case WM_NCLBUTTONDOWN: -	case WM_NCLBUTTONUP: -	case WM_NCMOUSEHOVER: -	case WM_NCMOUSEMOVE: -		if (pContainer && CSkin::m_frameSkins) { -			POINT pt; -			RECT rcWindow; -			BOOL isMin, isMax, isClose; -			int i; - -			GetCursorPos(&pt); -			GetWindowRect(hwndDlg, &rcWindow); - -			memcpy(&pContainer->oldbuttons[0], &pContainer->buttons[0], sizeof(TitleBtn) * 3); -			memset(&pContainer->buttons[0], 0, (sizeof(TitleBtn) * 3)); -			isMin = isMax = isClose = FALSE; - -			if (pt.x >= (rcWindow.left + pContainer->rcMin.left) && pt.x <= (rcWindow.left + pContainer->rcClose.right) && pt.y < rcWindow.top + 24 && wParam != HTTOPRIGHT) { -				LRESULT result = 0; //DefWindowProc(hwndDlg, msg, wParam, lParam); -				HDC hdc = GetWindowDC(hwndDlg); -				LONG left = rcWindow.left; - -				pt.y = 10; -				isMin = pt.x >= left + pContainer->rcMin.left && pt.x <= left + pContainer->rcMin.right; -				isMax = pt.x >= left + pContainer->rcMax.left && pt.x <= left + pContainer->rcMax.right; -				isClose = pt.x >= left + pContainer->rcClose.left && pt.x <= left + pContainer->rcClose.right; - -				if (msg == WM_NCMOUSEMOVE) { -					if (isMax) -						pContainer->buttons[BTN_MAX].isHot = TRUE; -					else if (isMin) -						pContainer->buttons[BTN_MIN].isHot = TRUE; -					else if (isClose) -						pContainer->buttons[BTN_CLOSE].isHot = TRUE; -				} -				else if (msg == WM_NCLBUTTONDOWN) { -					if (isMax) -						pContainer->buttons[BTN_MAX].isPressed = TRUE; -					else if (isMin) -						pContainer->buttons[BTN_MIN].isPressed = TRUE; -					else if (isClose) -						pContainer->buttons[BTN_CLOSE].isPressed = TRUE; -				} -				else if (msg == WM_NCLBUTTONUP) { -					if (isMin) -						SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MINIMIZE, 0); -					else if (isMax) { -						if (IsZoomed(hwndDlg)) -							PostMessage(hwndDlg, WM_SYSCOMMAND, SC_RESTORE, 0); -						else -							PostMessage(hwndDlg, WM_SYSCOMMAND, SC_MAXIMIZE, 0); -					} -					else if (isClose) -						PostMessage(hwndDlg, WM_SYSCOMMAND, SC_CLOSE, 0); -				} -				for (i = 0; i < 3; i++) { -					if (pContainer->buttons[i].isHot != pContainer->oldbuttons[i].isHot) { -						RECT *rc = 0; -						HICON hIcon = 0; - -						switch (i) { -						case 0: -							rc = &pContainer->rcMin; -							hIcon = CSkin::m_minIcon; -							break; -						case 1: -							rc = &pContainer->rcMax; -							hIcon = CSkin::m_maxIcon; -							break; -						case 2: -							rc = &pContainer->rcClose; -							hIcon = CSkin::m_closeIcon; -							break; -						} -						if (rc) { -							CSkinItem *item = &SkinItems[pContainer->buttons[i].isPressed ? ID_EXTBKTITLEBUTTONPRESSED : (pContainer->buttons[i].isHot ? ID_EXTBKTITLEBUTTONMOUSEOVER : ID_EXTBKTITLEBUTTON)]; -							CSkin::DrawItem(hdc, rc, item); -							DrawIconEx(hdc, rc->left + ((rc->right - rc->left) / 2 - 8), rc->top + ((rc->bottom - rc->top) / 2 - 8), hIcon, 16, 16, 0, 0, DI_NORMAL); -						} -					} -				} -				ReleaseDC(hwndDlg, hdc); -				return result; -			} -			else { -				LRESULT result = DefWindowProc(hwndDlg, msg, wParam, lParam); -				RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_NOCHILDREN); -				return result; -			} -		} -		break; - -	case WM_SETCURSOR: -		if (CSkin::m_frameSkins && (HWND)wParam == hwndDlg) { -			DefWindowProc(hwndDlg, msg, wParam, lParam); -			RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_NOCHILDREN); -			return 1; -		} -		break; - -	case WM_NCCALCSIZE: -		if (!CSkin::m_frameSkins) -			break; - -		if (wParam) { -			RECT *rc; -			NCCALCSIZE_PARAMS *ncsp = (NCCALCSIZE_PARAMS *)lParam; - -			DefWindowProc(hwndDlg, msg, wParam, lParam); -			rc = &ncsp->rgrc[0]; - -			rc->left += CSkin::m_realSkinnedFrame_left; -			rc->right -= CSkin::m_realSkinnedFrame_right; -			rc->bottom -= CSkin::m_realSkinnedFrame_bottom; -			rc->top += CSkin::m_realSkinnedFrame_caption; -			return TRUE; -		} - -		return DefWindowProc(hwndDlg, msg, wParam, lParam); - -	case WM_NCACTIVATE: -		if (pContainer) { -			pContainer->ncActive = wParam; -			if (bSkinned && CSkin::m_frameSkins) { -				SendMessage(hwndDlg, WM_NCPAINT, 0, 0); -				return 1; -			} -		} -		break; -	case WM_SETTEXT: -	case WM_SETICON: -		if (CSkin::m_frameSkins) { -			DefWindowProc(hwndDlg, msg, wParam, lParam); -			RedrawWindow(hwndDlg, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN); -			return 0; -		} -		break; - -	case WM_NCHITTEST: -	{ -		RECT r; -		POINT pt; -		int clip = CSkin::m_bClipBorder; - -		if (!pContainer) -			break; - -		if (!(pContainer->dwFlags & CNT_NOTITLE)) -			break; - -		GetWindowRect(hwndDlg, &r); -		GetCursorPos(&pt); -		if (pt.y <= r.bottom && pt.y >= r.bottom - clip - 6) { -			if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10) -				return HTBOTTOM; -			if (pt.x < r.left + clip + 10) -				return HTBOTTOMLEFT; -			if (pt.x > r.right - clip - 10) -				return HTBOTTOMRIGHT; - -		} -		else if (pt.y >= r.top && pt.y <= r.top + 6) { -			if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10) -				return HTTOP; -			if (pt.x < r.left + clip + 10) -				return HTTOPLEFT; -			if (pt.x > r.right - clip - 10) -				return HTTOPRIGHT; -		} -		else if (pt.x >= r.left && pt.x <= r.left + clip + 6) -			return HTLEFT; -		else if (pt.x >= r.right - clip - 6 && pt.x <= r.right) -			return HTRIGHT; -	} -	return(DefWindowProc(hwndDlg, WM_NCHITTEST, wParam, lParam)); - -	case 0xae:						// must be some undocumented message - seems it messes with the title bar... -		if (CSkin::m_frameSkins) -			return 0; -	} -	return mir_callNextSubclass(hwndDlg, ContainerWndProc, msg, wParam, lParam); -} - -// container window procedure... - -static BOOL fHaveTipper = FALSE; - -static INT_PTR CALLBACK DlgProcContainer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ -	int iItem = 0; -	TCITEM item; -	RECT rc; -	POINT pt; - -	TContainerData *pContainer = (TContainerData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); -	BOOL bSkinned = CSkin::m_skinEnabled ? TRUE : FALSE; -	HWND hwndTab = GetDlgItem(hwndDlg, IDC_MSGTABS); - -	switch (msg) { -	case WM_INITDIALOG: -		fHaveTipper = ServiceExists("mToolTip/ShowTip"); -		fForceOverlayIcons = M.GetByte("forceTaskBarStatusOverlays", 0) ? true : false; - -		pContainer = (TContainerData*)lParam; -		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)pContainer); -		mir_subclassWindow(hwndDlg, ContainerWndProc); - -		pContainer->hwnd = hwndDlg; -		{ -			DWORD dwCreateFlags = pContainer->dwFlags; -			pContainer->isCloned = (dwCreateFlags & CNT_CREATE_CLONED); -			pContainer->fPrivateThemeChanged = FALSE; - -			SendMessage(hwndDlg, DM_OPTIONSAPPLIED, 0, 0);          // set options... -			pContainer->dwFlags |= dwCreateFlags; - -			LoadOverrideTheme(pContainer); -			DWORD ws = GetWindowLongPtr(hwndTab, GWL_STYLE); -			if (pContainer->dwFlagsEx & TCF_FLAT) -				ws |= TCS_BUTTONS; - -			memset((void*)&pContainer->mOld, -1000, sizeof(MARGINS)); - -			if (pContainer->dwFlagsEx & TCF_SINGLEROWTABCONTROL) { -				ws &= ~TCS_MULTILINE; -				ws |= TCS_SINGLELINE; -				ws |= TCS_FIXEDWIDTH; -			} -			else { -				ws &= ~TCS_SINGLELINE; -				ws |= TCS_MULTILINE; -				if (ws & TCS_BUTTONS) -					ws |= TCS_FIXEDWIDTH; -			} -			SetWindowLongPtr(hwndTab, GWL_STYLE, ws); - -			pContainer->buttonItems = g_ButtonSet.items; - -			pContainer->dwFlags = ((pContainer->dwFlagsEx & (TCF_SBARLEFT | TCF_SBARRIGHT)) ? -				pContainer->dwFlags | CNT_SIDEBAR : pContainer->dwFlags & ~CNT_SIDEBAR); - -			pContainer->SideBar = new CSideBar(pContainer); -			pContainer->MenuBar = new CMenuBar(hwndDlg, pContainer); - -			SetClassLongPtr(hwndDlg, GCL_STYLE, GetClassLongPtr(hwndDlg, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW)); -			SetClassLongPtr(hwndTab, GCL_STYLE, GetClassLongPtr(hwndTab, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW)); - -			SetClassLongPtr(hwndDlg, GCL_STYLE, GetClassLongPtr(hwndDlg, GCL_STYLE) & ~CS_DROPSHADOW); - -			// additional system menu items... -			HMENU hSysmenu = GetSystemMenu(hwndDlg, FALSE); -			int iMenuItems = GetMenuItemCount(hSysmenu); - -			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_SEPARATOR, 0, _T("")); -			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_STRING, IDM_STAYONTOP, TranslateT("Stay on top")); -			if (!CSkin::m_frameSkins) -				InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_STRING, IDM_NOTITLE, TranslateT("Hide title bar")); -			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_SEPARATOR, 0, _T("")); -			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_STRING, IDM_MOREOPTIONS, TranslateT("Container options...")); -			SetWindowText(hwndDlg, TranslateT("Message session...")); -			SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)PluginConfig.g_iconContainer); - -			// make the tab control the controlling parent window for all message dialogs - -			ws = GetWindowLongPtr(hwndTab, GWL_EXSTYLE); -			SetWindowLongPtr(hwndTab, GWL_EXSTYLE, ws | WS_EX_CONTROLPARENT); - -			LONG x_pad = M.GetByte("x-pad", 3) + (pContainer->dwFlagsEx & TCF_CLOSEBUTTON ? 7 : 0); -			LONG y_pad = M.GetByte("y-pad", 3) + ((pContainer->dwFlags & CNT_TABSBOTTOM) ? 1 : 0); - -			if (pContainer->dwFlagsEx & TCF_FLAT) -				y_pad++; //(pContainer->dwFlags & CNT_TABSBOTTOM ? 1 : 2); - -			TabCtrl_SetPadding(hwndTab, x_pad, y_pad); - -			TabCtrl_SetImageList(hwndTab, PluginConfig.g_hImageList); - -			SendMessage(hwndDlg, DM_CONFIGURECONTAINER, 0, 10); - -			// context menu -			pContainer->hMenuContext = PluginConfig.g_hMenuContext; - -			// tab tooltips... -			if (!fHaveTipper || M.GetByte("d_tooltips", 0) == 0) { -				pContainer->hwndTip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, -					CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, g_hInst, (LPVOID)NULL); - -				if (pContainer->hwndTip) { -					SetWindowPos(pContainer->hwndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); -					TabCtrl_SetToolTips(hwndTab, pContainer->hwndTip); -				} -			} -			else pContainer->hwndTip = 0; - -			if (pContainer->dwFlags & CNT_CREATE_MINIMIZED) { -				WINDOWPLACEMENT wp = { 0 }; -				wp.length = sizeof(wp); - -				SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) & ~WS_VISIBLE); -				ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE); -				SendMessage(hwndDlg, DM_RESTOREWINDOWPOS, 0, 0); -				//GetClientRect(hwndDlg, &pContainer->rcSaved); -				ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE); -				GetWindowPlacement(hwndDlg, &wp); -				pContainer->rcSaved.left = pContainer->rcSaved.top = 0; -				pContainer->rcSaved.right = wp.rcNormalPosition.right - wp.rcNormalPosition.left; -				pContainer->rcSaved.bottom = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; -			} -			else { -				SendMessage(hwndDlg, DM_RESTOREWINDOWPOS, 0, 0); -				ShowWindow(hwndDlg, SW_SHOWNORMAL); -			} -		} - -		// prevent ugly back background being visible while tabbed clients are created -		if (M.isAero()) { -			MARGINS m = { -1 }; -			CMimAPI::m_pfnDwmExtendFrameIntoClientArea(hwndDlg, &m); -		} -		return TRUE; - -	case DM_RESTOREWINDOWPOS: -		// retrieve the container window geometry information from the database. -		if (pContainer->isCloned && pContainer->hContactFrom != 0 && !(pContainer->dwFlags & CNT_GLOBALSIZE)) { -			if (Utils_RestoreWindowPosition(hwndDlg, pContainer->hContactFrom, SRMSGMOD_T, "split")) { -				if (Utils_RestoreWindowPositionNoMove(hwndDlg, pContainer->hContactFrom, SRMSGMOD_T, "split")) -					if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, "split")) -						if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, "split")) -							SetWindowPos(hwndDlg, 0, 50, 50, 450, 300, SWP_NOZORDER | SWP_NOACTIVATE); -			} -		} -		else { -			if (pContainer->dwFlags & CNT_GLOBALSIZE) { -				if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, "split")) -					if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, "split")) -						SetWindowPos(hwndDlg, 0, 50, 50, 450, 300, SWP_NOZORDER | SWP_NOACTIVATE); -			} -			else { -				char szCName[CONTAINER_NAMELEN + 20]; -				mir_snprintf(szCName, SIZEOF(szCName), "%s%d", CONTAINER_PREFIX, pContainer->iContainerIndex); -				if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, szCName)) { -					if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, szCName)) -						if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, "split")) -							if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, "split")) -								SetWindowPos(hwndDlg, 0, 50, 50, 450, 300, SWP_NOZORDER | SWP_NOACTIVATE); -				} -			} -		} -		return 0; - -	case WM_SIZE: -		if (IsIconic(hwndDlg)) -			pContainer->dwFlags |= CNT_DEFERREDSIZEREQUEST; -		else { -			RECT rcClient, rcUnadjusted; -			TCITEM item = { 0 }; - -			GetClientRect(hwndDlg, &rcClient); -			pContainer->MenuBar->getClientRect(); - -			if (pContainer->hwndStatus) { -				TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -				SendMessage(pContainer->hwndStatus, WM_USER + 101, 0, (LPARAM)dat); - -				RECT rcs; -				GetWindowRect(pContainer->hwndStatus, &rcs); -				pContainer->statusBarHeight = (rcs.bottom - rcs.top) + 1; -				SendMessage(pContainer->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, 0); -			} -			else pContainer->statusBarHeight = 0; - -			CopyRect(&pContainer->rcSaved, &rcClient); -			rcUnadjusted = rcClient; - -			pContainer->MenuBar->Resize(LOWORD(lParam)); -			LONG rebarHeight = pContainer->MenuBar->getHeight(); -			pContainer->MenuBar->Show((pContainer->dwFlags & CNT_NOMENUBAR) ? SW_HIDE : SW_SHOW); - -			LONG sbarWidth = pContainer->SideBar->getWidth(); -			LONG sbarWidth_left = pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_LEFT ? sbarWidth : 0; - -			if (lParam) { -				DWORD	dwSWPFlags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_DEFERERASE | SWP_NOCOPYBITS; // | SWP_NOSENDCHANGING  | SWP_ASYNCWINDOWPOS; -				SetWindowPos(hwndTab, 0, pContainer->tBorder_outer_left + sbarWidth_left, pContainer->tBorder_outer_top + rebarHeight, -					(rcClient.right - rcClient.left) - (pContainer->tBorder_outer_left + pContainer->tBorder_outer_right + sbarWidth), -					(rcClient.bottom - rcClient.top) - pContainer->statusBarHeight - (pContainer->tBorder_outer_top + pContainer->tBorder_outer_bottom) - rebarHeight, dwSWPFlags); -			} - -			pContainer->SideBar->resizeScrollWnd(sbarWidth_left ? pContainer->tBorder_outer_left : rcClient.right - pContainer->tBorder_outer_right - (sbarWidth - 2), -				pContainer->tBorder_outer_top + rebarHeight, 0, -				(rcClient.bottom - rcClient.top) - pContainer->statusBarHeight - (pContainer->tBorder_outer_top + pContainer->tBorder_outer_bottom) - rebarHeight); - -			AdjustTabClientRect(pContainer, &rcClient); - -			BOOL sizeChanged = (((rcClient.right - rcClient.left) != pContainer->preSIZE.cx) || ((rcClient.bottom - rcClient.top) != pContainer->preSIZE.cy)); -			if (sizeChanged) { -				pContainer->preSIZE.cx = rcClient.right - rcClient.left; -				pContainer->preSIZE.cy = rcClient.bottom - rcClient.top; -			} - -			// we care about all client sessions, but we really resize only the active tab (hwndActive) -			// we tell inactive tabs to resize theirselves later when they get activated (DM_CHECKSIZE -			// just queues a resize request) -			int nCount = TabCtrl_GetItemCount(hwndTab); - -			for (int i = 0; i < nCount; i++) { -				item.mask = TCIF_PARAM; -				TabCtrl_GetItem(hwndTab, i, &item); -				if ((HWND)item.lParam == pContainer->hwndActive) { -					SetWindowPos((HWND)item.lParam, 0, rcClient.left, rcClient.top, (rcClient.right - rcClient.left), (rcClient.bottom - rcClient.top), -						SWP_NOSENDCHANGING | SWP_NOACTIVATE/*|SWP_NOCOPYBITS*/); -					if (!pContainer->bSizingLoop && sizeChanged) { -						TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -						DM_ScrollToBottom(dat, 0, 1); -					} -				} -				else if (sizeChanged) -					SendMessage((HWND)item.lParam, DM_CHECKSIZE, 0, 0); -			} -			pContainer->SideBar->scrollIntoView(); - -			if (!M.isAero()) {					// aero mode uses buffered paint, no forced redraw needed -				RedrawWindow(hwndTab, NULL, NULL, RDW_INVALIDATE | (pContainer->bSizingLoop ? RDW_ERASE : 0)); -				RedrawWindow(hwndDlg, NULL, NULL, (bSkinned ? RDW_FRAME : 0) | RDW_INVALIDATE | ((pContainer->bSizingLoop || wParam == SIZE_RESTORED) ? RDW_ERASE : 0)); -			} - -			if (pContainer->hwndStatus) -				InvalidateRect(pContainer->hwndStatus, NULL, FALSE); - -			if ((CSkin::m_bClipBorder != 0 || CSkin::m_bRoundedCorner) && CSkin::m_frameSkins) { -				HRGN rgn; -				int clip = CSkin::m_bClipBorder; - -				RECT rcWindow; -				GetWindowRect(hwndDlg, &rcWindow); - -				if (CSkin::m_bRoundedCorner) -					rgn = CreateRoundRectRgn(clip, clip, (rcWindow.right - rcWindow.left) - clip + 1, -					(rcWindow.bottom - rcWindow.top) - clip + 1, CSkin::m_bRoundedCorner + clip, CSkin::m_bRoundedCorner + clip); -				else -					rgn = CreateRectRgn(clip, clip, (rcWindow.right - rcWindow.left) - clip, (rcWindow.bottom - rcWindow.top) - clip); -				SetWindowRgn(hwndDlg, rgn, TRUE); -			} -			else if (CSkin::m_frameSkins) -				SetWindowRgn(hwndDlg, NULL, TRUE); -		} -		break; - -	case WM_NOTIFY: -		if (pContainer == NULL) -			break; -		if (pContainer->MenuBar) { -			LRESULT processed = pContainer->MenuBar->processMsg(msg, wParam, lParam); -			if (processed != -1) { -				SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, processed); -				return(processed); -			} -		} - -		if (pContainer->hwndStatus != 0 && ((LPNMHDR)lParam)->hwndFrom == pContainer->hwndStatus) { -			switch (((LPNMHDR)lParam)->code) { -			case NM_CLICK: -			case NM_RCLICK: -				NMMOUSE *nm = (NMMOUSE*)lParam; -				int nPanel; -				if (nm->dwItemSpec == 0xFFFFFFFE) { -					nPanel = 2; -					SendMessage(pContainer->hwndStatus, SB_GETRECT, nPanel, (LPARAM)&rc); -					if (nm->pt.x > rc.left && nm->pt.x < rc.right) -						goto panel_found; -					else -						return FALSE; -				} -				else nPanel = nm->dwItemSpec; -			panel_found: -				if (nPanel == 2) { -					TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -					SendMessage(pContainer->hwndStatus, SB_GETRECT, nPanel, (LPARAM)&rc); -					if (dat) -						CheckStatusIconClick(dat, nm->pt, rc, 2, ((LPNMHDR)lParam)->code); -				} -				else if (((LPNMHDR)lParam)->code == NM_RCLICK) { -					GetCursorPos(&pt); -					MCONTACT hContact = 0; -					SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); -					if (hContact) { -						int iSel = 0; -						HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, hContact, 0); -						iSel = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); -						if (iSel) -							CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(iSel), MPCF_CONTACTMENU), hContact); -						DestroyMenu(hMenu); -					} -				} -				return TRUE; -			} -			break; -		} - -		switch (((LPNMHDR)lParam)->code) { -		case TCN_SELCHANGE: -			memset(&item, 0, sizeof(item)); -			iItem = TabCtrl_GetCurSel(hwndTab); -			item.mask = TCIF_PARAM; -			if (TabCtrl_GetItem(hwndTab, iItem, &item)) { -				if ((HWND)item.lParam != pContainer->hwndActive) -					if (pContainer->hwndActive && IsWindow(pContainer->hwndActive)) -						ShowWindow(pContainer->hwndActive, SW_HIDE); - -				pContainer->hwndActive = (HWND)item.lParam; -				SendMessage((HWND)item.lParam, DM_SAVESIZE, 0, 1); -				ShowWindow((HWND)item.lParam, SW_SHOW); -				if (!IsIconic(hwndDlg)) -					SetFocus(pContainer->hwndActive); -			} -			SendMessage(hwndTab, EM_VALIDATEBOTTOM, 0, 0); -			return 0; - -			// tooltips -		case NM_RCLICK: -			int iItem; -			bool fFromSidebar = false; -			TCITEM item = { 0 }; -			TWindowData *dat = 0; - -			GetCursorPos(&pt); -			HMENU subMenu = GetSubMenu(pContainer->hMenuContext, 0); - -			if (((LPNMHDR)lParam)->idFrom == IDC_MSGTABS) { -				if ((iItem = GetTabItemFromMouse(hwndTab, &pt)) == -1) -					break; - -				item.mask = TCIF_PARAM; -				TabCtrl_GetItem(hwndTab, iItem, &item); -				if (item.lParam && IsWindow((HWND)item.lParam)) -					dat = (TWindowData*)GetWindowLongPtr((HWND)item.lParam, GWLP_USERDATA); -			} -			// sent from a sidebar button (RMB click) instead of the tab control -			else if (((LPNMHDR)lParam)->idFrom == 5000) { -				TSideBarNotify* n = reinterpret_cast<TSideBarNotify *>(lParam); -				dat = const_cast<TWindowData *>(n->dat); -				fFromSidebar = true; -			} - -			if (dat) -				MsgWindowUpdateMenu(dat, subMenu, MENU_TABCONTEXT); - -			int iSelection = TrackPopupMenu(subMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); -			if (iSelection >= IDM_CONTAINERMENU) { -				char szIndex[10]; -				itoa(iSelection - IDM_CONTAINERMENU, szIndex, 10); -				if (iSelection - IDM_CONTAINERMENU >= 0) { -					ptrT tszName(db_get_tsa(NULL, CONTAINER_KEY, szIndex)); -					if (tszName != NULL) -						SendMessage((HWND)item.lParam, DM_CONTAINERSELECTED, 0, tszName); -				} -				return 1; -			} -			switch (iSelection) { -			case ID_TABMENU_CLOSETAB: -				if (fFromSidebar) -					SendMessage(dat->hwnd, WM_CLOSE, 1, 0); -				else -					SendMessage(hwndDlg, DM_CLOSETABATMOUSE, 0, (LPARAM)&pt); -				break; -			case ID_TABMENU_CLOSEOTHERTABS: -				CloseOtherTabs(hwndTab, *dat); -				break; -			case ID_TABMENU_SAVETABPOSITION: -				db_set_dw(dat->hContact, SRMSGMOD_T, "tabindex", dat->iTabID * 100); -				break; -			case ID_TABMENU_CLEARSAVEDTABPOSITION: -				db_unset(dat->hContact, SRMSGMOD_T, "tabindex"); -				break; -			case ID_TABMENU_LEAVECHATROOM: -				if (dat && dat->bType == SESSIONTYPE_CHAT) { -					SESSION_INFO *si = dat->si; -					if (si && dat->hContact) { -						char *szProto = GetContactProto(dat->hContact); -						if (szProto) -							CallProtoService(szProto, PS_LEAVECHAT, dat->hContact, 0); -					} -				} -				break; -			case ID_TABMENU_ATTACHTOCONTAINER: -				if ((iItem = GetTabItemFromMouse(hwndTab, &pt)) == -1) -					break; -				memset(&item, 0, sizeof(item)); -				item.mask = TCIF_PARAM; -				TabCtrl_GetItem(hwndTab, iItem, &item); -				CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_SELECTCONTAINER), hwndDlg, SelectContainerDlgProc, (LPARAM)item.lParam); -				break; -			case ID_TABMENU_CONTAINEROPTIONS: -				if (pContainer->hWndOptions == 0) -					CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CONTAINEROPTIONS), hwndDlg, DlgProcContainerOptions, (LPARAM)pContainer); -				break; -			case ID_TABMENU_CLOSECONTAINER: -				SendMessage(hwndDlg, WM_CLOSE, 0, 0); -				break; -			} -			InvalidateRect(hwndTab, NULL, FALSE); -			return 1; -		} -		break; - -	case WM_COMMAND: -		MCONTACT hContact; -		{ -			bool fProcessContactMenu = pContainer->MenuBar->isContactMenu(); -			bool fProcessMainMenu = pContainer->MenuBar->isMainMenu(); -			pContainer->MenuBar->Cancel(); - -			TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -			DWORD dwOldFlags = pContainer->dwFlags; - -			if (dat) { -				if (fProcessContactMenu) -					return(CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact)); -				else if (fProcessMainMenu) { -					return(CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), 0)); -				} -				else if (MsgWindowMenuHandler(dat, LOWORD(wParam), MENU_PICMENU) == 1) -					break; -			} -			SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); -			if (LOWORD(wParam) == IDC_TBFIRSTUID - 1) -				break; - -			switch (LOWORD(wParam)) { -			case IDC_TOGGLESIDEBAR: -				GetWindowRect(hwndDlg, &rc); -				{ -					LONG dwNewLeft; -					bool fVisible = pContainer->SideBar->isVisible(); -					if (fVisible) { -						dwNewLeft = pContainer->SideBar->getWidth(); -						pContainer->SideBar->setVisible(false); -					} -					else { -						pContainer->SideBar->setVisible(true); -						dwNewLeft = -(pContainer->SideBar->getWidth()); -					} - -					pContainer->preSIZE.cx = pContainer->preSIZE.cy = 0; -					pContainer->oldDCSize.cx = pContainer->oldDCSize.cy = 0; -				} - -				PostMessage(hwndDlg, WM_SIZE, 0, 1); -				break; - -			case IDC_SIDEBARDOWN: -			case IDC_SIDEBARUP: -			{ -				HWND hwnd = GetFocus(); -				pContainer->SideBar->processScrollerButtons(LOWORD(wParam)); -				SetFocus(hwnd); -			} -			break; - -			default: -				Utils::CmdDispatcher(Utils::CMD_CONTAINER, hwndDlg, LOWORD(wParam), wParam, lParam, 0, pContainer); -			} - -			if (pContainer->dwFlags != dwOldFlags) -				SendMessage(hwndDlg, DM_CONFIGURECONTAINER, 0, 0); -		} -		break; - -	case WM_ENTERSIZEMOVE: -		GetClientRect(hwndTab, &rc); -		{ -			SIZE sz; -			sz.cx = rc.right - rc.left; -			sz.cy = rc.bottom - rc.top; -			pContainer->oldSize = sz; -			pContainer->bSizingLoop = TRUE; -		} -		break; - -	case WM_EXITSIZEMOVE: -		GetClientRect(hwndTab, &rc); -		if (!((rc.right - rc.left) == pContainer->oldSize.cx && (rc.bottom - rc.top) == pContainer->oldSize.cy)) { -			TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -			DM_ScrollToBottom(dat, 0, 0); -			SendMessage(pContainer->hwndActive, WM_SIZE, 0, 0); -		} -		pContainer->bSizingLoop = FALSE; -		break; - -	// determine minimum and maximum size limits -	// 1) for maximizing the window when the "vertical maximize" option is set -	// 2) to limit the minimum height when manually resizing the window -	// (this avoids overlapping of controls inside the window and ensures -	// that at least 2 lines of the message log are always visible). -	case WM_GETMINMAXINFO: -		RECT rcWindow; -		{ -			RECT rcClient = { 0 }; - -			MINMAXINFO *mmi = (MINMAXINFO *)lParam; -			mmi->ptMinTrackSize.x = 275; -			mmi->ptMinTrackSize.y = 130; -			GetClientRect(hwndTab, &rc); -			if (pContainer->hwndActive)								// at container creation time, there is no hwndActive yet.. -				GetClientRect(pContainer->hwndActive, &rcClient); -			GetWindowRect(hwndDlg, &rcWindow); -			pt.y = rc.top; -			TabCtrl_AdjustRect(hwndTab, FALSE, &rc); -			// uChildMinHeight holds the min height for the client window only -			// so let's add the container's vertical padding (title bar, tab bar, -			// window border, status bar) to this value -			if (pContainer->hwndActive) -				mmi->ptMinTrackSize.y = pContainer->uChildMinHeight + (pContainer->hwndActive ? ((rcWindow.bottom - rcWindow.top) - rcClient.bottom) : 0); - -			if (pContainer->dwFlags & CNT_VERTICALMAX || (GetKeyState(VK_CONTROL) & 0x8000)) { -				RECT rcDesktop = { 0 }; -				BOOL fDesktopValid = FALSE; -				int monitorXOffset = 0; -				WINDOWPLACEMENT wp = { 0 }; - -				HMONITOR hMonitor = MonitorFromWindow(hwndDlg, 2); -				if (hMonitor) { -					MONITORINFO mi = { 0 }; -					mi.cbSize = sizeof(mi); -					GetMonitorInfoA(hMonitor, &mi); -					rcDesktop = mi.rcWork; -					OffsetRect(&rcDesktop, -mi.rcMonitor.left, -mi.rcMonitor.top); -					monitorXOffset = mi.rcMonitor.left; -					fDesktopValid = TRUE; -				} -				if (!fDesktopValid) -					SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0); - -				wp.length = sizeof(wp); -				GetWindowPlacement(hwndDlg, &wp); -				mmi->ptMaxSize.y = rcDesktop.bottom - rcDesktop.top; -				mmi->ptMaxSize.x = wp.rcNormalPosition.right - wp.rcNormalPosition.left; -				mmi->ptMaxPosition.x = wp.rcNormalPosition.left - monitorXOffset; -				mmi->ptMaxPosition.y = 0; -				if (IsIconic(hwndDlg)) { -					mmi->ptMaxPosition.x += rcDesktop.left; -					mmi->ptMaxPosition.y += rcDesktop.top; -				} - -				// protect against invalid values... -				if (mmi->ptMinTrackSize.y < 50 || mmi->ptMinTrackSize.y > rcDesktop.bottom) -					mmi->ptMinTrackSize.y = 130; -			} -		} -		return 0; - -	case DM_UPDATETITLE: -		{ -			MCONTACT hContact = 0; -			TWindowData *dat = NULL; - -			if (lParam) {               // lParam != 0 means sent by a chat window -				TCHAR szText[512]; -				dat = (TWindowData*)GetWindowLongPtr((HWND)wParam, GWLP_USERDATA); -				GetWindowText((HWND)wParam, szText, SIZEOF(szText)); -				szText[SIZEOF(szText) - 1] = 0; -				SetWindowText(hwndDlg, szText); -				if (dat) -					SendMessage(hwndDlg, DM_SETICON, (WPARAM)dat, (LPARAM)(dat->hTabIcon != dat->hTabStatusIcon ? dat->hTabIcon : dat->hTabStatusIcon)); -				return 0; -			} -			if (wParam == 0) {           // no hContact given - obtain the hContact for the active tab -				if (pContainer->hwndActive && IsWindow(pContainer->hwndActive)) -					SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); -				else -					break; -				dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -			} -			else { -				HWND hwnd = M.FindWindow(wParam); -				if (hwnd == 0) { -					SESSION_INFO *si = SM_FindSessionByHCONTACT(wParam); -					if (si) { -						SendMessage(si->hWnd, GC_UPDATETITLE, 0, 0); -						return 0; -					} -				} -				hContact = wParam; -				if (hwnd && hContact) -					dat = (TWindowData*)GetWindowLongPtr(hwnd, GWLP_USERDATA); -			} -			if (dat) { -				SendMessage(hwndDlg, DM_SETICON, (WPARAM)dat, (LPARAM)(dat->hXStatusIcon ? dat->hXStatusIcon : dat->hTabStatusIcon)); -				TCHAR *szNewTitle = Utils::FormatTitleBar(dat, pContainer->settings->szTitleFormat); -				if (szNewTitle) { -					SetWindowText(hwndDlg, szNewTitle); -					mir_free(szNewTitle); -				} -			} -		} -		return 0; - -	case WM_TIMER: -		if (wParam == TIMERID_HEARTBEAT) { -			if (GetForegroundWindow() != hwndDlg && (pContainer->settings->autoCloseSeconds > 0) && !pContainer->fHidden) { -				BOOL fResult = TRUE; -				BroadCastContainer(pContainer, DM_CHECKAUTOHIDE, (WPARAM)pContainer->settings->autoCloseSeconds, (LPARAM)&fResult); - -				if (fResult && 0 == pContainer->hWndOptions) -					PostMessage(hwndDlg, WM_CLOSE, 1, 0); -			} - -			TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -			if (dat && dat->bType == SESSIONTYPE_IM) { -				if (dat->idle && pContainer->hwndActive && IsWindow(pContainer->hwndActive)) -					dat->Panel->Invalidate(TRUE); -			} -			else if (dat) -				SendMessage(dat->hwnd, GC_UPDATESTATUSBAR, 0, 0); -		} -		else if (wParam == TIMERID_HOVER) { -			RECT rcWindow; -			GetWindowRect(hwndDlg, &rcWindow); -		} -		break; - -	case WM_SYSCOMMAND: -		switch (wParam) { -		case IDM_STAYONTOP: -			SetWindowPos(hwndDlg, (pContainer->dwFlags & CNT_STICKY) ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); -			CheckMenuItem(GetSystemMenu(hwndDlg, FALSE), IDM_STAYONTOP, (pContainer->dwFlags & CNT_STICKY) ? MF_BYCOMMAND | MF_UNCHECKED : MF_BYCOMMAND | MF_CHECKED); -			ApplyContainerSetting(pContainer, CNT_STICKY, pContainer->dwFlags & CNT_STICKY ? 0 : 1, false); -			break; -		case IDM_NOTITLE: -			pContainer->oldSize.cx = 0; -			pContainer->oldSize.cy = 0; - -			CheckMenuItem(GetSystemMenu(hwndDlg, FALSE), IDM_NOTITLE, (pContainer->dwFlags & CNT_NOTITLE) ? MF_BYCOMMAND | MF_UNCHECKED : MF_BYCOMMAND | MF_CHECKED); -			ApplyContainerSetting(pContainer, CNT_NOTITLE, pContainer->dwFlags & CNT_NOTITLE ? 0 : 1, false); -			break; -		case IDM_MOREOPTIONS: -			if (IsIconic(pContainer->hwnd)) -				SendMessage(pContainer->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); -			if (pContainer->hWndOptions == 0) -				CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CONTAINEROPTIONS), hwndDlg, DlgProcContainerOptions, (LPARAM)pContainer); -			break; -		case SC_MAXIMIZE: -			pContainer->oldSize.cx = pContainer->oldSize.cy = 0; -			break; -		case SC_RESTORE: -			pContainer->oldSize.cx = pContainer->oldSize.cy = 0; -			memset((void*)&pContainer->mOld, -1000, sizeof(MARGINS)); -			break; -		case SC_MINIMIZE: -			TWindowData *dat = reinterpret_cast<TWindowData *>(GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA)); -			if (dat) { -				GetWindowRect(pContainer->hwndActive, &pContainer->rcLogSaved); -				pContainer->ptLogSaved.x = pContainer->rcLogSaved.left; -				pContainer->ptLogSaved.y = pContainer->rcLogSaved.top; -				ScreenToClient(hwndDlg, &pContainer->ptLogSaved); -			} -		} -		break; - -	case DM_SELECTTAB: -		switch (wParam) { -		case DM_SELECT_BY_HWND: -			ActivateTabFromHWND(hwndTab, (HWND)lParam); -			break; - -		case DM_SELECT_NEXT: -		case DM_SELECT_PREV: -		case DM_SELECT_BY_INDEX: -			int iItems = TabCtrl_GetItemCount(hwndTab); -			if (iItems == 1) -				break; - -			int iCurrent = TabCtrl_GetCurSel(hwndTab), iNewTab; - -			if (wParam == DM_SELECT_PREV) -				iNewTab = iCurrent ? iCurrent - 1 : iItems - 1;     // cycle if current is already the leftmost tab.. -			else if (wParam == DM_SELECT_NEXT) -				iNewTab = (iCurrent == (iItems - 1)) ? 0 : iCurrent + 1; -			else { -				if ((int)lParam > iItems) -					break; -				iNewTab = lParam - 1; -			} - -			if (iNewTab != iCurrent) { -				memset(&item, 0, sizeof(item)); -				item.mask = TCIF_PARAM; -				if (TabCtrl_GetItem(hwndTab, iNewTab, &item)) { -					TabCtrl_SetCurSel(hwndTab, iNewTab); -					ShowWindow(pContainer->hwndActive, SW_HIDE); -					pContainer->hwndActive = (HWND)item.lParam; -					ShowWindow((HWND)item.lParam, SW_SHOW); -					SetFocus(pContainer->hwndActive); -				} -			} -			break; -		} -		break; - -	case WM_INITMENUPOPUP: -		pContainer->MenuBar->setActive(reinterpret_cast<HMENU>(wParam)); -		break; - -	case WM_LBUTTONDOWN: -		if (pContainer->dwFlags & CNT_NOTITLE) { -			GetCursorPos(&pt); -			return SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); -		} -		break; - -		// pass the WM_ACTIVATE msg to the active message dialog child -	case WM_NCACTIVATE: -		if (IsWindowVisible(hwndDlg)) -			pContainer->fHidden = false; -		break; - -	case WM_ACTIVATE: -		if (pContainer == NULL) -			break; - -		if (LOWORD(wParam == WA_INACTIVE)) -			BroadCastContainer(pContainer, DM_CHECKINFOTIP, wParam, lParam); - -		if (LOWORD(wParam == WA_INACTIVE) && (HWND)lParam != PluginConfig.g_hwndHotkeyHandler && GetParent((HWND)lParam) != hwndDlg) { -			BOOL fTransAllowed = !bSkinned || PluginConfig.m_bIsVista; - -			if (pContainer->dwFlags & CNT_TRANSPARENCY && fTransAllowed) { -				SetLayeredWindowAttributes(hwndDlg, Skin->getColorKey(), (BYTE)HIWORD(pContainer->settings->dwTransparency), (pContainer->dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0)); -			} -		} -		pContainer->hwndSaved = 0; - -		if (LOWORD(wParam) != WA_ACTIVE) { -			pContainer->MenuBar->Cancel(); -			break; -		} - -	case WM_MOUSEACTIVATE: -		if (pContainer != NULL) { -			TCITEM item; -			int curItem = 0; -			BOOL  fTransAllowed = !bSkinned || PluginConfig.m_WinVerMajor >= 6; - -			FlashContainer(pContainer, 0, 0); -			pContainer->dwFlashingStarted = 0; -			pLastActiveContainer = pContainer; -			if (pContainer->dwFlags & CNT_DEFERREDTABSELECT) { -				pContainer->dwFlags &= ~CNT_DEFERREDTABSELECT; -				SendMessage(hwndDlg, WM_SYSCOMMAND, SC_RESTORE, 0); - -				NMHDR nmhdr = { hwndTab, IDC_MSGTABS, TCN_SELCHANGE }; -				SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nmhdr);     // do it via a WM_NOTIFY / TCN_SELCHANGE to simulate user-activation -			} -			if (pContainer->dwFlags & CNT_DEFERREDSIZEREQUEST) { -				pContainer->dwFlags &= ~CNT_DEFERREDSIZEREQUEST; -				SendMessage(hwndDlg, WM_SIZE, 0, 0); -			} - -			if (pContainer->dwFlags & CNT_TRANSPARENCY && fTransAllowed) { -				DWORD trans = LOWORD(pContainer->settings->dwTransparency); -				SetLayeredWindowAttributes(hwndDlg, Skin->getColorKey(), (BYTE)trans, (pContainer->dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0)); -			} -			if (pContainer->dwFlags & CNT_NEED_UPDATETITLE) { -				MCONTACT hContact = 0; -				pContainer->dwFlags &= ~CNT_NEED_UPDATETITLE; -				if (pContainer->hwndActive) { -					SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); -					if (hContact) -						SendMessage(hwndDlg, DM_UPDATETITLE, hContact, 0); -				} -			} -			memset(&item, 0, sizeof(item)); -			item.mask = TCIF_PARAM; -			if ((curItem = TabCtrl_GetCurSel(hwndTab)) >= 0) -				TabCtrl_GetItem(hwndTab, curItem, &item); -			if (pContainer->dwFlags & CNT_DEFERREDCONFIGURE && curItem >= 0) { -				pContainer->dwFlags &= ~CNT_DEFERREDCONFIGURE; -				pContainer->hwndActive = (HWND)item.lParam; -				SendMessage(hwndDlg, WM_SYSCOMMAND, SC_RESTORE, 0); -				if (pContainer->hwndActive != 0 && IsWindow(pContainer->hwndActive)) { -					ShowWindow(pContainer->hwndActive, SW_SHOW); -					SetFocus(pContainer->hwndActive); -					SendMessage(pContainer->hwndActive, WM_ACTIVATE, WA_ACTIVE, 0); -					RedrawWindow(pContainer->hwndActive, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); -				} -			} -			else if (curItem >= 0) -				SendMessage((HWND)item.lParam, WM_ACTIVATE, WA_ACTIVE, 0); -		} -		break; - +/////////////////////////////////////////////////////////////////////////////////////////
 +// Miranda NG: the free IM client for Microsoft* Windows*
 +//
 +// Copyright (ñ) 2012-15 Miranda NG project,
 +// Copyright (c) 2000-09 Miranda ICQ/IM project,
 +// all portions of this codebase are copyrighted to the people
 +// listed in contributors.txt.
 +//
 +// This program is free software; you can redistribute it and/or
 +// modify it under the terms of the GNU General Public License
 +// as published by the Free Software Foundation; either version 2
 +// of the License, or (at your option) any later version.
 +//
 +// This program is distributed in the hope that it will be useful,
 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +// GNU General Public License for more details.
 +//
 +// you should have received a copy of the GNU General Public License
 +// along with this program; if not, write to the Free Software
 +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 +//
 +// part of tabSRMM messaging plugin for Miranda.
 +//
 +// (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
 +//
 +// implements the "Container" window which acts as a toplevel window
 +// for message sessions.
 +
 +#include "commonheaders.h"
 +
 +#define CONTAINER_KEY "TAB_ContainersW"
 +#define CONTAINER_SUBKEY "containerW"
 +#define CONTAINER_PREFIX "CNTW_"
 +
 +TContainerData *pFirstContainer = 0;        // the linked list of struct ContainerWindowData
 +TContainerData *pLastActiveContainer = NULL;
 +
 +static TContainerData* TSAPI AppendToContainerList(TContainerData*);
 +static TContainerData* TSAPI RemoveContainerFromList(TContainerData*);
 +
 +static bool fForceOverlayIcons = false;
 +
 +// Windows Vista+
 +// extend the glassy area to get aero look for the status bar, tab bar, info panel
 +// and outer margins.
 +
 +void TSAPI SetAeroMargins(TContainerData *pContainer)
 +{
 +	if (!pContainer)
 +		return;
 +
 +	if (!M.isAero() || CSkin::m_skinEnabled) {
 +		pContainer->MenuBar->setAero(false);
 +		return;
 +	}
 +
 +	TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +	if (!dat)
 +		return;
 +
 +	RECT	rcWnd;
 +	if (dat->bType == SESSIONTYPE_IM) {
 +		if (dat->Panel->isActive())
 +			GetWindowRect(GetDlgItem(dat->hwnd, IDC_LOG), &rcWnd);
 +		else
 +			GetWindowRect(dat->hwnd, &rcWnd);
 +	}
 +	else {
 +		if (dat->Panel->isActive())
 +			GetWindowRect(GetDlgItem(dat->hwnd, IDC_CHAT_LOG), &rcWnd);
 +		else
 +			GetWindowRect(dat->hwnd, &rcWnd);
 +	}
 +
 +	POINT	pt = { rcWnd.left, rcWnd.top };
 +	ScreenToClient(pContainer->hwnd, &pt);
 +
 +	MARGINS m;
 +	m.cyTopHeight = pt.y;
 +	pContainer->MenuBar->setAero(true);
 +
 +	// bottom part
 +	GetWindowRect(dat->hwnd, &rcWnd);
 +	pt.x = rcWnd.left;
 +
 +	LONG sbar_left, sbar_right;
 +	if (!pContainer->SideBar->isActive()) {
 +		pt.y = rcWnd.bottom + ((pContainer->iChilds > 1 || !(pContainer->dwFlags & CNT_HIDETABS)) ? pContainer->tBorder : 0);
 +		sbar_left = 0, sbar_right = 0;
 +	}
 +	else {
 +		pt.y = rcWnd.bottom;
 +		sbar_left = (pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_LEFT ? pContainer->SideBar->getWidth() : 0);
 +		sbar_right = (pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_RIGHT ? pContainer->SideBar->getWidth() : 0);
 +	}
 +	ScreenToClient(pContainer->hwnd, &pt);
 +	GetClientRect(pContainer->hwnd, &rcWnd);
 +	m.cyBottomHeight = (rcWnd.bottom - pt.y);
 +
 +	if (m.cyBottomHeight < 0 || m.cyBottomHeight >= rcWnd.bottom)
 +		m.cyBottomHeight = 0;
 +
 +	m.cxLeftWidth = pContainer->tBorder_outer_left;
 +	m.cxRightWidth = pContainer->tBorder_outer_right;
 +	m.cxLeftWidth += sbar_left;
 +	m.cxRightWidth += sbar_right;
 +
 +	if (memcmp(&m, &pContainer->mOld, sizeof(MARGINS)) != 0) {
 +		pContainer->mOld = m;
 +		CMimAPI::m_pfnDwmExtendFrameIntoClientArea(pContainer->hwnd, &m);
 +	}
 +}
 +
 +static LRESULT CALLBACK ContainerWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	TContainerData *pContainer = (TContainerData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 +	BOOL bSkinned = CSkin::m_skinEnabled ? TRUE : FALSE;
 +
 +	switch (msg) {
 +	case WM_NCPAINT: {
 +		PAINTSTRUCT ps;
 +		HDC hdcReal;
 +		RECT rcClient;
 +		LONG width, height;
 +		HDC hdc;
 +		CSkinItem *item = &SkinItems[0], *item_normal, *item_pressed, *item_hot;
 +		HICON hIcon;
 +		HFONT hOldFont = 0;
 +		TEXTMETRIC tm;
 +
 +		if (!pContainer || !bSkinned)
 +			break;
 +
 +		if (CSkin::m_frameSkins) {
 +			HDC dcFrame = GetDCEx(hwndDlg, 0, DCX_WINDOW |/*DCX_INTERSECTRGN|*/0x10000); // GetWindowDC(hwndDlg);
 +			LONG clip_top, clip_left;
 +			RECT rcText;
 +			HDC dcMem = CreateCompatibleDC(pContainer->cachedDC ? pContainer->cachedDC : dcFrame);
 +			int i;
 +
 +			RECT rcWindow, rcClient;
 +			POINT pt, pt1;
 +			GetWindowRect(hwndDlg, &rcWindow);
 +			GetClientRect(hwndDlg, &rcClient);
 +			pt.y = 0;
 +			pt.x = 0;
 +			ClientToScreen(hwndDlg, &pt);
 +			pt1.x = rcClient.right;
 +			pt1.y = rcClient.bottom;
 +			ClientToScreen(hwndDlg, &pt1);
 +			clip_top = pt.y - rcWindow.top;
 +			clip_left = pt.x - rcWindow.left;
 +
 +			rcWindow.right = rcWindow.right - rcWindow.left;
 +			rcWindow.bottom = rcWindow.bottom - rcWindow.top;
 +			rcWindow.left = rcWindow.top = 0;
 +
 +			HBITMAP hbmMem = CreateCompatibleBitmap(dcFrame, rcWindow.right, rcWindow.bottom);
 +			HBITMAP hbmOld = (HBITMAP)SelectObject(dcMem, hbmMem);
 +
 +			ExcludeClipRect(dcFrame, clip_left, clip_top, clip_left + (pt1.x - pt.x), clip_top + (pt1.y - pt.y));
 +			ExcludeClipRect(dcMem, clip_left, clip_top, clip_left + (pt1.x - pt.x), clip_top + (pt1.y - pt.y));
 +			CSkinItem *item = pContainer->ncActive ? &SkinItems[ID_EXTBKFRAME] : &SkinItems[ID_EXTBKFRAMEINACTIVE];
 +
 +			CSkin::DrawItem(dcMem, &rcWindow, item);
 +
 +			TCHAR szWindowText[512];
 +			GetWindowText(hwndDlg, szWindowText, SIZEOF(szWindowText));
 +			szWindowText[511] = 0;
 +			hOldFont = (HFONT)SelectObject(dcMem, PluginConfig.hFontCaption);
 +			GetTextMetrics(dcMem, &tm);
 +			SetTextColor(dcMem, CInfoPanel::m_ipConfig.clrs[IPFONTCOUNT - 1]);
 +			SetBkMode(dcMem, TRANSPARENT);
 +			rcText.left = 20 + CSkin::m_SkinnedFrame_left + CSkin::m_bClipBorder + CSkin::m_titleBarLeftOff;//26;
 +			rcText.right = rcWindow.right - 3 * CSkin::m_titleBarButtonSize.cx - 11 - CSkin::m_titleBarRightOff;
 +			rcText.top = CSkin::m_captionOffset + CSkin::m_bClipBorder;
 +			rcText.bottom = rcText.top + tm.tmHeight;
 +			rcText.left += CSkin::m_captionPadding;
 +			DrawText(dcMem, szWindowText, -1, &rcText, DT_SINGLELINE | DT_VCENTER | DT_END_ELLIPSIS | DT_NOPREFIX);
 +			SelectObject(dcMem, hOldFont);
 +
 +			// icon
 +			hIcon = (HICON)SendMessage(hwndDlg, WM_GETICON, ICON_SMALL, 0);
 +			DrawIconEx(dcMem, 4 + CSkin::m_SkinnedFrame_left + CSkin::m_bClipBorder + CSkin::m_titleBarLeftOff, rcText.top + (rcText.bottom - rcText.top) / 2 - 8, hIcon, 16, 16, 0, 0, DI_NORMAL);
 +
 +			// title buttons
 +			pContainer->rcClose.top = pContainer->rcMin.top = pContainer->rcMax.top = CSkin::m_titleButtonTopOff;
 +			pContainer->rcClose.bottom = pContainer->rcMin.bottom = pContainer->rcMax.bottom = CSkin::m_titleButtonTopOff + CSkin::m_titleBarButtonSize.cy;
 +
 +			pContainer->rcClose.right = rcWindow.right - 10 - CSkin::m_titleBarRightOff;
 +			pContainer->rcClose.left = pContainer->rcClose.right - CSkin::m_titleBarButtonSize.cx;
 +
 +			pContainer->rcMax.right = pContainer->rcClose.left - 2;
 +			pContainer->rcMax.left = pContainer->rcMax.right - CSkin::m_titleBarButtonSize.cx;
 +
 +			pContainer->rcMin.right = pContainer->rcMax.left - 2;
 +			pContainer->rcMin.left = pContainer->rcMin.right - CSkin::m_titleBarButtonSize.cx;
 +
 +			item_normal = &SkinItems[ID_EXTBKTITLEBUTTON];
 +			item_hot = &SkinItems[ID_EXTBKTITLEBUTTONMOUSEOVER];
 +			item_pressed = &SkinItems[ID_EXTBKTITLEBUTTONPRESSED];
 +
 +			for (i = 0; i < 3; i++) {
 +				RECT *rc = 0;
 +				HICON hIcon = 0;
 +
 +				switch (i) {
 +				case 0:
 +					rc = &pContainer->rcMin;
 +					hIcon = CSkin::m_minIcon;
 +					break;
 +				case 1:
 +					rc = &pContainer->rcMax;
 +					hIcon = CSkin::m_maxIcon;
 +					break;
 +				case 2:
 +					rc = &pContainer->rcClose;
 +					hIcon = CSkin::m_closeIcon;
 +					break;
 +				}
 +				if (rc) {
 +					item = pContainer->buttons[i].isPressed ? item_pressed : (pContainer->buttons[i].isHot ? item_hot : item_normal);
 +					CSkin::DrawItem(dcMem, rc, item);
 +					DrawIconEx(dcMem, rc->left + ((rc->right - rc->left) / 2 - 8), rc->top + ((rc->bottom - rc->top) / 2 - 8), hIcon, 16, 16, 0, 0, DI_NORMAL);
 +				}
 +			}
 +			SetBkMode(dcMem, TRANSPARENT);
 +			BitBlt(dcFrame, 0, 0, rcWindow.right, rcWindow.bottom, dcMem, 0, 0, SRCCOPY);
 +			SelectObject(dcMem, hbmOld);
 +			DeleteObject(hbmMem);
 +			DeleteDC(dcMem);
 +			ReleaseDC(hwndDlg, dcFrame);
 +		}
 +		else mir_callNextSubclass(hwndDlg, ContainerWndProc, msg, wParam, lParam);
 +
 +		hdcReal = BeginPaint(hwndDlg, &ps);
 +
 +		GetClientRect(hwndDlg, &rcClient);
 +		width = rcClient.right - rcClient.left;
 +		height = rcClient.bottom - rcClient.top;
 +		if (width != pContainer->oldDCSize.cx || height != pContainer->oldDCSize.cy) {
 +			CSkinItem *sbaritem = &SkinItems[ID_EXTBKSTATUSBAR];
 +			BOOL statusBarSkinnd = !(pContainer->dwFlags & CNT_NOSTATUSBAR) && !sbaritem->IGNORED;
 +			LONG sbarDelta = statusBarSkinnd ? pContainer->statusBarHeight : 0;
 +
 +			pContainer->oldDCSize.cx = width;
 +			pContainer->oldDCSize.cy = height;
 +
 +			if (pContainer->cachedDC) {
 +				SelectObject(pContainer->cachedDC, pContainer->oldHBM);
 +				DeleteObject(pContainer->cachedHBM);
 +				DeleteDC(pContainer->cachedDC);
 +			}
 +			pContainer->cachedDC = CreateCompatibleDC(hdcReal);
 +			pContainer->cachedHBM = CreateCompatibleBitmap(hdcReal, width, height);
 +			pContainer->oldHBM = (HBITMAP)SelectObject(pContainer->cachedDC, pContainer->cachedHBM);
 +
 +			hdc = pContainer->cachedDC;
 +
 +			if (!CSkin::DrawItem(hdc, &rcClient, item))
 +				FillRect(hdc, &rcClient, GetSysColorBrush(COLOR_3DFACE));
 +
 +			if (sbarDelta) {
 +				rcClient.top = rcClient.bottom - sbarDelta;
 +				CSkin::DrawItem(hdc, &rcClient, sbaritem);
 +			}
 +		}
 +		BitBlt(hdcReal, 0, 0, width, height, pContainer->cachedDC, 0, 0, SRCCOPY);
 +		EndPaint(hwndDlg, &ps);
 +		return 0;
 +	}
 +	case WM_NCLBUTTONDOWN:
 +	case WM_NCLBUTTONUP:
 +	case WM_NCMOUSEHOVER:
 +	case WM_NCMOUSEMOVE:
 +		if (pContainer && CSkin::m_frameSkins) {
 +			POINT pt;
 +			RECT rcWindow;
 +			BOOL isMin, isMax, isClose;
 +			int i;
 +
 +			GetCursorPos(&pt);
 +			GetWindowRect(hwndDlg, &rcWindow);
 +
 +			memcpy(&pContainer->oldbuttons[0], &pContainer->buttons[0], sizeof(TitleBtn) * 3);
 +			memset(&pContainer->buttons[0], 0, (sizeof(TitleBtn) * 3));
 +			isMin = isMax = isClose = FALSE;
 +
 +			if (pt.x >= (rcWindow.left + pContainer->rcMin.left) && pt.x <= (rcWindow.left + pContainer->rcClose.right) && pt.y < rcWindow.top + 24 && wParam != HTTOPRIGHT) {
 +				LRESULT result = 0; //DefWindowProc(hwndDlg, msg, wParam, lParam);
 +				HDC hdc = GetWindowDC(hwndDlg);
 +				LONG left = rcWindow.left;
 +
 +				pt.y = 10;
 +				isMin = pt.x >= left + pContainer->rcMin.left && pt.x <= left + pContainer->rcMin.right;
 +				isMax = pt.x >= left + pContainer->rcMax.left && pt.x <= left + pContainer->rcMax.right;
 +				isClose = pt.x >= left + pContainer->rcClose.left && pt.x <= left + pContainer->rcClose.right;
 +
 +				if (msg == WM_NCMOUSEMOVE) {
 +					if (isMax)
 +						pContainer->buttons[BTN_MAX].isHot = TRUE;
 +					else if (isMin)
 +						pContainer->buttons[BTN_MIN].isHot = TRUE;
 +					else if (isClose)
 +						pContainer->buttons[BTN_CLOSE].isHot = TRUE;
 +				}
 +				else if (msg == WM_NCLBUTTONDOWN) {
 +					if (isMax)
 +						pContainer->buttons[BTN_MAX].isPressed = TRUE;
 +					else if (isMin)
 +						pContainer->buttons[BTN_MIN].isPressed = TRUE;
 +					else if (isClose)
 +						pContainer->buttons[BTN_CLOSE].isPressed = TRUE;
 +				}
 +				else if (msg == WM_NCLBUTTONUP) {
 +					if (isMin)
 +						SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MINIMIZE, 0);
 +					else if (isMax) {
 +						if (IsZoomed(hwndDlg))
 +							PostMessage(hwndDlg, WM_SYSCOMMAND, SC_RESTORE, 0);
 +						else
 +							PostMessage(hwndDlg, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
 +					}
 +					else if (isClose)
 +						PostMessage(hwndDlg, WM_SYSCOMMAND, SC_CLOSE, 0);
 +				}
 +				for (i = 0; i < 3; i++) {
 +					if (pContainer->buttons[i].isHot != pContainer->oldbuttons[i].isHot) {
 +						RECT *rc = 0;
 +						HICON hIcon = 0;
 +
 +						switch (i) {
 +						case 0:
 +							rc = &pContainer->rcMin;
 +							hIcon = CSkin::m_minIcon;
 +							break;
 +						case 1:
 +							rc = &pContainer->rcMax;
 +							hIcon = CSkin::m_maxIcon;
 +							break;
 +						case 2:
 +							rc = &pContainer->rcClose;
 +							hIcon = CSkin::m_closeIcon;
 +							break;
 +						}
 +						if (rc) {
 +							CSkinItem *item = &SkinItems[pContainer->buttons[i].isPressed ? ID_EXTBKTITLEBUTTONPRESSED : (pContainer->buttons[i].isHot ? ID_EXTBKTITLEBUTTONMOUSEOVER : ID_EXTBKTITLEBUTTON)];
 +							CSkin::DrawItem(hdc, rc, item);
 +							DrawIconEx(hdc, rc->left + ((rc->right - rc->left) / 2 - 8), rc->top + ((rc->bottom - rc->top) / 2 - 8), hIcon, 16, 16, 0, 0, DI_NORMAL);
 +						}
 +					}
 +				}
 +				ReleaseDC(hwndDlg, hdc);
 +				return result;
 +			}
 +			else {
 +				LRESULT result = DefWindowProc(hwndDlg, msg, wParam, lParam);
 +				RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_NOCHILDREN);
 +				return result;
 +			}
 +		}
 +		break;
 +
 +	case WM_SETCURSOR:
 +		if (CSkin::m_frameSkins && (HWND)wParam == hwndDlg) {
 +			DefWindowProc(hwndDlg, msg, wParam, lParam);
 +			RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW | RDW_NOCHILDREN);
 +			return 1;
 +		}
 +		break;
 +
 +	case WM_NCCALCSIZE:
 +		if (!CSkin::m_frameSkins)
 +			break;
 +
 +		if (wParam) {
 +			RECT *rc;
 +			NCCALCSIZE_PARAMS *ncsp = (NCCALCSIZE_PARAMS *)lParam;
 +
 +			DefWindowProc(hwndDlg, msg, wParam, lParam);
 +			rc = &ncsp->rgrc[0];
 +
 +			rc->left += CSkin::m_realSkinnedFrame_left;
 +			rc->right -= CSkin::m_realSkinnedFrame_right;
 +			rc->bottom -= CSkin::m_realSkinnedFrame_bottom;
 +			rc->top += CSkin::m_realSkinnedFrame_caption;
 +			return TRUE;
 +		}
 +
 +		return DefWindowProc(hwndDlg, msg, wParam, lParam);
 +
 +	case WM_NCACTIVATE:
 +		if (pContainer) {
 +			pContainer->ncActive = wParam;
 +			if (bSkinned && CSkin::m_frameSkins) {
 +				SendMessage(hwndDlg, WM_NCPAINT, 0, 0);
 +				return 1;
 +			}
 +		}
 +		break;
 +	case WM_SETTEXT:
 +	case WM_SETICON:
 +		if (CSkin::m_frameSkins) {
 +			DefWindowProc(hwndDlg, msg, wParam, lParam);
 +			RedrawWindow(hwndDlg, NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
 +			return 0;
 +		}
 +		break;
 +
 +	case WM_NCHITTEST:
 +	{
 +		RECT r;
 +		POINT pt;
 +		int clip = CSkin::m_bClipBorder;
 +
 +		if (!pContainer)
 +			break;
 +
 +		if (!(pContainer->dwFlags & CNT_NOTITLE))
 +			break;
 +
 +		GetWindowRect(hwndDlg, &r);
 +		GetCursorPos(&pt);
 +		if (pt.y <= r.bottom && pt.y >= r.bottom - clip - 6) {
 +			if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10)
 +				return HTBOTTOM;
 +			if (pt.x < r.left + clip + 10)
 +				return HTBOTTOMLEFT;
 +			if (pt.x > r.right - clip - 10)
 +				return HTBOTTOMRIGHT;
 +
 +		}
 +		else if (pt.y >= r.top && pt.y <= r.top + 6) {
 +			if (pt.x > r.left + clip + 10 && pt.x < r.right - clip - 10)
 +				return HTTOP;
 +			if (pt.x < r.left + clip + 10)
 +				return HTTOPLEFT;
 +			if (pt.x > r.right - clip - 10)
 +				return HTTOPRIGHT;
 +		}
 +		else if (pt.x >= r.left && pt.x <= r.left + clip + 6)
 +			return HTLEFT;
 +		else if (pt.x >= r.right - clip - 6 && pt.x <= r.right)
 +			return HTRIGHT;
 +	}
 +	return(DefWindowProc(hwndDlg, WM_NCHITTEST, wParam, lParam));
 +
 +	case 0xae:						// must be some undocumented message - seems it messes with the title bar...
 +		if (CSkin::m_frameSkins)
 +			return 0;
 +	}
 +	return mir_callNextSubclass(hwndDlg, ContainerWndProc, msg, wParam, lParam);
 +}
 +
 +// container window procedure...
 +
 +static BOOL fHaveTipper = FALSE;
 +
 +static INT_PTR CALLBACK DlgProcContainer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 +{
 +	int iItem = 0;
 +	TCITEM item;
 +	RECT rc;
 +	POINT pt;
 +
 +	TContainerData *pContainer = (TContainerData*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
 +	BOOL bSkinned = CSkin::m_skinEnabled ? TRUE : FALSE;
 +	HWND hwndTab = GetDlgItem(hwndDlg, IDC_MSGTABS);
 +
 +	switch (msg) {
 +	case WM_INITDIALOG:
 +		fHaveTipper = ServiceExists("mToolTip/ShowTip");
 +		fForceOverlayIcons = M.GetByte("forceTaskBarStatusOverlays", 0) ? true : false;
 +
 +		pContainer = (TContainerData*)lParam;
 +		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)pContainer);
 +		mir_subclassWindow(hwndDlg, ContainerWndProc);
 +
 +		pContainer->hwnd = hwndDlg;
 +		{
 +			DWORD dwCreateFlags = pContainer->dwFlags;
 +			pContainer->isCloned = (dwCreateFlags & CNT_CREATE_CLONED);
 +			pContainer->fPrivateThemeChanged = FALSE;
 +
 +			SendMessage(hwndDlg, DM_OPTIONSAPPLIED, 0, 0);          // set options...
 +			pContainer->dwFlags |= dwCreateFlags;
 +
 +			LoadOverrideTheme(pContainer);
 +			DWORD ws = GetWindowLongPtr(hwndTab, GWL_STYLE);
 +			if (pContainer->dwFlagsEx & TCF_FLAT)
 +				ws |= TCS_BUTTONS;
 +
 +			memset((void*)&pContainer->mOld, -1000, sizeof(MARGINS));
 +
 +			if (pContainer->dwFlagsEx & TCF_SINGLEROWTABCONTROL) {
 +				ws &= ~TCS_MULTILINE;
 +				ws |= TCS_SINGLELINE;
 +				ws |= TCS_FIXEDWIDTH;
 +			}
 +			else {
 +				ws &= ~TCS_SINGLELINE;
 +				ws |= TCS_MULTILINE;
 +				if (ws & TCS_BUTTONS)
 +					ws |= TCS_FIXEDWIDTH;
 +			}
 +			SetWindowLongPtr(hwndTab, GWL_STYLE, ws);
 +
 +			pContainer->buttonItems = g_ButtonSet.items;
 +
 +			pContainer->dwFlags = ((pContainer->dwFlagsEx & (TCF_SBARLEFT | TCF_SBARRIGHT)) ?
 +				pContainer->dwFlags | CNT_SIDEBAR : pContainer->dwFlags & ~CNT_SIDEBAR);
 +
 +			pContainer->SideBar = new CSideBar(pContainer);
 +			pContainer->MenuBar = new CMenuBar(hwndDlg, pContainer);
 +
 +			SetClassLongPtr(hwndDlg, GCL_STYLE, GetClassLongPtr(hwndDlg, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW));
 +			SetClassLongPtr(hwndTab, GCL_STYLE, GetClassLongPtr(hwndTab, GCL_STYLE) & ~(CS_VREDRAW | CS_HREDRAW));
 +
 +			SetClassLongPtr(hwndDlg, GCL_STYLE, GetClassLongPtr(hwndDlg, GCL_STYLE) & ~CS_DROPSHADOW);
 +
 +			// additional system menu items...
 +			HMENU hSysmenu = GetSystemMenu(hwndDlg, FALSE);
 +			int iMenuItems = GetMenuItemCount(hSysmenu);
 +
 +			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_SEPARATOR, 0, _T(""));
 +			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_STRING, IDM_STAYONTOP, TranslateT("Stay on top"));
 +			if (!CSkin::m_frameSkins)
 +				InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_STRING, IDM_NOTITLE, TranslateT("Hide title bar"));
 +			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_SEPARATOR, 0, _T(""));
 +			InsertMenu(hSysmenu, iMenuItems++ - 2, MF_BYPOSITION | MF_STRING, IDM_MOREOPTIONS, TranslateT("Container options..."));
 +			SetWindowText(hwndDlg, TranslateT("Message session..."));
 +			SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)PluginConfig.g_iconContainer);
 +
 +			// make the tab control the controlling parent window for all message dialogs
 +
 +			ws = GetWindowLongPtr(hwndTab, GWL_EXSTYLE);
 +			SetWindowLongPtr(hwndTab, GWL_EXSTYLE, ws | WS_EX_CONTROLPARENT);
 +
 +			LONG x_pad = M.GetByte("x-pad", 3) + (pContainer->dwFlagsEx & TCF_CLOSEBUTTON ? 7 : 0);
 +			LONG y_pad = M.GetByte("y-pad", 3) + ((pContainer->dwFlags & CNT_TABSBOTTOM) ? 1 : 0);
 +
 +			if (pContainer->dwFlagsEx & TCF_FLAT)
 +				y_pad++; //(pContainer->dwFlags & CNT_TABSBOTTOM ? 1 : 2);
 +
 +			TabCtrl_SetPadding(hwndTab, x_pad, y_pad);
 +
 +			TabCtrl_SetImageList(hwndTab, PluginConfig.g_hImageList);
 +
 +			SendMessage(hwndDlg, DM_CONFIGURECONTAINER, 0, 10);
 +
 +			// context menu
 +			pContainer->hMenuContext = PluginConfig.g_hMenuContext;
 +
 +			// tab tooltips...
 +			if (!fHaveTipper || M.GetByte("d_tooltips", 0) == 0) {
 +				pContainer->hwndTip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT,
 +					CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL, g_hInst, (LPVOID)NULL);
 +
 +				if (pContainer->hwndTip) {
 +					SetWindowPos(pContainer->hwndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 +					TabCtrl_SetToolTips(hwndTab, pContainer->hwndTip);
 +				}
 +			}
 +			else pContainer->hwndTip = 0;
 +
 +			if (pContainer->dwFlags & CNT_CREATE_MINIMIZED) {
 +				WINDOWPLACEMENT wp = { 0 };
 +				wp.length = sizeof(wp);
 +
 +				SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE) & ~WS_VISIBLE);
 +				ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE);
 +				SendMessage(hwndDlg, DM_RESTOREWINDOWPOS, 0, 0);
 +				//GetClientRect(hwndDlg, &pContainer->rcSaved);
 +				ShowWindow(hwndDlg, SW_SHOWMINNOACTIVE);
 +				GetWindowPlacement(hwndDlg, &wp);
 +				pContainer->rcSaved.left = pContainer->rcSaved.top = 0;
 +				pContainer->rcSaved.right = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
 +				pContainer->rcSaved.bottom = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
 +			}
 +			else {
 +				SendMessage(hwndDlg, DM_RESTOREWINDOWPOS, 0, 0);
 +				ShowWindow(hwndDlg, SW_SHOWNORMAL);
 +			}
 +		}
 +
 +		// prevent ugly back background being visible while tabbed clients are created
 +		if (M.isAero()) {
 +			MARGINS m = { -1 };
 +			CMimAPI::m_pfnDwmExtendFrameIntoClientArea(hwndDlg, &m);
 +		}
 +		return TRUE;
 +
 +	case DM_RESTOREWINDOWPOS:
 +		// retrieve the container window geometry information from the database.
 +		if (pContainer->isCloned && pContainer->hContactFrom != 0 && !(pContainer->dwFlags & CNT_GLOBALSIZE)) {
 +			if (Utils_RestoreWindowPosition(hwndDlg, pContainer->hContactFrom, SRMSGMOD_T, "split")) {
 +				if (Utils_RestoreWindowPositionNoMove(hwndDlg, pContainer->hContactFrom, SRMSGMOD_T, "split"))
 +					if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, "split"))
 +						if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, "split"))
 +							SetWindowPos(hwndDlg, 0, 50, 50, 450, 300, SWP_NOZORDER | SWP_NOACTIVATE);
 +			}
 +		}
 +		else {
 +			if (pContainer->dwFlags & CNT_GLOBALSIZE) {
 +				if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, "split"))
 +					if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, "split"))
 +						SetWindowPos(hwndDlg, 0, 50, 50, 450, 300, SWP_NOZORDER | SWP_NOACTIVATE);
 +			}
 +			else {
 +				char szCName[CONTAINER_NAMELEN + 20];
 +				mir_snprintf(szCName, SIZEOF(szCName), "%s%d", CONTAINER_PREFIX, pContainer->iContainerIndex);
 +				if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, szCName)) {
 +					if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, szCName))
 +						if (Utils_RestoreWindowPosition(hwndDlg, NULL, SRMSGMOD_T, "split"))
 +							if (Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, SRMSGMOD_T, "split"))
 +								SetWindowPos(hwndDlg, 0, 50, 50, 450, 300, SWP_NOZORDER | SWP_NOACTIVATE);
 +				}
 +			}
 +		}
 +		return 0;
 +
 +	case WM_SIZE:
 +		if (IsIconic(hwndDlg))
 +			pContainer->dwFlags |= CNT_DEFERREDSIZEREQUEST;
 +		else {
 +			RECT rcClient, rcUnadjusted;
 +			TCITEM item = { 0 };
 +
 +			GetClientRect(hwndDlg, &rcClient);
 +			pContainer->MenuBar->getClientRect();
 +
 +			if (pContainer->hwndStatus) {
 +				TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +				SendMessage(pContainer->hwndStatus, WM_USER + 101, 0, (LPARAM)dat);
 +
 +				RECT rcs;
 +				GetWindowRect(pContainer->hwndStatus, &rcs);
 +				pContainer->statusBarHeight = (rcs.bottom - rcs.top) + 1;
 +				SendMessage(pContainer->hwndStatus, SB_SETTEXT, (WPARAM)(SBT_OWNERDRAW) | 2, 0);
 +			}
 +			else pContainer->statusBarHeight = 0;
 +
 +			CopyRect(&pContainer->rcSaved, &rcClient);
 +			rcUnadjusted = rcClient;
 +
 +			pContainer->MenuBar->Resize(LOWORD(lParam));
 +			LONG rebarHeight = pContainer->MenuBar->getHeight();
 +			pContainer->MenuBar->Show((pContainer->dwFlags & CNT_NOMENUBAR) ? SW_HIDE : SW_SHOW);
 +
 +			LONG sbarWidth = pContainer->SideBar->getWidth();
 +			LONG sbarWidth_left = pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_LEFT ? sbarWidth : 0;
 +
 +			if (lParam) {
 +				DWORD	dwSWPFlags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_DEFERERASE | SWP_NOCOPYBITS; // | SWP_NOSENDCHANGING  | SWP_ASYNCWINDOWPOS;
 +				SetWindowPos(hwndTab, 0, pContainer->tBorder_outer_left + sbarWidth_left, pContainer->tBorder_outer_top + rebarHeight,
 +					(rcClient.right - rcClient.left) - (pContainer->tBorder_outer_left + pContainer->tBorder_outer_right + sbarWidth),
 +					(rcClient.bottom - rcClient.top) - pContainer->statusBarHeight - (pContainer->tBorder_outer_top + pContainer->tBorder_outer_bottom) - rebarHeight, dwSWPFlags);
 +			}
 +
 +			pContainer->SideBar->resizeScrollWnd(sbarWidth_left ? pContainer->tBorder_outer_left : rcClient.right - pContainer->tBorder_outer_right - (sbarWidth - 2),
 +				pContainer->tBorder_outer_top + rebarHeight, 0,
 +				(rcClient.bottom - rcClient.top) - pContainer->statusBarHeight - (pContainer->tBorder_outer_top + pContainer->tBorder_outer_bottom) - rebarHeight);
 +
 +			AdjustTabClientRect(pContainer, &rcClient);
 +
 +			BOOL sizeChanged = (((rcClient.right - rcClient.left) != pContainer->preSIZE.cx) || ((rcClient.bottom - rcClient.top) != pContainer->preSIZE.cy));
 +			if (sizeChanged) {
 +				pContainer->preSIZE.cx = rcClient.right - rcClient.left;
 +				pContainer->preSIZE.cy = rcClient.bottom - rcClient.top;
 +			}
 +
 +			// we care about all client sessions, but we really resize only the active tab (hwndActive)
 +			// we tell inactive tabs to resize theirselves later when they get activated (DM_CHECKSIZE
 +			// just queues a resize request)
 +			int nCount = TabCtrl_GetItemCount(hwndTab);
 +
 +			for (int i = 0; i < nCount; i++) {
 +				item.mask = TCIF_PARAM;
 +				TabCtrl_GetItem(hwndTab, i, &item);
 +				if ((HWND)item.lParam == pContainer->hwndActive) {
 +					SetWindowPos((HWND)item.lParam, 0, rcClient.left, rcClient.top, (rcClient.right - rcClient.left), (rcClient.bottom - rcClient.top),
 +						SWP_NOSENDCHANGING | SWP_NOACTIVATE/*|SWP_NOCOPYBITS*/);
 +					if (!pContainer->bSizingLoop && sizeChanged) {
 +						TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +						DM_ScrollToBottom(dat, 0, 1);
 +					}
 +				}
 +				else if (sizeChanged)
 +					SendMessage((HWND)item.lParam, DM_CHECKSIZE, 0, 0);
 +			}
 +			pContainer->SideBar->scrollIntoView();
 +
 +			if (!M.isAero()) {					// aero mode uses buffered paint, no forced redraw needed
 +				RedrawWindow(hwndTab, NULL, NULL, RDW_INVALIDATE | (pContainer->bSizingLoop ? RDW_ERASE : 0));
 +				RedrawWindow(hwndDlg, NULL, NULL, (bSkinned ? RDW_FRAME : 0) | RDW_INVALIDATE | ((pContainer->bSizingLoop || wParam == SIZE_RESTORED) ? RDW_ERASE : 0));
 +			}
 +
 +			if (pContainer->hwndStatus)
 +				InvalidateRect(pContainer->hwndStatus, NULL, FALSE);
 +
 +			if ((CSkin::m_bClipBorder != 0 || CSkin::m_bRoundedCorner) && CSkin::m_frameSkins) {
 +				HRGN rgn;
 +				int clip = CSkin::m_bClipBorder;
 +
 +				RECT rcWindow;
 +				GetWindowRect(hwndDlg, &rcWindow);
 +
 +				if (CSkin::m_bRoundedCorner)
 +					rgn = CreateRoundRectRgn(clip, clip, (rcWindow.right - rcWindow.left) - clip + 1,
 +					(rcWindow.bottom - rcWindow.top) - clip + 1, CSkin::m_bRoundedCorner + clip, CSkin::m_bRoundedCorner + clip);
 +				else
 +					rgn = CreateRectRgn(clip, clip, (rcWindow.right - rcWindow.left) - clip, (rcWindow.bottom - rcWindow.top) - clip);
 +				SetWindowRgn(hwndDlg, rgn, TRUE);
 +			}
 +			else if (CSkin::m_frameSkins)
 +				SetWindowRgn(hwndDlg, NULL, TRUE);
 +		}
 +		break;
 +
 +	case WM_NOTIFY:
 +		if (pContainer == NULL)
 +			break;
 +		if (pContainer->MenuBar) {
 +			LRESULT processed = pContainer->MenuBar->processMsg(msg, wParam, lParam);
 +			if (processed != -1) {
 +				SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, processed);
 +				return(processed);
 +			}
 +		}
 +
 +		if (pContainer->hwndStatus != 0 && ((LPNMHDR)lParam)->hwndFrom == pContainer->hwndStatus) {
 +			switch (((LPNMHDR)lParam)->code) {
 +			case NM_CLICK:
 +			case NM_RCLICK:
 +				NMMOUSE *nm = (NMMOUSE*)lParam;
 +				int nPanel;
 +				if (nm->dwItemSpec == 0xFFFFFFFE) {
 +					nPanel = 2;
 +					SendMessage(pContainer->hwndStatus, SB_GETRECT, nPanel, (LPARAM)&rc);
 +					if (nm->pt.x > rc.left && nm->pt.x < rc.right)
 +						goto panel_found;
 +					else
 +						return FALSE;
 +				}
 +				else nPanel = nm->dwItemSpec;
 +			panel_found:
 +				if (nPanel == 2) {
 +					TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +					SendMessage(pContainer->hwndStatus, SB_GETRECT, nPanel, (LPARAM)&rc);
 +					if (dat)
 +						CheckStatusIconClick(dat, nm->pt, rc, 2, ((LPNMHDR)lParam)->code);
 +				}
 +				else if (((LPNMHDR)lParam)->code == NM_RCLICK) {
 +					GetCursorPos(&pt);
 +					MCONTACT hContact = 0;
 +					SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +					if (hContact) {
 +						int iSel = 0;
 +						HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, hContact, 0);
 +						iSel = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL);
 +						if (iSel)
 +							CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(iSel), MPCF_CONTACTMENU), hContact);
 +						DestroyMenu(hMenu);
 +					}
 +				}
 +				return TRUE;
 +			}
 +			break;
 +		}
 +
 +		switch (((LPNMHDR)lParam)->code) {
 +		case TCN_SELCHANGE:
 +			memset(&item, 0, sizeof(item));
 +			iItem = TabCtrl_GetCurSel(hwndTab);
 +			item.mask = TCIF_PARAM;
 +			if (TabCtrl_GetItem(hwndTab, iItem, &item)) {
 +				if ((HWND)item.lParam != pContainer->hwndActive)
 +					if (pContainer->hwndActive && IsWindow(pContainer->hwndActive))
 +						ShowWindow(pContainer->hwndActive, SW_HIDE);
 +
 +				pContainer->hwndActive = (HWND)item.lParam;
 +				SendMessage((HWND)item.lParam, DM_SAVESIZE, 0, 1);
 +				ShowWindow((HWND)item.lParam, SW_SHOW);
 +				if (!IsIconic(hwndDlg))
 +					SetFocus(pContainer->hwndActive);
 +			}
 +			SendMessage(hwndTab, EM_VALIDATEBOTTOM, 0, 0);
 +			return 0;
 +
 +			// tooltips
 +		case NM_RCLICK:
 +			int iItem;
 +			bool fFromSidebar = false;
 +			TCITEM item = { 0 };
 +			TWindowData *dat = 0;
 +
 +			GetCursorPos(&pt);
 +			HMENU subMenu = GetSubMenu(pContainer->hMenuContext, 0);
 +
 +			if (((LPNMHDR)lParam)->idFrom == IDC_MSGTABS) {
 +				if ((iItem = GetTabItemFromMouse(hwndTab, &pt)) == -1)
 +					break;
 +
 +				item.mask = TCIF_PARAM;
 +				TabCtrl_GetItem(hwndTab, iItem, &item);
 +				if (item.lParam && IsWindow((HWND)item.lParam))
 +					dat = (TWindowData*)GetWindowLongPtr((HWND)item.lParam, GWLP_USERDATA);
 +			}
 +			// sent from a sidebar button (RMB click) instead of the tab control
 +			else if (((LPNMHDR)lParam)->idFrom == 5000) {
 +				TSideBarNotify* n = reinterpret_cast<TSideBarNotify *>(lParam);
 +				dat = const_cast<TWindowData *>(n->dat);
 +				fFromSidebar = true;
 +			}
 +
 +			if (dat)
 +				MsgWindowUpdateMenu(dat, subMenu, MENU_TABCONTEXT);
 +
 +			int iSelection = TrackPopupMenu(subMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL);
 +			if (iSelection >= IDM_CONTAINERMENU) {
 +				char szIndex[10];
 +				itoa(iSelection - IDM_CONTAINERMENU, szIndex, 10);
 +				if (iSelection - IDM_CONTAINERMENU >= 0) {
 +					ptrT tszName(db_get_tsa(NULL, CONTAINER_KEY, szIndex));
 +					if (tszName != NULL)
 +						SendMessage((HWND)item.lParam, DM_CONTAINERSELECTED, 0, tszName);
 +				}
 +				return 1;
 +			}
 +			switch (iSelection) {
 +			case ID_TABMENU_CLOSETAB:
 +				if (fFromSidebar)
 +					SendMessage(dat->hwnd, WM_CLOSE, 1, 0);
 +				else
 +					SendMessage(hwndDlg, DM_CLOSETABATMOUSE, 0, (LPARAM)&pt);
 +				break;
 +			case ID_TABMENU_CLOSEOTHERTABS:
 +				CloseOtherTabs(hwndTab, *dat);
 +				break;
 +			case ID_TABMENU_SAVETABPOSITION:
 +				db_set_dw(dat->hContact, SRMSGMOD_T, "tabindex", dat->iTabID * 100);
 +				break;
 +			case ID_TABMENU_CLEARSAVEDTABPOSITION:
 +				db_unset(dat->hContact, SRMSGMOD_T, "tabindex");
 +				break;
 +			case ID_TABMENU_LEAVECHATROOM:
 +				if (dat && dat->bType == SESSIONTYPE_CHAT) {
 +					SESSION_INFO *si = dat->si;
 +					if (si && dat->hContact) {
 +						char *szProto = GetContactProto(dat->hContact);
 +						if (szProto)
 +							CallProtoService(szProto, PS_LEAVECHAT, dat->hContact, 0);
 +					}
 +				}
 +				break;
 +			case ID_TABMENU_ATTACHTOCONTAINER:
 +				if ((iItem = GetTabItemFromMouse(hwndTab, &pt)) == -1)
 +					break;
 +				memset(&item, 0, sizeof(item));
 +				item.mask = TCIF_PARAM;
 +				TabCtrl_GetItem(hwndTab, iItem, &item);
 +				CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_SELECTCONTAINER), hwndDlg, SelectContainerDlgProc, (LPARAM)item.lParam);
 +				break;
 +			case ID_TABMENU_CONTAINEROPTIONS:
 +				if (pContainer->hWndOptions == 0)
 +					CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CONTAINEROPTIONS), hwndDlg, DlgProcContainerOptions, (LPARAM)pContainer);
 +				break;
 +			case ID_TABMENU_CLOSECONTAINER:
 +				SendMessage(hwndDlg, WM_CLOSE, 0, 0);
 +				break;
 +			}
 +			InvalidateRect(hwndTab, NULL, FALSE);
 +			return 1;
 +		}
 +		break;
 +
 +	case WM_COMMAND:
 +		MCONTACT hContact;
 +		{
 +			bool fProcessContactMenu = pContainer->MenuBar->isContactMenu();
 +			bool fProcessMainMenu = pContainer->MenuBar->isMainMenu();
 +			pContainer->MenuBar->Cancel();
 +
 +			TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +			DWORD dwOldFlags = pContainer->dwFlags;
 +
 +			if (dat) {
 +				if (fProcessContactMenu)
 +					return(CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)dat->hContact));
 +				else if (fProcessMainMenu) {
 +					return(CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_MAINMENU), 0));
 +				}
 +				else if (MsgWindowMenuHandler(dat, LOWORD(wParam), MENU_PICMENU) == 1)
 +					break;
 +			}
 +			SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +			if (LOWORD(wParam) == IDC_TBFIRSTUID - 1)
 +				break;
 +
 +			switch (LOWORD(wParam)) {
 +			case IDC_TOGGLESIDEBAR:
 +				GetWindowRect(hwndDlg, &rc);
 +				{
 +					LONG dwNewLeft;
 +					bool fVisible = pContainer->SideBar->isVisible();
 +					if (fVisible) {
 +						dwNewLeft = pContainer->SideBar->getWidth();
 +						pContainer->SideBar->setVisible(false);
 +					}
 +					else {
 +						pContainer->SideBar->setVisible(true);
 +						dwNewLeft = -(pContainer->SideBar->getWidth());
 +					}
 +
 +					pContainer->preSIZE.cx = pContainer->preSIZE.cy = 0;
 +					pContainer->oldDCSize.cx = pContainer->oldDCSize.cy = 0;
 +				}
 +
 +				PostMessage(hwndDlg, WM_SIZE, 0, 1);
 +				break;
 +
 +			case IDC_SIDEBARDOWN:
 +			case IDC_SIDEBARUP:
 +			{
 +				HWND hwnd = GetFocus();
 +				pContainer->SideBar->processScrollerButtons(LOWORD(wParam));
 +				SetFocus(hwnd);
 +			}
 +			break;
 +
 +			default:
 +				Utils::CmdDispatcher(Utils::CMD_CONTAINER, hwndDlg, LOWORD(wParam), wParam, lParam, 0, pContainer);
 +			}
 +
 +			if (pContainer->dwFlags != dwOldFlags)
 +				SendMessage(hwndDlg, DM_CONFIGURECONTAINER, 0, 0);
 +		}
 +		break;
 +
 +	case WM_ENTERSIZEMOVE:
 +		GetClientRect(hwndTab, &rc);
 +		{
 +			SIZE sz;
 +			sz.cx = rc.right - rc.left;
 +			sz.cy = rc.bottom - rc.top;
 +			pContainer->oldSize = sz;
 +			pContainer->bSizingLoop = TRUE;
 +		}
 +		break;
 +
 +	case WM_EXITSIZEMOVE:
 +		GetClientRect(hwndTab, &rc);
 +		if (!((rc.right - rc.left) == pContainer->oldSize.cx && (rc.bottom - rc.top) == pContainer->oldSize.cy)) {
 +			TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +			DM_ScrollToBottom(dat, 0, 0);
 +			SendMessage(pContainer->hwndActive, WM_SIZE, 0, 0);
 +		}
 +		pContainer->bSizingLoop = FALSE;
 +		break;
 +
 +	// determine minimum and maximum size limits
 +	// 1) for maximizing the window when the "vertical maximize" option is set
 +	// 2) to limit the minimum height when manually resizing the window
 +	// (this avoids overlapping of controls inside the window and ensures
 +	// that at least 2 lines of the message log are always visible).
 +	case WM_GETMINMAXINFO:
 +		RECT rcWindow;
 +		{
 +			RECT rcClient = { 0 };
 +
 +			MINMAXINFO *mmi = (MINMAXINFO *)lParam;
 +			mmi->ptMinTrackSize.x = 275;
 +			mmi->ptMinTrackSize.y = 130;
 +			GetClientRect(hwndTab, &rc);
 +			if (pContainer->hwndActive)								// at container creation time, there is no hwndActive yet..
 +				GetClientRect(pContainer->hwndActive, &rcClient);
 +			GetWindowRect(hwndDlg, &rcWindow);
 +			pt.y = rc.top;
 +			TabCtrl_AdjustRect(hwndTab, FALSE, &rc);
 +			// uChildMinHeight holds the min height for the client window only
 +			// so let's add the container's vertical padding (title bar, tab bar,
 +			// window border, status bar) to this value
 +			if (pContainer->hwndActive)
 +				mmi->ptMinTrackSize.y = pContainer->uChildMinHeight + (pContainer->hwndActive ? ((rcWindow.bottom - rcWindow.top) - rcClient.bottom) : 0);
 +
 +			if (pContainer->dwFlags & CNT_VERTICALMAX || (GetKeyState(VK_CONTROL) & 0x8000)) {
 +				RECT rcDesktop = { 0 };
 +				BOOL fDesktopValid = FALSE;
 +				int monitorXOffset = 0;
 +				WINDOWPLACEMENT wp = { 0 };
 +
 +				HMONITOR hMonitor = MonitorFromWindow(hwndDlg, 2);
 +				if (hMonitor) {
 +					MONITORINFO mi = { 0 };
 +					mi.cbSize = sizeof(mi);
 +					GetMonitorInfoA(hMonitor, &mi);
 +					rcDesktop = mi.rcWork;
 +					OffsetRect(&rcDesktop, -mi.rcMonitor.left, -mi.rcMonitor.top);
 +					monitorXOffset = mi.rcMonitor.left;
 +					fDesktopValid = TRUE;
 +				}
 +				if (!fDesktopValid)
 +					SystemParametersInfo(SPI_GETWORKAREA, 0, &rcDesktop, 0);
 +
 +				wp.length = sizeof(wp);
 +				GetWindowPlacement(hwndDlg, &wp);
 +				mmi->ptMaxSize.y = rcDesktop.bottom - rcDesktop.top;
 +				mmi->ptMaxSize.x = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
 +				mmi->ptMaxPosition.x = wp.rcNormalPosition.left - monitorXOffset;
 +				mmi->ptMaxPosition.y = 0;
 +				if (IsIconic(hwndDlg)) {
 +					mmi->ptMaxPosition.x += rcDesktop.left;
 +					mmi->ptMaxPosition.y += rcDesktop.top;
 +				}
 +
 +				// protect against invalid values...
 +				if (mmi->ptMinTrackSize.y < 50 || mmi->ptMinTrackSize.y > rcDesktop.bottom)
 +					mmi->ptMinTrackSize.y = 130;
 +			}
 +		}
 +		return 0;
 +
 +	case DM_UPDATETITLE:
 +		{
 +			MCONTACT hContact = 0;
 +			TWindowData *dat = NULL;
 +
 +			if (lParam) {               // lParam != 0 means sent by a chat window
 +				TCHAR szText[512];
 +				dat = (TWindowData*)GetWindowLongPtr((HWND)wParam, GWLP_USERDATA);
 +				GetWindowText((HWND)wParam, szText, SIZEOF(szText));
 +				szText[SIZEOF(szText) - 1] = 0;
 +				SetWindowText(hwndDlg, szText);
 +				if (dat)
 +					SendMessage(hwndDlg, DM_SETICON, (WPARAM)dat, (LPARAM)(dat->hTabIcon != dat->hTabStatusIcon ? dat->hTabIcon : dat->hTabStatusIcon));
 +				return 0;
 +			}
 +			if (wParam == 0) {           // no hContact given - obtain the hContact for the active tab
 +				if (pContainer->hwndActive && IsWindow(pContainer->hwndActive))
 +					SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +				else
 +					break;
 +				dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +			}
 +			else {
 +				HWND hwnd = M.FindWindow(wParam);
 +				if (hwnd == 0) {
 +					SESSION_INFO *si = SM_FindSessionByHCONTACT(wParam);
 +					if (si) {
 +						SendMessage(si->hWnd, GC_UPDATETITLE, 0, 0);
 +						return 0;
 +					}
 +				}
 +				hContact = wParam;
 +				if (hwnd && hContact)
 +					dat = (TWindowData*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
 +			}
 +			if (dat) {
 +				SendMessage(hwndDlg, DM_SETICON, (WPARAM)dat, (LPARAM)(dat->hXStatusIcon ? dat->hXStatusIcon : dat->hTabStatusIcon));
 +				TCHAR *szNewTitle = Utils::FormatTitleBar(dat, pContainer->settings->szTitleFormat);
 +				if (szNewTitle) {
 +					SetWindowText(hwndDlg, szNewTitle);
 +					mir_free(szNewTitle);
 +				}
 +			}
 +		}
 +		return 0;
 +
 +	case WM_TIMER:
 +		if (wParam == TIMERID_HEARTBEAT) {
 +			if (GetForegroundWindow() != hwndDlg && (pContainer->settings->autoCloseSeconds > 0) && !pContainer->fHidden) {
 +				BOOL fResult = TRUE;
 +				BroadCastContainer(pContainer, DM_CHECKAUTOHIDE, (WPARAM)pContainer->settings->autoCloseSeconds, (LPARAM)&fResult);
 +
 +				if (fResult && 0 == pContainer->hWndOptions)
 +					PostMessage(hwndDlg, WM_CLOSE, 1, 0);
 +			}
 +
 +			TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +			if (dat && dat->bType == SESSIONTYPE_IM) {
 +				if (dat->idle && pContainer->hwndActive && IsWindow(pContainer->hwndActive))
 +					dat->Panel->Invalidate(TRUE);
 +			}
 +			else if (dat)
 +				SendMessage(dat->hwnd, GC_UPDATESTATUSBAR, 0, 0);
 +		}
 +		else if (wParam == TIMERID_HOVER) {
 +			RECT rcWindow;
 +			GetWindowRect(hwndDlg, &rcWindow);
 +		}
 +		break;
 +
 +	case WM_SYSCOMMAND:
 +		switch (wParam) {
 +		case IDM_STAYONTOP:
 +			SetWindowPos(hwndDlg, (pContainer->dwFlags & CNT_STICKY) ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
 +			CheckMenuItem(GetSystemMenu(hwndDlg, FALSE), IDM_STAYONTOP, (pContainer->dwFlags & CNT_STICKY) ? MF_BYCOMMAND | MF_UNCHECKED : MF_BYCOMMAND | MF_CHECKED);
 +			ApplyContainerSetting(pContainer, CNT_STICKY, pContainer->dwFlags & CNT_STICKY ? 0 : 1, false);
 +			break;
 +		case IDM_NOTITLE:
 +			pContainer->oldSize.cx = 0;
 +			pContainer->oldSize.cy = 0;
 +
 +			CheckMenuItem(GetSystemMenu(hwndDlg, FALSE), IDM_NOTITLE, (pContainer->dwFlags & CNT_NOTITLE) ? MF_BYCOMMAND | MF_UNCHECKED : MF_BYCOMMAND | MF_CHECKED);
 +			ApplyContainerSetting(pContainer, CNT_NOTITLE, pContainer->dwFlags & CNT_NOTITLE ? 0 : 1, false);
 +			break;
 +		case IDM_MOREOPTIONS:
 +			if (IsIconic(pContainer->hwnd))
 +				SendMessage(pContainer->hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
 +			if (pContainer->hWndOptions == 0)
 +				CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CONTAINEROPTIONS), hwndDlg, DlgProcContainerOptions, (LPARAM)pContainer);
 +			break;
 +		case SC_MAXIMIZE:
 +			pContainer->oldSize.cx = pContainer->oldSize.cy = 0;
 +			break;
 +		case SC_RESTORE:
 +			pContainer->oldSize.cx = pContainer->oldSize.cy = 0;
 +			memset((void*)&pContainer->mOld, -1000, sizeof(MARGINS));
 +			break;
 +		case SC_MINIMIZE:
 +			TWindowData *dat = reinterpret_cast<TWindowData *>(GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA));
 +			if (dat) {
 +				GetWindowRect(pContainer->hwndActive, &pContainer->rcLogSaved);
 +				pContainer->ptLogSaved.x = pContainer->rcLogSaved.left;
 +				pContainer->ptLogSaved.y = pContainer->rcLogSaved.top;
 +				ScreenToClient(hwndDlg, &pContainer->ptLogSaved);
 +			}
 +		}
 +		break;
 +
 +	case DM_SELECTTAB:
 +		switch (wParam) {
 +		case DM_SELECT_BY_HWND:
 +			ActivateTabFromHWND(hwndTab, (HWND)lParam);
 +			break;
 +
 +		case DM_SELECT_NEXT:
 +		case DM_SELECT_PREV:
 +		case DM_SELECT_BY_INDEX:
 +			int iItems = TabCtrl_GetItemCount(hwndTab);
 +			if (iItems == 1)
 +				break;
 +
 +			int iCurrent = TabCtrl_GetCurSel(hwndTab), iNewTab;
 +
 +			if (wParam == DM_SELECT_PREV)
 +				iNewTab = iCurrent ? iCurrent - 1 : iItems - 1;     // cycle if current is already the leftmost tab..
 +			else if (wParam == DM_SELECT_NEXT)
 +				iNewTab = (iCurrent == (iItems - 1)) ? 0 : iCurrent + 1;
 +			else {
 +				if ((int)lParam > iItems)
 +					break;
 +				iNewTab = lParam - 1;
 +			}
 +
 +			if (iNewTab != iCurrent) {
 +				memset(&item, 0, sizeof(item));
 +				item.mask = TCIF_PARAM;
 +				if (TabCtrl_GetItem(hwndTab, iNewTab, &item)) {
 +					TabCtrl_SetCurSel(hwndTab, iNewTab);
 +					ShowWindow(pContainer->hwndActive, SW_HIDE);
 +					pContainer->hwndActive = (HWND)item.lParam;
 +					ShowWindow((HWND)item.lParam, SW_SHOW);
 +					SetFocus(pContainer->hwndActive);
 +				}
 +			}
 +			break;
 +		}
 +		break;
 +
 +	case WM_INITMENUPOPUP:
 +		pContainer->MenuBar->setActive(reinterpret_cast<HMENU>(wParam));
 +		break;
 +
 +	case WM_LBUTTONDOWN:
 +		if (pContainer->dwFlags & CNT_NOTITLE) {
 +			GetCursorPos(&pt);
 +			return SendMessage(hwndDlg, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y));
 +		}
 +		break;
 +
 +		// pass the WM_ACTIVATE msg to the active message dialog child
 +	case WM_NCACTIVATE:
 +		if (IsWindowVisible(hwndDlg))
 +			pContainer->fHidden = false;
 +		break;
 +
 +	case WM_ACTIVATE:
 +		if (pContainer == NULL)
 +			break;
 +
 +		if (LOWORD(wParam == WA_INACTIVE))
 +			BroadCastContainer(pContainer, DM_CHECKINFOTIP, wParam, lParam);
 +
 +		if (LOWORD(wParam == WA_INACTIVE) && (HWND)lParam != PluginConfig.g_hwndHotkeyHandler && GetParent((HWND)lParam) != hwndDlg) {
 +			BOOL fTransAllowed = !bSkinned || PluginConfig.m_bIsVista;
 +
 +			if (pContainer->dwFlags & CNT_TRANSPARENCY && fTransAllowed) {
 +				SetLayeredWindowAttributes(hwndDlg, Skin->getColorKey(), (BYTE)HIWORD(pContainer->settings->dwTransparency), (pContainer->dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0));
 +			}
 +		}
 +		pContainer->hwndSaved = 0;
 +
 +		if (LOWORD(wParam) != WA_ACTIVE) {
 +			pContainer->MenuBar->Cancel();
 +			break;
 +		}
 +
 +	case WM_MOUSEACTIVATE:
 +		if (pContainer != NULL) {
 +			TCITEM item;
 +			int curItem = 0;
 +			BOOL  fTransAllowed = !bSkinned || PluginConfig.m_WinVerMajor >= 6;
 +
 +			FlashContainer(pContainer, 0, 0);
 +			pContainer->dwFlashingStarted = 0;
 +			pLastActiveContainer = pContainer;
 +			if (pContainer->dwFlags & CNT_DEFERREDTABSELECT) {
 +				pContainer->dwFlags &= ~CNT_DEFERREDTABSELECT;
 +				SendMessage(hwndDlg, WM_SYSCOMMAND, SC_RESTORE, 0);
 +
 +				NMHDR nmhdr = { hwndTab, IDC_MSGTABS, TCN_SELCHANGE };
 +				SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nmhdr);     // do it via a WM_NOTIFY / TCN_SELCHANGE to simulate user-activation
 +			}
 +			if (pContainer->dwFlags & CNT_DEFERREDSIZEREQUEST) {
 +				pContainer->dwFlags &= ~CNT_DEFERREDSIZEREQUEST;
 +				SendMessage(hwndDlg, WM_SIZE, 0, 0);
 +			}
 +
 +			if (pContainer->dwFlags & CNT_TRANSPARENCY && fTransAllowed) {
 +				DWORD trans = LOWORD(pContainer->settings->dwTransparency);
 +				SetLayeredWindowAttributes(hwndDlg, Skin->getColorKey(), (BYTE)trans, (pContainer->dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0));
 +			}
 +			if (pContainer->dwFlags & CNT_NEED_UPDATETITLE) {
 +				MCONTACT hContact = 0;
 +				pContainer->dwFlags &= ~CNT_NEED_UPDATETITLE;
 +				if (pContainer->hwndActive) {
 +					SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +					if (hContact)
 +						SendMessage(hwndDlg, DM_UPDATETITLE, hContact, 0);
 +				}
 +			}
 +			memset(&item, 0, sizeof(item));
 +			item.mask = TCIF_PARAM;
 +			if ((curItem = TabCtrl_GetCurSel(hwndTab)) >= 0)
 +				TabCtrl_GetItem(hwndTab, curItem, &item);
 +			if (pContainer->dwFlags & CNT_DEFERREDCONFIGURE && curItem >= 0) {
 +				pContainer->dwFlags &= ~CNT_DEFERREDCONFIGURE;
 +				pContainer->hwndActive = (HWND)item.lParam;
 +				SendMessage(hwndDlg, WM_SYSCOMMAND, SC_RESTORE, 0);
 +				if (pContainer->hwndActive != 0 && IsWindow(pContainer->hwndActive)) {
 +					ShowWindow(pContainer->hwndActive, SW_SHOW);
 +					SetFocus(pContainer->hwndActive);
 +					SendMessage(pContainer->hwndActive, WM_ACTIVATE, WA_ACTIVE, 0);
 +					RedrawWindow(pContainer->hwndActive, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
 +				}
 +			}
 +			else if (curItem >= 0)
 +				SendMessage((HWND)item.lParam, WM_ACTIVATE, WA_ACTIVE, 0);
 +		}
 +		break;
 +
  	case WM_MOUSEMOVE:
  		// wine: fix for erase/paint tab on mouse enter/leave tab.
  		GetCursorPos(&pt);
 @@ -1268,985 +1268,985 @@ static INT_PTR CALLBACK DlgProcContainer(HWND hwndDlg, UINT msg, WPARAM wParam,  		SendMessage(hwndTab, WM_MOUSEMOVE, wParam, (LPARAM)&pt);
  		break;
 -	case DM_CLOSETABATMOUSE: -		if ((iItem = GetTabItemFromMouse(hwndTab, (POINT*)lParam)) != -1) { -			HWND hwndCurrent = pContainer->hwndActive; - -			TCITEM item = { 0 }; -			item.mask = TCIF_PARAM; -			TabCtrl_GetItem(hwndTab, iItem, &item); -			if (item.lParam) { -				if ((HWND)item.lParam != hwndCurrent) { -					pContainer->bDontSmartClose = TRUE; -					SendMessage((HWND)item.lParam, WM_CLOSE, 0, 1); -					RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE); -					pContainer->bDontSmartClose = FALSE; -				} -				else SendMessage((HWND)item.lParam, WM_CLOSE, 0, 1); -			} -		} -		break; - -	case WM_PAINT: -		if (bSkinned || M.isAero()) { -			PAINTSTRUCT ps; -			BeginPaint(hwndDlg, &ps); -			EndPaint(hwndDlg, &ps); -			return 0; -		} -		break; - -	case WM_ERASEBKGND: -		// avoid flickering of the menu bar when aero is active -		if (pContainer) { -			HDC hdc = (HDC)wParam; -			GetClientRect(hwndDlg, &rc); - -			if (M.isAero()) { -				HDC hdcMem; -				HANDLE  hbp = CMimAPI::m_pfnBeginBufferedPaint(hdc, &rc, BPBF_TOPDOWNDIB, 0, &hdcMem); -				FillRect(hdcMem, &rc, CSkin::m_BrushBack); -				CSkin::FinalizeBufferedPaint(hbp, &rc); -			} -			else { -				if (CSkin::m_skinEnabled) -					CSkin::DrawItem(hdc, &rc, &SkinItems[ID_EXTBKCONTAINER]); -				else { -					CSkin::FillBack(hdc, &rc); -					if (pContainer->SideBar->isActive() && pContainer->SideBar->isVisible()) { - -						HPEN hPen = ::CreatePen(PS_SOLID, 1, PluginConfig.m_cRichBorders ? PluginConfig.m_cRichBorders : ::GetSysColor(COLOR_3DSHADOW)); -						HPEN hOldPen = reinterpret_cast<HPEN>(::SelectObject(hdc, hPen)); -						LONG x = (pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_LEFT ? pContainer->SideBar->getWidth() - 2 + pContainer->tBorder_outer_left : -							rc.right - pContainer->SideBar->getWidth() + 1 - pContainer->tBorder_outer_right); -						::MoveToEx(hdc, x, rc.top, 0); -						::LineTo(hdc, x, rc.bottom); -						::SelectObject(hdc, hOldPen); -						::DeleteObject(hPen); -					} -				} -			} -			SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 1); -			return TRUE; -		} -		break; - -	case DM_OPTIONSAPPLIED: -		char szCname[40]; -		TCHAR szTitleFormat[200]; -		{ -			TCHAR *szThemeName = NULL; -			DBVARIANT dbv = { 0 }; - -			szTitleFormat[0] = 0; - -			if (pContainer->isCloned && pContainer->hContactFrom != 0) { -				pContainer->settings = &PluginConfig.globalContainerSettings; - -				pContainer->szRelThemeFile[0] = pContainer->szAbsThemeFile[0] = 0; -				mir_snprintf(szCname, SIZEOF(szCname), "%s_theme", CONTAINER_PREFIX); -				if (!db_get_ts(pContainer->hContactFrom, SRMSGMOD_T, szCname, &dbv)) -					szThemeName = dbv.ptszVal; -			} -			else { -				Utils::ReadPrivateContainerSettings(pContainer); -				if (szThemeName == NULL) { -					mir_snprintf(szCname, SIZEOF(szCname), "%s%d_theme", CONTAINER_PREFIX, pContainer->iContainerIndex); -					if (!db_get_ts(NULL, SRMSGMOD_T, szCname, &dbv)) -						szThemeName = dbv.ptszVal; -				} -			} -			Utils::SettingsToContainer(pContainer); - -			if (szThemeName != NULL) { -				PathToAbsoluteT(szThemeName, pContainer->szAbsThemeFile, M.getDataPath()); -				_tcsncpy_s(pContainer->szRelThemeFile, szThemeName, _TRUNCATE); -				db_free(&dbv); -			} -			else pContainer->szAbsThemeFile[0] = pContainer->szRelThemeFile[0] = 0; - -			pContainer->ltr_templates = pContainer->rtl_templates = 0; -		} -		break; - -	case DM_STATUSBARCHANGED: -		SendMessage(hwndDlg, WM_SIZE, 0, 0); - -		GetWindowRect(hwndDlg, &rc); -		SetWindowPos(hwndDlg, 0, rc.left, rc.top, rc.right - rc.left, (rc.bottom - rc.top) + 1, SWP_NOZORDER | SWP_NOACTIVATE); -		SetWindowPos(hwndDlg, 0, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOACTIVATE); -		RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); - -		if (pContainer->hwndStatus != 0 && pContainer->hwndActive != 0) -			PostMessage(pContainer->hwndActive, DM_STATUSBARCHANGED, 0, 0); -		return 0; - -	case DM_CONFIGURECONTAINER: -		UINT sBarHeight; -		{ -			HMENU hSysmenu = GetSystemMenu(hwndDlg, FALSE); -			MCONTACT hContact = 0; - -			DWORD wsold, ws = wsold = GetWindowLongPtr(hwndDlg, GWL_STYLE); -			if (!CSkin::m_frameSkins) { -				ws = (pContainer->dwFlags & CNT_NOTITLE) ? -					((IsWindowVisible(hwndDlg) ? WS_VISIBLE : 0) | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPCHILDREN | WS_THICKFRAME | (CSkin::m_frameSkins ? WS_SYSMENU : WS_SYSMENU | WS_SIZEBOX)) : -					ws | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN; -			} - -			SetWindowLongPtr(hwndDlg, GWL_STYLE, ws); - -			pContainer->tBorder = M.GetByte((bSkinned ? "S_tborder" : "tborder"), 2); -			pContainer->tBorder_outer_left = g_ButtonSet.left + M.GetByte((bSkinned ? "S_tborder_outer_left" : "tborder_outer_left"), 2); -			pContainer->tBorder_outer_right = g_ButtonSet.right + M.GetByte((bSkinned ? "S_tborder_outer_right" : "tborder_outer_right"), 2); -			pContainer->tBorder_outer_top = g_ButtonSet.top + M.GetByte((bSkinned ? "S_tborder_outer_top" : "tborder_outer_top"), 2); -			pContainer->tBorder_outer_bottom = g_ButtonSet.bottom + M.GetByte((bSkinned ? "S_tborder_outer_bottom" : "tborder_outer_bottom"), 2); -			sBarHeight = (UINT)M.GetByte((bSkinned ? "S_sbarheight" : "sbarheight"), 0); - -			if (LOBYTE(LOWORD(GetVersion())) >= 5) { -				BOOL fTransAllowed = !bSkinned || PluginConfig.m_WinVerMajor >= 6; - -				DWORD exold, ex = exold = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE); -				ex = (pContainer->dwFlags & CNT_TRANSPARENCY && (!CSkin::m_skinEnabled || fTransAllowed)) ? ex | WS_EX_LAYERED : ex & ~(WS_EX_LAYERED); - -				SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, ex); -				if (pContainer->dwFlags & CNT_TRANSPARENCY && fTransAllowed) { -					DWORD trans = LOWORD(pContainer->settings->dwTransparency); -					SetLayeredWindowAttributes(hwndDlg, Skin->getColorKey(), (BYTE)trans, (/* pContainer->bSkinned ? LWA_COLORKEY : */ 0) | (pContainer->dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0)); -				} -			} - -			if (!CSkin::m_frameSkins) -				CheckMenuItem(hSysmenu, IDM_NOTITLE, (pContainer->dwFlags & CNT_NOTITLE) ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED); - -			CheckMenuItem(hSysmenu, IDM_STAYONTOP, pContainer->dwFlags & CNT_STICKY ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED); -			SetWindowPos(hwndDlg, (pContainer->dwFlags & CNT_STICKY) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS); -			if (ws != wsold) { -				GetWindowRect(hwndDlg, &rc); -				if ((ws & WS_CAPTION) != (wsold & WS_CAPTION)) { -					SetWindowPos(hwndDlg, 0, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCOPYBITS); -					RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW); -					if (pContainer->hwndActive != 0) { -						TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -						DM_ScrollToBottom(dat, 0, 0); -					} -				} -			} - -			pContainer->dwFlags = ((pContainer->dwFlagsEx & (TCF_SBARLEFT | TCF_SBARRIGHT)) ? -				pContainer->dwFlags | CNT_SIDEBAR : pContainer->dwFlags & ~CNT_SIDEBAR); - -			pContainer->SideBar->Init(); - -			ws = wsold = GetWindowLongPtr(hwndTab, GWL_STYLE); -			if (pContainer->dwFlags & CNT_TABSBOTTOM) -				ws |= (TCS_BOTTOM); -			else -				ws &= ~(TCS_BOTTOM); -			if ((ws & (TCS_BOTTOM | TCS_MULTILINE)) != (wsold & (TCS_BOTTOM | TCS_MULTILINE))) { -				SetWindowLongPtr(hwndTab, GWL_STYLE, ws); -				RedrawWindow(hwndTab, NULL, NULL, RDW_INVALIDATE); -			} - -			if (pContainer->dwFlags & CNT_NOSTATUSBAR) { -				if (pContainer->hwndStatus) { -					DestroyWindow(pContainer->hwndStatus); -					pContainer->hwndStatus = 0; -					pContainer->statusBarHeight = 0; -					SendMessage(hwndDlg, DM_STATUSBARCHANGED, 0, 0); -				} -			} -			else if (pContainer->hwndStatus == 0) { -				pContainer->hwndStatus = CreateWindowEx(0, _T("TSStatusBarClass"), NULL, SBT_TOOLTIPS | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL); - -				if (sBarHeight && bSkinned) -					SendMessage(pContainer->hwndStatus, SB_SETMINHEIGHT, sBarHeight, 0); -			} -			if (pContainer->hwndActive != 0) { -				hContact = 0; -				SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); -				if (hContact) -					SendMessage(hwndDlg, DM_UPDATETITLE, hContact, 0); -			} -			SendMessage(hwndDlg, WM_SIZE, 0, 1); -			BroadCastContainer(pContainer, DM_CONFIGURETOOLBAR, 0, 1); -		} -		return 0; - -	// search the first and most recent unread events in all client tabs... -	// return all information via a RECENTINFO structure (tab indices, -	// window handles and timestamps). -	case DM_QUERYRECENT: -		DWORD dwTimestamp; -		{ -			int iItems = TabCtrl_GetItemCount(hwndTab); -			TCITEM item = { 0 }; - -			RECENTINFO *ri = (RECENTINFO *)lParam; -			ri->iFirstIndex = ri->iMostRecent = -1; -			ri->dwFirst = ri->dwMostRecent = 0; -			ri->hwndFirst = ri->hwndMostRecent = 0; - -			for (int i = 0; i < iItems; i++) { -				item.mask = TCIF_PARAM; -				TabCtrl_GetItem(hwndTab, i, &item); -				SendMessage((HWND)item.lParam, DM_QUERYLASTUNREAD, 0, (LPARAM)&dwTimestamp); -				if (dwTimestamp > ri->dwMostRecent) { -					ri->dwMostRecent = dwTimestamp; -					ri->iMostRecent = i; -					ri->hwndMostRecent = (HWND)item.lParam; -					if (ri->iFirstIndex == -1) { -						ri->iFirstIndex = i; -						ri->dwFirst = dwTimestamp; -						ri->hwndFirst = (HWND)item.lParam; -					} -				} -			} -		} -		return 0; - -	// search tab with either next or most recent unread message and select it -	case DM_QUERYPENDING: -		RECENTINFO ri; -		{ -			SendMessage(hwndDlg, DM_QUERYRECENT, 0, (LPARAM)&ri); - -			NMHDR nmhdr; -			nmhdr.code = TCN_SELCHANGE; - -			if (wParam == DM_QUERY_NEXT && ri.iFirstIndex != -1) { -				TabCtrl_SetCurSel(hwndTab, ri.iFirstIndex); -				SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nmhdr); -			} -			if (wParam == DM_QUERY_MOSTRECENT && ri.iMostRecent != -1) { -				TabCtrl_SetCurSel(hwndTab, ri.iMostRecent); -				SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nmhdr); -			} -		} -		return 0; - -	case DM_SETICON: -		{ -			TWindowData *dat = (TWindowData*)wParam; -			HICON hIconMsg = PluginConfig.g_IconMsgEvent; -			HICON hIconBig = (dat && dat->cache) ? LoadSkinnedProtoIconBig(dat->cache->getProto(), dat->cache->getStatus()) : 0; - -			if (Win7Taskbar->haveLargeIcons()) { -				if ((HICON)lParam == PluginConfig.g_buttonBarIcons[ICON_DEFAULT_TYPING] || (HICON)lParam == hIconMsg) { -					Win7Taskbar->setOverlayIcon(hwndDlg, lParam); -					if (GetForegroundWindow() != hwndDlg) -						SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam); -					if ((HICON)lParam == hIconMsg) -						pContainer->hIconTaskbarOverlay = hIconMsg; -					break; -				} - -				if (dat) { -					if (dat->hTaskbarIcon == 0) -						dat->hTaskbarIcon = ((dat->pContainer->dwFlags & CNT_AVATARSONTASKBAR) ? Utils::iconFromAvatar(dat) : 0); -					else { -						if (!(dat->pContainer->dwFlags & CNT_AVATARSONTASKBAR)) { -							DestroyIcon(dat->hTaskbarIcon); -							dat->hTaskbarIcon = 0; -						} -					} - -					if (dat->hTaskbarIcon) { -						SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)dat->hTaskbarIcon); -						SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam); -						Win7Taskbar->setOverlayIcon(hwndDlg, (LPARAM)(dat->hTabIcon ? (LPARAM)dat->hTabIcon : lParam)); -					} -					else { -						if (0 == hIconBig || (HICON)CALLSERVICE_NOTFOUND == hIconBig) -							SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)lParam); -						else -							SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIconBig); -						SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam); -						if (dat->pContainer->hIconTaskbarOverlay) -							Win7Taskbar->setOverlayIcon(hwndDlg, (LPARAM)dat->pContainer->hIconTaskbarOverlay); -						else if (Win7Taskbar->haveAlwaysGroupingMode() && fForceOverlayIcons) -							Win7Taskbar->setOverlayIcon(hwndDlg, lParam); -						else -							Win7Taskbar->clearOverlayIcon(hwndDlg); -					} -					return 0; -				} -			} - -			// default handling (no win7 taskbar) -			if ((HICON)lParam == PluginConfig.g_buttonBarIcons[ICON_DEFAULT_TYPING]) {              // always set typing icon, but don't save it... -				SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)PluginConfig.g_IconTypingEventBig); -				SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam); -				break; -			} -			if (reinterpret_cast<HICON>(lParam) == hIconMsg) -				hIconBig = LoadSkinnedIconBig(SKINICON_EVENT_MESSAGE); - -			if (pContainer->hIcon == STICK_ICON_MSG && (HICON)lParam != hIconMsg && pContainer->dwFlags & CNT_NEED_UPDATETITLE) { -				lParam = (LPARAM)hIconMsg; -				hIconBig = LoadSkinnedIconBig(SKINICON_EVENT_MESSAGE); -			} -			SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam); -			if (0 != hIconBig && reinterpret_cast<HICON>(CALLSERVICE_NOTFOUND) != hIconBig) -				SendMessage(hwndDlg, WM_SETICON, ICON_BIG, LPARAM(hIconBig)); -			pContainer->hIcon = (lParam == (LPARAM)hIconMsg) ? STICK_ICON_MSG : 0; -		} -		return 0; - -	case WM_DRAWITEM: -		{ -			DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam; -			if (dis->hwndItem == pContainer->hwndStatus && !(pContainer->dwFlags & CNT_NOSTATUSBAR)) { -				TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); -				if (dat) -					DrawStatusIcons(dat, dis->hDC, dis->rcItem, 2); -				return TRUE; -			} -		} -		return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - -	case WM_MEASUREITEM: -		return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - -	case DM_QUERYCLIENTAREA: -		{ -			RECT *rc = (RECT *)lParam; -			if (rc) { -				if (!IsIconic(hwndDlg)) -					GetClientRect(hwndDlg, rc); -				else -					CopyRect(rc, &pContainer->rcSaved); -				AdjustTabClientRect(pContainer, rc); -			} -		} -		return 0; - -	case WM_DESTROY: -		pContainer->hwnd = 0; -		pContainer->hwndActive = 0; -		pContainer->hMenuContext = 0; -		if (pContainer->hwndStatus) -			DestroyWindow(pContainer->hwndStatus); - -		// mir_free private theme... -		if (pContainer->theme.isPrivate) { -			mir_free(pContainer->ltr_templates); -			mir_free(pContainer->rtl_templates); -			mir_free(pContainer->theme.logFonts); -			mir_free(pContainer->theme.fontColors); -			mir_free(pContainer->theme.rtfFonts); -		} - -		if (pContainer->hwndTip) -			DestroyWindow(pContainer->hwndTip); -		RemoveContainerFromList(pContainer); -		SM_RemoveContainer(pContainer); -		if (pContainer->cachedDC) { -			SelectObject(pContainer->cachedDC, pContainer->oldHBM); -			DeleteObject(pContainer->cachedHBM); -			DeleteDC(pContainer->cachedDC); -		} -		if (pContainer->cachedToolbarDC) { -			SelectObject(pContainer->cachedToolbarDC, pContainer->oldhbmToolbarBG); -			DeleteObject(pContainer->hbmToolbarBG); -			DeleteDC(pContainer->cachedToolbarDC); -		} -		return 0; - -	case WM_NCDESTROY: -		if (pContainer) { -			delete pContainer->MenuBar; -			delete pContainer->SideBar; -			if (pContainer->settings != &PluginConfig.globalContainerSettings) -				mir_free(pContainer->settings); -			mir_free(pContainer); -		} -		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0); -		break; - -	case WM_CLOSE: -		if (PluginConfig.m_bHideOnClose && !lParam) { -			ShowWindow(hwndDlg, SW_HIDE); -			pContainer->fHidden = true; -		} -		else { -			if (TabCtrl_GetItemCount(hwndTab) > 1) { -				LRESULT res = CWarning::show(CWarning::WARN_CLOSEWINDOW, MB_YESNOCANCEL | MB_ICONQUESTION); -				if (IDNO == res || IDCANCEL == res) -					break; -			} - -			// dont ask if container is empty (no tabs) -			if (lParam == 0 && TabCtrl_GetItemCount(hwndTab) > 0) { -				int clients = TabCtrl_GetItemCount(hwndTab), iOpenJobs = 0; - -				TCITEM item = { 0 }; -				item.mask = TCIF_PARAM; -				for (int i = 0; i < clients; i++) { -					TabCtrl_GetItem(hwndTab, i, &item); -					if (item.lParam && IsWindow((HWND)item.lParam)) -						SendMessage((HWND)item.lParam, DM_CHECKQUEUEFORCLOSE, 0, (LPARAM)&iOpenJobs); -				} -				if (iOpenJobs && pContainer) { -					if (pContainer->exFlags & CNT_EX_CLOSEWARN) -						return TRUE; - -					pContainer->exFlags |= CNT_EX_CLOSEWARN; -					LRESULT result = SendQueue::WarnPendingJobs(iOpenJobs); -					pContainer->exFlags &= ~CNT_EX_CLOSEWARN; -					if (result == IDNO) -						return TRUE; -				} -			} - -			// save geometry information to the database... -			if (!(pContainer->dwFlags & CNT_GLOBALSIZE)) { -				WINDOWPLACEMENT wp = { 0 }; -				wp.length = sizeof(wp); -				if (GetWindowPlacement(hwndDlg, &wp) != 0) { -					if (pContainer->isCloned && pContainer->hContactFrom != 0) { -						TCITEM item = { 0 }; -						item.mask = TCIF_PARAM; -						TabCtrl_GetItem(hwndTab, TabCtrl_GetCurSel(hwndTab), &item); - -						MCONTACT hContact; -						SendMessage((HWND)item.lParam, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); -						db_set_b(hContact, SRMSGMOD_T, "splitmax", (BYTE)((wp.showCmd == SW_SHOWMAXIMIZED) ? 1 : 0)); - -						for (int i = 0; i < TabCtrl_GetItemCount(hwndTab); i++) { -							if (TabCtrl_GetItem(hwndTab, i, &item)) { -								SendMessage((HWND)item.lParam, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); -								db_set_dw(hContact, SRMSGMOD_T, "splitx", wp.rcNormalPosition.left); -								db_set_dw(hContact, SRMSGMOD_T, "splity", wp.rcNormalPosition.top); -								db_set_dw(hContact, SRMSGMOD_T, "splitwidth", wp.rcNormalPosition.right - wp.rcNormalPosition.left); -								db_set_dw(hContact, SRMSGMOD_T, "splitheight", wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); -							} -						} -					} -					else { -						char szCName[40]; -						mir_snprintf(szCName, SIZEOF(szCName), "%s%dx", CONTAINER_PREFIX, pContainer->iContainerIndex); -						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.left); -						mir_snprintf(szCName, SIZEOF(szCName), "%s%dy", CONTAINER_PREFIX, pContainer->iContainerIndex); -						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.top); -						mir_snprintf(szCName, SIZEOF(szCName), "%s%dwidth", CONTAINER_PREFIX, pContainer->iContainerIndex); -						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.right - wp.rcNormalPosition.left); -						mir_snprintf(szCName, SIZEOF(szCName), "%s%dheight", CONTAINER_PREFIX, pContainer->iContainerIndex); -						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top); - -						db_set_b(0, SRMSGMOD_T, "splitmax", (BYTE)((wp.showCmd == SW_SHOWMAXIMIZED) ? 1 : 0)); -					} -				} -			} - -			// clear temp flags which should NEVER be saved... -			if (pContainer->isCloned && pContainer->hContactFrom != 0) { -				TCITEM item = { 0 }; -				item.mask = TCIF_PARAM; -				pContainer->dwFlags &= ~(CNT_DEFERREDCONFIGURE | CNT_CREATE_MINIMIZED | CNT_DEFERREDSIZEREQUEST | CNT_CREATE_CLONED); -				for (int i = 0; i < TabCtrl_GetItemCount(hwndTab); i++) { -					if (TabCtrl_GetItem(hwndTab, i, &item)) { -						MCONTACT hContact; -						SendMessage((HWND)item.lParam, DM_QUERYHCONTACT, 0, (LPARAM)&hContact); - -						char szCName[40]; -						mir_snprintf(szCName, SIZEOF(szCName), "%s_theme", CONTAINER_PREFIX); -						if (mir_tstrlen(pContainer->szRelThemeFile) > 1) { -							if (pContainer->fPrivateThemeChanged == TRUE) { -								PathToRelativeT(pContainer->szRelThemeFile, pContainer->szAbsThemeFile, M.getDataPath()); -								db_set_ts(hContact, SRMSGMOD_T, szCName, pContainer->szRelThemeFile); -								pContainer->fPrivateThemeChanged = FALSE; -							} -						} -						else { -							db_unset(hContact, SRMSGMOD_T, szCName); -							pContainer->fPrivateThemeChanged = FALSE; -						} -					} -				} -			} -			else Utils::SaveContainerSettings(pContainer, CONTAINER_PREFIX); -			DestroyWindow(hwndDlg); -		} -	} -	return FALSE; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// CreateContainer MUST allocate a ContainerWindowData and pass its address -// to CreateDialogParam() via the LPARAM. It also adds the struct to the linked list -// of containers. -// -// The WM_DESTROY handler of the container DlgProc is responsible for mir_free()'ing the -// pointer and for removing the struct from the linked list. - -TContainerData* TSAPI CreateContainer(const TCHAR *name, int iTemp, MCONTACT hContactFrom) -{ -	if (CMimAPI::m_shutDown) -		return NULL; - -	TContainerData *pContainer = (TContainerData*)mir_calloc(sizeof(TContainerData)); -	if (pContainer == NULL) -		return NULL; -	_tcsncpy(pContainer->szName, name, CONTAINER_NAMELEN + 1); -	AppendToContainerList(pContainer); - -	if (M.GetByte("limittabs", 0) && !_tcscmp(name, _T("default"))) -		iTemp |= CNT_CREATEFLAG_CLONED; - -	// save container name to the db -	if (!M.GetByte("singlewinmode", 0)) { -		int iFirstFree = -1, iFound = FALSE, i = 0; -		do { -			char szCounter[10]; -			itoa(i, szCounter, 10); -			ptrT tszName(db_get_tsa(NULL, CONTAINER_KEY, szCounter)); -			if (tszName == NULL) { -				if (iFirstFree != -1) { -					pContainer->iContainerIndex = iFirstFree; -					itoa(iFirstFree, szCounter, 10); -				} -				else pContainer->iContainerIndex = i; - -				db_set_ts(NULL, CONTAINER_KEY, szCounter, name); -				BuildContainerMenu(); -				break; -			} - -			if (!_tcsncmp(tszName, name, CONTAINER_NAMELEN)) { -				pContainer->iContainerIndex = i; -				iFound = TRUE; -			} -			else if (!_tcsncmp(tszName, _T("**mir_free**"), CONTAINER_NAMELEN)) -				iFirstFree = i; -		} while (++i && iFound == FALSE); -	} -	else { -		iTemp |= CNT_CREATEFLAG_CLONED; -		pContainer->iContainerIndex = 1; -	} - -	if (iTemp & CNT_CREATEFLAG_MINIMIZED) -		pContainer->dwFlags = CNT_CREATE_MINIMIZED; -	if (iTemp & CNT_CREATEFLAG_CLONED) { -		pContainer->dwFlags |= CNT_CREATE_CLONED; -		pContainer->hContactFrom = hContactFrom; -	} -	pContainer->hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGCONTAINER), NULL, DlgProcContainer, (LPARAM)pContainer); -	return pContainer; -} - -// search the list of tabs and return the tab (by index) which "belongs" to the given -// hwnd. The hwnd is the handle of a message dialog childwindow. At creation, -// the dialog handle is stored in the TCITEM.lParam field, because we need -// to know the owner of the tab. -// -// hwndTab: handle of the tab control itself. -// hwnd: handle of a message dialog. -// -// returns the tab index (zero based), -1 if no tab is found (which SHOULD not -// really happen, but who knows... ;)) - -int TSAPI GetTabIndexFromHWND(HWND hwndTab, HWND hwnd) -{ -	int iItems = TabCtrl_GetItemCount(hwndTab); - -	TCITEM item = { 0 }; -	item.mask = TCIF_PARAM; -	for (int i = 0; i < iItems; i++) { -		TabCtrl_GetItem(hwndTab, i, &item); -		if ((HWND)item.lParam == hwnd) -			return i; -	} -	return -1; -} - -HWND TSAPI GetHWNDFromTabIndex(HWND hwndTab, int idx) -{ -	TCITEM item = { 0 }; -	item.mask = TCIF_PARAM; -	TabCtrl_GetItem(hwndTab, idx, &item); -	return (HWND)item.lParam; -} - -// activates the tab belonging to the given client HWND (handle of the actual -// message window. - -int TSAPI ActivateTabFromHWND(HWND hwndTab, HWND hwnd) -{ -	int iItem = GetTabIndexFromHWND(hwndTab, hwnd); -	if (iItem >= 0) { -		TabCtrl_SetCurSel(hwndTab, iItem); - -		NMHDR nmhdr = { 0 }; -		nmhdr.code = TCN_SELCHANGE; -		SendMessage(GetParent(hwndTab), WM_NOTIFY, 0, (LPARAM)&nmhdr);     // do it via a WM_NOTIFY / TCN_SELCHANGE to simulate user-activation -		return iItem; -	} -	return -1; -} - -// enumerates tabs and closes all of them, but the one in dat -void TSAPI CloseOtherTabs(HWND hwndTab, TWindowData &dat) -{ -	for (int idxt = 0; idxt < dat.pContainer->iChilds;) { -		HWND otherTab = GetHWNDFromTabIndex(hwndTab, idxt); -		if (otherTab != NULL && otherTab != dat.hwnd) -			SendMessage(otherTab, WM_CLOSE, 1, 0); -		else -			++idxt; -	} -} - -// cut off contact name to the option value set via Options->Tabbed messaging -// some people were requesting this, because really long contact list names -// are causing extraordinary wide tabs and these are looking ugly and wasting -// screen space. -// -// size = max length of target string - -int TSAPI CutContactName(const TCHAR *oldname, TCHAR *newname, unsigned int size) -{ -	size_t cutMax = PluginConfig.m_iTabNameLimit; - -	if (mir_tstrlen(oldname) <= cutMax) -		_tcsncpy_s(newname, size, oldname, _TRUNCATE); -	else { -		TCHAR fmt[30]; -		mir_sntprintf(fmt, SIZEOF(fmt), _T("%%%d.%ds..."), cutMax, cutMax); -		mir_sntprintf(newname, size, fmt, oldname); -	} -	return 0; -} - -// functions for handling the linked list of struct ContainerWindowData *foo - -static TContainerData* TSAPI AppendToContainerList(TContainerData *pContainer) -{ -	if (!pFirstContainer) { -		pFirstContainer = pContainer; -		pFirstContainer->pNext = NULL; -		return pFirstContainer; -	} - -	TContainerData *p = pFirstContainer; -	while (p->pNext != 0) -		p = p->pNext; -	p->pNext = pContainer; -	pContainer->pNext = NULL; -	return p; -} - -TContainerData* TSAPI FindContainerByName(const TCHAR *name) -{ -	if (name == NULL || mir_tstrlen(name) == 0) -		return 0; - -	if (M.GetByte("singlewinmode", 0)) // single window mode - always return 0 and force a new container -		return NULL; - -	for (TContainerData *p = pFirstContainer; p; p = p->pNext) -		if (!_tcsncmp(p->szName, name, CONTAINER_NAMELEN)) -			return p; - -	// error, didn't find it. -	return NULL; -} - -static TContainerData* TSAPI RemoveContainerFromList(TContainerData *pContainer) -{ -	if (pContainer == pFirstContainer) { -		if (pContainer->pNext != NULL) -			pFirstContainer = pContainer->pNext; -		else -			pFirstContainer = NULL; - -		if (pLastActiveContainer == pContainer)     // make sure, we don't reference this container anymore -			pLastActiveContainer = pFirstContainer; - -		return pFirstContainer; -	} - -	for (TContainerData *p = pFirstContainer; p; p = p->pNext) { -		if (p->pNext == pContainer) { -			p->pNext = p->pNext->pNext; - -			if (pLastActiveContainer == pContainer)     // make sure, we don't reference this container anymore -				pLastActiveContainer = pFirstContainer; - -			return 0; -		} -	} -	return NULL; -} - -// calls the TabCtrl_AdjustRect to calculate the "real" client area of the tab. -// also checks for the option "hide tabs when only one tab open" and adjusts -// geometry if necessary -// rc is the RECT obtained by GetClientRect(hwndTab) - -void TSAPI AdjustTabClientRect(TContainerData *pContainer, RECT *rc) -{ -	HWND hwndTab = GetDlgItem(pContainer->hwnd, IDC_MSGTABS); -	DWORD tBorder = pContainer->tBorder; -	DWORD dwStyle = GetWindowLongPtr(hwndTab, GWL_STYLE); - -	RECT rcTab, rcTabOrig; -	GetClientRect(hwndTab, &rcTab); -	if (!(pContainer->dwFlags & CNT_SIDEBAR) && (pContainer->iChilds > 1 || !(pContainer->dwFlags & CNT_HIDETABS))) { -		rcTabOrig = rcTab; -		TabCtrl_AdjustRect(hwndTab, FALSE, &rcTab); -		DWORD dwTopPad = rcTab.top - rcTabOrig.top; - -		rc->left += tBorder; -		rc->right -= tBorder; - -		if (dwStyle & TCS_BUTTONS) { -			if (pContainer->dwFlags & CNT_TABSBOTTOM) { -				int nCount = TabCtrl_GetItemCount(hwndTab); -				if (nCount > 0) { -					RECT rcItem; -					TabCtrl_GetItemRect(hwndTab, nCount - 1, &rcItem); -					rc->bottom = rcItem.top; -				} -			} -			else { -				rc->top += (dwTopPad - 2); -				rc->bottom = rcTabOrig.bottom; -			} -		} -		else { -			if (pContainer->dwFlags & CNT_TABSBOTTOM) -				rc->bottom = rcTab.bottom + 2; -			else { -				rc->top += (dwTopPad - 2); -				rc->bottom = rcTabOrig.bottom; -			} -		} - -		rc->top += tBorder; -		rc->bottom -= tBorder; -	} -	else { -		rc->bottom = rcTab.bottom; -		rc->top = rcTab.top; -	} -	rc->right -= (pContainer->tBorder_outer_left + pContainer->tBorder_outer_right); -	if (pContainer->SideBar->isVisible()) -		rc->right -= pContainer->SideBar->getWidth(); -} - -// retrieve the container name for the given contact handle. -// if none is assigned, return the name of the default container - -int TSAPI GetContainerNameForContact(MCONTACT hContact, TCHAR *szName, int iNameLen) -{ -	// single window mode using cloned (temporary) containers -	if (M.GetByte("singlewinmode", 0)) { -		_tcsncpy_s(szName, iNameLen, _T("Message Session"), _TRUNCATE); -		return 0; -	} - -	// use clist group names for containers... -	if (M.GetByte("useclistgroups", 0)) { -		ptrT tszGroup(db_get_tsa(hContact, "CList", "Group")); -		if (tszGroup == NULL) { -			_tcsncpy_s(szName, iNameLen, _T("default"), _TRUNCATE); -			return 0; -		} - -		_tcsncpy_s(szName, iNameLen, tszGroup, _TRUNCATE); -		return 1; -	} - -	ptrT tszContainerName(db_get_tsa(hContact, SRMSGMOD_T, CONTAINER_SUBKEY)); -	if (tszContainerName == NULL) { -		_tcsncpy_s(szName, iNameLen, _T("default"), _TRUNCATE); -		return 0; -	} - -	_tcsncpy_s(szName, iNameLen, tszContainerName, _TRUNCATE); -	return 1; -} - -void TSAPI DeleteContainer(int iIndex) -{ -	char szIndex[10]; -	itoa(iIndex, szIndex, 10); -	ptrT tszContainerName(db_get_tsa(NULL, CONTAINER_KEY, szIndex)); -	if (tszContainerName == NULL) -		return; - -	db_set_ts(NULL, CONTAINER_KEY, szIndex, _T("**mir_free**")); - -	for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { -		ptrT tszValue(db_get_tsa(hContact, SRMSGMOD_T, CONTAINER_SUBKEY)); -		if (!mir_tstrcmp(tszValue, tszContainerName)) -			db_unset(hContact, SRMSGMOD_T, CONTAINER_SUBKEY); -	} - -	char szSetting[CONTAINER_NAMELEN + 30]; -	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%d_Flags", CONTAINER_PREFIX, iIndex); -	db_unset(NULL, SRMSGMOD_T, szSetting); -	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%d_Trans", CONTAINER_PREFIX, iIndex); -	db_unset(NULL, SRMSGMOD_T, szSetting); -	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dwidth", CONTAINER_PREFIX, iIndex); -	db_unset(NULL, SRMSGMOD_T, szSetting); -	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dheight", CONTAINER_PREFIX, iIndex); -	db_unset(NULL, SRMSGMOD_T, szSetting); -	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dx", CONTAINER_PREFIX, iIndex); -	db_unset(NULL, SRMSGMOD_T, szSetting); -	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dy", CONTAINER_PREFIX, iIndex); -	db_unset(NULL, SRMSGMOD_T, szSetting); -} - -void TSAPI RenameContainer(int iIndex, const TCHAR *szNew) -{ -	if (mir_tstrlen(szNew) == 0) -		return; - -	char szIndex[10]; -	itoa(iIndex, szIndex, 10); -	ptrT tszContainerName(db_get_tsa(NULL, CONTAINER_KEY, szIndex)); -	if (tszContainerName == NULL) -		return; - -	db_set_ts(NULL, CONTAINER_KEY, szIndex, szNew); - -	for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { -		ptrT tszValue(db_get_tsa(hContact, SRMSGMOD_T, CONTAINER_SUBKEY)); -		if (!mir_tstrcmp(tszValue, tszContainerName)) -			db_set_ts(hContact, SRMSGMOD_T, CONTAINER_SUBKEY, szNew); -	} -} - -HMENU TSAPI BuildContainerMenu() -{ -	if (PluginConfig.g_hMenuContainer != 0) { -		HMENU submenu = GetSubMenu(PluginConfig.g_hMenuContext, 0); -		RemoveMenu(submenu, 6, MF_BYPOSITION); -		DestroyMenu(PluginConfig.g_hMenuContainer); -		PluginConfig.g_hMenuContainer = 0; -	} - -	// no container attach menu, if we are using the "clist group mode" -	if (M.GetByte("useclistgroups", 0) || M.GetByte("singlewinmode", 0)) -		return NULL; - -	HMENU hMenu = CreateMenu(); -	int i = 0; -	while (true) { -		char szCounter[10]; -		itoa(i, szCounter, 10); -		ptrT tszName(db_get_tsa(NULL, CONTAINER_KEY, szCounter)); -		if (tszName == NULL) -			break; - -		if (_tcsncmp(tszName, _T("**mir_free**"), CONTAINER_NAMELEN)) -			AppendMenu(hMenu, MF_STRING, IDM_CONTAINERMENU + i, !_tcscmp(tszName, _T("default")) ? TranslateT("Default container") : tszName); -		i++; -	} - -	InsertMenu(PluginConfig.g_hMenuContext, ID_TABMENU_ATTACHTOCONTAINER, MF_BYCOMMAND | MF_POPUP, (UINT_PTR)hMenu, TranslateT("Attach to")); -	PluginConfig.g_hMenuContainer = hMenu; -	return hMenu; -} - -// flashes the container -// iMode != 0: turn on flashing -// iMode == 0: turn off flashing - -void TSAPI FlashContainer(TContainerData *pContainer, int iMode, int iCount) -{ -	if (pContainer->dwFlags & CNT_NOFLASH)                  // container should never flash -		return; - -	FLASHWINFO fwi; -	fwi.cbSize = sizeof(fwi); -	fwi.uCount = 0; - -	if (iMode) { -		fwi.dwFlags = FLASHW_ALL; -		if (pContainer->dwFlags & CNT_FLASHALWAYS) -			fwi.dwFlags |= FLASHW_TIMER; -		else -			fwi.uCount = (iCount == 0) ? M.GetByte("nrflash", 4) : iCount; -		fwi.dwTimeout = M.GetDword("flashinterval", 1000); - -	} -	else fwi.dwFlags = FLASHW_STOP; - -	fwi.hwnd = pContainer->hwnd; -	pContainer->dwFlashingStarted = GetTickCount(); -	FlashWindowEx(&fwi); -} - -void TSAPI ReflashContainer(TContainerData *pContainer) -{ -	DWORD dwStartTime = pContainer->dwFlashingStarted; - -	if (GetForegroundWindow() == pContainer->hwnd || GetActiveWindow() == pContainer->hwnd)       // dont care about active windows -		return; - -	if (pContainer->dwFlags & CNT_NOFLASH || pContainer->dwFlashingStarted == 0) -		return;                                                                                 // dont care about containers which should never flash - -	if (pContainer->dwFlags & CNT_FLASHALWAYS) -		FlashContainer(pContainer, 1, 0); -	else { -		// recalc the remaining flashes -		DWORD dwInterval = M.GetDword("flashinterval", 1000); -		int iFlashesElapsed = (GetTickCount() - dwStartTime) / dwInterval; -		DWORD dwFlashesDesired = M.GetByte("nrflash", 4); -		if (iFlashesElapsed < (int)dwFlashesDesired) -			FlashContainer(pContainer, 1, dwFlashesDesired - iFlashesElapsed); -		else { -			BOOL isFlashed = FlashWindow(pContainer->hwnd, TRUE); -			if (!isFlashed) -				FlashWindow(pContainer->hwnd, TRUE); -		} -	} -	pContainer->dwFlashingStarted = dwStartTime; -} - -// broadcasts a message to all child windows (tabs/sessions) - -void TSAPI BroadCastContainer(const TContainerData *pContainer, UINT message, WPARAM wParam, LPARAM lParam, BYTE bType) -{ -	if (pContainer == NULL) -		return; -	HWND hwndTab = GetDlgItem(pContainer->hwnd, IDC_MSGTABS); - -	TCITEM item = { 0 }; -	item.mask = TCIF_PARAM; - -	int nCount = TabCtrl_GetItemCount(hwndTab); -	for (int i = 0; i < nCount; i++) { -		TabCtrl_GetItem(hwndTab, i, &item); -		if (IsWindow((HWND)item.lParam)) { -			if (bType == SESSIONTYPE_ANY) -				SendMessage((HWND)item.lParam, message, wParam, lParam); -			else { -				TWindowData *dat = (TWindowData*)GetWindowLongPtr((HWND)item.lParam, GWLP_USERDATA); -				if (dat && dat->bType == bType) -					SendMessage((HWND)item.lParam, message, wParam, lParam); -			} -		} -	} -} - -void TSAPI CloseAllContainers() -{ -	bool fOldHideSetting = PluginConfig.m_bHideOnClose; - -	while (pFirstContainer != NULL) { -		if (!IsWindow(pFirstContainer->hwnd)) -			pFirstContainer = pFirstContainer->pNext; -		else { -			PluginConfig.m_bHideOnClose = false; -			::SendMessage(pFirstContainer->hwnd, WM_CLOSE, 0, 1); -		} -	} - -	PluginConfig.m_bHideOnClose = fOldHideSetting; -} +	case DM_CLOSETABATMOUSE:
 +		if ((iItem = GetTabItemFromMouse(hwndTab, (POINT*)lParam)) != -1) {
 +			HWND hwndCurrent = pContainer->hwndActive;
 +
 +			TCITEM item = { 0 };
 +			item.mask = TCIF_PARAM;
 +			TabCtrl_GetItem(hwndTab, iItem, &item);
 +			if (item.lParam) {
 +				if ((HWND)item.lParam != hwndCurrent) {
 +					pContainer->bDontSmartClose = TRUE;
 +					SendMessage((HWND)item.lParam, WM_CLOSE, 0, 1);
 +					RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE);
 +					pContainer->bDontSmartClose = FALSE;
 +				}
 +				else SendMessage((HWND)item.lParam, WM_CLOSE, 0, 1);
 +			}
 +		}
 +		break;
 +
 +	case WM_PAINT:
 +		if (bSkinned || M.isAero()) {
 +			PAINTSTRUCT ps;
 +			BeginPaint(hwndDlg, &ps);
 +			EndPaint(hwndDlg, &ps);
 +			return 0;
 +		}
 +		break;
 +
 +	case WM_ERASEBKGND:
 +		// avoid flickering of the menu bar when aero is active
 +		if (pContainer) {
 +			HDC hdc = (HDC)wParam;
 +			GetClientRect(hwndDlg, &rc);
 +
 +			if (M.isAero()) {
 +				HDC hdcMem;
 +				HANDLE  hbp = CMimAPI::m_pfnBeginBufferedPaint(hdc, &rc, BPBF_TOPDOWNDIB, 0, &hdcMem);
 +				FillRect(hdcMem, &rc, CSkin::m_BrushBack);
 +				CSkin::FinalizeBufferedPaint(hbp, &rc);
 +			}
 +			else {
 +				if (CSkin::m_skinEnabled)
 +					CSkin::DrawItem(hdc, &rc, &SkinItems[ID_EXTBKCONTAINER]);
 +				else {
 +					CSkin::FillBack(hdc, &rc);
 +					if (pContainer->SideBar->isActive() && pContainer->SideBar->isVisible()) {
 +
 +						HPEN hPen = ::CreatePen(PS_SOLID, 1, PluginConfig.m_cRichBorders ? PluginConfig.m_cRichBorders : ::GetSysColor(COLOR_3DSHADOW));
 +						HPEN hOldPen = reinterpret_cast<HPEN>(::SelectObject(hdc, hPen));
 +						LONG x = (pContainer->SideBar->getFlags() & CSideBar::SIDEBARORIENTATION_LEFT ? pContainer->SideBar->getWidth() - 2 + pContainer->tBorder_outer_left :
 +							rc.right - pContainer->SideBar->getWidth() + 1 - pContainer->tBorder_outer_right);
 +						::MoveToEx(hdc, x, rc.top, 0);
 +						::LineTo(hdc, x, rc.bottom);
 +						::SelectObject(hdc, hOldPen);
 +						::DeleteObject(hPen);
 +					}
 +				}
 +			}
 +			SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 1);
 +			return TRUE;
 +		}
 +		break;
 +
 +	case DM_OPTIONSAPPLIED:
 +		char szCname[40];
 +		TCHAR szTitleFormat[200];
 +		{
 +			TCHAR *szThemeName = NULL;
 +			DBVARIANT dbv = { 0 };
 +
 +			szTitleFormat[0] = 0;
 +
 +			if (pContainer->isCloned && pContainer->hContactFrom != 0) {
 +				pContainer->settings = &PluginConfig.globalContainerSettings;
 +
 +				pContainer->szRelThemeFile[0] = pContainer->szAbsThemeFile[0] = 0;
 +				mir_snprintf(szCname, SIZEOF(szCname), "%s_theme", CONTAINER_PREFIX);
 +				if (!db_get_ts(pContainer->hContactFrom, SRMSGMOD_T, szCname, &dbv))
 +					szThemeName = dbv.ptszVal;
 +			}
 +			else {
 +				Utils::ReadPrivateContainerSettings(pContainer);
 +				if (szThemeName == NULL) {
 +					mir_snprintf(szCname, SIZEOF(szCname), "%s%d_theme", CONTAINER_PREFIX, pContainer->iContainerIndex);
 +					if (!db_get_ts(NULL, SRMSGMOD_T, szCname, &dbv))
 +						szThemeName = dbv.ptszVal;
 +				}
 +			}
 +			Utils::SettingsToContainer(pContainer);
 +
 +			if (szThemeName != NULL) {
 +				PathToAbsoluteT(szThemeName, pContainer->szAbsThemeFile, M.getDataPath());
 +				_tcsncpy_s(pContainer->szRelThemeFile, szThemeName, _TRUNCATE);
 +				db_free(&dbv);
 +			}
 +			else pContainer->szAbsThemeFile[0] = pContainer->szRelThemeFile[0] = 0;
 +
 +			pContainer->ltr_templates = pContainer->rtl_templates = 0;
 +		}
 +		break;
 +
 +	case DM_STATUSBARCHANGED:
 +		SendMessage(hwndDlg, WM_SIZE, 0, 0);
 +
 +		GetWindowRect(hwndDlg, &rc);
 +		SetWindowPos(hwndDlg, 0, rc.left, rc.top, rc.right - rc.left, (rc.bottom - rc.top) + 1, SWP_NOZORDER | SWP_NOACTIVATE);
 +		SetWindowPos(hwndDlg, 0, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOZORDER | SWP_NOACTIVATE);
 +		RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
 +
 +		if (pContainer->hwndStatus != 0 && pContainer->hwndActive != 0)
 +			PostMessage(pContainer->hwndActive, DM_STATUSBARCHANGED, 0, 0);
 +		return 0;
 +
 +	case DM_CONFIGURECONTAINER:
 +		UINT sBarHeight;
 +		{
 +			HMENU hSysmenu = GetSystemMenu(hwndDlg, FALSE);
 +			MCONTACT hContact = 0;
 +
 +			DWORD wsold, ws = wsold = GetWindowLongPtr(hwndDlg, GWL_STYLE);
 +			if (!CSkin::m_frameSkins) {
 +				ws = (pContainer->dwFlags & CNT_NOTITLE) ?
 +					((IsWindowVisible(hwndDlg) ? WS_VISIBLE : 0) | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPCHILDREN | WS_THICKFRAME | (CSkin::m_frameSkins ? WS_SYSMENU : WS_SYSMENU | WS_SIZEBOX)) :
 +					ws | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
 +			}
 +
 +			SetWindowLongPtr(hwndDlg, GWL_STYLE, ws);
 +
 +			pContainer->tBorder = M.GetByte((bSkinned ? "S_tborder" : "tborder"), 2);
 +			pContainer->tBorder_outer_left = g_ButtonSet.left + M.GetByte((bSkinned ? "S_tborder_outer_left" : "tborder_outer_left"), 2);
 +			pContainer->tBorder_outer_right = g_ButtonSet.right + M.GetByte((bSkinned ? "S_tborder_outer_right" : "tborder_outer_right"), 2);
 +			pContainer->tBorder_outer_top = g_ButtonSet.top + M.GetByte((bSkinned ? "S_tborder_outer_top" : "tborder_outer_top"), 2);
 +			pContainer->tBorder_outer_bottom = g_ButtonSet.bottom + M.GetByte((bSkinned ? "S_tborder_outer_bottom" : "tborder_outer_bottom"), 2);
 +			sBarHeight = (UINT)M.GetByte((bSkinned ? "S_sbarheight" : "sbarheight"), 0);
 +
 +			if (LOBYTE(LOWORD(GetVersion())) >= 5) {
 +				BOOL fTransAllowed = !bSkinned || PluginConfig.m_WinVerMajor >= 6;
 +
 +				DWORD exold, ex = exold = GetWindowLongPtr(hwndDlg, GWL_EXSTYLE);
 +				ex = (pContainer->dwFlags & CNT_TRANSPARENCY && (!CSkin::m_skinEnabled || fTransAllowed)) ? ex | WS_EX_LAYERED : ex & ~(WS_EX_LAYERED);
 +
 +				SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, ex);
 +				if (pContainer->dwFlags & CNT_TRANSPARENCY && fTransAllowed) {
 +					DWORD trans = LOWORD(pContainer->settings->dwTransparency);
 +					SetLayeredWindowAttributes(hwndDlg, Skin->getColorKey(), (BYTE)trans, (/* pContainer->bSkinned ? LWA_COLORKEY : */ 0) | (pContainer->dwFlags & CNT_TRANSPARENCY ? LWA_ALPHA : 0));
 +				}
 +			}
 +
 +			if (!CSkin::m_frameSkins)
 +				CheckMenuItem(hSysmenu, IDM_NOTITLE, (pContainer->dwFlags & CNT_NOTITLE) ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED);
 +
 +			CheckMenuItem(hSysmenu, IDM_STAYONTOP, pContainer->dwFlags & CNT_STICKY ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED);
 +			SetWindowPos(hwndDlg, (pContainer->dwFlags & CNT_STICKY) ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS);
 +			if (ws != wsold) {
 +				GetWindowRect(hwndDlg, &rc);
 +				if ((ws & WS_CAPTION) != (wsold & WS_CAPTION)) {
 +					SetWindowPos(hwndDlg, 0, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_FRAMECHANGED | SWP_NOCOPYBITS);
 +					RedrawWindow(hwndDlg, NULL, NULL, RDW_INVALIDATE | RDW_FRAME | RDW_UPDATENOW);
 +					if (pContainer->hwndActive != 0) {
 +						TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +						DM_ScrollToBottom(dat, 0, 0);
 +					}
 +				}
 +			}
 +
 +			pContainer->dwFlags = ((pContainer->dwFlagsEx & (TCF_SBARLEFT | TCF_SBARRIGHT)) ?
 +				pContainer->dwFlags | CNT_SIDEBAR : pContainer->dwFlags & ~CNT_SIDEBAR);
 +
 +			pContainer->SideBar->Init();
 +
 +			ws = wsold = GetWindowLongPtr(hwndTab, GWL_STYLE);
 +			if (pContainer->dwFlags & CNT_TABSBOTTOM)
 +				ws |= (TCS_BOTTOM);
 +			else
 +				ws &= ~(TCS_BOTTOM);
 +			if ((ws & (TCS_BOTTOM | TCS_MULTILINE)) != (wsold & (TCS_BOTTOM | TCS_MULTILINE))) {
 +				SetWindowLongPtr(hwndTab, GWL_STYLE, ws);
 +				RedrawWindow(hwndTab, NULL, NULL, RDW_INVALIDATE);
 +			}
 +
 +			if (pContainer->dwFlags & CNT_NOSTATUSBAR) {
 +				if (pContainer->hwndStatus) {
 +					DestroyWindow(pContainer->hwndStatus);
 +					pContainer->hwndStatus = 0;
 +					pContainer->statusBarHeight = 0;
 +					SendMessage(hwndDlg, DM_STATUSBARCHANGED, 0, 0);
 +				}
 +			}
 +			else if (pContainer->hwndStatus == 0) {
 +				pContainer->hwndStatus = CreateWindowEx(0, _T("TSStatusBarClass"), NULL, SBT_TOOLTIPS | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwndDlg, NULL, g_hInst, NULL);
 +
 +				if (sBarHeight && bSkinned)
 +					SendMessage(pContainer->hwndStatus, SB_SETMINHEIGHT, sBarHeight, 0);
 +			}
 +			if (pContainer->hwndActive != 0) {
 +				hContact = 0;
 +				SendMessage(pContainer->hwndActive, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +				if (hContact)
 +					SendMessage(hwndDlg, DM_UPDATETITLE, hContact, 0);
 +			}
 +			SendMessage(hwndDlg, WM_SIZE, 0, 1);
 +			BroadCastContainer(pContainer, DM_CONFIGURETOOLBAR, 0, 1);
 +		}
 +		return 0;
 +
 +	// search the first and most recent unread events in all client tabs...
 +	// return all information via a RECENTINFO structure (tab indices,
 +	// window handles and timestamps).
 +	case DM_QUERYRECENT:
 +		DWORD dwTimestamp;
 +		{
 +			int iItems = TabCtrl_GetItemCount(hwndTab);
 +			TCITEM item = { 0 };
 +
 +			RECENTINFO *ri = (RECENTINFO *)lParam;
 +			ri->iFirstIndex = ri->iMostRecent = -1;
 +			ri->dwFirst = ri->dwMostRecent = 0;
 +			ri->hwndFirst = ri->hwndMostRecent = 0;
 +
 +			for (int i = 0; i < iItems; i++) {
 +				item.mask = TCIF_PARAM;
 +				TabCtrl_GetItem(hwndTab, i, &item);
 +				SendMessage((HWND)item.lParam, DM_QUERYLASTUNREAD, 0, (LPARAM)&dwTimestamp);
 +				if (dwTimestamp > ri->dwMostRecent) {
 +					ri->dwMostRecent = dwTimestamp;
 +					ri->iMostRecent = i;
 +					ri->hwndMostRecent = (HWND)item.lParam;
 +					if (ri->iFirstIndex == -1) {
 +						ri->iFirstIndex = i;
 +						ri->dwFirst = dwTimestamp;
 +						ri->hwndFirst = (HWND)item.lParam;
 +					}
 +				}
 +			}
 +		}
 +		return 0;
 +
 +	// search tab with either next or most recent unread message and select it
 +	case DM_QUERYPENDING:
 +		RECENTINFO ri;
 +		{
 +			SendMessage(hwndDlg, DM_QUERYRECENT, 0, (LPARAM)&ri);
 +
 +			NMHDR nmhdr;
 +			nmhdr.code = TCN_SELCHANGE;
 +
 +			if (wParam == DM_QUERY_NEXT && ri.iFirstIndex != -1) {
 +				TabCtrl_SetCurSel(hwndTab, ri.iFirstIndex);
 +				SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nmhdr);
 +			}
 +			if (wParam == DM_QUERY_MOSTRECENT && ri.iMostRecent != -1) {
 +				TabCtrl_SetCurSel(hwndTab, ri.iMostRecent);
 +				SendMessage(hwndDlg, WM_NOTIFY, 0, (LPARAM)&nmhdr);
 +			}
 +		}
 +		return 0;
 +
 +	case DM_SETICON:
 +		{
 +			TWindowData *dat = (TWindowData*)wParam;
 +			HICON hIconMsg = PluginConfig.g_IconMsgEvent;
 +			HICON hIconBig = (dat && dat->cache) ? LoadSkinnedProtoIconBig(dat->cache->getProto(), dat->cache->getStatus()) : 0;
 +
 +			if (Win7Taskbar->haveLargeIcons()) {
 +				if ((HICON)lParam == PluginConfig.g_buttonBarIcons[ICON_DEFAULT_TYPING] || (HICON)lParam == hIconMsg) {
 +					Win7Taskbar->setOverlayIcon(hwndDlg, lParam);
 +					if (GetForegroundWindow() != hwndDlg)
 +						SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam);
 +					if ((HICON)lParam == hIconMsg)
 +						pContainer->hIconTaskbarOverlay = hIconMsg;
 +					break;
 +				}
 +
 +				if (dat) {
 +					if (dat->hTaskbarIcon == 0)
 +						dat->hTaskbarIcon = ((dat->pContainer->dwFlags & CNT_AVATARSONTASKBAR) ? Utils::iconFromAvatar(dat) : 0);
 +					else {
 +						if (!(dat->pContainer->dwFlags & CNT_AVATARSONTASKBAR)) {
 +							DestroyIcon(dat->hTaskbarIcon);
 +							dat->hTaskbarIcon = 0;
 +						}
 +					}
 +
 +					if (dat->hTaskbarIcon) {
 +						SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)dat->hTaskbarIcon);
 +						SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam);
 +						Win7Taskbar->setOverlayIcon(hwndDlg, (LPARAM)(dat->hTabIcon ? (LPARAM)dat->hTabIcon : lParam));
 +					}
 +					else {
 +						if (0 == hIconBig || (HICON)CALLSERVICE_NOTFOUND == hIconBig)
 +							SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)lParam);
 +						else
 +							SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIconBig);
 +						SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam);
 +						if (dat->pContainer->hIconTaskbarOverlay)
 +							Win7Taskbar->setOverlayIcon(hwndDlg, (LPARAM)dat->pContainer->hIconTaskbarOverlay);
 +						else if (Win7Taskbar->haveAlwaysGroupingMode() && fForceOverlayIcons)
 +							Win7Taskbar->setOverlayIcon(hwndDlg, lParam);
 +						else
 +							Win7Taskbar->clearOverlayIcon(hwndDlg);
 +					}
 +					return 0;
 +				}
 +			}
 +
 +			// default handling (no win7 taskbar)
 +			if ((HICON)lParam == PluginConfig.g_buttonBarIcons[ICON_DEFAULT_TYPING]) {              // always set typing icon, but don't save it...
 +				SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)PluginConfig.g_IconTypingEventBig);
 +				SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam);
 +				break;
 +			}
 +			if (reinterpret_cast<HICON>(lParam) == hIconMsg)
 +				hIconBig = LoadSkinnedIconBig(SKINICON_EVENT_MESSAGE);
 +
 +			if (pContainer->hIcon == STICK_ICON_MSG && (HICON)lParam != hIconMsg && pContainer->dwFlags & CNT_NEED_UPDATETITLE) {
 +				lParam = (LPARAM)hIconMsg;
 +				hIconBig = LoadSkinnedIconBig(SKINICON_EVENT_MESSAGE);
 +			}
 +			SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, lParam);
 +			if (0 != hIconBig && reinterpret_cast<HICON>(CALLSERVICE_NOTFOUND) != hIconBig)
 +				SendMessage(hwndDlg, WM_SETICON, ICON_BIG, LPARAM(hIconBig));
 +			pContainer->hIcon = (lParam == (LPARAM)hIconMsg) ? STICK_ICON_MSG : 0;
 +		}
 +		return 0;
 +
 +	case WM_DRAWITEM:
 +		{
 +			DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)lParam;
 +			if (dis->hwndItem == pContainer->hwndStatus && !(pContainer->dwFlags & CNT_NOSTATUSBAR)) {
 +				TWindowData *dat = (TWindowData*)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA);
 +				if (dat)
 +					DrawStatusIcons(dat, dis->hDC, dis->rcItem, 2);
 +				return TRUE;
 +			}
 +		}
 +		return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam);
 +
 +	case WM_MEASUREITEM:
 +		return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam);
 +
 +	case DM_QUERYCLIENTAREA:
 +		{
 +			RECT *rc = (RECT *)lParam;
 +			if (rc) {
 +				if (!IsIconic(hwndDlg))
 +					GetClientRect(hwndDlg, rc);
 +				else
 +					CopyRect(rc, &pContainer->rcSaved);
 +				AdjustTabClientRect(pContainer, rc);
 +			}
 +		}
 +		return 0;
 +
 +	case WM_DESTROY:
 +		pContainer->hwnd = 0;
 +		pContainer->hwndActive = 0;
 +		pContainer->hMenuContext = 0;
 +		if (pContainer->hwndStatus)
 +			DestroyWindow(pContainer->hwndStatus);
 +
 +		// mir_free private theme...
 +		if (pContainer->theme.isPrivate) {
 +			mir_free(pContainer->ltr_templates);
 +			mir_free(pContainer->rtl_templates);
 +			mir_free(pContainer->theme.logFonts);
 +			mir_free(pContainer->theme.fontColors);
 +			mir_free(pContainer->theme.rtfFonts);
 +		}
 +
 +		if (pContainer->hwndTip)
 +			DestroyWindow(pContainer->hwndTip);
 +		RemoveContainerFromList(pContainer);
 +		SM_RemoveContainer(pContainer);
 +		if (pContainer->cachedDC) {
 +			SelectObject(pContainer->cachedDC, pContainer->oldHBM);
 +			DeleteObject(pContainer->cachedHBM);
 +			DeleteDC(pContainer->cachedDC);
 +		}
 +		if (pContainer->cachedToolbarDC) {
 +			SelectObject(pContainer->cachedToolbarDC, pContainer->oldhbmToolbarBG);
 +			DeleteObject(pContainer->hbmToolbarBG);
 +			DeleteDC(pContainer->cachedToolbarDC);
 +		}
 +		return 0;
 +
 +	case WM_NCDESTROY:
 +		if (pContainer) {
 +			delete pContainer->MenuBar;
 +			delete pContainer->SideBar;
 +			if (pContainer->settings != &PluginConfig.globalContainerSettings)
 +				mir_free(pContainer->settings);
 +			mir_free(pContainer);
 +		}
 +		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, 0);
 +		break;
 +
 +	case WM_CLOSE:
 +		if (PluginConfig.m_bHideOnClose && !lParam) {
 +			ShowWindow(hwndDlg, SW_HIDE);
 +			pContainer->fHidden = true;
 +		}
 +		else {
 +			if (TabCtrl_GetItemCount(hwndTab) > 1) {
 +				LRESULT res = CWarning::show(CWarning::WARN_CLOSEWINDOW, MB_YESNOCANCEL | MB_ICONQUESTION);
 +				if (IDNO == res || IDCANCEL == res)
 +					break;
 +			}
 +
 +			// dont ask if container is empty (no tabs)
 +			if (lParam == 0 && TabCtrl_GetItemCount(hwndTab) > 0) {
 +				int clients = TabCtrl_GetItemCount(hwndTab), iOpenJobs = 0;
 +
 +				TCITEM item = { 0 };
 +				item.mask = TCIF_PARAM;
 +				for (int i = 0; i < clients; i++) {
 +					TabCtrl_GetItem(hwndTab, i, &item);
 +					if (item.lParam && IsWindow((HWND)item.lParam))
 +						SendMessage((HWND)item.lParam, DM_CHECKQUEUEFORCLOSE, 0, (LPARAM)&iOpenJobs);
 +				}
 +				if (iOpenJobs && pContainer) {
 +					if (pContainer->exFlags & CNT_EX_CLOSEWARN)
 +						return TRUE;
 +
 +					pContainer->exFlags |= CNT_EX_CLOSEWARN;
 +					LRESULT result = SendQueue::WarnPendingJobs(iOpenJobs);
 +					pContainer->exFlags &= ~CNT_EX_CLOSEWARN;
 +					if (result == IDNO)
 +						return TRUE;
 +				}
 +			}
 +
 +			// save geometry information to the database...
 +			if (!(pContainer->dwFlags & CNT_GLOBALSIZE)) {
 +				WINDOWPLACEMENT wp = { 0 };
 +				wp.length = sizeof(wp);
 +				if (GetWindowPlacement(hwndDlg, &wp) != 0) {
 +					if (pContainer->isCloned && pContainer->hContactFrom != 0) {
 +						TCITEM item = { 0 };
 +						item.mask = TCIF_PARAM;
 +						TabCtrl_GetItem(hwndTab, TabCtrl_GetCurSel(hwndTab), &item);
 +
 +						MCONTACT hContact;
 +						SendMessage((HWND)item.lParam, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +						db_set_b(hContact, SRMSGMOD_T, "splitmax", (BYTE)((wp.showCmd == SW_SHOWMAXIMIZED) ? 1 : 0));
 +
 +						for (int i = 0; i < TabCtrl_GetItemCount(hwndTab); i++) {
 +							if (TabCtrl_GetItem(hwndTab, i, &item)) {
 +								SendMessage((HWND)item.lParam, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +								db_set_dw(hContact, SRMSGMOD_T, "splitx", wp.rcNormalPosition.left);
 +								db_set_dw(hContact, SRMSGMOD_T, "splity", wp.rcNormalPosition.top);
 +								db_set_dw(hContact, SRMSGMOD_T, "splitwidth", wp.rcNormalPosition.right - wp.rcNormalPosition.left);
 +								db_set_dw(hContact, SRMSGMOD_T, "splitheight", wp.rcNormalPosition.bottom - wp.rcNormalPosition.top);
 +							}
 +						}
 +					}
 +					else {
 +						char szCName[40];
 +						mir_snprintf(szCName, SIZEOF(szCName), "%s%dx", CONTAINER_PREFIX, pContainer->iContainerIndex);
 +						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.left);
 +						mir_snprintf(szCName, SIZEOF(szCName), "%s%dy", CONTAINER_PREFIX, pContainer->iContainerIndex);
 +						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.top);
 +						mir_snprintf(szCName, SIZEOF(szCName), "%s%dwidth", CONTAINER_PREFIX, pContainer->iContainerIndex);
 +						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.right - wp.rcNormalPosition.left);
 +						mir_snprintf(szCName, SIZEOF(szCName), "%s%dheight", CONTAINER_PREFIX, pContainer->iContainerIndex);
 +						db_set_dw(0, SRMSGMOD_T, szCName, wp.rcNormalPosition.bottom - wp.rcNormalPosition.top);
 +
 +						db_set_b(0, SRMSGMOD_T, "splitmax", (BYTE)((wp.showCmd == SW_SHOWMAXIMIZED) ? 1 : 0));
 +					}
 +				}
 +			}
 +
 +			// clear temp flags which should NEVER be saved...
 +			if (pContainer->isCloned && pContainer->hContactFrom != 0) {
 +				TCITEM item = { 0 };
 +				item.mask = TCIF_PARAM;
 +				pContainer->dwFlags &= ~(CNT_DEFERREDCONFIGURE | CNT_CREATE_MINIMIZED | CNT_DEFERREDSIZEREQUEST | CNT_CREATE_CLONED);
 +				for (int i = 0; i < TabCtrl_GetItemCount(hwndTab); i++) {
 +					if (TabCtrl_GetItem(hwndTab, i, &item)) {
 +						MCONTACT hContact;
 +						SendMessage((HWND)item.lParam, DM_QUERYHCONTACT, 0, (LPARAM)&hContact);
 +
 +						char szCName[40];
 +						mir_snprintf(szCName, SIZEOF(szCName), "%s_theme", CONTAINER_PREFIX);
 +						if (mir_tstrlen(pContainer->szRelThemeFile) > 1) {
 +							if (pContainer->fPrivateThemeChanged == TRUE) {
 +								PathToRelativeT(pContainer->szRelThemeFile, pContainer->szAbsThemeFile, M.getDataPath());
 +								db_set_ts(hContact, SRMSGMOD_T, szCName, pContainer->szRelThemeFile);
 +								pContainer->fPrivateThemeChanged = FALSE;
 +							}
 +						}
 +						else {
 +							db_unset(hContact, SRMSGMOD_T, szCName);
 +							pContainer->fPrivateThemeChanged = FALSE;
 +						}
 +					}
 +				}
 +			}
 +			else Utils::SaveContainerSettings(pContainer, CONTAINER_PREFIX);
 +			DestroyWindow(hwndDlg);
 +		}
 +	}
 +	return FALSE;
 +}
 +
 +/////////////////////////////////////////////////////////////////////////////////////////
 +// CreateContainer MUST allocate a ContainerWindowData and pass its address
 +// to CreateDialogParam() via the LPARAM. It also adds the struct to the linked list
 +// of containers.
 +//
 +// The WM_DESTROY handler of the container DlgProc is responsible for mir_free()'ing the
 +// pointer and for removing the struct from the linked list.
 +
 +TContainerData* TSAPI CreateContainer(const TCHAR *name, int iTemp, MCONTACT hContactFrom)
 +{
 +	if (CMimAPI::m_shutDown)
 +		return NULL;
 +
 +	TContainerData *pContainer = (TContainerData*)mir_calloc(sizeof(TContainerData));
 +	if (pContainer == NULL)
 +		return NULL;
 +	_tcsncpy(pContainer->szName, name, CONTAINER_NAMELEN + 1);
 +	AppendToContainerList(pContainer);
 +
 +	if (M.GetByte("limittabs", 0) && !_tcscmp(name, _T("default")))
 +		iTemp |= CNT_CREATEFLAG_CLONED;
 +
 +	// save container name to the db
 +	if (!M.GetByte("singlewinmode", 0)) {
 +		int iFirstFree = -1, iFound = FALSE, i = 0;
 +		do {
 +			char szCounter[10];
 +			itoa(i, szCounter, 10);
 +			ptrT tszName(db_get_tsa(NULL, CONTAINER_KEY, szCounter));
 +			if (tszName == NULL) {
 +				if (iFirstFree != -1) {
 +					pContainer->iContainerIndex = iFirstFree;
 +					itoa(iFirstFree, szCounter, 10);
 +				}
 +				else pContainer->iContainerIndex = i;
 +
 +				db_set_ts(NULL, CONTAINER_KEY, szCounter, name);
 +				BuildContainerMenu();
 +				break;
 +			}
 +
 +			if (!_tcsncmp(tszName, name, CONTAINER_NAMELEN)) {
 +				pContainer->iContainerIndex = i;
 +				iFound = TRUE;
 +			}
 +			else if (!_tcsncmp(tszName, _T("**mir_free**"), CONTAINER_NAMELEN))
 +				iFirstFree = i;
 +		} while (++i && iFound == FALSE);
 +	}
 +	else {
 +		iTemp |= CNT_CREATEFLAG_CLONED;
 +		pContainer->iContainerIndex = 1;
 +	}
 +
 +	if (iTemp & CNT_CREATEFLAG_MINIMIZED)
 +		pContainer->dwFlags = CNT_CREATE_MINIMIZED;
 +	if (iTemp & CNT_CREATEFLAG_CLONED) {
 +		pContainer->dwFlags |= CNT_CREATE_CLONED;
 +		pContainer->hContactFrom = hContactFrom;
 +	}
 +	pContainer->hwnd = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_MSGCONTAINER), NULL, DlgProcContainer, (LPARAM)pContainer);
 +	return pContainer;
 +}
 +
 +// search the list of tabs and return the tab (by index) which "belongs" to the given
 +// hwnd. The hwnd is the handle of a message dialog childwindow. At creation,
 +// the dialog handle is stored in the TCITEM.lParam field, because we need
 +// to know the owner of the tab.
 +//
 +// hwndTab: handle of the tab control itself.
 +// hwnd: handle of a message dialog.
 +//
 +// returns the tab index (zero based), -1 if no tab is found (which SHOULD not
 +// really happen, but who knows... ;))
 +
 +int TSAPI GetTabIndexFromHWND(HWND hwndTab, HWND hwnd)
 +{
 +	int iItems = TabCtrl_GetItemCount(hwndTab);
 +
 +	TCITEM item = { 0 };
 +	item.mask = TCIF_PARAM;
 +	for (int i = 0; i < iItems; i++) {
 +		TabCtrl_GetItem(hwndTab, i, &item);
 +		if ((HWND)item.lParam == hwnd)
 +			return i;
 +	}
 +	return -1;
 +}
 +
 +HWND TSAPI GetHWNDFromTabIndex(HWND hwndTab, int idx)
 +{
 +	TCITEM item = { 0 };
 +	item.mask = TCIF_PARAM;
 +	TabCtrl_GetItem(hwndTab, idx, &item);
 +	return (HWND)item.lParam;
 +}
 +
 +// activates the tab belonging to the given client HWND (handle of the actual
 +// message window.
 +
 +int TSAPI ActivateTabFromHWND(HWND hwndTab, HWND hwnd)
 +{
 +	int iItem = GetTabIndexFromHWND(hwndTab, hwnd);
 +	if (iItem >= 0) {
 +		TabCtrl_SetCurSel(hwndTab, iItem);
 +
 +		NMHDR nmhdr = { 0 };
 +		nmhdr.code = TCN_SELCHANGE;
 +		SendMessage(GetParent(hwndTab), WM_NOTIFY, 0, (LPARAM)&nmhdr);     // do it via a WM_NOTIFY / TCN_SELCHANGE to simulate user-activation
 +		return iItem;
 +	}
 +	return -1;
 +}
 +
 +// enumerates tabs and closes all of them, but the one in dat
 +void TSAPI CloseOtherTabs(HWND hwndTab, TWindowData &dat)
 +{
 +	for (int idxt = 0; idxt < dat.pContainer->iChilds;) {
 +		HWND otherTab = GetHWNDFromTabIndex(hwndTab, idxt);
 +		if (otherTab != NULL && otherTab != dat.hwnd)
 +			SendMessage(otherTab, WM_CLOSE, 1, 0);
 +		else
 +			++idxt;
 +	}
 +}
 +
 +// cut off contact name to the option value set via Options->Tabbed messaging
 +// some people were requesting this, because really long contact list names
 +// are causing extraordinary wide tabs and these are looking ugly and wasting
 +// screen space.
 +//
 +// size = max length of target string
 +
 +int TSAPI CutContactName(const TCHAR *oldname, TCHAR *newname, unsigned int size)
 +{
 +	size_t cutMax = PluginConfig.m_iTabNameLimit;
 +
 +	if (mir_tstrlen(oldname) <= cutMax)
 +		_tcsncpy_s(newname, size, oldname, _TRUNCATE);
 +	else {
 +		TCHAR fmt[30];
 +		mir_sntprintf(fmt, SIZEOF(fmt), _T("%%%d.%ds..."), cutMax, cutMax);
 +		mir_sntprintf(newname, size, fmt, oldname);
 +	}
 +	return 0;
 +}
 +
 +// functions for handling the linked list of struct ContainerWindowData *foo
 +
 +static TContainerData* TSAPI AppendToContainerList(TContainerData *pContainer)
 +{
 +	if (!pFirstContainer) {
 +		pFirstContainer = pContainer;
 +		pFirstContainer->pNext = NULL;
 +		return pFirstContainer;
 +	}
 +
 +	TContainerData *p = pFirstContainer;
 +	while (p->pNext != 0)
 +		p = p->pNext;
 +	p->pNext = pContainer;
 +	pContainer->pNext = NULL;
 +	return p;
 +}
 +
 +TContainerData* TSAPI FindContainerByName(const TCHAR *name)
 +{
 +	if (name == NULL || mir_tstrlen(name) == 0)
 +		return 0;
 +
 +	if (M.GetByte("singlewinmode", 0)) // single window mode - always return 0 and force a new container
 +		return NULL;
 +
 +	for (TContainerData *p = pFirstContainer; p; p = p->pNext)
 +		if (!_tcsncmp(p->szName, name, CONTAINER_NAMELEN))
 +			return p;
 +
 +	// error, didn't find it.
 +	return NULL;
 +}
 +
 +static TContainerData* TSAPI RemoveContainerFromList(TContainerData *pContainer)
 +{
 +	if (pContainer == pFirstContainer) {
 +		if (pContainer->pNext != NULL)
 +			pFirstContainer = pContainer->pNext;
 +		else
 +			pFirstContainer = NULL;
 +
 +		if (pLastActiveContainer == pContainer)     // make sure, we don't reference this container anymore
 +			pLastActiveContainer = pFirstContainer;
 +
 +		return pFirstContainer;
 +	}
 +
 +	for (TContainerData *p = pFirstContainer; p; p = p->pNext) {
 +		if (p->pNext == pContainer) {
 +			p->pNext = p->pNext->pNext;
 +
 +			if (pLastActiveContainer == pContainer)     // make sure, we don't reference this container anymore
 +				pLastActiveContainer = pFirstContainer;
 +
 +			return 0;
 +		}
 +	}
 +	return NULL;
 +}
 +
 +// calls the TabCtrl_AdjustRect to calculate the "real" client area of the tab.
 +// also checks for the option "hide tabs when only one tab open" and adjusts
 +// geometry if necessary
 +// rc is the RECT obtained by GetClientRect(hwndTab)
 +
 +void TSAPI AdjustTabClientRect(TContainerData *pContainer, RECT *rc)
 +{
 +	HWND hwndTab = GetDlgItem(pContainer->hwnd, IDC_MSGTABS);
 +	DWORD tBorder = pContainer->tBorder;
 +	DWORD dwStyle = GetWindowLongPtr(hwndTab, GWL_STYLE);
 +
 +	RECT rcTab, rcTabOrig;
 +	GetClientRect(hwndTab, &rcTab);
 +	if (!(pContainer->dwFlags & CNT_SIDEBAR) && (pContainer->iChilds > 1 || !(pContainer->dwFlags & CNT_HIDETABS))) {
 +		rcTabOrig = rcTab;
 +		TabCtrl_AdjustRect(hwndTab, FALSE, &rcTab);
 +		DWORD dwTopPad = rcTab.top - rcTabOrig.top;
 +
 +		rc->left += tBorder;
 +		rc->right -= tBorder;
 +
 +		if (dwStyle & TCS_BUTTONS) {
 +			if (pContainer->dwFlags & CNT_TABSBOTTOM) {
 +				int nCount = TabCtrl_GetItemCount(hwndTab);
 +				if (nCount > 0) {
 +					RECT rcItem;
 +					TabCtrl_GetItemRect(hwndTab, nCount - 1, &rcItem);
 +					rc->bottom = rcItem.top;
 +				}
 +			}
 +			else {
 +				rc->top += (dwTopPad - 2);
 +				rc->bottom = rcTabOrig.bottom;
 +			}
 +		}
 +		else {
 +			if (pContainer->dwFlags & CNT_TABSBOTTOM)
 +				rc->bottom = rcTab.bottom + 2;
 +			else {
 +				rc->top += (dwTopPad - 2);
 +				rc->bottom = rcTabOrig.bottom;
 +			}
 +		}
 +
 +		rc->top += tBorder;
 +		rc->bottom -= tBorder;
 +	}
 +	else {
 +		rc->bottom = rcTab.bottom;
 +		rc->top = rcTab.top;
 +	}
 +	rc->right -= (pContainer->tBorder_outer_left + pContainer->tBorder_outer_right);
 +	if (pContainer->SideBar->isVisible())
 +		rc->right -= pContainer->SideBar->getWidth();
 +}
 +
 +// retrieve the container name for the given contact handle.
 +// if none is assigned, return the name of the default container
 +
 +int TSAPI GetContainerNameForContact(MCONTACT hContact, TCHAR *szName, int iNameLen)
 +{
 +	// single window mode using cloned (temporary) containers
 +	if (M.GetByte("singlewinmode", 0)) {
 +		_tcsncpy_s(szName, iNameLen, _T("Message Session"), _TRUNCATE);
 +		return 0;
 +	}
 +
 +	// use clist group names for containers...
 +	if (M.GetByte("useclistgroups", 0)) {
 +		ptrT tszGroup(db_get_tsa(hContact, "CList", "Group"));
 +		if (tszGroup == NULL) {
 +			_tcsncpy_s(szName, iNameLen, _T("default"), _TRUNCATE);
 +			return 0;
 +		}
 +
 +		_tcsncpy_s(szName, iNameLen, tszGroup, _TRUNCATE);
 +		return 1;
 +	}
 +
 +	ptrT tszContainerName(db_get_tsa(hContact, SRMSGMOD_T, CONTAINER_SUBKEY));
 +	if (tszContainerName == NULL) {
 +		_tcsncpy_s(szName, iNameLen, _T("default"), _TRUNCATE);
 +		return 0;
 +	}
 +
 +	_tcsncpy_s(szName, iNameLen, tszContainerName, _TRUNCATE);
 +	return 1;
 +}
 +
 +void TSAPI DeleteContainer(int iIndex)
 +{
 +	char szIndex[10];
 +	itoa(iIndex, szIndex, 10);
 +	ptrT tszContainerName(db_get_tsa(NULL, CONTAINER_KEY, szIndex));
 +	if (tszContainerName == NULL)
 +		return;
 +
 +	db_set_ts(NULL, CONTAINER_KEY, szIndex, _T("**mir_free**"));
 +
 +	for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
 +		ptrT tszValue(db_get_tsa(hContact, SRMSGMOD_T, CONTAINER_SUBKEY));
 +		if (!mir_tstrcmp(tszValue, tszContainerName))
 +			db_unset(hContact, SRMSGMOD_T, CONTAINER_SUBKEY);
 +	}
 +
 +	char szSetting[CONTAINER_NAMELEN + 30];
 +	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%d_Flags", CONTAINER_PREFIX, iIndex);
 +	db_unset(NULL, SRMSGMOD_T, szSetting);
 +	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%d_Trans", CONTAINER_PREFIX, iIndex);
 +	db_unset(NULL, SRMSGMOD_T, szSetting);
 +	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dwidth", CONTAINER_PREFIX, iIndex);
 +	db_unset(NULL, SRMSGMOD_T, szSetting);
 +	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dheight", CONTAINER_PREFIX, iIndex);
 +	db_unset(NULL, SRMSGMOD_T, szSetting);
 +	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dx", CONTAINER_PREFIX, iIndex);
 +	db_unset(NULL, SRMSGMOD_T, szSetting);
 +	mir_snprintf(szSetting, SIZEOF(szSetting), "%s%dy", CONTAINER_PREFIX, iIndex);
 +	db_unset(NULL, SRMSGMOD_T, szSetting);
 +}
 +
 +void TSAPI RenameContainer(int iIndex, const TCHAR *szNew)
 +{
 +	if (mir_tstrlen(szNew) == 0)
 +		return;
 +
 +	char szIndex[10];
 +	itoa(iIndex, szIndex, 10);
 +	ptrT tszContainerName(db_get_tsa(NULL, CONTAINER_KEY, szIndex));
 +	if (tszContainerName == NULL)
 +		return;
 +
 +	db_set_ts(NULL, CONTAINER_KEY, szIndex, szNew);
 +
 +	for (MCONTACT hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) {
 +		ptrT tszValue(db_get_tsa(hContact, SRMSGMOD_T, CONTAINER_SUBKEY));
 +		if (!mir_tstrcmp(tszValue, tszContainerName))
 +			db_set_ts(hContact, SRMSGMOD_T, CONTAINER_SUBKEY, szNew);
 +	}
 +}
 +
 +HMENU TSAPI BuildContainerMenu()
 +{
 +	if (PluginConfig.g_hMenuContainer != 0) {
 +		HMENU submenu = GetSubMenu(PluginConfig.g_hMenuContext, 0);
 +		RemoveMenu(submenu, 6, MF_BYPOSITION);
 +		DestroyMenu(PluginConfig.g_hMenuContainer);
 +		PluginConfig.g_hMenuContainer = 0;
 +	}
 +
 +	// no container attach menu, if we are using the "clist group mode"
 +	if (M.GetByte("useclistgroups", 0) || M.GetByte("singlewinmode", 0))
 +		return NULL;
 +
 +	HMENU hMenu = CreateMenu();
 +	int i = 0;
 +	while (true) {
 +		char szCounter[10];
 +		itoa(i, szCounter, 10);
 +		ptrT tszName(db_get_tsa(NULL, CONTAINER_KEY, szCounter));
 +		if (tszName == NULL)
 +			break;
 +
 +		if (_tcsncmp(tszName, _T("**mir_free**"), CONTAINER_NAMELEN))
 +			AppendMenu(hMenu, MF_STRING, IDM_CONTAINERMENU + i, !_tcscmp(tszName, _T("default")) ? TranslateT("Default container") : tszName);
 +		i++;
 +	}
 +
 +	InsertMenu(PluginConfig.g_hMenuContext, ID_TABMENU_ATTACHTOCONTAINER, MF_BYCOMMAND | MF_POPUP, (UINT_PTR)hMenu, TranslateT("Attach to"));
 +	PluginConfig.g_hMenuContainer = hMenu;
 +	return hMenu;
 +}
 +
 +// flashes the container
 +// iMode != 0: turn on flashing
 +// iMode == 0: turn off flashing
 +
 +void TSAPI FlashContainer(TContainerData *pContainer, int iMode, int iCount)
 +{
 +	if (pContainer->dwFlags & CNT_NOFLASH)                  // container should never flash
 +		return;
 +
 +	FLASHWINFO fwi;
 +	fwi.cbSize = sizeof(fwi);
 +	fwi.uCount = 0;
 +
 +	if (iMode) {
 +		fwi.dwFlags = FLASHW_ALL;
 +		if (pContainer->dwFlags & CNT_FLASHALWAYS)
 +			fwi.dwFlags |= FLASHW_TIMER;
 +		else
 +			fwi.uCount = (iCount == 0) ? M.GetByte("nrflash", 4) : iCount;
 +		fwi.dwTimeout = M.GetDword("flashinterval", 1000);
 +
 +	}
 +	else fwi.dwFlags = FLASHW_STOP;
 +
 +	fwi.hwnd = pContainer->hwnd;
 +	pContainer->dwFlashingStarted = GetTickCount();
 +	FlashWindowEx(&fwi);
 +}
 +
 +void TSAPI ReflashContainer(TContainerData *pContainer)
 +{
 +	DWORD dwStartTime = pContainer->dwFlashingStarted;
 +
 +	if (GetForegroundWindow() == pContainer->hwnd || GetActiveWindow() == pContainer->hwnd)       // dont care about active windows
 +		return;
 +
 +	if (pContainer->dwFlags & CNT_NOFLASH || pContainer->dwFlashingStarted == 0)
 +		return;                                                                                 // dont care about containers which should never flash
 +
 +	if (pContainer->dwFlags & CNT_FLASHALWAYS)
 +		FlashContainer(pContainer, 1, 0);
 +	else {
 +		// recalc the remaining flashes
 +		DWORD dwInterval = M.GetDword("flashinterval", 1000);
 +		int iFlashesElapsed = (GetTickCount() - dwStartTime) / dwInterval;
 +		DWORD dwFlashesDesired = M.GetByte("nrflash", 4);
 +		if (iFlashesElapsed < (int)dwFlashesDesired)
 +			FlashContainer(pContainer, 1, dwFlashesDesired - iFlashesElapsed);
 +		else {
 +			BOOL isFlashed = FlashWindow(pContainer->hwnd, TRUE);
 +			if (!isFlashed)
 +				FlashWindow(pContainer->hwnd, TRUE);
 +		}
 +	}
 +	pContainer->dwFlashingStarted = dwStartTime;
 +}
 +
 +// broadcasts a message to all child windows (tabs/sessions)
 +
 +void TSAPI BroadCastContainer(const TContainerData *pContainer, UINT message, WPARAM wParam, LPARAM lParam, BYTE bType)
 +{
 +	if (pContainer == NULL)
 +		return;
 +	HWND hwndTab = GetDlgItem(pContainer->hwnd, IDC_MSGTABS);
 +
 +	TCITEM item = { 0 };
 +	item.mask = TCIF_PARAM;
 +
 +	int nCount = TabCtrl_GetItemCount(hwndTab);
 +	for (int i = 0; i < nCount; i++) {
 +		TabCtrl_GetItem(hwndTab, i, &item);
 +		if (IsWindow((HWND)item.lParam)) {
 +			if (bType == SESSIONTYPE_ANY)
 +				SendMessage((HWND)item.lParam, message, wParam, lParam);
 +			else {
 +				TWindowData *dat = (TWindowData*)GetWindowLongPtr((HWND)item.lParam, GWLP_USERDATA);
 +				if (dat && dat->bType == bType)
 +					SendMessage((HWND)item.lParam, message, wParam, lParam);
 +			}
 +		}
 +	}
 +}
 +
 +void TSAPI CloseAllContainers()
 +{
 +	bool fOldHideSetting = PluginConfig.m_bHideOnClose;
 +
 +	while (pFirstContainer != NULL) {
 +		if (!IsWindow(pFirstContainer->hwnd))
 +			pFirstContainer = pFirstContainer->pNext;
 +		else {
 +			PluginConfig.m_bHideOnClose = false;
 +			::SendMessage(pFirstContainer->hwnd, WM_CLOSE, 0, 1);
 +		}
 +	}
 +
 +	PluginConfig.m_bHideOnClose = fOldHideSetting;
 +}
  | 
