📄 listbox.c
字号:
int keylen = strlen (key); if (start >= pData->itemCount) 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 (pData->str_cmp (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) {#ifndef _GRAY_SCREEN SetBrushColor (hdc, PIXEL_darkblue); SetBkColor (hdc, PIXEL_darkblue);#else SetBrushColor (hdc, PIXEL_black); SetBkColor (hdc, PIXEL_black);#endif SetTextColor (hdc, PIXEL_lightwhite); } else { SetBrushColor (hdc, PIXEL_lightwhite); SetBkColor (hdc, PIXEL_lightwhite); SetTextColor (hdc, PIXEL_black); } FillBox (hdc, 0, y, width, pData->itemHeight); 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 (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; } break; } plbi = plbi->next; index ++; } newItem->dwFlags |= LBIF_SELECTED; return -1;}static void lstDrawFocusRect (HDC hdc, PLISTBOXDATA pData, RECT* rc){ if (pData->itemHilighted < pData->itemTop || pData->itemHilighted > (pData->itemTop + pData->itemVisibles)) return; if (pData->dwFlags & LBF_FOCUS) { lstGetItemsRect (pData, pData->itemHilighted, pData->itemHilighted, rc); InflateRect (rc, -1, -1);#ifndef _GRAY_SCREEN SetPenColor (hdc, PIXEL_lightwhite); FocusRect (hdc, rc->left - 1, rc->top, rc->right, rc->bottom); #endif }}static void lstCalcParams (const RECT* rcClient, PLISTBOXDATA pData){ pData->itemVisibles = (RECTHP (rcClient)) / pData->itemHeight;}static void lstSetVScrollInfo (HWND hwnd, PLISTBOXDATA pData, BOOL fRedraw){ SCROLLINFO si; if (pData->itemVisibles >= pData->itemCount) { SetScrollPos (hwnd, SB_VERT, 0); EnableScrollBar (hwnd, SB_VERT, 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);}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 (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) pData->itemHilighted = pData->itemTop; if (pData->itemHilighted > ITEM_BOTTOM (pData)) pData->itemHilighted = ITEM_BOTTOM (pData); lstSetVScrollInfo (hwnd, pData, TRUE); InvalidateRect (hwnd, NULL, TRUE); } return 0; } case LB_SETCURSEL: case LB_SETCARETINDEX: { int new = (int)wParam; int old, newTop; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (new < 0 || new > pData->itemCount - 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -