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

📄 tree-box.zc

📁 实现树形结构
💻 ZC
📖 第 1 页 / 共 2 页
字号:
//[cf]
//[c]
//[of]:handle popup (event)
public func handle popup (m: tree box, e: popup event)

	def caught = handle popup (super (m), e)

	if not nil (original selected item (m)) && original selected item (m) <> selected item (m)
		selected item (m) = original selected item (m)
		original selected item (m) = nil
		synchronize widget selection (m)
	end

	return caught

end
//[cf]
//[cf]
//[of]:private
//[of]:synchronize widget tree
func synchronize widget tree (m: tree box)

	def tree = tree model (m)
	if is nil (tree)
		return
	end

	def root = root (tree)
	def t := temp string buffer
	append text (root, t)
	def hRoot = add item (m, as string (t), TVI_ROOT, TVI_FIRST, root)
	release (t)

	expand (m, hRoot)

end
//[cf]
//[of]:synchronize widget selection
func synchronize widget selection (m: tree box)

	synchronizing selection (m) = true
	select (m, selected item (m))
	synchronizing selection (m) = false

end
//[c]
//[c]SUB-FUNCTIONS
//[of]:	select (m, item)
private func select (m: tree box, item: tree item)

	def hItem : HTREEITEM
	if is nil (item)
		hItem = nil
	else
		def parent = parent (item)
		if is nil (parent)
			hItem = root (m)
		else
			def hParent = expand (m, parent)
			hItem = find handle (m, hParent, item)
		end
	end
	select (m, hItem)

end
//[cf]
//[of]:	expand (m, item)
private func expand (m: tree box, item: tree item) : HTREEITEM

	def hItem : HTREEITEM
	if is nil (parent (item))
		hItem = root (m)
	else
		def hParent = expand (m, parent (item))
		hItem = find handle (m, hParent, item)
	end
	expand (m, hItem)
	return hItem	

end
//[cf]
//[cf]
//[of]:synchronize image list
func synchronize image list (m: tree box)

	send message (
		m, 
		TVM_SETIMAGELIST, 
		TVSIL_NORMAL: WPARAM, 
		handle (image list (m)): LPARAM)

end
//[cf]
//[c]
//[c]Events from model
//[of]:text changed (item)
func text changed (m: tree box, item: tree item)

	// ignore event -- the widget is not activated
	if is nil (hwnd (m))
		return
	end

	def hItem = find handle (m, item)
	
	// ignore event -- the node is not visible in the tree
	if is nil (hItem)
		return
	end
	
	// update item if item added or removed
	update item (m, hItem, item)

end
//[cf]
//[of]:has children changed (item)
func has children changed (m: tree box, item: tree item)

	// ignore event -- the widget is not activated
	if is nil (hwnd (m))
		return
	end

	def hItem = find handle (m, item)
	
	// ignore event -- the node is not visible in the tree
	if is nil (hItem)
		return
	end
	
	// ignore event -- the node is expanded
	if is expanded (m, hItem)
		return
	end

	// update item to draw or remove the 'plus' sign
	update item (m, hItem, item)

end
//[cf]
//[of]:data changed (item)
func data changed (m: tree box, item: tree item)

	// ignore event -- the widget is not activated
	if is nil (hwnd (m))
		return
	end

	def hItem = find handle (m, item)
	
	// ignore event -- the node is not visible in the tree
	if is nil (hItem)
		return
	end
	
	def e: local tree item changed event
	type (e) = tree item changed event type
	tree item (e) = item
	notify parent (m, e)

end
//[cf]
//[of]:children replaced (tree replace event)
func children replaced (m: tree box, e: tree replace event)
	
	// ignore event -- the widget is not activated
	if is nil (hwnd (m))
		return
	end

	def hParent = find handle (m, parent (e))
	
	// ignore event -- the node is not visible in the tree
	if is nil (hParent)
		return
	end
	
	// do not update children if collaped
	if is expanded (m, hParent)
	
		// find first item to remove
		def n = index (e)
		def hPrev = TVI_FIRST
		def hChild = first child (m, hParent)
		def child = first child (parent (e))
		while n > 0
			hPrev = hChild
			hChild = next sibling (m, hChild)
			child = next sibling (child)
			n -= 1
		end
	
		// removed items	
		n = removed (e)
		while n > 0
			def hNext = next sibling (m, hChild)
			delete item (m, hChild)
			hChild = hNext
			n -= 1
		end
	
		// inserted items
		def t := temp string buffer
		n = inserted (e)
		while n > 0
			remove all (t)
			append text (child, t)
			hPrev = add item (m, as string (t), hParent, hPrev, child)
			child = next sibling (child)
			n -= 1
		end
		release (t)
	end
	
	// update item if item added or removed
	if inserted (e) <> 0 || removed (e) <> 0
		update item (m, hParent, parent (e))
	end
	
end
//[cf]
//[c]
//[of]:get ex style
private func get ex style (m: tree box)

	if edit border (style (m)) == border sunken
		return WS_EX_CLIENTEDGE
	else
		return 0:d
	end
	
end
//[cf]
//[of]:get style
//[c]
func get style (m: tree box)

	return base style (m) | 
		WS_CLIPCHILDREN | WS_VSCROLL |
		TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT  | TVS_SHOWSELALWAYS |
		WS_BORDER
	
end
//[cf]
//[of]:update from style
//[c]
private func update from style (m: tree box)

	set edit font (m)

	def style = style (m)
	send message (m, TVM_SETBKCOLOR, 0 : WPARAM, edit background (style) : LPARAM)
	send message (m, TVM_SETTEXTCOLOR, 0 : WPARAM, edit color (style) : LPARAM)

end
//[cf]
//[c]
//[of]:find handle (item)
private func find handle (m: tree box, item: tree item) : HTREEITEM

	def hItem : HTREEITEM
	if is nil (parent (item))
		hItem = root (m)
	else
		def hParent = find handle (m, parent (item))
		hItem = find handle (m, hParent, item)
	end
	return hItem	

end
//[cf]
//[of]:find handle (hParent, item)
private func find handle (m: tree box, hParent: HTREEITEM, item: tree item)
	
	def hItem = first child (m, hParent)
	while not nil (hItem)
		if item == tree item (m, hItem)
			return hItem
		end
		hItem = next sibling (m, hItem)
	end

	return nil

end		
//[c]
//[cf]
//[c]
//[of]:add children (hParent, parent)
func add children (m: tree box, hParent: HTREEITEM, parent: tree item)
	
	open (parent)
	def child = first child (parent)
	if is nil (child)
		update item (m, hParent, parent)
		// do not close, so we catch all event from children
		//close (parent)
		return
	end

	def t := temp string buffer
	def hPrev = TVI_FIRST
	while not nil (child)
		remove all (t)
		append text (child, t)
		hPrev = add item (m, as string (t), hParent, hPrev, child)
		child = next sibling (child)
	end
	release (t)

end
//[cf]
//[of]:add item (text, hParent, hPrev, child)
func add item (m: tree box, text: string, hParent: HTREEITEM, hPrev: HTREEITEM, child: tree item)

	def tvins: TVINSERTSTRUCT
	def tvi = item (tvins)
	mask (tvi) = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE
	stateMask (tvi) = 0
	pszText (tvi) = text
	cchTextMax (tvi) = size (text)
	lParam (tvi) = child: LPARAM
	cChildren (tvi) = (has children (child) -> 1, 0)
	
	def image = image (child)
	iImage (tvi) = image
	iSelectedImage (tvi) = image
	
	hInsertAfter (tvins) = hPrev
	hParent (tvins) = hParent
	
	// Add the item to the tree view control. 
	return send message (m, TVM_INSERTITEM, 0:WPARAM, tvins:LPARAM) : HTREEITEM

end	
//[cf]
//[of]:update item (hItem, item)
func update item (m: tree box, hItem: HTREEITEM, item: tree item)

	def t := temp string buffer
	append text (item, t)
	def text = as string (t)

	def tvi : TVITEM
	mask (tvi) = TVIF_TEXT | TVIF_CHILDREN
	stateMask (tvi) = 0
	hItem (tvi) = hItem
	pszText (tvi) = text
	cChildren (tvi) = (has children (item) -> 1, 0)
	
	send message (m, TVM_SETITEM, 0:WPARAM, tvi:LPARAM) 
	
	release (t)

end	
//[cf]
//[of]:tree item (hItem)
private func tree item (m: tree box, hItem: HTREEITEM)
	def tvi : TVITEM
	mask (tvi) = TVIF_PARAM
	hItem (tvi) = hItem
	send message (m, TVM_GETITEM, 0:WPARAM, tvi:LPARAM) 
	return lParam (tvi) : tree item
end
//[cf]
//[c]
//[of]:root
private func root (m: tree box)
	return send message (m, TVM_GETNEXTITEM, TVGN_ROOT:WPARAM) : HTREEITEM
end
//[cf]
//[of]:first child (hItem)
private func first child (m: tree box, hItem: HTREEITEM)
	return send message (m, TVM_GETNEXTITEM, TVGN_CHILD:WPARAM, hItem:LPARAM) : HTREEITEM
end
//[cf]
//[of]:next sibling (hItem)
private func next sibling (m: tree box, hItem: HTREEITEM)
	return send message (m, TVM_GETNEXTITEM, TVGN_NEXT:WPARAM, hItem:LPARAM) : HTREEITEM
end
//[cf]
//[of]:parent (hItem)
private func parent (m: tree box, hItem: HTREEITEM)
	return send message (m, TVM_GETNEXTITEM, TVGN_PARENT:WPARAM, hItem:LPARAM) : HTREEITEM
end
//[cf]
//[of]:expand (hItem)
private func expand (m: tree box, hItem: HTREEITEM)
	send message (m, TVM_EXPAND, TVE_EXPAND:WPARAM, hItem:LPARAM)
end
//[cf]
//[of]:select (hItem)
private func select (m: tree box, hItem: HTREEITEM)
	send message (m, TVM_SELECTITEM, TVGN_CARET:WPARAM, hItem:LPARAM)
end
//[cf]
//[of]:delete item (hItem)
private func delete item (m: tree box, hItem: HTREEITEM)

	// if selection is deleted: we have to move selection because
	// window can change selection to something that is already
	// deleted.
	def item = selected item (m)
	if item == tree item (m, hItem)
		// Important: do not use 'parent (item)' since item may be already 
		// deleted.
		set selection (m, tree item (m, parent (m, hItem)))
	end

	return send message (m, TVM_DELETEITEM, 0:WPARAM, hItem:LPARAM)

end
//[cf]
//[of]:is collapsed (hItem)
private func is collapsed (m: tree box, hItem: HTREEITEM)
	return ~ is expanded (m, hItem)
end
//[cf]
//[of]:is expanded (hItem)
private func is expanded (m: tree box, hItem: HTREEITEM)
	def tvi : TVITEM
	mask (tvi) = 0
	stateMask (tvi) = TVIS_EXPANDED
	hItem (tvi) = hItem
	send message (m, TVM_GETITEM, 0:WPARAM, tvi:LPARAM) 
	return (state (tvi) & TVIS_EXPANDED) <> 0
end
//[cf]
//[cf]
//[cf]
//[of]:tree box class
//[of]:type
public struct tree box class : local box class
	// empty
end
//[cf]
//[of]:tree box class
public func tree box class

	def c = the tree box class
	if ~ initialized
		initialized = true
		c . copy (box class)
		c . release = ^actual release (tree box)
		c . compute min size = ^actual compute min size (tree box)
		c . accept focus = ^yes (box)
		c . window proc = ^window proc (tree box, UINT, WPARAM, LPARAM)
		c . wm size = ^wm size (box, UINT, WPARAM, LPARAM)
		c . wm notify  = ^wm notify (box, UINT, WPARAM, LPARAM)
		c . wm command = ^wm command (box, UINT, WPARAM, LPARAM)
		c . notify = ^notify proc (tree box, LPNMHDR)
		c . on popup = ^handle popup (tree box, popup event)
	end
	return c

end

private def initialized = false
private def the tree box class: local tree box class
//[cf]
//[cf]

⌨️ 快捷键说明

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