| /* |
| * Progress control |
| * |
| * Copyright 1997 Dimitrie O. Paun |
| * |
| * TODO: |
| * - I do not know what to to on WM_[SG]ET_FONT |
| * Problems: |
| * - I think I do not compute correctly the numer of leds to be drawn |
| */ |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include "windows.h" |
| #include "sysmetrics.h" |
| #include "progress.h" |
| #include "graphics.h" |
| #include "heap.h" |
| #include "win.h" |
| #include "debug.h" |
| |
| /* Control configuration constants */ |
| |
| #define LED_WIDTH 8 |
| #define LED_GAP 2 |
| |
| /* Work constants */ |
| |
| #define UNKNOWN_PARAM(msg, wParam, lParam) WARN(progress, \ |
| "Unknown parameter(s) for message " #msg \ |
| "(%04x): wp=%04x lp=%08lx\n", msg, wParam, lParam); |
| |
| #define PROGRESS_GetInfoPtr(wndPtr) ((PROGRESS_INFO *)wndPtr->wExtra) |
| |
| |
| /*********************************************************************** |
| * PROGRESS_Paint |
| * Draw the arrows. The background need not be erased. |
| * If dc!=0, it draws on it |
| */ |
| static void PROGRESS_Paint(WND *wndPtr, HDC32 dc) |
| { |
| PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr); |
| HBRUSH32 ledBrush; |
| int rightBar, rightMost; |
| PAINTSTRUCT32 ps; |
| RECT32 rect; |
| HDC32 hdc; |
| |
| TRACE(progress, "paint pos=%d min=%d, max=%d\n", |
| infoPtr->CurVal, infoPtr->MinVal, infoPtr->MaxVal); |
| |
| /* get a dc */ |
| hdc = dc==0 ? BeginPaint32(wndPtr->hwndSelf, &ps) : dc; |
| |
| /* get the required brush */ |
| ledBrush = GetSysColorBrush32(COLOR_HIGHLIGHT); |
| |
| /* get rect for the bar, adjusted for the border */ |
| GetClientRect32(wndPtr->hwndSelf, &rect); |
| |
| /* draw the border */ |
| DrawEdge32(hdc, &rect, BDR_SUNKENOUTER, BF_RECT|BF_ADJUST|BF_MIDDLE); |
| rect.left++; rect.right--; rect.top++; rect.bottom--; |
| rightMost = rect.right; |
| |
| /* compute extent of progress bar */ |
| rightBar = rect.left + |
| MulDiv32(infoPtr->CurVal-infoPtr->MinVal, |
| rect.right - rect.left, |
| infoPtr->MaxVal-infoPtr->MinVal); |
| |
| /* now draw the bar */ |
| while(rect.left < rightBar) { |
| rect.right = rect.left+LED_WIDTH; |
| FillRect32(hdc, &rect, ledBrush); |
| rect.left = rect.right+LED_GAP; |
| } |
| |
| /* clean-up */ |
| if(!dc) |
| EndPaint32(wndPtr->hwndSelf, &ps); |
| } |
| |
| /*********************************************************************** |
| * PROGRESS_CoercePos |
| * Makes sure the current position (CUrVal) is within bounds. |
| */ |
| static void PROGRESS_CoercePos(WND *wndPtr) |
| { |
| PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr); |
| |
| if(infoPtr->CurVal < infoPtr->MinVal) |
| infoPtr->CurVal = infoPtr->MinVal; |
| if(infoPtr->CurVal > infoPtr->MaxVal) |
| infoPtr->CurVal = infoPtr->MaxVal; |
| } |
| |
| /*********************************************************************** |
| * ProgressWindowProc |
| */ |
| LRESULT WINAPI ProgressWindowProc(HWND32 hwnd, UINT32 message, |
| WPARAM32 wParam, LPARAM lParam) |
| { |
| WND *wndPtr = WIN_FindWndPtr(hwnd); |
| PROGRESS_INFO *infoPtr = PROGRESS_GetInfoPtr(wndPtr); |
| UINT32 temp; |
| |
| switch(message) |
| { |
| case WM_CREATE: |
| /* initialize the info struct */ |
| infoPtr->MinVal=0; |
| infoPtr->MaxVal=100; |
| infoPtr->CurVal=0; |
| infoPtr->Step=10; |
| TRACE(updown, "Progress Ctrl creation, hwnd=%04x\n", hwnd); |
| break; |
| |
| case WM_DESTROY: |
| TRACE(updown, "Progress Ctrl destruction, hwnd=%04x\n", hwnd); |
| break; |
| |
| case WM_ERASEBKGND: |
| /* pretend to erase it here, but we will do it in the paint |
| function to avoid flicker */ |
| return 1; |
| |
| case WM_GETFONT: |
| /* FIXME: What do we need to do? */ |
| break; |
| |
| case WM_SETFONT: |
| /* FIXME: What do we need to do? */ |
| break; |
| |
| case WM_PAINT: |
| PROGRESS_Paint(wndPtr, wParam); |
| break; |
| |
| case PBM_DELTAPOS: |
| if(lParam) |
| UNKNOWN_PARAM(PBM_DELTAPOS, wParam, lParam); |
| temp = infoPtr->CurVal; |
| if(wParam != 0){ |
| infoPtr->CurVal += (UINT16)wParam; |
| PROGRESS_CoercePos(wndPtr); |
| PROGRESS_Paint(wndPtr, 0); |
| } |
| return temp; |
| |
| case PBM_SETPOS: |
| if (lParam) |
| UNKNOWN_PARAM(PBM_SETPOS, wParam, lParam); |
| temp = infoPtr->CurVal; |
| if(temp != wParam){ |
| infoPtr->CurVal = (UINT16)wParam; |
| PROGRESS_CoercePos(wndPtr); |
| PROGRESS_Paint(wndPtr, 0); |
| } |
| return temp; |
| |
| case PBM_SETRANGE: |
| if (wParam) |
| UNKNOWN_PARAM(PBM_SETRANGE, wParam, lParam); |
| temp = MAKELONG(infoPtr->MinVal, infoPtr->MaxVal); |
| if(temp != lParam){ |
| infoPtr->MinVal = LOWORD(lParam); |
| infoPtr->MaxVal = HIWORD(lParam); |
| if(infoPtr->MaxVal <= infoPtr->MinVal) |
| infoPtr->MaxVal = infoPtr->MinVal+1; |
| PROGRESS_CoercePos(wndPtr); |
| PROGRESS_Paint(wndPtr, 0); |
| } |
| return temp; |
| |
| case PBM_SETSTEP: |
| if (lParam) |
| UNKNOWN_PARAM(PBM_SETSTEP, wParam, lParam); |
| temp = infoPtr->Step; |
| infoPtr->Step = (UINT16)wParam; |
| return temp; |
| |
| case PBM_STEPIT: |
| if (wParam || lParam) |
| UNKNOWN_PARAM(PBM_STEPIT, wParam, lParam); |
| temp = infoPtr->CurVal; |
| infoPtr->CurVal += infoPtr->Step; |
| if(infoPtr->CurVal > infoPtr->MaxVal) |
| infoPtr->CurVal = infoPtr->MinVal; |
| if(temp != infoPtr->CurVal) |
| PROGRESS_Paint(wndPtr, 0); |
| return temp; |
| |
| default: |
| if (message >= WM_USER) |
| ERR(progress, "unknown msg %04x wp=%04x lp=%08lx\n", |
| message, wParam, lParam ); |
| return DefWindowProc32A( hwnd, message, wParam, lParam ); |
| } |
| |
| return 0; |
| } |
| |
| |
| |