TA的每日心情 | 衰 3 天前 |
---|
签到天数: 301 天 [LV.8]以坛为家I
论坛元老
- 积分
- 5131
|
首先我们先定义个展示tooltip的xml
- <?xml version="1.0"?>
- <SOUI name="tip" title="tip" width="-1" height="-1" resizable="0" wndType="normal" toolwindow="1" translucent="1">
- <root size="-1,-1" colorBkgnd="#212629f0" class="style_tip" padding="10,10,10,10" layout="vbox">
- <text name="txt_tip" colorText="#FFFFFFb0" font="face:微软雅黑,size:12" maxWidth="300" multiLines="1"/>
- </root>
- </SOUI>
复制代码 其中txt_tip就是用来展示tip内容的。我们可以在此处指定tooltip的展示样式。
在uires中关联一下这个xml
- <LAYOUT>
- <file name="XML_TOOLTIP" path="xml\tooltip.xml"/>
- </LAYOUT>
复制代码 然后我们实现一个tooltip类
- //头文件CToolTipEx.h
- #pragma once
- class CToolTipEx : public IToolTip
- , public IMsgFilter
- , public SHostWnd
- {
- public:
- CToolTipEx(void);
- virtual ~CToolTipEx(void);
- BOOL CreateWnd();
- HWND Hwnd();
- public://IToolTip
- STDMETHOD_(BOOL, Create)(THIS) OVERRIDE;
- STDMETHOD_(BOOL, Destroy)(THIS) OVERRIDE;
- STDMETHOD_(BOOL, PreTranslateMessage)(THIS_ MSG* pMsg) OVERRIDE;
- STDMETHOD_(void, UpdateTip)(THIS_ const TIPID* id, RECT rc, LPCTSTR pszTip, int nScale) OVERRIDE;
- STDMETHOD_(void, SetToolTip)(THIS_ LPCRECT rc, UINT tipAlign, LPCTSTR pszTip, int nScale) OVERRIDE;
- STDMETHOD_(void, ClearTip)(THIS) OVERRIDE;
- STDMETHOD_(void, RelayEvent)(THIS_ const MSG* pMsg) OVERRIDE;
- STDMETHOD_(long, AddRef)(THIS) OVERRIDE {
- return SNativeWnd::AddRef();
- }
- STDMETHOD_(long, Release)(THIS) OVERRIDE {
- return SNativeWnd::Release();
- }
- STDMETHOD_(void, OnFinalRelease)(THIS) OVERRIDE {
- delete this;
- }
- STDMETHOD_(IMsgFilter*, GetMsgFilter)(THIS) OVERRIDE {
- return this;
- }
-
- //要重写这两个接口,不然内部自己建立时会不停建立tip。会导致死循环
- virtual IToolTip* CreateTooltip() const { return NULL; }
- virtual void DestroyTooltip(IToolTip* pTooltip) {}
- protected:
- int OnCreate(LPCREATESTRUCT lpCreateStruct);
- BOOL OnInitDialog(HWND wndFocus, LPARAM lInitParam);
- void OnTimer(UINT_PTR idEvent);
- BEGIN_MSG_MAP_EX(CToolTipEx)
- MSG_WM_CREATE(OnCreate)
- MSG_WM_INITDIALOG(OnInitDialog)
- MSG_WM_TIMER(OnTimer)
- CHAIN_MSG_MAP(SHostWnd)
- REFLECT_NOTIFICATIONS_EX()
- END_MSG_MAP()
- void ShowTip(BOOL bShow);
- private:
- HWND m_hWnd;
- DWORD m_Tick;
- int m_nDelay;
- int m_nShowSpan;
- SStringT m_strTip;
- int m_nScale;
- CRect m_rcTarget;
- SStatic* m_txtTip;
- TIPID m_id;
- bool m_bShow;
- };
- //源文件CToolTipEx.cpp
- #include "stdafx.h"
- #include "CToolTipEx.h"
- #define TIMERID_DELAY2 1
- #define TIMERID_SPAN2 2
- #define MARGIN_TIP2 5
- CToolTipEx::CToolTipEx(void) : SHostWnd(_T("LAYOUT:XML_TOOLTIP"))
- , m_nDelay(50)
- , m_nShowSpan(5000)
- , m_Tick(0)
- {
- m_id.dwHi = m_id.dwLow = 0;
- m_bShow = false;
- }
- CToolTipEx::~CToolTipEx(void)
- {
- }
- BOOL CToolTipEx::CreateWnd()
- {
- m_hWnd = SHostWnd::Create(::GetActiveWindow(), 0, 0, 0, 0);
- SendMessage(WM_INITDIALOG);
- return TRUE;
- }
- HWND CToolTipEx::Hwnd()
- {
- return m_hWnd;
- }
- BOOL CToolTipEx::Create()
- {
- CreateWnd();
- return TRUE;
- }
- BOOL CToolTipEx::Destroy()
- {
- return TRUE;
- }
- BOOL CToolTipEx::PreTranslateMessage(MSG* pMsg)
- {
- if (IsWindow())
- RelayEvent(pMsg);
- return FALSE;
- }
- void CToolTipEx::UpdateTip(const TIPID* id, RECT rc, LPCTSTR pszTip, int nScale)
- {
- if (m_id.dwHi == id->dwHi && m_id.dwLow == id->dwLow) return;
- m_id = *id;
- m_rcTarget = rc;
- m_strTip = pszTip;
- m_strTip.Replace(_T("\\n"), _T("\n"));
- if (IsWindowVisible())
- ShowTip(TRUE);
- }
- void CToolTipEx::SetToolTip(LPCRECT rc, UINT tipAlign, LPCTSTR pszTip, int nScale)
- {
- }
- void CToolTipEx::ClearTip()
- {
- m_id.dwHi = m_id.dwLow = 0;
- ShowTip(FALSE);
- }
- void CToolTipEx::RelayEvent(const MSG* pMsg)
- {
- switch (pMsg->message)
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_MBUTTONDOWN:
- OnTimer(TIMERID_SPAN2);//hide tip
- break;
- case WM_MOUSEMOVE:
- {
- CPoint pt(GET_X_LPARAM(pMsg->lParam), GET_Y_LPARAM(pMsg->lParam));
- if (!m_rcTarget.PtInRect(pt))
- {
- OnTimer(TIMERID_SPAN2);//hide tip
- }
- else if (/*!IsWindowVisible() &&*/ !m_strTip.IsEmpty())
- {
- DWORD t = ::GetTickCount();
- if ((t - m_Tick) > DWORD(m_nDelay))
- {
- KillTimer(TIMERID_DELAY2);
- SetTimer(TIMERID_DELAY2, m_nDelay);
- m_Tick = t;
- }
- ::ClientToScreen(pMsg->hwnd, &pt);
- SetWindowPos(0, pt.x, pt.y + 18, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_NOACTIVATE);
- }
- }
- break;
- default:
- break;
- }
- }
- int CToolTipEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- SHostWnd::OnCreate(lpCreateStruct);
- return 0;
- }
- BOOL CToolTipEx::OnInitDialog(HWND wndFocus, LPARAM lInitParam)
- {
- m_txtTip = FindChildByName2<SStatic>(L"txt_tip");
- return TRUE;
- }
- void CToolTipEx::OnTimer(UINT_PTR idEvent)
- {
- SetMsgHandled(FALSE);
- switch (idEvent)
- {
- case TIMERID_DELAY2:
- {
- if (!m_bShow)
- {
- KillTimer(TIMERID_DELAY2);
- ShowTip(TRUE);
- m_bShow = true;
- }
- SetTimer(TIMERID_SPAN2, m_nShowSpan);
- }
- break;
- case TIMERID_SPAN2:
- {
- ShowTip(FALSE);
- KillTimer(TIMERID_SPAN2);
- m_bShow = false;
- }
- break;
- }
- }
- void CToolTipEx::ShowTip(BOOL bShow)
- {
- if (!bShow)
- {
- ShowWindow(SW_HIDE);
- m_rcTarget.SetRect(0, 0, 0, 0);
- m_strTip = _T("");
- }
- else if (!m_strTip.IsEmpty())
- {
- ShowWindow(SW_SHOW);
- m_txtTip->SetWindowText(m_strTip);
- }
- }
复制代码 控件使用:
我们需要在cpp中实现一个SToolTipFactory,然后将SToolTipFactory注册到App中。
- #include "CToolTipEx.h"
- class SToolTipFactory : public TObjRefImpl<IToolTipFactory>
- {
- public:
- IToolTip* CreateToolTip(HWND hHost)
- {
- CToolTipEx* pTipCtrl = new CToolTipEx;
- if (!pTipCtrl->CreateWnd())
- {
- delete pTipCtrl;
- return NULL;
- }
- return pTipCtrl;
- }
- void DestroyToolTip(IToolTip* pToolTip)
- {
- if (pToolTip)
- {
- CToolTipEx* pTipCtrl = (CToolTipEx*)pToolTip;
- pTipCtrl->DestroyWindow();
- }
- }
- };
- //注册
- //注册用户自定义皮肤和控件
- void Regitercustom()
- {
- m_theApp->SetToolTipFactory(new SToolTipFactory);
- }
复制代码 效果如下:
代码地址:
https://github.com/JeanPenty/ToolTipExDemo
ToolTipExDemo-main.zip
(33.81 KB, 下载次数: 0)
|
|