📄 osdtreeview.c
字号:
if (buffer == NULL) return 0;
p = pData->pItemSelected;
mwOsFreeMemory (p->text);
p->text = strdup (buffer);
if (p->text == NULL)
return -1;
NotifyParent(hwnd, id, TVN_SELCHANGE);
return 0;
}
//=====================================================================
case TVM_DELETEITEM:
{
PTVITEM p;
int id = LOWORD (wParam);
if (pData->pItemSelected != pData->root) /*不是根节点*/
{
p = getParent (pData, pData->pItemSelected);
p->dwFlags |= TVIF_SELECTED;
RemoveTree (hwnd, pData, pData->pItemSelected);
pData->pItemSelected = p;
InvalidateRect (hwnd, NULL, FALSE);
tvSetVScrollInfo (hwnd, pData, TRUE);
tvSetHScrollInfo (hwnd, pData, TRUE);
NotifyParent(hwnd, id, TVN_DELETEITEMA);
}
}
break;
//=====================================================================
//wParam=父节点 lParam=PTVITEMINFO
//=====================================================================
//case TVM_ADDITEM:
case TVM_INSERTITEMA:
{
TVINSERTSTRUCT* pTVItemInfo;
PTVITEM parent, newItem = NULL;
pTVItemInfo = (TVINSERTSTRUCT*) lParam;
parent = (PTVITEM) wParam;
newItem =(TVITEM*)PrMalloc(sizeof(TVITEM));
if (newItem == NULL)
return -1;
newItem->text = strdup (pTVItemInfo->text);
if (newItem->text == NULL)
{
PrFree(newItem);
return -1;
}
SetIconKind(ICON_SMALL); /*选择小图标*/
if (pData->dwStyle & TVS_WITHICON)
{
/*if (pTVItemInfo->hIconFold)
newItem->IconFold = (DWORD) pTVItemInfo->hIconFold;
if (pTVItemInfo->hIconUnfold)
newItem->IconUnfold=(DWORD)pTVItemInfo->hIconUnfold;*///houzh
}else{
newItem->IconFold = 0L;
newItem->IconUnfold = 0L;
}
InsertChild (hwnd, pData, parent, newItem);
tvSetVScrollInfo (hwnd, pData, TRUE);
tvSetHScrollInfo (hwnd, pData, TRUE);
InvalidateRect (hwnd, NULL, FALSE);
return 0;
}
//=====================================================================
//=====================================================================
case WM_KEYDOWN:
{
PTVITEM p, t;
RECT rc;
int count, c, rctop;
GetClientRect (hwnd, &rc);
switch (LOWORD (wParam))
{
case VK_RIGHT:
p = pData->pItemSelected;
count = getCountFromItem (pData, p);
rctop = rc.top;//houzh -hwnd->ScrollTop;
if (p->child == NULL)
return 0;
else if (p->dwFlags & TVIF_FOLD)
{
p->dwFlags &= ~TVIF_FOLD;
pData->nWidth = getTVWidth (pData);
pData->nVisItemCount = getVisItemCount (pData);
count = count - pData->nItemTop - 1;
rc.top = rctop + count * pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
tvSetVScrollInfo (hwnd, pData, TRUE);
tvSetHScrollInfo (hwnd, pData, TRUE);
}
else
{
t = p->child;
pData->pItemSelected = t;
p->dwFlags &= ~TVIF_SELECTED;
t->dwFlags |= TVIF_SELECTED;
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;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
count = count - pData->nItemTop - 1;
rc.top = rctop + count * pData->nItemHeight;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
}
break;
//--------------------------------------------------------------
//
//--------------------------------------------------------------
case VK_LEFT:
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;
pData->nWidth = getTVWidth (pData);
pData->nVisItemCount = getVisItemCount (pData);
count = count - pData->nItemTop - 1;
rc.top = rctop + count * pData->nItemHeight;//houzh -hwnd->ScrollTop;
InvalidateRect (hwnd, &rc, FALSE);
tvSetVScrollInfo (hwnd, pData, TRUE);
tvSetHScrollInfo (hwnd, pData, TRUE);
}
else /*没有子节点或出于折叠,则跳到父节点*/
{
t = getParent (pData, p);
if (t == NULL)
return 0;
pData->pItemSelected = t;
p->dwFlags &= ~TVIF_SELECTED;
t->dwFlags |= TVIF_SELECTED;
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;//houzh-hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
count = count - pData->nItemTop - 1;
rc.top = rctop + count * pData->nItemHeight;//-hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
}
break;
//--------------------------------------------------------------
//
//--------------------------------------------------------------
case VK_UP:
p = pData->pItemSelected;
count = getCountFromItem (pData, p);
rctop = rc.top;
if (count <= 1)
break;
c = count - 1;
t = getItemFromRow (pData, c);
if (t == NULL) break;
p->dwFlags &= ~TVIF_SELECTED;
t->dwFlags |= TVIF_SELECTED;
pData->pItemSelected = t;
if (c * pData->nItemHeight <= hwnd->ScrollTop)
{
//hwnd->ScrollTop-=pData->nItemHeight;
InvalidateRect (hwnd, NULL, FALSE);
tvSetVScrollInfo (hwnd, pData, TRUE);
break;
}else{
c = c - pData->nItemTop - 1;
rc.top = rctop + c * pData->nItemHeight;//houzh -hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
count = count - pData->nItemTop - 1;
rc.top = rctop + count * pData->nItemHeight;//houzh -hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
}
break;
//--------------------------------------------------------------
//
//--------------------------------------------------------------
case VK_DOWN:
p = pData->pItemSelected;
count = getCountFromItem (pData, p);
rctop = rc.top;
if (count >= pData->nVisItemCount) break;
c = count + 1;
t = getItemFromRow (pData, c);
if (t == NULL) break;
p->dwFlags &= ~TVIF_SELECTED;
t->dwFlags |= TVIF_SELECTED;
pData->pItemSelected = t;
if (c*pData->nItemHeight>(RECTH(&rc)/*houzh+hwnd->ScrollTop*/))
{
//houzh hwnd->ScrollTop+=pData->nItemHeight;
InvalidateRect (hwnd, NULL, FALSE);
tvSetVScrollInfo (hwnd, pData, TRUE);
break;
}else{
c = c - pData->nItemTop - 1; /*现在*/
rc.top = rctop + c * pData->nItemHeight;//houzh -hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
count = count - pData->nItemTop - 1; /*原来*/
rc.top = rctop+count*pData->nItemHeight;//-hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
}
break;
case VK_PRIOR: SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP, (LPARAM)0); break;
case VK_NEXT: SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,(LPARAM)0); break;
case VK_HOME: SendMessage(hwnd,WM_VSCROLL,SB_TOP,(LPARAM)0); break;
case VK_END: SendMessage(hwnd,WM_VSCROLL,SB_BOTTOM,(LPARAM)0); break;
default:
return 0;
}
}
break;
//========================================================
case WM_LBUTTONDOWN:
{
int mouseX = LOWORD(lParam);
int mouseY = HIWORD(lParam);
int right, left, count, deep, h, c, rctop;
RECT rc;
PTVITEM p;
count = (mouseY/*houzh +hwnd->ScrollTop*/)/ pData->nItemHeight + 1; /*判断在显示范围内第几行*/
count += pData->nItemTop;
if (count > pData->nVisItemCount) break;
p = getItemFromRow(pData, count); /*根据在第几行row 取出节点*/
if (p == NULL) break;
h = pData->nItemHeight;
deep = getItemdeep (pData, p); /*p 到根节点有几行(向右缩进)*/
left = /*houzh -hwnd->ScrollLeft +*/ TVBoxGap + deep * pData->nItemHeight;
right = left + h + TVBoxGap + p->text_ext.cx;
if (pData->dwStyle & TVS_WITHICON) right += h + TVICONGAP;
if (mouseX < left || mouseX > right) break;
GetClientRect (hwnd, &rc);
rctop = rc.top;
//--------------------------------------------------------------------------
//在控制盒范围内
//--------------------------------------------------------------------------
if (mouseX <= left + h && mouseX >= left)
{
if (p->child == NULL) break;
else if (CountFromItem (p, pData->pItemSelected, 0) != 0)
{
pData->pItemSelected->dwFlags &= ~TVIF_SELECTED; /*转换展开/折叠*/
pData->pItemSelected = p;
p->dwFlags |= TVIF_SELECTED;
}
p->dwFlags = (p->dwFlags & ~TVIF_FOLD) | (~p->dwFlags & TVIF_FOLD);
pData->nWidth = getTVWidth (pData);
pData->nVisItemCount = getVisItemCount (pData);
rc.top = rctop + (count - pData->nItemTop - 1) * pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
tvSetVScrollInfo (hwnd, pData, TRUE);
tvSetHScrollInfo (hwnd, pData, TRUE);
break;
}
left = left + h;
//----------------在节点文字内----------------------------------------
if (mouseX <= right && mouseX >= left)
{
if (p == pData->pItemSelected) break;
c = getCountFromItem (pData, pData->pItemSelected); /*从根节点到指定节点共有多少行*/
c = c -pData->nItemTop - 1; /*可显示行数to c*/
if (c < 0) c = 0;
pData->pItemSelected->dwFlags &= ~TVIF_SELECTED;
rc.top = (rctop + c * pData->nItemHeight);//houzh -hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
//-----------------------------------
pData->pItemSelected = p; /*p变为当前节点*/
p->dwFlags |= TVIF_SELECTED;
rc.top =rctop+(count-pData->nItemTop-1)*pData->nItemHeight;//houzh -hwnd->ScrollTop;
rc.bottom = rc.top + pData->nItemHeight;
InvalidateRect (hwnd, &rc, FALSE);
}
}
break;
//=====================================================================
case WM_LBUTTONDBLCLK:
{
int mouseX = LOWORD(lParam);
int mouseY = HIWORD(lParam);
int right, left, count, deep, h;
PTVITEM p;
RECT rc;
count = (mouseY/*houzh +hwnd->ScrollTop*/) / pData->nItemHeight + 1;
if (count > pData->nVisItemCount) break;
p = getItemFromRow(pData, count);
if (p == NULL) break;
h = pData->nItemHeight;
deep = getItemdeep (pData, p); /*缩进数量*/
left = /*houzh -hwnd->ScrollLeft*/+ TVBoxGap + h + deep * h;
right = left + TVBoxGap + p->text_ext.cx;
if (pData->dwStyle & TVS_WITHICON) right += (h + TVICONGAP);
if (p->child && mouseX <= right && mouseX >= left)
{
p->dwFlags = (p->dwFlags & ~TVIF_FOLD) | (~p->dwFlags & TVIF_FOLD); /*转换展开/折叠*/
pData->nWidth = getTVWidth (pData);
pData->nVisItemCount = getVisItemCount (pData);
tvSetVScrollInfo (hwnd, pData, TRUE);
tvSetHScrollInfo (hwnd, pData, TRUE);
GetClientRect (hwnd, &rc);
rc.top += (count - pData->nItemTop - 1) * pData->nItemHeight;//-hwnd->ScrollTop;
InvalidateRect (hwnd, &rc, FALSE);
break;
}
}
break;
//=====================================================================
/* case WM_VSCROLL:
hwnd->ScrollHeight=pData->nItemCount * pData->nItemHeight ;
return DefWindowProc(hwnd, message, wParam, lParam);
//==============================================
case WM_HSCROLL:
hwnd->ScrollWidth=pData->nWidth;
return DefWindowProc(hwnd, message, wParam, lParam);*/
//==============================================
case WM_SETFOCUS:
if (pData->dwStyle & TVS_FOCUS) break;
pData->dwStyle |= TVS_FOCUS;
InvalidateRect (hwnd, NULL, FALSE);
break;
//===============================================
case WM_KILLFOCUS:
if (!(pData->dwStyle & TVS_FOCUS)) break;
pData->dwStyle &= ~TVS_FOCUS;
InvalidateRect (hwnd, NULL, FALSE);
break;
//===============================================
case WM_GETDLGCODE:
return DLGC_WANTARROWS | DLGC_WANTCHARS;
default:
return DefWindowProc( hwnd, message, wParam, lParam);
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -