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

📄 listbox.c

📁 TN-kernel内核针对LPC系列ARM7处理器和S3C44B0X重新定制好的源代码包。内含Nano-X GUI。
💻 C
📖 第 1 页 / 共 4 页
字号:
{
    RECT rcInv;

    if (pos < pData->itemTop || pos > (pData->itemTop + pData->itemVisibles))
        return;

    GetClientRect (hwnd, &rcInv);
    rcInv.top = (pos - pData->itemTop)*pData->itemHeight;
    rcInv.bottom = rcInv.top + pData->itemHeight;

    InvalidateRect (hwnd, &rcInv, fEBk);
}

static BOOL lstInvalidateUnderItem (HWND hwnd, PLISTBOXDATA pData, int pos)
{
    RECT rcInv;

    if (pos > (pData->itemTop + pData->itemVisibles))
        return FALSE;

    if (pos <= pData->itemTop) {
        InvalidateRect (hwnd, NULL, TRUE);
        return TRUE;
    }

    GetClientRect (hwnd, &rcInv);

    lstGetItemsRect (pData, pos, -1, &rcInv);

    if (rcInv.top < rcInv.bottom)
        InvalidateRect (hwnd, &rcInv, TRUE);

    return TRUE;
}

static PLISTBOXITEM lstGetItem (PLISTBOXDATA pData, int pos)
{
    int i;
    PLISTBOXITEM plbi;

    plbi = pData->head;
    for (i=0; i < pos && plbi; i++)
        plbi = plbi->next;

    return plbi;
}

static int lstFindItem (PLISTBOXDATA pData, int start, char* key, BOOL bExact)
{
    PLISTBOXITEM plbi;
    int keylen = strlen (key);

    if (start >= (pData->itemCount - 1))
        start = 0;

    plbi = lstGetItem (pData, start);

    while (plbi)
    {
        if (bExact && (keylen != strlen (plbi->key))) {
            plbi = plbi->next;
            start ++;
            continue;
        }

        if (strncasecmp (key, plbi->key, keylen) == 0)
            return start;

        plbi = plbi->next;
        start ++;
    }

    return LB_ERR;
}

static void lstOnDrawSListBoxItems (HDC hdc, DWORD dwStyle,
                PLISTBOXDATA pData, int width)
{
    PLISTBOXITEM plbi;
    int i;
    int x = 0, y = 0;
    int offset;
    RECT rc;
    COLORREF bk;

    plbi = lstGetItem (pData, pData->itemTop);

    for (i = 0; plbi && i < (pData->itemVisibles + 1); i++) {

        if (plbi->dwFlags & LBIF_SELECTED) {
            SetBkColor (hdc, bk = BLUE);
            SetTextColor (hdc, WHITE);
        }
        else {
            SetBkColor (hdc, bk = WHITE);
            SetTextColor (hdc, BLACK);
        }
        rc.left = 0;
        rc.top = y;
        rc.right = width;
        rc.bottom = y + pData->itemHeight;
        FastFillRect(hdc, &rc, bk);

        if (dwStyle & LBS_CHECKBOX) {
            x = LST_INTER_BMPTEXT;
            if (plbi->dwFlags & LBIF_CHECKED)
                offset = 0;
            else if (plbi->dwFlags & LBIF_PARTCHECKED)
                offset = LST_WIDTH_CHECKMARK << 1;
            else
                offset = LST_WIDTH_CHECKMARK;
#if 0        /* fix: no bitmap */
            FillBoxWithBitmapPart (hdc,
                x, y + ((pData->itemHeight - LST_HEIGHT_CHECKMARK)>>1),
                LST_WIDTH_CHECKMARK, LST_HEIGHT_CHECKMARK,
                0, 0,
                &sg_bmpCheckMark,
                offset, 0);
#endif
            x += LST_WIDTH_CHECKMARK + LST_INTER_BMPTEXT;
        }
#if 0        /* fix: no icon */
        if (dwStyle & LBS_USEICON && plbi->dwData) {
            DrawIcon (hdc,
                x, y, pData->itemHeight, pData->itemHeight,
                (HICON) plbi->dwData);
            x += pData->itemHeight + LST_INTER_BMPTEXT;
        }
#endif

/* jmt: should be SYSTEM_FIXED_FONT because of minigui's GetSysCharXXX() */
#if 0
        SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
#endif
        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
        TextOut (hdc, x+2, y, plbi->key,-1);

        y += pData->itemHeight;
        plbi = plbi->next;
    }
}

static int lstSelectItem (DWORD dwStyle, PLISTBOXDATA pData, int newSel)
{
    PLISTBOXITEM plbi, newItem;
    int index;

    newItem = lstGetItem (pData, newSel);
#if 1        /* jmt: fixed if no item added */
    if (!newItem) return -1;
#endif
#ifdef _DEBUG
    if (!newItem)
        fprintf (stderr, "ASSERT failed: return value of lstGetItem"
                         " in lstSelectItem.\n");
#endif

    if (dwStyle & LBS_MULTIPLESEL) {
        newItem->dwFlags ^= LBIF_SELECTED;
        return newSel;
    }

    index = 0;
    plbi = pData->head;
    while (plbi) {
        if (plbi->dwFlags & LBIF_SELECTED) {
            if (index != newSel) {
                plbi->dwFlags &= ~LBIF_SELECTED;
                newItem->dwFlags |= LBIF_SELECTED;
                return index;
            }
            break;
        }

        plbi = plbi->next;
        index ++;
    }

    newItem->dwFlags |= LBIF_SELECTED;
    return -1;
}

static void lstDrawFocusRect (HDC hdc, PLISTBOXDATA pData, RECT* rc)
{
    HGDIOBJ oldbrush,oldpen;

    if (pData->itemHilighted < pData->itemTop
            || pData->itemHilighted > (pData->itemTop + pData->itemVisibles))
        return;

    if (pData->dwFlags & LBF_FOCUS) {
        lstGetItemsRect (pData, pData->itemHilighted, pData->itemHilighted, rc);
#if 0
        InflateRect (rc, -1, -1);

        FocusRect (hdc, rc->left - 1, rc->top, rc->right, rc->bottom);
#else
        oldbrush=SelectObject(hdc, GetStockObject(NULL_BRUSH));
        oldpen=SelectObject(hdc, CreatePen(PS_SOLID, 1,
                                GetSysColor(COLOR_BTNHIGHLIGHT)));
#if 0
        GdSetMode(MWMODE_XOR);
#endif
        Rectangle (hdc, rc->left, rc->top, rc->right, rc->bottom);
#if 0
        GdSetMode(MWMODE_SET);
#endif
        SelectObject(hdc,oldbrush);
        DeleteObject(SelectObject(hdc,oldpen));
#endif
    }
}

static void lstCalcParams (const RECT* rcClient, PLISTBOXDATA pData)
{
#define RECTHP(prc)  (prc->bottom - prc->top)
    pData->itemVisibles = (RECTHP (rcClient)) / pData->itemHeight;

#if 1        /* test calculation of itemVisibles */
    if( ((RECTHP (rcClient)) % pData->itemHeight) )
            pData->itemVisibles++;
#endif
}

extern BOOL SetScrollPos (HWND hWnd, int iSBar, int iNewPos);
extern BOOL EnableScrollBar (HWND hWnd, int iSBar, BOOL bEnable);

static void lstSetVScrollInfo (HWND hwnd, PLISTBOXDATA pData, BOOL fRedraw)
{
    SCROLLINFO si;

    if (pData->itemVisibles >= pData->itemCount)
    {
        SetScrollPos (hwnd, SB_VERT, 0);
        EnableScrollBar (hwnd, SB_VERT, FALSE);
        return;
    }

    si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
    si.nMax = pData->itemCount - 1;
    si.nMin = 0;
    si.nPage = min (pData->itemVisibles, (pData->itemCount - pData->itemTop));
    si.nPos = pData->itemTop;

    SetScrollInfo (hwnd, SB_VERT, &si, fRedraw);
    EnableScrollBar (hwnd, SB_VERT, TRUE);
}

LRESULT CALLBACK
ListboxCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC             hdc;
    HWND            pCtrl;
    PLISTBOXDATA    pData;
    DWORD           dwStyle;

    pCtrl   = hwnd;
    dwStyle = pCtrl->style;

    switch (message)
    {
        case WM_CREATE:
            pData = (LISTBOXDATA*) GdMalloc (sizeof(LISTBOXDATA));
            if (pData == NULL)
                return -1;

            pCtrl->userdata = (DWORD)pData;
            if (!lstInitListBoxData (hwnd, pData, DEF_LB_BUFFER_LEN)) {
                free (pData);
                return -1;
            }
        break;

        case WM_SIZE:
        {
            RECT rc;

            pData = (PLISTBOXDATA)pCtrl->userdata;
            GetClientRect(hwnd, &rc);
            lstCalcParams (&rc, pData);
        }
        break;

        case WM_DESTROY:
            pData = (PLISTBOXDATA)pCtrl->userdata;
            lstListBoxCleanUp (pData);
            free (pData);
        break;

        case LB_RESETCONTENT:
            pData = (PLISTBOXDATA)pCtrl->userdata;
            lstResetListBoxContent (pData);
            InvalidateRect (hwnd, NULL, TRUE);
        break;

        case LB_ADDSTRING:
        case LB_INSERTSTRING:
        {
            char* string = NULL;
            PLISTBOXITEMINFO plbii = NULL;
            PLISTBOXITEM newItem;
            int pos;

            if (dwStyle & LBS_CHECKBOX || dwStyle & LBS_USEICON) {
                plbii = (PLISTBOXITEMINFO)lParam;
                if (!plbii)
                    return LB_ERR;

                string = plbii->string;
            }
            else {
                string = (char*)lParam;
                if (string == NULL || string [0] == '\0')
                    return LB_ERR;
            }

            pData = (PLISTBOXDATA)pCtrl->userdata;
            newItem = lstAllocItem (pData);
            if (!newItem) {
                NotifyParent (hwnd, pCtrl->id, LBN_ERRSPACE);
                return LB_ERRSPACE;
            }

            newItem->key = FixStrAlloc (strlen (string));
            strcpy (newItem->key, string);
            newItem->dwFlags = LBIF_NORMAL;
            if (plbii) {
                switch (plbii->cmFlag) {
                    case CMFLAG_CHECKED:
                        newItem->dwFlags |= LBIF_CHECKED;
                    break;
                    case CMFLAG_PARTCHECKED:
                        newItem->dwFlags |= LBIF_PARTCHECKED;
                    break;
                }

                if (dwStyle & LBS_USEICON)
                    newItem->dwData = (DWORD)plbii->hIcon;
                else
                    newItem->dwData = 0L;
            }
            newItem->dwAddData = 0L;

            if (message == LB_ADDSTRING)
                pos = lstAddNewItem (dwStyle, pData, newItem, -1);
            else
                pos = lstAddNewItem (dwStyle, pData, newItem, (int)wParam);

            lstInvalidateUnderItem (hwnd, pData, pos);

            lstSetVScrollInfo (hwnd, pData, TRUE);

            return pos;
        }
        break;

        case LB_DELETESTRING:
        {
            PLISTBOXITEM removed;
            int delete;

            delete = (int)wParam;

            pData = (PLISTBOXDATA)pCtrl->userdata;
            removed = lstRemoveItem (pData, &delete);
            if (removed) {
                FreeFixStr (removed->key);
                lstFreeItem (pData, removed);

                pData->itemCount --;

                if (pData->itemTop != 0
                        && pData->itemCount <= pData->itemVisibles) {
                    pData->itemTop = 0;
                    InvalidateRect (hwnd, NULL, TRUE);
                }
                else {
                    lstInvalidateUnderItem (hwnd, pData, delete);
                    if (delete <= pData->itemTop) {
                        pData->itemTop --;
                        if (pData->itemTop < 0)
                            pData->itemTop = 0;
                    }
                }

                if (pData->itemHilighted >= pData->itemCount) {
                    pData->itemHilighted = pData->itemCount - 1;
                    if (pData->itemHilighted < 0)
                        pData->itemHilighted = 0;
                }

                if (pData->itemHilighted < pData->itemTop)
                    pData->itemHilighted = pData->itemTop;
                if (pData->itemHilighted > ITEM_BOTTOM (pData))
                    pData->itemHilighted = ITEM_BOTTOM (pData);

                lstSetVScrollInfo (hwnd, pData, TRUE);
            }
        }
        break;

        case LB_FINDSTRING:
            if( *(char*)lParam == '\0' )
                return LB_ERR;

            pData = (PLISTBOXDATA)pCtrl->userdata;
            return lstFindItem(pData, (int)wParam, (char*)lParam, FALSE);

        case LB_FINDSTRINGEXACT:
            if( *(char*)lParam == '\0' )
                return LB_ERR;

            pData = (PLISTBOXDATA)pCtrl->userdata;
            return lstFindItem(pData, (int)wParam, (char*)lParam, TRUE);

        case LB_SETTOPINDEX:
        {
            int newTop = (int) wParam;

            pData = (PLISTBOXDATA)pCtrl->userdata;

            if (newTop <0)
                newTop = 0;

⌨️ 快捷键说明

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