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

📄 listbox.c

📁 在ADS环境下MiniGUI的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
            plbi = plbi->next;
            start ++;
            continue;
        }

        if (pData->str_cmp (key, plbi->key, keylen) == 0)
            return start;
            
        plbi = plbi->next;
        start ++;
    }

    return LB_ERR;
}

static void lstOnDrawSListBoxItems (HWND hWnd, HDC hdc,
                PLISTBOXDATA pData, int width)
{
    DWORD dwStyle = GetWindowStyle (hWnd);
    PLISTBOXITEM plbi;
    int i;
    int x = 0, y = 0;
    int offset;

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

        if (plbi->dwFlags & LBIF_SELECTED) {
            SetBkMode (hdc, BM_OPAQUE);
            SetBkColor (hdc, GetWindowElementColorEx (hWnd, BKC_HILIGHT_NORMAL));
            SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_HILIGHT_NORMAL));
            SetBrushColor (hdc, GetWindowElementColorEx (hWnd, BKC_HILIGHT_NORMAL));
            FillBox (hdc, 0, y, width, pData->itemHeight);
        }
        else {
            SetBkMode (hdc, BM_TRANSPARENT);
            SetTextColor (hdc, GetWindowElementColorEx (hWnd, FGC_CONTROL_NORMAL));
        }

        x = LST_INTER_BMPTEXT;
        if (dwStyle & LBS_CHECKBOX) {
            if (plbi->dwFlags & LBIF_CHECKED)
                offset = 0;
            else if (plbi->dwFlags & LBIF_PARTCHECKED)
                offset = LST_WIDTH_CHECKMARK << 1;
            else
                offset = LST_WIDTH_CHECKMARK;
            
            FillBoxWithBitmapPart (hdc, 
                x, y + ((pData->itemHeight - LST_HEIGHT_CHECKMARK)>>1),
                LST_WIDTH_CHECKMARK, LST_HEIGHT_CHECKMARK,
                0, 0,
                CHECKMARK_BMP,
                offset, 0);

            x += LST_WIDTH_CHECKMARK + LST_INTER_BMPTEXT;
        }

        if (dwStyle & LBS_USEICON && plbi->dwImage) {
            if (plbi->dwFlags & LBIF_USEBITMAP) {
                FillBoxWithBitmap (hdc, x, y, 0, pData->itemHeight, 
                            (PBITMAP) plbi->dwImage);
                x += ((PBITMAP)(plbi->dwImage))->bmWidth;
            }
            else {
                int width;
                DrawIcon (hdc, x, y, 0, pData->itemHeight, 
                            (HICON) plbi->dwImage);
                GetIconSize ((HICON) plbi->dwImage, &width, NULL);
                x += width;
            }
            x += LST_INTER_BMPTEXT;
        }

        {
            FONTMETRICS fm;

            GetFontMetrics (GetCurFont (hdc), &fm);
            TextOut (hdc, x, y + ((pData->itemHeight - fm.font_height) >> 1), plbi->key);
        }

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

static int lstSelectItem (HWND hwnd, PLISTBOXDATA pData, int newSel)
{
    PLISTBOXITEM plbi, newItem;
    int index;
    
    newItem = lstGetItem (pData, newSel);
    
#ifdef _DEBUG
    if (!newItem)
        fprintf (stderr, "ASSERT failed: return value of lstGetItem"
                         " in lstSelectItem.\n");
#endif

    if (GetWindowStyle (hwnd) & 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 int lstCancelSelected (HWND hwnd, PLISTBOXDATA pData)
{
    PLISTBOXITEM plbi;
    int index;

    index = 0;
    plbi = pData->head;
    while (plbi) {
        if (plbi->dwFlags & LBIF_SELECTED) {
            RECT rc;

            plbi->dwFlags &= ~LBIF_SELECTED;
            lstGetItemsRect (pData, index, index, &rc);
            InvalidateRect (hwnd, &rc, TRUE);
            return index;
        }

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

    return -1;
}

static void lstDrawFocusRect (HWND hwnd, HDC hdc, PLISTBOXDATA pData)
{
    RECT rc;

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

    if (pData->dwFlags & LBF_FOCUS) {
        GetClientRect (hwnd, &rc);
        lstGetItemsRect (pData, 
                         pData->itemHilighted, pData->itemHilighted,
                         &rc);
        InflateRect (&rc, -1, -1);
#ifndef _GRAY_SCREEN
        SetPenColor (hdc, PIXEL_lightwhite);
        FocusRect (hdc, rc.left, rc.top, rc.right, rc.bottom); 
#endif
    }
}

static void lstCalcParams (const RECT* rcClient, PLISTBOXDATA pData)
{
    pData->itemVisibles = (RECTHP (rcClient)) / pData->itemHeight;
}

static void change_scrollbar (HWND hwnd, PLISTBOXDATA pData, BOOL bShow)
{
    if (pData->sbPolicy == SB_POLICY_ALWAYS)
        EnableScrollBar (hwnd, SB_VERT, bShow);
    else if (pData->sbPolicy == SB_POLICY_AUTOMATIC)
        ShowScrollBar (hwnd, SB_VERT, bShow);
}

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

    if (pData->sbPolicy == SB_POLICY_NEVER) {
        ShowScrollBar (hwnd, SB_VERT, FALSE);
        return;
    }

    if (pData->itemVisibles >= pData->itemCount) {
        SetScrollPos (hwnd, SB_VERT, 0);
        change_scrollbar (hwnd, pData, FALSE);
        return;
    }
    
    si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
    si.nMax = pData->itemCount - 1;
    si.nMin = 0;
#if 0
    si.nPage = MIN (pData->itemVisibles, (pData->itemCount - pData->itemTop));
#else
    si.nPage = MIN (pData->itemVisibles, pData->itemCount);
#endif
    si.nPos = pData->itemTop;
    SetScrollInfo (hwnd, SB_VERT, &si, fRedraw);
    EnableScrollBar (hwnd, SB_VERT, TRUE);
    change_scrollbar (hwnd, pData, TRUE);
}

static int ListboxCtrlProc (HWND hwnd, int message, WPARAM wParam, LPARAM lParam)
{
    HDC             hdc;
    PCONTROL        pCtrl;
    PLISTBOXDATA    pData;
    DWORD           dwStyle;
#if _USE_FIXSTR
    int             len;
#endif
    
    pCtrl   = Control(hwnd);
    dwStyle = pCtrl->dwStyle;

    switch (message)
    {
        case MSG_CREATE:
            pData = (LISTBOXDATA*) calloc (1, sizeof(LISTBOXDATA));
            if (pData == NULL) 
                return -1;

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

            lstSetVScrollInfo (hwnd, pData, FALSE);
        break;

        case MSG_SIZECHANGED:
            pData = (PLISTBOXDATA)pCtrl->dwAddData2;
            lstCalcParams ((const RECT*)lParam, pData);
            break;

        case MSG_DESTROY:
            pData = (PLISTBOXDATA)pCtrl->dwAddData2;
            lstListBoxCleanUp (pData);
            free (pData);
            break;

        case LB_SETSTRCMPFUNC:
            pData = (PLISTBOXDATA)pCtrl->dwAddData2;
            if (pData->itemCount == 0 && lParam) {
                pData->str_cmp = (STRCMP)lParam;
                return LB_OKAY;
            }
            return LB_ERR;

        case LB_RESETCONTENT:
            pData = (PLISTBOXDATA)pCtrl->dwAddData2;
            lstResetListBoxContent (pData);
            InvalidateRect (hwnd, NULL, TRUE);
            return 0;
        
        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->dwAddData2;
            newItem = lstAllocItem (pData);
            if (!newItem) {
                if (dwStyle & LBS_NOTIFY)
                    NotifyParent (hwnd, pCtrl->id, LBN_ERRSPACE);
                return LB_ERRSPACE;
            }

#if _USE_FIXSTR
            len = strlen (string);
            newItem->key = FixStrAlloc (len);
            if (!newItem->key) {
                lstFreeItem (pData, newItem);
                return LB_ERRSPACE;
            }
            if (len > 0)
                strcpy (newItem->key, string);
#else
            newItem->key = strdup (string);
            if (!newItem->key) {
                lstFreeItem (pData, newItem);
                return LB_ERRSPACE;
            }
#endif
            newItem->dwFlags = LBIF_NORMAL;
            if (plbii) {

                if (plbii->cmFlag & CMFLAG_CHECKED)
                    newItem->dwFlags |= LBIF_CHECKED;
                else if (plbii->cmFlag & CMFLAG_PARTCHECKED)
                    newItem->dwFlags |= LBIF_PARTCHECKED;

                if (plbii->cmFlag & IMGFLAG_BITMAP)
                    newItem->dwFlags |= LBIF_USEBITMAP;
                
                if (dwStyle & LBS_USEICON)
                    newItem->dwImage = (DWORD)plbii->hIcon;
                else
                    newItem->dwImage = 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;
        }
        
        case LB_DELETESTRING:
        {
            PLISTBOXITEM removed;
            int delete;

            delete = (int)wParam;

            pData = (PLISTBOXDATA)pCtrl->dwAddData2;
            removed = lstRemoveItem (pData, &delete);
            if (removed) {
#if _USE_FIXSTR
                FreeFixStr (removed->key);
#else
                free (removed->key);
#endif
                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);
                return LB_OKAY;
            }

            return LB_ERR;
        }

        case LB_FINDSTRING:
            if( *(char*)lParam == '\0' )
                return LB_ERR;
                
            pData = (PLISTBOXDATA)pCtrl->dwAddData2;
            return lstFindItem(pData, (int)wParam, (char*)lParam, FALSE);

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

            pData = (PLISTBOXDATA)pCtrl->dwAddData2;
            return lstFindItem(pData, (int)wParam, (char*)lParam, TRUE);
    
        case LB_SETTOPINDEX:
        {
            int newTop = (int) wParam;
            
            pData = (PLISTBOXDATA)pCtrl->dwAddData2;

            if (newTop <0)
                newTop = 0;
            else if (newTop > pData->itemCount - pData->itemVisibles)
                newTop = pData->itemCount - pData->itemVisibles;
                
            if (pData->itemTop != newTop) {
                pData->itemTop = newTop;

                if (pData->itemHilighted < pData->itemTop)

⌨️ 快捷键说明

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