Skip to content
Snippets Groups Projects
button.c 15.8 KiB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
/* File: button.c -- Button type widgets
Alexandre Julliard's avatar
Alexandre Julliard committed
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
 * Copyright (C) 1993 Johannes Ruscheinski
 * Copyright (C) 1993 David Metcalfe
Alexandre Julliard's avatar
Alexandre Julliard committed
 * Copyright (C) 1994 Alexandre Julliard
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
static char Copyright1[] = "Copyright Johannes Ruscheinski, 1993";
static char Copyright2[] = "Copyright David Metcalfe, 1993";
Alexandre Julliard's avatar
Alexandre Julliard committed
static char Copyright3[] = "Copyright Alexandre Julliard, 1994";
Alexandre Julliard's avatar
Alexandre Julliard committed
*/
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
#include "win.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
#include "user.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
#include "syscolor.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
#include "graphics.h"
#include "button.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
#include "stddebug.h"
#include "debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
extern void DEFWND_SetText( HWND hwnd, LPSTR text );  /* windows/defwnd.c */

Alexandre Julliard's avatar
Alexandre Julliard committed
static void PB_Paint( HWND hWnd, HDC hDC, WORD action );
static void CB_Paint( HWND hWnd, HDC hDC, WORD action );
static void GB_Paint( HWND hWnd, HDC hDC, WORD action );
static void UB_Paint( HWND hWnd, HDC hDC, WORD action );
static void OB_Paint( HWND hWnd, HDC hDC, WORD action );
Alexandre Julliard's avatar
Alexandre Julliard committed
static void BUTTON_CheckAutoRadioButton(HWND hWnd);
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
#define MAX_BTN_TYPE  12
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
static 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 */
};

typedef void (*pfPaint)(HWND,HDC,WORD);

static pfPaint btnPaintFunc[MAX_BTN_TYPE] =
{
    PB_Paint,    /* BS_PUSHBUTTON */
    PB_Paint,    /* BS_DEFPUSHBUTTON */
    CB_Paint,    /* BS_CHECKBOX */
    CB_Paint,    /* BS_AUTOCHECKBOX */
    CB_Paint,    /* BS_RADIOBUTTON */
    CB_Paint,    /* BS_3STATE */
    CB_Paint,    /* BS_AUTO3STATE */
    GB_Paint,    /* BS_GROUPBOX */
    UB_Paint,    /* BS_USERBUTTON */
    CB_Paint,    /* BS_AUTORADIOBUTTON */
    NULL,        /* Not defined */
    OB_Paint     /* BS_OWNERDRAW */
Alexandre Julliard's avatar
Alexandre Julliard committed
};

Alexandre Julliard's avatar
Alexandre Julliard committed
#define PAINT_BUTTON(hwnd,style,action) \
     if (btnPaintFunc[style]) { \
         HDC hdc = GetDC( hwnd ); \
         (btnPaintFunc[style])(hwnd,hdc,action); \
         ReleaseDC( hwnd, hdc ); }

Alexandre Julliard's avatar
Alexandre Julliard committed
static HBITMAP hbitmapCheckBoxes = 0;
static WORD checkBoxWidth = 0, checkBoxHeight = 0;

Alexandre Julliard's avatar
Alexandre Julliard committed

LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
{
Alexandre Julliard's avatar
Alexandre Julliard committed
        RECT rect;
Alexandre Julliard's avatar
Alexandre Julliard committed
	LONG lResult = 0;
	WND *wndPtr = WIN_FindWndPtr(hWnd);
	LONG style = wndPtr->dwStyle & 0x0000000F;
Alexandre Julliard's avatar
Alexandre Julliard committed
        BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
Alexandre Julliard's avatar
Alexandre Julliard committed

	switch (uMsg) {
Alexandre Julliard's avatar
Alexandre Julliard committed
	case WM_GETDLGCODE:
                switch(style)
                {
                case BS_PUSHBUTTON:
                    return DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON;
                case BS_DEFPUSHBUTTON:
                    return DLGC_BUTTON | DLGC_DEFPUSHBUTTON;
                case BS_RADIOBUTTON:
                case BS_AUTORADIOBUTTON:
                    return DLGC_BUTTON | DLGC_RADIOBUTTON;
                default:
                    return DLGC_BUTTON;
                }

Alexandre Julliard's avatar
Alexandre Julliard committed
	case WM_ENABLE:
Alexandre Julliard's avatar
Alexandre Julliard committed
                PAINT_BUTTON( hWnd, style, ODA_DRAWENTIRE );
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

	case WM_CREATE:
Alexandre Julliard's avatar
Alexandre Julliard committed
		if (!hbitmapCheckBoxes)
		{
		    BITMAP bmp;
		    hbitmapCheckBoxes = LoadBitmap( 0, MAKEINTRESOURCE(OBM_CHECKBOXES) );
		    GetObject( hbitmapCheckBoxes, sizeof(bmp), (LPSTR)&bmp );
		    checkBoxWidth  = bmp.bmWidth / 4;
		    checkBoxHeight = bmp.bmHeight / 3;
		}
		
Alexandre Julliard's avatar
Alexandre Julliard committed
		if (style < 0L || style >= MAX_BTN_TYPE)
Alexandre Julliard's avatar
Alexandre Julliard committed
		    lResult = -1L;
		else
		{
Alexandre Julliard's avatar
Alexandre Julliard committed
                    infoPtr->state = BUTTON_UNCHECKED;
                    infoPtr->hFont = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
		    lResult = 0L;
		}
		break;

Alexandre Julliard's avatar
Alexandre Julliard committed
        case WM_ERASEBKGND:
                break;

Alexandre Julliard's avatar
Alexandre Julliard committed
	case WM_PAINT:
Alexandre Julliard's avatar
Alexandre Julliard committed
                if (btnPaintFunc[style])
                {
                    PAINTSTRUCT ps;
                    HDC hdc = BeginPaint( hWnd, &ps );
                    (btnPaintFunc[style])( hWnd, hdc, ODA_DRAWENTIRE );
                    ReleaseDC( hWnd, hdc );
                }
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

	case WM_LBUTTONDOWN:
Alexandre Julliard's avatar
Alexandre Julliard committed
                SendMessage( hWnd, BM_SETSTATE, TRUE, 0 );
                SetFocus( hWnd );
                SetCapture( hWnd );
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

	case WM_LBUTTONUP:
Alexandre Julliard's avatar
Alexandre Julliard committed
	        ReleaseCapture();
	        if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
Alexandre Julliard's avatar
Alexandre Julliard committed
                SendMessage( hWnd, BM_SETSTATE, FALSE, 0 );
                GetClientRect( hWnd, &rect );
                if (PtInRect( &rect, MAKEPOINT(lParam) ))
                {
                    switch(style)
                    {
                    case BS_AUTOCHECKBOX:
                        SendMessage( hWnd, BM_SETCHECK,
                                    !(infoPtr->state & BUTTON_CHECKED), 0 );
                        break;
                    case BS_AUTORADIOBUTTON:
                        SendMessage( hWnd, BM_SETCHECK, TRUE, 0 );
                        break;
                    case BS_AUTO3STATE:
                        SendMessage( hWnd, BM_SETCHECK,
                                     (infoPtr->state & BUTTON_3STATE) ? 0 :
                                     ((infoPtr->state & 3) + 1), 0 );
                        break;
                    }
                    SendMessage( GetParent(hWnd), WM_COMMAND,
                                 wndPtr->wIDmenu, MAKELPARAM(hWnd,BN_CLICKED));
                }
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

Alexandre Julliard's avatar
Alexandre Julliard committed
        case WM_MOUSEMOVE:
                if (GetCapture() == hWnd)
                {
                    GetClientRect( hWnd, &rect );
                    if (PtInRect( &rect, MAKEPOINT(lParam)) )
                       SendMessage( hWnd, BM_SETSTATE, TRUE, 0 );
                    else SendMessage( hWnd, BM_SETSTATE, FALSE, 0 );
                }
                break;
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
        case WM_NCHITTEST:
                if(style == BS_GROUPBOX) return HTTRANSPARENT;
                lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
                break;

Alexandre Julliard's avatar
Alexandre Julliard committed
        case WM_SETTEXT:
Alexandre Julliard's avatar
Alexandre Julliard committed
		DEFWND_SetText( hWnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
Alexandre Julliard's avatar
Alexandre Julliard committed
                PAINT_BUTTON( hWnd, style, ODA_DRAWENTIRE );
Alexandre Julliard's avatar
Alexandre Julliard committed
		return 0;

Alexandre Julliard's avatar
Alexandre Julliard committed
        case WM_SETFONT:
                infoPtr->hFont = wParam;
                if (lParam)
                    PAINT_BUTTON( hWnd, style, ODA_DRAWENTIRE );
                break;

        case WM_GETFONT:
                return infoPtr->hFont;

Alexandre Julliard's avatar
Alexandre Julliard committed
	case WM_SETFOCUS:
Alexandre Julliard's avatar
Alexandre Julliard committed
                infoPtr->state |= BUTTON_HASFOCUS;
                PAINT_BUTTON( hWnd, style, ODA_FOCUS );
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

	case WM_KILLFOCUS:
Alexandre Julliard's avatar
Alexandre Julliard committed
                infoPtr->state &= ~BUTTON_HASFOCUS;
                PAINT_BUTTON( hWnd, style, ODA_FOCUS );
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

	case WM_SYSCOLORCHANGE:
Alexandre Julliard's avatar
Alexandre Julliard committed
		InvalidateRect(hWnd, NULL, FALSE);
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

Alexandre Julliard's avatar
Alexandre Julliard committed
	case BM_SETSTYLE:
		if ((wParam & 0x0f) >= MAX_BTN_TYPE) break;
		wndPtr->dwStyle = (wndPtr->dwStyle & 0xfffffff0) 
		                   | (wParam & 0x0000000f);
                style = wndPtr->dwStyle & 0x0000000f;
                PAINT_BUTTON( hWnd, style, ODA_DRAWENTIRE );
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

	case BM_GETCHECK:
Alexandre Julliard's avatar
Alexandre Julliard committed
		lResult = infoPtr->state & 3;
		break;

	case BM_SETCHECK:
                if (wParam > maxCheckState[style])
                    wParam = maxCheckState[style];
		if ((infoPtr->state & 3) != wParam)
                {
                    infoPtr->state = (infoPtr->state & ~3) | wParam;
                    PAINT_BUTTON( hWnd, style, ODA_SELECT );
                }
Alexandre Julliard's avatar
Alexandre Julliard committed
		if(style == BS_AUTORADIOBUTTON && wParam==BUTTON_CHECKED)
			BUTTON_CheckAutoRadioButton(hWnd);
Alexandre Julliard's avatar
Alexandre Julliard committed
                break;

	case BM_GETSTATE:
		lResult = infoPtr->state;
Alexandre Julliard's avatar
Alexandre Julliard committed
		break;

Alexandre Julliard's avatar
Alexandre Julliard committed
	case BM_SETSTATE:
                if (!wParam != !(infoPtr->state & BUTTON_HIGHLIGHTED))
                {
                    if (wParam) infoPtr->state |= BUTTON_HIGHLIGHTED;
                    else infoPtr->state &= ~BUTTON_HIGHLIGHTED;
                    PAINT_BUTTON( hWnd, style, ODA_SELECT );
                }
                break;

Alexandre Julliard's avatar
Alexandre Julliard committed
	default:
		lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
		break;
	}

	return lResult;
}


/**********************************************************************
 *       Push Button Functions
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
static void PB_Paint( HWND hButton, HDC hDC, WORD action )
Alexandre Julliard's avatar
Alexandre Julliard committed
{
Alexandre Julliard's avatar
Alexandre Julliard committed
    RECT rc;
Alexandre Julliard's avatar
Alexandre Julliard committed
    HPEN hOldPen;
    HBRUSH hOldBrush;
Alexandre Julliard's avatar
Alexandre Julliard committed
    char *text;
Alexandre Julliard's avatar
Alexandre Julliard committed
    DWORD dwTextSize;
    int delta;
Alexandre Julliard's avatar
Alexandre Julliard committed
    TEXTMETRIC tm;
Alexandre Julliard's avatar
Alexandre Julliard committed
    WND *wndPtr = WIN_FindWndPtr( hButton );
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;

    GetClientRect(hButton, &rc);

      /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
    if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
    SendMessage( GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
                 MAKELPARAM(hButton, CTLCOLOR_BTN) );
    hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame);
    hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace);
    SetBkMode(hDC, TRANSPARENT);
    Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
    if (action == ODA_DRAWENTIRE)
Alexandre Julliard's avatar
Alexandre Julliard committed
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
        SetPixel( hDC, rc.left, rc.top, GetSysColor(COLOR_WINDOW) );
        SetPixel( hDC, rc.left, rc.bottom-1, GetSysColor(COLOR_WINDOW) );
        SetPixel( hDC, rc.right-1, rc.top, GetSysColor(COLOR_WINDOW) );
        SetPixel( hDC, rc.right-1, rc.bottom-1, GetSysColor(COLOR_WINDOW) );
Alexandre Julliard's avatar
Alexandre Julliard committed
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
    InflateRect( &rc, -1, -1 );
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    if ((wndPtr->dwStyle & 0x000f) == BS_DEFPUSHBUTTON)
Alexandre Julliard's avatar
Alexandre Julliard committed
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
        Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
        InflateRect( &rc, -1, -1 );
Alexandre Julliard's avatar
Alexandre Julliard committed
    if (infoPtr->state & BUTTON_HIGHLIGHTED)
Alexandre Julliard's avatar
Alexandre Julliard committed
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
        /* draw button shadow: */
        SelectObject(hDC, sysColorObjects.hbrushBtnShadow );
        PatBlt(hDC, rc.left, rc.top, 1, rc.bottom-rc.top, PATCOPY );
        PatBlt(hDC, rc.left, rc.top, rc.right-rc.left, 1, PATCOPY );
        rc.left += 2;  /* To position the text down and right */
        rc.top  += 2;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
    else GRAPH_DrawReliefRect( hDC, &rc, 2, 2, FALSE );
Alexandre Julliard's avatar
Alexandre Julliard committed
    
    /* draw button label, if any: */
Alexandre Julliard's avatar
Alexandre Julliard committed
    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
Alexandre Julliard's avatar
Alexandre Julliard committed
    if (text[0])
    {
        SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
                     GetSysColor(COLOR_GRAYTEXT) : GetSysColor(COLOR_BTNTEXT));
        DrawText(hDC, text, -1, &rc,
                 DT_SINGLELINE | DT_CENTER | DT_VCENTER);
        /* do we have the focus? */
        if (infoPtr->state & BUTTON_HASFOCUS)
        {
            dwTextSize = GetTextExtent(hDC, text, strlen(text) );
            delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
            rc.left += delta;
            rc.right -= delta;
            GetTextMetrics(hDC, &tm);
            delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
            rc.top += delta; 	rc.bottom -= delta;
            DrawFocusRect(hDC, &rc);
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
    SelectObject(hDC, (HANDLE)hOldPen);
    SelectObject(hDC, (HANDLE)hOldBrush);
Alexandre Julliard's avatar
Alexandre Julliard committed
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
 *       Check Box & Radio Button Functions
Alexandre Julliard's avatar
Alexandre Julliard committed
 */
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
static void CB_Paint( HWND hWnd, HDC hDC, WORD action )
Alexandre Julliard's avatar
Alexandre Julliard committed
{
    RECT rc;
Alexandre Julliard's avatar
Alexandre Julliard committed
    HBRUSH hBrush;
Alexandre Julliard's avatar
Alexandre Julliard committed
    int textlen, delta, x, y;
Alexandre Julliard's avatar
Alexandre Julliard committed
    char *text;
    TEXTMETRIC tm;
    SIZE size;
    WND *wndPtr = WIN_FindWndPtr(hWnd);
Alexandre Julliard's avatar
Alexandre Julliard committed
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    GetClientRect(hWnd, &rc);
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
Alexandre Julliard's avatar
Alexandre Julliard committed
    hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
			 MAKELPARAM(hWnd, CTLCOLOR_BTN));
Alexandre Julliard's avatar
Alexandre Julliard committed
    if (action == ODA_DRAWENTIRE) FillRect(hDC, &rc, hBrush);
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    GetTextMetrics(hDC, &tm);
    delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
Alexandre Julliard's avatar
Alexandre Julliard committed
    textlen = strlen( text );
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
      /* Draw the check-box bitmap */
    x = y = 0;
    if (infoPtr->state & BUTTON_HIGHLIGHTED) x += 2 * checkBoxWidth;
    if (infoPtr->state & (BUTTON_CHECKED | BUTTON_3STATE)) x += checkBoxWidth;
    if (((wndPtr->dwStyle & 0x0f) == BS_RADIOBUTTON) ||
        ((wndPtr->dwStyle & 0x0f) == BS_AUTORADIOBUTTON)) y += checkBoxHeight;
    else if (infoPtr->state & BUTTON_3STATE) y += 2 * checkBoxHeight;
    GRAPH_DrawBitmap( hDC, hbitmapCheckBoxes, rc.left, rc.top + delta,
Alexandre Julliard's avatar
Alexandre Julliard committed
                      x, y, checkBoxWidth, checkBoxHeight );
Alexandre Julliard's avatar
Alexandre Julliard committed
    rc.left += checkBoxWidth + tm.tmAveCharWidth / 2;

    if (action == ODA_DRAWENTIRE)
Alexandre Julliard's avatar
Alexandre Julliard committed
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
        if (wndPtr->dwStyle & WS_DISABLED)
            SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
        DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
Alexandre Julliard's avatar
Alexandre Julliard committed
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
    
    if ((action == ODA_FOCUS) ||
        ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
Alexandre Julliard's avatar
Alexandre Julliard committed
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
        GetTextExtentPoint(hDC, text, textlen, &size);
        rc.top += delta - 1;
        rc.bottom -= delta + 1;
        rc.left--;
        rc.right = rc.left + size.cx + 2;
        DrawFocusRect(hDC, &rc);
Alexandre Julliard's avatar
Alexandre Julliard committed
/**********************************************************************
 *       BUTTON_CheckAutoRadioButton
 *
 * hWnd is checked, uncheck everything else in group
 */
static void BUTTON_CheckAutoRadioButton(HWND hWnd)
{
    HWND parent = GetParent(hWnd);
    HWND sibling;
    for(sibling = GetNextDlgGroupItem(parent,hWnd,FALSE);
        sibling != hWnd;
        sibling = GetNextDlgGroupItem(parent,sibling,FALSE))
	    SendMessage(sibling,BM_SETCHECK,BUTTON_UNCHECKED,0);
}


Alexandre Julliard's avatar
Alexandre Julliard committed
/**********************************************************************
 *       Group Box Functions
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
static void GB_Paint( HWND hWnd, HDC hDC, WORD action )
Alexandre Julliard's avatar
Alexandre Julliard committed
{
    RECT rc;
    char *text;
    SIZE size;
Alexandre Julliard's avatar
Alexandre Julliard committed
    WND *wndPtr = WIN_FindWndPtr( hWnd );
Alexandre Julliard's avatar
Alexandre Julliard committed
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    if (action != ODA_DRAWENTIRE) return;
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
    SendMessage( GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
		 MAKELPARAM(hWnd, CTLCOLOR_BTN));
Alexandre Julliard's avatar
Alexandre Julliard committed
    SelectObject( hDC, sysColorObjects.hpenWindowFrame );
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    GetClientRect(hWnd, &rc);
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    MoveTo( hDC, rc.left, rc.top+2 );
    LineTo( hDC, rc.right-1, rc.top+2 );
Alexandre Julliard's avatar
Alexandre Julliard committed
    LineTo( hDC, rc.right-1, rc.bottom-1 );
Alexandre Julliard's avatar
Alexandre Julliard committed
    LineTo( hDC, rc.left, rc.bottom-1 );
    LineTo( hDC, rc.left, rc.top+2 );
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
Alexandre Julliard's avatar
Alexandre Julliard committed
    GetTextExtentPoint(hDC, text, strlen(text), &size);
    rc.left  += 10;
    rc.right  = rc.left + size.cx + 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
    rc.bottom = size.cy;
Alexandre Julliard's avatar
Alexandre Julliard committed
    if (wndPtr->dwStyle & WS_DISABLED)
        SetTextColor( hDC, GetSysColor(COLOR_GRAYTEXT) );
Alexandre Julliard's avatar
Alexandre Julliard committed
    DrawText(hDC, text, -1, &rc, DT_SINGLELINE );
Alexandre Julliard's avatar
Alexandre Julliard committed
}


/**********************************************************************
 *       User Button Functions
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
static void UB_Paint( HWND hWnd, HDC hDC, WORD action )
Alexandre Julliard's avatar
Alexandre Julliard committed
{
    RECT rc;
    HBRUSH hBrush;
Alexandre Julliard's avatar
Alexandre Julliard committed
    WND *wndPtr = WIN_FindWndPtr( hWnd );
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;

    if (action == ODA_SELECT) return;
Alexandre Julliard's avatar
Alexandre Julliard committed

    GetClientRect(hWnd, &rc);

Alexandre Julliard's avatar
Alexandre Julliard committed
    if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
Alexandre Julliard's avatar
Alexandre Julliard committed
    hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
			 MAKELPARAM(hWnd, CTLCOLOR_BTN));
    FillRect(hDC, &rc, hBrush);

Alexandre Julliard's avatar
Alexandre Julliard committed
    if ((action == ODA_FOCUS) ||
        ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS)))
        DrawFocusRect(hDC, &rc);
Alexandre Julliard's avatar
Alexandre Julliard committed
}
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed

/**********************************************************************
 *       Ownerdrawn Button Functions
 */

Alexandre Julliard's avatar
Alexandre Julliard committed
static void OB_Paint( HWND hWnd, HDC hDC, WORD action )
Alexandre Julliard's avatar
Alexandre Julliard committed
{
    HANDLE	hDis;
    LPDRAWITEMSTRUCT lpdis;
Alexandre Julliard's avatar
Alexandre Julliard committed
    WND *wndPtr = WIN_FindWndPtr( hWnd );
    BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
Alexandre Julliard's avatar
Alexandre Julliard committed

Alexandre Julliard's avatar
Alexandre Julliard committed
    if (!(hDis = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) ))) return;
    lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_LIN_ADDR(hDis);
Alexandre Julliard's avatar
Alexandre Julliard committed
    lpdis->CtlType    = ODT_BUTTON;
    lpdis->CtlID      = wndPtr->wIDmenu;
    lpdis->itemID     = 0;
    lpdis->itemAction = action;
    lpdis->itemState  = (infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0 |
                     (infoPtr->state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0 |
                     (wndPtr->dwStyle & WS_DISABLED) ? ODS_DISABLED : 0;
    lpdis->hwndItem   = hWnd;
    lpdis->hDC        = hDC;
Alexandre Julliard's avatar
Alexandre Julliard committed
    GetClientRect( hWnd, &lpdis->rcItem );
Alexandre Julliard's avatar
Alexandre Julliard committed
    lpdis->itemData   = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
    SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, USER_HEAP_SEG_ADDR(hDis) );
Alexandre Julliard's avatar
Alexandre Julliard committed
    USER_HEAP_FREE(hDis);
}