Win32 SDK 下的TreeCtrl控件的封装
自己照着MFC封装,半月前封装了一半,碰到问题就放下了,今天终于封装好了.
[Ctree.h]文件
#pragma once
#include <windows.h>
#include <commctrl.h> struct MTVINSERTSTRUCT
{
TVINSERTSTRUCT tvInsert;
TCHAR strMid[2500];
}; class CTree
{
public:
CTree();
~CTree(); HWND m_hWnd;
public:
//获得树控件的句柄
BOOL GetHwnd(HWND _pHwnd, UINT _idd); //插入树节点
HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct);
HTREEITEM InsertItem(LPCTSTR lpszItem, int nImage, int nSelectedImage,
HTREEITEM hParent, HTREEITEM hInsertAfter); //获得选中节点的句柄
HTREEITEM GetSelectedItem()const;
//删除选中节点
BOOL DeleteItem(HTREEITEM hItem);
//删除所有的节点项
BOOL DeleteAllItem();
//设置节点附加的32位数据
BOOL SetItemData(HTREEITEM hItem, DWORD dwData);
//设置节点项数据
BOOL SetItem(TVITEM *pItem);
BOOL SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage,
UINT nState, UINT nStateMask, LPARAM lParam);
//获得选中节点项附加的32位数据
DWORD GetItemData(HTREEITEM hItem)const;
//获得选中节点项的显示的名称
TCHAR* GetItemText(HTREEITEM hItem)const;
//获得选中节点项的图标索引值
BOOL GetItemImage(HTREEITEM hItem, int &nImage, int &nSelectedImage)const;
//获得选中节点项的展开状态
BOOL GetItemState(HTREEITEM hItem, UINT nStateMask) const;
};
[Ctree.cpp]文件
#include "CTree.h"
#include <tchar.h>
#include <atlchecked.h> #pragma region MY_CtreeCtrl_Class CTree::CTree()
{
m_hWnd = NULL; } CTree::~CTree()
{ } BOOL CTree::GetHwnd(HWND _pHwnd, UINT _idd)
{
m_hWnd = GetDlgItem(_pHwnd, _idd);
if (m_hWnd)
{
return TRUE;
}
return FALSE;
} HTREEITEM CTree::InsertItem(LPTVINSERTSTRUCT lpInsertStruct)
{
IsWindow(m_hWnd);
return (HTREEITEM)::SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)lpInsertStruct);
} HTREEITEM CTree::InsertItem(LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter)
{
IsWindow(m_hWnd);
TVINSERTSTRUCT lpInsert;
lpInsert.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
lpInsert.item.iImage = nImage;
lpInsert.item.iSelectedImage = nSelectedImage;
lpInsert.item.pszText = (LPWSTR)lpszItem; if (NULL == hParent)
hParent = TVI_ROOT;
lpInsert.hParent = hParent; lpInsert.hInsertAfter = hInsertAfter; return InsertItem(&lpInsert);
} HTREEITEM CTree::GetSelectedItem() const
{
IsWindow(m_hWnd);
return (HTREEITEM)::SendMessage(m_hWnd, TVM_GETNEXTITEM, TVGN_CARET, 0);
} BOOL CTree::DeleteItem(HTREEITEM hItem)
{
IsWindow(m_hWnd);
return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)hItem);
} BOOL CTree::DeleteAllItem()
{
IsWindow(m_hWnd);
return (BOOL)::SendMessage(m_hWnd, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
}
//32位系统可用
BOOL CTree::SetItemData(HTREEITEM hItem, DWORD dwData)
{
IsWindow(m_hWnd); return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData);
}
//64位系统上要用LPARAM 用DWORD要被截断
//***********************************************************************************
BOOL AfxCTreeCtrl::SetItemData(HTREEITEM hItem, LPARAM dwData)
{
ASSERT(IsWindow(m_hWnd));
return SetItem(hItem, TVIF_PARAM, NULL, 0, 0, 0, 0, (LPARAM)dwData);
}
//***********************************************************************************
BOOL CTree::SetItem(TVITEM * pItem)
{
IsWindow(m_hWnd);
return (BOOL)SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)pItem);
} BOOL CTree::SetItem(HTREEITEM hItem, UINT nMask, LPCTSTR lpszItem, int nImage, int nSelectedImage, UINT nState, UINT nStateMask, LPARAM lParam)
{
IsWindow(m_hWnd);
TVITEM item;
item.hItem = hItem;
item.mask = nMask;
item.pszText = (LPTSTR)lpszItem;
item.iImage = nImage;
item.iSelectedImage = nSelectedImage;
item.state = nState;
item.stateMask = nStateMask;
item.lParam = lParam;
return (BOOL)::SendMessage(m_hWnd, TVM_SETITEM, 0, (LPARAM)&item);
}
//32位系统可用
DWORD CTree::GetItemData(HTREEITEM hItem) const
{
IsWindow(m_hWnd);
if (NULL == hItem)
return 0;
TVITEM item;
item.hItem = hItem;
item.mask = TVIF_PARAM;
::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
return item.lParam; }
//64位系统用
LPARAM AfxCTreeCtrl::GetItemData(HTREEITEM hItem) const
{
ASSERT(IsWindow(m_hWnd));
TVITEM item;
item.hItem = hItem;
item.mask = TVIF_PARAM;
::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
return (LPARAM)item.lParam;
}
TCHAR* CTree::GetItemText(HTREEITEM hItem) const
{
IsWindow(m_hWnd);
TCHAR* str = new TCHAR[128];
TVITEM item;
item.hItem = hItem;
item.mask = TVIF_TEXT;
item.pszText = str;
item.cchTextMax = 128; ::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item); return str;
} BOOL CTree::GetItemImage(HTREEITEM hItem, int &nImage, int &nSelectedImage) const
{
IsWindow(m_hWnd);
TVITEM item = { 0 };
item.hItem = hItem;
item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
BOOL bRes = (BOOL)::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
if (bRes)
{
nImage = item.iImage;
nSelectedImage = item.iSelectedImage;
}
return bRes;
} BOOL CTree::GetItemState(HTREEITEM hItem, UINT nStateMask) const
{
IsWindow(m_hWnd);
TVITEM item = { 0 };
item.hItem = hItem;
item.mask = TVIF_STATE;
item.stateMask = nStateMask;
item.state = 0;
::SendMessage(m_hWnd, TVM_GETITEM, 0, (LPARAM)&item);
return item.state;
} #pragma endregion MY_CtreeCtrl_Class
[test.cpp]中测试
HTREEITEM hItem = m_tree.GetSelectedItem();
//TVITEM tvi;
//TCHAR szName[20] = { 0 };
////LPARAM lp = 0;
//tvi.mask = TVIF_TEXT | TVIF_PARAM;
//tvi.hItem = hItem;
//tvi.pszText = szName;
//tvi.cchTextMax = sizeof(szName);
////tvi.lParam = lp;
//TreeView_GetItem(m_tree.m_hWnd, &tvi);
//Stu *pstu = (Stu*)tvi.lParam; //获得选中节点的附加(由SetItemData设置的)数据
/*Stu* pstu = (Stu*)m_tree.GetItemData(hItem);
TCHAR *pch = (TCHAR*)m_tree.GetItemData(hItem);*/
//上次在封装这附加数据的时候碰到了问题.
在设置的时候:
TCHAR *pch = new TCHAR;
pch=mid;//mid为要设置的附加数据,类型为TCHAR
m_tree.SetItemData(nItem, (DWORD)pch);
就一直取不出来要的数据,就放下了.今天来看的时候才发现
TCHAR *pch = new TCHAR[128];
_tcscpy_s(pch, 128, mid);
m_tree.SetItemData(nItem, (DWORD)pch);
我用结构体指针为附加数据时,又能正确取出数据.就有点晕菜了,最后才发现.
TCHAR new出来时没给定大小.
正确代码为:
TCHAR *pch = new TCHAR[128];
_tcscpy_s(pch, 128, mid);
m_tree.SetItemData(nItem, (DWORD)pch);
//获得选中节点的Text
/*TCHAR *pch = m_tree.GetItemText(hItem);
MessageBox(NULL, pch, TEXT("123"), MB_OK);*/ //获得选中节点的图标的索引
/*int nImate, nSelectedImage;
m_tree.GetItemImage(hItem, nImate, nSelectedImage);*/ //获得选中节点是否展开,返回0为未展开,非0为展开状态 //UINT n = m_tree.GetItemState(hItem, TVIS_EXPANDED); BOOL m = m_tree.GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED;
释放节点附加数据内存
//5.附加内存的释放
//在子控件通知消息中捕获TVN_DELETEITEM消息
NMHDR *pNMHDR = (NMHDR*)lParam;
if (pNMHDR->idFrom == IDC_TREE1 && pNMHDR->code==TVN_DELETEITEM)
{
NMTREEVIEW *pnmTV = (NMTREEVIEW*)lParam;
HTREEITEM hSelItem = pnmTV-> itemNew.hItem; //从lParam参数中获得选中项的句柄
//释放节点附加数据内存
TVITEM item = pnmTV->itemOld;
if (item.lParam != 0)
{
delete (TCHAR*)item.lParam;//删除的数据类型要和前面添加时你附加的数据类型一样,
} }
Win32 SDK 下的TreeCtrl控件的封装的更多相关文章
- Win32 SDK程序创建一些控件(简单调用InitCommonControlsEx,并指定ICC_LISTVIEW_CLASSES控件就可以了)
在Win32 SDK中创建一些控件的时候需要注意一下(具体是哪些控件请参看MSDN文档中列出来的) /* MSDN:Carries information used to load common co ...
- 9.2.2 .net framework下的MVC 控件的封装(下)
控件封装的部分说明 可能有人觉得应该前后端分离,我也承认这是应该的方向,我们也在考虑使用ng2等简化前端.但是,我们封装控件还是因为如下原因综合考虑的: 我们这是个框架,上面支撑了许多个应用,包含几百 ...
- 9.2.1 .net framework下的MVC 控件的封装(上)
在写.net core下mvc控件的编写之前,我先说一下.net framework下我们MVC控件的做法. MVC下控件的写法,主要有如下三种,最后一种是泛型的写法,mvc提供的控件都是基本控件. ...
- win32 TreeCtrl控件通知消息, LVN_SELCHANGED和LVN_ITEMCHANGED用法
今天出了个奇怪的问题,当我在主窗口上创建一个用模板对话框的子窗口时, 在子窗口上放的TreeCtrl控件不响应LVN_SELCHANGED消息,也是晕死了, 我以为是消息捕获的问题,我在主窗口上也捕获 ...
- Google SwipeRefreshLayout(Goolge官方下拉刷新控件)尝鲜
前天Google官方终于出了Android刷新控件——SwipeRefreshLayout. 使用前先需要将android.support.v4.jar升级到19.1.升级后,可能会出现SDK版本与A ...
- Android——谷歌官方下拉刷新控件SwipeRefreshLayout(转)
转自:http://blog.csdn.net/zouzhigang96/article/details/50476402 版权声明:本文为博主原创文章,未经博主允许不得转载. 前言: 如今谷歌推出了 ...
- android官方下拉刷新控件SwipeRefreshLayout的使用
可能开发安卓的人大多数都用过很多下拉刷新的开源组件,但是今天用了官方v4支持包的SwipeRefreshLayout觉得效果也蛮不错的,特拿出来分享. 简介:SwipeRefreshLayout组件只 ...
- 分享一个 C# Winfrom 下的 OutlookBar 控件的使用
最近在上网的时候,发现了这个C# 下的 OutlookBar 控件,看了一下感觉还真不错,特此记录一下. using System; using System.Drawing; using Syste ...
- [Android]下拉刷新控件RefreshableView的实现
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4172483.html 需求:自定义一个ViewGroup,实现 ...
- android SwipeRefreshLayout google官方下拉刷新控件
下拉刷新功能之前一直使用的是XlistView很方便我前面的博客有介绍 SwipeRefreshLayout是google官方推出的下拉刷新控件使用方法也比较简单 今天就来使用下SwipeRefres ...
随机推荐
- 【Vyos-开源篇-1】- VMware 安装 VyOS 虚拟机
文章说明:使用VMware ESXi和VMware Workstation安装vyos软路由. 一.项目准备 1.1.VMware ESXi 我家里的是一台8核心,20G内存,2T的N5105工控机, ...
- php不使用Office包实现上万条数据导出表格
经过上传客户要求主副表迁出,又提出可以将某张表的数据导出excel,听着很简单,实际看数据表发现上万条数据,并且需要关联表查询相关字段,导出的表格才可以被客户看明白. 要是使用office包目前后台内 ...
- 4.4K Star!推荐一款新一代的极简监控系统!轻量高性能!超500个监控指标,颜值高、功能强大!
在信息化快速发展的今天,企业运维面临的挑战日益增多.传统的运维监控系统往往存在功能冗余.性能低下.操作复杂等问题,难以满足现代企业对高效.稳定.智能的运维管理需求. 今天给大家推荐一款新一代极简运维监 ...
- Ubuntu 安装 gitweb + Apache2
背景 之前已经使用了gerrit进行代码管理,但是在有些代码由于内部技术管理不当而丢失了Review记录. 因此找到了通过gitweb弥补的问题. 做法 安装 sudo apt-get install ...
- FFmpeg开发笔记(三十三)分析ZLMediaKit对H.264流的插帧操作
<FFmpeg开发实战:从零基础到短视频上线>一书的"3.4.3 把原始的H264文件封装为MP4格式"介绍了如何把H.264裸流封装为MP4文件.那么在网络上传输 ...
- 模拟用户登录-cookes
import requests url = 'https://www.xread8.com/user/login.json' headers = { 'User-Agent': 'Mozilla/5. ...
- 算法金 | 来了,pandas 2.0
大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今日 210+/10000,内含 Pandas 是一个强大的数据分析库,广泛应用于科学 ...
- zookeeper的znode节点过多无法通过zkCli.sh移除节点
背景描述:zookeeper的一个目录下的znode节点过多,导致在执行ls 和rmr命令的时候,直接终止会话退出,无法递归删除下面的子节点,具体情况如下(生产环境的zookeeper是clickho ...
- 类、事件与对象---Dad&Mom简单练习
目的: 模拟一个家庭日常发生的场景:妈妈做好饭,说:"开饭了!",这是爸爸听到了妈妈的喊话就立马动身开始饭吃.而儿子此时正在打游戏,于是他就说:"等我打完这把游戏再吃!& ...
- 【JavaScript高级01】JavaScript基础深入
1,数据类型 JavaScript将数据分为六大类型,分别为数值类型(number).字符串类型(string).布尔类型(boolean).undefined(定义未赋值).null(赋值为空值). ...