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

📄 listbox.c

📁 TN-kernel内核针对LPC系列ARM7处理器和S3C44B0X重新定制好的源代码包。内含Nano-X GUI。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Copyright (C) 1999, 2000, Wei Yongming.
 * Portions Copyright (c) 2000 Greg Haerr <greg@censoft.com>
 *
 * Listbox for Microwindows win32 api.
 */

/*
**  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.
**
** 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
**  Kevin Tseng     2000/05/26  gv          port to microwin        ported
**  Greg Haerr      2000/06/15  Utah        3d look, bug fixes      Finished
**  Kevin Tseng     2000/06/22  gv          port to mw-nanox        ported
**  Kevin Tseng     2000/06/22  gv          fixed bug if no item    Finished
**  Kevin Tseng     2000/08/08  gv          enable scrollbar(V)     porting
**  Kevin Tseng     2000/08/10  gv          enable scrollbar(V)     ported
**  Kevin Tseng     2000/08/10  gv          WM_CHAR, WM_KEYDOWN     ported
**
** TODO:
** 1. Multiple columns support.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MWINCLUDECOLORS
#include "windows.h"
#include "wintools.h"         /* Draw3dBox */
#include "device.h"         /* GdGetTextSize */

#define FixStrAlloc(n)       GdMalloc((n)+1)
#define FreeFixStr(p)        GdFree(p)

#define LBIF_NORMAL         0x0000L
#define LBIF_SELECTED       0x0001L
#define LBIF_CHECKED        0x0010L
#define LBIF_PARTCHECKED    0x0020L
#define LBIF_CHECKMARKMASK  0x00F0L

#define CMFLAG_BLANK        0
#define CMFLAG_CHECKED      1
#define CMFLAG_PARTCHECKED  2
typedef struct _LISTBOXITEMINFO {
    int     insPos;         /* insert position */
    char*   string;         /* item string */
    int     cmFlag;         /* check mark flag */
    HICON   hIcon;          /* handle of icon */
} LISTBOXITEMINFO, *PLISTBOXITEMINFO;

typedef struct _LISTBOXITEM {
    char*   key;                /* item sort key */
    DWORD   dwFlags;            /* item flags */
    DWORD   dwData;             /* item data */
    DWORD   dwAddData;          /* item additional data */
    struct  _LISTBOXITEM* next;  /* next item */
} LISTBOXITEM, *PLISTBOXITEM;

#define DEF_LB_BUFFER_LEN       5

#define LBF_FOCUS               0x0001
#define LBF_NOTHINGSELECTED        0x0002

typedef struct _LISTBOXDATA {
    DWORD dwFlags;          /* listbox flags */

    int itemCount;          /* items count */
    int itemTop;            /* start display item */
    int itemVisibles;       /* number of visible items */

    int itemHilighted;      /* current hilighted item */
    int itemHeight;         /* item height */

    LISTBOXITEM* head;      /* items linked list head */

    int buffLen;            /* buffer length */
    LISTBOXITEM* buffStart; /* buffer start */
    LISTBOXITEM* buffEnd;   /* buffer end */
    LISTBOXITEM* freeList;  /* free list in buffer */
} LISTBOXDATA, *PLISTBOXDATA;

void ListboxControlCleanup ();
static LRESULT CALLBACK
ListboxCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

#define ITEM_BOTTOM(x)  (x->itemTop + x->itemVisibles - 1)

#define LST_WIDTH_CHECKMARK     11
#define LST_HEIGHT_CHECKMARK    11
#define LST_INTER_BMPTEXT       2

int WINAPI MwRegisterListboxControl(HINSTANCE hInstance)
{
        WNDCLASS        wc;
#if 0
    static BITMAP sg_bmpCheckMark;
    if (!LoadSystemBitmap (&sg_bmpCheckMark, "checkmark")) {
        fprintf (stderr, "Load ListBox Check Mark Bitmap failure!\n");
        return FALSE;
    }
#endif
        wc.style        = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
        wc.lpfnWndProc        = (WNDPROC)ListboxCtrlProc;
        wc.cbClsExtra        = 0;
        wc.cbWndExtra        = 0;
        wc.hInstance        = hInstance;
        wc.hIcon        = NULL;
        wc.hCursor        = 0; /*LoadCursor(NULL, IDC_ARROW);*/
        wc.hbrBackground= GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName        = NULL;
        wc.lpszClassName= "LISTBOX";

        return RegisterClass(&wc);
}

void ListboxControlCleanup ()
{
#if 0
    UnloadBitmap (&sg_bmpCheckMark);
#endif
}

static LRESULT NotifyParent (HWND hwnd, int id, int code)
{
    return SendMessage (GetParent (hwnd), WM_COMMAND,
                 (WPARAM) MAKELONG (id, code), (LPARAM)hwnd);
}

static BOOL lstInitListBoxData (HWND hwnd,LISTBOXDATA* pData, int len)
{
    int i, xw, xh, xb;
    PLISTBOXITEM plbi;
    HDC hdc;

    memset (pData, 0, sizeof (LISTBOXDATA));
#if 0
    pData->itemHeight = GetSysCharHeight ();
#else
    hdc=GetDC(hwnd);
#if MWCLIENT        /* nanox client */
    GrSetGCFont(hdc->gc,hdc->font->fontid);
    GrGetGCTextSize(hdc->gc,"X",1,
                MWTF_ASCII,&xw,&xh,&xb);
#else
    GdSetFont(hdc->font->pfont);
    GdGetTextSize(hdc->font->pfont,"X",1,
                &xw,&xh,&xb,MWTF_ASCII);
#endif
    ReleaseDC(hwnd,hdc);
    pData->itemHeight=xh + 1;
#endif
    pData->itemHilighted = 0;
    pData->dwFlags = LBF_NOTHINGSELECTED;

    /* init item buffer. */
    if (!(pData->buffStart = GdMalloc (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) {
        FreeFixStr (plbi->key);
        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;
#if 0
    pData->itemVisibles = 0;
#endif

    plbi = pData->head;
    while (plbi) {
        FreeFixStr (plbi->key);
        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;
}

static PLISTBOXITEM lstAllocItem (PLISTBOXDATA pData)
{
    PLISTBOXITEM plbi;

    if (pData->freeList) {
        plbi = pData->freeList;
        pData->freeList = plbi->next;
    }
    else
        plbi = (PLISTBOXITEM) GdMalloc (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)

⌨️ 快捷键说明

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