📄 listbox.c
字号:
/*** $Id: listbox.c,v 1.48 2003/09/04 02:40:36 weiym Exp $**** listbox.c: the List Box Control module.**** Copyright (C) 2003 Feynman Software.** Copyright (C) 1999 ~ 2002 Wei Yongming.** ** Current maintainer: Wei Yongming.**** 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***//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program 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 General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//*** TODO:** * Multiple columns support.*/#include <stdio.h>#include <stdlib.h>#include <string.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"#ifdef _CTRL_LISTBOX#include "ctrlmisc.h"#include "listbox.h"#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 bmp_checkmark;#define CHECKMARK_BMP (&bmp_checkmark)static int ListboxCtrlProc (HWND hwnd, int message, WPARAM wParam, LPARAM lParam);#ifdef _INCORE_RES#ifdef _FLAT_WINDOW_STYLE#include "checkmark-flat-bmp.c"#else#include "checkmark-3d-bmp.c"#endif#endifBOOL RegisterListboxControl (void){ WNDCLASS WndClass;#ifdef _INCORE_RES if (LoadBitmapFromMemory (HDC_SCREEN, &bmp_checkmark, (void*)checkmark_bmp_data, sizeof (checkmark_bmp_data), "bmp")) return FALSE;#else if (!LoadSystemBitmap (&bmp_checkmark, "checkmark")) return FALSE;#endif WndClass.spClassName = CTRL_LISTBOX; WndClass.dwStyle = WS_NONE; WndClass.dwExStyle = WS_EX_NONE; WndClass.hCursor = GetSystemCursor (0); WndClass.iBkColor = PIXEL_lightwhite; WndClass.WinProc = ListboxCtrlProc; return AddNewControlClass (&WndClass) == ERR_OK;}#if 0void ListboxControlCleanup (void){ return;}#endifstatic BOOL lstInitListBoxData (PCONTROL pCtrl, LISTBOXDATA* pData, int len){ int i; PLISTBOXITEM plbi; pData->itemHeight = pCtrl->pLogFont->size; pData->itemHilighted = 0; pData->str_cmp = strncmp; // 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 (pData->str_cmp (newItem->key, plbi->key, (size_t)-1) < 0) { insPosItem = NULL; insPos = 0; } else { while (plbi->next) { if (pData->str_cmp (newItem->key, plbi->next->key, (size_t)-1) <= 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) { insPosItem = NULL; insPos = 0; } else { int index = 1; while (plbi) { 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -