⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osdtreeview.c

📁 MiniWinOuterSM MiniWinOuterSM
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "osdwindows.h"
#include"osdcommctrl.h"
#define	TVBoxHalfHeight		4
#define TVBoxGap		3
#define TVICONGAP		3					/*ICON 间隙宽度*/

#define ICON_FOLD       1//GetLargeSystemIcon (5)
#define ICON_UNFOLD  2  // GetLargeSystemIcon (6)
/*****************************************************************************

*****************************************************************************/
typedef struct tagTVDATA
{
	DWORD	dwStyle;				// draw icon or not;
	INT 	nVisCount;					// how many items can be showed in client area.
	INT	nItemHeight;			// the height of one item.
	INT	nItemCount;				// Number of all items in treeview.
	INT	nVisItemCount;		//可视项总数 Number of items which can(not should) be drawed  in client area. That means excluding children of fold items. 
	INT 	nItemTop;					// how many items are above the client area and should not be drawed.

	INT	nWidth;						// the width of treeview.
	INT 	nVisWidth;					// how many pixels can be showed in client area.
	PTVITEM	pItemSelected;	// this item is selected.
	PTVITEM	root;						//根节点 the root item of treeview.
} TVDATA,* PTVDATA;

static UINT TreeViewCtrlProc (HWND hwnd, int message, WPARAM wParam, LPARAM lParam);
/*****************************************************************************

*****************************************************************************/
BOOL RegisterTreeViewCtrl (void)
{
	WNDCLASS	wc;
//	wc.style	= CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
	wc.WndProc	= (WNDPROC)TreeViewCtrlProc;
//	wc.cbClsExtra	= 0;
//	wc.cbWndExtra	= 10;
//	wc.hInstance	= hInstance;
//	wc.hIcon	= NULL;
//	wc.hCursor	= 0;
//	wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
//	wc.lpszMenuName	= NULL;
	wc.ClassName= "TREEVIEW";
	return RegisterClass(&wc);
}
/*****************************************************************************
Initialize Treeview.
*****************************************************************************/
static BOOL tvInitTVData (HWND hwnd, PTVDATA pData, DWORD dwStyle)
{	
	PTVITEM	tvRoot;
    HDC hdc;

	pData->dwStyle = dwStyle;
	//创建根节点	
	if (!(tvRoot =(PTVITEM)PrMalloc(sizeof(TVITEM))))return FALSE;
	tvRoot->text = strdup ("Root");
	tvRoot->dwFlags = TVI_ROOT | TVIS_SELECTED;
	tvRoot->child = tvRoot->next = NULL;
	
   hdc = GetDC (hwnd);
	pData->nItemHeight = MAX(16,GetSysCCharWidth(hwnd));	/*起码要比图标大*/	
	pData->nVisItemCount = 1;
	pData->nItemCount = 1;
	pData->root = tvRoot;
	pData->pItemSelected = tvRoot;
	pData->nItemTop = 0;

    GetTextExtentPoint(hdc, tvRoot->text, -1, &tvRoot->text_ext);
	pData->nWidth = TVBoxGap + pData->nItemHeight + tvRoot->text_ext.cx;

	/*houzhif (pData->dwStyle & TVS_WITHICON)		
		pData->nWidth += pData->nItemHeight + TVICONGAP;*/

    ReleaseDC (hwnd, hdc);
	return TRUE;
}
/*****************************************************************************

*****************************************************************************/
static PTVITEM findParent (PTVITEM root, PTVITEM pChild)	
{	
	PTVITEM q = root->child;				// recursive function.
	PTVITEM t;
	while (q != NULL && q !=pChild) 
	{
		if (( t = findParent (q, pChild)) != NULL)
			return t;
		q = q->next;
	}
	if (q == pChild)
		return root;
	else 
		return NULL;
}
/*****************************************************************************

*****************************************************************************/
static PTVITEM getParent (PTVDATA pData, PTVITEM pChild)	
{ 
	if (pChild == pData->root || pChild == NULL)		// the given node.
		return NULL;
	return findParent (pData->root, pChild);
}
/*****************************************************************************
取前一节点
*****************************************************************************/
static PTVITEM getPrev (PTVDATA pData, PTVITEM pCur)		
{
	PTVITEM p,t;											// sibling is current node.
	p = getParent (pData, pCur);
	if (p == NULL || p->child == pCur)	return NULL;
	t = p->child;
	while (t->next != NULL && t->next != pCur)
		t = t->next;
	if (t->next != pCur)
		return NULL;
	return t;
}
/*****************************************************************************
展开全部节点
*****************************************************************************/
static void UnfoldAll (PTVITEM p)
{
	PTVITEM t;
	if (p == NULL) return;
	p->dwFlags &= ~TVIS_BOLD;
	t = p->child;
	while (t) 
	{
		UnfoldAll (t);
		t = t->next;
	}
}
/*****************************************************************************
计算p节点下显示项总数
*****************************************************************************/
static int VisItemCount (PTVITEM p, int c)
{
	PTVITEM t;
	static int count;
	count = c;
	count++;
	if (!(p->dwFlags & TVIS_BOLD)) 			/*展开*/	
	{
		t = p->child;
		while (t) 
		{
			VisItemCount (t, count);
			t = t->next;
		}
	}
	return count;
}
/*****************************************************************************
计算控件的显示项总数
*****************************************************************************/
static int getVisItemCount (PTVDATA pData)
{
	if (pData->root == NULL)
		return 0;
	return VisItemCount (pData->root, 0);
}
/*****************************************************************************
取pcur 到pTgt 之间有多少行
*****************************************************************************/
static int Itemdeep (PTVITEM pCur, PTVITEM pTgt, int d)
{
	static int deep;
	int q = 0;
	PTVITEM t;

	deep = d;
	if (pCur == pTgt)
		return deep;
	else 
	{
		t = pCur->child;
		deep++;
		while (t != NULL && !(q = Itemdeep (t, pTgt, deep))) 
			t = t->next;
	}
	deep--;
	return q;
}
/*****************************************************************************
取ptGt到根节点有多少行(不管是否展开)
*****************************************************************************/
static int getItemdeep (PTVDATA pData, PTVITEM pTgt)
{
	if (pTgt == NULL || pTgt == pData->root)
		return 0;
	return Itemdeep (pData->root, pTgt, 0);
}
/*****************************************************************************

*****************************************************************************/
static int TVWidth (PTVDATA pData, PTVITEM p, int w)
{
	PTVITEM t;
	static int width;
	int wtemp, h;

	h = pData->nItemHeight;
	width = w;
	wtemp = TVBoxGap + h + TVBoxGap + getItemdeep (pData, p) * h + p->text_ext.cx;
	if (pData->dwStyle & TVS_WITHICON)		wtemp += h + TVICONGAP;

	width = MAX (wtemp, width);
	if (!(p->dwFlags & TVIF_FOLD)) 
	{
		t = p->child;
		while (t) 
		{
			TVWidth (pData, t, width);
			t = t->next;
		}
	}
	return width;
}
/*****************************************************************************
计算节点占据的最大宽度
*****************************************************************************/			
static int getTVWidth (PTVDATA pData)
{
	return TVWidth (pData, pData->root, 0);
}
/*****************************************************************************
删除节点
*****************************************************************************/
static void RemoveSubTree (PTVDATA pData, PTVITEM p)		//  Used by RemoveTree().
{
	PTVITEM q, n;
	if (p == NULL )
		return;						//  recursive function.
	q = p->child;
	while (q != NULL)					/*删除其下的子节点*/ 
	{
		n = q->next;
		RemoveSubTree (pData, q);
		q = n;
	}
	mwOsFreeMemory (p->text);
	mwOsFreeMemory (p);
	pData->nItemCount--;	
}
/*****************************************************************************

*****************************************************************************/
static void RemoveTree (HWND hwnd, PTVDATA pData, PTVITEM pChild)		// Remove a tree or subtree.
{
	PTVITEM p, q;
	if (pChild == NULL) return;
	
	if (pChild == pData->root)			/*根节点*/ 
	{
		pData->root = NULL;
		pData->pItemSelected = NULL;
		pData->nVisItemCount = 1;
		pData->nWidth = 1;
		pData->nItemTop  = 0;
		RemoveSubTree (pData, pChild);
	} 
	else 
	{
		p = pData->pItemSelected = getParent (pData, pChild);  /*将父节点变为当前项*/
		if (pChild == p->child)
			p->child = pChild->next;
		else 
		{
			q = p->child;
			while (q !=NULL && q->next != pChild)
				q = q->next;
			q->next = pChild->next;
		}
		RemoveSubTree (pData, pChild);
		pData->nWidth = getTVWidth (pData);
		pData->nVisItemCount = getVisItemCount (pData);
	}
}
/*****************************************************************************
在p节点及子节点查找字符串
*****************************************************************************/
static PTVITEM findString (PTVITEM p, char* string)
{
	PTVITEM q, t = NULL;
	if (!strcmp (p->text, string))
		return p;
	else 
	{
		q = p->child;
		while (q != NULL && !(t = findString (q, string)))
			q = q->next;
	}
	return t;
}
/*****************************************************************************
在整个树中查找字符串
*****************************************************************************/
static PTVITEM find (PTVDATA pData, char* string)
{
	if (pData->root == NULL)
		return NULL;
	return findString (pData->root, string);
}
/*****************************************************************************

*****************************************************************************/
static int countPrevNext (PTVDATA pData, PTVITEM prev, int c)
{
	static int count;
	PTVITEM t;
	count = c;
	count++;
	if (!(prev->dwFlags & TVIF_FOLD)) 
	{
		t = prev->child;
		while (t) 
		{
			countPrevNext (pData, t, count);
			t = t->next;
		}
	}
	return count;
}
/*****************************************************************************
取前一节点项目数
*****************************************************************************/
static int getItemsWithPrev (PTVDATA pData, PTVITEM pCur)
{
	PTVITEM prev = getPrev(pData, pCur);
	if (prev == NULL)
		return 0;
	return countPrevNext (pData, prev, 0) - 1;
}
/*****************************************************************************
取后一节点项目数
*****************************************************************************/
static int getItemsWithNext (PTVDATA pData, PTVITEM pCur)
{
	if (pCur == NULL || pCur->next == NULL)
		return 0;
	return countPrevNext (pData, pCur, 0) - 1;
}
/*****************************************************************************
插入节点
input: parent-父节点, pchild-要插入的子节点
*****************************************************************************/
static void InsertChild (HWND hwnd, PTVDATA pData, PTVITEM pParent, PTVITEM pChild)
{
	PTVITEM p, t = NULL;						// Add a node.
	int deep, h, w;
    HDC hdc;

	if (pChild == NULL)		return;
	pChild->child = pChild->next = NULL;

	if (pParent == NULL)	pParent = pData->pItemSelected;	/*如果父为空,则父为当前选中项*/

	if (pParent->child == NULL)
		pParent->child = pChild;
	else if (pData->dwStyle & TVS_SORT) 
	{
		p = pParent->child;
		while (strcmp(pChild->text, p->text) > 0 && p->next != NULL) 
		{
			t = p;
			p = p->next;
		}
		if (strcmp(pChild->text, p->text) > 0)
			p->next = pChild;
		else if (t == NULL) 
		{
			pParent->child = pChild;
			pChild->next = p;
		} 
		else 
		{
			t->next = pChild;
			pChild->next = p;
		}
	}
	else 
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -