⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 progressbar.c

📁 有了操作系统、TCP/IP协议栈、文件系统
💻 C
字号:
/*** $Id: progressbar.c,v 1.31 2005/01/31 09:12:48 clear Exp $**** progressbar.c: the Progress Bar Control module.**** Copyright (C) 2003, 2004 Feynman Software.** Copyright (C) 1999 ~ 2002 Wei Yongming.**** Current maintainer: Wei Yonming.**** Note:**   Originally by Zhao Jianghua. **** Create date: 1999/8/29***//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program 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 General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//*** TODO:*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "ctrl/ctrlhelper.h"#include "ctrl/progressbar.h"#include "cliprect.h"#include "internals.h"#include "ctrlclass.h"#ifdef _CTRL_PROGRESSBAR#include "ctrlmisc.h"#include "progressbar_impl.h"#ifdef _FLAT_WINDOW_STYLE#define  WIDTH_PBAR_BORDER  1#else#define  WIDTH_PBAR_BORDER  2#endifstatic int ProgressBarCtrlProc (HWND hwnd, int message, WPARAM wParam, LPARAM lParam);BOOL RegisterProgressBarControl (void){    WNDCLASS WndClass;    WndClass.spClassName = CTRL_PROGRESSBAR;    WndClass.dwStyle     = WS_NONE;    WndClass.dwExStyle   = WS_EX_NONE;    WndClass.hCursor     = GetSystemCursor (0);    WndClass.iBkColor    = GetWindowElementColor (BKC_CONTROL_DEF);    WndClass.WinProc     = ProgressBarCtrlProc;    return AddNewControlClass (&WndClass) == ERR_OK;}#if 0void ProgressBarControlCleanup (void){    // do nothing    return;}#endifstatic void pbarOnDraw (HWND hwnd, HDC hdc, PROGRESSDATA* pData, BOOL fVertical){    RECT    rcClient;    int     x, y, w, h;    ldiv_t   ndiv_progress;    unsigned int     nAllPart;    unsigned int     nNowPart;    int     whOne, nRem;    int     ix, iy;    int     i;    int     step;        if (pData->nMax == pData->nMin)        return;        if ((pData->nMax - pData->nMin) > 5)        step = 5;    else        step = 1;    GetClientRect (hwnd, &rcClient);    x = rcClient.left + WIDTH_PBAR_BORDER;    y = rcClient.top + WIDTH_PBAR_BORDER;    w = RECTW (rcClient) - (WIDTH_PBAR_BORDER << 1);    h = RECTH (rcClient) - (WIDTH_PBAR_BORDER << 1);    ndiv_progress = ldiv (pData->nMax - pData->nMin, step);    nAllPart = ndiv_progress.quot;        ndiv_progress = ldiv (pData->nPos - pData->nMin, step);    nNowPart = ndiv_progress.quot;    if (fVertical)        ndiv_progress = ldiv (h, nAllPart);    else        ndiv_progress = ldiv (w, nAllPart);            whOne = ndiv_progress.quot;    nRem = ndiv_progress.rem;    SetBrushColor (hdc, GetWindowElementColorEx (hwnd, BKC_HILIGHT_NORMAL));     if (whOne >= 4) {        if (fVertical) {            for (i = 0, iy = y + h - 1; i < nNowPart; ++i) {                if ((iy - whOne) < y)                     whOne = iy - y;                FillBox (hdc, x + 1, iy - whOne, w - 2, whOne - 1);                iy -= whOne;                if(nRem > 0) {                    iy --;                    nRem --;                }            }        }        else {            for (i = 0, ix = x + 1; i < nNowPart; ++i) {                if ((ix + whOne) > (x + w))                     whOne = x + w - ix;                FillBox (hdc, ix, y + 1, whOne - 1, h - 2);                ix += whOne;                if(nRem > 0) {                    ix ++;                    nRem --;                }            }        }    }    else {        // no vertical support        double d = (nNowPart*1.0)/nAllPart;        if (fVertical) {            int prog = (int)(h*d);            FillBox (hdc, x + 1, rcClient.bottom - WIDTH_PBAR_BORDER - prog,                     w - 2, prog);        }        else {            char szText[8];            SIZE text_ext;            RECT rc_clip = rcClient;            int prog = (int)(w*d);            FillBox (hdc, x, y + 1, (int)(w*d), h - 2);            SetBkMode (hdc, BM_TRANSPARENT);            sprintf (szText, "%d%%", (int)(d*100));            GetTextExtent (hdc, szText, -1, &text_ext);            x += ((w - text_ext.cx) >> 1);            y += ((h - text_ext.cy) >> 1);            rc_clip.right = prog;            SelectClipRect (hdc, &rc_clip);            SetTextColor (hdc, GetWindowElementColorEx (hwnd, FGC_HILIGHT_NORMAL));            SetBkColor (hdc, PIXEL_black);            TextOut (hdc, x, y, szText);            rc_clip.right = rcClient.right;            rc_clip.left = prog;            SelectClipRect (hdc, &rc_clip);            SetTextColor (hdc, GetWindowElementColorEx (hwnd, FGC_CONTROL_NORMAL));            SetBkColor (hdc, PIXEL_lightwhite);            TextOut (hdc, x, y, szText);        }    }}static void pbarNormalizeParams (const CONTROL* pCtrl,                 PROGRESSDATA* pData, BOOL fNotify){    if (pData->nPos > pData->nMax) {        if (fNotify)            NotifyParent ((HWND)pCtrl, pCtrl->id, PBN_REACHMAX);        pData->nPos = pData->nMax;    }    if (pData->nPos < pData->nMin) {        if (fNotify)            NotifyParent ((HWND)pCtrl, pCtrl->id, PBN_REACHMIN);        pData->nPos = pData->nMin;    }}static void pbarOnNewPos (const CONTROL* pCtrl, PROGRESSDATA* pData, unsigned int new_pos){    double d;    unsigned int old_pos;    int range = pData->nMax - pData->nMin;    int old_prog, new_prog, width;    RECT rc_client;    if (range == 0 || new_pos == pData->nPos)        return;    old_pos = pData->nPos;    pData->nPos = new_pos;    pbarNormalizeParams (pCtrl, pData, pCtrl->dwStyle & PBS_NOTIFY);    GetClientRect ((HWND)pCtrl, &rc_client);    if (pCtrl->dwStyle & PBS_VERTICAL)        width = RECTH (rc_client) - (WIDTH_PBAR_BORDER << 1);    else        width = RECTW (rc_client) - (WIDTH_PBAR_BORDER << 1);    old_prog = old_pos - pData->nMin;    d = (old_prog*1.0)/range;    old_prog = (int) (d * width);    new_prog = pData->nPos - pData->nMin;    d = (new_prog*1.0)/range;    new_prog = (int) (d * width);    if (pCtrl->dwStyle & PBS_VERTICAL) {        old_prog = rc_client.bottom - WIDTH_PBAR_BORDER - old_prog;        new_prog = rc_client.bottom - WIDTH_PBAR_BORDER - new_prog;        rc_client.top = MIN (old_prog, new_prog) - 2;        rc_client.bottom = MAX (old_prog, new_prog) + 2;    }    else {        HDC hdc;        char text [10];        RECT rc_text;        SIZE text_ext;        sprintf (text, "%d%%", (int)(d*100));        hdc = GetClientDC ((HWND)pCtrl);        GetTextExtent (hdc, text, -1, &text_ext);        ReleaseDC (hdc);        rc_text.left = rc_client.left + ((RECTW(rc_client) - text_ext.cx) >> 1);        rc_text.top = rc_client.top + ((RECTH(rc_client) - text_ext.cy) >> 1);        rc_text.right = rc_text.left + text_ext.cx;        rc_text.bottom = rc_text.top + text_ext.cy;        InvalidateRect ((HWND)pCtrl, &rc_client, TRUE);        rc_client.left = MIN (old_prog, new_prog);        rc_client.right = MAX (old_prog, new_prog);    }    InvalidateRect ((HWND)pCtrl, &rc_client, TRUE);}static int ProgressBarCtrlProc (HWND hwnd, int message, WPARAM wParam, LPARAM lParam){    HDC           hdc;    PCONTROL      pCtrl;    PROGRESSDATA* pData;        pCtrl = Control (hwnd);         switch (message)    {        case MSG_CREATE:            if (!(pData = malloc (sizeof (PROGRESSDATA)))) {                fprintf(stderr, "Create progress bar control failure!\n");                return -1;            }                        pData->nMax     = 100;            pData->nMin     = 0;            pData->nPos     = 0;            pData->nStepInc = 10;                        pCtrl->dwAddData2 = (DWORD)pData;        break;            case MSG_DESTROY:            free ((void *)(pCtrl->dwAddData2));        break;        case MSG_NCPAINT:            return 0;                case MSG_GETDLGCODE:            return DLGC_STATIC;        case MSG_GETTEXTLENGTH:        case MSG_GETTEXT:        case MSG_SETTEXT:            return -1;        case MSG_PAINT:        {            RECT rcClient;                        GetClientRect (hwnd, &rcClient);            hdc = BeginPaint (hwnd);#ifdef _FLAT_WINDOW_STYLE            SetPenColor (hdc, GetWindowElementColorEx (hwnd, BKC_CONTROL_DEF));            Rectangle (hdc, rcClient.left, rcClient.top,                              rcClient.right - 1, rcClient.bottom - 1);            SetPenColor (hdc, GetWindowElementColorEx (hwnd, FGC_CONTROL_NORMAL));            Rectangle (hdc, rcClient.left + 1, rcClient.top + 1,                              rcClient.right - 2, rcClient.bottom - 2);#else            Draw3DThickFrameEx (hdc, hwnd, rcClient.left, rcClient.top,                              rcClient.right - 1, rcClient.bottom - 1,                              DF_3DBOX_PRESSED | DF_3DBOX_NOTFILL, 0);#endif            pbarOnDraw (hwnd, hdc, (PROGRESSDATA *)pCtrl->dwAddData2,                             pCtrl->dwStyle & PBS_VERTICAL);            EndPaint (hwnd, hdc);            return 0;        }        case PBM_SETRANGE:            pData = (PROGRESSDATA *)pCtrl->dwAddData2;            if (wParam == lParam)                return PB_ERR;            pData->nMin = MIN (wParam, lParam);            pData->nMax = MAX (wParam, lParam);            if (pData->nPos > pData->nMax)                pData->nPos = pData->nMax;            if (pData->nPos < pData->nMin)                pData->nPos = pData->nMin;            if (pData->nStepInc > (pData->nMax - pData->nMin))                pData->nStepInc = pData->nMax - pData->nMin;            InvalidateRect (hwnd, NULL, TRUE);            return PB_OKAY;                case PBM_SETSTEP:            pData = (PROGRESSDATA *)pCtrl->dwAddData2;            if (wParam > (pData->nMax - pData->nMin))                return PB_ERR;            pData->nStepInc = wParam;            return PB_OKAY;                case PBM_SETPOS:            pData = (PROGRESSDATA *)pCtrl->dwAddData2;                        if (pData->nPos == wParam)                return PB_OKAY;            pbarOnNewPos (pCtrl, pData, wParam);            return PB_OKAY;                case PBM_DELTAPOS:            pData = (PROGRESSDATA *)pCtrl->dwAddData2;            if (wParam == 0)                return PB_OKAY;                        pbarOnNewPos (pCtrl, pData, pData->nPos + wParam);            return PB_OKAY;                case PBM_STEPIT:            pData = (PROGRESSDATA *)pCtrl->dwAddData2;                        if (pData->nStepInc == 0)                return PB_OKAY;            pbarOnNewPos (pCtrl, pData, pData->nPos + pData->nStepInc);            return PB_OKAY;                    case MSG_FONTCHANGED:            InvalidateRect (hwnd, NULL, TRUE);            break;    }        return DefaultControlProc (hwnd, message, wParam, lParam);}#endif /* _CTRL_PROGRESSBAR */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -