Author: gadamopoulos
Date: Sun Jul 17 15:18:11 2011
New Revision: 52715
URL:
http://svn.reactos.org/svn/reactos?rev=52715&view=rev
Log:
[user32]
- Partly sync button handling with wine. Needed for hot tracking
Modified:
branches/GSoC_2011/ThemesSupport/dll/win32/user32/controls/button.c
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/user32/controls/button.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/user32/controls/button.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/user32/controls/button.c [iso-8859-1] Sun
Jul 17 15:18:11 2011
@@ -31,7 +31,6 @@
* Styles
* - BS_NOTIFY: is it complete?
* - BS_RIGHTBUTTON: same as BS_LEFTTEXT
- * - BS_TYPEMASK
*
* Messages
* - WM_CHAR: Checks a (manual or automatic) check box on '+' or '=',
clears it on '-' key.
@@ -72,17 +71,10 @@
#define STATE_GWL_OFFSET 0
#define HFONT_GWL_OFFSET (sizeof(LONG))
#define HIMAGE_GWL_OFFSET (HFONT_GWL_OFFSET+sizeof(HFONT))
-#define UISTATE_GWL_OFFSET (HIMAGE_GWL_OFFSET+sizeof(HFONT))
-#define NB_EXTRA_BYTES (UISTATE_GWL_OFFSET+sizeof(LONG))
-
- /* Button state values */
-#define BUTTON_UNCHECKED 0x00
-#define BUTTON_CHECKED 0x01
-#define BUTTON_3STATE 0x02
-#define BUTTON_HIGHLIGHTED 0x04
-#define BUTTON_HASFOCUS 0x08
+#define NB_EXTRA_BYTES (HIMAGE_GWL_OFFSET+sizeof(HANDLE))
+
+/* undocumented flags */
#define BUTTON_NSTATES 0x0F
- /* undocumented flags */
#define BUTTON_BTNPRESSED 0x40
#define BUTTON_UNKNOWN2 0x20
#define BUTTON_UNKNOWN3 0x10
@@ -103,22 +95,22 @@
static void OB_Paint( HWND hwnd, HDC hDC, UINT action );
static void BUTTON_CheckAutoRadioButton( HWND hwnd );
-#define MAX_BTN_TYPE 12
+#define MAX_BTN_TYPE 16
static const WORD maxCheckState[MAX_BTN_TYPE] =
{
- BUTTON_UNCHECKED, /* BS_PUSHBUTTON */
- BUTTON_UNCHECKED, /* BS_DEFPUSHBUTTON */
- BUTTON_CHECKED, /* BS_CHECKBOX */
- BUTTON_CHECKED, /* BS_AUTOCHECKBOX */
- BUTTON_CHECKED, /* BS_RADIOBUTTON */
- BUTTON_3STATE, /* BS_3STATE */
- BUTTON_3STATE, /* BS_AUTO3STATE */
- BUTTON_UNCHECKED, /* BS_GROUPBOX */
- BUTTON_UNCHECKED, /* BS_USERBUTTON */
- BUTTON_CHECKED, /* BS_AUTORADIOBUTTON */
- BUTTON_UNCHECKED, /* Not defined */
- BUTTON_UNCHECKED /* BS_OWNERDRAW */
+ BST_UNCHECKED, /* BS_PUSHBUTTON */
+ BST_UNCHECKED, /* BS_DEFPUSHBUTTON */
+ BST_CHECKED, /* BS_CHECKBOX */
+ BST_CHECKED, /* BS_AUTOCHECKBOX */
+ BST_CHECKED, /* BS_RADIOBUTTON */
+ BST_INDETERMINATE, /* BS_3STATE */
+ BST_INDETERMINATE, /* BS_AUTO3STATE */
+ BST_UNCHECKED, /* BS_GROUPBOX */
+ BST_UNCHECKED, /* BS_USERBUTTON */
+ BST_CHECKED, /* BS_AUTORADIOBUTTON */
+ BST_UNCHECKED, /* BS_PUSHBOX */
+ BST_UNCHECKED /* BS_OWNERDRAW */
};
typedef void (*pfPaint)( HWND hwnd, HDC hdc, UINT action );
@@ -135,7 +127,7 @@
GB_Paint, /* BS_GROUPBOX */
UB_Paint, /* BS_USERBUTTON */
CB_Paint, /* BS_AUTORADIOBUTTON */
- NULL, /* Not defined */
+ NULL, /* BS_PUSHBOX */
OB_Paint /* BS_OWNERDRAW */
};
@@ -169,17 +161,7 @@
SetWindowLongPtrW( hwnd, STATE_GWL_OFFSET, state );
}
-static __inline void set_ui_state( HWND hwnd, LONG flags )
-{
- SetWindowLongPtrW( hwnd, UISTATE_GWL_OFFSET, flags );
-}
-
-static __inline LONG get_ui_state( HWND hwnd )
-{
- return GetWindowLongPtrW( hwnd, UISTATE_GWL_OFFSET );
-}
-
-__inline static HFONT get_button_font( HWND hwnd )
+static inline HFONT get_button_font( HWND hwnd )
{
return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
}
@@ -191,7 +173,7 @@
static inline UINT get_button_type( LONG window_style )
{
- return (window_style & 0x0f);
+ return (window_style & BS_TYPEMASK);
}
/* paint a button of any type */
@@ -221,27 +203,6 @@
GetClientRect( hwnd, &rc );
DPtoLP( hdc, (POINT *)&rc, 2 );
IntersectClipRect( hdc, rc.left, rc.top, rc.right, rc.bottom );
-}
-
-/* Retrieve the UI state for the control */
-static BOOL button_update_uistate(HWND hwnd, BOOL unicode)
-{
- LONG flags, prevflags;
-
- if (unicode)
- flags = DefWindowProcW(hwnd, WM_QUERYUISTATE, 0, 0);
- else
- flags = DefWindowProcA(hwnd, WM_QUERYUISTATE, 0, 0);
-
- prevflags = get_ui_state(hwnd);
-
- if (prevflags != flags)
- {
- set_ui_state(hwnd, flags);
- return TRUE;
- }
-
- return FALSE;
}
/***********************************************************************
@@ -256,6 +217,7 @@
UINT btn_type = get_button_type( style );
LONG state;
HANDLE oldHbitmap;
+
#ifdef __REACTOS__
PWND pWnd;
@@ -268,6 +230,8 @@
}
}
#endif
+
+ if (!IsWindow( hWnd )) return 0;
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
@@ -305,11 +269,10 @@
/* XP turns a BS_USERBUTTON into BS_PUSHBUTTON */
if (btn_type == BS_USERBUTTON )
{
- style = (style & ~0x0f) | BS_PUSHBUTTON;
+ style = (style & ~BS_TYPEMASK) | BS_PUSHBUTTON;
SetWindowLongPtrW( hWnd, GWL_STYLE, style );
}
- set_button_state( hWnd, BUTTON_UNCHECKED );
- button_update_uistate( hWnd, unicode );
+ set_button_state( hWnd, BST_UNCHECKED );
return 0;
#ifdef __REACTOS__
@@ -384,7 +347,7 @@
if (!(state & BUTTON_BTNPRESSED)) break;
state &= BUTTON_NSTATES;
set_button_state( hWnd, state );
- if (!(state & BUTTON_HIGHLIGHTED))
+ if (!(state & BST_PUSHED))
{
ReleaseCapture();
break;
@@ -398,14 +361,14 @@
switch(btn_type)
{
case BS_AUTOCHECKBOX:
- SendMessageW( hWnd, BM_SETCHECK, !(state & BUTTON_CHECKED), 0 );
+ SendMessageW( hWnd, BM_SETCHECK, !(state & BST_CHECKED), 0 );
break;
case BS_AUTORADIOBUTTON:
SendMessageW( hWnd, BM_SETCHECK, TRUE, 0 );
break;
case BS_AUTO3STATE:
SendMessageW( hWnd, BM_SETCHECK,
- (state & BUTTON_3STATE) ? 0 : ((state & 3) + 1),
0 );
+ (state & BST_INDETERMINATE) ? 0 : ((state & 3) +
1), 0 );
break;
}
BUTTON_NOTIFY_PARENT(hWnd, BN_CLICKED);
@@ -419,7 +382,7 @@
{
state &= BUTTON_NSTATES;
set_button_state( hWnd, state );
- if (state & BUTTON_HIGHLIGHTED) SendMessageW( hWnd, BM_SETSTATE, FALSE, 0
);
+ if (state & BST_PUSHED) SendMessageW( hWnd, BM_SETSTATE, FALSE, 0 );
}
break;
@@ -474,7 +437,7 @@
case WM_SETFOCUS:
TRACE("WM_SETFOCUS %p\n",hWnd);
- set_button_state( hWnd, get_button_state(hWnd) | BUTTON_HASFOCUS );
+ set_button_state( hWnd, get_button_state(hWnd) | BST_FOCUS );
paint_button( hWnd, btn_type, ODA_FOCUS );
if (style & BS_NOTIFY)
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
@@ -483,7 +446,7 @@
case WM_KILLFOCUS:
TRACE("WM_KILLFOCUS %p\n",hWnd);
state = get_button_state( hWnd );
- set_button_state( hWnd, state & ~BUTTON_HASFOCUS );
+ set_button_state( hWnd, state & ~BST_FOCUS );
paint_button( hWnd, btn_type, ODA_FOCUS );
if ((state & BUTTON_BTNPRESSED) && GetCapture() == hWnd)
@@ -499,9 +462,9 @@
break;
case BM_SETSTYLE:
- if ((wParam & 0x0f) >= MAX_BTN_TYPE) break;
- btn_type = wParam & 0x0f;
- style = (style & ~0x0f) | btn_type;
+ if ((wParam & BS_TYPEMASK) >= MAX_BTN_TYPE) break;
+ btn_type = wParam & BS_TYPEMASK;
+ style = (style & ~BS_TYPEMASK) | btn_type;
SetWindowLongPtrW( hWnd, GWL_STYLE, style );
/* Only redraw if lParam flag is set.*/
@@ -552,7 +515,7 @@
set_button_state( hWnd, (state & ~3) | wParam );
paint_button( hWnd, btn_type, ODA_SELECT );
}
- if ((btn_type == BS_AUTORADIOBUTTON) && (wParam == BUTTON_CHECKED)
&& (style & WS_CHILD))
+ if ((btn_type == BS_AUTORADIOBUTTON) && (wParam == BST_CHECKED)
&& (style & WS_CHILD))
BUTTON_CheckAutoRadioButton( hWnd );
break;
@@ -562,26 +525,11 @@
case BM_SETSTATE:
state = get_button_state( hWnd );
if (wParam)
- {
- if (state & BUTTON_HIGHLIGHTED) break;
- set_button_state( hWnd, state | BUTTON_HIGHLIGHTED );
- }
+ set_button_state( hWnd, state | BST_PUSHED );
else
- {
- if (!(state & BUTTON_HIGHLIGHTED)) break;
- set_button_state( hWnd, state & ~BUTTON_HIGHLIGHTED );
- }
+ set_button_state( hWnd, state & ~BST_PUSHED );
+
paint_button( hWnd, btn_type, ODA_SELECT );
- break;
-
- case WM_UPDATEUISTATE:
- if (unicode)
- DefWindowProcW(hWnd, uMsg, wParam, lParam);
- else
- DefWindowProcA(hWnd, uMsg, wParam, lParam);
-
- if (button_update_uistate(hWnd, unicode))
- paint_button( hWnd, btn_type, ODA_DRAWENTIRE );
break;
case WM_NCHITTEST:
@@ -626,7 +574,7 @@
/* "Convert" pushlike buttons to pushbuttons */
if (style & BS_PUSHLIKE)
- style &= ~0x0F;
+ style &= ~BS_TYPEMASK;
if (!(style & BS_MULTILINE))
dtStyle |= DT_SINGLELINE;
@@ -699,9 +647,6 @@
}
DrawTextW(hdc, text, -1, &r, dtStyle | DT_CALCRECT);
HeapFree( GetProcessHeap(), 0, text );
-
- if (get_ui_state( hwnd ) & UISF_HIDEACCEL)
- dtStyle |= DT_HIDEPREFIX;
break;
case BS_ICON:
@@ -805,7 +750,7 @@
* I don't have Win31 on hand to verify that, so I leave it as is.
*/
- if ((style & BS_PUSHLIKE) && (state & BUTTON_3STATE))
+ if ((style & BS_PUSHLIKE) && (state & BST_INDETERMINATE))
{
hbr = GetSysColorBrush(COLOR_GRAYTEXT);
flags |= DSS_MONO;
@@ -818,10 +763,7 @@
lpOutputProc = BUTTON_DrawTextCallback;
if (!(text = get_button_text( hwnd ))) return;
lp = (LPARAM)text;
- wp = (WPARAM)dtFlags;
-
- if (dtFlags & DT_HIDEPREFIX)
- flags |= DSS_HIDEPREFIX;
+ wp = dtFlags;
break;
case BS_ICON:
@@ -857,7 +799,7 @@
HFONT hFont;
LONG state = get_button_state( hwnd );
LONG style = GetWindowLongPtrW( hwnd, GWL_STYLE );
- BOOL pushedState = (state & BUTTON_HIGHLIGHTED);
+ BOOL pushedState = (state & BST_PUSHED);
HWND parent;
GetClientRect( hwnd, &rc );
@@ -900,7 +842,7 @@
uState |= DFCS_PUSHED;
}
- if (state & (BUTTON_CHECKED | BUTTON_3STATE))
+ if (state & (BST_CHECKED | BST_INDETERMINATE))
uState |= DFCS_CHECKED;
DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
@@ -922,14 +864,10 @@
SetTextColor( hDC, oldTxtColor );
draw_focus:
- if ((action == ODA_FOCUS) ||
- ((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS)))
- {
- if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
- {
- InflateRect( &rc, -2, -2 );
- DrawFocusRect( hDC, &rc );
- }
+ if (action == ODA_FOCUS || (state & BST_FOCUS))
+ {
+ InflateRect( &rc, -2, -2 );
+ DrawFocusRect( hDC, &rc );
}
cleanup:
@@ -1008,11 +946,11 @@
if ((get_button_type(style) == BS_RADIOBUTTON) ||
(get_button_type(style) == BS_AUTORADIOBUTTON)) flags = DFCS_BUTTONRADIO;
- else if (state & BUTTON_3STATE) flags = DFCS_BUTTON3STATE;
+ else if (state & BST_INDETERMINATE) flags = DFCS_BUTTON3STATE;
else flags = DFCS_BUTTONCHECK;
- if (state & (BUTTON_CHECKED | BUTTON_3STATE)) flags |= DFCS_CHECKED;
- if (state & BUTTON_HIGHLIGHTED) flags |= DFCS_PUSHED;
+ if (state & (BST_CHECKED | BST_INDETERMINATE)) flags |= DFCS_CHECKED;
+ if (state & BST_PUSHED) flags |= DFCS_PUSHED;
if (style & WS_DISABLED) flags |= DFCS_INACTIVE;
@@ -1055,16 +993,12 @@
BUTTON_DrawLabel(hwnd, hDC, dtFlags, &rtext);
/* ... and focus */
- if ((action == ODA_FOCUS) ||
- ((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS)))
- {
- if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
- {
- rtext.left--;
- rtext.right++;
- IntersectRect(&rtext, &rtext, &client);
- DrawFocusRect( hDC, &rtext );
- }
+ if (action == ODA_FOCUS || (state & BST_FOCUS))
+ {
+ rtext.left--;
+ rtext.right++;
+ IntersectRect(&rtext, &rtext, &client);
+ DrawFocusRect( hDC, &rtext );
}
}
@@ -1085,8 +1019,8 @@
{
if (!sibling) break;
if ((hwnd != sibling) &&
- ((GetWindowLongPtrW( sibling, GWL_STYLE) & 0x0f) == BS_AUTORADIOBUTTON))
- SendMessageW( sibling, BM_SETCHECK, BUTTON_UNCHECKED, 0 );
+ ((GetWindowLongPtrW( sibling, GWL_STYLE) & BS_TYPEMASK) ==
BS_AUTORADIOBUTTON))
+ SendMessageW( sibling, BM_SETCHECK, BST_UNCHECKED, 0 );
sibling = GetNextDlgGroupItem( parent, sibling, FALSE );
} while (sibling != start);
}
@@ -1155,8 +1089,6 @@
LONG state = get_button_state( hwnd );
HWND parent;
- if (action == ODA_SELECT) return;
-
GetClientRect( hwnd, &rc);
if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont );
@@ -1169,14 +1101,23 @@
(WPARAM)hDC, (LPARAM)hwnd);
FillRect( hDC, &rc, hBrush );
- if ((action == ODA_FOCUS) ||
- ((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS)))
- {
- if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
- DrawFocusRect( hDC, &rc );
- }
-
- BUTTON_NOTIFY_PARENT( hwnd, BN_PAINT );
+ if (action == ODA_FOCUS || (state & BST_FOCUS))
+ DrawFocusRect( hDC, &rc );
+
+ switch (action)
+ {
+ case ODA_FOCUS:
+ BUTTON_NOTIFY_PARENT( hwnd, (state & BST_FOCUS) ? BN_SETFOCUS : BN_KILLFOCUS
);
+ break;
+
+ case ODA_SELECT:
+ BUTTON_NOTIFY_PARENT( hwnd, (state & BST_PUSHED) ? BN_HILITE : BN_UNHILITE
);
+ break;
+
+ default:
+ BUTTON_NOTIFY_PARENT( hwnd, BN_PAINT );
+ break;
+ }
}
@@ -1196,8 +1137,8 @@
dis.CtlID = id;
dis.itemID = 0;
dis.itemAction = action;
- dis.itemState = ((state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0) |
- ((state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0) |
+ dis.itemState = ((state & BST_FOCUS) ? ODS_FOCUS : 0) |
+ ((state & BST_PUSHED) ? ODS_SELECTED : 0) |
(IsWindowEnabled(hwnd) ? 0: ODS_DISABLED);
dis.hwndItem = hwnd;
dis.hDC = hDC;