📄 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 + -