ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

progress.c
Go to the documentation of this file.
00001 /*
00002  * Progress control
00003  *
00004  * Copyright 1997, 2002 Dimitrie O. Paun
00005  * Copyright 1998, 1999 Eric Kohl
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  *
00021  * NOTE
00022  * 
00023  * This code was audited for completeness against the documented features
00024  * of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun.
00025  * 
00026  * Unless otherwise noted, we believe this code to be complete, as per
00027  * the specification mentioned above.
00028  * If you discover missing features, or bugs, please note them below.
00029  *
00030  * TODO:
00031  *
00032  * Styles:
00033  *    -- PBS_SMOOTHREVERSE
00034  *
00035  */
00036 
00037 #include <stdarg.h>
00038 #include <string.h>
00039 #include "windef.h"
00040 #include "winbase.h"
00041 #include "wingdi.h"
00042 #include "winuser.h"
00043 #include "winnls.h"
00044 #include "commctrl.h"
00045 #include "comctl32.h"
00046 #include "uxtheme.h"
00047 #include "vssym32.h"
00048 #include "wine/debug.h"
00049 
00050 WINE_DEFAULT_DEBUG_CHANNEL(progress);
00051 
00052 typedef struct
00053 {
00054     HWND      Self;         /* The window handle for this control */
00055     INT       CurVal;       /* Current progress value */
00056     INT       MinVal;       /* Minimum progress value */
00057     INT       MaxVal;       /* Maximum progress value */
00058     INT       Step;         /* Step to use on PMB_STEPIT */
00059     INT       MarqueePos;   /* Marquee animation position */
00060     BOOL      Marquee;      /* Whether the marquee animation is enabled */
00061     COLORREF  ColorBar;     /* Bar color */
00062     COLORREF  ColorBk;      /* Background color */
00063     HFONT     Font;         /* Handle to font (not unused) */
00064 } PROGRESS_INFO;
00065 
00066 /* Control configuration constants */
00067 
00068 #define LED_GAP           2
00069 #define MARQUEE_LEDS      5
00070 #define ID_MARQUEE_TIMER  1
00071 
00072 /* Helper to obtain size of a progress bar chunk ("led"). */
00073 static inline int get_led_size ( const PROGRESS_INFO *infoPtr, LONG style,
00074                                  const RECT* rect )
00075 {
00076     HTHEME theme = GetWindowTheme (infoPtr->Self);
00077     if (theme)
00078     {
00079         int chunkSize;
00080         if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSCHUNKSIZE, &chunkSize )))
00081             return chunkSize;
00082     }
00083 
00084     if (style & PBS_VERTICAL)
00085         return MulDiv (rect->right - rect->left, 2, 3);
00086     else
00087         return MulDiv (rect->bottom - rect->top, 2, 3);
00088 }
00089 
00090 /* Helper to obtain gap between progress bar chunks */
00091 static inline int get_led_gap ( const PROGRESS_INFO *infoPtr )
00092 {
00093     HTHEME theme = GetWindowTheme (infoPtr->Self);
00094     if (theme)
00095     {
00096         int spaceSize;
00097         if (SUCCEEDED( GetThemeInt( theme, 0, 0, TMT_PROGRESSSPACESIZE, &spaceSize )))
00098             return spaceSize;
00099     }
00100 
00101     return LED_GAP;
00102 }
00103 
00104 /* Get client rect. Takes into account that theming needs no adjustment. */
00105 static inline void get_client_rect (HWND hwnd, RECT* rect)
00106 {
00107     HTHEME theme = GetWindowTheme (hwnd);
00108     GetClientRect (hwnd, rect);
00109     if (!theme)
00110         InflateRect(rect, -1, -1);
00111     else
00112     {
00113         DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
00114         int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR;
00115         GetThemeBackgroundContentRect (theme, 0, part, 0, rect, rect);
00116     }
00117 }
00118 
00119 /* Compute the extend of the bar */
00120 static inline int get_bar_size( LONG style, const RECT* rect )
00121 {
00122     if (style & PBS_VERTICAL)
00123         return rect->bottom - rect->top;
00124     else
00125         return rect->right - rect->left;
00126 }
00127 
00128 /* Compute the pixel position of a progress value */
00129 static inline int get_bar_position( const PROGRESS_INFO *infoPtr, LONG style,
00130                                     const RECT* rect, INT value )
00131 {
00132     return MulDiv (value - infoPtr->MinVal, get_bar_size (style, rect),
00133                       infoPtr->MaxVal - infoPtr->MinVal);
00134 }
00135 
00136 /***********************************************************************
00137  * PROGRESS_Invalidate
00138  *
00139  * Don't be too clever about invalidating the progress bar.
00140  * InstallShield depends on this simple behaviour.
00141  */
00142 static void PROGRESS_Invalidate( const PROGRESS_INFO *infoPtr, INT old, INT new )
00143 {
00144     InvalidateRect( infoPtr->Self, NULL, old > new );
00145 }
00146 
00147 /* Information for a progress bar drawing helper */
00148 typedef struct tagProgressDrawInfo
00149 {
00150     HDC hdc;
00151     RECT rect;
00152     HBRUSH hbrBar;
00153     HBRUSH hbrBk;
00154     int ledW, ledGap;
00155     HTHEME theme;
00156     RECT bgRect;
00157 } ProgressDrawInfo;
00158 
00159 typedef void (*ProgressDrawProc)(const ProgressDrawInfo* di, int start, int end);
00160 
00161 /* draw solid horizontal bar from 'start' to 'end' */
00162 static void draw_solid_bar_H (const ProgressDrawInfo* di, int start, int end)
00163 {
00164     RECT r;
00165     r.left = di->rect.left + start;
00166     r.top = di->rect.top;
00167     r.right = di->rect.left + end;
00168     r.bottom = di->rect.bottom;
00169     FillRect (di->hdc, &r, di->hbrBar);
00170 }
00171 
00172 /* draw solid horizontal background from 'start' to 'end' */
00173 static void draw_solid_bkg_H (const ProgressDrawInfo* di, int start, int end)
00174 {
00175     RECT r;
00176     r.left = di->rect.left + start;
00177     r.top = di->rect.top;
00178     r.right = di->rect.left + end;
00179     r.bottom = di->rect.bottom;
00180     FillRect (di->hdc, &r, di->hbrBk);
00181 }
00182 
00183 /* draw solid vertical bar from 'start' to 'end' */
00184 static void draw_solid_bar_V (const ProgressDrawInfo* di, int start, int end)
00185 {
00186     RECT r;
00187     r.left = di->rect.left;
00188     r.top = di->rect.bottom - end;
00189     r.right = di->rect.right;
00190     r.bottom = di->rect.bottom - start;
00191     FillRect (di->hdc, &r, di->hbrBar);
00192 }
00193 
00194 /* draw solid vertical background from 'start' to 'end' */
00195 static void draw_solid_bkg_V (const ProgressDrawInfo* di, int start, int end)
00196 {
00197     RECT r;
00198     r.left = di->rect.left;
00199     r.top = di->rect.bottom - end;
00200     r.right = di->rect.right;
00201     r.bottom = di->rect.bottom - start;
00202     FillRect (di->hdc, &r, di->hbrBk);
00203 }
00204 
00205 /* draw chunky horizontal bar from 'start' to 'end' */
00206 static void draw_chunk_bar_H (const ProgressDrawInfo* di, int start, int end)
00207 {
00208     RECT r;
00209     int right = di->rect.left + end;
00210     r.left = di->rect.left + start;
00211     r.top = di->rect.top;
00212     r.bottom = di->rect.bottom;
00213     while (r.left < right)
00214     {
00215         r.right = min (r.left + di->ledW, right);
00216         FillRect (di->hdc, &r, di->hbrBar);
00217         r.left = r.right;
00218         r.right = min (r.left + di->ledGap, right);
00219         FillRect (di->hdc, &r, di->hbrBk);
00220         r.left = r.right;
00221     }
00222 }
00223 
00224 /* draw chunky vertical bar from 'start' to 'end' */
00225 static void draw_chunk_bar_V (const ProgressDrawInfo* di, int start, int end)
00226 {
00227     RECT r;
00228     int top = di->rect.bottom - end;
00229     r.left = di->rect.left;
00230     r.right = di->rect.right;
00231     r.bottom = di->rect.bottom - start;
00232     while (r.bottom > top)
00233     {
00234         r.top = max (r.bottom - di->ledW, top);
00235         FillRect (di->hdc, &r, di->hbrBar);
00236         r.bottom = r.top;
00237         r.top = max (r.bottom - di->ledGap, top);
00238         FillRect (di->hdc, &r, di->hbrBk);
00239         r.bottom = r.top;
00240     }
00241 }
00242 
00243 /* drawing functions for "classic" style */
00244 static const ProgressDrawProc drawProcClassic[8] = {
00245   /* Smooth */
00246     /* Horizontal */
00247     draw_solid_bar_H, draw_solid_bkg_H,
00248     /* Vertical */
00249     draw_solid_bar_V, draw_solid_bkg_V,
00250   /* Chunky */
00251     /* Horizontal */
00252     draw_chunk_bar_H, draw_solid_bkg_H,
00253     /* Vertical */
00254     draw_chunk_bar_V, draw_solid_bkg_V,
00255 };
00256 
00257 /* draw themed horizontal bar from 'start' to 'end' */
00258 static void draw_theme_bar_H (const ProgressDrawInfo* di, int start, int end)
00259 {
00260     RECT r;
00261     r.left = di->rect.left + start;
00262     r.top = di->rect.top;
00263     r.bottom = di->rect.bottom;
00264     r.right = di->rect.left + end;
00265     DrawThemeBackground (di->theme, di->hdc, PP_CHUNK, 0, &r, NULL);
00266 }
00267 
00268 /* draw themed vertical bar from 'start' to 'end' */
00269 static void draw_theme_bar_V (const ProgressDrawInfo* di, int start, int end)
00270 {
00271     RECT r;
00272     r.left = di->rect.left;
00273     r.right = di->rect.right;
00274     r.bottom = di->rect.bottom - start;
00275     r.top = di->rect.bottom - end;
00276     DrawThemeBackground (di->theme, di->hdc, PP_CHUNKVERT, 0, &r, NULL);
00277 }
00278 
00279 /* draw themed horizontal background from 'start' to 'end' */
00280 static void draw_theme_bkg_H (const ProgressDrawInfo* di, int start, int end)
00281 {
00282     RECT r;
00283     r.left = di->rect.left + start;
00284     r.top = di->rect.top;
00285     r.right = di->rect.left + end;
00286     r.bottom = di->rect.bottom;
00287     DrawThemeBackground (di->theme, di->hdc, PP_BAR, 0, &di->bgRect, &r);
00288 }
00289 
00290 /* draw themed vertical background from 'start' to 'end' */
00291 static void draw_theme_bkg_V (const ProgressDrawInfo* di, int start, int end)
00292 {
00293     RECT r;
00294     r.left = di->rect.left;
00295     r.top = di->rect.bottom - end;
00296     r.right = di->rect.right;
00297     r.bottom = di->rect.bottom - start;
00298     DrawThemeBackground (di->theme, di->hdc, PP_BARVERT, 0, &di->bgRect, &r);
00299 }
00300 
00301 /* drawing functions for themed style */
00302 static const ProgressDrawProc drawProcThemed[8] = {
00303   /* Smooth */
00304     /* Horizontal */
00305     draw_theme_bar_H, draw_theme_bkg_H,
00306     /* Vertical */
00307     draw_theme_bar_V, draw_theme_bkg_V,
00308   /* Chunky */
00309     /* Horizontal */
00310     draw_theme_bar_H, draw_theme_bkg_H,
00311     /* Vertical */
00312     draw_theme_bar_V, draw_theme_bkg_V,
00313 };
00314 
00315 /***********************************************************************
00316  * PROGRESS_Draw
00317  * Draws the progress bar.
00318  */
00319 static LRESULT PROGRESS_Draw (PROGRESS_INFO *infoPtr, HDC hdc)
00320 {
00321     int barSize;
00322     DWORD dwStyle;
00323     BOOL barSmooth;
00324     const ProgressDrawProc* drawProcs;
00325     ProgressDrawInfo pdi;
00326 
00327     TRACE("(infoPtr=%p, hdc=%p)\n", infoPtr, hdc);
00328 
00329     pdi.hdc = hdc;
00330     pdi.theme = GetWindowTheme (infoPtr->Self);
00331 
00332     /* get the required bar brush */
00333     if (infoPtr->ColorBar == CLR_DEFAULT)
00334         pdi.hbrBar = GetSysColorBrush(COLOR_HIGHLIGHT);
00335     else
00336         pdi.hbrBar = CreateSolidBrush (infoPtr->ColorBar);
00337 
00338     if (infoPtr->ColorBk == CLR_DEFAULT)
00339         pdi.hbrBk = GetSysColorBrush(COLOR_3DFACE);
00340     else
00341         pdi.hbrBk = CreateSolidBrush(infoPtr->ColorBk);
00342 
00343     /* get the window style */
00344     dwStyle = GetWindowLongW (infoPtr->Self, GWL_STYLE);
00345 
00346     /* get client rectangle */
00347     GetClientRect (infoPtr->Self, &pdi.rect);
00348     if (!pdi.theme) {
00349         FrameRect( hdc, &pdi.rect, pdi.hbrBk );
00350         InflateRect(&pdi.rect, -1, -1);
00351     }
00352     else
00353     {
00354         RECT cntRect;
00355         int part = (dwStyle & PBS_VERTICAL) ? PP_BARVERT : PP_BAR;
00356         
00357         GetThemeBackgroundContentRect (pdi.theme, hdc, part, 0, &pdi.rect, 
00358             &cntRect);
00359         
00360         /* Exclude content rect - content background will be drawn later */
00361         ExcludeClipRect (hdc, cntRect.left, cntRect.top, 
00362             cntRect.right, cntRect.bottom);
00363         if (IsThemeBackgroundPartiallyTransparent (pdi.theme, part, 0))
00364             DrawThemeParentBackground (infoPtr->Self, hdc, NULL);
00365         DrawThemeBackground (pdi.theme, hdc, part, 0, &pdi.rect, NULL);
00366         SelectClipRgn (hdc, NULL);
00367         CopyRect (&pdi.rect, &cntRect);
00368     }
00369 
00370     /* compute some drawing parameters */
00371     barSmooth = (dwStyle & PBS_SMOOTH) && !pdi.theme;
00372     drawProcs = &((pdi.theme ? drawProcThemed : drawProcClassic)[(barSmooth ? 0 : 4)
00373         + ((dwStyle & PBS_VERTICAL) ? 2 : 0)]);
00374     barSize = get_bar_size( dwStyle, &pdi.rect );
00375     if (pdi.theme)
00376     {
00377         GetWindowRect( infoPtr->Self, &pdi.bgRect );
00378         MapWindowPoints( infoPtr->Self, 0, (POINT*)&pdi.bgRect, 2 );
00379     }
00380 
00381     if (!barSmooth)
00382         pdi.ledW = get_led_size( infoPtr, dwStyle, &pdi.rect);
00383     pdi.ledGap = get_led_gap( infoPtr );
00384 
00385     if (dwStyle & PBS_MARQUEE)
00386     {
00387         const int ledW = !barSmooth ? (pdi.ledW + pdi.ledGap) : 1;
00388         const int leds = (barSize + ledW - 1) / ledW;
00389         const int ledMEnd = infoPtr->MarqueePos + MARQUEE_LEDS;
00390 
00391         if (ledMEnd > leds)
00392         {
00393             /* case 1: the marquee bar extends over the end and wraps around to 
00394              * the start */
00395             const int gapStart = max((ledMEnd - leds) * ledW, 0);
00396             const int gapEnd = min(infoPtr->MarqueePos * ledW, barSize);
00397 
00398             drawProcs[0]( &pdi, 0, gapStart);
00399             drawProcs[1]( &pdi, gapStart, gapEnd);
00400             drawProcs[0]( &pdi, gapEnd, barSize);
00401         }
00402         else
00403         {
00404             /* case 2: the marquee bar is between start and end */
00405             const int barStart = infoPtr->MarqueePos * ledW;
00406             const int barEnd = min (ledMEnd * ledW, barSize);
00407 
00408             drawProcs[1]( &pdi, 0, barStart);
00409             drawProcs[0]( &pdi, barStart, barEnd);
00410             drawProcs[1]( &pdi, barEnd, barSize);
00411         }
00412     }
00413     else
00414     {
00415         int barEnd = get_bar_position( infoPtr, dwStyle, &pdi.rect,
00416             infoPtr->CurVal);
00417         if (!barSmooth)
00418         {
00419             const int ledW = pdi.ledW + pdi.ledGap;
00420             barEnd = min (((barEnd + ledW - 1) / ledW) * ledW, barSize);
00421         }
00422         drawProcs[0]( &pdi, 0, barEnd);
00423         drawProcs[1]( &pdi, barEnd, barSize);
00424     }
00425 
00426     /* delete bar brush */
00427     if (infoPtr->ColorBar != CLR_DEFAULT) DeleteObject (pdi.hbrBar);
00428     if (infoPtr->ColorBk != CLR_DEFAULT) DeleteObject (pdi.hbrBk);
00429 
00430     return 0;
00431 }
00432 
00433 /***********************************************************************
00434  * PROGRESS_Paint
00435  * Draw the progress bar. The background need not be erased.
00436  * If dc!=0, it draws on it
00437  */
00438 static LRESULT PROGRESS_Paint (PROGRESS_INFO *infoPtr, HDC hdc)
00439 {
00440     PAINTSTRUCT ps;
00441     if (hdc) return PROGRESS_Draw (infoPtr, hdc);
00442     hdc = BeginPaint (infoPtr->Self, &ps);
00443     PROGRESS_Draw (infoPtr, hdc);
00444     EndPaint (infoPtr->Self, &ps);
00445     return 0;
00446 }
00447 
00448 
00449 /***********************************************************************
00450  * PROGRESS_Timer
00451  * Handle the marquee timer messages
00452  */
00453 static LRESULT PROGRESS_Timer (PROGRESS_INFO *infoPtr, INT idTimer)
00454 {
00455     if(idTimer == ID_MARQUEE_TIMER)
00456     {
00457         LONG style = GetWindowLongW (infoPtr->Self, GWL_STYLE);
00458         RECT rect;
00459         int ledWidth, leds;
00460         HTHEME theme = GetWindowTheme (infoPtr->Self);
00461         BOOL barSmooth = (style & PBS_SMOOTH) && !theme;
00462 
00463         get_client_rect (infoPtr->Self, &rect);
00464 
00465         if(!barSmooth)
00466             ledWidth = get_led_size( infoPtr, style, &rect ) + 
00467                 get_led_gap( infoPtr );
00468         else
00469             ledWidth = 1;
00470 
00471         leds = (get_bar_size( style, &rect ) + ledWidth - 1) / 
00472             ledWidth;
00473 
00474         /* increment the marquee progress */
00475         if(++infoPtr->MarqueePos >= leds)
00476         {
00477             infoPtr->MarqueePos = 0;
00478         }
00479 
00480         InvalidateRect(infoPtr->Self, &rect, FALSE);
00481         UpdateWindow(infoPtr->Self);
00482     }
00483     return 0;
00484 }
00485 
00486 
00487 /***********************************************************************
00488  *           PROGRESS_CoercePos
00489  * Makes sure the current position (CurVal) is within bounds.
00490  */
00491 static void PROGRESS_CoercePos(PROGRESS_INFO *infoPtr)
00492 {
00493     if(infoPtr->CurVal < infoPtr->MinVal)
00494         infoPtr->CurVal = infoPtr->MinVal;
00495     if(infoPtr->CurVal > infoPtr->MaxVal)
00496         infoPtr->CurVal = infoPtr->MaxVal;
00497 }
00498 
00499 
00500 /***********************************************************************
00501  *           PROGRESS_SetFont
00502  * Set new Font for progress bar
00503  */
00504 static HFONT PROGRESS_SetFont (PROGRESS_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
00505 {
00506     HFONT hOldFont = infoPtr->Font;
00507     infoPtr->Font = hFont;
00508     /* Since infoPtr->Font is not used, there is no need for repaint */
00509     return hOldFont;
00510 }
00511 
00512 static DWORD PROGRESS_SetRange (PROGRESS_INFO *infoPtr, int low, int high)
00513 {
00514     DWORD res = MAKELONG(LOWORD(infoPtr->MinVal), LOWORD(infoPtr->MaxVal));
00515 
00516     /* if nothing changes, simply return */
00517     if(infoPtr->MinVal == low && infoPtr->MaxVal == high) return res;
00518 
00519     infoPtr->MinVal = low;
00520     infoPtr->MaxVal = high;
00521     PROGRESS_CoercePos(infoPtr);
00522     InvalidateRect(infoPtr->Self, NULL, TRUE);
00523     return res;
00524 }
00525 
00526 /***********************************************************************
00527  *           ProgressWindowProc
00528  */
00529 static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
00530                                          WPARAM wParam, LPARAM lParam)
00531 {
00532     PROGRESS_INFO *infoPtr;
00533     static const WCHAR themeClass[] = {'P','r','o','g','r','e','s','s',0};
00534     HTHEME theme;
00535 
00536     TRACE("hwnd=%p msg=%04x wparam=%lx lParam=%lx\n", hwnd, message, wParam, lParam);
00537 
00538     infoPtr = (PROGRESS_INFO *)GetWindowLongPtrW(hwnd, 0);
00539 
00540     if (!infoPtr && message != WM_CREATE)
00541         return DefWindowProcW( hwnd, message, wParam, lParam );
00542 
00543     switch(message) {
00544     case WM_CREATE:
00545     {
00546     DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
00547         
00548         theme = OpenThemeData (hwnd, themeClass);
00549 
00550     dwExStyle &= ~(WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE);
00551     if (!theme) dwExStyle |= WS_EX_STATICEDGE;
00552         SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle);
00553     /* Force recalculation of a non-client area */
00554     SetWindowPos(hwnd, 0, 0, 0, 0, 0,
00555         SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
00556 
00557         /* allocate memory for info struct */
00558         infoPtr = Alloc (sizeof(PROGRESS_INFO));
00559         if (!infoPtr) return -1;
00560         SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
00561 
00562         /* initialize the info struct */
00563         infoPtr->Self = hwnd;
00564         infoPtr->MinVal = 0;
00565         infoPtr->MaxVal = 100;
00566         infoPtr->CurVal = 0;
00567         infoPtr->Step = 10;
00568         infoPtr->MarqueePos = 0;
00569         infoPtr->Marquee = FALSE;
00570         infoPtr->ColorBar = CLR_DEFAULT;
00571         infoPtr->ColorBk = CLR_DEFAULT;
00572         infoPtr->Font = 0;
00573 
00574         TRACE("Progress Ctrl creation, hwnd=%p\n", hwnd);
00575         return 0;
00576     }
00577 
00578     case WM_DESTROY:
00579         TRACE("Progress Ctrl destruction, hwnd=%p\n", hwnd);
00580         Free (infoPtr);
00581         SetWindowLongPtrW(hwnd, 0, 0);
00582         theme = GetWindowTheme (hwnd);
00583         CloseThemeData (theme);
00584         return 0;
00585 
00586     case WM_ERASEBKGND:
00587         return 1;
00588 
00589     case WM_GETFONT:
00590         return (LRESULT)infoPtr->Font;
00591 
00592     case WM_SETFONT:
00593         return (LRESULT)PROGRESS_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);
00594 
00595     case WM_PRINTCLIENT:
00596     case WM_PAINT:
00597         return PROGRESS_Paint (infoPtr, (HDC)wParam);
00598 
00599     case WM_TIMER:
00600         return PROGRESS_Timer (infoPtr, (INT)wParam);
00601 
00602     case WM_THEMECHANGED:
00603     {
00604         DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
00605         
00606         theme = GetWindowTheme (hwnd);
00607         CloseThemeData (theme);
00608         theme = OpenThemeData (hwnd, themeClass);
00609         
00610         /* WS_EX_STATICEDGE disappears when the control is themed */
00611         if (theme)
00612             dwExStyle &= ~WS_EX_STATICEDGE;
00613         else
00614             dwExStyle |= WS_EX_STATICEDGE;
00615         SetWindowLongW (hwnd, GWL_EXSTYLE, dwExStyle);
00616         
00617         InvalidateRect (hwnd, NULL, FALSE);
00618         return 0;
00619     }
00620 
00621     case PBM_DELTAPOS:
00622     {
00623     INT oldVal;
00624         oldVal = infoPtr->CurVal;
00625         if(wParam != 0) {
00626         infoPtr->CurVal += (INT)wParam;
00627         PROGRESS_CoercePos (infoPtr);
00628         TRACE("PBM_DELTAPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
00629             PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
00630             UpdateWindow( infoPtr->Self );
00631         }
00632         return oldVal;
00633     }
00634 
00635     case PBM_SETPOS:
00636     {
00637         UINT oldVal;
00638         oldVal = infoPtr->CurVal;
00639         if(oldVal != wParam) {
00640         infoPtr->CurVal = (INT)wParam;
00641         PROGRESS_CoercePos(infoPtr);
00642         TRACE("PBM_SETPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
00643             PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
00644             UpdateWindow( infoPtr->Self );
00645         }
00646         return oldVal;
00647     }
00648 
00649     case PBM_SETRANGE:
00650         return PROGRESS_SetRange (infoPtr, (int)LOWORD(lParam), (int)HIWORD(lParam));
00651 
00652     case PBM_SETSTEP:
00653     {
00654     INT oldStep;
00655         oldStep = infoPtr->Step;
00656         infoPtr->Step = (INT)wParam;
00657         return oldStep;
00658     }
00659 
00660     case PBM_GETSTEP:
00661         return infoPtr->Step;
00662 
00663     case PBM_STEPIT:
00664     {
00665     INT oldVal;
00666         oldVal = infoPtr->CurVal;
00667         infoPtr->CurVal += infoPtr->Step;
00668         if(infoPtr->CurVal > infoPtr->MaxVal)
00669         infoPtr->CurVal = infoPtr->MinVal;
00670         if(oldVal != infoPtr->CurVal)
00671     {
00672         TRACE("PBM_STEPIT: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
00673             PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
00674             UpdateWindow( infoPtr->Self );
00675     }
00676         return oldVal;
00677     }
00678 
00679     case PBM_SETRANGE32:
00680         return PROGRESS_SetRange (infoPtr, (int)wParam, (int)lParam);
00681 
00682     case PBM_GETRANGE:
00683         if (lParam) {
00684             ((PPBRANGE)lParam)->iLow = infoPtr->MinVal;
00685             ((PPBRANGE)lParam)->iHigh = infoPtr->MaxVal;
00686         }
00687         return wParam ? infoPtr->MinVal : infoPtr->MaxVal;
00688 
00689     case PBM_GETPOS:
00690         return infoPtr->CurVal;
00691 
00692     case PBM_SETBARCOLOR:
00693         infoPtr->ColorBar = (COLORREF)lParam;
00694     InvalidateRect(hwnd, NULL, TRUE);
00695     return 0;
00696 
00697     case PBM_GETBARCOLOR:
00698     return infoPtr->ColorBar;
00699 
00700     case PBM_SETBKCOLOR:
00701         infoPtr->ColorBk = (COLORREF)lParam;
00702     InvalidateRect(hwnd, NULL, TRUE);
00703     return 0;
00704 
00705     case PBM_GETBKCOLOR:
00706     return infoPtr->ColorBk;
00707 
00708     case PBM_SETSTATE:
00709         if(wParam != PBST_NORMAL)
00710             FIXME("state %04lx not yet handled\n", wParam);
00711         return PBST_NORMAL;
00712 
00713     case PBM_GETSTATE:
00714         return PBST_NORMAL;
00715 
00716     case PBM_SETMARQUEE:
00717     if(wParam != 0)
00718         {
00719             infoPtr->Marquee = TRUE;
00720             SetTimer(infoPtr->Self, ID_MARQUEE_TIMER, (UINT)lParam, NULL);
00721         }
00722         else
00723         {
00724             infoPtr->Marquee = FALSE;
00725             KillTimer(infoPtr->Self, ID_MARQUEE_TIMER);
00726         }
00727     return infoPtr->Marquee;
00728 
00729     default:
00730         if ((message >= WM_USER) && (message < WM_APP) && !COMCTL32_IsReflectedMessage(message))
00731         ERR("unknown msg %04x wp=%04lx lp=%08lx\n", message, wParam, lParam );
00732         return DefWindowProcW( hwnd, message, wParam, lParam );
00733     }
00734 }
00735 
00736 
00737 /***********************************************************************
00738  * PROGRESS_Register [Internal]
00739  *
00740  * Registers the progress bar window class.
00741  */
00742 void PROGRESS_Register (void)
00743 {
00744     WNDCLASSW wndClass;
00745 
00746     ZeroMemory (&wndClass, sizeof(wndClass));
00747     wndClass.style         = CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
00748     wndClass.lpfnWndProc   = (WNDPROC)ProgressWindowProc;
00749     wndClass.cbClsExtra    = 0;
00750     wndClass.cbWndExtra    = sizeof (PROGRESS_INFO *);
00751     wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
00752     wndClass.lpszClassName = PROGRESS_CLASSW;
00753 
00754     RegisterClassW (&wndClass);
00755 }
00756 
00757 
00758 /***********************************************************************
00759  * PROGRESS_Unregister [Internal]
00760  *
00761  * Unregisters the progress bar window class.
00762  */
00763 void PROGRESS_Unregister (void)
00764 {
00765     UnregisterClassW (PROGRESS_CLASSW, NULL);
00766 }

Generated on Sun May 27 2012 04:17:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.