/*
 * Progress control
 *
 * Copyright 1997, 2002 Dimitrie O. Paun
 * Copyright 1998, 1999 Eric Kohl
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * NOTE
 * 
 * This code was audited for completeness against the documented features
 * of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun.
 * 
 * Unless otherwise noted, we believe this code to be complete, as per
 * the specification mentioned above.
 * If you discover missing features, or bugs, please note them below.
 *
 */

#include <stdarg.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
#include "uxtheme.h"
#include "tmschema.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(progress);

typedef struct
{
    HWND      Self;         /* The window handle for this control */
    INT       CurVal;       /* Current progress value */
    INT       MinVal;       /* Minimum progress value */
    INT       MaxVal;       /* Maximum progress value */
    INT       Step;         /* Step to use on PMB_STEPIT */
    INT       MarqueePos;   /* Marquee animation position */
    BOOL      Marquee;      /* Whether the marquee animation is enabled */
    COLORREF  ColorBar;     /* Bar color */
    COLORREF  ColorBk;      /* Background color */
    HFONT     Font;         /* Handle to font (not unused) */
} PROGRESS_INFO;

/* Control configuration constants */

#define LED_GAP           2
#define MARQUEE_LEDS      5
#define ID_MARQUEE_TIMER  1

/* Helper to obtain size of a progress bar chunk ("led"). */
static inline int get_led_size ( PROGRESS_INFO *infoPtr, LONG style,
                                 const RECT* rect )
{
    HTHEME theme = GetWindowTheme (infoPtr->Self);
    if (theme)
    {
        int chunkSize;
        if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSCHUNKSIZE, &chunkSize )))
            return chunkSize;
    }

    if (style & PBS_VERTICAL)
        return MulDiv (rect->right - rect->left, 2, 3);
    else
        return MulDiv (rect->bottom - rect->top, 2, 3);
}

/* Helper to obtain gap between progress bar chunks */
static inline int get_led_gap ( PROGRESS_INFO *infoPtr )
{
    HTHEME theme = GetWindowTheme (infoPtr->Self);
    if (theme)
    {
        int spaceSize;
        if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSSPACESIZE, &spaceSize )))
            return spaceSize;
    }

    return LED_GAP;
}

/* Get client rect. Takes into account that theming needs no adjustment. */
static inline void get_client_rect (HWND hwnd, RECT* rect)
{
    HTHEME theme = GetWindowTheme (hwnd);
    GetClientRect (hwnd, rect);
    if (!theme)
        InflateRect(rect, -1, -1);
    else
    {
        DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
        int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR;
        GetThemeBackgroundContentRect (theme, 0, part, 0, rect, rect);
    }
}

/* Compute the extend of the bar */
static inline int get_bar_size( LONG style, const RECT* rect )
{
    if (style & PBS_VERTICAL)
        return rect->bottom - rect->top;
    else
        return rect->right - rect->left;
}

/* Compute the pixel position of a progress value */
static inline int get_bar_position( PROGRESS_INFO *infoPtr, LONG style,
                                    const RECT* rect, INT value )
{
    return MulDiv (value - infoPtr->MinVal, get_bar_size (style, rect),
                      infoPtr->MaxVal - infoPtr->MinVal);
}

/***********************************************************************
 * PROGRESS_Invalidate
 *
 * Don't be too clever about invalidating the progress bar.
 * InstallShield depends on this simple behaviour.
 */
static void PROGRESS_Invalidate( PROGRESS_INFO *infoPtr, INT old, INT new )
{
    InvalidateRect( infoPtr->Self, NULL, old > new );
}

/* Information for a progress bar drawing helper */
typedef struct tagProgressDrawInfo
{
    HDC hdc;
    RECT rect;
    HBRUSH hbrBar;
    HBRUSH hbrBk;
    int ledW, ledGap;
    HTHEME theme;
    RECT bgRect;
} ProgressDrawInfo;

typedef void (*ProgressDrawProc)(const ProgressDrawInfo* di, int start, int end);

/* draw solid horizontal bar from 'start' to 'end' */
static void draw_solid_bar_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.right = di->rect.left + end;
    r.bottom = di->rect.bottom;
    FillRect (di->hdc, &r, di->hbrBar);
}

/* draw solid horizontal background from 'start' to 'end' */
static void draw_solid_bkg_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.right = di->rect.left + end;
    r.bottom = di->rect.bottom;
    FillRect (di->hdc, &r, di->hbrBk);
}

/* draw solid vertical bar from 'start' to 'end' */
static void draw_solid_bar_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left;
    r.top = di->rect.bottom - end;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    FillRect (di->hdc, &r, di->hbrBar);
}

/* draw solid vertical background from 'start' to 'end' */
static void draw_solid_bkg_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left;
    r.top = di->rect.bottom - end;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    FillRect (di->hdc, &r, di->hbrBk);
}

/* draw chunky horizontal bar from 'start' to 'end' */
static void draw_chunk_bar_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    int right = di->rect.left + end;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.bottom = di->rect.bottom;
    while (r.left < right)
    {
        r.right = min (r.left + di->ledW, right);
        FillRect (di->hdc, &r, di->hbrBar);
        r.left = r.right;
        r.right = min (r.left + di->ledGap, right);
        FillRect (di->hdc, &r, di->hbrBk);
        r.left = r.right;
    }
}

/* draw chunky vertical bar from 'start' to 'end' */
static void draw_chunk_bar_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    int top = di->rect.bottom - end;
    r.left = di->rect.left;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    while (r.bottom > top)
    {
        r.top = max (r.bottom - di->ledW, top);
        FillRect (di->hdc, &r, di->hbrBar);
        r.bottom = r.top;
        r.top = max (r.bottom - di->ledGap, top);
        FillRect (di->hdc, &r, di->hbrBk);
        r.bottom = r.top;
    }
}

/* drawing functions for "classic" style */
static const ProgressDrawProc drawProcClassic[8] = {
  /* Smooth */
    /* Horizontal */
    draw_solid_bar_H, draw_solid_bkg_H,
    /* Vertical */
    draw_solid_bar_V, draw_solid_bkg_V,
  /* Chunky */
    /* Horizontal */
    draw_chunk_bar_H, draw_solid_bkg_H,
    /* Vertical */
    draw_chunk_bar_V, draw_solid_bkg_V,
};

/* draw themed horizontal bar from 'start' to 'end' */
static void draw_theme_bar_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    int right = di->rect.left + end;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.bottom = di->rect.bottom;
    while (r.left < right)
    {
        r.right = min (r.left + di->ledW, right);
        DrawThemeBackground (di->theme, di->hdc, PP_CHUNK, 0, &r, NULL);
        r.left = r.right;
        r.right = min (r.left + di->ledGap, right);
        DrawThemeBackground (di->theme, di->hdc, PP_BAR, 0, &di->bgRect, &r);
        r.left = r.right;
    }
}

/* draw themed horizontal bar from 'start' to 'end' */
static void draw_theme_bar_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    int top = di->rect.bottom - end;
    r.left = di->rect.left;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    while (r.bottom > top)
    {
        r.top = max (r.bottom - di->ledW, top);
        DrawThemeBackground (di->theme, di->hdc, PP_CHUNKVERT, 0, &r, NULL);
        r.bottom = r.top;
        r.top = max (r.bottom - di->ledGap, top);
        DrawThemeBackground (di->theme, di->hdc, PP_BARVERT, 0, &di->bgRect, &r);
        r.bottom = r.top;
    }
}

/* draw themed horizontal background from 'start' to 'end' */
static void draw_theme_bkg_H (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left + start;
    r.top = di->rect.top;
    r.right = di->rect.left + end;
    r.bottom = di->rect.bottom;
    DrawThemeBackground (di->theme, di->hdc, PP_BAR, 0, &di->bgRect, &r);
}

/* draw themed vertical background from 'start' to 'end' */
static void draw_theme_bkg_V (const ProgressDrawInfo* di, int start, int end)
{
    RECT r;
    r.left = di->rect.left;
    r.top = di->rect.bottom - end;
    r.right = di->rect.right;
    r.bottom = di->rect.bottom - start;
    DrawThemeBackground (di->theme, di->hdc, PP_BARVERT, 0, &di->bgRect, &r);
}

/* drawing functions for themed style */
static const ProgressDrawProc drawProcThemed[8] = {
  /* Smooth */
    /* Horizontal */
    draw_theme_bar_H, draw_theme_bkg_H,
    /* Vertical */
    draw_theme_bar_V, draw_theme_bkg_V,
  /* Chunky */
    /* Horizontal */
    draw_theme_bar_H, draw_theme_bkg_H,
    /* Vertical */
    draw_theme_bar_V, draw_theme_bkg_V,
};

/***********************************************************************
 * PROGRESS_Draw
 * Draws the progress bar.
 */
static LRESULT PROGRESS_Draw (PROGRESS_INFO *infoPtr, HDC hdc)
{
    int barSize;
    DWORD dwStyle;
    BOOL barSmooth;
    const ProgressDrawProc* drawProcs;
    ProgressDrawInfo pdi;

    TRACE("(infoPtr=%p, hdc=%p)\n", infoPtr, hdc);

    pdi.hdc = hdc;
    pdi.theme = GetWindowTheme (infoPtr->Self);

    /* get the required bar brush */
    if (infoPtr->ColorBar == CLR_DEFAULT)
        pdi.hbrBar = GetSysColorBrush(COLOR_HIGHLIGHT);
    else
        pdi.hbrBar = CreateSolidBrush (infoPtr->ColorBar);

    if (infoPtr->ColorBk == CLR_DEFAULT)
        pdi.hbrBk = GetSysColorBrush(COLOR_3DFACE);
    else
        pdi.hbrBk = CreateSolidBrush(infoPtr->ColorBk);

    /* get the window style */
    dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);

    /* get client rectangle */
    GetClientRect (infoPtr->Self, &pdi.rect);
    if (!pdi.theme) {
        FrameRect( hdc, &pdi.rect, pdi.hbrBk );
        InflateRect(&pdi.rect, -1, -1);
    }
    else
    {
        RECT cntRect;
        int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR;
        
        GetThemeBackgroundContentRect (pdi.theme, hdc, part, 0, &pdi.rect, 
            &cntRect);
        
        /* Exclude content rect - content background will be drawn later */
        ExcludeClipRect (hdc, cntRect.left, cntRect.top, 
            cntRect.right, cntRect.bottom);
        if (IsThemeBackgroundPartiallyTransparent (pdi.theme, part, 0))
            DrawThemeParentBackground (infoPtr->Self, hdc, NULL);
        DrawThemeBackground (pdi.theme, hdc, part, 0, &pdi.rect, NULL);
        SelectClipRgn (hdc, NULL);
        CopyRect (&pdi.rect, &cntRect);
    }

    /* compute some drawing parameters */
    barSmooth = (dwStyle & PBS_SMOOTH) && !pdi.theme;
    drawProcs = &((pdi.theme ? drawProcThemed : drawProcClassic)[(barSmooth ? 0 : 4)
        + ((dwStyle & PBS_VERTICAL) ? 2 : 0)]);
    barSize = get_bar_size( dwStyle, &pdi.rect );
    if (pdi.theme)
    {
        GetWindowRect( infoPtr->Self, &pdi.bgRect );
        ScreenToClient( infoPtr->Self, (POINT*)&pdi.bgRect );
        ScreenToClient( infoPtr->Self, (POINT*)&pdi.bgRect.right );
    }

    if (!barSmooth)
        pdi.ledW = get_led_size( infoPtr, dwStyle, &pdi.rect);
    pdi.ledGap = get_led_gap( infoPtr );

    if (dwStyle & PBS_MARQUEE)
    {
        const int ledW = !barSmooth ? (pdi.ledW + pdi.ledGap) : 1;
        const int leds = (barSize + ledW - 1) / ledW;
        const int ledMEnd = infoPtr->MarqueePos + MARQUEE_LEDS;

        if (ledMEnd > leds)
        {
            /* case 1: the marquee bar extends over the end and wraps around to 
             * the start */
            const int gapStart = max((ledMEnd - leds) * ledW, 0);
            const int gapEnd = min(infoPtr->MarqueePos * ledW, barSize);

            drawProcs[0]( &pdi, 0, gapStart);
            drawProcs[1]( &pdi, gapStart, gapEnd);
            drawProcs[0]( &pdi, gapEnd, barSize);
        }
        else
        {
            /* case 2: the marquee bar is between start and end */
            const int barStart = infoPtr->MarqueePos * ledW;
            const int barEnd = min (ledMEnd * ledW, barSize);

            drawProcs[1]( &pdi, 0, barStart);
            drawProcs[0]( &pdi, barStart, barEnd);
            drawProcs[1]( &pdi, barEnd, barSize);
        }
    }
    else
    {
        int barEnd = get_bar_position( infoPtr, dwStyle, &pdi.rect,
            infoPtr->CurVal);
        if (!barSmooth)
        {
            const int ledW = pdi.ledW + pdi.ledGap;
            barEnd = min (((barEnd + ledW - 1) / ledW) * ledW, barSize);
        }
        drawProcs[0]( &pdi, 0, barEnd);
        drawProcs[1]( &pdi, barEnd, barSize);
    }

    /* delete bar brush */
    if (infoPtr->ColorBar != CLR_DEFAULT) DeleteObject (pdi.hbrBar);
    if (infoPtr->ColorBk != CLR_DEFAULT) DeleteObject (pdi.hbrBk);

    return 0;
}

/***********************************************************************
 * PROGRESS_Paint
 * Draw the progress bar. The background need not be erased.
 * If dc!=0, it draws on it
 */
static LRESULT PROGRESS_Paint (PROGRESS_INFO *infoPtr, HDC hdc)
{
    PAINTSTRUCT ps;
    if (hdc) return PROGRESS_Draw (infoPtr, hdc);
    hdc = BeginPaint (infoPtr->Self, &ps);
    PROGRESS_Draw (infoPtr, hdc);
    EndPaint (infoPtr->Self, &ps);
    return 0;
}


/***********************************************************************
 * PROGRESS_Timer
 * Handle the marquee timer messages
 */
static LRESULT PROGRESS_Timer (PROGRESS_INFO *infoPtr, INT idTimer)
{
    if(idTimer == ID_MARQUEE_TIMER)
    {
        LONG style = GetWindowLongW (infoPtr->Self, GWL_STYLE);
        RECT rect;
        int ledWidth, leds;
        HTHEME theme = GetWindowTheme (infoPtr->Self);
        BOOL barSmooth = (style & PBS_SMOOTH) && !theme;

        get_client_rect (infoPtr->Self, &rect);

        if(!barSmooth)
            ledWidth = get_led_size( infoPtr, style, &rect ) + 
                get_led_gap( infoPtr );
        else
            ledWidth = 1;

        leds = (get_bar_size( style, &rect ) + ledWidth - 1) / 
            ledWidth;

        /* increment the marquee progress */
        if(++infoPtr->MarqueePos >= leds)
        {
            infoPtr->MarqueePos = 0;
        }

        InvalidateRect(infoPtr->Self, &rect, FALSE);
        UpdateWindow(infoPtr->Self);
    }
    return 0;
}


/***********************************************************************
 *           PROGRESS_CoercePos
 * Makes sure the current position (CurVal) is within bounds.
 */
static void PROGRESS_CoercePos(PROGRESS_INFO *infoPtr)
{
    if(infoPtr->CurVal < infoPtr->MinVal)
        infoPtr->CurVal = infoPtr->MinVal;
    if(infoPtr->CurVal > infoPtr->MaxVal)
        infoPtr->CurVal = infoPtr->MaxVal;
}


/***********************************************************************
 *           PROGRESS_SetFont
 * Set new Font for progress bar
 */
static HFONT PROGRESS_SetFont (PROGRESS_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
{
    HFONT hOldFont = infoPtr->Font;
    infoPtr->Font = hFont;
    /* Since infoPtr->Font is not used, there is no need for repaint */
    return hOldFont;
}

static DWORD PROGRESS_SetRange (PROGRESS_INFO *infoPtr, int low, int high)
{
    DWORD res = MAKELONG(LOWORD(infoPtr->MinVal), LOWORD(infoPtr->MaxVal));

    /* if nothing changes, simply return */
    if(infoPtr->MinVal == low && infoPtr->MaxVal == high) return res;

    infoPtr->MinVal = low;
    infoPtr->MaxVal = high;
    PROGRESS_CoercePos(infoPtr);
    InvalidateRect(infoPtr->Self, NULL, TRUE);
    return res;
}

/***********************************************************************
 *           ProgressWindowProc
 */
static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
                                         WPARAM wParam, LPARAM lParam)
{
    PROGRESS_INFO *infoPtr;
    static const WCHAR themeClass[] = {'P','r','o','g','r','e','s','s',0};
    HTHEME theme;

    TRACE("hwnd=%p msg=%04x wparam=%x lParam=%lx\n", hwnd, message, wParam, lParam);

    infoPtr = (PROGRESS_INFO *)GetWindowLongPtrW(hwnd, 0);

    if (!infoPtr && message != WM_CREATE)
        return DefWindowProcW( hwnd, message, wParam, lParam );

    switch(message) {
    case WM_CREATE:
    {
	DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
        
        theme = OpenThemeData (hwnd, themeClass);

	dwExStyle &= ~(WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
	if (!theme) dwExStyle |= WS_EX_STATICEDGE;
        SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle);
	/* Force recalculation of a non-client area */
	SetWindowPos(hwnd, 0, 0, 0, 0, 0,
	    SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);

        /* allocate memory for info struct */
        infoPtr = (PROGRESS_INFO *)Alloc (sizeof(PROGRESS_INFO));
        if (!infoPtr) return -1;
        SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);

        /* initialize the info struct */
        infoPtr->Self = hwnd;
        infoPtr->MinVal = 0;
        infoPtr->MaxVal = 100;
        infoPtr->CurVal = 0;
        infoPtr->Step = 10;
        infoPtr->MarqueePos = 0;
        infoPtr->Marquee = FALSE;
        infoPtr->ColorBar = CLR_DEFAULT;
        infoPtr->ColorBk = CLR_DEFAULT;
        infoPtr->Font = 0;

        TRACE("Progress Ctrl creation, hwnd=%p\n", hwnd);
        return 0;
    }

    case WM_DESTROY:
        TRACE("Progress Ctrl destruction, hwnd=%p\n", hwnd);
        Free (infoPtr);
        SetWindowLongPtrW(hwnd, 0, 0);
        theme = GetWindowTheme (hwnd);
        CloseThemeData (theme);
        return 0;

    case WM_ERASEBKGND:
        return 1;

    case WM_GETFONT:
        return (LRESULT)infoPtr->Font;

    case WM_SETFONT:
        return (LRESULT)PROGRESS_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);

    case WM_PRINTCLIENT:
    case WM_PAINT:
        return PROGRESS_Paint (infoPtr, (HDC)wParam);

    case WM_TIMER:
        return PROGRESS_Timer (infoPtr, (INT)wParam);

    case WM_THEMECHANGED:
    {
        DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
        
        theme = GetWindowTheme (hwnd);
        CloseThemeData (theme);
        theme = OpenThemeData (hwnd, themeClass);
        
        /* WS_EX_STATICEDGE disappears when the control is themed */
        if (theme)
            dwExStyle &= ~WS_EX_STATICEDGE;
        else
            dwExStyle |= WS_EX_STATICEDGE;
        SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle);
        
        InvalidateRect (hwnd, NULL, FALSE);
        return 0;
    }

    case PBM_DELTAPOS:
    {
	INT oldVal;
        oldVal = infoPtr->CurVal;
        if(wParam != 0) {
	    infoPtr->CurVal += (INT)wParam;
	    PROGRESS_CoercePos (infoPtr);
	    TRACE("PBM_DELTAPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
            UpdateWindow( infoPtr->Self );
        }
        return oldVal;
    }

    case PBM_SETPOS:
    {
        UINT oldVal;
        oldVal = infoPtr->CurVal;
        if(oldVal != wParam) {
	    infoPtr->CurVal = (INT)wParam;
	    PROGRESS_CoercePos(infoPtr);
	    TRACE("PBM_SETPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
            UpdateWindow( infoPtr->Self );
        }
        return oldVal;
    }

    case PBM_SETRANGE:
        return PROGRESS_SetRange (infoPtr, (int)LOWORD(lParam), (int)HIWORD(lParam));

    case PBM_SETSTEP:
    {
	INT oldStep;
        oldStep = infoPtr->Step;
        infoPtr->Step = (INT)wParam;
        return oldStep;
    }

    case PBM_STEPIT:
    {
	INT oldVal;
        oldVal = infoPtr->CurVal;
        infoPtr->CurVal += infoPtr->Step;
        if(infoPtr->CurVal > infoPtr->MaxVal)
	    infoPtr->CurVal = infoPtr->MinVal;
        if(oldVal != infoPtr->CurVal)
	{
	    TRACE("PBM_STEPIT: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
            UpdateWindow( infoPtr->Self );
	}
        return oldVal;
    }

    case PBM_SETRANGE32:
        return PROGRESS_SetRange (infoPtr, (int)wParam, (int)lParam);

    case PBM_GETRANGE:
        if (lParam) {
            ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
            ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
        }
        return wParam ? infoPtr->MinVal : infoPtr->MaxVal;

    case PBM_GETPOS:
        return infoPtr->CurVal;

    case PBM_SETBARCOLOR:
        infoPtr->ColorBar = (COLORREF)lParam;
	InvalidateRect(hwnd, NULL, TRUE);
	return 0;

    case PBM_SETBKCOLOR:
        infoPtr->ColorBk = (COLORREF)lParam;
	InvalidateRect(hwnd, NULL, TRUE);
	return 0;

    case PBM_SETMARQUEE:
	if(wParam != 0)
        {
            infoPtr->Marquee = TRUE;
            SetTimer(infoPtr->Self, ID_MARQUEE_TIMER, (UINT)lParam, NULL);
        }
        else
        {
            infoPtr->Marquee = FALSE;
            KillTimer(infoPtr->Self, ID_MARQUEE_TIMER);
        }
	return infoPtr->Marquee;

    default:
        if ((message >= WM_USER) && (message < WM_APP))
	    ERR("unknown msg %04x wp=%04x lp=%08lx\n", message, wParam, lParam );
        return DefWindowProcW( hwnd, message, wParam, lParam );
    }
}


/***********************************************************************
 * PROGRESS_Register [Internal]
 *
 * Registers the progress bar window class.
 */
void PROGRESS_Register (void)
{
    WNDCLASSW wndClass;

    ZeroMemory (&wndClass, sizeof(wndClass));
    wndClass.style         = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
    wndClass.lpfnWndProc   = (WNDPROC)ProgressWindowProc;
    wndClass.cbClsExtra    = 0;
    wndClass.cbWndExtra    = sizeof (PROGRESS_INFO *);
    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
    wndClass.lpszClassName = PROGRESS_CLASSW;

    RegisterClassW (&wndClass);
}


/***********************************************************************
 * PROGRESS_Unregister [Internal]
 *
 * Unregisters the progress bar window class.
 */
void PROGRESS_Unregister (void)
{
    UnregisterClassW (PROGRESS_CLASSW, NULL);
}
