Added support for PBS_MARQUEE style.

This commit is contained in:
Thomas Weidenmueller 2004-08-02 22:19:50 +00:00 committed by Alexandre Julliard
parent dd5b23fddb
commit 7155eff8bc
2 changed files with 280 additions and 38 deletions

View File

@ -26,9 +26,6 @@
* 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.
*
* TODO
* --support PBS_MARQUE
*
*/
@ -52,6 +49,8 @@ typedef struct
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) */
@ -59,7 +58,9 @@ typedef struct
/* Control configuration constants */
#define LED_GAP 2
#define LED_GAP 2
#define MARQUEE_LEDS 5
#define ID_MARQUEE_TIMER 1
/***********************************************************************
* PROGRESS_Invalidate
@ -156,51 +157,215 @@ static LRESULT PROGRESS_Draw (PROGRESS_INFO *infoPtr, HDC hdc)
{
if (dwStyle & PBS_VERTICAL)
{
INT old_top = rect.top;
rect.top = rightBar;
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
rect.top = old_top;
FillRect(hdc, &rect, hbrBk);
if (dwStyle & PBS_MARQUEE)
{
INT old_top, old_bottom, ledMStart, leds;
old_top = rect.top;
old_bottom = rect.bottom;
leds = rect.bottom - rect.top;
ledMStart = (infoPtr->MarqueePos + MARQUEE_LEDS) - leds;
if(ledMStart > 0)
{
rect.top = max(rect.bottom - ledMStart, old_top);
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
}
if(infoPtr->MarqueePos > 0)
{
rect.top = max(old_bottom - infoPtr->MarqueePos, old_top);
FillRect(hdc, &rect, hbrBk);
rect.bottom = rect.top;
}
if(rect.top >= old_top)
{
rect.top = max(rect.bottom - MARQUEE_LEDS, old_top);
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
}
if(rect.top >= old_top)
{
rect.top = old_top;
FillRect(hdc, &rect, hbrBk);
}
}
else
{
INT old_top = rect.top;
rect.top = rightBar;
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
rect.top = old_top;
FillRect(hdc, &rect, hbrBk);
}
}
else
{
INT old_right = rect.right;
rect.right = rightBar;
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
rect.right = old_right;
FillRect(hdc, &rect, hbrBk);
if (dwStyle & PBS_MARQUEE)
{
INT old_left, old_right, ledMStart, leds;
old_left = rect.left;
old_right = rect.right;
leds = rect.right - rect.left;
ledMStart = (infoPtr->MarqueePos + MARQUEE_LEDS) - leds;
rect.right = rect.left;
if(ledMStart > 0)
{
rect.right = min(rect.left + ledMStart, old_right);
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
}
if(infoPtr->MarqueePos > 0)
{
rect.right = min(old_left + infoPtr->MarqueePos, old_right);
FillRect(hdc, &rect, hbrBk);
rect.left = rect.right;
}
if(rect.right < old_right)
{
rect.right = min(rect.left + MARQUEE_LEDS, old_right);
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
}
if(rect.right < old_right)
{
rect.right = old_right;
FillRect(hdc, &rect, hbrBk);
}
}
else
{
INT old_right = rect.right;
rect.right = rightBar;
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
rect.right = old_right;
FillRect(hdc, &rect, hbrBk);
}
}
} else {
if (dwStyle & PBS_VERTICAL) {
while(rect.bottom > rightBar) {
rect.top = rect.bottom - ledWidth;
if (rect.top < rightMost)
rect.top = rightMost;
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
rect.top -= LED_GAP;
if (rect.top <= rightBar) break;
FillRect(hdc, &rect, hbrBk);
rect.bottom = rect.top;
if (dwStyle & PBS_MARQUEE)
{
INT i, old_top, old_bottom, ledMStart, leds;
old_top = rect.top;
old_bottom = rect.bottom;
leds = ((rect.bottom - rect.top) + (ledWidth + LED_GAP) - 1) / (ledWidth + LED_GAP);
ledMStart = (infoPtr->MarqueePos + MARQUEE_LEDS) - leds;
while(ledMStart > 0)
{
rect.top = max(rect.bottom - ledWidth, old_top);
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
rect.top -= LED_GAP;
if (rect.top <= old_top) break;
FillRect(hdc, &rect, hbrBk);
rect.bottom = rect.top;
ledMStart--;
}
if(infoPtr->MarqueePos > 0)
{
rect.top = max(old_bottom - (infoPtr->MarqueePos * (ledWidth + LED_GAP)), old_top);
FillRect(hdc, &rect, hbrBk);
rect.bottom = rect.top;
}
for(i = 0; i < MARQUEE_LEDS && rect.top >= old_top; i++)
{
rect.top = max(rect.bottom - ledWidth, old_top);
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
rect.top -= LED_GAP;
if (rect.top <= old_top) break;
FillRect(hdc, &rect, hbrBk);
rect.bottom = rect.top;
}
if(rect.top >= old_top)
{
rect.top = old_top;
FillRect(hdc, &rect, hbrBk);
}
}
else
{
while(rect.bottom > rightBar) {
rect.top = rect.bottom - ledWidth;
if (rect.top < rightMost)
rect.top = rightMost;
FillRect(hdc, &rect, hbrBar);
rect.bottom = rect.top;
rect.top -= LED_GAP;
if (rect.top <= rightBar) break;
FillRect(hdc, &rect, hbrBk);
rect.bottom = rect.top;
}
}
rect.top = rightMost;
FillRect(hdc, &rect, hbrBk);
} else {
while(rect.left < rightBar) {
rect.right = rect.left + ledWidth;
if (rect.right > rightMost)
rect.right = rightMost;
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
rect.right += LED_GAP;
if (rect.right >= rightBar) break;
FillRect(hdc, &rect, hbrBk);
rect.left = rect.right;
if (dwStyle & PBS_MARQUEE)
{
INT i, old_right, old_left, ledMStart, leds;
old_left = rect.left;
old_right = rect.right;
leds = ((rect.right - rect.left) + ledWidth - 1) / (ledWidth + LED_GAP);
ledMStart = (infoPtr->MarqueePos + MARQUEE_LEDS) - leds;
rect.right = rect.left;
while(ledMStart > 0)
{
rect.right = min(rect.left + ledWidth, old_right);
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
rect.right += LED_GAP;
if (rect.right > old_right) break;
FillRect(hdc, &rect, hbrBk);
rect.left = rect.right;
ledMStart--;
}
if(infoPtr->MarqueePos > 0)
{
rect.right = min(old_left + (infoPtr->MarqueePos * (ledWidth + LED_GAP)), old_right);
FillRect(hdc, &rect, hbrBk);
rect.left = rect.right;
}
for(i = 0; i < MARQUEE_LEDS && rect.right < old_right; i++)
{
rect.right = min(rect.left + ledWidth, old_right);
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
rect.right += LED_GAP;
if (rect.right > old_right) break;
FillRect(hdc, &rect, hbrBk);
rect.left = rect.right;
}
if(rect.right < old_right)
{
rect.right = old_right;
FillRect(hdc, &rect, hbrBk);
}
}
else
{
while(rect.left < rightBar) {
rect.right = rect.left + ledWidth;
if (rect.right > rightMost)
rect.right = rightMost;
FillRect(hdc, &rect, hbrBar);
rect.left = rect.right;
rect.right += LED_GAP;
if (rect.right >= rightBar) break;
FillRect(hdc, &rect, hbrBk);
rect.left = rect.right;
}
rect.right = rightMost;
FillRect(hdc, &rect, hbrBk);
}
rect.right = rightMost;
FillRect(hdc, &rect, hbrBk);
}
}
@ -228,6 +393,63 @@ static LRESULT PROGRESS_Paint (PROGRESS_INFO *infoPtr, HDC hdc)
}
/***********************************************************************
* 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;
GetClientRect (infoPtr->Self, &rect);
InflateRect(&rect, -1, -1);
if(!(style & PBS_SMOOTH))
{
int width, height;
if(style & PBS_VERTICAL)
{
width = rect.bottom - rect.top;
height = rect.right - rect.left;
}
else
{
height = rect.bottom - rect.top;
width = rect.right - rect.left;
}
ledWidth = MulDiv (height, 2, 3);
leds = (width + ledWidth - 1) / (ledWidth + LED_GAP);
}
else
{
ledWidth = 1;
if(style & PBS_VERTICAL)
{
leds = rect.bottom - rect.top;
}
else
{
leds = rect.right - rect.left;
}
}
/* increment the marquee progress */
if(++infoPtr->MarqueePos >= leds)
{
infoPtr->MarqueePos = 0;
}
InvalidateRect(infoPtr->Self, &rect, TRUE);
}
return 0;
}
/***********************************************************************
* PROGRESS_CoercePos
* Makes sure the current position (CurVal) is within bounds.
@ -304,6 +526,8 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
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;
@ -326,6 +550,9 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
case WM_PAINT:
return PROGRESS_Paint (infoPtr, (HDC)wParam);
case WM_TIMER:
return PROGRESS_Timer (infoPtr, (INT)wParam);
case PBM_DELTAPOS:
{
INT oldVal;
@ -401,6 +628,19 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
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 );

View File

@ -456,10 +456,12 @@ static const WCHAR PROGRESS_CLASSW[] = { 'm','s','c','t','l','s','_',
#define PBM_GETRANGE (WM_USER+7)
#define PBM_GETPOS (WM_USER+8)
#define PBM_SETBARCOLOR (WM_USER+9)
#define PBM_SETMARQUEE (WM_USER+10)
#define PBM_SETBKCOLOR CCM_SETBKCOLOR
#define PBS_SMOOTH 0x01
#define PBS_VERTICAL 0x04
#define PBS_MARQUEE 0x08
typedef struct
{