summaryrefslogtreecommitdiff
path: root/plugins/Tabsrmm/src/taskbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Tabsrmm/src/taskbar.cpp')
-rw-r--r--plugins/Tabsrmm/src/taskbar.cpp956
1 files changed, 0 insertions, 956 deletions
diff --git a/plugins/Tabsrmm/src/taskbar.cpp b/plugins/Tabsrmm/src/taskbar.cpp
deleted file mode 100644
index dfe645bd4a..0000000000
--- a/plugins/Tabsrmm/src/taskbar.cpp
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * 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: taskbar.cpp 13178 2010-12-05 21:29:17Z silvercircle $
- *
- * Windows 7 taskbar integration
- *
- * - overlay icons
- * - custom taskbar thumbnails for aero peek in tabbed containers
- * - read Windows 7 task bar configuration from the registry.
- */
-/**
- * how it works:
- *
- * Because of the fact, the DWM does not talk to non-toplevel windows
- * we need an invisible "proxy window" for each tab. This window is a very
- * small and hidden toplevel tool window which is used to communicate
- * with the dwm. Each proxy is associated with the client window (the "tab")
- * and registers itself with the message container window via
- * ITaskbarList3::RegisterTab().
- *
- * Instead of automatically created snapshots of the window content, we
- * use custom generated thumbnails for the task bar buttons, including
- * nickname, UID, status message and avatar. This makes the thumbnails
- * easily recognizable.
- *
- * Thumbnails are generated "on request", only when the desktop window
- * manager needs one.
- *
- * Each proxy window has a CThumbIM or CThumbMUC object which represents
- * the actual thumbnail bitmap.
- */
-
-#include "commonheaders.h"
-
-/**
- * maps MUC event types to icon names for retrieving the "big" icons
- * while generating task bar thumbnails.
- * used by getMUCBigICon()
- */
-
-/*
-struct TMUCLargeIconsMap {
- UINT eventType;
- char* szIconDesc;
-} MUCLargeIconMap[] = {
- { GC_EVENT_NICK, "chat_nick" },
- { GC_EVENT_PART, "chat_part" }
-};
-*/
-
-CTaskbarInteract* Win7Taskbar = 0;
-
-/**
- * set the overlay icon for a task bar button. Used for typing notifications and incoming
- * message indicator.
- *
- * @param hwndDlg HWND: container window handle
- * @param lParam LPARAM: icon handle
- * @return true if icon has been set and taskbar will accept it, false otherwise
- */
-bool CTaskbarInteract::setOverlayIcon(HWND hwndDlg, LPARAM lParam) const
-{
- if (m_pTaskbarInterface && m_isEnabled && m_fHaveLargeicons) {
- m_pTaskbarInterface->SetOverlayIcon(hwndDlg,(HICON)lParam, NULL);
- return(true);
- }
- return(false);
-}
-
-/**
- * check the task bar status for "large icon mode".
- * @return bool: true if large icons are in use, false otherwise
- */
-bool CTaskbarInteract::haveLargeIcons()
-{
- m_fHaveLargeicons = false;
-
- if (m_pTaskbarInterface && m_isEnabled) {
- HKEY hKey;
- DWORD val = 1;
- DWORD valGrouping = 2;
- DWORD size = 4;
- DWORD dwType = REG_DWORD;
- /*
- * check whether the taskbar is set to show large icons. This is necessary, because the method SetOverlayIcon()
- * always returns S_OK, but the icon is simply ignored when using small taskbar icons.
- * also, figure out the button grouping mode.
- */
- if(::RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), &hKey) == ERROR_SUCCESS) {
- ::RegQueryValueEx(hKey, _T("TaskbarSmallIcons"), 0, &dwType, (LPBYTE)&val, &size);
- size = 4;
- dwType = REG_DWORD;
- /*
- * this is the "grouping mode" setting for the task bar. 0 = always combine, no labels
- */
- ::RegQueryValueEx(hKey, _T("TaskbarGlomLevel"), 0, &dwType, (LPBYTE)&valGrouping, &size);
- ::RegCloseKey(hKey);
- }
- m_fHaveLargeicons = (val ? false : true); // small icons in use, revert to default icon feedback
- m_fHaveAlwaysGrouping = (valGrouping == 0 ? true : false);
- }
- return(m_fHaveLargeicons);
-}
-
-/**
- * removes the overlay icon for the given container window
- * @param hwndDlg HWND: window handle
- */
-void CTaskbarInteract::clearOverlayIcon(HWND hwndDlg) const
-{
- if (m_pTaskbarInterface && m_isEnabled)
- m_pTaskbarInterface->SetOverlayIcon(hwndDlg, NULL, NULL);
-}
-
-LONG CTaskbarInteract::updateMetrics()
-{
- m_IconSize = 32;
-
- return(m_IconSize);
-}
-
-/**
- * register a new task bar button ("tab") for the button group hwndContainer
- * (one of the top level message windows)
- * @param hwndTab proxy window handle
- * @param hwndContainer a message container window
- */
-void CTaskbarInteract::registerTab(const HWND hwndTab, const HWND hwndContainer) const
-{
- if(m_isEnabled) {
- m_pTaskbarInterface->RegisterTab(hwndTab, hwndContainer);
- m_pTaskbarInterface->SetTabOrder(hwndTab, 0);
- }
-}
-
-/**
- * remove a previously registered proxy window. The destructor of the proxy
- * window class is using this before destroying the proxy window itself.
- * @param hwndTab proxy window handle
- */
-void CTaskbarInteract::unRegisterTab(const HWND hwndTab) const
-{
- if(m_isEnabled)
- m_pTaskbarInterface->UnregisterTab(hwndTab);
-}
-
-/**
- * set a tab as active. The active thumbnail will appear with a slightly
- * different background and transparency.
- *
- * @param hwndTab window handle of the PROXY window to activate
- * (don't use the real window handle of the message
- * tab, because it is not a toplevel window).
- * @param hwndGroup window group to which it belongs (usually, the
- * container window handle).
- */
-void CTaskbarInteract::SetTabActive(const HWND hwndTab, const HWND hwndGroup) const
-{
- if(m_isEnabled)
- m_pTaskbarInterface->SetTabActive(hwndTab, hwndGroup, 0);
-}
-
-/**
- * create a proxy window object for the given session. Do NOT call this more than once
- * per session and not outside of WM_INITDIALOG after most things are initialized.
- * @param dat session window data
- *
- * static member function. Ignored when OS is not Windows 7 or global option for
- * Windows 7 task bar support is diabled.
- */
-void CProxyWindow::add(TWindowData *dat)
-{
- if(PluginConfig.m_bIsWin7 && PluginConfig.m_useAeroPeek) // && (!CSkin::m_skinEnabled || M->GetByte("forceAeroPeek", 0)))
- dat->pWnd = new CProxyWindow(dat);
- else
- dat->pWnd = 0;
-}
-
-/**
- * This is called from the broadcasted WM_DWMCOMPOSITIONCHANGED event by all messages
- * sessions. It checks and, if needed, destroys or creates a proxy object, based on
- * the status of the DWM
- * @param dat session window data
- *
- * static member function
- */
-void CProxyWindow::verify(TWindowData *dat)
-{
- if(PluginConfig.m_bIsWin7 && PluginConfig.m_useAeroPeek) {
- if(0 == dat->pWnd) {
- dat->pWnd = new CProxyWindow(dat);
- if(dat->pWnd) {
- dat->pWnd->updateIcon(dat->hTabStatusIcon);
- dat->pWnd->updateTitle(dat->cache->getNick());
- }
- }
- else
- dat->pWnd->verifyDwmState();
- }
- /*
- * this should not happens, but who knows...
- */
- else {
- if(dat->pWnd) {
- delete dat->pWnd;
- dat->pWnd = 0;
- }
- }
-}
-
-/**
- * create the proxy (toplevel) window required to show per tab thumbnails
- * and previews for a message session.
- * each tab has one invisible proxy window
- */
-CProxyWindow::CProxyWindow(const TWindowData *dat)
-{
- m_dat = dat;
- m_hBigIcon = 0;
- m_thumb = 0;
-
- m_hwndProxy = ::CreateWindowEx(/*WS_EX_TOOLWINDOW | */WS_EX_NOACTIVATE, PROXYCLASSNAME, _T(""),
- WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION, -32000, -32000, 10, 10, NULL, NULL, g_hInst, (LPVOID)this);
-
-#if defined(__LOGDEBUG_)
- _DebugTraceW(_T("create proxy object for: %s"), m_dat->cache->getNick());
-#endif
- Win7Taskbar->registerTab(m_hwndProxy, m_dat->pContainer->hwnd);
- if(CMimAPI::m_pfnDwmSetWindowAttribute) {
- BOOL fIconic = TRUE;
- BOOL fHasIconicBitmap = TRUE;
-
- CMimAPI::m_pfnDwmSetWindowAttribute(m_hwndProxy, DWMWA_FORCE_ICONIC_REPRESENTATION, &fIconic, sizeof(fIconic));
- CMimAPI::m_pfnDwmSetWindowAttribute(m_hwndProxy, DWMWA_HAS_ICONIC_BITMAP, &fHasIconicBitmap, sizeof(fHasIconicBitmap));
- }
-}
-
-CProxyWindow::~CProxyWindow()
-{
- Win7Taskbar->unRegisterTab(m_hwndProxy);
- ::DestroyWindow(m_hwndProxy);
-
-#if defined(__LOGDEBUG_)
- _DebugTraceW(_T("destroy proxy object for: %s"), m_dat->cache->getNick());
-#endif
- if(m_thumb) {
- delete m_thumb;
- m_thumb = 0;
- }
-}
-
-/**
- * verify status of DWM when system broadcasts a WM_DWMCOMPOSITIONCHANGED message
- * delete thumbnails, if no longer needed
- */
-void CProxyWindow::verifyDwmState()
-{
- if(!M->isDwmActive()) {
- if(m_thumb) {
- delete m_thumb;
- m_thumb = 0;
- }
- }
- else {
- /*
- * force thumbnail recreation
- */
- m_width = 0;
- m_height = 0;
- }
-}
-
-/**
- * send a thumbnail to the DWM. If required, refresh it first.
- * called by WM_DWMSENDICONICTHUMBNAIL handler.
- *
- * @param width thumbnail width as requested by DWM via lParam
- * @param height thumbnail height as requested by DWM via lParam
- */
-void CProxyWindow::sendThumb(LONG width, LONG height)
-{
- if(0 == m_thumb) {
- m_width = width;
- m_height = height;
- if(m_dat->bType == SESSIONTYPE_IM)
- m_thumb = new CThumbIM(this);
- else
- m_thumb = new CThumbMUC(this);
- }
- else if(width != m_width || height != m_height || !m_thumb->isValid()) {
- m_width = width;
- m_height = height;
- m_thumb->update();
- }
- if(m_thumb)
- CMimAPI::m_pfnDwmSetIconicThumbnail(m_hwndProxy, m_thumb->getHBM(), DWM_SIT_DISPLAYFRAME);
-}
-
-/**
- * send a live preview image of a given message session to the DWM.
- * called by WM_DWMSENDICONICLIVEPREVIEWBITMAP on DWM's request.
- *
- * The bitmap can be deleted after submitting it, because the DWM
- * will cache a copy of it (and re-request it when its own bitmap cache
- * was purged).
- */
-void CProxyWindow::sendPreview()
-{
- POINT pt = {0};
- RECT rcContainer;
- HDC hdc, dc;
- FORMATRANGE fr = {0};
- int twips = (int)(15.0f / PluginConfig.g_DPIscaleY);
- RECT rcTemp;
- RECT rcRich, rcLog;
- bool fIsChat = m_dat->bType == SESSIONTYPE_IM ? false : true;
- TWindowData* dat_active = reinterpret_cast<TWindowData *>(::GetWindowLongPtr(m_dat->pContainer->hwndActive, GWLP_USERDATA));
-
- if(m_thumb && dat_active) {
- HWND hwndRich = ::GetDlgItem(m_dat->hwnd, fIsChat ? IDC_CHAT_LOG : IDC_LOG);
- LONG cx, cy;
- POINT ptOrigin = {0}, ptBottom;
-
- if(m_dat->dwFlags & MWF_NEEDCHECKSIZE) {
- RECT rcClient;
-
- ::SendMessage(m_dat->pContainer->hwnd, DM_QUERYCLIENTAREA, 0, (LPARAM)&rcClient);
- ::MoveWindow(m_dat->hwnd, rcClient.left, rcClient.top, (rcClient.right - rcClient.left), (rcClient.bottom - rcClient.top), FALSE);
- ::SendMessage(m_dat->hwnd, WM_SIZE, 0, 0);
- ::SendMessage(m_dat->hwnd, DM_FORCESCROLL, 0, 0);
- }
- /*
- * a minimized container has a null rect as client area, so do not use it
- * use the last known client area size instead.
- */
-
- if(!::IsIconic(m_dat->pContainer->hwnd)) {
- ::GetWindowRect(m_dat->pContainer->hwndActive, &rcLog);
- ::GetClientRect(m_dat->pContainer->hwnd, &rcContainer);
- pt.x = rcLog.left;
- pt.y = rcLog.top;
- ::ScreenToClient(m_dat->pContainer->hwnd, &pt);
- }
- else {
- rcLog = m_dat->pContainer->rcLogSaved;
- rcContainer = m_dat->pContainer->rcSaved;
- pt = m_dat->pContainer->ptLogSaved;
- }
-
- ::GetWindowRect(::GetDlgItem(m_dat->pContainer->hwndActive, dat_active->bType == SESSIONTYPE_IM ? IDC_LOG : IDC_CHAT_LOG), &rcTemp);
- ptBottom.x = rcTemp.left;
- ptBottom.y = rcTemp.bottom;
- ::ScreenToClient(m_dat->pContainer->hwnd, &ptBottom);
-
- cx = rcLog.right - rcLog.left;
- cy = rcLog.bottom - rcLog.top;
- rcRich.left = 0;
- rcRich.top = 0;
- rcRich.right = cx;
- rcRich.bottom = ptBottom.y - pt.y;
-
- dc = ::GetDC(m_dat->hwnd);
- hdc = ::CreateCompatibleDC(dc);
- HBITMAP hbm = CSkin::CreateAeroCompatibleBitmap(rcContainer, hdc);
- HBITMAP hbmOld = reinterpret_cast<HBITMAP>(::SelectObject(hdc, hbm));
-
- HBRUSH brb = ::CreateSolidBrush(RGB(20, 20, 20));
- ::FillRect(hdc, &rcContainer, brb);
- ::DeleteObject(brb);
- CImageItem::SetBitmap32Alpha(hbm, 100);
-
- LRESULT first = ::SendMessage(hwndRich, EM_CHARFROMPOS, 0, reinterpret_cast<LPARAM>(&ptOrigin));
-
- /*
- * paint the content of the message log control into a separate bitmap without
- * transparency
- */
- HDC hdcRich = ::CreateCompatibleDC(dc);
- HBITMAP hbmRich = CSkin::CreateAeroCompatibleBitmap(rcRich, hdcRich);
- HBITMAP hbmRichOld = reinterpret_cast<HBITMAP>(::SelectObject(hdcRich, hbmRich));
-
- COLORREF clr = fIsChat ? M->GetDword(FONTMODULE, SRMSGSET_BKGCOLOUR, SRMSGDEFSET_BKGCOLOUR) : m_dat->pContainer->theme.inbg;
- HBRUSH br = ::CreateSolidBrush(clr);
- ::FillRect(hdcRich, &rcRich, br);
- ::DeleteObject(br);
-
- if(m_dat->hwndIEView)
- ::SendMessage(m_dat->hwndIEView, WM_PRINT, reinterpret_cast<WPARAM>(hdcRich), PRF_CLIENT | PRF_NONCLIENT);
- else if(m_dat->hwndHPP) {
- CSkin::RenderText(hdcRich, m_dat->hTheme, CTranslator::get(CTranslator::GEN_AEROPEEK_NOHPP),
- &rcRich, DT_VCENTER | DT_CENTER | DT_WORDBREAK, 10, m_dat->pContainer->theme.fontColors[MSGFONTID_MYMSG], false);
- }
- else {
- rcRich.right *= twips;
- rcRich.bottom *= twips;
-
- fr.hdc = hdcRich;
- fr.hdcTarget = hdcRich;
- fr.rc = rcRich;
- fr.rcPage = rcRich;
- fr.chrg.cpMax = -1;
- fr.chrg.cpMin = first;
-
- ::SendMessage(hwndRich, EM_FORMATRANGE, 1, reinterpret_cast<LPARAM>(&fr));
- }
-
- ::SelectObject(hdcRich, hbmRichOld);
- CImageItem::SetBitmap32Alpha(hbmRich, 255);
- ::SelectObject(hdcRich, hbmRich);
- ::BitBlt(hdc, pt.x, pt.y, cx, cy, hdcRich, 0, 0, SRCCOPY);
- ::SelectObject(hdcRich, hbmRichOld);
- ::DeleteObject(hbmRich);
- ::DeleteDC(hdcRich);
-
- ::SelectObject(hdc, hbmOld);
- ::DeleteDC(hdc);
- if(CSkin::m_skinEnabled && CSkin::m_frameSkins) {
- pt.x = CSkin::m_SkinnedFrame_left;
- pt.y = CSkin::m_SkinnedFrame_caption + CSkin::m_SkinnedFrame_bottom;
- }
- else
- pt.x = pt.y = 0;
- CMimAPI::m_pfnDwmSetIconicLivePreviewBitmap(m_hwndProxy, hbm, &pt, m_dat->pContainer->dwFlags & CNT_CREATE_MINIMIZED ? 0 : DWM_SIT_DISPLAYFRAME);
- ::ReleaseDC(m_dat->hwnd, dc);
- ::DeleteObject(hbm);
- }
-}
-
-/**
- * set the large icon for the thumbnail. This is mostly used by group chats
- * to indicate last active event in the session.
- *
- * hIcon may be 0 to remove a custom big icon. In that case, the renderer
- * will try to figure out a suitable one, based on session data.
- *
- * @param hIcon icon handle (should be a 32x32 icon)
- * @param fInvalidate invalidate the thumbnail (default value = true)
- */
-void CProxyWindow::setBigIcon(const HICON hIcon, bool fInvalidate)
-{
- m_hBigIcon = hIcon;
- if(fInvalidate)
- Invalidate();
-}
-
-/**
- * set a overlay icon for the thumbnail. This is mostly used by group chats
- * to indicate last active event in the session.
- *
- * hIcon may be 0 to remove a custom overlay icon.
- *
- * @param hIcon icon handle (should be a 16x16 icon)
- * @param fInvalidate invalidate the thumbnail (default value = true)
- */
-void CProxyWindow::setOverlayIcon(const HICON hIcon, bool fInvalidate)
-{
- m_hOverlayIcon = hIcon;
- if(fInvalidate)
- Invalidate();
-}
-
-/**
- * update the (small) thumbnail icon in front of the title string
- * @param hIcon new icon handle
- */
-void CProxyWindow::updateIcon(const HICON hIcon) const
-{
- if(m_hwndProxy && hIcon)
- ::SendMessage(m_hwndProxy, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(hIcon));
-}
-
-/**
- * set the task bar button ("tab") active. This activates the proxy
- * window as a sub-window of the (top level) container window.
- * This is called whenever the active message tab or window changes
- */
-void CProxyWindow::activateTab() const
-{
- Win7Taskbar->SetTabActive(m_hwndProxy, m_dat->pContainer->hwnd);
-}
-/**
- * invalidate the thumbnail, it will be recreated at the next request
- * by the DWM
- *
- * this is called from several places whenever a relevant information,
- * represented in a thumbnail image, has changed.
- *
- * also tell the DWM that it must request a new thumb.
- */
-void CProxyWindow::Invalidate() const
-{
- if(m_thumb) {
- m_thumb->setValid(false);
- /*
- * tell the DWM to request a new thumbnail for the proxy window m_hwnd
- * when it needs one.
- */
- CMimAPI::m_pfnDwmInvalidateIconicBitmaps(m_hwndProxy);
- }
-}
-
-/**
- * update the thumb title string (usually, the nickname)
- * @param tszTitle: new title string
- */
-void CProxyWindow::updateTitle(const TCHAR *tszTitle) const
-{
- if(m_hwndProxy && tszTitle)
- ::SetWindowText(m_hwndProxy, tszTitle);
-}
-
-/**
- * stub window procedure for the custom proxy window class
- * just initialize GWLP_USERDATA and call the object's method
- *
- * static member function
- */
-LRESULT CALLBACK CProxyWindow::stubWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CProxyWindow* pWnd = reinterpret_cast<CProxyWindow *>(::GetWindowLongPtr(hWnd, GWLP_USERDATA));
-
- if(pWnd)
- return(pWnd->wndProc(hWnd, msg, wParam, lParam));
-
- switch(msg) {
- case WM_NCCREATE: {
- CREATESTRUCT *cs = reinterpret_cast<CREATESTRUCT *>(lParam);
- CProxyWindow *pWnd = reinterpret_cast<CProxyWindow *>(cs->lpCreateParams);
- ::SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<UINT_PTR>(pWnd));
- return(pWnd->wndProc(hWnd, msg, wParam, lParam));
- }
- default:
- break;
- }
- return(::DefWindowProc(hWnd, msg, wParam, lParam));
-}
-
-/**
- * window procedure for the proxy window
- */
-LRESULT CALLBACK CProxyWindow::wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch(msg) {
-
-#if defined(__LOGDEBUG_)
- case WM_NCCREATE:
- _DebugTraceW(_T("create proxy WINDOW for: %s"), m_dat->cache->getNick());
- break;
-#endif
- case WM_CLOSE: {
- TContainerData* pC = m_dat->pContainer;
-
- if(m_dat->hwnd != pC->hwndActive)
- SendMessage(m_dat->hwnd, WM_CLOSE, 1, 3);
- else
- SendMessage(m_dat->hwnd, WM_CLOSE, 1, 2);
- if(!IsIconic(pC->hwnd))
- SetForegroundWindow(pC->hwnd);
- return(0);
- }
-
- /*
- * proxy window was activated by clicking on the thumbnail. Send this
- * to the real message window.
- */
- case WM_ACTIVATE:
- if(WA_ACTIVE == wParam) {
- if(IsWindow(m_dat->hwnd))
- ::PostMessage(m_dat->hwnd, DM_ACTIVATEME, 0, 0);
- return(0); // no default processing, avoid flickering.
- }
- break;
-
- case WM_NCDESTROY:
- ::SetWindowLongPtr(hWnd, GWLP_USERDATA, 0);
-#if defined(__LOGDEBUG_)
- _DebugTraceW(_T("destroy proxy WINDOW for: %s"), m_dat->cache->getNick());
-#endif
- break;
-
- case WM_DWMSENDICONICTHUMBNAIL:
- sendThumb(HIWORD(lParam), LOWORD(lParam));
- return(0);
-
- case WM_DWMSENDICONICLIVEPREVIEWBITMAP:
- sendPreview();
- return(0);
-
- default:
- break;
- }
- return(::DefWindowProc(hWnd, msg, wParam, lParam));
-}
-
-/**
- * base thumbnail class. Create the background and common parts for a
- * thumbnail
- *
- * @param _p owner proxy window object
- * @return
- */
-CThumbBase::CThumbBase(const CProxyWindow* _p)
-{
- m_pWnd = _p;
- m_hbmThumb = 0;
- renderBase();
-}
-
-/**
- * render base for a thumbnail. This creates the background, the large icon
- * and the basic status mode text. It also divides the thumbnail rectangle
- * into a few content rectangles used later by the content renderer.
- */
-void CThumbBase::renderBase()
-{
- HICON hIcon = 0;
- HBRUSH brBack;
- LONG lIconSize = 32;
-
- m_width = m_pWnd->getWidth();
- m_height = m_pWnd->getHeight();
- m_dat = m_pWnd->getDat();
- m_dtFlags = 0;
- m_hOldFont = 0;
-
-#if defined(__LOGDEBUG_)
- _DebugTraceW(_T("refresh base (background) with %d, %d"), m_width, m_height);
-#endif
-
- m_rc.right = m_width;
- m_rc.bottom = m_height;
- m_rc.left = m_rc.top = 0;
-
- if(m_hbmThumb) {
- ::DeleteObject(m_hbmThumb);
- m_hbmThumb = 0;
- }
-
- HDC dc = ::GetDC(m_pWnd->getHwnd());
- m_hdc = ::CreateCompatibleDC(dc);
-
- m_hbmThumb = CSkin::CreateAeroCompatibleBitmap(m_rc, m_hdc);
- m_hbmOld = reinterpret_cast<HBITMAP>(::SelectObject(m_hdc, m_hbmThumb));
- ReleaseDC(m_pWnd->getHwnd(), dc);
-
- brBack = ::CreateSolidBrush(m_dat->dwUnread ? RGB(80, 60, 60) : RGB(60, 60, 60));
- ::FillRect(m_hdc, &m_rc, brBack);
- ::DeleteObject(brBack);
-
- ::SelectObject(m_hdc, m_hbmOld);
- CImageItem::SetBitmap32Alpha(m_hbmThumb, m_dat->dwUnread ? 110 : 60);
- m_hbmOld = reinterpret_cast<HBITMAP>(::SelectObject(m_hdc, m_hbmThumb));
-
- SetBkMode(m_hdc, TRANSPARENT);
-
- m_hOldFont = reinterpret_cast<HFONT>(::SelectObject(m_hdc, CInfoPanel::m_ipConfig.hFonts[IPFONTID_STATUS]));
- ::GetTextExtentPoint32A(m_hdc, "A", 1, &m_sz);
-
- InflateRect(&m_rc, -3, -3);
-
- setupRect();
- hIcon = m_pWnd->getBigIcon();
-
- if(0 == hIcon) {
- if(m_dat->dwUnread) {
- if(PluginConfig.g_IconMsgEventBig)
- hIcon = PluginConfig.g_IconMsgEventBig;
- else {
- hIcon = PluginConfig.g_IconMsgEvent;
- lIconSize = 16;
- }
- }
- else {
- hIcon = reinterpret_cast<HICON>(LoadSkinnedProtoIconBig(m_dat->cache->getActiveProto(), m_dat->cache->getActiveStatus()));
- if(0 == hIcon || reinterpret_cast<HICON>(CALLSERVICE_NOTFOUND) == hIcon) {
- hIcon = reinterpret_cast<HICON>(LoadSkinnedProtoIcon(m_dat->cache->getActiveProto(), m_dat->cache->getActiveStatus()));
- lIconSize = 16;
- }
- }
- }
- ::DrawIconEx(m_hdc, m_rcIcon.right / 2 - lIconSize / 2, m_rcIcon.top, hIcon, lIconSize, lIconSize, 0, 0, DI_NORMAL);
- hIcon = m_pWnd->getOverlayIcon();
- if(hIcon)
- ::DrawIconEx(m_hdc, m_rcIcon.right - 16, m_rcIcon.top + 16, hIcon, 16, 16, 0, 0, DI_NORMAL);
-
- m_rcIcon.top += (lIconSize + 3);
- CSkin::RenderText(m_hdc, m_dat->hTheme, m_dat->szStatus, &m_rcIcon, m_dtFlags | DT_CENTER | DT_WORD_ELLIPSIS, 10, 0, true);
- if(m_dat->dwUnread && SESSIONTYPE_IM == m_dat->bType) {
- wchar_t tszTemp[30];
-
- m_rcIcon.top += m_sz.cy;
- mir_sntprintf(tszTemp, 30, CTranslator::get(CTranslator::GEN_TASKBAR_STRING_UNREAD), m_dat->dwUnread);
- CSkin::RenderText(m_hdc, m_dat->hTheme, tszTemp, &m_rcIcon, m_dtFlags | DT_CENTER | DT_WORD_ELLIPSIS, 10, 0, true);
- }
- m_rcIcon= m_rcTop;
- m_rcIcon.top += 2;
- m_rcIcon.left = m_rc.right / 3;
- m_cx = m_rcIcon.right - m_rcIcon.left;
- m_cy = m_rcIcon.bottom - m_rcIcon.top;
-}
-
-/**
- * divide space into content rectangles for normal thumbnails
- */
-void CThumbBase::setupRect()
-{
- if(SESSIONTYPE_IM == m_pWnd->getDat()->bType) {
- m_rcTop = m_rc;
- m_rcBottom = m_rc;
- m_rcBottom.top = m_rc.bottom - ( 2 * (m_rcBottom.bottom / 5)) - 2;
- m_rcTop.bottom = m_rcBottom.top - 2;
-
- m_rcIcon = m_rcTop;
- m_rcIcon.right = m_rc.right / 3;
- }
- else {
- m_rcTop = m_rc;
- m_rcBottom = m_rc;
- m_rcBottom.top = m_rc.bottom - ( 2 * (m_rcBottom.bottom / 5)) - 2;
- m_rcTop.bottom = m_rcBottom.top - 2;
-
- m_rcIcon = m_rcTop;
- m_rcIcon.right = m_rc.left + 42;
- }
-}
-
-/**
- * destroy the thumbnail object. Just delete the bitmap we cached
- * @return
- */
-CThumbBase::~CThumbBase()
-{
- if(m_hbmThumb) {
- ::DeleteObject(m_hbmThumb);
- m_hbmThumb = 0;
- m_isValid = false;
- }
-#if defined(__LOGDEBUG_)
- _DebugTraceW(_T("destroy CThumbBase"));
-#endif
-}
-
-/**
- * create a IM session thumbnail. base class will create the
- * bitmap and render the background.
- *
- * @param _p our owner (CProxyWindow object)
- */
-CThumbIM::CThumbIM(const CProxyWindow* _p) : CThumbBase(_p)
-{
- renderContent();
- setValid(true);
-}
-
-/**
- * update the thumbnail, render everything and set it valid
- */
-void CThumbIM::update()
-{
- renderBase();
- renderContent();
- setValid(true);
-}
-
-/**
- * render the content for an IM chat session thumbnail
- * m_hdc etc. must already be initialized (done by the constructor)
- * background had been already rendered
- */
-void CThumbIM::renderContent()
-{
- HBITMAP hbmAvatar, hbmOldAv;
- double dNewWidth = 0.0, dNewHeight = 0.0;
- bool fFree = false;
- HRGN hRgn = 0;
- HDC dc;
- const wchar_t* tszStatusMsg = 0;
-
- hbmAvatar = (m_dat->ace && m_dat->ace->hbmPic) ? m_dat->ace->hbmPic : PluginConfig.g_hbmUnknown;
- Utils::scaleAvatarHeightLimited(hbmAvatar, dNewWidth, dNewHeight, m_rcIcon.bottom - m_rcIcon.top);
-
- HBITMAP hbmResized = CSkin::ResizeBitmap(hbmAvatar, dNewWidth, dNewHeight, fFree);
-
- dc = CreateCompatibleDC(m_hdc);
- hbmOldAv = reinterpret_cast<HBITMAP>(::SelectObject(dc, hbmResized));
-
- LONG xOff = m_rcIcon.right - (LONG)dNewWidth - 2;
- LONG yOff = (m_cy - (LONG)dNewHeight) / 2 + m_rcIcon.top;
-
- hRgn = ::CreateRectRgn(xOff - 1, yOff - 1, xOff + (LONG)dNewWidth + 2, yOff + (LONG)dNewHeight + 2);
- CSkin::m_default_bf.SourceConstantAlpha = 150;
- CMimAPI::m_MyAlphaBlend(m_hdc, xOff, yOff, (LONG)dNewWidth, (LONG)dNewHeight, dc, 0, 0, (LONG)dNewWidth, (LONG)dNewHeight, CSkin::m_default_bf);
- CSkin::m_default_bf.SourceConstantAlpha = 255;
- ::FrameRgn(m_hdc, hRgn, reinterpret_cast<HBRUSH>(::GetStockObject(BLACK_BRUSH)), 1, 1);
-
- ::DeleteObject(hRgn);
- ::SelectObject(dc, hbmOldAv);
-
- if(hbmResized != hbmAvatar)
- ::DeleteObject(hbmResized);
-
- ::DeleteDC(dc);
- m_rcBottom.bottom -= 16;
-
- /*
- * status message and bottom line (either UID or nick name, depending on
- * task bar grouping mode). For chat rooms, it is the topic.
- */
- if((m_rcBottom.bottom - m_rcBottom.top) < 2 * m_sz.cy)
- m_dtFlags |= DT_SINGLELINE;
-
- m_rcBottom.bottom -= ((m_rcBottom.bottom - m_rcBottom.top) % m_sz.cy); // adjust to a multiple of line height
-
- if(0 == (tszStatusMsg = m_dat->cache->getStatusMsg()))
- tszStatusMsg = CTranslator::get(CTranslator::GEN_NO_STATUS);
-
- CSkin::RenderText(m_hdc, m_dat->hTheme, tszStatusMsg, &m_rcBottom, DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | m_dtFlags, 10, 0, true);
- m_rcBottom.bottom = m_rc.bottom;
- m_rcBottom.top = m_rcBottom.bottom - m_sz.cy - 2;
- CSkin::RenderText(m_hdc, m_dat->hTheme, Win7Taskbar->haveAlwaysGroupingMode() ? m_dat->cache->getUIN() : m_dat->cache->getNick(),
- &m_rcBottom, m_dtFlags | DT_SINGLELINE | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS, 10, 0, true);
-
- /*
- * finalize it
- * do NOT delete the bitmap, the dwm will need the handle
- * m_hbm is deleted when a new thumbnail is generated on dwm's request.
- * this is not a leak!
- */
- if(m_hOldFont)
- ::SelectObject(m_hdc, m_hOldFont);
-
- ::SelectObject(m_hdc, m_hbmOld);
- ::DeleteDC(m_hdc);
-}
-
-/**
- * create a MUC session thumbnail. base class will create the
- * bitmap and render the background.
- *
- * @param _p our owner (CProxyWindow object)
- * @return
- */
-CThumbMUC::CThumbMUC(const CProxyWindow* _p) : CThumbBase(_p)
-{
- renderContent();
- setValid(true);
-}
-
-/**
- * update an invalidated thumbnail
- */
-void CThumbMUC::update()
-{
- renderBase();
- renderContent();
- setValid(true);
-}
-
-/**
- * render content area for a MUC thumbnail
- */
-void CThumbMUC::renderContent()
-{
- if(m_dat->si) {
- const MODULEINFO* mi = MM_FindModule(m_dat->si->pszModule);
- wchar_t szTemp[250];
- const wchar_t* szStatusMsg = 0;
-
- if(mi) {
- if(m_dat->dwUnread) {
- mir_sntprintf(szTemp, 30, CTranslator::get(CTranslator::GEN_TASKBAR_STRING_UNREAD), m_dat->dwUnread);
- CSkin::RenderText(m_hdc, m_dat->hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true);
- m_rcIcon.top += m_sz.cy;
- }
- if(m_dat->si->iType != GCW_SERVER) {
- wchar_t* _p = NULL;
- if ( m_dat->si->ptszStatusbarText )
- _p = wcschr(m_dat->si->ptszStatusbarText, ']');
- if( _p ) {
- _p++;
- wchar_t _t = *_p;
- *_p = 0;
- mir_sntprintf(szTemp, SIZEOF(szTemp), CTranslator::get(CTranslator::GEN_TASKBAR_STRING_CHAT_ROOM), m_dat->si->ptszStatusbarText);
- *_p = _t;
- }
- else
- mir_sntprintf(szTemp, SIZEOF(szTemp), CTranslator::get(CTranslator::GEN_TASKBAR_STRING_CHAT_ROOM), L"");
- CSkin::RenderText(m_hdc, m_dat->hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true);
- m_rcIcon.top += m_sz.cy;
- mir_sntprintf(szTemp, SIZEOF(szTemp), CTranslator::get(CTranslator::GEN_TASKBAR_STRING_USERS), m_dat->si->nUsersInNicklist);
- CSkin::RenderText(m_hdc, m_dat->hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true);
- }
- else {
- mir_sntprintf(szTemp, SIZEOF(szTemp), CTranslator::get(CTranslator::GEN_TASKBAR_STRING_SERVER_WINDOW));
- CSkin::RenderText(m_hdc, m_dat->hTheme, szTemp, &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true);
- if(mi->tszIdleMsg[0] && _tcslen(mi->tszIdleMsg) > 2) {
- m_rcIcon.top += m_sz.cy;
- CSkin::RenderText(m_hdc, m_dat->hTheme, &mi->tszIdleMsg[2], &m_rcIcon, m_dtFlags | DT_SINGLELINE | DT_RIGHT, 10, 0, true);
- }
- }
- }
-
- if((m_rcBottom.bottom - m_rcBottom.top) < 2 * m_sz.cy)
- m_dtFlags |= DT_SINGLELINE;
-
- m_rcBottom.bottom -= ((m_rcBottom.bottom - m_rcBottom.top) % m_sz.cy); // adjust to a multiple of line height
-
- if(m_dat->si->iType != GCW_SERVER) {
- if(0 == (szStatusMsg = m_dat->si->ptszTopic))
- szStatusMsg = CTranslator::get(CTranslator::GEN_MUC_NO_TOPIC);
- }
- else if(mi) {
- mir_sntprintf(szTemp, SIZEOF(szTemp), CTranslator::get(CTranslator::MUC_SBAR_ON_SERVER), m_dat->szMyNickname, mi->ptszModDispName, L"");
- szStatusMsg = szTemp;
- }
-
- CSkin::RenderText(m_hdc, m_dat->hTheme, szStatusMsg, &m_rcBottom, DT_WORD_ELLIPSIS | DT_END_ELLIPSIS | m_dtFlags, 10, 0, true);
- }
- /*
- * finalize it
- * do NOT delete the bitmap, the dwm will need the handle
- * m_hbm is deleted when a new thumbnail is generated on dwm's request.
- * this is not a leak!
- */
- if(m_hOldFont)
- ::SelectObject(m_hdc, m_hOldFont);
-
- ::SelectObject(m_hdc, m_hbmOld);
- ::DeleteDC(m_hdc);
-}