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

📄 status.c

📁 <Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.
💻 C
📖 第 1 页 / 共 2 页
字号:
                } else {
                        if(plist->isselected) {
                                hDC = GetDC(hWnd);
                                InitDC(hDC);
                                StatusButtonUp(hDC, ip);
                                ReleaseDC(hWnd, hDC);
                                plist->isselected = FALSE;
                        }
                }
        }
        GlobalUnlock(hitems);
        break;


    case WM_DESTROY:

        hitems = (HANDLE) GetWindowLong(hWnd, 0);
        GlobalUnlock(hitems);
        GlobalFree(hitems);

        SetWindowLong(hWnd, 0, 0L);
        break;

    case SM_NEW:
        hitems = (HANDLE) GetWindowLong(hWnd, 0);
        if (hitems != NULL) {
                GlobalFree(hitems);
        }
        hitems = (HANDLE) wParam;
        if (hitems == NULL) {
                SetWindowLong(hWnd, 0, 0L);
                InvalidateRect(hWnd, NULL, TRUE);
                break;
        }
        plist = (PILIST) GlobalLock(hitems);
        if (plist == NULL) {
                SetWindowLong(hWnd, 0, 0L);
                InvalidateRect(hWnd, NULL, TRUE);
                break;
        }
        plist->selitem = -1;
        StatusResize(hWnd, plist);
        GlobalUnlock(hitems);
        SetWindowLong(hWnd, 0, (LONG)hitems);
        InvalidateRect(hWnd, NULL, TRUE);
        break;

    case SM_SETTEXT:
        hitems = (HANDLE) GetWindowLong(hWnd, 0);
        if (hitems == NULL) {
                break;
        }
        plist = (PILIST) GlobalLock(hitems);
        ip = StatusGetItem(plist, wParam);
        if (ip != NULL) {
                if (lParam == 0) {
                        ip->text[0] = '\0';
                } else {
                        strncpy(ip->text, (LPSTR) lParam, SF_MAXLABEL);
                        ip->text[SF_MAXLABEL] = '\0';
                }

                /* if this is a variable width field, we need to redo
                 * all size calcs in case the field width has changed.
                 * in that case, we need to repaint the entire window
                 * and not just this field - so set rc to indicate the
                 * area to be redrawn.
                 */
                if (ip->flags & SF_VAR) {
                        StatusResize(hWnd, plist);
                        GetClientRect(hWnd, &rc);
                        RedrawWindow(hWnd, &rc, NULL,
                                RDW_INVALIDATE|RDW_ERASE|RDW_UPDATENOW);
                } else {
                        /* instead of just invalidating the window, we can
                         * force the window to be repainted now. This is
                         * essential for status updates during a busy
                         * loop when no messages are being processed,
                         * but we should still update the user on what's
                         * happening.
                         */
                        RedrawWindow(hWnd, &ip->rc, NULL,
                                RDW_INVALIDATE|RDW_NOERASE|RDW_UPDATENOW);
                }

        }
        GlobalUnlock(hitems);
        break;

    default:
        return(DefWindowProc(hWnd, message, wParam, lParam));
    }
    return 0;
}

/***************************************************************************
 * Function: StatusResize
 *
 * Purpose:
 *
 * Position the labels and buttons within the status window 
 */
void
StatusResize(HWND hWnd, PILIST iplistp)
{
        RECT rc;
        int curpos_right, curpos_left;
        int height, width;
        int i;
        PSTATEL ip;


        if (iplistp == NULL) {
                return;
        }
        GetClientRect(hWnd, &rc);
        curpos_left = rc.left + status_charwidth / 2;
        curpos_right = rc.right - (status_charwidth / 2);

        /* loop through all items setting their position rects.
         * items are flagged as being left or right. We place them
         * in order starting at the left and the right, with a single
         * char's width between each item
         */
        for (i = 0; i < iplistp->nitems; i++) {
                ip = &iplistp->statels[i];

                width = StatusCalcWidth(hWnd, ip);
                height = StatusCalcHeight(hWnd, ip);
                ip->rc.top = (rc.bottom - height) / 2;
                ip->rc.bottom = ip->rc.top + height;

                /* see if  this item fits. Items that partially fit
                 * are placed reduced in size.
                 */
                if (ip->flags & SF_LEFT) {

                        if (curpos_left+width >= curpos_right) {
                                /* doesn't completely fit-does it partly? */
                                if ((curpos_left + 1) >= curpos_right){

                                        /* no - this item does not fit */
                                        ip->rc.left = 0;
                                        ip->rc.right = 0;
                                } else {
                                        /* partial fit */
                                        ip->rc.left = curpos_left;
                                        ip->rc.right = curpos_right - 1;
                                        curpos_left = curpos_right;
                                }
                        } else {
                                /* complete fit */
                                ip->rc.left = curpos_left;
                                ip->rc.right = curpos_left + width;
                                curpos_left += width + 1;
                        }
                } else {

                        /* same size check for right-aligned items */
                        if (curpos_right-width <= curpos_left) {

                                /* partial fit ? */
                                if (curpos_right <= curpos_left+1) {
                                        ip->rc.left = 0;
                                        ip->rc.right = 0;
                                } else {
                                        /* yes - partial fit */
                                        ip->rc.left = curpos_left + 1;
                                        ip->rc.right = curpos_right;
                                        curpos_right = curpos_left;
                                }
                        } else {
                                /* complete fit */
                                ip->rc.right = curpos_right;
                                ip->rc.left = curpos_right - width;
                                curpos_right -= (width + 1);
                        }
                }
        }
}


/***************************************************************************
 * Function: StatusPaint
 *
 * Purpose:
 *
 * Paint the status window
 */
void
StatusPaint(HWND hWnd, PILIST iplistp)
{
        RECT rc;
        HDC hDC;
        PAINTSTRUCT ps;
        int i;
        PSTATEL ip;
        HPEN hpenOld;

        GetClientRect(hWnd, &rc);
        hDC = BeginPaint(hWnd, &ps);
        InitDC(hDC);

        RaiseRect(hDC, &rc);
        if (iplistp == NULL) {
                EndPaint(hWnd, &ps);
                return;
        }
        for (i =0; i < iplistp->nitems; i++) {
                ip = &iplistp->statels[i];

                if (ip->rc.left == ip->rc.right) {
                        continue;
                }
                if (ip->type == SF_STATIC) {
                        if (ip->flags & SF_RAISE) {
                                RaiseRect(hDC, &ip->rc);
                        } else if (ip->flags & SF_LOWER) {
                                LowerRect(hDC, &ip->rc);
                        }
                        rc = ip->rc;
                        rc.left += (status_charwidth / 2);
                        rc.right--;
                        rc.top++;
                        rc.bottom--;
                        hpenOld = SelectObject(hDC, hpenNeutral);
                        Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
                        SelectObject(hDC, hpenOld);
                        DrawText(hDC, ip->text, lstrlen(ip->text), &rc,
                                        DT_LEFT | DT_VCENTER);
                } else {
                        StatusButtonUp(hDC, ip);
                }
        }

        EndPaint(hWnd, &ps);
}

/***************************************************************************
 * Function: RaiseRect
 *
 * Purpose:
 *
 */
void
RaiseRect(HDC hDC, LPRECT rcp)
{
        TopLeft(hDC, rcp, hpenHilight, FALSE);
        BottomRight(hDC, rcp, hpenLowlight, FALSE);
}

/***************************************************************************
 * Function: LowerRect
 *
 * Purpose:
 *
 */ 
void
LowerRect(HDC hDC, LPRECT rcp)
{
        TopLeft(hDC, rcp, hpenLowlight, FALSE);
        BottomRight(hDC, rcp, hpenHilight, FALSE);
}

/***************************************************************************
 * Function: StatusButtonUp
 *
 * Purpose:
 *
 */
void
StatusButtonUp(HDC hDC, PSTATEL ip)
{
        RECT rc;
        HPEN hpenOld;

        rc = ip->rc;
        TopLeft(hDC, &rc, hpenBlack, TRUE);
        BottomRight(hDC, &rc, hpenBlack, FALSE);

        rc.top++;
        rc.bottom--;
        rc.left++;
        rc.right--;
        TopLeft(hDC, &rc, hpenHilight, FALSE);
        BottomRight(hDC, &rc, hpenLowlight, TRUE);

        rc.top++;
        rc.bottom--;
        rc.left++;
        rc.right--;
        BottomRight(hDC, &rc, hpenLowlight, TRUE);
        rc.bottom--;
        rc.right--;
        hpenOld = SelectObject(hDC, hpenNeutral);
        Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
        SelectObject(hDC, hpenOld);
        DrawText(hDC, ip->text, lstrlen(ip->text), &rc, DT_CENTER | DT_VCENTER);
}

/***************************************************************************
 * Function: StatusButtonDown
 *
 * Purpose:
 *
 */
void
StatusButtonDown(HDC hDC, PSTATEL ip)
{
        RECT rc;
        HPEN hpenOld;

        rc = ip->rc;
        TopLeft(hDC, &rc, hpenBlack, TRUE);
        BottomRight(hDC, &rc, hpenBlack, FALSE);

        rc.top++;
        rc.bottom--;
        rc.left++;
        rc.right--;
        TopLeft(hDC, &rc, hpenLowlight, TRUE);
        rc.top++;
        rc.left++;
        TopLeft(hDC, &rc, hpenNeutral, TRUE);
        rc.top++;
        rc.left++;
        TopLeft(hDC, &rc, hpenNeutral, TRUE);
        rc.top++;
        rc.left++;
        hpenOld = SelectObject(hDC, hpenNeutral);
        Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
        SelectObject(hDC, hpenOld);
        DrawText(hDC, ip->text, lstrlen(ip->text), &rc, DT_CENTER | DT_VCENTER);
}

/***************************************************************************
 * Function: TopLeft
 *
 * Purpose:
 *
 */
void
TopLeft(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners)
{
        HPEN hpenOld;
        int x, y;

        hpenOld = SelectObject(hDC, hpen);
        x = rcp->right - 1;
        y = rcp->bottom;
        if (!bCorners) {
                x--;
                y--;
        }
        MoveToEx(hDC, x, rcp->top, NULL);
        LineTo(hDC, rcp->left, rcp->top);
        LineTo(hDC, rcp->left, y);
        SelectObject(hDC, hpenOld);
}

/***************************************************************************
 * Function: BottomRight
 *
 * Purpose:
 *
 */
void
BottomRight(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners)
{
        HPEN hpenOld;
        int x, y;

        hpenOld = SelectObject(hDC, hpen);
        x = rcp->left - 1;
        y = rcp->top;
        if (!bCorners) {
                x++;
                y++;
        }
        MoveToEx(hDC, rcp->right-1, y, NULL);
        LineTo(hDC, rcp->right-1, rcp->bottom-1);
        LineTo(hDC, x, rcp->bottom-1);
        SelectObject(hDC, hpenOld);
}

/***************************************************************************
 * Function: StatusGetItem
 *
 * Purpose:
 *
 */
PSTATEL
StatusGetItem(PILIST plist, int id)
{
        int i;

        if (plist == NULL) {
                return(NULL);
        }
        for (i = 0; i < plist->nitems; i++) {
                if (plist->statels[i].id == id) {
                        return(&plist->statels[i]);
                }
        }
        return(NULL);
}

/***************************************************************************
 * Function: StatusCalcWidth
 *
 * Purpose:
 *
 * Calculate the width of a given field. This is the width in characters
 * multiplied by the average character width, plus a few units for
 * borders.
 *
 * If SF_VAR is set, this field size varies depending on the text, so
 * we use GetTextExtent for the field size. If SF_VAR is selected, the caller
 * can specify that the size is not to exceed the (width * avecharwidth)
 * size (using SF_SZMAX) or that it is not be less than it (SF_SZMIN).
 */
int
StatusCalcWidth(HWND hWnd, PSTATEL ip)
{
        int ch_size, t_size;
        SIZE sz;
        HDC hDC;

        ch_size = ip->width * status_charwidth;
        if (ip->flags & SF_VAR) {
                hDC = GetDC(hWnd);
                InitDC(hDC);
                GetTextExtentPoint(hDC, ip->text, lstrlen(ip->text), &sz);
                ReleaseDC(hWnd, hDC);
                t_size = sz.cx;

                /*
                 * check this size against min/max size if
                 * requested
                 */

                if (ip->flags & SF_SZMIN) {
                        if (ch_size > t_size) {
                                t_size = ch_size;
                        }
                }
                if (ip->flags & SF_SZMAX) {
                        if (ch_size < t_size) {
                                t_size = ch_size;
                        }
                }
                ch_size = t_size;
        }

        if (ch_size != 0) {
                if (ip->type == SF_BUTTON) {
                        return(ch_size+6);
                } else {
                        return(ch_size+4);
                }
        } else {
                return(0);
        }
}

/***************************************************************************
 * Function: StatusCalcHeight
 *
 * Purpose:
 *
 * Calculate the height of a given field
 */
int
StatusCalcHeight(HWND hWnd, PSTATEL ip)
{
        int size;

        size = status_charheight;
        if (ip->type == SF_BUTTON) {
                return(size + 6);
        } else {
                return(size + 2);
        }
}

⌨️ 快捷键说明

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