2025-11-27 16:46:48 +09:00

764 lines
20 KiB
C++

// OXTaskPanel.cpp : implementation file
//
#include "stdafx.h"
#include "OXTaskPanel.h"
//Theme API wrapper declarations
HMODULE g_huxtheme = NULL;
bool G_LoadThemeLibrary()
{
if (!g_huxtheme)
g_huxtheme = ::LoadLibrary(_T("uxtheme.dll"));
return (g_huxtheme != NULL);
}
HTHEME G_OpenThemeData(HWND hwnd, LPCTSTR pszClassList)
{
G_LoadThemeLibrary();
OPENTHEMEDATA pOpenThemeData = (OPENTHEMEDATA)GetProcAddress(g_huxtheme, "OpenThemeData");
if (pOpenThemeData != NULL)
return (*pOpenThemeData)(hwnd, pszClassList);
else
return NULL;
}
HRESULT G_CloseThemeData(HTHEME hTheme)
{
G_LoadThemeLibrary();
CLOSETHEMEDATA pCloseThemeData = (CLOSETHEMEDATA)GetProcAddress(g_huxtheme, "CloseThemeData");
if (pCloseThemeData != NULL)
return (*pCloseThemeData)(hTheme);
else
return E_FAIL;
}
HRESULT G_DrawThemeBackground(HTHEME hTheme, HDC hdc,
int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect)
{
G_LoadThemeLibrary();
DRAWTHEMEBACKGROUND pDrawThemeBackground =
(DRAWTHEMEBACKGROUND)GetProcAddress(g_huxtheme, "DrawThemeBackground");
if (pDrawThemeBackground != NULL)
return (*pDrawThemeBackground)(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);
else
return E_FAIL;
}
HRESULT G_DrawThemeText(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwTextFlags,
DWORD dwTextFlags2, const RECT *pRect)
{
G_LoadThemeLibrary();
DRAWTHEMETEXT pDrawThemeText = (DRAWTHEMETEXT)GetProcAddress(g_huxtheme, "DrawThemeText");
if (pDrawThemeText != NULL)
return (*pDrawThemeText)(hTheme, hdc, iPartId, iStateId, pszText, iCharCount, dwTextFlags, dwTextFlags2, pRect);
else
return E_FAIL;
}
HRESULT G_DrawThemeEdge(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
const RECT *pDestRect, UINT uEdge, UINT uFlags, OPTIONAL OUT RECT *pContentRect)
{
G_LoadThemeLibrary();
DRAWTHEMEEDGE pDrawThemeEdge = (DRAWTHEMEEDGE)GetProcAddress(g_huxtheme, "DrawThemeEdge");
if (pDrawThemeEdge != NULL)
return (*pDrawThemeEdge)(hTheme, hdc, iPartId, iStateId, pDestRect, uEdge, uFlags, pContentRect);
else
return E_FAIL;
}
HRESULT G_GetThemeColor(HTHEME hTheme, int iPartId,
int iStateId, int iPropId, OUT COLORREF *pColor)
{
G_LoadThemeLibrary();
GETTHEMECOLOR pGetThemeColor = (GETTHEMECOLOR)GetProcAddress(g_huxtheme, "GetThemeColor");
if (pGetThemeColor != NULL)
return (*pGetThemeColor)(hTheme, iPartId, iStateId, iPropId, pColor);
else
return E_FAIL;
}
HRESULT G_GetThemeFont(HTHEME hTheme, OPTIONAL HDC hdc, int iPartId,
int iStateId, int iPropId, OUT LOGFONT *pFont)
{
G_LoadThemeLibrary();
GETTHEMEFONT pGetThemeFont = (GETTHEMEFONT)GetProcAddress(g_huxtheme, "GetThemeFont");
if (pGetThemeFont != NULL)
return (*pGetThemeFont)(hTheme, hdc, iPartId, iStateId, iPropId, pFont);
else
return E_FAIL;
}
// COXTaskPanel
IMPLEMENT_DYNAMIC(COXTaskPanel, CWnd)
COXTaskPanel::COXTaskPanel():m_hTheme(NULL),m_bLastHover(false),
m_ActiveItem(NULL),m_bMouseOnControl(false),pOldFocus(NULL),
m_bIgnoreButtonUp(false),m_nAnimSteps(0)
{
}
COXTaskPanel::~COXTaskPanel()
{
}
BEGIN_MESSAGE_MAP(COXTaskPanel, CWnd)
ON_WM_CREATE()
ON_WM_CLOSE()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_VSCROLL()
ON_WM_MOUSEWHEEL()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_THEMECHANGED, OnThemeChanged)
ON_WM_TIMER()
END_MESSAGE_MAP()
// COXTaskPanel message handlers
BOOL COXTaskPanel::Create(RECT rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
rect.right = rect.left + PDPanelFixedWidth;
return CWnd::Create(NULL, _T("Panel"), WS_VISIBLE|WS_CHILD|WS_VSCROLL, rect, pParentWnd, nID, pContext);
}
int COXTaskPanel::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_hTheme = G_OpenThemeData(m_hWnd, _T("EXPLORERBAR"));
return 0;
}
void COXTaskPanel::OnClose()
{
G_CloseThemeData(m_hTheme);
CWnd::OnClose();
}
void COXTaskPanel::OnPaint()
{
CPaintDC dc(this);
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
dc.SetWindowOrg(0, yPos);
CRect rect;
GetClientRect(&rect);
rect.bottom += yPos;
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bmap;
bmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
CBitmap* pOldBitmap = memdc.SelectObject(&bmap);
if(COXTaskPanel::IsThemed())
G_DrawThemeBackground(m_hTheme, memdc.m_hDC, 1, 0,rect, NULL);
else
memdc.FillSolidRect(rect,GetSysColor(COLOR_WINDOW));
DrawGroups(memdc.m_hDC);
dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memdc, 0, 0, SRCCOPY);
memdc.SelectObject(pOldBitmap);
}
BOOL COXTaskPanel::OnEraseBkgnd(CDC* /*pDC*/)
{
return FALSE;
}
LRESULT COXTaskPanel::OnThemeChanged(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
G_CloseThemeData(m_hTheme);
m_hTheme = G_OpenThemeData(m_hWnd, _T("EXPLORERBAR"));
return 1;
}
void COXTaskPanel::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
switch(nSBCode)
{
case SB_LINEDOWN:
nPos = GetScrollPos(SB_VERT) + 1;
break;
case SB_LINEUP:
nPos = GetScrollPos(SB_VERT) - 1;
break;
case SB_PAGEDOWN:
nPos = GetScrollPos(SB_VERT) + MulDiv(GetSystemMetrics(SM_CYMENU), 9, 8);
break;
case SB_PAGEUP:
nPos = GetScrollPos(SB_VERT) - MulDiv(GetSystemMetrics(SM_CYMENU), 9, 8);
break;
case SB_TOP:
nPos = 0;
break;
case SB_BOTTOM:
nPos = GetScrollLimit(SB_VERT);
break;
case SB_ENDSCROLL:
return;
}
SetScrollPos(SB_VERT, nPos, TRUE);
Invalidate();
}
BOOL COXTaskPanel::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
if(GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL)
{
OnVScroll(zDelta > 0 ? SB_PAGEUP : SB_PAGEDOWN, 0, NULL);
return TRUE;
}
return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}
void COXTaskPanel::OnMouseMove(UINT nFlags, CPoint point)
{
if(!m_bMouseOnControl)
{
m_bMouseOnControl = true;
TRACKMOUSEEVENT tme = {0};
tme.cbSize = sizeof TRACKMOUSEEVENT;
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
TrackMouseEvent(&tme);
pOldFocus = SetFocus();
}
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
point.y += yPos;
bool bFoundHover = false;
for(vector<TaskGroup>::iterator it = m_vecGroups.begin();
it != m_vecGroups.end(); it++)
{
if(it->m_HeaderRect.PtInRect(point) )
{
SetCursor(AfxGetApp()->LoadOEMCursor(OCR_HAND));
if(!it->m_bIsMouseHovered)
{
it->m_bIsMouseHovered = true;
Invalidate();
}
bFoundHover = true;
break;
}
else
{
Item* pItem = NULL;
pItem = it->FindItemWithPt(point);
if(!it->m_bIsCollapsed && (pItem) )
{
InvalidateRect(m_ActiveItem->m_ItemRect);
m_ActiveItem = pItem;
Invalidate();
SetCursor(AfxGetApp()->LoadOEMCursor(OCR_HAND));
}
it->m_bIsMouseHovered = false;
}
}
if(!bFoundHover)
{
if(m_bLastHover)
{
Invalidate();
m_bLastHover = false;
}
}
point.y -= yPos;
CWnd::OnMouseMove(nFlags, point);
}
LRESULT COXTaskPanel::OnMouseLeave(WPARAM /* wParam */, LPARAM /* lParam */)
{
m_bMouseOnControl = false;
if(pOldFocus)
{
pOldFocus->SetFocus();
pOldFocus = NULL;
}
return 0;
}
void COXTaskPanel::OnLButtonDown(UINT nFlags, CPoint point)
{
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
point.y += yPos;
for(vector<TaskGroup>::iterator it = m_vecGroups.begin();
it != m_vecGroups.end(); it++)
{
// Check to see if an animation is already active for this task group
if(it->m_bAnimationEnabled)
{
continue;
}
if(it->m_HeaderRect.PtInRect(point))
{
if(it->m_bIsCollapsed)
{
SetTimer(ANIMATIONTIMERID, ANIMATIONINTERVAL, NULL);
m_nAnimSteps = NUMANIMSTEPS;
}
else
{
SetTimer(REVANIMATIONTIMERID, ANIMATIONINTERVAL, NULL);
m_nAnimSteps = -NUMANIMSTEPS;
}
it->m_bAnimationEnabled = true;
it->m_bIsCollapsed = !it->m_bIsCollapsed;
Invalidate();
m_bIgnoreButtonUp = true;
break;
}
}
point.y -= yPos;
CWnd::OnLButtonDown(nFlags, point);
}
void COXTaskPanel::OnLButtonUp(UINT nFlags, CPoint point)
{
if(!m_bIgnoreButtonUp)
{
int yPos = (GetWindowLong(m_hWnd, GWL_STYLE) & WS_VSCROLL) ? GetScrollPos(SB_VERT) : 0;
point.y += yPos;
for(vector<TaskGroup>::iterator it = m_vecGroups.begin();
it != m_vecGroups.end(); it++)
{
Item* pItem = NULL;
bool bItemValid = false;
pItem = it->FindItemWithPt(point);
bItemValid = !it->m_bIsCollapsed;
if( it->m_HeaderRect.PtInRect(point) || (bItemValid && pItem ) )
{
if(bItemValid && pItem->m_strCmd.GetLength())
{
OnMouseLeave(0,0);
ShellExecute(m_hWnd,_T("open"),pItem->m_strCmd,
NULL,NULL,SW_SHOW);
}
SetCursor(AfxGetApp()->LoadOEMCursor(OCR_HAND));
}
}
point.y -= yPos;
}
else
{
m_bIgnoreButtonUp = false;
}
CWnd::OnLButtonUp(nFlags, point);
}
void COXTaskPanel::OnTimer(UINT_PTR nIDEvent)
{
if(nIDEvent == ANIMATIONTIMERID)
{
if(m_nAnimSteps--)
Invalidate();
else
{
m_nAnimSteps = 0;
KillTimer(ANIMATIONTIMERID);
}
}
if(nIDEvent == REVANIMATIONTIMERID)
{
if(m_nAnimSteps++)
Invalidate();
else
{
m_nAnimSteps = 0;
KillTimer(REVANIMATIONTIMERID);
}
}
CWnd::OnTimer(nIDEvent);
}
bool COXTaskPanel::IsThemed()
{
bool ret = false;
OSVERSIONINFO ovi = {0};
ovi.dwOSVersionInfoSize = sizeof ovi;
GetVersionEx(&ovi);
if( (ovi.dwMajorVersion==5 && ovi.dwMinorVersion>=1) || (ovi.dwMajorVersion>5) )
{
//Windows XP or later detected
typedef BOOL WINAPI ISAPPTHEMED();
typedef BOOL WINAPI ISTHEMEACTIVE();
ISAPPTHEMED* pISAPPTHEMED = NULL;
ISTHEMEACTIVE* pISTHEMEACTIVE = NULL;
HMODULE hMod = LoadLibrary(_T("uxtheme.dll"));
if(hMod)
{
pISAPPTHEMED = reinterpret_cast<ISAPPTHEMED*>(GetProcAddress(hMod,"IsAppThemed"));
pISTHEMEACTIVE = reinterpret_cast<ISTHEMEACTIVE*>(GetProcAddress(hMod,"IsThemeActive"));
if(pISAPPTHEMED && pISTHEMEACTIVE)
{
if(pISAPPTHEMED() && pISTHEMEACTIVE())
{
typedef HRESULT CALLBACK DLLGETVERSION(DLLVERSIONINFO*);
DLLGETVERSION* pDLLGETVERSION = NULL;
HMODULE hModComCtl = LoadLibrary(_T("comctl32.dll"));
if(hModComCtl)
{
pDLLGETVERSION = reinterpret_cast<DLLGETVERSION*>(
GetProcAddress(hModComCtl,"DllGetVersion"));
if(pDLLGETVERSION)
{
DLLVERSIONINFO dvi = {0};
dvi.cbSize = sizeof dvi;
if(pDLLGETVERSION(&dvi) == NOERROR )
{
ret = dvi.dwMajorVersion >= 6;
}
}
FreeLibrary(hModComCtl);
}
}
}
FreeLibrary(hMod);
}
}
return ret;
}
TaskGroup* COXTaskPanel::AddGroup(LPCTSTR szGroupName)
{
m_vecGroups.push_back(TaskGroup(szGroupName));
return &(*(m_vecGroups.end() - 1));
}
void COXTaskPanel::DrawGroupItem(HDC hDC, const CRect& recGroupItem, vector<Item>::iterator it2)
{
it2->m_ItemRect = recGroupItem;
HICON hIcon = (HICON)LoadImage(AfxGetInstanceHandle(),
MAKEINTRESOURCE(it2->m_nIconID), IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
DrawIconEx(hDC,recGroupItem.left - (PDGroupItemLeftMargin-PDGroupIconLeftMargin),
recGroupItem.top + PDGroupIconVerticalDisplacement, hIcon, 16, 16,0, NULL,DI_NORMAL);
DestroyIcon(hIcon);
if(&(*it2) == m_ActiveItem)
{
m_ActiveItem = NULL;
TCHAR buff[128];
_tcscpy_s(buff,it2->m_strText);
int oldMode = SetBkMode(hDC, TRANSPARENT);
COLORREF color;
if(COXTaskPanel::IsThemed())
{
G_GetThemeColor(m_hTheme,5,0,TMT_TEXTCOLOR,&color);
int shift = 48;
color = RGB(min(255,GetRValue(color) + shift),
min(255,GetGValue(color) + shift), min(255,GetBValue(color) + shift));
}
else
{
color = GetSysColor(COLOR_HOTLIGHT);
}
COLORREF oldcolor = SetTextColor(hDC, color);
LOGFONT font;
G_GetThemeFont(m_hTheme, hDC,5,0,TMT_FONT,&font);
font.lfUnderline = TRUE;
HFONT hFont = NULL;
if(COXTaskPanel::IsThemed())
hFont = CreateFontIndirect(&font);
else
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
DrawTextEx(hDC,buff,it2->m_strText.GetLength(),
(LPRECT)&recGroupItem,DT_LEFT|DT_VCENTER|DT_SINGLELINE,NULL);
SetTextColor(hDC, oldcolor);
if(oldMode)
SetBkMode(hDC, oldMode);
SelectObject(hDC,hFontOld);
DeleteObject(hFont);
}
else
{
if(COXTaskPanel::IsThemed())
{
G_DrawThemeText(m_hTheme, hDC, 5, 0, it2->m_strText, it2->m_strText.GetLength(),
DT_LEFT|DT_VCENTER|DT_SINGLELINE,NULL,recGroupItem);
}
else
{
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
LOGFONT lf = {0};
GetObject(hFont, sizeof(lf), &lf);
DeleteObject(hFont);
hFont = CreateFontIndirect(&lf);
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
int oldMode = SetBkMode(hDC, TRANSPARENT);
DrawText(hDC,it2->m_strText,it2->m_strText.GetLength(),
(RECT*)&recGroupItem,DT_LEFT|DT_VCENTER|DT_SINGLELINE);
if(oldMode)
SetBkMode(hDC, oldMode);
SelectObject(hDC,hFontOld);
DeleteObject(hFont);
}
}
}
void COXTaskPanel::DrawGroupHeader(HDC hDC, const CRect& recGroupHeader, vector<TaskGroup>::iterator it)
{
if(COXTaskPanel::IsThemed())
{
G_DrawThemeBackground(m_hTheme, hDC, 8, 0, recGroupHeader, NULL);
G_DrawThemeEdge(m_hTheme, hDC, 8, 0, recGroupHeader,EDGE_SUNKEN,BF_FLAT,NULL);
}
else
FillRect(hDC,recGroupHeader,(HBRUSH)(COLOR_3DFACE + 1));
CString grpText = *it;
CRect recGroupText(recGroupHeader);
recGroupText.MoveToX(recGroupText.left + PDHeaderTextDisplacement);
if(COXTaskPanel::IsThemed())
G_DrawThemeText(m_hTheme, hDC, 8, 0, grpText, grpText.GetLength(),
DT_LEFT|DT_VCENTER|DT_SINGLELINE,NULL,recGroupText);
else
{
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
LOGFONT lf = {0};
GetObject(hFont, sizeof(lf), &lf);
DeleteObject(hFont);
lf.lfWeight = FW_BOLD;
hFont = CreateFontIndirect(&lf);
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
int oldMode = SetBkMode(hDC, TRANSPARENT);
DrawText(hDC,grpText,grpText.GetLength(),recGroupText,DT_VCENTER|DT_SINGLELINE);
if(oldMode)
SetBkMode(hDC, oldMode);
SelectObject(hDC,hFontOld);
DeleteObject(hFont);
}
CRect recGroupIcon(recGroupHeader.left + PDHeaderIconDisplacement,
recGroupHeader.top, recGroupHeader.right, recGroupHeader.bottom);
int iPart = 0;
if(it->m_bIsCollapsed)
iPart = 7;
else
iPart = 6;
if(it->m_bIsMouseHovered)
{
if(COXTaskPanel::IsThemed())
G_DrawThemeBackground(m_hTheme, hDC, iPart, 2, recGroupIcon, NULL);
else
{
CDC pDC;
pDC.Attach(hDC);
pDC.Draw3dRect(recGroupIcon,GetSysColor(COLOR_3DHILIGHT), GetSysColor(COLOR_3DSHADOW));
pDC.Detach();
if(it->m_bIsCollapsed)
{
DrawDownArrow(hDC, recGroupIcon);
}
else
{
DrawUpArrow(hDC, recGroupIcon);
}
}
m_bLastHover = true;
}
else
{
if(COXTaskPanel::IsThemed())
G_DrawThemeBackground(m_hTheme, hDC, iPart, 0, recGroupIcon, NULL);
else
{
if(it->m_bIsCollapsed)
{
DrawDownArrow(hDC, recGroupIcon);
}
else
{
DrawUpArrow(hDC, recGroupIcon);
}
}
}
}
void COXTaskPanel::DrawDownArrow(HDC hDC, const CRect& recGroupIcon)
{
LOGFONT lf = {0};
_tcscpy_s(lf.lfFaceName,LF_FACESIZE, _T("Marlett"));
lf.lfCharSet = DEFAULT_CHARSET;
HFONT hFont = CreateFontIndirect(&lf);
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
int oldMode = SetBkMode(hDC, TRANSPARENT);
DrawText(hDC,_T("6"),1,(RECT*)&recGroupIcon,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
if(oldMode)
SetBkMode(hDC, oldMode);
SelectObject(hDC,hFontOld);
DeleteObject(hFont);
}
void COXTaskPanel::DrawUpArrow(HDC hDC, const CRect& recGroupIcon)
{
LOGFONT lf = {0};
_tcscpy_s(lf.lfFaceName,LF_FACESIZE,_T("Marlett"));
lf.lfCharSet = DEFAULT_CHARSET;
HFONT hFont = CreateFontIndirect(&lf);
HFONT hFontOld = (HFONT)SelectObject(hDC, hFont);
int oldMode = SetBkMode(hDC, TRANSPARENT);
DrawText(hDC,_T("5"),1,(RECT*)&recGroupIcon,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
if(oldMode)
SetBkMode(hDC, oldMode);
SelectObject(hDC,hFontOld);
DeleteObject(hFont);
}
void COXTaskPanel::DrawGroups(HDC hDC)
{
CRect recGroupHeader(PDLeftMargin, PDTopMargin,PDLeftMargin + PDHeaderWidth,PDTopMargin + PDHeaderHeight);
for(vector<TaskGroup>::iterator it = m_vecGroups.begin(); it != m_vecGroups.end(); it++)
{
it->m_HeaderRect = recGroupHeader;
DrawGroupHeader(hDC, recGroupHeader, it);
int sz = 0;
if((!it->m_bIsCollapsed) || (it->m_bIsCollapsed && it->m_bAnimationEnabled))
{
sz = (int)it->m_vecItems.size();
CRect recGroupBodySource(recGroupHeader.left, recGroupHeader.bottom,
recGroupHeader.right, recGroupHeader.bottom + (sz * PDGroupItemHeight));
if(it->m_bAnimationEnabled)
{
if(m_nAnimSteps == 0)
it->m_bAnimationEnabled = false;
else
{
if(m_nAnimSteps>0)
sz = (int) ((float)sz / (float)max(m_nAnimSteps,1));
else
sz = (int) ((float)sz / (float)max(NUMANIMSTEPS + m_nAnimSteps,1));
}
}
CRect recGroupBodyTarget(recGroupHeader.left, recGroupHeader.bottom,
recGroupHeader.right, recGroupHeader.bottom + (sz * PDGroupItemHeight));
HDC hDrawDC = hDC;
HDC tmpDC = NULL;
HBITMAP hbmap = NULL;
HBITMAP oldbmap = NULL;
CRect rect;
GetClientRect(&rect);
if(it->m_bAnimationEnabled)
{
tmpDC = CreateCompatibleDC(hDC);
hbmap = CreateCompatibleBitmap(hDC, rect.Width(), rect.Height());
oldbmap = (HBITMAP)SelectObject(tmpDC,hbmap);
hDrawDC = tmpDC;
}
if(!(it->m_bIsCollapsed && !it->m_bAnimationEnabled))
{
if(COXTaskPanel::IsThemed())
G_DrawThemeBackground(m_hTheme, hDrawDC, 5, 0, recGroupBodySource, NULL);
else
{
FillRect(hDrawDC,recGroupBodySource,(HBRUSH)(COLOR_WINDOW + 1));
HBRUSH hBrushFrame = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);
FrameRect(hDrawDC,recGroupBodySource,hBrushFrame);
}
CRect recGroupItem(recGroupBodySource.left + PDGroupItemLeftMargin,
recGroupBodySource.top,recGroupBodySource.right, recGroupBodySource.top + PDGroupItemHeight);
for(vector<Item>::iterator it2 = it->m_vecItems.begin();
it2 != it->m_vecItems.end(); it2++)
{
if(!recGroupBodyTarget.PtInRect(CPoint(recGroupItem.left,recGroupItem.top)))
break;
DrawGroupItem(hDrawDC,recGroupItem, it2);
recGroupItem.MoveToY(recGroupItem.bottom);
}
}
else
{
sz = 0;
}
if(it->m_bAnimationEnabled)
{
RenderAlphaBlend(hDC, tmpDC, recGroupBodyTarget, recGroupBodySource);
SelectObject(tmpDC,oldbmap);
DeleteObject(hbmap);
DeleteDC(tmpDC);
}
}
recGroupHeader.MoveToY(recGroupHeader.top + PDGroupSeparatorWidth + (sz * PDGroupItemHeight));
}
AdjustScrollBars(recGroupHeader);
}
void COXTaskPanel::AdjustScrollBars(CRect recGroupHeader)
{
CRect rect;
GetClientRect(&rect);
if(!(recGroupHeader.top + PDHeaderHeight < rect.bottom))
{
ShowScrollBar(SB_VERT,TRUE);
SCROLLINFO si = {0};
si.cbSize = sizeof SCROLLBARINFO;
si.fMask = SIF_PAGE|SIF_RANGE;
si.nMin = 0;
si.nMax = recGroupHeader.top;
si.nPage = rect.Height();
SetScrollInfo(SB_VERT, &si, TRUE);
}
else
ShowScrollBar(SB_VERT,FALSE);
}
bool COXTaskPanel::RenderAlphaBlend(HDC hDC, HDC tmpDC, CRect recGroupBodyTarget, CRect recGroupBodySource)
{
BLENDFUNCTION bf = {0};
bf.BlendOp = AC_SRC_OVER;
if(m_nAnimSteps>0)
bf.SourceConstantAlpha = (BYTE)((float)255 * (float)(NUMANIMSTEPS-m_nAnimSteps)/(float)NUMANIMSTEPS);
else
bf.SourceConstantAlpha = (BYTE)((float)255 * (float)(-m_nAnimSteps)/(float)NUMANIMSTEPS);
bf.SourceConstantAlpha = min(bf.SourceConstantAlpha, 128);
return !(FALSE == AlphaBlend(hDC,recGroupBodyTarget.left,recGroupBodyTarget.top,
recGroupBodyTarget.Width(),recGroupBodyTarget.Height(),
tmpDC,recGroupBodySource.left,recGroupBodySource.top,
recGroupBodySource.Width(),recGroupBodySource.Height(),bf));
}