OB_Paint /* BS_OWNERDRAW */
};
+/* The original code from user32 was kept in order to make it easier to bring changes from user32 */
#ifdef _USER32_
/*********************************************************************
* button class descriptor
IDC_ARROW, /* cursor */
0 /* brush */
};
-#endif
static inline LONG get_button_state( HWND hwnd )
#endif /* __REACTOS__ */
-#ifndef _USER32_
+static inline HFONT get_button_font( HWND hwnd )
+{
+ return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
+}
+
+static inline void set_button_font( HWND hwnd, HFONT font )
+{
+ SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, (LONG_PTR)font );
+}
+
+static inline UINT get_button_type( LONG window_style )
+{
+ return (window_style & BS_TYPEMASK);
+}
+
+/* paint a button of any type */
+static inline void paint_button( HWND hwnd, LONG style, UINT action )
+{
+ if (btnPaintFunc[style] && IsWindowVisible(hwnd))
+ {
+ HDC hdc = GetDC( hwnd );
+ btnPaintFunc[style]( hwnd, hdc, action );
+ ReleaseDC( hwnd, hdc );
+ }
+}
+
+#else
+
#define NtUserAlterWindowStyle SetWindowLongPtrW
+static inline void _SetButtonData(HWND hwnd, PBUTTON_DATA data)
+{
+ SetWindowLongPtrW( hwnd, 0, (LONG)data );
+}
+
HRGN set_control_clipping( HDC hdc, const RECT *rect )
{
RECT rc = *rect;
return hrgn;
}
-BOOL BUTTON_Paint(HTHEME theme, HWND hwnd, HDC hParamDC, UINT action);
+BOOL BUTTON_PaintWithTheme(HTHEME theme, HWND hwnd, HDC hParamDC, LPARAM prfFlag);
-#endif
+static inline LONG_PTR get_button_image(HWND hwnd)
+{
+ return _GetButtonData(hwnd)->image;
+}
+
+static inline LONG_PTR set_button_image(HWND hwnd, LONG_PTR image)
+{
+ PBUTTON_DATA data = _GetButtonData(hwnd);
+ LONG_PTR ret = data->image;
+ data->image = image;
+ return ret;
+}
+
+static inline LONG get_button_state( HWND hwnd )
+{
+ return _GetButtonData(hwnd)->state;
+}
+
+static inline void set_button_state( HWND hwnd, LONG state )
+{
+ _GetButtonData(hwnd)->state = state;
+}
+
+static __inline void set_ui_state( HWND hwnd, LONG flags )
+{
+ _GetButtonData(hwnd)->ui_state = flags;
+}
+
+static __inline LONG get_ui_state( HWND hwnd )
+{
+ return _GetButtonData(hwnd)->ui_state;
+}
static inline HFONT get_button_font( HWND hwnd )
{
- return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
+ return (HFONT)_GetButtonData(hwnd)->font;
}
static inline void set_button_font( HWND hwnd, HFONT font )
{
- SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, (LONG_PTR)font );
+ _GetButtonData(hwnd)->font = font;
}
static inline UINT get_button_type( LONG window_style )
/* paint a button of any type */
static inline void paint_button( HWND hwnd, LONG style, UINT action )
{
+ HTHEME theme = GetWindowTheme(hwnd);
+ RECT rc;
+ HDC hdc = GetDC( hwnd );
+ /* GetDC appears to give a dc with a clip rect that includes the whoe parent, not sure if it is correct or not. */
+ GetClientRect(hwnd, &rc);
+ IntersectClipRect (hdc, rc.left, rc. top, rc.right, rc.bottom);
+ if (theme && BUTTON_PaintWithTheme(theme, hwnd, hdc, 0))
+ {
+ ReleaseDC( hwnd, hdc );
+ return;
+ }
if (btnPaintFunc[style] && IsWindowVisible(hwnd))
{
- HDC hdc = GetDC( hwnd );
btnPaintFunc[style]( hwnd, hdc, action );
- ReleaseDC( hwnd, hdc );
}
+ ReleaseDC( hwnd, hdc );
}
+#endif
+
+
/* retrieve the button text; returned buffer must be freed by caller */
static inline WCHAR *get_button_text( HWND hwnd )
{
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
+#ifndef _USER32_
+ switch (uMsg)
+ {
+ case WM_NCCREATE:
+ {
+ PBUTTON_DATA data = HeapAlloc( GetProcessHeap(), 0, sizeof(BUTTON_DATA) );
+ if (!data)
+ {
+ ERR("Failed to alloc internal button data\n");
+ return -1;
+ }
+
+ memset(data, 0, sizeof(BUTTON_DATA));
+ SetRect(&data->rcTextMargin, 1,1,1,1);
+
+ _SetButtonData(hWnd, data);
+ break;
+ }
+ case WM_NCDESTROY:
+ {
+ PBUTTON_DATA data = _GetButtonData(hWnd);
+ if (!data)
+ {
+ ERR("No data");
+ return 0;
+ }
+ HeapFree( GetProcessHeap(), 0, data );
+ _SetButtonData(hWnd, NULL);
+ }
+ case WM_CREATE:
+ OpenThemeData(hWnd, WC_BUTTONW);
+ break;
+ case WM_DESTROY:
+ CloseThemeData (GetWindowTheme(hWnd));
+ break;
+ case WM_THEMECHANGED:
+ CloseThemeData (GetWindowTheme(hWnd));
+ OpenThemeData(hWnd, WC_BUTTONW);
+ InvalidateRect(hWnd, NULL, FALSE);
+ break;
+ case WM_MOUSEHOVER:
+ {
+ int state = (int)SendMessageW(hWnd, BM_GETSTATE, 0, 0);
+ set_button_state(hWnd, state|BST_HOT);
+ InvalidateRect(hWnd, NULL, FALSE);
+ break;
+ }
+ case WM_MOUSELEAVE:
+ {
+ int state = (int)SendMessageW(hWnd, BM_GETSTATE, 0, 0);
+ set_button_state(hWnd, state&(~BST_HOT));
+ InvalidateRect(hWnd, NULL, FALSE);
+ break;
+ }
+ case WM_MOUSEMOVE:
+ {
+ TRACKMOUSEEVENT mouse_event;
+ mouse_event.cbSize = sizeof(TRACKMOUSEEVENT);
+ mouse_event.dwFlags = TME_QUERY;
+ if(!TrackMouseEvent(&mouse_event) || !(mouse_event.dwFlags&(TME_HOVER|TME_LEAVE)))
+ {
+ mouse_event.dwFlags = TME_HOVER|TME_LEAVE;
+ mouse_event.hwndTrack = hWnd;
+ mouse_event.dwHoverTime = 1;
+ TrackMouseEvent(&mouse_event);
+ }
+ break;
+ }
+ case BCM_GETTEXTMARGIN:
+ {
+ RECT* prc = (RECT*)lParam;
+ PBUTTON_DATA data = _GetButtonData(hWnd);
+ if (!prc || !data)
+ return FALSE;
+ *prc = data->rcTextMargin;
+ return TRUE;
+ }
+ case BCM_SETTEXTMARGIN:
+ {
+ RECT* prc = (RECT*)lParam;
+ PBUTTON_DATA data = _GetButtonData(hWnd);
+ if (!prc || !data)
+ return FALSE;
+ data->rcTextMargin = *prc;
+ return TRUE;
+ }
+ case BCM_SETIMAGELIST:
+ {
+ BUTTON_IMAGELIST * pimldata = (BUTTON_IMAGELIST *)lParam;
+ PBUTTON_DATA data = _GetButtonData(hWnd);
+ if (!data || !pimldata || !pimldata->himl)
+ return FALSE;
+ data->imlData = *pimldata;
+ return TRUE;
+ }
+ case BCM_GETIMAGELIST:
+ {
+ BUTTON_IMAGELIST * pimldata = (BUTTON_IMAGELIST *)lParam;
+ PBUTTON_DATA data = _GetButtonData(hWnd);
+ if (!data|| !pimldata)
+ return FALSE;
+ *pimldata = data->imlData;
+ return TRUE;
+ }
+ }
+
+ if (!_GetButtonData(hWnd))
+ {
+ ERR("no data!\n");
+ return unicode ? DefWindowProcW(hWnd, uMsg, wParam, lParam) :
+ DefWindowProcA(hWnd, uMsg, wParam, lParam);
+ }
+
+#endif
+
switch (uMsg)
{
case WM_GETDLGCODE:
case WM_DESTROY:
break;
#endif
-
case WM_ERASEBKGND:
if (btn_type == BS_OWNERDRAW)
{
{
PAINTSTRUCT ps;
HDC hdc = wParam ? (HDC)wParam : BeginPaint( hWnd, &ps );
+#ifndef _USER32_
+ HTHEME theme = GetWindowTheme(hWnd);
+ if (theme && BUTTON_PaintWithTheme(theme, hWnd, hdc, uMsg == WM_PRINTCLIENT ? lParam : 0))
+ {
+ if ( !wParam ) EndPaint( hWnd, &ps );
+ return 0;
+ }
+#endif
if (btnPaintFunc[btn_type])
{
int nOldMode = SetBkMode( hdc, OPAQUE );
case WM_SETFOCUS:
TRACE("WM_SETFOCUS %p\n",hWnd);
set_button_state( hWnd, get_button_state(hWnd) | BST_FOCUS );
+#ifndef _USER32_
+ if (btn_type != BS_OWNERDRAW)
+ InvalidateRect(hWnd, NULL, FALSE);
+ else
+#endif
paint_button( hWnd, btn_type, ODA_FOCUS );
if (style & BS_NOTIFY)
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
TRACE("WM_KILLFOCUS %p\n",hWnd);
state = get_button_state( hWnd );
set_button_state( hWnd, state & ~BST_FOCUS );
+#ifdef _USER32_
paint_button( hWnd, btn_type, ODA_FOCUS );
+#endif
if ((state & BUTTON_BTNPRESSED) && GetCapture() == hWnd)
ReleaseCapture();
default:
return 0;
}
+#ifdef _USER32_
oldHbitmap = (HBITMAP)SetWindowLongPtrW( hWnd, HIMAGE_GWL_OFFSET, lParam );
+#else
+ oldHbitmap = (HBITMAP)set_button_image(hWnd, lParam );
+#endif
InvalidateRect( hWnd, NULL, FALSE );
return (LRESULT)oldHbitmap;
case BM_GETIMAGE:
+#ifdef _USER32_
return GetWindowLongPtrW( hWnd, HIMAGE_GWL_OFFSET );
+#else
+ return get_button_image(hWnd);
+#endif
case BM_GETCHECK:
return get_button_state( hWnd ) & 3;
if ((state & 3) != wParam)
{
set_button_state( hWnd, (state & ~3) | wParam );
+#ifdef _USER32
paint_button( hWnd, btn_type, ODA_SELECT );
+#else
+ InvalidateRect(hWnd, NULL, FALSE);
+#endif
}
if ((btn_type == BS_AUTORADIOBUTTON) && (wParam == BST_CHECKED) && (style & WS_CHILD))
BUTTON_CheckAutoRadioButton( hWnd );
else
set_button_state( hWnd, state & ~BST_PUSHED );
+#ifdef _USER32_
paint_button( hWnd, btn_type, ODA_SELECT );
+#else
+ InvalidateRect(hWnd, NULL, FALSE);
+#endif
break;
#ifdef __REACTOS__
}
case BS_ICON:
+#ifdef _USER32_
if (!GetIconInfo((HICON)GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET ), &iconInfo))
+#else
+ if (!GetIconInfo((HICON)get_button_image(hwnd), &iconInfo))
+#endif
goto empty_rect;
GetObjectW (iconInfo.hbmColor, sizeof(BITMAP), &bm);
break;
case BS_BITMAP:
+#ifdef _USER32_
if (!GetObjectW( (HANDLE)GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET ), sizeof(BITMAP), &bm))
+#else
+ if (!GetObjectW( (HANDLE)get_button_image(hwnd), sizeof(BITMAP), &bm))
+#endif
goto empty_rect;
r.right = r.left + bm.bmWidth;
case BS_ICON:
flags |= DST_ICON;
+#ifdef _USER32_
lp = GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET );
+#else
+ lp = get_button_image(hwnd);
+#endif
break;
case BS_BITMAP:
flags |= DST_BITMAP;
+#ifdef _USER32_
lp = GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET );
+#else
+ lp = get_button_image(hwnd);
+#endif
break;
default:
wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC;
wndClass.lpfnWndProc = ButtonWndProcW;
wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = NB_EXTRA_BYTES;
+ wndClass.cbWndExtra = sizeof(PBUTTON_DATA);
wndClass.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszClassName = WC_BUTTONW;