📄 listbox.c
字号:
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); FocusRect (hdc, rc->left - 1, rc->top, rc->right, rc->bottom); }}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; si.nPage = min (pData->itemVisibles, (pData->itemCount - pData->itemTop)); si.nPos = pData->itemTop; SetScrollInfo (hwnd, SB_VERT, &si, fRedraw); EnableScrollBar (hwnd, SB_VERT, TRUE);}int ListboxCtrlProc (HWND hwnd, int message, WPARAM wParam, LPARAM lParam){ HDC hdc; PCONTROL pCtrl; PLISTBOXDATA pData; DWORD dwStyle; pCtrl = Control(hwnd); dwStyle = pCtrl->dwStyle; switch (message) { case MSG_CREATE: pData = (LISTBOXDATA*) calloc (sizeof(LISTBOXDATA), 1); if (pData == NULL) return -1; pCtrl->dwAddData2 = (DWORD)pData; if (!lstInitListBoxData (pData, DEF_LB_BUFFER_LEN)) { free (pData); return -1; } 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_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) { NotifyParent (hwnd, pCtrl->id, LBN_ERRSPACE); return LB_ERRSPACE; }#if _USE_FIXSTR newItem->key = FixStrAlloc (strlen (string)); if (!newItem->key) { lstFreeItem (pData, newItem); return LB_ERRSPACE; } 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) { 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; } return 0; 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 0; case LB_FINDSTRING: if( *(char*)lParam == '\0' ) return LB_ERR; pData = (PLISTBOXDATA)pCtrl->dwAddData2; return lstFindItem(pData, (int)wParam, (char*)lParam, FALSE); return 0; case LB_FINDSTRINGEXACT: if( *(char*)lParam == '\0' ) return LB_ERR; pData = (PLISTBOXDATA)pCtrl->dwAddData2; return lstFindItem(pData, (int)wParam, (char*)lParam, TRUE); return 0; 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) return LB_ERR; old = pData->itemHilighted; if (new >= 0 && new != old) { if (pData->itemCount - new >= pData->itemVisibles) newTop = new; else newTop = max (pData->itemCount - pData->itemVisibles, 0); pData->itemTop = newTop; pData->itemHilighted = new; lstSetVScrollInfo (hwnd, pData, TRUE); } if (!(dwStyle & LBS_MULTIPLESEL)) lstSelectItem (dwStyle, pData, new); InvalidateRect (hwnd, NULL, TRUE); return old; } break; case LB_GETCOUNT: pData = (PLISTBOXDATA)pCtrl->dwAddData2; return pData->itemCount; break; case LB_GETCURSEL: { PLISTBOXITEM plbi; int index = 0; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (dwStyle & LBS_MULTIPLESEL) return pData->itemHilighted; plbi = pData->head; while (plbi) { if (plbi->dwFlags & LBIF_SELECTED) return index; index ++; plbi = plbi->next; } return LB_ERR; } break; case LB_GETSELCOUNT: { int nSel; PLISTBOXITEM plbi; pData = (PLISTBOXDATA)pCtrl->dwAddData2; nSel = 0; plbi = pData->head; while (plbi) { if (plbi->dwFlags & LBIF_SELECTED) nSel ++; plbi = plbi->next; } return nSel; } return 0; case LB_GETTOPINDEX: pData = (PLISTBOXDATA)pCtrl->dwAddData2; return pData->itemTop; break; case LB_GETCARETINDEX: pData = (PLISTBOXDATA)pCtrl->dwAddData2; return pData->itemHilighted; break; case LB_GETTEXTLEN: { PLISTBOXITEM plbi; pData = (PLISTBOXDATA)pCtrl->dwAddData2; plbi = lstGetItem (pData, (int)wParam); if (plbi) return strlen (plbi->key); else return LB_ERR; } break; case LB_GETTEXT: { PLISTBOXITEM plbi; pData = (PLISTBOXDATA)pCtrl->dwAddData2; plbi = lstGetItem (pData, (int)wParam); if (plbi) strcpy ((char*)lParam, plbi->key); else return LB_ERR; } break; case LB_SETTEXT: { PLISTBOXITEM plbi; char* newStr; pData = (PLISTBOXDATA)pCtrl->dwAddData2; plbi = lstGetItem (pData, (int)wParam); if (plbi) {#if _USE_FIXSTR newStr = FixStrAlloc (strlen ((char*)lParam)); if (newStr) { FreeFixStr (plbi->key); plbi->key = newStr; strcpy (plbi->key, (char*)lParam);#else newStr = strdup ((const char*)lParam); if (newStr) { free (plbi->key); plbi->key = newStr;#endif lstInvalidateItem (hwnd, pData, (int)wParam, TRUE); } else return LB_ERR; } else return LB_ERR; } break; case LB_GETITEMDATA: { PLISTBOXITEM plbi; PLISTBOXITEMINFO plbii; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (!(plbi = lstGetItem (pData, (int)wParam))) return LB_ERR; if (!(dwStyle & LBS_CHECKBOX || dwStyle & LBS_USEICON)) { return plbi->dwData; } plbii = (PLISTBOXITEMINFO)lParam; if (!plbii) return LB_ERR; if (plbi->dwFlags & LBIF_CHECKED) plbii->cmFlag = CMFLAG_CHECKED; else if (plbi->dwFlags & LBIF_PARTCHECKED) plbii->cmFlag = CMFLAG_PARTCHECKED; else plbii->cmFlag = CMFLAG_BLANK; plbii->hIcon = (HICON)plbi->dwData; return LB_OKAY; } break; case LB_SETITEMDATA: { PLISTBOXITEM plbi; PLISTBOXITEMINFO plbii; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (!(plbi = lstGetItem (pData, (int)wParam))) return LB_ERR; if (!(dwStyle & LBS_CHECKBOX || dwStyle & LBS_USEICON)) { plbi->dwData = (DWORD)lParam; return LB_OKAY; } plbii = (PLISTBOXITEMINFO)lParam; if (!plbii) return LB_ERR; plbi->dwFlags &= ~LBIF_CHECKMARKMASK; switch (plbii->cmFlag) { case CMFLAG_CHECKED: plbi->dwFlags |= LBIF_CHECKED; break; case CMFLAG_PARTCHECKED: plbi->dwFlags |= LBIF_PARTCHECKED; break; } if (dwStyle & LBS_USEICON) plbi->dwData = (DWORD)plbii->hIcon; else plbi->dwData = 0; lstInvalidateItem (hwnd, pData, (int)wParam, TRUE); return LB_OKAY; } break; case LB_GETITEMADDDATA: { PLISTBOXITEM plbi; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (!(plbi = lstGetItem (pData, (int)wParam))) return LB_ERR; return plbi->dwAddData; } break; case LB_SETITEMADDDATA: { PLISTBOXITEM plbi; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (!(plbi = lstGetItem (pData, (int)wParam))) return LB_ERR; plbi->dwAddData = (DWORD)lParam; return LB_OKAY; } break; case LB_GETCHECKMARK: { PLISTBOXITEM plbi; if (!(dwStyle & LBS_CHECKBOX)) return LB_ERR; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (!(plbi = lstGetItem (pData, (int)wParam))) return LB_ERR; if (plbi->dwFlags & LBIF_CHECKED) return CMFLAG_CHECKED; if (plbi->dwFlags & LBIF_PARTCHECKED) return CMFLAG_PARTCHECKED; return CMFLAG_BLANK; } break; case LB_SETCHECKMARK: { PLISTBOXITEM plbi; if (!(dwStyle & LBS_CHECKBOX)) return LB_ERR; pData = (PLISTBOXDATA)pCtrl->dwAddData2; if (!(plbi = lstGetItem (pData, (int)wParam))) return LB_ERR; plbi->dwFlags &= ~LBIF_CHECKMARKMASK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -