[WTL/ATL]_[初级]_[TreeView控件如何显示ToolTip]

news2024/9/23 21:32:31

场景

  1. 在开发界面程序时,CTreeViewCtrl(它实际内部封装的就是Win32TreeView控件)一般会用来作为选择某些类型的树形菜单,点击某项的时候,右边能显示某些对应的数据。当这个控件的宽度固定时,有时候每行的文本项可能由于过长从而穿透了整个控件的水平位置, 从而显示效果来看是不好的。这时候希望可以用省略号的样式来省略后边多出的文本,之后鼠标移动到这个文本项时能显示完整的文字,那么这个文本提示,或者说tooltip如何实现?

说明

  1. CTreeViewCtrlWTL的新版里可以使用它的子类CTreeViewCtrlExTCTreeViewCtrlExTHTREEITEM常用操作进行了封装,也可以对返回的CTreeItemT类进行操作,它提供了很多便利的方法对HTREEITEM的处理。
CTreeViewCtrlExT<CWindow> treeView_;
  1. 默认情况下,当创建一个CTreeViewCtrl时,默认就会创建一个tooltip,除非指定样式TVS_NOTOOLTIPS才不会创建这个子控件。可是就算是默认创建里,这个tooltip并不会自动显示,还需要进行一些编码。
treeView_.Create(m_hWnd,NULL,L"Tree",WS_VISIBLE | WS_CHILD | 
		TVS_SHOWSELALWAYS | 
		TVS_FULLROWSELECT |
		TVS_HASLINES |
		TVS_LINESATROOT |
		TVS_INFOTIP | WS_BORDER|
		TVS_HASBUTTONS,0,kMyTreeViewId);

auto tooltip = treeView_.GetToolTips();
assert(tooltip.m_hWnd);

  1. TreeView创建时如果提供了TVS_INFOTIP样式,当鼠标移动到文本项的上边时,就会触发一个TVN_GETINFOTIP通知。通过捕抓这个通知,就可以设置在tooltip显示的文本。没错,这个样式就是可让tooltip显示。注意,这个样式不能和TVS_NOTOOLTIPS使用,只有创建了tooltip才会有提示气泡。
BEGIN_MSG_MAP_EX(CView)
	NOTIFY_HANDLER_EX(kMyTreeViewId,TVN_GETINFOTIP,onInfoTip)
	REFLECT_NOTIFICATIONS()
END_MSG_MAP()


LRESULT CView::onInfoTip(LPNMHDR pnmh)
{
	LPNMTVGETINFOTIP pTip = (LPNMTVGETINFOTIP)pnmh;
	CTreeItem item(pTip->hItem,&treeView_);

	item.GetText(pTip->pszText, pTip->cchTextMax);
	return 0;
}

例子

  1. 通过onInfoTip方法,把HTREEITEM的文本内容复制到LPNMTVGETINFOTIP结构的文本字段里,它的长度最长有1024字节.

View.h

// View.h : interface of the CView class
//
/

#pragma once

#include <utility>
#include <string>


enum
{
	kMyStaticId = WM_USER+1,
	kMyTreeViewId,
	kMyButtonId
};

class CView : public CWindowImpl<CView>
{
public:
	DECLARE_WND_CLASS(NULL)

	BOOL PreTranslateMessage(MSG* pMsg);

	BEGIN_MSG_MAP_EX(CView)
		MSG_WM_CREATE(OnCreate)
		MESSAGE_HANDLER(WM_PAINT, OnPaint)
		NOTIFY_HANDLER_EX(kMyTreeViewId,TVN_GETINFOTIP,onInfoTip)
		REFLECT_NOTIFICATIONS()
	END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
//	LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
//	LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
//	LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
	int OnCreate(LPCREATESTRUCT lpCreateStruct);
	LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
	void UpdateLayout();
	void AddMockData();
	void OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl);
	LRESULT onInfoTip(LPNMHDR pnmh);

private:
	std::wstring GetControlText(HWND hwnd,wchar_t* buf = NULL);
	HTREEITEM AppendItem(HTREEITEM hParentItem,LPWSTR pText,bool hasChildren = false);

	CTreeViewCtrlExT<CWindow> treeView_;

	CFont font_normal_;
	CFont font_bold_;

	CBrushHandle brush_white_;
	CBrushHandle brush_hollow_;
	CBrush brush_red_;
	CToolTipCtrl tooltip_;
	TCHAR strToolTipText_[MAX_PATH];

public:
};

View.cpp

// View.cpp : implementation of the CView class
//
/

#include "stdafx.h"
#include "resource.h"
#include <utility>
#include <sstream>
#include <assert.h>

#include "View.h"
#include <CommCtrl.h>
#include <string>
#include <regex>

using namespace std;

BOOL CView::PreTranslateMessage(MSG* pMsg)
{
	return FALSE;
}

LRESULT CView::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	CPaintDC dc(m_hWnd);
	CMemoryDC mdc(dc,dc.m_ps.rcPaint);

	CRect rect_client;
	GetClientRect(&rect_client);
	mdc.FillSolidRect(rect_client,RGB(255,255,255));
	//TODO: Add your drawing code here

	return 0;
}

static HFONT GetFont(int pixel,bool bold,const wchar_t* font_name)
{
	LOGFONT lf; 
	memset(&lf, 0, sizeof(LOGFONT)); // zero out structure 
	lf.lfHeight = pixel; // request a 8-pixel-height font
	if(bold)
	{
		lf.lfWeight = FW_BOLD;  
	}
	lstrcpy(lf.lfFaceName, font_name); // request a face name "Arial"
	
	HFONT font = ::CreateFontIndirect(&lf);
	return font;
}


std::wstring CView::GetControlText(HWND hwnd,wchar_t* buf)
{
	auto length = ::GetWindowTextLength(hwnd);
	bool bufNull = false;
	if(!buf){
		buf = new wchar_t[length+1]();
		bufNull = true;
	}
	
	::GetWindowText(hwnd,buf,length+1);
	std::wstring str(buf);

	if(bufNull)
		delete []buf;

	return str;
}

static std::wstring GetProductBinDir()
{
	static wchar_t szbuf[MAX_PATH];  
	GetModuleFileName(NULL,szbuf,MAX_PATH);  
    PathRemoveFileSpec(szbuf);
	int length = lstrlen(szbuf);
	szbuf[length] = L'\\';
	szbuf[length+1] = 0;
	return std::wstring(szbuf);
}

HTREEITEM CView::AppendItem(HTREEITEM hParentItem,LPWSTR pText,bool hasChildren)
{
	TVINSERTSTRUCT tvis;
	tvis.hParent=hParentItem;
	tvis.hInsertAfter=TVI_LAST;

	tvis.itemex.mask=TVIF_TEXT|TVIF_PARAM;
	if(hasChildren)
		tvis.itemex.mask |= TVIF_CHILDREN;
	
	tvis.itemex.pszText=pText;

	return treeView_.InsertItem(&tvis);
}

void CView::AddMockData()
{
	AppendItem(NULL,L"Tobey");
	AppendItem(NULL,L"Level",true);
	auto nameItem = AppendItem(NULL,L"Website");
	AppendItem(nameItem,L"https://blog.csdn.net/infoworld");
}

int CView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	font_normal_ = ::GetFont(16,false,L"Arial");
	font_bold_ = ::GetFont(16,true,L"Arial");


	// `TVS_INFOTIP`样式是必须的,不然无法触发`TVN_GETINFOTIP`消息.
	// `TVS_NOTOOLTIPS`样式不能设置,如果设置了,不会创建`tooltip`控件; 
	// 默认`treeView`控件会创建一个`tooltip`控件.
	treeView_.Create(m_hWnd,NULL,L"Tree",WS_VISIBLE | WS_CHILD | 
		TVS_SHOWSELALWAYS | 
		TVS_FULLROWSELECT |
		TVS_HASLINES |
		TVS_LINESATROOT |
		TVS_INFOTIP | WS_BORDER|
		TVS_HASBUTTONS,0,kMyTreeViewId);

	// 会自动创建一个`tooltip`,这里只是一个例子
	auto tooltip = treeView_.GetToolTips();
	assert(tooltip.m_hWnd);
	AddMockData();

	brush_hollow_ = AtlGetStockBrush(HOLLOW_BRUSH);
	brush_white_ = AtlGetStockBrush(WHITE_BRUSH);
	brush_red_.CreateSolidBrush(RGB(255,0,0));
	UpdateLayout();

	return 0;
}

LRESULT CView::onInfoTip(LPNMHDR pnmh)
{
	LPNMTVGETINFOTIP pTip = (LPNMTVGETINFOTIP)pnmh;
	CTreeItem item(pTip->hItem,&treeView_);

	item.GetText(pTip->pszText, pTip->cchTextMax);
	return 0;
}

void CView::OnCommandIDHandlerEX(UINT uNotifyCode, int nID, CWindow wndCtl)
{
		
}

void CView::UpdateLayout()
{
	CRect rect;
	GetClientRect(&rect);

	CClientDC dc(m_hWnd);
	dc.SelectFont(font_normal_);

	CSize size_control(700,300);
	CRect rect_control = CRect(CPoint(20,20),size_control);
	treeView_.MoveWindow(rect_control);

}

图1:

在这里插入图片描述

下载

https://download.csdn.net/download/infoworld/87448039

参考

  1. TVM_SETTOOLTIPS message (Commctrl.h)

  2. How to Use Tree-View Infotips

  3. Tree View

  4. Using Tree-View Controls

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/342637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【图像分类】基于PyTorch搭建LSTM实现MNIST手写数字体识别(双向LSTM,附完整代码和数据集)

写在前面&#xff1a; 首先感谢兄弟们的关注和订阅&#xff0c;让我有创作的动力&#xff0c;在创作过程我会尽最大能力&#xff0c;保证作品的质量&#xff0c;如果有问题&#xff0c;可以私信我&#xff0c;让我们携手共进&#xff0c;共创辉煌。 在https://blog.csdn.net/A…

【CSS】元素居中总结-水平居中、垂直居中、水平垂直居中

【CSS】元素居中一、 水平居中1.行内元素水平居中&#xff08;1&#xff09;text-align2.块级元素水平居中2.1 margin&#xff08;1&#xff09;margin2.2布局&#xff08;1&#xff09;flex justify-content&#xff08;推荐&#xff09;&#xff08;2&#xff09; flexmargin…

张驰咨询:关于六西格玛,有一些常见的疑惑!

​ 很多想要学习六西格玛的学员&#xff0c;经常会有这些困惑&#xff1a; 以前没有接触过六西格玛&#xff0c;需要什么基础吗&#xff1f;自学还是培训&#xff1f;哪些行业会用到六西格玛呢&#xff1f;学习六西格玛对以后的工作有哪些帮助&#xff1f;如何选择六西格玛培…

STM32配置读取双路24位模数转换(24bit ADC)芯片CS1238数据

STM32配置读取双路24位模数转换&#xff08;24bit ADC&#xff09;芯片CS1238数据 CS1238是一款国产双路24位ADC芯片&#xff0c;与CS1238对应的单路24位ADC芯片是CS1237&#xff0c;功能上相当于HX711和TM7711的组合。其功能如下所示&#xff1a; 市面上的模块&#xff1a; …

股票买卖接口怎么来的?

现在股票买卖接口主要是在线上研发&#xff0c;有专业的开发团队进行源码开发和完善&#xff0c;但是&#xff0c;常常会在开发过程中出现问题&#xff0c;也就是遇到一些特殊的情况需要及时处理&#xff0c;那么股票买卖接口怎么开发实现出来的&#xff1f;一、股票买卖接口开…

案例分享| 助力数字化转型:广州期货交易所全栈信创项目管理平台上线

广州期货交易所项目管理平台基于易趋&#xff08;easytrack&#xff09;进行实施&#xff0c;通过近半年的开发及试运行&#xff0c;现已成功交付上线、推广使用&#xff0c;取得了良好的应用效果。1. 关于广州期货交易所&#xff08;以下简称广期所&#xff09;广期所于2021年…

MySQL8.0安装教程

文章目录1.官网下载MySQL2.下载完记住解压的地址&#xff08;一会用到&#xff09;3.进入刚刚解压的文件夹下&#xff0c;创建data和my.ini在根目录下创建一个txt文件&#xff0c;名字叫my&#xff0c;文件后缀为ini&#xff0c;之后复制下面这个代码放在my.ini文件下&#xff…

华为手表开发:WATCH 3 Pro(4)创建项目 + 首页新建按钮,修改初始文本

华为手表开发&#xff1a;WATCH 3 Pro&#xff08;4&#xff09;创建项目 首页新建按钮&#xff0c;修改初始文本初环境与设备创建项目创建项目入口配置项目认识目录结构修改首页初始文本文件名&#xff1a;index.hml新建按钮 “ 按钮 ”index.hml初 鸿蒙可穿戴开发 希望能写…

直播预告 | 对谈谷歌云 DORA 布道师:聊聊最关键的四个 DevOps 表现指标

本期分享 DORA 的全称是 DevOps Research and Assessment&#xff0c;是一个致力于 DevOps 调研与研究的组织&#xff0c;2018 年加入 Google Cloud。自 2014 年起&#xff0c;DORA 每年会发布一份行业报告&#xff0c;基于对数千名从业者的调研&#xff0c;分析高效能团队与低…

联想K14电脑开机全屏变成绿色无法使用怎么U盘重装系统?

联想K14电脑开机全屏变成绿色无法使用怎么U盘重装系统&#xff1f;最近有用户使用联想K14电脑的时候&#xff0c;开机后桌面就变成了绿色的背景显示&#xff0c;无法进行任何的操作。而且通过强制重启之后还是会出现这个问题&#xff0c;那么这个情况如何去进行系统重装呢&…

PMP证书要怎么考,含金量怎么样?

很多朋友在对PMP不是了解的时候&#xff0c;会有些犹豫&#xff0c;PMP证书到底值不值得考。考下来有用吗&#xff1f; PMP证书当然有用&#xff0c;要含金量有含金量&#xff0c;要专业知识有专业知识&#xff0c;不过要是考了不用&#xff0c;久而久之忘了学习的内容&#x…

怿星科技校招礼盒:我想开了

校招礼盒大揭秘为了帮助2023届新同学快速了解怿星文化增强认同感经过1个多月的精心准备我们的校招大礼盒终于跟大家见面啦&#xff01;&#xff01;我们用了大量的公司IP形象-小怿通过各式各样的姿势和表情欢迎新同学的到来搭配着IP的蓝色色调传递出一种科幻与探索的感觉希望加…

计算机组成原理:1. 计算机系统概论

更好的阅读体验\huge{\color{red}{更好的阅读体验}}更好的阅读体验 文章目录1.1 计算机系统简介1.1.1 计算机软硬件概念1.1.2 计算机的层次1.1.3计算机组成和计算机体系结构1.2 计算机的基本组成1.2.1 冯诺伊曼计算机的特点1.2.2 计算机的硬件框图1.2.3 计算机的工作步骤1.3 计…

问卷调查会遇到哪些问题?怎么解决?

提到问卷调查我们并不陌生&#xff0c;它经常被用作调查市场、观察某类群体的行为特征等多种调查中。通过问卷调查得出的数据能够非常真实反映出是市场的现状和变化趋势&#xff0c;所以大家经常使用这个方法进行调查研究。不过&#xff0c;很多人在进行问卷调查的时候也会遇到…

JAVA八股、JAVA面经

还有三天面一个JAVA软件开发岗&#xff0c;之前完全没学过JAVA&#xff0c;整理一些面经...... 大佬整理的&#xff1a;Java面试必备八股文_-半度的博客-CSDN博客 另JAVA学习资料&#xff1a;Java | CS-Notes Java 基础Java 容器Java 并发Java 虚拟机Java IO目录 int和Inte…

电商新趋势来临!?解析Dtop 环球嘉年华电商是否值得加入!

近年来,电商平台的发展瞬息万变,加上疫情的推波助澜,让全球的电子商务来到前所未有的光景,营业销售额直达颠覆性的增长。 许多商家也因此纷涌而入,谋划分得电子商务的一杯羹。随着参与成为电商的商家日益剧增,商家们想从中谋利也不是件易事。再加上市场不断洗牌的形势下,传统电…

楔形文字的起源全2课-北京大学拱玉书 笔记

楔形文字的起源全2课-北京大学拱玉书 说明&#xff1a;以下图片素材均出自视频 【楔形文字的文源】 《吉尔伽美什史诗》记载的楔形文字起源&#xff1a; 学术界对楔形文字起源的总结&#xff1a; 【关于文字的演化理论发展史】 威廉.瓦尔伯顿提出文字“叙事图画”演变说…

浅谈 RBAC 权限模型

写作背景 工作两年半了&#xff0c;笔者一直在做 To B 的产品&#xff0c;像是后端管理系统、Saas 系统都有接触过&#xff0c;它们都有一个共同点&#xff1a;权限管理。我每天都在接触但只是从前端开发这个角色去理解&#xff0c;我对整个业务流程其实是比较模糊的&#xff…

第三部分:(主从)复合句——第一章:名词性从句

回顾&#xff1a;第二部分讲解的是并列句&#xff0c;即多件同等重要的事通过并列连词进行相连接&#xff0c;构成并列句 但是&#xff0c;现实生活中并不是许多事都是同等重要的&#xff0c;复合句就出现了&#xff0c;复合句全称为主从复合句 复合句 多件事不一样重要 主句…

GIS在地质灾害危险性评估与灾后重建中的实践技术应用及python机器学习灾害易发性评价模型建立与优化进阶

除滑坡灾害外&#xff0c;还包括崩塌、泥石流、地面沉降等各种地质灾害&#xff0c;具有类型多样、分布广泛、危害性大的特点。地质灾害危险性评价着重于根据多种影响因素和区域选择来评估在某个区域中某个阶段发生的地质灾害程度。以此预测和分析未来某个地形单位发生地质灾害…