Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprogress.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
1.7.6.1
|