[User32]
[reactos.git] / reactos / dll / win32 / user32 / controls / button.c
index 5dd03c0..8b4003b 100644 (file)
@@ -102,8 +102,6 @@ static void GB_Paint( HWND hwnd, HDC hDC, UINT action );
 static void UB_Paint( HWND hwnd, HDC hDC, UINT action );
 static void OB_Paint( HWND hwnd, HDC hDC, UINT action );
 static void BUTTON_CheckAutoRadioButton( HWND hwnd );
-static LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
-static LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
 
 #define MAX_BTN_TYPE  12
 
@@ -249,8 +247,8 @@ static BOOL button_update_uistate(HWND hwnd, BOOL unicode)
 /***********************************************************************
  *           ButtonWndProc_common
  */
-static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg,
-                                    WPARAM wParam, LPARAM lParam, BOOL unicode )
+LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
+                                  WPARAM wParam, LPARAM lParam, BOOL unicode )
 {
     RECT rect;
     POINT pt;
@@ -291,6 +289,13 @@ static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg,
         }
         if (btn_type >= MAX_BTN_TYPE)
             return -1; /* abort */
+
+        /* XP turns a BS_USERBUTTON into BS_PUSHBUTTON */
+        if (btn_type == BS_USERBUTTON )
+        {
+            style = (style & ~0x0f) | BS_PUSHBUTTON;
+            SetWindowLongPtrW( hWnd, GWL_STYLE, style );
+        }
         set_button_state( hWnd, BUTTON_UNCHECKED );
         button_update_uistate( hWnd, unicode );
         return 0;
@@ -474,9 +479,6 @@ static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg,
         InvalidateRect( hWnd, NULL, FALSE );
         break;
 
-#ifndef __REACTOS__
-    case BM_SETSTYLE16:
-#endif
     case BM_SETSTYLE:
         if ((wParam & 0x0f) >= MAX_BTN_TYPE) break;
         btn_type = wParam & 0x0f;
@@ -485,7 +487,7 @@ static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg,
 
         /* Only redraw if lParam flag is set.*/
         if (lParam)
-           paint_button( hWnd, btn_type, ODA_DRAWENTIRE );
+            InvalidateRect( hWnd, NULL, TRUE );
 
         break;
 
@@ -514,15 +516,9 @@ static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg,
     case BM_GETIMAGE:
         return GetWindowLongPtrW( hWnd, HIMAGE_GWL_OFFSET );
 
-#ifndef __REACTOS__
-    case BM_GETCHECK16:
-#endif
     case BM_GETCHECK:
         return get_button_state( hWnd ) & 3;
 
-#ifndef __REACTOS__
-    case BM_SETCHECK16:
-#endif
     case BM_SETCHECK:
         if (wParam > maxCheckState[btn_type]) wParam = maxCheckState[btn_type];
         state = get_button_state( hWnd );
@@ -541,15 +537,9 @@ static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg,
             BUTTON_CheckAutoRadioButton( hWnd );
         break;
 
-#ifndef __REACTOS__
-    case BM_GETSTATE16:
-#endif
     case BM_GETSTATE:
         return get_button_state( hWnd );
 
-#ifndef __REACTOS__
-    case BM_SETSTATE16:
-#endif
     case BM_SETSTATE:
         state = get_button_state( hWnd );
         if (wParam)
@@ -591,7 +581,7 @@ static LRESULT ButtonWndProc_common(HWND hWnd, UINT uMsg,
  * the passed HWND and calls the real window procedure (with a WND*
  * pointer pointing to the locked windowstructure).
  */
-static LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
 {
     if (!IsWindow( hWnd )) return 0;
     return ButtonWndProc_common( hWnd, uMsg, wParam, lParam, TRUE );
@@ -601,7 +591,7 @@ static LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 /***********************************************************************
  *           ButtonWndProcA
  */
-static LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
 {
     if (!IsWindow( hWnd )) return 0;
     return ButtonWndProc_common( hWnd, uMsg, wParam, lParam, FALSE );
@@ -839,7 +829,7 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, const RECT *rc)
  */
 static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
 {
-    RECT     rc, focus_rect, r;
+    RECT     rc, r;
     UINT     dtFlags, uState;
     HPEN     hOldPen;
     HBRUSH   hOldBrush;
@@ -871,11 +861,15 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
 
     if (get_button_type(style) == BS_DEFPUSHBUTTON)
     {
-        Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
+        if (action != ODA_FOCUS)
+            Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
        InflateRect( &rc, -1, -1 );
     }
 
-    uState = DFCS_BUTTONPUSH | DFCS_ADJUSTRECT;
+    /* completely skip the drawing if only focus has changed */
+    if (action == ODA_FOCUS) goto draw_focus;
+
+    uState = DFCS_BUTTONPUSH;
 
     if (style & BS_FLAT)
         uState |= DFCS_MONO;
@@ -892,8 +886,6 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
 
     DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
 
-    focus_rect = rc;
-
     /* draw button label */
     r = rc;
     dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &r);
@@ -904,21 +896,20 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
     if (pushedState)
        OffsetRect(&r, 1, 1);
 
-    IntersectClipRect(hDC, rc.left, rc.top, rc.right, rc.bottom);
-
     oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
 
     BUTTON_DrawLabel(hwnd, hDC, dtFlags, &r);
 
     SetTextColor( hDC, oldTxtColor );
 
-    if (state & BUTTON_HASFOCUS)
+draw_focus:
+    if ((action == ODA_FOCUS) ||
+        ((action == ODA_DRAWENTIRE) && (state & BUTTON_HASFOCUS)))
     {
         if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
         {
-            InflateRect( &focus_rect, -1, -1 );
-            IntersectRect(&focus_rect, &focus_rect, &rc);
-            DrawFocusRect( hDC, &focus_rect );
+            InflateRect( &rc, -2, -2 );
+            DrawFocusRect( hDC, &rc );
         }
     }
 
@@ -1165,6 +1156,8 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
         if (!(get_ui_state(hwnd) & UISF_HIDEFOCUS))
             DrawFocusRect( hDC, &rc );
     }
+
+    BUTTON_NOTIFY_PARENT( hwnd, BN_PAINT );
 }