📄 listbox.c
字号:
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->userdata; if (!(plbi = lstGetItem(pData, (int) wParam))) return LB_ERR; plbi->dwFlags &= ~LBIF_CHECKMARKMASK; switch (lParam) { case CMFLAG_CHECKED: plbi->dwFlags |= LBIF_CHECKED; break; case CMFLAG_PARTCHECKED: plbi->dwFlags |= LBIF_PARTCHECKED; break; } lstInvalidateItem(hwnd, pData, (int) wParam, FALSE); return LB_OKAY; } break; case LB_GETSELITEMS: { int nItem; int nSel = 0; int index = 0; int *pInt; PLISTBOXITEM plbi; nItem = (int) wParam; pInt = (int *) lParam; pData = (PLISTBOXDATA) pCtrl->userdata; plbi = pData->head; while (plbi) { if (plbi->dwFlags & LBIF_SELECTED) { if (pInt) { if (nSel < nItem) *(pInt + nSel) = index; else return nItem; } nSel++; } plbi = plbi->next; index++; } return nSel; } break; case LB_GETSEL: { PLISTBOXITEM plbi; pData = (PLISTBOXDATA) pCtrl->userdata; plbi = lstGetItem(pData, (int) wParam); if (plbi) return plbi->dwFlags & LBIF_SELECTED; else return LB_ERR; } break; case LB_SETSEL: { PLISTBOXITEM plbi; pData = (PLISTBOXDATA) pCtrl->userdata; plbi = lstGetItem(pData, (int) lParam); if (plbi) { pData->dwFlags &= ~LBF_NOTHINGSELECTED; if (wParam == -1) plbi->dwFlags ^= LBIF_SELECTED; else if (wParam == 0) plbi->dwFlags &= ~LBIF_SELECTED; else plbi->dwFlags |= LBIF_SELECTED; lstInvalidateItem(hwnd, pData, (int) lParam, FALSE); } else return LB_ERR; } break; case LB_GETITEMHEIGHT: pData = (PLISTBOXDATA) pCtrl->userdata; return pData->itemHeight; break; case LB_SETITEMHEIGHT: pData = (PLISTBOXDATA) pCtrl->userdata; if (pData->itemHeight != LOWORD(lParam)) { pData->itemHeight = LOWORD(lParam); lstCalcParams(hwnd, NULL, pData); lstSetVScrollInfo(hwnd, pData, TRUE); InvalidateRect(hwnd, NULL, TRUE); } break; case WM_SETFOCUS: { pData = (PLISTBOXDATA) pCtrl->userdata; if (pData->dwFlags & LBF_FOCUS) break; pData->dwFlags |= LBF_FOCUS; //lstInvalidateItem ( hwnd, pData, pData->itemHilighted, FALSE ); hdc = GetDC(hwnd); lstDrawFocusRect(hwnd, hdc, pData, TRUE); ReleaseDC(hwnd, hdc); NotifyParent(hwnd, pCtrl->id, LBN_SETFOCUS); } break; case WM_KILLFOCUS: { pData = (PLISTBOXDATA) pCtrl->userdata; pData->dwFlags &= ~LBF_FOCUS; //lstInvalidateItem ( hwnd, pData, pData->itemHilighted, FALSE ); hdc = GetDC(hwnd); lstDrawFocusRect(hwnd, hdc, pData, FALSE); ReleaseDC(hwnd, hdc); NotifyParent(hwnd, pCtrl->id, LBN_KILLFOCUS); } break; case WM_GETDLGCODE: return DLGC_WANTARROWS | DLGC_WANTCHARS; case WM_GETTEXTLENGTH: case WM_GETTEXT: case WM_SETTEXT: return -1; case WM_SETFONT: { PLISTBOXDATA pData = (PLISTBOXDATA) pCtrl->userdata; SET_WND_FONT(hwnd, (HFONT) wParam); lstCalcHeight(hwnd); lstCalcParams(hwnd, NULL, pData); if (LOWORD(lParam) != 0) InvalidateRect(hwnd, NULL, TRUE); } break; case WM_GETFONT: return (LRESULT)GET_WND_FONT(hwnd); case WM_NCCALCSIZE: { LPNCCALCSIZE_PARAMS lpnc; /* calculate client rect from passed window rect in rgrc[0] */ lpnc = (LPNCCALCSIZE_PARAMS) lParam; if (GetWindowLong(hwnd, GWL_STYLE) & WS_BORDER) InflateRect(&lpnc->rgrc[0], -2, -2); } break; case WM_NCPAINT: { RECT rc; hdc = wParam ? (HDC) wParam : GetWindowDC(hwnd); GetWindowRect(hwnd, &rc); if (dwStyle & WS_BORDER) Draw3dInset(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); if (!wParam) ReleaseDC(hwnd, hdc); } break; case WM_PAINT: { PAINTSTRUCT ps; hdc = BeginPaint(hwnd, &ps); pData = (PLISTBOXDATA) pCtrl->userdata; /* * If this is the first paint and there's nothing * selected, then auto select the topmost displayed item. */#if 0 /* GB: Why this ??? With multiselect listbox it's wrong... */ if (pData->dwFlags & LBF_NOTHINGSELECTED) { lstSelectItem(hwnd->style, pData, pData->itemTop); pData->dwFlags &= ~LBF_NOTHINGSELECTED; }#endif /* if(hwnd->style & WS_BORDER) OffsetRect ( &ps.rcPaint, 2, 2 ); */ lstOnDrawSListBoxItems(hwnd, hdc, dwStyle, pData, &ps.rcPaint); EndPaint(hwnd, &ps); } break; case WM_LBUTTONDBLCLK: if (dwStyle & LBS_NOTIFY) NotifyParent(hwnd, pCtrl->id, LBN_DBLCLK); break; case WM_LBUTTONDOWN: { int oldSel, mouseX, mouseY, hit; pData = (PLISTBOXDATA) pCtrl->userdata; if (pData->itemCount == 0) break; mouseX = LOWORD(lParam); mouseY = HIWORD(lParam); hit = mouseY / pData->itemHeight; hit += pData->itemTop; if (hit >= pData->itemCount) break; oldSel = lstSelectItem(dwStyle, pData, hit); if ((dwStyle & LBS_NOTIFY) && (oldSel != hit)) NotifyParent(hwnd, pCtrl->id, LBN_SELCHANGE); if (oldSel >= 0) { if (oldSel >= pData->itemTop && (oldSel <= pData->itemTop + pData->itemVisibles)) { lstInvalidateItem(hwnd, pData, oldSel, FALSE); } } lstInvalidateItem(hwnd, pData, hit, FALSE); if (pData->itemHilighted != hit) { hdc = GetDC(hwnd); /* hdc = GetClientDC (hwnd); */ lstDrawFocusRect(hwnd, hdc, pData, FALSE); ReleaseDC(hwnd, hdc); } pData->itemHilighted = hit; if (dwStyle & LBS_CHECKBOX) { if (mouseX > 0 && mouseX < LST_WIDTH_CHECKMARK) { NotifyParent(hwnd, pCtrl->id, LBN_CLICKCHECKMARK); if (dwStyle & LBS_AUTOCHECK) { PLISTBOXITEM plbi; plbi = lstGetItem(pData, hit); switch (plbi-> dwFlags & LBIF_CHECKMARKMASK) { case LBIF_CHECKED: plbi->dwFlags &= ~LBIF_CHECKMARKMASK; break; default: plbi->dwFlags &= ~LBIF_CHECKMARKMASK; plbi->dwFlags |= LBIF_CHECKED; break; } lstInvalidateItem(hwnd, pData, hit, FALSE); } } } if ((dwStyle & LBS_OWNERDRAWVARIABLE)) lstCalcParams(hwnd, NULL, pData); lstSetVScrollInfo(hwnd, pData, TRUE); } break; case WM_LBUTTONUP: break; case WM_MOUSEMOVE: break; case WM_KEYDOWN: { int oldSel, newSel, newTop, oldHighlight; pData = (PLISTBOXDATA) pCtrl->userdata; newTop = pData->itemTop; newSel = pData->itemHilighted; oldHighlight = pData->itemHilighted; switch (LOWORD(wParam)) { case VK_HOME: /* SCANCODE_HOME: */ newSel = 0; newTop = 0; break; case VK_LEFT: if (dwStyle & WS_HSCROLL) PostMessage(hwnd, WM_HSCROLL, SB_LINELEFT, 0); break; case VK_RIGHT: if (dwStyle & WS_HSCROLL) PostMessage(hwnd, WM_HSCROLL, SB_LINERIGHT, 0); break; case VK_END: /* SCANCODE_END: */ newSel = pData->itemCount - 1; if (pData->itemCount > pData->itemVisibles) newTop = pData->itemCount - pData->itemVisibles; else newTop = 0; break; case VK_DOWN: /* SCANCODE_CURSORBLOCKDOWN: */ newSel++; if (newSel >= pData->itemCount) return 0; if (newSel > ITEM_BOTTOM(pData)) newTop++; break; case VK_UP: /* SCANCODE_CURSORBLOCKUP: */ newSel--; if (newSel < 0) return 0; if (newSel < pData->itemTop) newTop--; break; case VK_NEXT: /* SCANCODE_PAGEDOWN: */ newSel += pData->itemVisibles; if (newSel >= pData->itemCount) newSel = pData->itemCount - 1; if (pData->itemCount - newSel >= pData->itemVisibles) newTop = newSel; else newTop = max(pData->itemCount - pData->itemVisibles, 0); break; case VK_PRIOR: /* SCANCODE_PAGEUP: */ newSel -= pData->itemVisibles; if (newSel < 0) newSel = 0; newTop -= pData->itemVisibles; if (newTop < 0) newTop = 0; break; default: return 0; } if (pData->itemHilighted != newSel) { if (pData->itemTop != newTop) { pData->itemTop = newTop; pData->itemHilighted = newSel; if (!(dwStyle & LBS_MULTIPLESEL)) { oldSel = lstSelectItem(dwStyle, pData, newSel); if ((dwStyle & LBS_NOTIFY) && (oldSel != newSel)) NotifyParent(hwnd, pCtrl->id,LBN_SELCHANGE); } InvalidateRect(hwnd, NULL, TRUE); } else { if (!(dwStyle & LBS_MULTIPLESEL)) oldSel = lstSelectItem(dwStyle, pData, newSel); pData->itemHilighted = newSel; if ((dwStyle & LBS_NOTIFY) && (oldSel != newSel)) NotifyParent(hwnd, pCtrl->id, LBN_SELCHANGE); if (oldSel != newSel) lstInvalidateItem(hwnd, pData, oldSel, FALSE); if ((oldHighlight != newSel) && (oldHighlight != oldSel)) lstInvalidateItem(hwnd, pData, oldHighlight, FALSE); lstInvalidateItem(hwnd, pData, newSel, FALSE); } if ((dwStyle & LBS_OWNERDRAWVARIABLE)) lstCalcParams(hwnd, NULL, pData); lstSetVScrollInfo(hwnd, pData, TRUE); } } break; case WM_CHAR: { char head[2]; int index; int newTop; switch ((char) (wParam)) { case 0x00: /* NULL */ case 0x07: /* BEL */ case 0x08: /* BS */ case 0x09: /* HT */ case 0x0A: /* LF */ case 0x0B: /* VT */ case 0x0C: /* FF */ case 0x0D: /* CR */ case 0x1B: /* Escape */ return SendMessage(GetParent(hwnd), WM_CHAR, wParam, lParam);; } head[0] = (char) (wParam); head[1] = '\0'; pData = (PLISTBOXDATA) pCtrl->userdata; if (head[0] == ' ') { if (dwStyle & LBS_MULTIPLESEL) { lstSelectItem(dwStyle, pData, pData->itemHilighted); lstInvalidateItem(hwnd, pData, pData-> itemHilighted, FALSE); } else if (dwStyle & LBS_CHECKBOX) { NotifyParent(hwnd, pCtrl->id, LBN_CLICKCHECKMARK); if (dwStyle & LBS_AUTOCHECK) { PLISTBOXITEM plbi; plbi = lstGetItem(pData, pData->itemHilighted); switch (plbi-> dwFlags & LBIF_CHECKMARKMASK) { case LBIF_CHECKED: plbi->dwFlags &= ~LBIF_CHECKMARKMASK; break; default: plbi->dwFlags &= ~LBIF_CHECKMARKMASK; plbi->dwFlags |= LBIF_CHECKED; break; } lstInvalidateItem(hwnd, pData, pData-> itemHilighted, FALSE); } } break; } index = lstFindItem(pData, pData->itemHilighted + 1, head, FALSE); if (index < 0) { index = lstFindItem(pData, 0, head, FALSE); } if (index >= 0) { if (pData->itemCount - index >= pData->itemVisibles) newTop = index; else newTop = max(pData->itemCount - pData->itemVisibles, 0); pData->itemTop = newTop; pData->itemHilighted = index; if (!(dwStyle & LBS_MULTIPLESEL)) lstSelectItem(dwStyle, pData, index); InvalidateRect(hwnd, NULL, TRUE); if ((dwStyle & LBS_OWNERDRAWVARIABLE)) lstCalcParams(hwnd, NULL, pData); lstSetVScrollInfo(hwnd, pData, TRUE); } } break; case WM_VSCROLL: { int newTop; int scrollHeight = 0; pData = (PLISTBOXDATA) pCtrl->userdata; newTop = pData->itemTop; switch (wParam) { case SB_LINEDOWN:#if 0 /* test itemVisibles */ printf("itemVisibles:%d\n", pData->itemVisibles); printf("SB_LINEDOWN:(%d:%d)\n", ITEM_BOTTOM(pData), (pData->itemCount - 1));#endif if (ITEM_BOTTOM(pData) < (pData->itemCount - 1)) { newTop++; scrollHeight = -pData->itemHeight; /* for ScrollWindow() */ } break; case SB_LINEUP: if (pData->itemTop > 0) { newTop--; scrollHeight = pData->itemHeight; } break; case SB_PAGEDOWN: if ((pData->itemTop + (pData->itemVisibles << 1)) <= pData->itemCount) newTop += pData->itemVisibles; else newTop = pData->itemCount - pData->itemVisibles; if (newTop < 0) return 0; scrollHeight = -(newTop - pData->itemTop) * pData->itemHeight; break; case SB_PAGEUP: if (pData->itemTop >= pData->itemVisibles) newTop -= pData->itemVisibles; else newTop = 0; scrollHeight = (pData->itemTop - newTop) * pData->itemHeight; break; case SB_THUMBTRACK: newTop = (int) lParam; scrollHeight = (pData->itemTop - newTop) * pData->itemHeight; break; } if (scrollHeight) { pData->itemTop = newTop;#if 0 /* !!: fix: no scroll */ ScrollWindow(hwnd, 0, scrollHeight, NULL, NULL);#endif if ((dwStyle & LBS_OWNERDRAWVARIABLE)) lstCalcParams(hwnd, NULL, pData); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); lstSetVScrollInfo(hwnd, pData, TRUE); return 0; } } break; case WM_HSCROLL: { int lh; RECT rc; GetClientRect(hwnd, &rc); pData = (PLISTBOXDATA) pCtrl->userdata; lh = pData->hoffset; switch (wParam) { case SB_LINERIGHT: pData->hoffset += 10; break; case SB_LINELEFT: pData->hoffset -= 10; break; case SB_PAGELEFT: pData->hoffset -= rc.right * 3 / 4; break; case SB_PAGERIGHT: pData->hoffset += rc.right * 3 / 4; break; case SB_THUMBTRACK: pData->hoffset = lParam; break; } if (pData->hoffset > pData->hextent - rc.right) pData->hoffset = pData->hextent - rc.right; if (pData->hoffset < 0) pData->hoffset = 0; if (pData->hoffset != lh) lstSetHScrollInfo(hwnd, pData, TRUE); } break; case LB_SETTABSTOPS: pData = (PLISTBOXDATA) pCtrl->userdata; pData->nTabStops = (int) wParam; if (pData->pTabStops) free(pData->pTabStops); if ((int) wParam > 0) { RECT rc; int i; rc.left = rc.top = rc.bottom = 0; pData->pTabStops = (LPINT) malloc(sizeof(int) * wParam); for (i = 0; i < (int) wParam; i++) { rc.right = ((LPINT) lParam)[i]; MapDialogRect(GetParent(hwnd), &rc); pData->pTabStops[i] = rc.right; } } else pData->pTabStops = NULL; InvalidateRect(hwnd, NULL, TRUE); break; case LB_SETHORIZONTALEXTENT: pData = (PLISTBOXDATA) pCtrl->userdata; pData->hextent = wParam; pData->hoffset = 0; lstSetHScrollInfo(hwnd, pData, TRUE); break; case LB_GETHORIZONTALEXTENT: pData = (PLISTBOXDATA) pCtrl->userdata; return pData->hextent; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -