From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/tabsrmm/src/controls.cpp | 1157 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1157 insertions(+) create mode 100644 plugins/tabsrmm/src/controls.cpp (limited to 'plugins/tabsrmm/src/controls.cpp') diff --git a/plugins/tabsrmm/src/controls.cpp b/plugins/tabsrmm/src/controls.cpp new file mode 100644 index 0000000000..f524de5f1a --- /dev/null +++ b/plugins/tabsrmm/src/controls.cpp @@ -0,0 +1,1157 @@ +/* + * astyle --force-indent=tab=4 --brackets=linux --indent-switches + * --pad=oper --one-line=keep-blocks --unpad=paren + * + * Miranda IM: the free IM client for Microsoft* Windows* + * + * Copyright 2000-2009 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 + * + * $Id: controls.cpp 13587 2011-04-12 13:54:26Z george.hazan $ + * + * Menu and status bar control(s) for the container window. + * + */ + +#include "commonheaders.h" +static WNDPROC OldStatusBarproc = 0; + +extern int status_icon_list_size; +extern TStatusBarIconNode *status_icon_list; + +bool CMenuBar::m_buttonsInit = false; +HHOOK CMenuBar::m_hHook = 0; +TBBUTTON CMenuBar::m_TbButtons[8] = {0}; +CMenuBar* CMenuBar::m_Owner = 0; +HBITMAP CMenuBar::m_MimIcon = 0; +int CMenuBar::m_MimIconRefCount = 0; + +CMenuBar::CMenuBar(HWND hwndParent, const TContainerData *pContainer) +{ + m_pContainer = const_cast(pContainer); + + if(m_MimIcon == 0) { + HDC hdc = ::GetDC(m_pContainer->hwnd); + HANDLE hIcon = LoadSkinnedIconHandle(SKINICON_OTHER_MIRANDA); + + HDC hdcTemp = ::CreateCompatibleDC(hdc); + + RECT rc = {0,0,16,16}; + m_MimIcon = CSkin::CreateAeroCompatibleBitmap(rc, hdcTemp); + HBITMAP hbmOld = reinterpret_cast(::SelectObject(hdcTemp, m_MimIcon)); + ::DrawIconEx(hdcTemp, 0, 0, (HICON)hIcon, 16, 16, 0, 0, DI_NORMAL); + ::SelectObject(hdcTemp, hbmOld); + + ::DeleteDC(hdcTemp); + ::ReleaseDC(m_pContainer->hwnd, hdc); + } + + m_MimIconRefCount++; + + m_hwndToolbar = ::CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAME, NULL, WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE|TBSTYLE_FLAT|TBSTYLE_TRANSPARENT|TBSTYLE_LIST|/*CCS_NOPARENTALIGN|*/CCS_NODIVIDER|CCS_TOP, + 0, 0, 0, 0, hwndParent, NULL, g_hInst, NULL); + + ::SendMessage(m_hwndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + + if(m_buttonsInit == false) { + ::ZeroMemory(m_TbButtons, sizeof(m_TbButtons)); + + m_TbButtons[0].iBitmap = 0;//I_IMAGENONE; + m_TbButtons[0].iString = 0;//(INT_PTR)TranslateT("&Main"); + m_TbButtons[0].fsState = TBSTATE_ENABLED; + m_TbButtons[0].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[0].idCommand = 100; + m_TbButtons[0].dwData = 0; + + m_TbButtons[1].iBitmap = I_IMAGENONE; + m_TbButtons[1].iString = (INT_PTR)CTranslator::get(CTranslator::GEN_MENUBAR_FILE); + m_TbButtons[1].fsState = TBSTATE_ENABLED; + m_TbButtons[1].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[1].idCommand = 101; + m_TbButtons[1].dwData = reinterpret_cast(::GetSubMenu(PluginConfig.getMenuBar(), 0)); + + m_TbButtons[2].iBitmap = I_IMAGENONE; + m_TbButtons[2].iString = (INT_PTR)CTranslator::get(CTranslator::GEN_MENUBAR_VIEW); + m_TbButtons[2].fsState = TBSTATE_ENABLED; + m_TbButtons[2].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[2].idCommand = 102; + m_TbButtons[2].dwData = reinterpret_cast(::GetSubMenu(PluginConfig.getMenuBar(), 1)); + + m_TbButtons[3].iBitmap = I_IMAGENONE; + m_TbButtons[3].iString = (INT_PTR)CTranslator::get(CTranslator::GEN_MENUBAR_USER); + m_TbButtons[3].fsState = TBSTATE_ENABLED; + m_TbButtons[3].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[3].idCommand = 103; + m_TbButtons[3].dwData = 0; // dynamically built by Clist service + + m_TbButtons[4].iBitmap = I_IMAGENONE; + m_TbButtons[4].iString = (INT_PTR)CTranslator::get(CTranslator::GEN_MENUBAR_ROOM); + m_TbButtons[4].fsState = TBSTATE_ENABLED; + m_TbButtons[4].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[4].idCommand = 104; + m_TbButtons[4].dwData = 0; + + m_TbButtons[5].iBitmap = I_IMAGENONE; + m_TbButtons[5].iString = (INT_PTR)CTranslator::get(CTranslator::GEN_MENUBAR_LOG); + m_TbButtons[5].fsState = TBSTATE_ENABLED; + m_TbButtons[5].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[5].idCommand = 105; + m_TbButtons[5].dwData = reinterpret_cast(::GetSubMenu(PluginConfig.getMenuBar(), 2)); + + m_TbButtons[6].iBitmap = I_IMAGENONE; + m_TbButtons[6].iString = (INT_PTR)CTranslator::get(CTranslator::GEN_MENUBAR_CONTAINER); + m_TbButtons[6].fsState = TBSTATE_ENABLED; + m_TbButtons[6].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[6].idCommand = 106; + m_TbButtons[6].dwData = reinterpret_cast(::GetSubMenu(PluginConfig.getMenuBar(), 3)); + + m_TbButtons[7].iBitmap = I_IMAGENONE; + m_TbButtons[7].iString = (INT_PTR)CTranslator::get(CTranslator::GEN_MENUBAR_HELP); + m_TbButtons[7].fsState = TBSTATE_ENABLED; + m_TbButtons[7].fsStyle = BTNS_DROPDOWN|BTNS_AUTOSIZE; + m_TbButtons[7].idCommand = 107; + m_TbButtons[7].dwData = reinterpret_cast(::GetSubMenu(PluginConfig.getMenuBar(), 4)); + + m_buttonsInit = true; + } + + ::SendMessage(m_hwndToolbar, TB_ADDBUTTONS, sizeof(m_TbButtons)/sizeof(TBBUTTON), (LPARAM)m_TbButtons); + + m_size_y = HIWORD(::SendMessage(m_hwndToolbar, TB_GETBUTTONSIZE, 0, 0)); + + TBADDBITMAP tb; + tb.nID = (UINT_PTR)m_MimIcon; + tb.hInst = 0; + + ::SendMessage(m_hwndToolbar, TB_ADDBITMAP, 1, (LPARAM)&tb); + + m_activeMenu = 0; + m_activeID = 0; + m_isAero = M->isAero(); + m_mustAutoHide = false; + m_activeSubMenu = 0; + m_fTracking = false; + m_isContactMenu = m_isMainMenu = false; + + m_oldWndProc = (WNDPROC)::GetWindowLongPtr(m_hwndToolbar, GWLP_WNDPROC); + ::SetWindowLongPtr(m_hwndToolbar, GWLP_USERDATA, (UINT_PTR)this); + ::SetWindowLongPtr(m_hwndToolbar, GWLP_WNDPROC, (UINT_PTR)wndProc); +} + +CMenuBar::~CMenuBar() +{ + ::SetWindowLongPtr(m_hwndToolbar, GWLP_WNDPROC, (UINT_PTR)m_oldWndProc); + ::SetWindowLongPtr(m_hwndToolbar, GWLP_USERDATA, 0); + ::DestroyWindow(m_hwndToolbar); + releaseHook(); + m_MimIconRefCount--; + if(m_MimIconRefCount == 0) { + ::DeleteObject(m_MimIcon); + m_MimIcon = 0; + } +} + +/** + * retrieves the client rectangle for the rebar control. This must be + * called once per WM_SIZE event by the parent window. getHeight() depends on it. + * + * @return RECT&: client rectangle of the rebar control + */ +const RECT& CMenuBar::getClientRect() +{ + ::GetClientRect(m_hwndToolbar, &m_rcClient); + return(m_rcClient); +} + +void CMenuBar::obtainHook() +{ + releaseHook(); + if(m_hHook == 0) + m_hHook = ::SetWindowsHookEx(WH_MSGFILTER, CMenuBar::MessageHook, g_hInst, 0); + m_Owner = this; +} + +void CMenuBar::releaseHook() +{ + if(m_hHook) { + ::UnhookWindowsHookEx(m_hHook); + m_hHook = 0; + } +} +/** + * Retrieve the height of the rebar control + * + * @return LONG: height of the rebar, in pixels + */ +LONG CMenuBar::getHeight() const +{ + return((m_pContainer->dwFlags & CNT_NOMENUBAR) ? 0 : m_size_y); +} + +/** + * process all relevant messages. Must be called by the parent window's + * window procedure. + * + * @param msg + * @param wParam + * @param lParam + * + * @return LRESULT: message processing result. Win32 conform. + * -1 means: nothing processed, caller should continue as usual. + */ +LONG_PTR CMenuBar::processMsg(const UINT msg, const WPARAM wParam, const LPARAM lParam) +{ + if(msg == WM_NOTIFY) { + NMHDR* pNMHDR = (NMHDR*)lParam; + switch(pNMHDR->code) { + case NM_CUSTOMDRAW: { + NMCUSTOMDRAW *nm = (NMCUSTOMDRAW*)lParam; + return(customDrawWorker(nm)); + } + + case TBN_DROPDOWN: { + NMTOOLBAR *mtb = (NMTOOLBAR *)lParam; + + LRESULT result = Handle(mtb); + return(result); + } + case TBN_HOTITEMCHANGE: { + NMTBHOTITEM *nmtb = (NMTBHOTITEM *)lParam; + + if(nmtb->idNew != 0 && m_fTracking && nmtb->idNew != m_activeID && m_activeID != 0) { + cancel(0); + return(0); + } + else if(m_fTracking == true && m_activeID == 0 && nmtb->idNew != 0) { + invoke(nmtb->idNew); + return(0); + } + break; + } + default: + return(-1); + } + } + else if(msg == WM_LBUTTONDOWN) { + if (m_pContainer->dwFlags & CNT_NOTITLE) { + POINT pt; + + ::GetCursorPos(&pt); + return ::SendMessage(m_pContainer->hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); + } + } + return(-1); +} + +/** + * subclass the toolbar control to handle some keyboard events and improve + * keyboard navigation + */ + +LRESULT CALLBACK CMenuBar::wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CMenuBar *menuBar = reinterpret_cast(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); + + switch(msg) { + case WM_SYSKEYUP: { + if(wParam == VK_MENU) { + menuBar->Cancel(); + return(0); + } + break; + } + default: + break; + } + return(::CallWindowProc(menuBar->m_oldWndProc, hWnd, msg, wParam, lParam)); +} + +/** + * Implements NM_CUSTOMDRAW for the toolbar + * + * @param nm NMCUSTOMDRAW *: sent via NM_CUSTOMDRAW message + * + * @return LONG_PTR: see Win32 NM_CUSTOMDRAW message. The function must return a valid + * message return value to indicate how Windows should continue with the drawing process. + * + * It may return zero in which case, the caller should allow default processing for + * the NM_CUSTOMDRAW message. + */ +LONG_PTR CMenuBar::customDrawWorker(NMCUSTOMDRAW *nm) +{ + bool fMustDraw = true; + + if(nm->hdr.hwndFrom == m_hwndToolbar) { + NMTBCUSTOMDRAW *nmtb = (NMTBCUSTOMDRAW *)(nm); + + switch(nmtb->nmcd.dwDrawStage) { + case CDDS_PREPAINT: + if(fMustDraw) { + if(nmtb->nmcd.dwItemSpec == 0) { + m_hdcDraw = ::CreateCompatibleDC(nmtb->nmcd.hdc); + //m_rcItem = nmtb->nmcd.rc; + ::GetClientRect(m_hwndToolbar, &m_rcItem); + m_rcItem.bottom -= 4; + m_hbmDraw = CSkin::CreateAeroCompatibleBitmap(m_rcItem, nmtb->nmcd.hdc); + m_hbmOld = reinterpret_cast(::SelectObject(m_hdcDraw, m_hbmDraw)); + m_hTheme = M->isAero() || M->isVSThemed() ? CMimAPI::m_pfnOpenThemeData(m_hwndToolbar, L"REBAR") : 0; + m_hOldFont = reinterpret_cast(::SelectObject(m_hdcDraw, reinterpret_cast(::GetStockObject(DEFAULT_GUI_FONT)))); + if(m_isAero) { + nm->rc.bottom--; + CSkin::ApplyAeroEffect(m_hdcDraw, &m_rcItem, CSkin::AERO_EFFECT_AREA_MENUBAR); + nm->rc.bottom++; + } + else if((PluginConfig.m_fillColor || M->isVSThemed()) && !CSkin::m_skinEnabled) { + if(PluginConfig.m_fillColor && PluginConfig.m_tbBackgroundHigh && PluginConfig.m_tbBackgroundLow) { + ::DrawAlpha(m_hdcDraw, &m_rcItem, PluginConfig.m_tbBackgroundHigh, 100, PluginConfig.m_tbBackgroundLow, 0, + GRADIENT_TB, 0, 0, 0); + } + else { + m_rcItem.bottom--; + if(PluginConfig.m_fillColor) + CSkin::FillBack(m_hdcDraw, &m_rcItem); + else if(M->isVSThemed()) + M->m_pfnDrawThemeBackground(m_hTheme, m_hdcDraw, 6, 1, &m_rcItem, &m_rcItem); + else + FillRect(m_hdcDraw, &m_rcItem, GetSysColorBrush(COLOR_3DFACE)); + } + } + else if(CSkin::m_MenuBGBrush) + ::FillRect(m_hdcDraw, &nm->rc, CSkin::m_MenuBGBrush); + else + ::FillRect(m_hdcDraw, &nm->rc, GetSysColorBrush(COLOR_3DFACE)); + } + return(CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYPOSTERASE); + } + else { + m_hdcDraw = 0; + return(CDRF_DODEFAULT); + } + + case CDDS_ITEMPREPAINT: + if(fMustDraw) { + TCHAR *szText = 0; + bool fDraw = true; + + int iIndex = idToIndex(nmtb->nmcd.dwItemSpec); + + if(iIndex >= 0 && iIndex < NR_BUTTONS) + szText = reinterpret_cast(m_TbButtons[iIndex].iString); + + UINT uState = nmtb->nmcd.uItemState; + + nmtb->nmcd.rc.bottom--; + if(CSkin::m_skinEnabled) { + CSkinItem *item = 0; + + ::FillRect(m_hdcDraw, &nmtb->nmcd.rc, CSkin::m_MenuBGBrush); + + if(uState & CDIS_MARKED || uState & CDIS_CHECKED || uState & CDIS_SELECTED) + item = &SkinItems[ID_EXTBKBUTTONSPRESSED]; + else if(uState & CDIS_HOT) + item = &SkinItems[ID_EXTBKBUTTONSMOUSEOVER]; + + if(item) + fDraw = !CSkin::DrawItem(m_hdcDraw, &nmtb->nmcd.rc, item); + else + fDraw = false; + } + if(fDraw) { + COLORREF clr = ::GetSysColor(COLOR_HOTLIGHT); + COLORREF clrRev = clr; + if(uState & CDIS_MARKED || uState & CDIS_CHECKED) { + ::DrawAlpha(m_hdcDraw, &nmtb->nmcd.rc, clrRev, 80, clrRev, 0, 9, + 31, 4, 0); + } + if(uState & CDIS_SELECTED) { + ::DrawAlpha(m_hdcDraw, &nmtb->nmcd.rc, clrRev, 80, clrRev, 0, 9, + 31, 4, 0); + } + if(uState & CDIS_HOT) { + ::DrawAlpha(m_hdcDraw, &nmtb->nmcd.rc, clrRev, 80, clrRev, 0, 9, + 31, 4, 0); + } + } + + if(szText) { + COLORREF clr = CSkin::m_skinEnabled ? CSkin::m_DefaultFontColor : + (PluginConfig.m_fillColor ? PluginConfig.m_genericTxtColor : + (uState & (CDIS_SELECTED | CDIS_HOT | CDIS_MARKED)) ? ::GetSysColor(COLOR_HIGHLIGHTTEXT) : ::GetSysColor(COLOR_BTNTEXT)); + + ::SetBkMode(m_hdcDraw, TRANSPARENT); + CSkin::RenderText(m_hdcDraw, m_hTheme, szText, &nmtb->nmcd.rc, DT_SINGLELINE | DT_VCENTER | DT_CENTER, + CSkin::m_glowSize, clr); + } + if(iIndex == 0) { + ::DrawIconEx(m_hdcDraw, (nmtb->nmcd.rc.left + nmtb->nmcd.rc.right) / 2 - 8, + (nmtb->nmcd.rc.top + nmtb->nmcd.rc.bottom) / 2 - 8, LoadSkinnedIcon(SKINICON_OTHER_MIRANDA), + 16, 16, 0, 0, DI_NORMAL); + } + return(CDRF_SKIPDEFAULT); + } + else + return(CDRF_DODEFAULT); + + case CDDS_PREERASE: + case CDDS_ITEMPOSTERASE: + case CDDS_ITEMPOSTPAINT: + case CDDS_ITEMPREERASE: + return(fMustDraw ? CDRF_SKIPDEFAULT : CDRF_DODEFAULT); + + case CDDS_POSTERASE: + return(fMustDraw ? CDRF_SKIPDEFAULT : CDRF_DODEFAULT); + + case CDDS_POSTPAINT: + if(nmtb->nmcd.dwItemSpec == 0 && m_hdcDraw) { + ::BitBlt(nmtb->nmcd.hdc, 0, 0, m_rcItem.right - m_rcItem.left, m_rcItem.bottom - m_rcItem.top, + m_hdcDraw, 0, 0, SRCCOPY); + ::SelectObject(m_hdcDraw, m_hbmOld); + ::DeleteObject(m_hbmDraw); + ::SelectObject(m_hdcDraw, m_hOldFont); + ::DeleteDC(m_hdcDraw); + m_hdcDraw = 0; + if(m_hTheme) + CMimAPI::m_pfnCloseThemeData(m_hTheme); + return(CDRF_SKIPDEFAULT); + } + else + return(CDRF_DODEFAULT); + + default: + return(CDRF_DODEFAULT); + } + + return(0); + } + return(0); +} + +/** + * Handle the TBN_DROPDOWN notification message sent by the + * toolbar control. + * + * @param nmtb NMTOOLBAR *: notification message structure + * + * @return LONG_PTR: must be a valid return value. See Win32 API, TBN_DROPDOWN + */ +LONG_PTR CMenuBar::Handle(const NMTOOLBAR *nmtb) +{ + if(nmtb->hdr.hwndFrom != m_hwndToolbar) + return(TBDDRET_NODEFAULT); + + const int index = idToIndex(nmtb->iItem); + invoke(nmtb->iItem); + + return(TBDDRET_DEFAULT); +} + +/** + * Invoke the dropdown menu for the button with the given control id. + * + * @param id int: the control id of the toolbar button which has been activated + */ +void CMenuBar::invoke(const int id) +{ + const int index = idToIndex(id); + + HMENU hMenu; + + m_isContactMenu = m_isMainMenu = false; + + TWindowData *dat = (TWindowData *)GetWindowLongPtr(m_pContainer->hwndActive, GWLP_USERDATA); + + HANDLE hContact = dat ? dat->hContact : 0; + + if(index == 3 && hContact != 0) { + hMenu = reinterpret_cast(::CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)hContact, 0)); + m_isContactMenu = true; + } else if(index == 0) { + hMenu = reinterpret_cast(::CallService(MS_CLIST_MENUBUILDMAIN, 0, 0)); + m_isMainMenu = true; + } else + hMenu = reinterpret_cast(m_TbButtons[index].dwData); + + RECT rcButton; + POINT pt; + ::SendMessage(m_hwndToolbar, TB_GETITEMRECT, (WPARAM)index, (LPARAM)&rcButton); + pt.x = rcButton.left; + pt.y = rcButton.bottom; + ::ClientToScreen(m_hwndToolbar, &pt); + + if(m_activeID) + cancel(0); + + m_activeMenu = hMenu; + m_activeSubMenu = 0; + m_activeID = id; + updateState(hMenu); + obtainHook(); + m_fTracking = true; + ::SendMessage(m_hwndToolbar, TB_SETSTATE, (WPARAM)id, TBSTATE_CHECKED | TBSTATE_ENABLED); + ::TrackPopupMenu(hMenu, 0, pt.x, pt.y, 0, m_pContainer->hwnd, 0); +} + +void CMenuBar::cancel(const int id) +{ + releaseHook(); + if(m_activeID) + ::SendMessage(m_hwndToolbar, TB_SETSTATE, (WPARAM)m_activeID, TBSTATE_ENABLED); + m_activeID = 0; + m_activeMenu = 0; + m_isContactMenu = m_isMainMenu = false; + ::EndMenu(); +} + +/** + * Cancel menu tracking completely + */ +void CMenuBar::Cancel(void) +{ + cancel(0); + m_fTracking = false; + autoShow(0); +} + +void CMenuBar::updateState(const HMENU hMenu) const +{ + TWindowData *dat = (TWindowData *)GetWindowLongPtr(m_pContainer->hwndActive, GWLP_USERDATA); + + if(dat) { + ::CheckMenuItem(hMenu, ID_VIEW_SHOWMENUBAR, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_NOMENUBAR ? MF_UNCHECKED : MF_CHECKED); + ::CheckMenuItem(hMenu, ID_VIEW_SHOWSTATUSBAR, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_NOSTATUSBAR ? MF_UNCHECKED : MF_CHECKED); + ::CheckMenuItem(hMenu, ID_VIEW_SHOWAVATAR, MF_BYCOMMAND | dat->showPic ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_VIEW_SHOWTITLEBAR, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_NOTITLE ? MF_UNCHECKED : MF_CHECKED); + + ::EnableMenuItem(hMenu, ID_VIEW_SHOWTITLEBAR, CSkin::m_skinEnabled && CSkin::m_frameSkins ? MF_GRAYED : MF_ENABLED); + + ::CheckMenuItem(hMenu, ID_VIEW_TABSATBOTTOM, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_TABSBOTTOM ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_VIEW_VERTICALMAXIMIZE, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_VERTICALMAX ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_VIEW_SHOWTOOLBAR, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_HIDETOOLBAR ? MF_UNCHECKED : MF_CHECKED); + ::CheckMenuItem(hMenu, ID_VIEW_BOTTOMTOOLBAR, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_BOTTOMTOOLBAR ? MF_CHECKED : MF_UNCHECKED); + + ::CheckMenuItem(hMenu, ID_VIEW_SHOWMULTISENDCONTACTLIST, MF_BYCOMMAND | (dat->sendMode & SMODE_MULTIPLE) ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_VIEW_STAYONTOP, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_STICKY ? MF_CHECKED : MF_UNCHECKED); + + ::EnableMenuItem(hMenu, 2, MF_BYPOSITION | (nen_options.bWindowCheck ? MF_GRAYED : MF_ENABLED)); + ::CheckMenuItem(hMenu, ID_EVENTPOPUPS_DISABLEALLEVENTPOPUPS, MF_BYCOMMAND | m_pContainer->dwFlags & (CNT_DONTREPORT | CNT_DONTREPORTUNFOCUSED | CNT_DONTREPORTFOCUSED | CNT_ALWAYSREPORTINACTIVE) ? MF_UNCHECKED : MF_CHECKED); + ::CheckMenuItem(hMenu, ID_EVENTPOPUPS_SHOWPOPUPSIFWINDOWISMINIMIZED, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_DONTREPORT ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_EVENTPOPUPS_SHOWPOPUPSFORALLINACTIVESESSIONS, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_ALWAYSREPORTINACTIVE ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_EVENTPOPUPS_SHOWPOPUPSIFWINDOWISUNFOCUSED, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_DONTREPORTUNFOCUSED ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_EVENTPOPUPS_SHOWPOPUPSIFWINDOWISFOCUSED, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_DONTREPORTFOCUSED ? MF_CHECKED : MF_UNCHECKED); + + ::CheckMenuItem(hMenu, ID_WINDOWFLASHING_USEDEFAULTVALUES, MF_BYCOMMAND | (m_pContainer->dwFlags & (CNT_NOFLASH | CNT_FLASHALWAYS)) ? MF_UNCHECKED : MF_CHECKED); + ::CheckMenuItem(hMenu, ID_WINDOWFLASHING_DISABLEFLASHING, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_NOFLASH ? MF_CHECKED : MF_UNCHECKED); + ::CheckMenuItem(hMenu, ID_WINDOWFLASHING_FLASHUNTILFOCUSED, MF_BYCOMMAND | m_pContainer->dwFlags & CNT_FLASHALWAYS ? MF_CHECKED : MF_UNCHECKED); + } +} + +/* + * this updates the container menu bar and other window elements depending on the current child + * session (IM, chat etc.). It fully supports IEView and will disable/enable the message log menus + * depending on the configuration of IEView (e.g. when template mode is on, the message log settin + * menus have no functionality, thus can be disabled to improve ui feedback quality). + */ + +void CMenuBar::configureMenu() const +{ + TWindowData *dat = (TWindowData *)::GetWindowLongPtr(m_pContainer->hwndActive, GWLP_USERDATA); + + BOOL fDisable = FALSE; + + if(dat) { + bool fChat = (dat->bType == SESSIONTYPE_CHAT); + + ::SendMessage(m_hwndToolbar, TB_SETSTATE, 103, fChat ? TBSTATE_HIDDEN : TBSTATE_ENABLED); + ::SendMessage(m_hwndToolbar, TB_SETSTATE, 104, fChat ? TBSTATE_ENABLED : TBSTATE_HIDDEN); + ::SendMessage(m_hwndToolbar, TB_SETSTATE, 105, fChat ? TBSTATE_HIDDEN : TBSTATE_ENABLED); + + if (dat->bType == SESSIONTYPE_IM) + ::EnableWindow(GetDlgItem(dat->hwnd, IDC_TIME), fDisable ? FALSE : TRUE); + } +} + +/** + * Automatically shows or hides the menu bar. Depends on the current state, + * used when the ALT key is hit in the message window. + */ +void CMenuBar::autoShow(const int showcmd) +{ + if(m_mustAutoHide && !(m_pContainer->dwFlags & CNT_NOMENUBAR)) { + m_pContainer->dwFlags |= CNT_NOMENUBAR; + m_mustAutoHide = false; + ::SendMessage(m_pContainer->hwnd, WM_SIZE, 0, 1); + releaseHook(); + } + + if(showcmd == 0) { + ::SetFocus(m_pContainer->hwndActive); + return; + } + + if(m_pContainer->dwFlags & CNT_NOMENUBAR) { + m_mustAutoHide = true; + m_pContainer->dwFlags &= ~CNT_NOMENUBAR; + ::SendMessage(m_pContainer->hwnd, WM_SIZE, 0, 1); + } + else // do nothing, already visible + m_mustAutoHide = false; + //obtainHook(); + ::SetFocus(m_hwndToolbar); + //::SendMessage(m_hwndToolbar, TB_SETHOTITEM, 0, HICF_ACCELERATOR); +} + +/** + * Message hook function, installed by the menu handler to support + * hot-tracking and keyboard navigation for the menu bar while a modal + * popup menu is active. + * + * Hook is only active while a (modal) popup menu is processed. + * + * @params See Win32, message hooks + * + * @return + */ +LRESULT CALLBACK CMenuBar::MessageHook(int nCode, WPARAM wParam, LPARAM lParam) +{ + if (nCode < 0) + return(::CallNextHookEx(m_hHook, nCode, wParam, lParam)); + + MSG *pMsg = reinterpret_cast(lParam); + bool fCancel = false; + + if(nCode == MSGF_MENU) { + switch(pMsg->message) { + case WM_KEYDOWN: + switch(pMsg->wParam) { + case VK_ESCAPE: { + fCancel = true; + break; + } + default: + break; + } + break; + + case WM_SYSKEYUP: + if(pMsg->wParam == VK_MENU) + fCancel = true; + break; + + case WM_LBUTTONDOWN: { + POINT pt; + + ::GetCursorPos(&pt); + if(::MenuItemFromPoint(0, m_Owner->m_activeMenu, pt) >= 0) // inside menu + break; + if(m_Owner->m_activeSubMenu && ::MenuItemFromPoint(0, m_Owner->m_activeSubMenu, pt) >= 0) + break; + else { // anywhere else, cancel the menu + ::CallNextHookEx(m_hHook, nCode, wParam, lParam); + m_Owner->Cancel(); + return(0); + } + } + /* + * allow hottracking by the toolbar control + */ + case WM_MOUSEMOVE: { + POINT pt; + + ::GetCursorPos(&pt); + ::ScreenToClient(m_Owner->m_hwndToolbar, &pt); + LPARAM newPos = MAKELONG(pt.x, pt.y); + ::SendMessage(m_Owner->m_hwndToolbar, pMsg->message, pMsg->wParam, newPos); + break; + } + default: + break; + } + /* + * some key event requested to cancel the menu + */ + if(fCancel) { + int iIndex = m_Owner->idToIndex(m_Owner->m_activeID); + if(iIndex != -1) + ::SendMessage(m_Owner->m_hwndToolbar, TB_SETHOTITEM, (WPARAM)iIndex, 0); + ::SetFocus(m_Owner->m_hwndToolbar); + ::SendMessage(m_Owner->m_hwndToolbar, TB_SETSTATE, (WPARAM)m_Owner->m_activeID, TBSTATE_ENABLED | TBSTATE_PRESSED); + m_Owner->cancel(0); + m_Owner->m_fTracking = false; + } + } + return(::CallNextHookEx(m_hHook, nCode, wParam, lParam)); +} + +/* + * window procedure for the status bar class. + */ + +static int tooltip_active = FALSE; +static POINT ptMouse = {0}; +RECT rcLastStatusBarClick; // remembers click (down event) point for status bar clicks + +LONG_PTR CALLBACK StatusBarSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TContainerData *pContainer = (TContainerData *)GetWindowLongPtr(GetParent(hWnd), GWLP_USERDATA); + + if (OldStatusBarproc == 0) { + WNDCLASSEX wc = {0}; + wc.cbSize = sizeof(wc); + GetClassInfoEx(g_hInst, STATUSCLASSNAME, &wc); + OldStatusBarproc = wc.lpfnWndProc; + } + switch (msg) { + case WM_CREATE: { + CREATESTRUCT *cs = (CREATESTRUCT *)lParam; + LRESULT ret; + HWND hwndParent = GetParent(hWnd); + /* + * dirty trick to get rid of that annoying sizing gripper + */ + SetWindowLongPtr(hwndParent, GWL_STYLE, GetWindowLongPtr(hwndParent, GWL_STYLE) & ~WS_THICKFRAME); + SetWindowLongPtr(hwndParent, GWL_EXSTYLE, GetWindowLongPtr(hwndParent, GWL_EXSTYLE) & ~WS_EX_APPWINDOW); + cs->style &= ~SBARS_SIZEGRIP; + ret = CallWindowProc(OldStatusBarproc, hWnd, msg, wParam, lParam); + SetWindowLongPtr(hwndParent, GWL_STYLE, GetWindowLongPtr(hwndParent, GWL_STYLE) | WS_THICKFRAME); + SetWindowLongPtr(hwndParent, GWL_EXSTYLE, GetWindowLongPtr(hwndParent, GWL_EXSTYLE) | WS_EX_APPWINDOW); + return ret; + } + + case WM_NCHITTEST: { + RECT r; + POINT pt; + LRESULT lr = SendMessage(GetParent(hWnd), WM_NCHITTEST, wParam, lParam); + int clip = CSkin::m_bClipBorder; + + GetWindowRect(hWnd, &r); + GetCursorPos(&pt); + if (pt.y <= r.bottom && pt.y >= r.bottom - clip - 3) { + if (pt.x > r.right - clip - 4) + return HTBOTTOMRIGHT; + } + if (lr == HTLEFT || lr == HTRIGHT || lr == HTBOTTOM || lr == HTTOP || lr == HTTOPLEFT || lr == HTTOPRIGHT + || lr == HTBOTTOMLEFT || lr == HTBOTTOMRIGHT) + return HTTRANSPARENT; + break; + } + + case WM_ERASEBKGND: + return 1; + + case WM_PAINT: { + PAINTSTRUCT ps; + TCHAR szText[1024]; + int i; + RECT itemRect; + HICON hIcon; + LONG height, width; + HDC hdc = BeginPaint(hWnd, &ps); + HFONT hFontOld = 0; + UINT nParts = SendMessage(hWnd, SB_GETPARTS, 0, 0); + LRESULT result; + RECT rcClient; + HDC hdcMem; + HBITMAP hbm, hbmOld; + HANDLE hbp = 0; + CSkinItem * item = &SkinItems[ID_EXTBKSTATUSBARPANEL]; + COLORREF clr = 0; + + BOOL fAero = M->isAero(); + HANDLE hTheme = fAero ? CMimAPI::m_pfnOpenThemeData(hWnd, L"ButtonStyle") : 0; + TWindowData* dat = 0; + + if(pContainer) + dat = (TWindowData *)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); + + GetClientRect(hWnd, &rcClient); + + if(CMimAPI::m_haveBufferedPaint) + hbp = CMimAPI::m_pfnBeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, NULL, &hdcMem); + else { + hdcMem = CreateCompatibleDC(hdc); + hbm = CSkin::CreateAeroCompatibleBitmap(rcClient, hdc); + hbmOld = (HBITMAP)SelectObject(hdcMem, hbm); + } + + SetBkMode(hdcMem, TRANSPARENT); + + clr = CSkin::m_skinEnabled ? CSkin::m_DefaultFontColor : (PluginConfig.m_fillColor ? PluginConfig.m_genericTxtColor : GetSysColor(COLOR_BTNTEXT)); + + hFontOld = (HFONT)SelectObject(hdcMem, GetStockObject(DEFAULT_GUI_FONT)); + + if (pContainer && CSkin::m_skinEnabled) + CSkin::SkinDrawBG(hWnd, GetParent(hWnd), pContainer, &rcClient, hdcMem); + else if(fAero) { + FillRect(hdcMem, &rcClient, CSkin::m_BrushBack); + CSkin::ApplyAeroEffect(hdcMem, &rcClient, CSkin::AERO_EFFECT_AREA_STATUSBAR); + } else { + CSkin::FillBack(hdcMem, &rcClient); + RECT rcFrame = rcClient; + if(PluginConfig.m_fillColor == 0) { + InflateRect(&rcFrame, -2, -1); + DrawEdge(hdcMem, &rcClient, BDR_RAISEDINNER | BDR_SUNKENOUTER, BF_RECT); + } + else { + CSkin::m_switchBarItem->setAlphaFormat(AC_SRC_ALPHA, 180); + CSkin::m_switchBarItem->Render(hdcMem, &rcFrame, true); + } + } + for (i = 0; i < (int)nParts; i++) { + SendMessage(hWnd, SB_GETRECT, (WPARAM)i, (LPARAM)&itemRect); + if (!item->IGNORED && !fAero && pContainer && CSkin::m_skinEnabled) + CSkin::DrawItem(hdcMem, &itemRect, item); + + if (i == 0) + itemRect.left += 2; + + /* + * draw visual message length indicator in the leftmost status bar field + */ + + if (PluginConfig.m_visualMessageSizeIndicator && i == 0) { + + if(dat && dat->bType == SESSIONTYPE_IM) { + HBRUSH br = CreateSolidBrush(RGB(0, 255, 0)); + HBRUSH brOld = (HBRUSH)SelectObject(hdcMem, br); + RECT rc = itemRect; + + rc.top = rc.bottom - 3; + rc.left = 0; + + if (!PluginConfig.m_autoSplit) { + float fMax = (float)dat->nMax; + float uPercent = (float)dat->textLen / ((fMax / (float)100.0) ? (fMax / (float)100.0) : (float)75.0); + float fx = ((float)rc.right / (float)100.0) * uPercent; + + rc.right = (LONG)fx; + FillRect(hdcMem, &rc, br); + } else { + float baselen = (dat->textLen <= dat->nMax) ? (float)dat->textLen : (float)dat->nMax; + float fMax = (float)dat->nMax; + float uPercent = baselen / ((fMax / (float)100.0) ? (fMax / (float)100.0) : (float)75.0); + float fx; + LONG width = rc.right - rc.left; + if (dat->textLen >= dat->nMax) + rc.right = rc.right / 3; + fx = ((float)rc.right / (float)100.0) * uPercent; + rc.right = (LONG)fx; + FillRect(hdcMem, &rc, br); + if (dat->textLen >= dat->nMax) { + SelectObject(hdcMem, brOld); + DeleteObject(br); + br = CreateSolidBrush(RGB(255, 0, 0)); + brOld = (HBRUSH)SelectObject(hdcMem, br); + rc.left = width / 3; + rc.right = width; + uPercent = (float)dat->textLen / (float)200.0; + fx = ((float)(rc.right - rc.left) / (float)100.0) * uPercent; + rc.right = rc.left + (LONG)fx; + FillRect(hdcMem, &rc, br); + } + } + DeleteObject(br); + } + } + + height = itemRect.bottom - itemRect.top; + width = itemRect.right - itemRect.left; + hIcon = (HICON)SendMessage(hWnd, SB_GETICON, i, 0); + szText[0] = 0; + result = SendMessage(hWnd, SB_GETTEXT, i, (LPARAM)szText); + if (i == 2 && pContainer) { + TWindowData *dat = (TWindowData *)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); + + if (dat) + DrawStatusIcons(dat, hdcMem, itemRect, 2); + } + else { + if (hIcon) { + if (LOWORD(result) > 1) { // we have a text + DrawIconEx(hdcMem, itemRect.left + 3, (height / 2 - 8) + itemRect.top, hIcon, 16, 16, 0, 0, DI_NORMAL); + if(dat) { + if(dat->showTyping == 2) + DrawIconEx(hdcMem, itemRect.left + 3, (height / 2 - 8) + itemRect.top, PluginConfig.g_iconOverlayEnabled, 16, 16, 0, 0, DI_NORMAL); + } + itemRect.left += 20; + CSkin::RenderText(hdcMem, hTheme, szText, &itemRect, DT_VCENTER | DT_END_ELLIPSIS | DT_SINGLELINE | DT_NOPREFIX, + CSkin::m_glowSize, clr); + } + else + DrawIconEx(hdcMem, itemRect.left + 3, (height / 2 - 8) + itemRect.top, hIcon, 16, 16, 0, 0, DI_NORMAL); + } + else { + itemRect.left += 2; + itemRect.right -= 2; + CSkin::RenderText(hdcMem, hTheme, szText, &itemRect, DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS | DT_NOPREFIX, + CSkin::m_glowSize, clr); + } + } + } + if(hbp) + CSkin::FinalizeBufferedPaint(hbp, &rcClient); + else { + BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + SelectObject(hdcMem, hFontOld); + DeleteDC(hdcMem); + } + + if(hTheme) + CMimAPI::m_pfnCloseThemeData(hTheme); + + EndPaint(hWnd, &ps); + return 0; + } + + /* + * tell status bar to update the part layout (re-calculate part widths) + * needed when an icon is added to or removed from the icon area + */ + case WM_USER + 101: { + struct TWindowData *dat = (struct TWindowData *)lParam; + RECT rcs; + int statwidths[5]; + struct TStatusBarIconNode *current = status_icon_list; + int list_icons = 0; + char buff[100]; + DWORD flags; + + while (current && dat) { + flags=current->sid.flags; + if(current->sid.flags&MBF_OWNERSTATE){ + struct TStatusBarIconNode *currentSIN = dat->pSINod; + + while (currentSIN) { + if (strcmp(currentSIN->sid.szModule, current->sid.szModule) == 0 && currentSIN->sid.dwId == current->sid.dwId) { + flags=currentSIN->sid.flags; + break; + } + currentSIN = currentSIN->next; + } + } + else { + sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId); + flags = M->GetByte(dat->hContact, current->sid.szModule, buff, current->sid.flags); + } + if (!(flags & MBF_HIDDEN)) + list_icons++; + current = current->next; + } + + SendMessage(hWnd, WM_SIZE, 0, 0); + GetWindowRect(hWnd, &rcs); + + statwidths[0] = (rcs.right - rcs.left) - (2 * SB_CHAR_WIDTH + 20) - (52 + ((list_icons) * (PluginConfig.m_smcxicon + 2))); + statwidths[1] = (rcs.right - rcs.left) - (62 + ((list_icons) * (PluginConfig.m_smcxicon + 2))); + statwidths[2] = -1; + SendMessage(hWnd, SB_SETPARTS, 3, (LPARAM) statwidths); + return 0; + } + + case WM_SETCURSOR: { + POINT pt; + + GetCursorPos(&pt); + SendMessage(GetParent(hWnd), msg, wParam, lParam); + if (pt.x == ptMouse.x && pt.y == ptMouse.y) { + return 1; + } + ptMouse = pt; + if (tooltip_active) { + KillTimer(hWnd, TIMERID_HOVER); + CallService("mToolTip/HideTip", 0, 0); + tooltip_active = FALSE; + } + KillTimer(hWnd, TIMERID_HOVER); + SetTimer(hWnd, TIMERID_HOVER, 450, 0); + break; + } + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: { + POINT pt; + + KillTimer(hWnd, TIMERID_HOVER); + CallService("mToolTip/HideTip", 0, 0); + tooltip_active = FALSE; + GetCursorPos(&pt); + rcLastStatusBarClick.left = pt.x - 2; + rcLastStatusBarClick.right = pt.x + 2; + rcLastStatusBarClick.top = pt.y - 2; + rcLastStatusBarClick.bottom = pt.y + 2; + + if (pContainer->dwFlags & CNT_NOTITLE) { + POINT pt1 = pt; + RECT rcIconpart; + + ScreenToClient(hWnd, &pt1); + SendMessage(hWnd, SB_GETRECT, 2, (LPARAM)&rcIconpart); + if(!PtInRect(&rcIconpart, pt1)) + return SendMessage(pContainer->hwnd, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, MAKELPARAM(pt.x, pt.y)); + } + break; + } + + case WM_TIMER: + if (wParam == TIMERID_HOVER) { + POINT pt; + char *szTTService = "mToolTip/ShowTipW"; + CLCINFOTIP ti = {0}; + ti.cbSize = sizeof(ti); + + KillTimer(hWnd, TIMERID_HOVER); + GetCursorPos(&pt); + if (pt.x == ptMouse.x && pt.y == ptMouse.y) { + RECT rc; + struct TWindowData *dat = (struct TWindowData *)GetWindowLongPtr(pContainer->hwndActive, GWLP_USERDATA); +//mad + SIZE size; + TCHAR szStatusBarText[512]; +//mad_ + ti.ptCursor = pt; + ScreenToClient(hWnd, &pt); + SendMessage(hWnd, SB_GETRECT, 2, (LPARAM)&rc); + if (dat && PtInRect(&rc, pt)) { + int gap = 2; + TStatusBarIconNode *current = status_icon_list; + TStatusBarIconNode *clicked = NULL; + TStatusBarIconNode *currentSIN = NULL; + + unsigned int iconNum = (pt.x - rc.left) / (PluginConfig.m_smcxicon + gap); + unsigned int list_icons = 0; + char buff[100]; + DWORD flags; + + while (current) { + if(current->sid.flags&MBF_OWNERSTATE&&dat->pSINod){ + TStatusBarIconNode *currentSIN = dat->pSINod; + flags=current->sid.flags; + while (currentSIN) { + if (strcmp(currentSIN->sid.szModule, current->sid.szModule) == 0 && currentSIN->sid.dwId == current->sid.dwId) { + flags=currentSIN->sid.flags; + break; + } + currentSIN = currentSIN->next; + } + } + else { + sprintf(buff, "SRMMStatusIconFlags%d", (int)current->sid.dwId); + flags = M->GetByte(dat->hContact, current->sid.szModule, buff, current->sid.flags); + } + if (!(flags & MBF_HIDDEN)) { + if (list_icons++ == iconNum) + clicked = current; + } + current = current->next; + } + + if(clicked&&clicked->sid.flags&MBF_OWNERSTATE) { + currentSIN=dat->pSINod; + while (currentSIN) { + if (strcmp(currentSIN->sid.szModule, clicked->sid.szModule) == 0 && currentSIN->sid.dwId == clicked->sid.dwId) { + clicked=currentSIN; + break; + } + currentSIN = currentSIN->next; + } + } + + if ((int)iconNum == list_icons && pContainer) { + TCHAR wBuf[512]; + + mir_sntprintf(wBuf, safe_sizeof(wBuf), CTranslator::get(CTranslator::CNT_SBAR_SOUNDS), + pContainer->dwFlags & CNT_NOSOUND ? CTranslator::get(CTranslator::GEN_DISABLED) : CTranslator::get(CTranslator::GEN_ENABLED)); + CallService(szTTService, (WPARAM)wBuf, (LPARAM)&ti); + tooltip_active = TRUE; + } + else if ((int)iconNum == list_icons + 1 && dat && dat->bType == SESSIONTYPE_IM) { + int mtnStatus = (int)M->GetByte(dat->hContact, SRMSGMOD, SRMSGSET_TYPING, M->GetByte(SRMSGMOD, SRMSGSET_TYPINGNEW, SRMSGDEFSET_TYPINGNEW)); + TCHAR wBuf[512]; + + mir_sntprintf(wBuf, safe_sizeof(wBuf), CTranslator::get(CTranslator::CNT_SBAR_MTN), + mtnStatus ? CTranslator::get(CTranslator::GEN_ENABLED) : CTranslator::get(CTranslator::GEN_DISABLED)); + CallService(szTTService, (WPARAM)wBuf, (LPARAM)&ti); + tooltip_active = TRUE; + } + else if((int)iconNum == list_icons + 2) { + TCHAR wBuf[512]; + + mir_sntprintf(wBuf, safe_sizeof(wBuf), _T("%s"), CTranslator::get(CTranslator::CNT_SBAR_SLIST)); + + CallService(szTTService, (WPARAM)wBuf, (LPARAM)&ti); + tooltip_active = TRUE; + } + else { + if (clicked) { + CallService("mToolTip/ShowTip", (WPARAM)clicked->sid.szTooltip, (LPARAM)&ti); + tooltip_active = TRUE; + } + } + } + SendMessage(hWnd, SB_GETRECT, 1, (LPARAM)&rc); + if (dat && PtInRect(&rc, pt)) { + int iLength = 0; + GETTEXTLENGTHEX gtxl = {0}; + int iQueued = M->GetDword(dat->hContact, "SendLater", "count", 0); + gtxl.codepage = CP_UTF8; + gtxl.flags = GTL_DEFAULT | GTL_PRECISE | GTL_NUMBYTES; + iLength = SendDlgItemMessage(dat->hwnd, dat->bType == SESSIONTYPE_IM ? IDC_MESSAGE : IDC_CHAT_MESSAGE, EM_GETTEXTLENGTHEX, (WPARAM) & gtxl, 0); + tooltip_active = TRUE; + + TCHAR wBuf[512]; + const TCHAR *szFormat = CTranslator::get(CTranslator::GEN_SBAR_TIP_MSGLENGTH); + + mir_sntprintf(wBuf, safe_sizeof(wBuf), szFormat, dat->iOpenJobs, iLength, dat->nMax ? dat->nMax : 20000, iQueued); + CallService(szTTService, (WPARAM)wBuf, (LPARAM)&ti); + } + //MAD + if(SendMessage(dat->pContainer->hwndStatus, SB_GETTEXT, 0, (LPARAM)szStatusBarText)) { + HDC hdc; + int iLen=SendMessage(dat->pContainer->hwndStatus,SB_GETTEXTLENGTH,0,0); + SendMessage(hWnd, SB_GETRECT, 0, (LPARAM)&rc); + GetTextExtentPoint32( hdc=GetDC( dat->pContainer->hwndStatus), szStatusBarText, iLen, &size ); + ReleaseDC (dat->pContainer->hwndStatus,hdc); + + if(dat && PtInRect(&rc,pt)&&((rc.right-rc.left)bType == SESSIONTYPE_CHAT) + M->GetTString(dat->hContact,dat->szProto,"Topic",&dbv); + + tooltip_active = TRUE; + CallService(szTTService, (WPARAM)dbv.ptszVal, (LPARAM)&ti); + if(dbv.pszVal) + DBFreeVariant(&dbv); + } + } + // MAD_ + } + } + break; + + case WM_DESTROY: + KillTimer(hWnd, TIMERID_HOVER); + } + return CallWindowProc(OldStatusBarproc, hWnd, msg, wParam, lParam); +} + -- cgit v1.2.3