You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
527 lines
13 KiB
C++
527 lines
13 KiB
C++
// XTPSkinDrawTools.cpp
|
|
//
|
|
// This file is a part of the XTREME SKINFRAMEWORK MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Common/Tmschema.h"
|
|
#include "Common/XTPVC80Helpers.h"
|
|
#include "Common/XTPImageManager.h"
|
|
|
|
#include "XTPSkinDrawTools.h"
|
|
#include "XTPSkinObject.h"
|
|
#include "XTPSkinManager.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
|
|
BOOL XTPFillSolidRect(HDC hdc, int x, int y, int cx, int cy, COLORREF clr)
|
|
{
|
|
COLORREF clrOld = ::SetBkColor(hdc, clr);
|
|
::ExtTextOut(hdc, 0, 0, ETO_OPAQUE, CRect(x, y, x + cx, y + cy), NULL, 0, NULL);
|
|
::SetBkColor(hdc, clrOld);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL XTPFillSolidRect(HDC hdc, LPRECT lprc, COLORREF clr)
|
|
{
|
|
COLORREF clrOld = ::SetBkColor(hdc, clr);
|
|
::ExtTextOut(hdc, 0, 0, ETO_OPAQUE, lprc, NULL, 0, NULL);
|
|
::SetBkColor(hdc, clrOld);
|
|
return TRUE;
|
|
}
|
|
|
|
void XTPFillSolidRect(HDC hdc, int x, int y, int cx, int cy, HBRUSH hBrush)
|
|
{
|
|
::FillRect(hdc, CRect(x, y, x + cx, y + cy), hBrush);
|
|
}
|
|
|
|
|
|
void AFX_CDECL XTPSkinFrameworkDrawFrame(HDC hdc, LPRECT lprc, int nSize, COLORREF clr)
|
|
{
|
|
XTPFillSolidRect(hdc, lprc->left, lprc->top, lprc->right - lprc->left - nSize, nSize, clr);
|
|
XTPFillSolidRect(hdc, lprc->left, lprc->top, nSize, lprc->bottom - lprc->top - nSize, clr);
|
|
XTPFillSolidRect(hdc, lprc->right, lprc->top, -nSize, lprc->bottom - lprc->top, clr);
|
|
XTPFillSolidRect(hdc, lprc->left, lprc->bottom, lprc->right - lprc->left, -nSize, clr);
|
|
}
|
|
|
|
void AFX_CDECL XTPSkinFrameworkDrawFrame(HDC hdc, LPRECT lprc, int nSize, HBRUSH hBrush)
|
|
{
|
|
XTPFillSolidRect(hdc, lprc->left, lprc->top, lprc->right - lprc->left - nSize, nSize, hBrush);
|
|
XTPFillSolidRect(hdc, lprc->left, lprc->top, nSize, lprc->bottom - lprc->top - nSize, hBrush);
|
|
XTPFillSolidRect(hdc, lprc->right - nSize, lprc->top, nSize, lprc->bottom - lprc->top, hBrush);
|
|
XTPFillSolidRect(hdc, lprc->left, lprc->bottom - nSize, lprc->right - lprc->left, nSize, hBrush);
|
|
}
|
|
|
|
|
|
DWORD DrawDiagonalLine(
|
|
HDC hdc,
|
|
LPRECT lprc,
|
|
int iDirection,
|
|
int iThickness,
|
|
UINT flags,
|
|
COLORREF clr)
|
|
{
|
|
RECT rc;
|
|
LPLONG py;
|
|
int cx;
|
|
int cy;
|
|
int dx;
|
|
int dy;
|
|
LPINT pc;
|
|
|
|
CXTPSkinManagerMetrics* pMetrics = XTPSkinManager()->GetMetrics();
|
|
|
|
if (IsRectEmpty(lprc))
|
|
return 0L;
|
|
|
|
rc = *lprc;
|
|
iThickness--;
|
|
|
|
cy = rc.bottom - rc.top;
|
|
cx = rc.right - rc.left;
|
|
|
|
if (!flags && (cy != cx))
|
|
cy -= iThickness * pMetrics->m_cyBorder;
|
|
|
|
if (cy >= cx)
|
|
{
|
|
cy /= cx;
|
|
pc = &cy;
|
|
|
|
cx = pMetrics->m_cxBorder;
|
|
|
|
}
|
|
else
|
|
{
|
|
cx /= cy;
|
|
pc = &cx;
|
|
|
|
cy = pMetrics->m_cyBorder;
|
|
}
|
|
|
|
dx = cx;
|
|
dy = iDirection * cy;
|
|
|
|
*pc = (*pc + iThickness) * pMetrics->m_cyBorder;
|
|
|
|
rc.right -= cx;
|
|
rc.bottom -= cy;
|
|
|
|
py = ((iDirection < 0) ? &rc.top : &rc.bottom);
|
|
|
|
while ((rc.left <= rc.right) && (rc.top <= rc.bottom))
|
|
{
|
|
if (!(flags & BF_MIDDLE))
|
|
{
|
|
XTPFillSolidRect(hdc, rc.left, *py, cx, cy, clr);
|
|
}
|
|
else
|
|
{
|
|
if (cy > pMetrics->m_cyBorder)
|
|
{
|
|
if (flags & BF_LEFT)
|
|
XTPFillSolidRect(hdc, rc.left, lprc->top, cx, *py - lprc->top + cy, clr);
|
|
else
|
|
XTPFillSolidRect(hdc, rc.left, *py, cx, lprc->bottom - *py, clr);
|
|
}
|
|
else
|
|
{
|
|
if (flags & BF_TOP)
|
|
XTPFillSolidRect(hdc, rc.left, *py, lprc->right - rc.left, cy, clr);
|
|
else
|
|
|
|
XTPFillSolidRect(hdc, lprc->left, *py, rc.left - lprc->left + cx, cy, clr);
|
|
}
|
|
}
|
|
|
|
rc.left += dx;
|
|
*py -= dy;
|
|
}
|
|
|
|
return MAKELONG(cx, cy);
|
|
}
|
|
|
|
|
|
BOOL DrawDiagonal(HDC hdc, LPRECT lprc, COLORREF clrTopLeft, COLORREF clrBottomRight, UINT flags)
|
|
{
|
|
int nDirection = 1;
|
|
|
|
switch (flags & (BF_RECT | BF_DIAGONAL))
|
|
{
|
|
case BF_DIAGONAL_ENDTOPLEFT:
|
|
case BF_DIAGONAL_ENDBOTTOMRIGHT:
|
|
nDirection = -1;
|
|
break;
|
|
}
|
|
|
|
DWORD dAdjust = DrawDiagonalLine(hdc, lprc, nDirection, 1, (flags & ~BF_MIDDLE),
|
|
((flags & BF_BOTTOM) ? clrBottomRight : clrTopLeft));
|
|
|
|
if (flags & BF_TOP)
|
|
lprc->left += LOWORD(dAdjust);
|
|
else
|
|
lprc->right -= LOWORD(dAdjust);
|
|
|
|
if (flags & BF_RIGHT)
|
|
lprc->top += HIWORD(dAdjust);
|
|
else
|
|
lprc->bottom -= HIWORD(dAdjust);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#ifndef BDR_OUTER
|
|
#define BDR_OUTER 0x0003
|
|
#endif
|
|
|
|
#ifndef BDR_INNER
|
|
#define BDR_INNER 0x000c
|
|
#endif
|
|
|
|
|
|
|
|
BOOL WINAPI XTRSkinFrameworkDrawEdge(HDC hdc, LPRECT lprc, UINT edge, UINT flags)
|
|
{
|
|
COLORREF clrTopLeft;
|
|
COLORREF clrBottomRight;
|
|
|
|
BOOL fResult = TRUE;
|
|
|
|
if (flags & BF_MONO)
|
|
flags |= BF_FLAT;
|
|
|
|
RECT rc = *lprc;
|
|
|
|
UINT bdrType = (edge & BDR_OUTER);
|
|
|
|
CXTPSkinManagerMetrics* pMetrics = XTPSkinManager()->GetMetrics();
|
|
|
|
if (bdrType)
|
|
{
|
|
|
|
DrawBorder:
|
|
|
|
if (flags & BF_FLAT)
|
|
{
|
|
if (flags & BF_MONO)
|
|
clrBottomRight = (bdrType & BDR_OUTER) ? pMetrics->GetColor(COLOR_WINDOWFRAME) : pMetrics->GetColor(COLOR_WINDOW);
|
|
else
|
|
clrBottomRight = (bdrType & BDR_OUTER) ? pMetrics->m_clrEdgeShadow : pMetrics->GetColor(COLOR_3DFACE);
|
|
|
|
clrTopLeft = clrBottomRight;
|
|
}
|
|
else
|
|
{
|
|
switch (bdrType)
|
|
{
|
|
case BDR_RAISEDOUTER:
|
|
clrTopLeft = ((flags & BF_SOFT) ? pMetrics->m_clrEdgeHighLight : pMetrics->GetColor(COLOR_3DLIGHT));
|
|
clrBottomRight = pMetrics->m_clrEdgeDkShadow;
|
|
break;
|
|
|
|
case BDR_RAISEDINNER:
|
|
clrTopLeft = ((flags & BF_SOFT) ? pMetrics->GetColor(COLOR_3DLIGHT) : pMetrics->m_clrEdgeHighLight);
|
|
clrBottomRight = pMetrics->m_clrEdgeShadow;
|
|
break;
|
|
|
|
case BDR_SUNKENOUTER:
|
|
clrTopLeft = ((flags & BF_SOFT) ? pMetrics->m_clrEdgeDkShadow : pMetrics->m_clrEdgeShadow);
|
|
clrBottomRight = pMetrics->m_clrEdgeHighLight;
|
|
break;
|
|
|
|
case BDR_SUNKENINNER:
|
|
clrTopLeft = ((flags & BF_SOFT) ? pMetrics->m_clrEdgeShadow : pMetrics->m_clrEdgeDkShadow);
|
|
clrBottomRight = pMetrics->GetColor(COLOR_3DLIGHT);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (flags & BF_DIAGONAL)
|
|
{
|
|
fResult = DrawDiagonal(hdc, &rc, clrTopLeft, clrBottomRight, flags);
|
|
}
|
|
else
|
|
{
|
|
if (flags & BF_RIGHT)
|
|
{
|
|
rc.right -= pMetrics->m_cxBorder;
|
|
XTPFillSolidRect(hdc, rc.right, rc.top, pMetrics->m_cxBorder, rc.bottom - rc.top, clrBottomRight);
|
|
}
|
|
if (flags & BF_BOTTOM)
|
|
{
|
|
rc.bottom -= pMetrics->m_cyBorder;
|
|
XTPFillSolidRect(hdc, rc.left, rc.bottom, rc.right - rc.left, pMetrics->m_cyBorder, clrBottomRight);
|
|
}
|
|
if (flags & BF_LEFT)
|
|
{
|
|
XTPFillSolidRect(hdc, rc.left, rc.top, pMetrics->m_cxBorder, rc.bottom - rc.top, clrTopLeft);
|
|
rc.left += pMetrics->m_cxBorder;
|
|
}
|
|
if (flags & BF_TOP)
|
|
{
|
|
XTPFillSolidRect(hdc, rc.left, rc.top, rc.right - rc.left, pMetrics->m_cyBorder, clrTopLeft);
|
|
rc.top += pMetrics->m_cyBorder;
|
|
}
|
|
fResult = TRUE;
|
|
}
|
|
}
|
|
|
|
bdrType = (edge & BDR_INNER);
|
|
|
|
if (bdrType)
|
|
{
|
|
edge &= ~BDR_INNER;
|
|
goto DrawBorder;
|
|
}
|
|
|
|
if (flags & BF_MIDDLE)
|
|
{
|
|
if (flags & BF_DIAGONAL)
|
|
fResult = FALSE; // TODO!
|
|
else
|
|
fResult = XTPFillSolidRect(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, ((flags & BF_MONO) ? pMetrics->GetColor(COLOR_WINDOW) : pMetrics->GetColor(COLOR_3DFACE)));
|
|
}
|
|
|
|
if (flags & BF_ADJUST)
|
|
*lprc = rc;
|
|
|
|
return fResult;
|
|
}
|
|
|
|
int AFX_CDECL XTPGetParentDCClipBox(HWND pwnd, HDC hdc, LPRECT lprc)
|
|
{
|
|
if (GetClipBox(hdc, lprc) == NULLREGION)
|
|
return FALSE;
|
|
|
|
if ((GetClassLongPtr(pwnd, GCL_STYLE) & CS_PARENTDC) == 0)
|
|
return TRUE;
|
|
|
|
RECT rc;
|
|
::GetClientRect(pwnd, &rc);
|
|
|
|
return IntersectRect(lprc, lprc, &rc);
|
|
}
|
|
|
|
BOOL WINAPI XTRSkinFrameworkDrawFrameControl(HDC hdc, LPRECT lprc, UINT uType, UINT uState)
|
|
{
|
|
CXTPSkinManager* pManager = XTPSkinManager();
|
|
|
|
if (uType == DFC_SCROLL && uState == DFCS_SCROLLSIZEGRIP)
|
|
{
|
|
XTPFillSolidRect(hdc, lprc, pManager->GetMetrics()->GetColor(COLOR_3DFACE));
|
|
|
|
CXTPSkinManagerClass* pClassScrollBar = pManager->GetSkinClass(NULL, _T("SCROLLBAR"));
|
|
pClassScrollBar->DrawThemeBackground(CDC::FromHandle(hdc), SBP_SIZEBOX, SZB_RIGHTALIGN, lprc);
|
|
|
|
return TRUE;
|
|
}
|
|
int nType = uState & 0xF;
|
|
|
|
if (uType == DFC_BUTTON && ((uState | DFCS_PUSHED | BF_ADJUST) == (DFCS_BUTTONPUSH | DFCS_PUSHED | BF_ADJUST)))
|
|
{
|
|
RECT rc = *lprc;
|
|
|
|
XTRSkinFrameworkDrawEdge(hdc, &rc,
|
|
(uState & (DFCS_PUSHED | DFCS_CHECKED)) ? EDGE_SUNKEN : EDGE_RAISED,
|
|
(UINT)(BF_ADJUST | BF_RECT));
|
|
|
|
XTPFillSolidRect(hdc, &rc, pManager->GetMetrics()->GetColor(COLOR_3DFACE));
|
|
|
|
if (uState & BF_ADJUST)
|
|
*lprc = rc;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
if ((uType == DFC_SCROLL) && (nType == DFCS_SCROLLLEFT || nType == DFCS_SCROLLRIGHT ||
|
|
nType == DFCS_SCROLLUP || nType == DFCS_SCROLLDOWN))
|
|
{
|
|
int nState = 1;
|
|
if (uState & DFCS_PUSHED) nState = 3;
|
|
if (uState & DFCS_INACTIVE) nState = 4;
|
|
|
|
CXTPSkinManagerClass* pClassScrollBar = pManager->GetSkinClass(NULL, _T("SCROLLBAR"));
|
|
pClassScrollBar->DrawThemeBackground(CDC::FromHandle(hdc), SBP_ARROWBTN, nType * 4 + nState, lprc);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void AFX_CDECL XTPSkinFrameworkGetIconSize(HICON hImage, int* pcx, int* pcy)
|
|
{
|
|
*pcx = 32;
|
|
*pcy = 32;
|
|
|
|
ICONINFO iconInfo;
|
|
if (!GetIconInfo(hImage, &iconInfo))
|
|
return;
|
|
|
|
BITMAP bm;
|
|
if (!GetObject(iconInfo.hbmMask, sizeof(BITMAP), &bm))
|
|
return;
|
|
|
|
*pcx = bm.bmWidth;
|
|
*pcy = bm.bmHeight;
|
|
|
|
if (!iconInfo.hbmColor)
|
|
{
|
|
*pcy /= 2;
|
|
}
|
|
|
|
if (iconInfo.hbmColor) DeleteObject(iconInfo.hbmColor);
|
|
if (iconInfo.hbmMask) DeleteObject(iconInfo.hbmMask);
|
|
}
|
|
|
|
|
|
HPALETTE XTPSkinFrameworkCreatePaletteFromDIBitmap(LPBITMAPINFO pbmi)
|
|
{
|
|
DWORD nNumColors = pbmi->bmiHeader.biClrUsed;
|
|
if (!nNumColors && pbmi->bmiHeader.biBitCount <= 8)
|
|
nNumColors = 1 << pbmi->bmiHeader.biBitCount;
|
|
|
|
if (!nNumColors)
|
|
return NULL;
|
|
|
|
PLOGPALETTE pLogPalette = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
|
|
if (!pLogPalette)
|
|
return NULL;
|
|
|
|
pLogPalette->palNumEntries = (WORD)nNumColors;
|
|
pLogPalette->palVersion = 0x300;
|
|
|
|
for (WORD i = 0; i < nNumColors; i++)
|
|
{
|
|
pLogPalette->palPalEntry[i].peBlue = pbmi->bmiColors[i].rgbBlue;
|
|
pLogPalette->palPalEntry[i].peRed = pbmi->bmiColors[i].rgbRed;
|
|
pLogPalette->palPalEntry[i].peGreen = pbmi->bmiColors[i].rgbGreen;
|
|
pLogPalette->palPalEntry[i].peFlags = 0;
|
|
}
|
|
|
|
HPALETTE hPalette = CreatePalette(pLogPalette);
|
|
|
|
free(pLogPalette);
|
|
|
|
return hPalette;
|
|
}
|
|
|
|
HBITMAP XTPSkinFrameworkCreateDDBFromPackedDIBitmap(LPBITMAPINFO pbmi, HPALETTE hPalette)
|
|
{
|
|
// Find out how big the bmiColors is
|
|
int nNumColors = (int)pbmi->bmiHeader.biClrUsed;
|
|
if (!nNumColors && pbmi->bmiHeader.biBitCount <= 8)
|
|
nNumColors = 1 << pbmi->bmiHeader.biBitCount;
|
|
|
|
LPVOID lpBits = &pbmi->bmiColors[nNumColors];
|
|
|
|
HDC hDC = GetDC(NULL);
|
|
HPALETTE hOldPal = SelectPalette(hDC, hPalette, FALSE);
|
|
|
|
HBITMAP hBitmap = CreateDIBitmap(hDC, &pbmi->bmiHeader, CBM_INIT, lpBits, pbmi, DIB_RGB_COLORS);
|
|
|
|
SelectPalette(hDC, hOldPal, FALSE);
|
|
ReleaseDC(NULL, hDC);
|
|
|
|
return hBitmap;
|
|
}
|
|
|
|
|
|
HBITMAP AFX_CDECL XTPSkinFrameworkLoadBitmap(HMODULE hModule, LPCTSTR lpszResourceName, BOOL& bAlpha)
|
|
{
|
|
if (CXTPImageManagerIcon::IsPngBitmapResource(hModule, lpszResourceName))
|
|
{
|
|
return CXTPImageManagerIcon::LoadBitmapFromResource(hModule, lpszResourceName, &bAlpha);
|
|
}
|
|
|
|
|
|
#define BitmapWidth(cx, bpp) (((((cx) * (bpp)) + 31) & ~31) >> 3)
|
|
|
|
HRSRC hResource = FindResource(hModule, lpszResourceName, RT_BITMAP);
|
|
if (hResource == NULL)
|
|
return NULL;
|
|
|
|
HGLOBAL hGlobal = LoadResource(hModule, hResource);
|
|
if (hGlobal == NULL)
|
|
return NULL;
|
|
|
|
LPBITMAPINFO pResourceInfo = (LPBITMAPINFO)::LockResource(hGlobal);
|
|
if (!pResourceInfo)
|
|
return NULL;
|
|
|
|
int biSizeImage = BitmapWidth(pResourceInfo->bmiHeader.biWidth,
|
|
pResourceInfo->bmiHeader.biBitCount) * pResourceInfo->bmiHeader.biHeight;
|
|
|
|
|
|
bAlpha = pResourceInfo->bmiHeader.biBitCount == 32;
|
|
HBITMAP hbmResult = NULL;
|
|
|
|
if (SizeofResource(hModule, hResource) >= int(biSizeImage + sizeof(BITMAPINFOHEADER)))
|
|
{
|
|
CDC dcSrc;
|
|
dcSrc.CreateCompatibleDC(NULL);
|
|
|
|
if (pResourceInfo->bmiHeader.biBitCount >= 24)
|
|
{
|
|
PBITMAPINFO pBitmapInfo = (PBITMAPINFO)malloc(sizeof(BITMAPINFOHEADER) + sizeof(COLORREF) * 3);
|
|
ASSERT(pBitmapInfo != NULL);
|
|
if (!pBitmapInfo)
|
|
return NULL;
|
|
|
|
MEMCPY_S(pBitmapInfo, &pResourceInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
|
|
pBitmapInfo->bmiHeader.biSizeImage = biSizeImage;
|
|
|
|
BYTE* pDestBits = NULL;
|
|
HBITMAP hBmp = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pDestBits, NULL, 0);
|
|
|
|
if (hBmp && pDestBits)
|
|
{
|
|
MEMCPY_S(pDestBits, &pResourceInfo->bmiColors, biSizeImage);
|
|
hbmResult = hBmp;
|
|
}
|
|
free(pBitmapInfo);
|
|
}
|
|
else
|
|
{
|
|
HPALETTE hPalette = XTPSkinFrameworkCreatePaletteFromDIBitmap(pResourceInfo);
|
|
|
|
hbmResult = XTPSkinFrameworkCreateDDBFromPackedDIBitmap(pResourceInfo, hPalette);
|
|
|
|
if (hPalette)
|
|
{
|
|
DeleteObject(hPalette);
|
|
}
|
|
}
|
|
}
|
|
|
|
UnlockResource(hGlobal);
|
|
FreeResource(hGlobal);
|
|
|
|
return hbmResult ;
|
|
}
|