透明信息提示框CFyToolTip设计及源码 适用于各类绘图的实时信息展示


在图形绘制领域,经常需要用到透明的信息提示窗口,比如当鼠标移动到一个图元上,显示该图元对象的实时数据(如设备名称、状态、实测数据等),当鼠标移开,及时隐藏该提示框;比如在曲线控件绘图时,随着鼠标移动,实时展示曲线对应的横纵坐标值等

透明信息提示框CFyToolTip设计及源码 适用于各类绘图的实时信息展示

 

各种通用开发库里,也有类似的控件,如C# WinForm的ToolTip,1>风格比较厚实,透明度不好,遮挡住了底部的图形;2>Tip窗口显示和隐藏不灵敏,感觉顿挫。浮云绘图将在本文详细设计和实现透明信息提示框CFyToolTip类。

 

一、透明提示框的需求描述

1. 需支持显示和隐藏功能;

2. 需支持设定指定显示位置功能;

3. 需支持设置或动态计算提示框的窗口大小尺寸;

4. 需支持提示框背景色和边框颜色;

5. 需支持提示框文本字体类型和字号设置;

6. 需支持多行信息提示;

7. 需支持每行设置不同的文本内容和字体颜色。

 

二、透明提示框的定义(C++)

根据上文的开发需求和上图的展示效果,相应属性定义如下代码。

显示Tip框方法有4个:

void ShowTips(CPoint& point, CRect& parentRect, CString* vals, int* colors, int count)用于实现上图实时测量多行文本多颜色字体的信息提示,当然也可以用于所有情形信息提示。

void ShowXTips(int xCenter, int yTop, CString strTipsContent)用于实现上图X轴上的居中显示的信息提示框。
void ShowY1Tips(int xRight, int yCenter, CString strTipsContent)用于显示左侧Y轴的信息提示。
void ShowY2Tips(int xLeft, int yCenter, CString strTipsContent)用于显示右侧Y轴的信息提示。

 1 // 作者:浮云绘图,专业付费定制图形编辑器、工控曲线、报表等各类绘图软件
 2 // QQ:316868127
 3 
 4 class CFyToolTip : public CWnd
 5 {
 6 private:
 7     CPoint  m_ptOrg;            //左上角坐标
 8     CSize   m_TipSize;          
 9     CString m_strTips;
10     COLORREF m_clrBack = 0xE0E0E0;
11     COLORREF m_clrText = 0x000000;
12     COLORREF m_clrFrameColor;
13 
14     bool m_bMultLineTip = false;        //多行不同颜色文字Tip模式标记
15     CString* m_values = NULL;           //多行文本
16     int* m_colors = NULL;               //多行字体颜色
17     int m_lineCount = 0;
18 
19     CString m_fontName = "微软雅黑";
20     int m_fontSize = 8;
21 
22     // Construction
23 public:
24     CFyToolTip();
25     virtual ~CFyToolTip();
26 
27 public:
28     BOOL Create(CWnd* pWnd, BYTE bAlpha, DWORD dwStyle= WS_POPUP);    
29 
30     void SetToolTipSize(CSize szSize);
31 
32     void ShowTips(int nX, int nY, CString strTipsContent);
33 
34     void HideTips();
35 
36     void SetBkColor(COLORREF clrBack);
37 
38     void SetTipTextColor(COLORREF clrText);
39 
40     void SetFrameColor(COLORREF clrFrame);
41 
42     void ShowTips(CPoint& point, CRect& parentRect, CString* vals, int* colors, int count);
43 
44     void ShowXTips(int xCenter, int yTop, CString strTipsContent);
45     void ShowY1Tips(int xRight, int yCenter, CString strTipsContent);
46     void ShowY2Tips(int xLeft, int yCenter, CString strTipsContent);
47 
48     int GetTipsTextHeight();
49 
50     void DrawTransparentRect(CDC* dc, CRect* rect);
51 
52 protected:
53     //{{AFX_MSG(CFyToolTip)
54     afx_msg void OnPaint();
55     afx_msg BOOL OnEraseBkgnd(CDC* pDC);
56     //}}AFX_MSG
57     DECLARE_MESSAGE_MAP()
58 };

 

三、透明提示框的实现

请看OnPaint函数,先重绘客户区背景和边框 --> 再画各行文本(文字、字体和颜色)。

每当调用ShowTips函数时,根据传入的显示起点和显示内容,重新计算Tip窗口的大小位置,再调用OnPaint完成重绘。

  1 BOOL CFyToolTip::Create(CWnd* pWnd, BYTE bAlpha, DWORD dwStyle)
  2 {
  3     LPCTSTR lpszClassName = AfxRegisterWndClass(NULL);
  4     BOOL bRet = CreateEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, lpszClassName, _T(""),        //WS_EX_TOOLWINDOW  WS_EX_TOPMOST
  5         dwStyle, 0, 0, 1, 1, pWnd->GetSafeHwnd(), NULL);                                // WS_POPUP WS_CHILD
  6     if (bRet)
  7     {
  8         CSize sz(30,20);
  9         MoveWindow(CRect(m_ptOrg, sz));
 10         m_TipSize = sz;
 11     }
 12 
 13     LONG para = GetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE);
 14     para |= WS_EX_LAYERED;
 15     SetWindowLong(this->GetSafeHwnd(), GWL_EXSTYLE, para);
 16     SetLayeredWindowAttributes(RGB(0, 0, 0), bAlpha, LWA_ALPHA);    //LWA_ALPHA 
 17 
 18     m_parent = pWnd;
 19     return bRet;
 20 }
 21 
 22 void CFyToolTip::OnPaint()
 23 {
 24     CPaintDC dc(this); // device context for painting
 25 
 26     // TODO: Add your message handler code here
 27     CRect rtWin;
 28     GetClientRect(rtWin);
 29     dc.FillSolidRect(rtWin, m_clrBack);
 30     dc.SetBkMode(TRANSPARENT);
 31     dc.Draw3dRect(rtWin, m_clrFrameColor, m_clrFrameColor);
 32     
 33     CFont font;
 34     font.CreatePointFont(m_fontSize * 10, m_fontName, NULL);
 35     CFont* pOldFont = dc.SelectObject(&font);
 36 
 37     CRect curLineRect;
 38     if (!m_bMultLineTip)
 39     {
 40         CSize txtSize = dc.GetTextExtent(m_strTips);      // 字串的长度像素
 41         curLineRect.SetRect(rtWin.left + 0, 1, rtWin.right, txtSize.cy);
 42         dc.SetTextColor(m_clrText);
 43         dc.DrawText(m_strTips, rtWin, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
 44     }
 45     else
 46     {
 47         int offsetY = 1;
 48         for (int i = 0; i < m_lineCount; i++)
 49         {
 50             CSize txtSize = dc.GetTextExtent(m_values[i]);      // 字串的长度像素
 51 
 52             dc.SetTextColor(m_colors[i]);
 53             curLineRect.SetRect(rtWin.left + 4, offsetY, rtWin.right, offsetY + txtSize.cy);
 54             dc.DrawText(m_values[i], curLineRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
 55 
 56             offsetY += txtSize.cy + 1;
 57         }
 58     }
 59     dc.SelectObject(pOldFont);
 60 }
 61 
 62 
 63 
 64 void CFyToolTip::ShowTips(int nX, int nY, CString strTipsContent)
 65 {
 66     m_bMultLineTip = false;
 67 
 68     
 69     m_strTips = strTipsContent;
 70 
 71     //计算字符串长宽
 72     HDC hDC = ::GetDC(this->m_hWnd);
 73     CDC dc;
 74     dc.Attach(hDC);
 75 
 76     CFont font;
 77     font.CreatePointFont(m_fontSize * 10, m_fontName, NULL);
 78     CFont* pOldFont = dc.SelectObject(&font);
 79     CSize txtSize = dc.GetTextExtent(m_strTips);      // 字串的长度像素
 80     dc.SelectObject(pOldFont);
 81 
 82     //设置窗口位置大小
 83     m_ptOrg = CPoint(nX, nY);
 84     m_TipSize= txtSize;
 85     MoveWindow(nX, nY, m_TipSize.cx, m_TipSize.cy, TRUE);
 86     if (!IsWindowVisible())
 87     {
 88         ShowWindow(SW_SHOW);
 89     }
 90     Invalidate(TRUE);
 91 }
 92 
 93 void CFyToolTip::ShowXTips(int xCenter, int yTop, CString strTipsContent)
 94 {
 95     m_bMultLineTip = false;
 96 
 97     m_strTips = strTipsContent;
 98 
 99     //计算字符串长宽
100     HDC hDC = ::GetDC(this->m_hWnd);
101     CDC dc;
102     dc.Attach(hDC);
103 
104     CFont font;
105     font.CreatePointFont(m_fontSize * 10, m_fontName, NULL);
106     CFont* pOldFont = dc.SelectObject(&font);
107     CSize txtSize = dc.GetTextExtent(m_strTips);      // 字串的长度像素
108     dc.SelectObject(pOldFont);
109 
110     //设置窗口位置大小
111     int nX = xCenter - txtSize.cx / 2;
112     m_ptOrg = CPoint(nX, yTop);
113     m_TipSize = txtSize;
114     MoveWindow(nX, yTop, m_TipSize.cx + 2, m_TipSize.cy, TRUE);
115     if (!IsWindowVisible())
116     {
117         ShowWindow(SW_SHOW);
118     }
119     Invalidate(TRUE);
120 }
121 
122 void CFyToolTip::ShowY1Tips(int xRight, int yCenter, CString strTipsContent)
123 {
124     ......
125 }
126 
127 void CFyToolTip::ShowY2Tips(int xLeft, int yCenter, CString strTipsContent)
128 {
129     ......
130 }
131 
132 void CFyToolTip::ShowTips(CPoint& point, CRect& parentRect, CString* vals, int* colors, int count)
133 {
134     ......
135 }
136 
137 void CFyToolTip::HideTips()
138 {
139     if (IsWindow(m_hWnd))
140     {
141         ShowWindow(SW_HIDE);
142     }
143 }
144 
145 
146 void CFyToolTip::SetBkColor(COLORREF clrBack)
147 {
148     m_clrBack = clrBack;
149 }
150 
151 void CFyToolTip::SetFrameColor(COLORREF clrFrame)
152 {
153     m_clrFrameColor = clrFrame;
154 }
155 
156 void CFyToolTip::SetTipTextColor(COLORREF clrText)
157 {
158     m_clrText = clrText;
159 }
160 .....

 

本文完整了实现了上图展示的3中透明信息提示框,可以满足绝大多数对透明窗口信息提示框的功能要求。如果在某些特性场景下,还需要支持FyTipTool提示框支持鼠标 点击、移动等事件,可以继续扩展。需增加以下事件支持:

	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseLeave();

 

四、CFyToolTip使用示例

 1 //1声明变量,Y轴上左Tip
 2 CFyToolTip* m_y1ToolTip;        
 3 
 4 
 5 //2构造变量,透明度200/255
 6 m_y1ToolTip = new CFyToolTip();
 7 m_y1ToolTip->Create(this, 200);
 8 
 9 
10 //3显示、隐藏提示框
11 if (GetPointInArea(point))
12 {
13     CString syTip = GetYToolTip(point);
14     int y1Right;
15     GetYAxesTipXPos(virpoint, y1Right, y2Left);
16     if (y1Right > 0)
17     {
18         CPoint tmpPt(y1Right, point.y);
19         ClientToScreen(&tmpPt);
20         m_y1ToolTip->ShowY1Tips(tmpPt.x, tmpPt.y, syTip);
21     }
22 }
23 else
24 {
25     m_y1ToolTip->HideTips();
26 }

 


posted @ 2023-07-09 10:21  浮云绘图  阅读(11)  评论(0编辑  收藏  举报