home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Softwarová Záchrana 3
/
Softwarova-zachrana-3.bin
/
TaskSwitchXP
/
TaskSwitchXP_1.0.26.exe
/
Source
/
ConfigTsXP
/
ownerdrawXp.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2004-08-30
|
11KB
|
383 lines
// ownerdrawXp.cpp
#include "stdafx.h"
#include "main.h"
#include "ownerdrawXp.h"
//-----------------------------------------------------------------
LRESULT CALLBACK _UxButtonProc(HWND, UINT, WPARAM, LPARAM);
BOOL LoadUxThemeDll();
void FreeUxThemeDll();
typedef HTHEME (WINAPI *OPENTHEMEDATA)(HWND, LPCWSTR);
typedef HRESULT (WINAPI *CLOSETHEMEDATA)(HTHEME);
typedef BOOL (WINAPI *ISTHEMEBACKGROUNDPARTIALLYTRANSPARENT)(HTHEME, int, int);
typedef HRESULT (WINAPI *DRAWTHEMEPARENTBACKGROUND)(HWND, HDC, RECT*);
typedef HRESULT (WINAPI *DRAWTHEMEBACKGROUND)(HTHEME, HDC, int, int, const RECT*, const RECT*);
OPENTHEMEDATA _pfnOpenThemeData = NULL;
CLOSETHEMEDATA _pfnCloseThemeData = NULL;
ISTHEMEBACKGROUNDPARTIALLYTRANSPARENT _pfnIsThemeBackgroundPartiallyTransparent = NULL;
DRAWTHEMEPARENTBACKGROUND _pfnDrawThemeParentBackground = NULL;
DRAWTHEMEBACKGROUND _pfnDrawThemeBackground = NULL;
ENABLETHEMEDIALOGTEXTURE g_pfnEnableThemeDialogTexture = NULL;
//-----------------------------------------------------------------
HINSTANCE _hinstUxThemeDll = NULL;
HTHEME _hthemeBtn = NULL;
WNDPROC _wpBtnProc = NULL;
//-----------------------------------------------------------------
BOOL LoadUxThemeDll(HWND hwnd) {
_ASSERT(_hinstUxThemeDll == NULL);
_hinstUxThemeDll = LoadLibrary(L"UxTheme.dll");
if (_hinstUxThemeDll) {
_pfnOpenThemeData = (OPENTHEMEDATA) \
GetProcAddress(_hinstUxThemeDll, "OpenThemeData");
if (_pfnOpenThemeData) {
_hthemeBtn = (_pfnOpenThemeData)(hwnd, L"Button");
_pfnCloseThemeData = (CLOSETHEMEDATA) \
GetProcAddress(_hinstUxThemeDll, "CloseThemeData");
_pfnIsThemeBackgroundPartiallyTransparent = (ISTHEMEBACKGROUNDPARTIALLYTRANSPARENT) \
GetProcAddress(_hinstUxThemeDll, "IsThemeBackgroundPartiallyTransparent");
_pfnDrawThemeParentBackground = (DRAWTHEMEPARENTBACKGROUND) \
GetProcAddress(_hinstUxThemeDll, "DrawThemeParentBackground");
_pfnDrawThemeBackground = (DRAWTHEMEBACKGROUND) \
GetProcAddress(_hinstUxThemeDll, "DrawThemeBackground");
g_pfnEnableThemeDialogTexture = (ENABLETHEMEDIALOGTEXTURE) \
GetProcAddress(_hinstUxThemeDll, "EnableThemeDialogTexture");
}
if (!_pfnOpenThemeData || !_pfnCloseThemeData ||
!_pfnIsThemeBackgroundPartiallyTransparent ||
!_pfnDrawThemeParentBackground || !_pfnDrawThemeBackground ||
!g_pfnEnableThemeDialogTexture || !_hthemeBtn) {
FreeUxThemeDll();
}
}
return(_hinstUxThemeDll != NULL);
}
//-----------------------------------------------------------------
void FreeUxThemeDll() {
if (_hinstUxThemeDll) {
if (_hthemeBtn) {
(_pfnCloseThemeData)(_hthemeBtn);
_hthemeBtn = NULL;
}
FreeLibrary(_hinstUxThemeDll);
_hinstUxThemeDll = NULL;
}
}
//-----------------------------------------------------------------
void InitOwnerDrawCtrls(HWND hwnd) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
GetClassInfoEx(g_hinstExe, WC_BUTTON, &wcex);
_wpBtnProc = wcex.lpfnWndProc;
LoadUxThemeDll(hwnd);
}
//-----------------------------------------------------------------
void UxThemeChanged(HWND hwnd) {
if (_hthemeBtn) {
(_pfnCloseThemeData)(_hthemeBtn);
_hthemeBtn = NULL;
}
if (!_hinstUxThemeDll)
LoadUxThemeDll(hwnd);
else {
if (_hinstUxThemeDll) {
_hthemeBtn = (_pfnOpenThemeData)(hwnd, L"Button");
}
}
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
typedef struct {
DWORD dwType;
LPARAM lParam1;
LPARAM lParam2;
BOOL fMouseOverBtn;
} UXBUTTON_DATA, *PUXBUTTON_DATA;
#define UXBTN_ICON16 1
#define UXBTN_COLOR 2
//-----------------------------------------------------------------
void SubClassUxIconButton(HWND hwndBtn, UINT idIcon, UINT idIconDisabled) {
SetWindowLong(hwndBtn, GWL_STYLE,
GetWindowLong(hwndBtn, GWL_STYLE) | BS_OWNERDRAW);
PUXBUTTON_DATA puxbd = new UXBUTTON_DATA;
puxbd->dwType = UXBTN_ICON16;
puxbd->fMouseOverBtn = FALSE;
if (idIcon) {
puxbd->lParam1 = (LPARAM)LoadIcon(g_hinstExe, MAKEINTRESOURCE(idIcon));
} else puxbd->lParam1 = NULL;
if (idIconDisabled) {
puxbd->lParam2 = (LPARAM)LoadIcon(g_hinstExe, MAKEINTRESOURCE(idIconDisabled));
} else puxbd->lParam2 = NULL;
SetWindowLongPtr(hwndBtn, GWLP_USERDATA, (LONG)(LONG_PTR)puxbd);
SetWindowLongPtr(hwndBtn, GWLP_WNDPROC, (LONG)(LONG_PTR)(WNDPROC)_UxButtonProc);
}
void SubClassUxColorButton(HWND hwndBtn, COLORREF cr) {
SetWindowLong(hwndBtn, GWL_STYLE,
GetWindowLong(hwndBtn, GWL_STYLE) | BS_OWNERDRAW);
PUXBUTTON_DATA puxbd = new UXBUTTON_DATA;
puxbd->dwType = UXBTN_COLOR;
puxbd->fMouseOverBtn = FALSE;
puxbd->lParam1 = (LPARAM)cr;
puxbd->lParam2 = NULL;
SetWindowLongPtr(hwndBtn, GWLP_USERDATA, (LONG)(LONG_PTR)puxbd);
SetWindowLongPtr(hwndBtn, GWLP_WNDPROC, (LONG)(LONG_PTR)(WNDPROC)_UxButtonProc);
}
//-----------------------------------------------------------------
void DrawUxButton(const DRAWITEMSTRUCT *pdi) {
PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
GetWindowLongPtr(pdi->hwndItem, GWLP_USERDATA);
_ASSERT(puxbd);
RECT itemRect = pdi->rcItem;
SetBkMode(pdi->hDC, TRANSPARENT);
if (_hthemeBtn) { // XP style
_ASSERT(_pfnIsThemeBackgroundPartiallyTransparent &&
_pfnDrawThemeParentBackground && _pfnDrawThemeBackground);
int iStateId = PBS_NORMAL;
if (pdi->itemState & ODS_DISABLED)
iStateId = PBS_DISABLED;
else if (pdi->itemState & ODS_SELECTED)
iStateId = PBS_PRESSED;
else if (puxbd->fMouseOverBtn)
iStateId = PBS_HOT;
else if (pdi->itemState & ODS_FOCUS)
iStateId = PBS_DEFAULTED;
if ((_pfnIsThemeBackgroundPartiallyTransparent)(_hthemeBtn, BP_PUSHBUTTON, iStateId))
(_pfnDrawThemeParentBackground)(pdi->hwndItem, pdi->hDC, &itemRect);
(_pfnDrawThemeBackground)(_hthemeBtn, pdi->hDC, BP_PUSHBUTTON, iStateId, &itemRect, NULL);
} else {
if (pdi->itemState & ODS_FOCUS) {
HBRUSH hbr = CreateSolidBrush(RGB(0,0,0));
FrameRect(pdi->hDC, &itemRect, hbr);
InflateRect(&itemRect, -1, -1);
DeleteObject(hbr);
}
FillRect(pdi->hDC, &itemRect, GetSysColorBrush(COLOR_BTNFACE));
if (pdi->itemState & ODS_SELECTED) { // draw pressed button
HBRUSH hbrBtnShadow = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW));
FrameRect(pdi->hDC, &itemRect, hbrBtnShadow);
DeleteObject(hbrBtnShadow);
} else { // draw non pressed button
DrawFrameControl(pdi->hDC, &itemRect, DFC_BUTTON,
(puxbd->fMouseOverBtn ? DFCS_BUTTONPUSH | DFCS_HOT : DFCS_BUTTONPUSH));
/* | ((pdi->itemState & ODS_SELECTED) ? DFCS_PUSHED : 0)*/
}
}
switch (puxbd->dwType) {
case UXBTN_ICON16: {
const int cxDlgUnit = LOWORD(GetDialogBaseUnits()),
cxSmIcon = 16,
cySmIcon = 16;
int x, y;
int xIcon = -1;
WCHAR szText[1024];
if (GetWindowText(pdi->hwndItem, szText, SIZEOF_ARRAY(szText))) {
SIZE sizeText;
int n = 0;
x = pdi->rcItem.left + cxSmIcon + cxDlgUnit + 6;
if (pdi->rcItem.right - x - 6 > 0) {
if (GetTextExtentExPoint(pdi->hDC, szText, lstrlen(szText),
pdi->rcItem.right - x - 6, &n, NULL, &sizeText)) {
if (n > 0 && szText[n] != L'\0') {
szText[n--] = L'\0';
for (int i = 0; i < 3; i++) {
if (n < 0) break;
szText[n--] = L'.';
}
}
sizeText.cx = min(sizeText.cx, pdi->rcItem.right - x - 6);
x = x + (pdi->rcItem.right - x - 6 - sizeText.cx) / 2;
xIcon = x - cxDlgUnit - cxSmIcon;
y = pdi->rcItem.top + (pdi->rcItem.bottom - pdi->rcItem.top - sizeText.cy) / 2;
if (pdi->itemState & ODS_SELECTED && !_hthemeBtn) {
x++;
y++;
}
DrawState(pdi->hDC, NULL, NULL, (LPARAM)szText, 0,
x, y, sizeText.cx, sizeText.cy, (pdi->itemState & ODS_DISABLED)
? DST_PREFIXTEXT | DSS_DISABLED : DST_PREFIXTEXT | DSS_NORMAL);
}
}
}
HICON hIcon = (pdi->itemState & ODS_DISABLED)
? (HICON)puxbd->lParam2 : (HICON)puxbd->lParam1;
if (hIcon) {
if (xIcon == -1) {
xIcon = pdi->rcItem.left + (pdi->rcItem.right - pdi->rcItem.left - cxSmIcon) / 2;
}
y = pdi->rcItem.top + (pdi->rcItem.bottom - pdi->rcItem.top - cySmIcon) / 2;
if (pdi->itemState & ODS_SELECTED && !_hthemeBtn) {
xIcon++;
y++;
}
DrawIconEx(pdi->hDC, xIcon, y,
hIcon, cxSmIcon, cySmIcon, 0, NULL, DI_NORMAL);
}
break;
}
case UXBTN_COLOR: {
RECT rc = pdi->rcItem;
InflateRect(&rc, -4, -4);
if (pdi->itemState & ODS_SELECTED && !_hthemeBtn)
OffsetRect(&rc, 1, 1);
if (!(pdi->itemState & ODS_DISABLED)) {
HBRUSH hbr = CreateSolidBrush((COLORREF)puxbd->lParam1);
FillRect(pdi->hDC, &rc, hbr);
DeleteObject(hbr);
FrameRect(pdi->hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
}
break;
}
default:
_ASSERT(FALSE);
}
if (pdi->itemState & ODS_FOCUS && !(pdi->itemState & ODS_NOFOCUSRECT)) {
InflateRect(&itemRect, -3, -3);
DrawFocusRect(pdi->hDC, &itemRect);
}
}
//-----------------------------------------------------------------
LRESULT CALLBACK _UxButtonProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_MOUSEMOVE: {
PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
GetWindowLongPtr(hwnd, GWLP_USERDATA);
_ASSERT(puxbd);
if (!puxbd->fMouseOverBtn) {
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hwnd;
tme.dwHoverTime = 0;
if (TrackMouseEvent(&tme)) {
puxbd->fMouseOverBtn = TRUE;
InvalidateRect(hwnd, NULL, TRUE);
}
}
break;
}
case WM_MOUSELEAVE: {
PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
GetWindowLongPtr(hwnd, GWLP_USERDATA);
_ASSERT(puxbd);
puxbd->fMouseOverBtn = FALSE;
InvalidateRect(hwnd, NULL, TRUE);
break;
}
/*case WM_SETCURSOR: {
HCURSOR hCursor = LoadCursor(NULL, IDC_HAND);
if (!hCursor)
hCursor = LoadCursor(NULL, IDC_ARROW);
SetCursor(hCursor);
return(TRUE);
//break;
}*/
case WM_LBUTTONDBLCLK:
PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);
return(0);
case WM_DESTROY: {
PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
GetWindowLongPtr(hwnd, GWLP_USERDATA);
_ASSERT(puxbd);
delete puxbd;
break;
}
}
return(CallWindowProc(_wpBtnProc, hwnd, uMsg, wParam, lParam));
}
//-----------------------------------------------------------------
void SetUxButtonColor(HWND hwndBtn, COLORREF cr) {
PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
GetWindowLongPtr(hwndBtn, GWLP_USERDATA);
_ASSERT(puxbd);
_ASSERT(puxbd->dwType == UXBTN_COLOR);
puxbd->lParam1 = (LPARAM)cr;
InvalidateRect(hwndBtn, NULL, TRUE);
}
COLORREF GetUxButtonColor(HWND hwndBtn) {
PUXBUTTON_DATA puxbd = (PUXBUTTON_DATA)(LONG_PTR)\
GetWindowLongPtr(hwndBtn, GWLP_USERDATA);
_ASSERT(puxbd);
_ASSERT(puxbd->dwType == UXBTN_COLOR);
return((COLORREF)puxbd->lParam1);
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------