📄 listbox.c
字号:
{ 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; 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; RECT rc; COLORREF bk; plbi = lstGetItem (pData, pData->itemTop); for (i = 0; plbi && i < (pData->itemVisibles + 1); i++) { if (plbi->dwFlags & LBIF_SELECTED) { SetBkColor (hdc, bk = BLUE); SetTextColor (hdc, WHITE); } else { SetBkColor (hdc, bk = WHITE); SetTextColor (hdc, BLACK); } rc.left = 0; rc.top = y; rc.right = width; rc.bottom = y + pData->itemHeight; FastFillRect(hdc, &rc, bk); 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;#if 0 /* fix: no bitmap */ FillBoxWithBitmapPart (hdc, x, y + ((pData->itemHeight - LST_HEIGHT_CHECKMARK)>>1), LST_WIDTH_CHECKMARK, LST_HEIGHT_CHECKMARK, 0, 0, &sg_bmpCheckMark, offset, 0);#endif x += LST_WIDTH_CHECKMARK + LST_INTER_BMPTEXT; }#if 0 /* fix: no icon */ if (dwStyle & LBS_USEICON && plbi->dwData) { DrawIcon (hdc, x, y, pData->itemHeight, pData->itemHeight, (HICON) plbi->dwData); x += pData->itemHeight + LST_INTER_BMPTEXT; }#endif/* jmt: should be SYSTEM_FIXED_FONT because of minigui's GetSysCharXXX() */#if 0 SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));#endif SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); TextOut (hdc, x+2, y, plbi->key,-1); y += pData->itemHeight; plbi = plbi->next; }}static int lstSelectItem (DWORD dwStyle, PLISTBOXDATA pData, int newSel){ PLISTBOXITEM plbi, newItem; int index; newItem = lstGetItem (pData, newSel);#if 1 /* jmt: fixed if no item added */ if (!newItem) return -1;#endif #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){ HGDIOBJ oldbrush,oldpen; if (pData->itemHilighted < pData->itemTop || pData->itemHilighted > (pData->itemTop + pData->itemVisibles)) return; if (pData->dwFlags & LBF_FOCUS) { lstGetItemsRect (pData, pData->itemHilighted, pData->itemHilighted, rc);#if 0 InflateRect (rc, -1, -1); FocusRect (hdc, rc->left - 1, rc->top, rc->right, rc->bottom);#else oldbrush=SelectObject(hdc, GetStockObject(NULL_BRUSH)); oldpen=SelectObject(hdc, CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT)));#if 0 GdSetMode(MWMODE_XOR);#endif Rectangle (hdc, rc->left, rc->top, rc->right, rc->bottom);#if 0 GdSetMode(MWMODE_SET);#endif SelectObject(hdc,oldbrush); DeleteObject(SelectObject(hdc,oldpen));#endif }}static void lstCalcParams (const RECT* rcClient, PLISTBOXDATA pData){#define RECTHP(prc) (prc->bottom - prc->top) pData->itemVisibles = (RECTHP (rcClient)) / pData->itemHeight;#if 1 /* test calculation of itemVisibles */ if( ((RECTHP (rcClient)) % pData->itemHeight) ) pData->itemVisibles++;#endif}extern BOOL SetScrollPos (HWND hWnd, int iSBar, int iNewPos);extern BOOL EnableScrollBar (HWND hWnd, int iSBar, BOOL bEnable);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; si.nPage = min (pData->itemVisibles, (pData->itemCount - pData->itemTop)); si.nPos = pData->itemTop; SetScrollInfo (hwnd, SB_VERT, &si, fRedraw); EnableScrollBar (hwnd, SB_VERT, TRUE);}LRESULT CALLBACKListboxCtrlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ HDC hdc; HWND pCtrl; PLISTBOXDATA pData; DWORD dwStyle; pCtrl = hwnd; dwStyle = pCtrl->style; switch (message) { case WM_CREATE: pData = (LISTBOXDATA*) malloc (sizeof(LISTBOXDATA)); if (pData == NULL) return -1; pCtrl->userdata = (DWORD)pData; if (!lstInitListBoxData (hwnd, pData, DEF_LB_BUFFER_LEN)) { free (pData); return -1; } break; case WM_SIZE: { RECT rc; pData = (PLISTBOXDATA)pCtrl->userdata; GetClientRect(hwnd, &rc); lstCalcParams (&rc, pData); } break; case WM_DESTROY: pData = (PLISTBOXDATA)pCtrl->userdata; lstListBoxCleanUp (pData); free (pData); break; case LB_RESETCONTENT: pData = (PLISTBOXDATA)pCtrl->userdata; lstResetListBoxContent (pData); InvalidateRect (hwnd, NULL, TRUE); break; 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->userdata; newItem = lstAllocItem (pData); if (!newItem) { NotifyParent (hwnd, pCtrl->id, LBN_ERRSPACE); return LB_ERRSPACE; } newItem->key = FixStrAlloc (strlen (string)); strcpy (newItem->key, string); newItem->dwFlags = LBIF_NORMAL; if (plbii) { switch (plbii->cmFlag) { case CMFLAG_CHECKED: newItem->dwFlags |= LBIF_CHECKED; break; case CMFLAG_PARTCHECKED: newItem->dwFlags |= LBIF_PARTCHECKED; break; } if (dwStyle & LBS_USEICON) newItem->dwData = (DWORD)plbii->hIcon; else newItem->dwData = 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; } break; case LB_DELETESTRING: { PLISTBOXITEM removed; int delete; delete = (int)wParam; pData = (PLISTBOXDATA)pCtrl->userdata; removed = lstRemoveItem (pData, &delete); if (removed) { FreeFixStr (removed->key); 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); } } break; case LB_FINDSTRING: if( *(char*)lParam == '\0' ) return LB_ERR; pData = (PLISTBOXDATA)pCtrl->userdata; return lstFindItem(pData, (int)wParam, (char*)lParam, FALSE); case LB_FINDSTRINGEXACT: if( *(char*)lParam == '\0' ) return LB_ERR; pData = (PLISTBOXDATA)pCtrl->userdata; return lstFindItem(pData, (int)wParam, (char*)lParam, TRUE); case LB_SETTOPINDEX: { int newTop = (int) wParam; pData = (PLISTBOXDATA)pCtrl->userdata; if (newTop <0) newTop = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -