#include "stdafx.h"
|
#include "AccordionWnd.h"
|
|
|
#define ITEM_HEIGHT 32
|
#define ITEM_SPACE 5
|
#define TIMER_ID_CHECKHOVER 1
|
#define EXPAND_ICON_WIDE 16
|
|
#define BORDER 5
|
#define SHADOWWIDE 5
|
|
CAccordionWnd::CAccordionWnd()
|
{
|
m_hWnd = NULL;
|
m_crFrame = GetSysColor(COLOR_WINDOWFRAME);
|
m_crBkgnd = RGB(255, 255, 255);//GetSysColor(COLOR_BTNFACE); ;
|
m_nPadding[PADDING_LEFT] = 5;
|
m_nPadding[PADDING_TOP] = 5;
|
m_nPadding[PADDING_RIGHT] = 5;
|
m_nPadding[PADDING_BOTTOM] = 5;
|
m_crItemBackground[0] = RGB(218, 218, 218);
|
m_crItemBackground[1] = RGB(34, 177, 76);
|
m_crItemFrame[0] = RGB(128, 128, 128);
|
m_crItemFrame[1] = RGB(128, 128, 128);
|
m_crItemText[0] = RGB(68, 84, 111);
|
m_crItemText[1] = RGB(0, 0, 0);
|
m_crSeparateLine = RGB(222, 222, 222);
|
m_crHoverItemBackground = RGB(244, 245, 247);
|
m_crHoverItemFrame = RGB(200, 222, 255);
|
m_hIconExpand = NULL;
|
m_hIconClose = NULL;
|
m_nHoverItem = -1;
|
m_nCheckHoverItem = -1;
|
m_bShadow = FALSE;
|
m_crShadowBkgnd = GetSysColor(COLOR_BTNFACE);
|
}
|
|
|
CAccordionWnd::~CAccordionWnd()
|
{
|
for (size_t i = 0; i < m_vectorItems.size(); i++) {
|
delete m_vectorItems[i];
|
}
|
m_vectorItems.clear();
|
}
|
|
BOOL CAccordionWnd::RegisterWndClass()
|
{
|
WNDCLASS wc;
|
wc.lpszClassName = ACCORDIONWND_CLASS;
|
wc.hInstance = AfxGetInstanceHandle();
|
wc.lpfnWndProc = WindowProc;
|
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
wc.hIcon = 0;
|
wc.lpszMenuName = NULL;
|
wc.hbrBackground = NULL;
|
wc.style = CS_GLOBALCLASS | CS_DBLCLKS;
|
wc.cbClsExtra = 0;
|
wc.cbWndExtra = 0;
|
|
// ×¢²á×Ô¶¨ÒåÀà
|
return (::RegisterClass(&wc) != 0);
|
}
|
|
CAccordionWnd * CAccordionWnd::FromHandle(HWND hWnd)
|
{
|
CAccordionWnd *pAccordionWnd = (CAccordionWnd *)::GetProp(hWnd, ACCORDIONWND_TAG);
|
return pAccordionWnd;
|
}
|
|
CAccordionWnd* CAccordionWnd::Hook(HWND hWnd)
|
{
|
CAccordionWnd* pAccordionWnd = (CAccordionWnd*)GetProp(hWnd, ACCORDIONWND_TAG);
|
if (pAccordionWnd == NULL) {
|
pAccordionWnd = new CAccordionWnd();
|
pAccordionWnd->m_hWnd = hWnd;
|
|
SetProp(hWnd, ACCORDIONWND_TAG, (HANDLE)pAccordionWnd);
|
}
|
|
|
return pAccordionWnd;
|
}
|
|
void CAccordionWnd::LoadExpandIcon(CString strExpandFile, CString strCloseFile)
|
{
|
m_hIconExpand = (HICON)::LoadImage(AfxGetInstanceHandle(), strExpandFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE,
|
LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
|
m_hIconClose = (HICON)::LoadImage(AfxGetInstanceHandle(), strCloseFile, IMAGE_ICON, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE,
|
LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
|
}
|
|
void CAccordionWnd::Setpadding(int type, unsigned int nPadding)
|
{
|
if (type >= PADDING_LEFT && PADDING_LEFT <= PADDING_BOTTOM) {
|
m_nPadding[type] = nPadding;
|
}
|
}
|
|
void CAccordionWnd::SetDefaultItemBackgroundColor(COLORREF crNormal, COLORREF crSel)
|
{
|
m_crItemBackground[0] = crNormal;
|
m_crItemBackground[1] = crSel;
|
}
|
|
void CAccordionWnd::SetDefaultItemFrameColor(COLORREF crNormal, COLORREF crSel)
|
{
|
m_crItemFrame[0] = crNormal;
|
m_crItemFrame[1] = crSel;
|
}
|
|
void CAccordionWnd::SetDefaultItemTextColor(COLORREF crNormal, COLORREF crSel)
|
{
|
m_crItemText[0] = crNormal;
|
m_crItemText[1] = crSel;
|
}
|
|
void CAccordionWnd::Init()
|
{
|
}
|
|
void CAccordionWnd::Release()
|
{
|
// delete
|
delete this;
|
}
|
|
/*
|
* Ìí¼ÓÏîÄ¿
|
* pszName -- Ãû³Æ
|
* pWnd -- °ó¶¨µÄ´°¿Ú
|
* nExpandHeight -- Õ¹¿ª¸ß¶È£¬Èç¹ûΪ0Ôò×Ô¶¯ÉèÖÃΪ´°¿Ú¸ß
|
*/
|
void CAccordionWnd::AddItem(char *pszName, CWnd *pWnd, int nExpandHeight, BOOL bExpand/* = TRUE*/, BOOL bEnable/* = TRUE*/)
|
{
|
ACCORDIONITEM *pItem = new ACCORDIONITEM;
|
memset(pItem, 0, sizeof(ACCORDIONITEM));
|
pItem->pWnd = pWnd;
|
pItem->bExpand = bExpand;
|
pItem->bEnable = bEnable;
|
strcpy_s(pItem->text, sizeof(pItem->text), pszName);
|
if (nExpandHeight == 0) {
|
RECT rect;
|
pWnd->GetWindowRect(&rect);
|
pItem->nExpandHeight = rect.bottom - rect.top;
|
}
|
else if (nExpandHeight == -1) {
|
pItem->nExpandHeight = -1;
|
}
|
else {
|
pItem->nExpandHeight = nExpandHeight;
|
}
|
m_vectorItems.push_back(pItem);
|
|
|
// ÖØÐµ÷Õû¸ö×Ó´°¿ÚµÄλÖÃ
|
ResizeItemWnd();
|
}
|
|
void CAccordionWnd::ResizeItemWnd()
|
{
|
RECT rcClient, rcItemClient;
|
GetClientRect(m_hWnd, &rcClient);
|
|
for (size_t i = 0; i < m_vectorItems.size(); i++) {
|
ACCORDIONITEM *pItem = m_vectorItems.at(i);
|
if (pItem->pWnd != NULL) {
|
GetItemRect(rcClient, (UINT)i, &rcItemClient);
|
rcItemClient.top += ITEM_HEIGHT;
|
if (pItem->nExpandHeight == -1) {
|
rcItemClient.bottom = rcClient.bottom;
|
}
|
else {
|
rcItemClient.bottom = rcItemClient.top + pItem->nExpandHeight;
|
}
|
|
pItem->pWnd->MoveWindow(&rcItemClient);
|
pItem->pWnd->ShowWindow(pItem->bExpand ? SW_SHOW : SW_HIDE);
|
}
|
}
|
}
|
|
BOOL CAccordionWnd::GetItemHeaderRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect)
|
{
|
RECT rcItem;
|
if (!GetItemRect(rcClient, nIndex, &rcItem)) {
|
return FALSE;
|
}
|
|
rcItem.bottom = rcItem.top + ITEM_HEIGHT;
|
CopyRect(lpRect, &rcItem);
|
return TRUE;
|
}
|
|
BOOL CAccordionWnd::GetItemRect(RECT rcClient, unsigned int nIndex, LPRECT lpRect)
|
{
|
if (nIndex >= m_vectorItems.size()) {
|
return FALSE;
|
}
|
|
RECT rcItemHeader;
|
rcItemHeader.left = rcClient.left + m_nPadding[PADDING_LEFT];
|
rcItemHeader.right = rcClient.right - m_nPadding[PADDING_RIGHT];
|
rcItemHeader.top = rcClient.top + m_nPadding[PADDING_TOP];
|
rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
|
for (size_t i = 0; i < m_vectorItems.size(); i++) {
|
ACCORDIONITEM *pItem = m_vectorItems.at(i);
|
if (pItem->bExpand) {
|
rcItemHeader.bottom += pItem->nExpandHeight;
|
}
|
|
if (i == nIndex) {
|
break;;
|
}
|
|
rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE;
|
rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
|
}
|
|
|
CopyRect(lpRect, &rcItemHeader);
|
return TRUE;
|
}
|
|
int CAccordionWnd::HitTest(POINT pt, int &nHitTest)
|
{
|
int nRet = -1;
|
nHitTest = -1;
|
RECT rcClient;
|
GetClientRect(m_hWnd, &rcClient);
|
if (PtInRect(&rcClient, pt)) {
|
nRet = 1;
|
}
|
|
int nItemIndex = -1;
|
RECT rcItemHeader;
|
for (size_t i = 0; i < m_vectorItems.size(); i++) {
|
GetItemHeaderRect(rcClient, (unsigned int)i, &rcItemHeader);
|
|
if (PtInRect(&rcItemHeader, pt)) {
|
nItemIndex = (unsigned int)i;
|
|
break;
|
}
|
}
|
|
if (nItemIndex != -1) {
|
nRet = 2;
|
nHitTest = nItemIndex;
|
}
|
|
return nRet;
|
}
|
|
BOOL CAccordionWnd::Togle(unsigned int nIndex)
|
{
|
if (nIndex >= m_vectorItems.size()) {
|
return FALSE;
|
}
|
|
ACCORDIONITEM *pItem = m_vectorItems[nIndex];
|
pItem->bExpand = !pItem->bExpand;
|
|
|
// ÖØÐµ÷Õû¸ö×Ó´°¿ÚµÄλÖÃ
|
ResizeItemWnd();
|
|
RECT rcClient;
|
GetClientRect(m_hWnd, &rcClient);
|
::InvalidateRect(m_hWnd, &rcClient, TRUE);
|
|
return TRUE;
|
}
|
|
void CAccordionWnd::Notify(int nCode, int dwData, int dwData1/* = 0*/, int dwData2/* = 0*/)
|
{
|
HWND hParent;
|
hParent = GetParent(m_hWnd);
|
if (hParent != NULL) {
|
ACCORDION_NMHDR accordionWndnmhdr;
|
accordionWndnmhdr.nmhdr.hwndFrom = m_hWnd;
|
accordionWndnmhdr.nmhdr.idFrom = GetWindowLong(m_hWnd, GWL_ID);
|
accordionWndnmhdr.nmhdr.code = nCode;
|
accordionWndnmhdr.dwData = dwData;
|
accordionWndnmhdr.dwData1 = dwData1;
|
accordionWndnmhdr.dwData2 = dwData2;
|
SendMessage(hParent, WM_NOTIFY, (WPARAM)accordionWndnmhdr.nmhdr.idFrom, (LPARAM)&accordionWndnmhdr);
|
}
|
}
|
|
/*
|
* À¹½Ø´°¿ÚÏûÏ¢º¯Êý
|
*/
|
LRESULT CALLBACK CAccordionWnd::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
{
|
CAccordionWnd* pAccordionWnd = (CAccordionWnd *)GetProp(hWnd, ACCORDIONWND_TAG);
|
if (pAccordionWnd == NULL && uMsg != WM_NCCREATE)
|
{
|
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
|
}
|
|
|
// Èç¹ûHookÔòÏìÓ¦ÏûÏ¢
|
ASSERT(hWnd);
|
switch (uMsg)
|
{
|
case WM_NCCREATE:
|
return CAccordionWnd::OnNcCreate(hWnd, wParam, lParam);
|
|
case WM_DESTROY:
|
return pAccordionWnd->OnDestroy(wParam, lParam);
|
|
case WM_NCCALCSIZE:
|
return pAccordionWnd->OnNcCalcsize(wParam, lParam);
|
|
case WM_NCPAINT:
|
return pAccordionWnd->OnNcPaint(wParam, lParam);
|
|
case WM_PAINT:
|
return pAccordionWnd->OnPaint(wParam, lParam);
|
|
case WM_TIMER:
|
return pAccordionWnd->OnTimer(wParam, lParam);
|
|
case WM_MOUSEMOVE:
|
return pAccordionWnd->OnMouseMove(wParam, lParam);
|
|
case WM_LBUTTONDOWN:
|
return pAccordionWnd->OnLButtonDown(wParam, lParam);
|
|
case WM_LBUTTONUP:
|
return pAccordionWnd->OnLButtonUp(wParam, lParam);
|
|
case WM_MOUSEWHEEL:
|
return pAccordionWnd->OnMouseWheel(wParam, lParam);
|
|
case WM_SIZE:
|
return pAccordionWnd->OnSize(wParam, lParam);
|
|
case WM_GETDLGCODE:
|
return DLGC_WANTALLKEYS;
|
|
default:
|
break;
|
}
|
|
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
|
}
|
|
/*
|
* WM_NCCREATE
|
* ´°¿Ú´´½¨Ç°µÄ³õʼ»¯¹¤×÷
|
*/
|
LRESULT CAccordionWnd::OnNcCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
{
|
CAccordionWnd* pAccordionWnd = (CAccordionWnd *)GetProp(hWnd, ACCORDIONWND_TAG);
|
ASSERT(pAccordionWnd == NULL);
|
|
Hook(hWnd);
|
return ::DefWindowProc(hWnd, WM_NCCREATE, wParam, lParam);
|
}
|
|
/*
|
* WM_NCCALCSIZE
|
*/
|
LRESULT CAccordionWnd::OnNcCalcsize(WPARAM wParam, LPARAM lParam)
|
{
|
if (!m_bShadow) {
|
return ::DefWindowProc(m_hWnd, WM_NCCALCSIZE, wParam, lParam);
|
}
|
|
|
LPRECT lprcWnd = (LPRECT)lParam;
|
lprcWnd->left += BORDER;
|
lprcWnd->top += BORDER;
|
lprcWnd->right -= (BORDER + SHADOWWIDE);
|
lprcWnd->bottom -= (BORDER + SHADOWWIDE);
|
|
return 0;
|
}
|
|
/*
|
* WM_DESTROY
|
* ´°¿ÚÏú»Ùʱ
|
*/
|
LRESULT CAccordionWnd::OnDestroy(WPARAM wParam, LPARAM lParam)
|
{
|
Release();
|
return ::DefWindowProc(m_hWnd, WM_DESTROY, wParam, lParam);
|
}
|
|
|
/*
|
* WM_TIMER
|
*/
|
LRESULT CAccordionWnd::OnTimer(WPARAM wParam, LPARAM lParam)
|
{
|
int nTimerId = (int)wParam;
|
if (m_nTimerId == nTimerId) {
|
|
POINT pt;
|
::GetCursorPos(&pt);
|
::ScreenToClient(m_hWnd, &pt);
|
|
int nRet, nHitTest;
|
nRet = HitTest(pt, nHitTest);
|
if (m_nCheckHoverItem != nHitTest) {
|
KillTimer(m_hWnd, m_nTimerId);
|
m_nHoverItem = nHitTest;
|
m_nCheckHoverItem = nHitTest;
|
|
RECT rcClient;
|
GetClientRect(m_hWnd, &rcClient);
|
::InvalidateRect(m_hWnd, &rcClient, TRUE);
|
}
|
}
|
|
|
return ::DefWindowProc(m_hWnd, WM_TIMER, wParam, lParam);
|
}
|
|
/*
|
* WM_MOUSEMOVE
|
* Êó±êÒÆ¶¯Ê±£¬¼ì²âÊó±êλÖò¢»Øµ÷¸øÖ÷´°¿Ú
|
*/
|
LRESULT CAccordionWnd::OnMouseMove(WPARAM wParam, LPARAM lParam)
|
{
|
POINT pt;
|
pt.x = (int)LOWORD(lParam);
|
pt.y = (int)HIWORD(lParam);
|
|
int nRet, nHitTest;
|
nRet = HitTest(pt, nHitTest);
|
|
if (nRet == 2) {
|
ACCORDIONITEM *pItem = m_vectorItems[nHitTest];
|
if (pItem != NULL && pItem->bEnable) {
|
::SetCursor(LoadCursor(NULL, IDC_HAND));
|
}
|
}
|
else {
|
::SetCursor(LoadCursor(NULL, IDC_ARROW));
|
}
|
|
int nLastItem = m_nHoverItem;
|
if (m_nHoverItem != nHitTest) {
|
m_nHoverItem = nHitTest;
|
|
RECT rcClient, rcLastItemClient, rcCurItemClient;
|
GetClientRect(m_hWnd, &rcClient);
|
GetItemRect(rcClient, nLastItem, &rcLastItemClient);
|
::InvalidateRect(m_hWnd, &rcLastItemClient, nHitTest < 0);
|
|
if (nHitTest >= 0) {
|
ACCORDIONITEM *pItem = m_vectorItems.at(nHitTest);
|
if (!pItem->bEnable) {
|
m_nHoverItem = -1;
|
}
|
else {
|
KillTimer(m_hWnd, m_nTimerId);
|
m_nTimerId = SetTimer(m_hWnd, TIMER_ID_CHECKHOVER, 200, NULL);
|
m_nCheckHoverItem = m_nHoverItem;
|
|
GetItemRect(rcClient, m_nHoverItem, &rcCurItemClient);
|
::InvalidateRect(m_hWnd, &rcCurItemClient, TRUE);
|
}
|
}
|
}
|
|
|
return ::DefWindowProc(m_hWnd, WM_MOUSEMOVE, wParam, lParam);
|
}
|
|
/*
|
* WM_LBUTTONDOWN
|
* Êó±ê×ó¼üÏÂѹ
|
*/
|
LRESULT CAccordionWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam)
|
{
|
POINT pt;
|
pt.x = (int)LOWORD(lParam);
|
pt.y = (int)HIWORD(lParam);
|
|
int nRet, nHitTest;
|
nRet = HitTest(pt, nHitTest);
|
|
if (nRet == 2) {
|
ACCORDIONITEM *pItem = m_vectorItems[nHitTest];
|
if (pItem != NULL && pItem->bEnable) {
|
::SetCursor(LoadCursor(NULL, IDC_HAND));
|
}
|
}
|
else {
|
::SetCursor(LoadCursor(NULL, IDC_ARROW));
|
}
|
|
|
return ::DefWindowProc(m_hWnd, WM_LBUTTONDOWN, wParam, lParam);
|
}
|
|
/*
|
* WM_LBUTTONUP
|
* Êó±ê×ó¼üÊÍ·Å
|
*/
|
LRESULT CAccordionWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam)
|
{
|
POINT pt;
|
pt.x = (int)LOWORD(lParam);
|
pt.y = (int)HIWORD(lParam);
|
|
int nRet, nHitTest;
|
nRet = HitTest(pt, nHitTest);
|
|
if (nRet == 2) {
|
ACCORDIONITEM *pItem = m_vectorItems[nHitTest];
|
if (pItem != NULL && pItem->bEnable) {
|
::SetCursor(LoadCursor(NULL, IDC_HAND));
|
Togle(nHitTest);
|
}
|
}
|
else {
|
::SetCursor(LoadCursor(NULL, IDC_ARROW));
|
}
|
|
|
return ::DefWindowProc(m_hWnd, WM_LBUTTONUP, wParam, lParam);
|
}
|
|
/*
|
* WM_MOUSEWHEEL
|
* Êó±ê¹öÂÖ¹ö¶¯Ê±£¬Ëõ·ÅͼÏñ
|
*/
|
LRESULT CAccordionWnd::OnMouseWheel(WPARAM wParam, LPARAM lParam)
|
{
|
return ::DefWindowProc(m_hWnd, WM_MOUSEWHEEL, wParam, lParam);
|
}
|
|
/*
|
* WM_NCPAINT
|
*/
|
LRESULT CAccordionWnd::OnNcPaint(WPARAM wParam, LPARAM lParam)
|
{
|
LRESULT lRet = ::DefWindowProc(m_hWnd, WM_NCPAINT, wParam, lParam);
|
|
|
// È»ºó»±ß¿ò
|
long styleEx = GetWindowLong(m_hWnd, GWL_EXSTYLE);
|
if ((styleEx & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE) {
|
|
RECT rcWindow, rcClient;
|
GetClientRect(m_hWnd, &rcClient);
|
::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.left);
|
::ClientToScreen(m_hWnd, (LPPOINT)&rcClient.right);
|
GetWindowRect(m_hWnd, &rcWindow);
|
::OffsetRect(&rcClient, -rcWindow.left, -rcWindow.top);
|
::OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
|
|
HRGN hRgnWnd = CreateRectRgnIndirect(&rcWindow);
|
HRGN hRgnClient = CreateRectRgnIndirect(&rcClient);
|
|
HDC hDC = GetWindowDC(m_hWnd);
|
::SelectClipRgn(hDC, hRgnWnd);
|
::ExtSelectClipRgn(hDC, hRgnClient, RGN_DIFF);
|
|
|
// ûÓÐÒõÓ°µÄ±ß¿ò
|
if (!m_bShadow) {
|
HBRUSH hBrushBK, hBrushFrame;
|
hBrushBK = CreateSolidBrush(m_crBkgnd);
|
::FillRect(hDC, &rcWindow, hBrushBK);
|
DeleteObject(hBrushBK);
|
|
hBrushFrame = CreateSolidBrush(m_crFrame);
|
::FrameRect(hDC, &rcWindow, hBrushFrame);
|
DeleteObject(hBrushFrame);
|
}
|
|
// ÓÐÒõÓ°µÄ±ß¿ò
|
else {
|
|
RECT rcFrame0, rcFrame1;
|
rcFrame0.left = rcWindow.left + SHADOWWIDE;
|
rcFrame0.top = rcWindow.top + SHADOWWIDE;
|
rcFrame0.right = rcWindow.right;
|
rcFrame0.bottom = rcWindow.bottom;
|
rcFrame1.left = rcWindow.left;
|
rcFrame1.top = rcWindow.top;
|
rcFrame1.right = rcWindow.right - SHADOWWIDE;
|
rcFrame1.bottom = rcWindow.bottom - SHADOWWIDE;
|
|
|
// ±³¾°¿òºÍ¶Ô»°¿ò(¸¸´°Ìå)±³¾°É«Ò»ÖÂ
|
HBRUSH hBrushBK, hBrushFrame;
|
hBrushBK = CreateSolidBrush(m_crShadowBkgnd);
|
::FillRect(hDC, &rcWindow, hBrushBK);
|
DeleteObject(hBrushBK);
|
|
|
// ÒõÓ°¿ò
|
BYTE r = GetRValue(m_crShadowBkgnd);
|
BYTE g = GetGValue(m_crShadowBkgnd);
|
BYTE b = GetBValue(m_crShadowBkgnd);
|
BYTE rstep = (r - GetRValue(m_crFrame)) / SHADOWWIDE;
|
BYTE gstep = (r - GetGValue(m_crFrame)) / SHADOWWIDE;
|
BYTE bstep = (r - GetBValue(m_crFrame)) / SHADOWWIDE;
|
|
for (int i = 0; i < SHADOWWIDE; i++) {
|
hBrushBK = CreateSolidBrush(RGB(r - i*rstep, g - i*gstep, b - i*bstep));
|
::FillRect(hDC, &rcFrame0, hBrushBK);
|
DeleteObject(hBrushBK);
|
rcFrame0.bottom -= 1;
|
rcFrame0.right -= 1;
|
}
|
|
|
// ǰ¾°¿ò
|
hBrushBK = CreateSolidBrush(m_crBkgnd);
|
::FillRect(hDC, &rcFrame1, hBrushBK);
|
DeleteObject(hBrushBK);
|
|
hBrushFrame = CreateSolidBrush(m_crFrame);
|
::FrameRect(hDC, &rcFrame1, hBrushFrame);
|
DeleteObject(hBrushFrame);
|
}
|
|
|
::DeleteObject(hRgnWnd);
|
::DeleteObject(hRgnClient);
|
ReleaseDC(m_hWnd, hDC);
|
}
|
|
return lRet;
|
}
|
|
/*
|
* WM_PAINT
|
*/
|
LRESULT CAccordionWnd::OnPaint(WPARAM wParam, LPARAM lParam)
|
{
|
HDC hDC, hMemDC;
|
HBITMAP hBitmap;
|
RECT rcClient;
|
CString strText;
|
HFONT hFont;
|
HBRUSH hBrushBK;
|
|
|
// BeginPaint
|
PAINTSTRUCT ps;
|
hDC = BeginPaint(m_hWnd, &ps);
|
GetClientRect(m_hWnd, &rcClient);
|
|
hMemDC = ::CreateCompatibleDC(hDC);
|
hBitmap = ::CreateCompatibleBitmap(hDC, rcClient.right - rcClient.left,
|
rcClient.bottom - rcClient.top);
|
::SelectObject(hMemDC, hBitmap);
|
::SetBkMode(hMemDC, TRANSPARENT);
|
|
|
// ±³¾°ÑÕÉ«
|
hBrushBK = CreateSolidBrush(m_crBkgnd);
|
::FillRect(hMemDC, &rcClient, hBrushBK);
|
DeleteObject(hBrushBK);
|
|
|
// »æ×ÓÏîÁбí
|
hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
::SelectObject(hMemDC, hFont);
|
|
HPEN hPenSeparate = ::CreatePen(PS_SOLID, 1, m_crSeparateLine);
|
RECT rcItem, rcItemHeader;
|
for (size_t i = 0; i < m_vectorItems.size(); i++) {
|
ACCORDIONITEM *pItem = m_vectorItems[i];
|
GetItemRect(rcClient, (UINT)i, &rcItem);
|
GetItemHeaderRect(rcClient, (UINT)i, &rcItemHeader);
|
|
|
// ÈȵãÏîµÄ±³¾°É«ºÍ±ß¿ò
|
if (m_nHoverItem == (int)i) {
|
HBRUSH hbrItemHeaderBackground = CreateSolidBrush(m_crHoverItemBackground);
|
HBRUSH hbrItemFrame = CreateSolidBrush(m_crHoverItemFrame);
|
|
HRGN hRgn = CreateRoundRectRgn(rcItemHeader.left, rcItemHeader.top, rcItemHeader.right, rcItemHeader.bottom, 2, 2);
|
::FillRgn(hMemDC, hRgn, hbrItemHeaderBackground);
|
::FrameRgn(hMemDC, hRgn, hbrItemFrame, 1, 1);
|
::DeleteObject(hbrItemHeaderBackground);
|
::DeleteObject(hbrItemFrame);
|
::DeleteObject(hRgn);
|
}
|
|
|
// ¼ýÍ·
|
BOOL bDrawIcon = DrawIconEx(hMemDC, rcItemHeader.left + (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2, rcItemHeader.top + (ITEM_HEIGHT - EXPAND_ICON_WIDE)/2,
|
pItem->bExpand ? m_hIconExpand : m_hIconClose, EXPAND_ICON_WIDE, EXPAND_ICON_WIDE, 0, 0, DI_NORMAL);
|
|
|
// Îı¾
|
::SetTextColor(hMemDC, m_nHoverItem == (int)i ? m_crItemText[1] : m_crItemText[0]);
|
RECT rcText;
|
rcText.left = rcItemHeader.left + (bDrawIcon ? ITEM_HEIGHT : (ITEM_HEIGHT - EXPAND_ICON_WIDE) / 2);
|
rcText.top = rcItemHeader.top;
|
rcText.right = rcItemHeader.right;
|
rcText.bottom = rcItemHeader.bottom;
|
::DrawText(hMemDC, pItem->text, (int)strlen(pItem->text), &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
|
|
// Îı¾Óұ߷ָôÏß
|
SIZE sizeText;
|
GetTextExtentPoint32(hMemDC, pItem->text, (int)strlen(pItem->text), &sizeText);
|
|
|
HPEN hOldPen = (HPEN)::SelectObject(hMemDC, hPenSeparate);
|
MoveToEx(hMemDC, rcText.left + sizeText.cx + 10, rcItemHeader.top+(rcItemHeader.bottom- rcItemHeader.top-1)/2, NULL);
|
LineTo(hMemDC, rcItemHeader.right-10, rcItemHeader.top+(rcItemHeader.bottom - rcItemHeader.top - 1) / 2);
|
::SelectObject(hMemDC, hOldPen);
|
|
|
rcItemHeader.top = rcItemHeader.bottom + ITEM_SPACE;
|
rcItemHeader.bottom = rcItemHeader.top + ITEM_HEIGHT;
|
}
|
::DeleteObject(hPenSeparate);
|
|
|
// EndPaint
|
::BitBlt(hDC, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
|
hMemDC, 0, 0, SRCCOPY);
|
EndPaint(m_hWnd, &ps);
|
::DeleteObject(hBitmap);
|
::DeleteDC(hMemDC);
|
|
|
return 1;
|
}
|
|
/*
|
* WM_SIZE
|
*/
|
LRESULT CAccordionWnd::OnSize(WPARAM wParam, LPARAM lParam)
|
{
|
LRESULT lRet = ::DefWindowProc(m_hWnd, WM_SIZE, wParam, lParam);
|
|
ResizeItemWnd();
|
|
return lRet;
|
}
|
|
/*
|
* ÉèÖñ³¾°É«
|
* color -- ±³¾°É«
|
*/
|
void CAccordionWnd::SetBkgndColor(COLORREF color)
|
{
|
m_crBkgnd = color;
|
}
|
|
|
/*
|
* ÉèÖÃÒõÓ°µÄ±³¾°É«(¼´¸¸´°¿ÚµÄ±³¾°)
|
* color -- ±³¾°É«
|
*/
|
void CAccordionWnd::SetShadowBkgnd(COLORREF color)
|
{
|
m_crShadowBkgnd = color;
|
}
|
|
/*
|
* ÉèÖñ߿òÑÕÉ«
|
* color -- ±ß¿òÑÕÉ«
|
*/
|
void CAccordionWnd::SetFrameColor(COLORREF color, BOOL bShadow/* = FALSE*/)
|
{
|
m_crFrame = color;
|
m_bShadow = bShadow;
|
SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
|
}
|