📄 listbox.c
字号:
/* * 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) malloc((n)+1)#define FreeFixStr(p) free(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 2typedef 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 0x0002typedef 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 CALLBACKListboxCtrlProc (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 2int 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 = 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) { 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) 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -