3 #include "XPImageButton.h"
\r
6 IMPLEMENT_DYNAMIC(CXPImageButton, CButton)
\r
7 CXPImageButton::CXPImageButton()
\r
11 CXPImageButton::~CXPImageButton()
\r
15 BEGIN_MESSAGE_MAP(CXPImageButton, CButton)
\r
16 ON_NOTIFY_REFLECT (NM_CUSTOMDRAW, OnNotifyCustomDraw)
\r
19 void CXPImageButton::OnNotifyCustomDraw(NMHDR * pNotifyStruct, LRESULT* result)
\r
21 LPNMCUSTOMDRAW pCustomDraw = (LPNMCUSTOMDRAW)pNotifyStruct;
\r
22 ASSERT(pCustomDraw->hdr.hwndFrom == m_hWnd);
\r
24 DWORD style = GetStyle();
\r
25 if ((style & (BS_BITMAP | BS_ICON)) == 0 || !m_xpButton.IsAppThemed() || !m_xpButton.IsActive())
\r
27 // not an icon or bitmap. So just let windows handle its drawing.
\r
28 *result = CDRF_DODEFAULT;
\r
32 if (pCustomDraw->dwDrawStage == CDDS_PREERASE)
\r
34 m_xpButton.DrawParentBackground(m_hWnd, pCustomDraw->hdc, &pCustomDraw->rc);
\r
37 if (pCustomDraw->dwDrawStage == CDDS_PREERASE || pCustomDraw->dwDrawStage == CDDS_PREPAINT)
\r
39 m_xpButton.Open(m_hWnd, L"BUTTON");
\r
40 if (!m_xpButton.IsAppThemed() || !m_xpButton.IsActive())
\r
42 *result = CDRF_DODEFAULT;
\r
46 // find the state for DrawThemeBackground()
\r
47 int state_id = PBS_NORMAL;
\r
48 if (style & WS_DISABLED)
\r
49 state_id = PBS_DISABLED;
\r
50 else if (pCustomDraw->uItemState & CDIS_SELECTED)
\r
51 state_id = PBS_PRESSED;
\r
52 else if (pCustomDraw->uItemState & CDIS_HOT)
\r
54 else if (style & BS_DEFPUSHBUTTON)
\r
55 state_id = PBS_DEFAULTED;
\r
57 // draw themed button background according to the button state
\r
58 m_xpButton.DrawBackground(pCustomDraw->hdc, BP_PUSHBUTTON, state_id, &pCustomDraw->rc, NULL);
\r
60 CRect content_rect (pCustomDraw->rc);
\r
61 m_xpButton.GetBackgroundContentRect(pCustomDraw->hdc, BP_PUSHBUTTON, state_id, &pCustomDraw->rc, &content_rect);
\r
65 if (style & BS_BITMAP)
\r
67 DrawBitmap(pCustomDraw->hdc, &content_rect, style);
\r
71 ASSERT (style & BS_ICON);
\r
72 DrawIcon(pCustomDraw->hdc, &content_rect, style);
\r
75 // draw the focus rectangle if needed
\r
76 if (pCustomDraw->uItemState & CDIS_FOCUS)
\r
78 // draw focus rectangle
\r
79 DrawFocusRect(pCustomDraw->hdc, &content_rect);
\r
82 *result = CDRF_SKIPDEFAULT;
\r
87 *result = CDRF_DODEFAULT;
\r
90 void CXPImageButton::DrawBitmap(HDC hDC, const CRect& Rect, DWORD style)
\r
92 HBITMAP hBitmap = GetBitmap();
\r
93 if (hBitmap == NULL)
\r
96 // determine the size of the bitmap image
\r
98 memset (&bmi, 0, sizeof(BITMAPINFO));
\r
99 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
\r
100 GetDIBits(hDC, hBitmap, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
\r
102 // determine position of top-left corner of bitmap
\r
103 int x = ImageLeft(bmi.bmiHeader.biWidth, Rect, style);
\r
104 int y = ImageTop(bmi.bmiHeader.biHeight, Rect, style);
\r
107 DrawState(hDC, NULL, NULL, (LPARAM) hBitmap, 0, x, y, bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight,
\r
108 (style & WS_DISABLED) != 0 ? (DST_BITMAP | DSS_DISABLED) : (DST_BITMAP | DSS_NORMAL));
\r
111 void CXPImageButton::DrawIcon(HDC hDC, const CRect& Rect, DWORD style)
\r
113 HICON hIcon = GetIcon();
\r
117 // determine the size of the icon
\r
119 GetIconInfo(hIcon, &ii);
\r
121 memset(&bmi, 0, sizeof(BITMAPINFO));
\r
122 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
\r
125 if (ii.hbmColor != NULL)
\r
127 GetDIBits(hDC, ii.hbmColor, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
\r
128 cx = bmi.bmiHeader.biWidth;
\r
129 cy = bmi.bmiHeader.biHeight;
\r
133 GetDIBits(hDC, ii.hbmMask, 0, 0, NULL, &bmi, DIB_RGB_COLORS);
\r
134 cx = bmi.bmiHeader.biWidth;
\r
135 cy = bmi.bmiHeader.biHeight/2;
\r
138 // determine the position of the top-left corner of the icon
\r
139 int x = ImageLeft (cx, Rect, style);
\r
140 int y = ImageTop (cy, Rect, style);
\r
143 DrawState(hDC, NULL, NULL, (LPARAM) hIcon, 0, x, y, cx, cy,
\r
144 (style & WS_DISABLED) != 0 ? (DST_ICON | DSS_DISABLED) : (DST_ICON | DSS_NORMAL));
\r
146 DeleteObject(ii.hbmColor);
\r
148 DeleteObject(ii.hbmMask);
\r
151 int CXPImageButton::ImageLeft(int cx, const CRect& Rect, DWORD style) const
\r
153 // calculate the left position of the image so it is drawn on left, right or centered (the default)
\r
154 // as set by the style settings.
\r
156 if (cx > Rect.Width())
\r
158 else if ((style & BS_CENTER) == BS_LEFT)
\r
160 else if ((style & BS_CENTER) == BS_RIGHT)
\r
161 x = Rect.right - cx;
\r
163 x = Rect.left + (Rect.Width() - cx)/2;
\r
167 int CXPImageButton::ImageTop(int cy, const CRect& Rect, DWORD style) const
\r
169 // calculate the top position of the image so it is drawn on top, bottom or vertically centered (the default)
\r
170 // as set by the style settings.
\r
172 if (cy > Rect.Height())
\r
173 cy = Rect.Height();
\r
174 if ((style & BS_VCENTER) == BS_TOP)
\r
176 else if ((style & BS_VCENTER) == BS_BOTTOM)
\r
177 y = Rect.bottom - cy;
\r
179 y = Rect.top + (Rect.Height() - cy)/2;
\r