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

📄 listbox.c

📁 在ecos 下mingui 的移植开发
💻 C
📖 第 1 页 / 共 3 页
字号:
// $Id: listbox.c,v 1.7 2000/11/17 07:02:01 ymwei Exp $//// listbox.c: the List Box Control module.//// Copyright (C) 1999, 2000, Wei Yongming.// // Current maintainer: Wei Yongming.///***  This library is free software; you can redistribute it and/or**  modify it under the terms of the GNU Library General Public**  License as published by the Free Software Foundation; either**  version 2 of the License, or (at your option) any later version.****  This library 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**  Library General Public License for more details.****  You should have received a copy of the GNU Library General Public**  License along with this library; if not, write to the Free**  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,**  MA 02111-1307, USA*//***  Alternatively, the contents of this file may be used under the terms **  of the Mozilla Public License (the "MPL License") in which case the**  provisions of the MPL License are applicable instead of those above.*/// Note://  Although there was a version by Zhao Jianghua, this version of//  LISTBOX control is written by Wei Yongming from scratch.//// Create date: 1999/8/31//// Modify records:////  Who             When        Where       For What                Status//-----------------------------------------------------------------------------//  Wei Yongming    1999/10/18  Tsinghua    Item Additional Data    Finished//  Wei Yongming    1999/10/31  Tsinghua    Space bar for checkmark Finished//  Wei Yongming    1999/10/31  Tsinghua    Character match item    Finished//  Wei Yongming    1999/11/07  Tsinghua    Character match item    Bug fixing//  WEI Yongming    2000/01/20  Tsinghua    Thumb dragging          Finished//  WEI Yongming    2000/02/24  Tsinghua    Add MPL License         Finished//// TODO:// 1. Multiple columns support.//#include <stdio.h>#include <stdlib.h>#include <string.h>#include <pthread.h>#include <semaphore.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "control.h"#include "cliprect.h"#include "internals.h"#include "ctrlclass.h"#include "ctrlmisc.h"#include "listbox.h"#ifndef lintstatic char fileid[] = "$Id: listbox.c,v 1.7 2000/11/17 07:02:01 ymwei Exp $";#endif#define _USE_FIXSTR      1#define ITEM_BOTTOM(x)  (x->itemTop + x->itemVisibles - 1)#define LST_WIDTH_CHECKMARK     11#define LST_HEIGHT_CHECKMARK    11#define LST_INTER_BMPTEXT       2static BITMAP sg_bmpCheckMark;BOOL RegisterListboxControl (void){    WNDCLASS WndClass;    if (!LoadSystemBitmap (&sg_bmpCheckMark, "checkmark")) {        fprintf (stderr, "Load ListBox Check Mark Bitmap failure!\n");        return FALSE;    }     WndClass.spClassName = "listbox";    WndClass.dwStyle     = 0;    WndClass.hCursor     = GetSystemCursor (0);    WndClass.iBkColor    = PIXEL_lightwhite;    WndClass.WinProc     = ListboxCtrlProc;    return AddNewControlClass (&WndClass) == ERR_OK;}void ListboxControlCleanup (void){    UnloadBitmap (&sg_bmpCheckMark);    return;}static BOOL lstInitListBoxData (LISTBOXDATA* pData, int len){    int i;    PLISTBOXITEM plbi;        pData->itemHeight = GetSysCharHeight ();    pData->itemHilighted = 0;    // init item buffer.    if (!(pData->buffStart = malloc (len * sizeof (LISTBOXITEM))))        return FALSE;    pData->buffLen = len;    pData->buffEnd = pData->buffStart + len;    pData->freeList = pData->buffStart;    plbi = pData->freeList;    for (i = 0; i < len - 1; i++) {        plbi->next = plbi + 1;        plbi ++;    }    plbi->next = NULL;    return TRUE;}static void lstListBoxCleanUp (LISTBOXDATA* pData){    PLISTBOXITEM plbi;    PLISTBOXITEM next;    plbi = pData->head;    while (plbi) {#if _USE_FIXSTR        FreeFixStr (plbi->key);#else        free (plbi->key);#endif        next = plbi->next;        if (plbi < pData->buffStart || plbi > pData->buffEnd)            free (plbi);        plbi = next;    }        free (pData->buffStart);}static void lstResetListBoxContent (PLISTBOXDATA pData){    int i;    PLISTBOXITEM plbi, next;    pData->itemCount = 0;    pData->itemTop = 0;    pData->itemHilighted = 0;    plbi = pData->head;    while (plbi) {#if _USE_FIXSTR        FreeFixStr (plbi->key);#else        free (plbi->key);#endif        next = plbi->next;        if (plbi < pData->buffStart || plbi > pData->buffEnd)            free (plbi);        plbi = next;    }    pData->head = NULL;    pData->freeList = pData->buffStart;    plbi = pData->freeList;    for (i = 0; i < pData->buffLen - 1; i++) {        plbi->next = plbi + 1;        plbi ++;    }    plbi->next = NULL;    return;}static PLISTBOXITEM lstAllocItem (PLISTBOXDATA pData){    PLISTBOXITEM plbi;    if (pData->freeList) {        plbi = pData->freeList;        pData->freeList = plbi->next;    }    else        plbi = (PLISTBOXITEM) malloc (sizeof (LISTBOXITEM));        return plbi;}static void lstFreeItem (PLISTBOXDATA pData, PLISTBOXITEM plbi){    if (plbi < pData->buffStart || plbi > pData->buffEnd)        free (plbi);    else {        plbi->next = pData->freeList;        pData->freeList = plbi;    }}static int lstAddNewItem (DWORD dwStyle,         PLISTBOXDATA pData, PLISTBOXITEM newItem, int pos){    PLISTBOXITEM plbi;    PLISTBOXITEM insPosItem = NULL;    int insPos = 0;    newItem->next = NULL;    if (!pData->head)        insPosItem = NULL;    else if (dwStyle & LBS_SORT) {        plbi = pData->head;        if (strcmp (newItem->key, plbi->key) < 0) {            insPosItem = NULL;            insPos = 0;        }        else {            while (plbi->next) {                if (strcmp (newItem->key, plbi->next->key) <= 0)                    break;                            plbi = plbi->next;                insPos ++;            }            insPosItem = plbi;        }    }    else {        plbi = pData->head;        if (pos < 0) {            while (plbi->next) {                plbi = plbi->next;                insPos ++;            }            insPosItem = plbi;        }        else if (pos > 0) {            int index = 0;            while (plbi->next) {                if (pos == index)                    break;                plbi = plbi->next;                index ++;                insPos ++;            }            insPosItem = plbi;        }    }    if (insPosItem) {        plbi = insPosItem->next;        insPosItem->next = newItem;        newItem->next = plbi;        insPos ++;    }    else {        plbi = pData->head;        pData->head = newItem;        newItem->next = plbi;    }    pData->itemCount ++;    return insPos;}static PLISTBOXITEM lstRemoveItem (PLISTBOXDATA pData, int* pos){    int index = 0;    PLISTBOXITEM plbi, prev;    if (!pData->head)        return NULL;    if (*pos < 0) {        prev = pData->head;        plbi = pData->head;        while (plbi->next) {            prev = plbi;            plbi = plbi->next;            index ++;        }        if (plbi == pData->head) {            pData->head = pData->head->next;            *pos = 0;            return plbi;        }        else {            prev->next = plbi->next;            *pos = index;            return plbi;        }    }    else if (*pos == 0) {        plbi = pData->head;        pData->head = plbi->next;        return plbi;    }    else {        index = 0;        prev = pData->head;        plbi = pData->head;        while (plbi->next) {            if (*pos == index)                break;            prev = plbi;            plbi = plbi->next;            index ++;        }        if (plbi == pData->head) {            pData->head = pData->head->next;            *pos = 0;            return plbi;        }        else {            prev->next = plbi->next;            *pos = index;            return plbi;        }    }    return NULL;}static void lstGetItemsRect (PLISTBOXDATA pData,                 int start, int end, RECT* prc){    if (start < 0)        start = 0;    prc->top = (start - pData->itemTop)*pData->itemHeight;    if (end >= 0)        prc->bottom = (end - pData->itemTop + 1)*pData->itemHeight;}static void lstInvalidateItem (HWND hwnd, PLISTBOXDATA pData,                 int pos, BOOL fEBk){    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;    else if (start < 0)        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;    plbi = lstGetItem (pData, pData->itemTop);        for (i = 0; plbi && i < (pData->itemVisibles + 1); i++) {        if (plbi->dwFlags & LBIF_SELECTED) {            SetBrushColor (hdc, PIXEL_darkblue);            SetBkColor (hdc, PIXEL_darkblue);            SetTextColor (hdc, PIXEL_lightwhite);        }        else {            SetBrushColor (hdc, PIXEL_lightwhite);            SetBkColor (hdc, PIXEL_lightwhite);            SetTextColor (hdc, PIXEL_black);        }        FillBox (hdc, 0, y, width, pData->itemHeight);        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;                        FillBoxWithBitmapPart (hdc,                 x, y + ((pData->itemHeight - LST_HEIGHT_CHECKMARK)>>1),                LST_WIDTH_CHECKMARK, LST_HEIGHT_CHECKMARK,                0, 0,                &sg_bmpCheckMark,                offset, 0);            x += LST_WIDTH_CHECKMARK + LST_INTER_BMPTEXT;        }        if (dwStyle & LBS_USEICON && plbi->dwData) {            DrawIcon (hdc,                 x, y, pData->itemHeight, pData->itemHeight,                 (HICON) plbi->dwData);            x += pData->itemHeight + LST_INTER_BMPTEXT;        }        TextOut (hdc, x, y, plbi->key);        y += pData->itemHeight;        plbi = plbi->next;    }}static int lstSelectItem (DWORD dwStyle, 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 (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;            }

⌨️ 快捷键说明

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