📄 treeview.c
字号:
return -1; case MSG_PAINT: { HDC hdc; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); hdc = BeginPaint (hwnd); tvOnDraw (hwnd, hdc, pData); EndPaint (hwnd, hdc); return 0; } case TVM_SETSTRCMPFUNC: pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); if (pData->nItemCount == 1 && lParam) { pData->str_cmp = (STRCMP)lParam; return 0; } return -1; case TVM_GETROOT: pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); return (int) pData->root; break; case TVM_SEARCHITEM: { const char *text; PTVITEM root, matched; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); root = (PTVITEM)wParam; text = (const char *)lParam; if (root == NULL) root = pData->root; if (text == NULL || is_descendant (pData->root, root, NULL)) return 0; matched = findStringDepthFirst (pData, root, text); return (int)matched; } case TVM_FINDCHILD: { const char *text; PTVITEM item, matched; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); item = (PTVITEM)wParam; text = (const char *)lParam; if (item == NULL) item = pData->root; if (text == NULL || is_descendant (pData->root, item, NULL)) return 0; matched = findStringInChildren (pData, item, text); return (int)matched; } case TVM_GETSELITEM: pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); return (int)pData->pItemSelected; case TVM_SETSELITEM: { PTVITEM old_sel, new_sel = (PTVITEM)wParam; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); old_sel = pData->pItemSelected; if (old_sel != new_sel) { if (is_descendant (pData->root, new_sel, NULL)) return -1; old_sel->dwFlags &= ~TVIF_SELECTED; new_sel->dwFlags |= TVIF_SELECTED; pData->pItemSelected = new_sel; NotifyParent (hwnd, pData->id, TVN_SELCHANGE); unfold_ancestor (hwnd, pData, new_sel); recalc_redraw (hwnd, pData); } return (int)old_sel; } case TVM_GETRELATEDITEM: { int related = (int) wParam; PTVITEM item = (PTVITEM) lParam; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); if (is_descendant (pData->root, item, NULL)) return 0; switch (related) { case TVIR_PARENT: return (int)item->parent; case TVIR_FIRSTCHILD: return (int)item->child; case TVIR_NEXTSIBLING: return (int)item->next; case TVIR_PREVSIBLING: return (int)getPrev (pData, item); } return 0; } case TVM_GETITEMTEXTLEN: { PTVITEM item = (PTVITEM) wParam; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); if (is_descendant (pData->root, item, NULL)) return -1; return strlen (item->text); } case TVM_GETITEMTEXT: { PTVITEM item = (PTVITEM) wParam; char* buffer = (char*) lParam; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); if (is_descendant (pData->root, item, NULL)) return -1; strcpy (buffer, item->text); return strlen (buffer); } case TVM_GETITEMINFO: { PTVITEM item = (PTVITEM)wParam; PTVITEMINFO info = (PTVITEMINFO)lParam; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); if (is_descendant (pData->root, item, NULL)) return -1; if (info) { if (info->text) strcpy (info->text, item->text); info->dwFlags = item->dwFlags; info->hIconFold = item->hIconFold; info->hIconUnfold = item->hIconUnfold; info->dwAddData = item->dwAddData; } return 0; } case TVM_SETITEMINFO: { PTVITEM item = (PTVITEM)wParam; PTVITEMINFO info = (PTVITEMINFO)lParam; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); if (is_descendant (pData->root, item, NULL)) return -1; if (info) { if (info->text) {#if _USE_FIXSTR FreeFixStr (item->text); item->text = FixStrAlloc (strlen (info->text)); if (item->text == NULL) { NotifyParent (hwnd, pData->id, TVN_ERRSPACE); return -1; } strcpy (item->text, info->text);#else free (item->text); item->text = strdup (info->text); if (item->text == NULL) { NotifyParent (hwnd, pData->id, TVN_ERRSPACE); return -1; }#endif } if (info->hIconFold) item->hIconFold = info->hIconFold; if (info->hIconUnfold) item->hIconFold = info->hIconUnfold; item->dwAddData = info->dwAddData; recalc_redraw (hwnd, pData); } return 0; } case TVM_DELTREE: { PTVITEM item = (PTVITEM)wParam; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); if (is_descendant (pData->root, item, NULL)) return -1; if (is_descendant (item, pData->pItemSelected, NULL) == 0) { change_selected (hwnd, pData, item->parent); } RemoveTree (hwnd, pData, item); recalc_redraw (hwnd, pData); return 0; } case TVM_ADDITEM: case TVM_INSERTITEM: { PTVITEMINFO pTVItemInfo; PTVITEM parent, newItem = NULL; pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); pTVItemInfo = (PTVITEMINFO) lParam; parent = (PTVITEM) wParam; if (parent == NULL) parent = pData->root; newItem = calloc (1, sizeof(TVITEM)); if (newItem == NULL) { NotifyParent (hwnd, pData->id, TVN_ERRSPACE); return 0; } #if _USE_FIXSTR newItem->text = FixStrAlloc (strlen(pTVItemInfo->text)); if (newItem->text == NULL) { free (newItem); NotifyParent (hwnd, pData->id, TVN_ERRSPACE); return 0; } strcpy (newItem->text, pTVItemInfo->text);#else newItem->text = strdup (pTVItemInfo->text); if (newItem->text == NULL) { free (newItem); NotifyParent (hwnd, pData->id, TVN_ERRSPACE); return 0; }#endif if (pData->dwStyle & TVS_WITHICON) { if (pTVItemInfo->hIconFold) newItem->hIconFold = (DWORD) pTVItemInfo->hIconFold; else newItem->hIconFold = (DWORD) ICON_FOLD; if (pTVItemInfo->hIconUnfold) newItem->hIconUnfold = (DWORD) pTVItemInfo->hIconUnfold; else newItem->hIconUnfold = (DWORD) ICON_UNFOLD; } else { newItem->hIconFold = 0L; newItem->hIconUnfold = 0L; } if (pTVItemInfo->dwFlags & TVIF_FOLD) { newItem->dwFlags = TVIF_FOLD; } newItem->dwAddData = pTVItemInfo->dwAddData; InsertChild (hwnd, pData, parent, newItem); tvSetVScrollInfo (hwnd, pData, TRUE); tvSetHScrollInfo (hwnd, pData, TRUE); InvalidateRect (hwnd, NULL, FALSE); return (int) newItem; } case MSG_KEYDOWN: { PTVITEM p, t; RECT rc; int count, c, rctop; GetClientRect (hwnd, &rc); pData = (PTVDATA) GetWindowAdditionalData2 (hwnd); switch (LOWORD (wParam)) { case SCANCODE_CURSORBLOCKRIGHT: p = pData->pItemSelected; count = getCountFromItem (pData, p); rctop = rc.top; if (p->child == NULL) return 0; else if (p->dwFlags & TVIF_FOLD) { p->dwFlags &= ~TVIF_FOLD; NotifyParentEx (hwnd, pData->id, TVN_UNFOLDED, (DWORD)p); pData->nWidth = getTVWidth (pData); pData->nVisItemCount = getVisItemCount (pData); count = count - pData->nItemTop - 1; rc.top = rctop + count * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; InvalidateRect (hwnd, &rc, FALSE); tvSetVScrollInfo (hwnd, pData, TRUE); tvSetHScrollInfo (hwnd, pData, TRUE); } else { t = p->child; change_selected (hwnd, pData, t); c = getCountFromItem (pData, t); if (c > pData->nItemTop + pData->nVisCount) { pData->nItemTop = c - pData->nVisCount; InvalidateRect (hwnd, NULL, FALSE); tvSetVScrollInfo (hwnd, pData, TRUE); break; } c = c - pData->nItemTop - 1; rc.top = rctop + c * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; rc.bottom = rc.top + pData->nItemHeight; InvalidateRect (hwnd, &rc, FALSE); count = count - pData->nItemTop - 1; rc.top = rctop + count * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; rc.bottom = rc.top + pData->nItemHeight; InvalidateRect (hwnd, &rc, FALSE); } break; case SCANCODE_CURSORBLOCKLEFT: p = pData->pItemSelected; count = getCountFromItem (pData, p); rctop = rc.top; if (p == NULL) return 0; if (p->child && !(p->dwFlags & TVIF_FOLD)) { p->dwFlags |= TVIF_FOLD; NotifyParentEx (hwnd, pData->id, TVN_FOLDED, (DWORD)p); pData->nWidth = getTVWidth (pData); pData->nVisItemCount = getVisItemCount (pData); count = count - pData->nItemTop - 1; rc.top = rctop + count * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; InvalidateRect (hwnd, &rc, FALSE); tvSetVScrollInfo (hwnd, pData, TRUE); tvSetHScrollInfo (hwnd, pData, TRUE); } else { t = getParent (pData, p); if (t == NULL) return 0; change_selected (hwnd, pData, t); c = getCountFromItem (pData, t); if (c <= pData->nItemTop) { pData->nItemTop = c - 1; InvalidateRect (hwnd, NULL, FALSE); tvSetVScrollInfo (hwnd, pData, TRUE); break; } c = c - pData->nItemTop - 1; rc.top = rctop + c * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; rc.bottom = rc.top + pData->nItemHeight; InvalidateRect (hwnd, &rc, FALSE); count = count - pData->nItemTop - 1; rc.top = rctop + count * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; rc.bottom = rc.top + pData->nItemHeight; InvalidateRect (hwnd, &rc, FALSE); } break; case SCANCODE_CURSORBLOCKUP: p = pData->pItemSelected; count = getCountFromItem (pData, p); rctop = rc.top; if (count <= 1) break; c = count - 1; t = getItemFromCount (pData, c); if (t == NULL) break; change_selected (hwnd, pData, t); if (c > pData->nItemTop && c <= pData->nItemTop + pData->nVisCount) { c = c - pData->nItemTop - 1; rc.top = rctop + c * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; rc.bottom = rc.top + pData->nItemHeight; InvalidateRect (hwnd, &rc, FALSE); count = count - pData->nItemTop - 1; rc.top = rctop + count * pData->nItemHeight; if (pData->dwStyle & WS_BORDER) rc.top += TV_BORDER; rc.bottom = rc.top + pData->nItemHeight; InvalidateRect (hwnd, &rc, FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -