📄 listbox.c
字号:
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: { RECT rc; 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 (pData->dwFlags & LBF_NOTHINGSELECTED) { lstSelectItem (hwnd->style, pData, pData->itemTop); pData->dwFlags &= ~LBF_NOTHINGSELECTED; } GetClientRect (hwnd, &rc); lstOnDrawSListBoxItems (hdc, dwStyle, pData, rc.right-rc.left); lstDrawFocusRect (hdc, pData, &rc); 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; RECT rcInv; 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; GetClientRect (hwnd, &rcInv); 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)) { lstGetItemsRect (pData, oldSel, oldSel, &rcInv); InvalidateRect (hwnd, &rcInv, TRUE); } } lstGetItemsRect (pData, hit, hit, &rcInv); InvalidateRect (hwnd, &rcInv, TRUE); if (pData->itemHilighted != hit) { hdc = GetDC(hwnd); /* hdc = GetClientDC (hwnd); */ lstDrawFocusRect (hdc, pData, &rcInv); 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, TRUE); } } } lstSetVScrollInfo (hwnd, pData, TRUE); } break; case WM_LBUTTONUP: break; case WM_MOUSEMOVE: break; case WM_KEYDOWN: { int oldSel, newSel, newTop; RECT rcInv; pData = (PLISTBOXDATA)pCtrl->userdata; newTop = pData->itemTop; newSel = pData->itemHilighted; switch (LOWORD (wParam)) { case VK_HOME: /* SCANCODE_HOME: */ newSel = 0; newTop = 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; } GetClientRect (hwnd, &rcInv); 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); if ((dwStyle & LBS_NOTIFY) && (oldSel != newSel)) NotifyParent (hwnd, pCtrl->id, LBN_SELCHANGE); if (oldSel >= 0) { if (oldSel >= pData->itemTop && oldSel <= (ITEM_BOTTOM (pData) + 1)) { lstGetItemsRect (pData, oldSel, oldSel, &rcInv); InvalidateRect (hwnd, &rcInv, TRUE); } } if (newSel < newTop) { pData->itemHilighted = newSel; break; } lstGetItemsRect (pData, pData->itemHilighted, pData->itemHilighted, &rcInv); hdc = GetDC(hwnd); /* hdc = GetClientDC (hwnd); */ lstDrawFocusRect (hdc, pData, &rcInv); ReleaseDC (hwnd,hdc); pData->itemHilighted = newSel; lstGetItemsRect (pData, newSel, newSel, &rcInv); InvalidateRect (hwnd, &rcInv, TRUE); } else { hdc = GetDC(hwnd); /* hdc = GetClientDC (hwnd); */ lstDrawFocusRect (hdc, pData, &rcInv); pData->itemHilighted = newSel; GetClientRect (hwnd, &rcInv); lstDrawFocusRect (hdc, pData, &rcInv); ReleaseDC (hwnd,hdc); } } lstSetVScrollInfo (hwnd, pData, TRUE); } } break; case WM_CHAR: { char head [2]; int index; int newTop; head [0] = (char) (wParam); head [1] = '\0'; pData = (PLISTBOXDATA)pCtrl->userdata; if (head[0] == ' ') { if (dwStyle & LBS_MULTIPLESEL) { RECT rcInv; GetClientRect (hwnd, &rcInv); lstSelectItem (dwStyle, pData, pData->itemHilighted); lstGetItemsRect (pData, pData->itemHilighted, pData->itemHilighted, &rcInv); InvalidateRect (hwnd, &rcInv, TRUE); } 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, TRUE); } } 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); 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 SendMessage (hwnd, WM_PAINT, 0, 0); lstSetVScrollInfo (hwnd, pData, TRUE); return 0; } } break; case WM_HSCROLL: pData = (PLISTBOXDATA)pCtrl->userdata; switch (wParam) { case SB_LINERIGHT: break; case SB_LINELEFT: break; case SB_PAGELEFT: break; case SB_PAGERIGHT: break; } break; default: return DefWindowProc (hwnd, message, wParam, lParam); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -