https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4ee54e25194dfc73c1780e97d9efeebe0806fcc2

commit 4ee54e25194dfc73c1780e97d9efeebe0806fcc2
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Mon Jan 8 16:44:38 2024 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Mon Jan 8 16:44:38 2024 +0900

    [SDK] cicuif.h: Add CUIFToolTip (#6317)
    
    Supporting TIPs...
    JIRA issue: CORE-19360
    - Half-implement CUIFToolTip.
    - Strengthen some classes.
---
 sdk/include/reactos/cicero/cicuif.h | 482 +++++++++++++++++++++++++++++++++---
 1 file changed, 452 insertions(+), 30 deletions(-)

diff --git a/sdk/include/reactos/cicero/cicuif.h 
b/sdk/include/reactos/cicero/cicuif.h
index 6e41ff1ca8e..637f699325e 100644
--- a/sdk/include/reactos/cicero/cicuif.h
+++ b/sdk/include/reactos/cicero/cicuif.h
@@ -71,7 +71,7 @@ struct CUIFTheme
 {
     LPCWSTR m_pszClassList;
     INT m_iPartId;
-    DWORD m_dwUnknown2; //FIXME: name and type
+    INT m_iStateId;
     HTHEME m_hTheme;
     static HINSTANCE s_hUXTHEME;
     static FN_OpenThemeData s_fnOpenThemeData;
@@ -109,7 +109,7 @@ struct CUIFTheme
     STDMETHOD(GetThemeFont)(HDC hDC, int iStateId, int iPropId, LOGFONTW 
*pFont);
     STDMETHOD_(COLORREF, GetThemeSysColor)(INT iColorId);
     STDMETHOD_(int, GetThemeSysSize)(int iSizeId);
-    STDMETHOD_(void, SetActiveTheme)(LPCWSTR pszClassList, INT iPartId, DWORD 
dwUnknown2);
+    STDMETHOD_(void, SetActiveTheme)(LPCWSTR pszClassList, INT iPartId, INT 
iStateId);
 };
 
 // static members
@@ -206,6 +206,7 @@ protected:
     LPWSTR m_pszToolTip;
     DWORD m_dwUnknown4[2]; //FIXME: name and type
     friend class CUIFWindow;
+    friend class CUIFToolTip;
 
 public:
     CUIFObject(CUIFObject *pParent, DWORD dwUnknown3, LPRECT prc, DWORD style);
@@ -221,7 +222,7 @@ public:
 
     STDMETHOD_(void, Initialize)();
     STDMETHOD_(void, OnPaint)(HDC hDC);
-    STDMETHOD_(void, OnUnknnown9)() { } // FIXME: name
+    STDMETHOD_(void, OnUnknown9)() { } // FIXME: name
     STDMETHOD_(void, OnLButtonDown)(LONG x, LONG y) { }
     STDMETHOD_(void, OnMButtonDown)(LONG x, LONG y) { }
     STDMETHOD_(void, OnRButtonDown)(LONG x, LONG y) { }
@@ -397,9 +398,10 @@ protected:
     CUIFToolTip *m_pToolTip;
     CUIFShadow *m_pShadow;
     BOOL m_bShowShadow;
-    CUIFWindow *m_pShadowOwner;
+    CUIFWindow *m_pShadowOrToolTipOwner;
     friend class CUIFObject;
     friend class CUIFShadow;
+    friend class CUIFToolTip;
 
 public:
     CUIFWindow(HINSTANCE hInst, DWORD style);
@@ -468,7 +470,44 @@ public:
 
 class CUIFToolTip : public CUIFWindow
 {
-    //FIXME
+protected:
+    CUIFObject *m_pToolTipTarget;
+    LPWSTR m_pszToolTipText;
+    BOOL m_bShowToolTip;
+    DWORD m_dwUnknown10; //FIXME: name and type
+    LONG m_nDelayTimeType2;
+    LONG m_nDelayTimeType3;
+    LONG m_nDelayTimeType1;
+    RECT m_rcToolTipMargin;
+    LONG m_cxToolTipWidth;
+    BOOL m_bToolTipHasBkColor;
+    BOOL m_bToolTipHasTextColor;
+    COLORREF m_rgbToolTipBkColor;
+    COLORREF m_rgbToolTipTextColor;
+    friend class CUIFObject;
+
+public:
+    enum { TOOLTIP_TIMER_ID = 0x3216 };
+    CUIFToolTip(HINSTANCE hInst, DWORD style, CUIFWindow *pToolTipOwner);
+    ~CUIFToolTip() override;
+
+    LONG GetDelayTime(UINT uType);
+    void GetMargin(LPRECT prc);
+    COLORREF GetTipBkColor();
+    COLORREF GetTipTextColor();
+    CUIFObject* FindObject(HWND hWnd, POINT pt);
+
+    void ShowTip();
+    void HideTip();
+
+    void GetTipWindowSize(LPSIZE pSize);
+    void GetTipWindowRect(LPRECT pRect, SIZE toolTipSize, LPCRECT prc);
+
+    void RelayEvent(LPMSG pMsg);
+
+    STDMETHOD_(void, OnPaint)(HDC hDC) override;
+    STDMETHOD_(void, Enable)(BOOL bEnable) override;
+    STDMETHOD_(void, OnTimer)(WPARAM wParam) override;
 };
 
 class CUIFShadow : public CUIFWindow
@@ -718,10 +757,10 @@ CUIFTheme::GetThemeSysSize(int iSizeId)
 
 /// @unimplemented
 inline STDMETHODIMP_(void)
-CUIFTheme::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, DWORD dwUnknown2)
+CUIFTheme::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, INT iStateId)
 {
     m_iPartId = iPartId;
-    m_dwUnknown2 = dwUnknown2; //FIXME: name and type
+    m_iStateId = iStateId;
     m_pszClassList = pszClassList;
 }
 
@@ -770,7 +809,9 @@ CUIFObject::~CUIFObject()
 {
     if (m_pWindow)
     {
-        //FIXME
+        CUIFToolTip *pToolTip = m_pWindow->m_pToolTip;
+        if (pToolTip && pToolTip->m_pToolTipTarget == this)
+            pToolTip->m_pToolTipTarget = NULL;
     }
 
     if (m_pszToolTip)
@@ -925,7 +966,7 @@ inline STDMETHODIMP_(void) CUIFObject::SetToolTip(LPCWSTR 
pszToolTip)
         size_t cch = wcslen(pszToolTip);
         m_pszToolTip = new(cicNoThrow) WCHAR[cch + 1];
         if (m_pszToolTip)
-            wcscpy(m_pszToolTip, pszToolTip);
+            lstrcpynW(m_pszToolTip, pszToolTip, cch + 1);
     }
 }
 
@@ -994,16 +1035,14 @@ inline LRESULT CUIFObject::NotifyCommand(WPARAM wParam, 
LPARAM lParam)
     return 0;
 }
 
-/// @unimplemented
 inline void CUIFObject::DetachWndObj()
 {
     if (m_pWindow)
     {
         CUIFToolTip *pToolTip = m_pWindow->m_pToolTip;
-        if (pToolTip)
-        {
-            //FIXME
-        }
+        if (pToolTip && pToolTip->m_pToolTipTarget == this)
+            pToolTip->m_pToolTipTarget = NULL;
+
         m_pWindow->RemoveUIObj(this);
         m_pWindow = NULL;
     }
@@ -1487,7 +1526,6 @@ inline CUIFWindow::~CUIFWindow()
     }
 }
 
-/// @unimplemented
 inline STDMETHODIMP_(void)
 CUIFWindow::Initialize()
 {
@@ -1519,11 +1557,17 @@ CUIFWindow::Initialize()
 
     if (m_style & UIF_STYLE_TOOLTIP)
     {
-        //FIXME: Create m_pToolTip
+        DWORD style = (m_style & UIF_STYLE_RTL) | UIF_STYLE_TOPMOST | 0x10;
+        m_pToolTip = new(cicNoThrow) CUIFToolTip(m_hInst, style, this);
+        if (m_pToolTip)
+            m_pToolTip->Initialize();
     }
+
     if (m_style & UIF_STYLE_SHADOW)
     {
-        //FIXME: Create m_pShadow
+        m_pShadow = new(cicNoThrow) CUIFShadow(m_hInst, UIF_STYLE_TOPMOST, 
this);
+        if (m_pShadow)
+            m_pShadow->Initialize();
     }
 
     return CUIFObject::Initialize();
@@ -1935,14 +1979,14 @@ CUIFWindow::WindowProc(HWND hWnd, UINT uMsg, WPARAM 
wParam, LPARAM lParam)
                 m_pShadow->Show(FALSE);
             if (!(pwp->flags & SWP_NOZORDER) && pwp->hwndInsertAfter == 
m_pShadow->m_hWnd)
                 pwp->flags |= SWP_NOZORDER;
-            //m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE)); //FIXME
+            m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE));
             return OnWindowPosChanging(hWnd, WM_WINDOWPOSCHANGING, wParam, 
lParam);
         }
         case WM_WINDOWPOSCHANGED:
         {
-            //WINDOWPOS *pwp = (WINDOWPOS *)lParam;
-            //if (m_pShadow) //FIXME
-            //    m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE));
+            WINDOWPOS *pwp = (WINDOWPOS *)lParam;
+            if (m_pShadow)
+                m_pShadow->OnOwnerWndMoved(!(pwp->flags & SWP_NOSIZE));
             return OnWindowPosChanged(hWnd, WM_WINDOWPOSCHANGED, wParam, 
lParam);
         }
         case WM_NOTIFY:
@@ -2052,11 +2096,27 @@ CUIFWindow::GetWorkArea(LPCRECT prcWnd, LPRECT 
prcWorkArea)
     return FALSE;
 }
 
-/// @unimplemented
 inline void
 CUIFWindow::AdjustWindowPosition()
 {
-    //FIXME
+    RECT rc;
+    rc.left = m_nLeft;
+    rc.right = m_nLeft + m_nWidth;
+    rc.top = m_nTop;
+    rc.bottom = m_nTop + m_nHeight;
+
+    RECT rcWorkArea;
+    if (!GetWorkArea(&rc, &rcWorkArea))
+        return;
+
+    if (m_nLeft < rcWorkArea.left)
+        m_nLeft = rcWorkArea.left;
+    if (m_nTop < rcWorkArea.top)
+        m_nTop = rcWorkArea.top;
+    if (m_nLeft + m_nWidth >= rcWorkArea.right)
+        m_nLeft = rcWorkArea.right - m_nWidth;
+    if (m_nTop + m_nHeight >= rcWorkArea.bottom)
+        m_nTop = rcWorkArea.bottom - m_nHeight;
 }
 
 /// @unimplemented
@@ -2087,9 +2147,9 @@ CUIFWindow::PaintObject(HDC hDC, LPCRECT prc)
         ::SetViewportOrgEx(hMemDC, -pRect->left, -pRect->top, NULL);
 
         if ((FAILED(CUIFTheme::EnsureThemeData(m_hWnd)) ||
-             !(m_style & 1) ||
+             !(m_style & UIF_STYLE_CHILD) ||
              FAILED(DrawThemeParentBackground(m_hWnd, hMemDC, &m_rc))) &&
-            FAILED(DrawThemeBackground(hMemDC, m_dwUnknown2, &m_rc, 0)))
+            FAILED(DrawThemeBackground(hMemDC, m_iStateId, &m_rc, 0)))
         {
             //if (m_pScheme)
             //    m_pScheme->FillRect(hMemDC, pRect, 22); //FIXME
@@ -2297,7 +2357,7 @@ CUIFWindow::OnAnimationStart()
 inline CUIFShadow::CUIFShadow(HINSTANCE hInst, DWORD style, CUIFWindow 
*pShadowOwner)
     : CUIFWindow(hInst, (style | UIF_STYLE_TOOLWINDOW))
 {
-    m_pShadowOwner = pShadowOwner;
+    m_pShadowOrToolTipOwner = pShadowOwner;
     m_rgbShadowColor = RGB(0, 0, 0);
     m_dwUnknown11[0] = 0;
     m_dwUnknown11[1] = 0;
@@ -2307,8 +2367,8 @@ inline CUIFShadow::CUIFShadow(HINSTANCE hInst, DWORD 
style, CUIFWindow *pShadowO
 
 inline CUIFShadow::~CUIFShadow()
 {
-    if (m_pShadowOwner)
-        m_pShadowOwner->m_pShadow = NULL;
+    if (m_pShadowOrToolTipOwner)
+        m_pShadowOrToolTipOwner->m_pShadow = NULL;
 }
 
 /// @unimplemented
@@ -2330,7 +2390,7 @@ inline void CUIFShadow::InitShadow()
 
 inline void CUIFShadow::AdjustWindowPos()
 {
-    HWND hwndOwner = m_pShadowOwner->m_hWnd;
+    HWND hwndOwner = m_pShadowOrToolTipOwner->m_hWnd;
     if (!::IsWindow(m_hWnd))
         return;
 
@@ -2383,7 +2443,7 @@ inline STDMETHODIMP_(LRESULT)
 CUIFShadow::OnWindowPosChanging(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM 
lParam)
 {
     WINDOWPOS *wp = (WINDOWPOS *)lParam;
-    wp->hwndInsertAfter = m_pShadowOwner->m_hWnd;
+    wp->hwndInsertAfter = m_pShadowOrToolTipOwner->m_hWnd;
     return ::DefWindowProc(hWnd, Msg, wParam, lParam);
 }
 
@@ -2421,3 +2481,365 @@ CUIFShadow::Show(BOOL bVisible)
         ::ShowWindow(m_hWnd, (bVisible ? SW_SHOWNOACTIVATE : SW_HIDE));
     }
 }
+
+/////////////////////////////////////////////////////////////////////////////
+
+inline
+CUIFToolTip::CUIFToolTip(HINSTANCE hInst, DWORD style, CUIFWindow 
*pToolTipOwner)
+    : CUIFWindow(hInst, style)
+{
+    m_pShadowOrToolTipOwner = pToolTipOwner;
+    m_rcToolTipMargin.left = 2;
+    m_rcToolTipMargin.top = 2;
+    m_rcToolTipMargin.right = 2;
+    m_rcToolTipMargin.bottom = 2;
+    m_pToolTipTarget = NULL;
+    m_pszToolTipText = NULL;
+    m_dwUnknown10 = 0; //FIXME: name and type
+    m_nDelayTimeType2 = -1;
+    m_nDelayTimeType3 = -1;
+    m_nDelayTimeType1 = -1;
+    m_cxToolTipWidth = -1;
+    m_bToolTipHasBkColor = 0;
+    m_bToolTipHasTextColor = 0;
+    m_rgbToolTipBkColor = 0;
+    m_rgbToolTipTextColor = 0;
+}
+
+inline
+CUIFToolTip::~CUIFToolTip()
+{
+    if (m_pShadowOrToolTipOwner)
+        m_pShadowOrToolTipOwner->m_pToolTip = NULL;
+    if (m_pszToolTipText)
+        delete[] m_pszToolTipText;
+}
+
+inline LONG
+CUIFToolTip::GetDelayTime(UINT uType)
+{
+    LONG nDelayTime;
+    switch (uType)
+    {
+        case 1:
+        {
+            nDelayTime = m_nDelayTimeType1;
+            if (nDelayTime == -1)
+                return ::GetDoubleClickTime() / 5;
+            return nDelayTime;
+        }
+        case 2:
+        {
+            nDelayTime = m_nDelayTimeType2;
+            if (nDelayTime == -1)
+                return 10 * ::GetDoubleClickTime();
+            return nDelayTime;
+        }
+        case 3:
+        {
+            nDelayTime = m_nDelayTimeType3;
+            if (nDelayTime == -1)
+                return ::GetDoubleClickTime();
+            return nDelayTime;
+        }
+    }
+}
+
+inline void CUIFToolTip::GetMargin(LPRECT prc)
+{
+    if (prc)
+        *prc = m_rcToolTipMargin;
+}
+
+inline COLORREF
+CUIFToolTip::GetTipBkColor()
+{
+    if (m_bToolTipHasBkColor)
+        return m_rgbToolTipBkColor;
+    return ::GetSysColor(COLOR_INFOBK);
+}
+
+inline COLORREF
+CUIFToolTip::GetTipTextColor()
+{
+    if (m_bToolTipHasTextColor)
+        return m_rgbToolTipTextColor;
+    return ::GetSysColor(COLOR_INFOTEXT);
+}
+
+inline CUIFObject*
+CUIFToolTip::FindObject(HWND hWnd, POINT pt)
+{
+    if (hWnd == m_pShadowOrToolTipOwner->m_hWnd)
+        return m_pShadowOrToolTipOwner->ObjectFromPoint(pt);
+    return NULL;
+}
+
+/// @unimplemented
+inline void
+CUIFToolTip::ShowTip()
+{
+    ::KillTimer(m_hWnd, TOOLTIP_TIMER_ID);
+
+    if (!m_pToolTipTarget)
+        return;
+
+    LPCWSTR pszText = m_pToolTipTarget->GetToolTip();
+    if (!pszText)
+        return;
+
+    if (!m_pToolTipTarget || m_pToolTipTarget->OnShowToolTip())
+        return;
+
+    POINT Point;
+    ::GetCursorPos(&Point);
+    ::ScreenToClient(m_pToolTipTarget->m_pWindow->m_hWnd, &Point);
+
+    RECT rc;
+    m_pToolTipTarget->GetRect(&rc);
+    if (!::PtInRect(&rc, Point))
+        return;
+
+    size_t cchText = wcslen(pszText);
+    m_pszToolTipText = new(cicNoThrow) WCHAR[cchText + 1];
+    if (!m_pszToolTipText)
+        return;
+
+    lstrcpynW(m_pszToolTipText, pszText, cchText + 1);
+
+    SIZE size;
+    GetTipWindowSize(&size);
+
+    RECT rc2 = rc;
+    ::ClientToScreen(m_pToolTipTarget->m_pWindow->m_hWnd, (LPPOINT)&rc);
+    ::ClientToScreen(m_pToolTipTarget->m_pWindow->m_hWnd, (LPPOINT)&rc.right);
+    GetTipWindowRect(&rc2, size, &rc);
+
+    m_bShowToolTip = TRUE;
+    Move(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
+    Show(TRUE);
+}
+
+inline void
+CUIFToolTip::HideTip()
+{
+    ::KillTimer(m_hWnd, TOOLTIP_TIMER_ID);
+    m_bShowToolTip = FALSE;
+
+    if (m_pToolTipTarget)
+        m_pToolTipTarget->OnHideToolTip();
+
+    if (m_bVisible)
+    {
+        if (m_pszToolTipText)
+        {
+            delete[] m_pszToolTipText;
+            m_pszToolTipText = NULL;
+        }
+        Show(FALSE);
+    }
+}
+
+inline void
+CUIFToolTip::GetTipWindowSize(LPSIZE pSize)
+{
+    if (!m_pszToolTipText)
+        return;
+
+    HDC hDC = ::GetDC(m_hWnd);
+    HGDIOBJ hFontOld = ::SelectObject(hDC, m_hFont);
+
+    RECT rcText = { 0, 0, 0, 0 };
+    INT cyText;
+    if (m_cxToolTipWidth <= 0)
+    {
+        cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | 
DT_SINGLELINE);
+    }
+    else
+    {
+        rcText.right = m_cxToolTipWidth;
+        cyText = ::DrawTextW(hDC, m_pszToolTipText, -1, &rcText, DT_CALCRECT | 
DT_WORDBREAK);
+    }
+
+    RECT rcMargin;
+    GetMargin(&rcMargin);
+
+    RECT rc;
+    rc.left     = rcText.left - rcMargin.left;
+    rc.top      = rcText.top - rcMargin.top;
+    rc.right    = rcText.right + rcMargin.right;
+    rc.bottom   = rcText.top + cyText + rcMargin.bottom;
+    ClientRectToWindowRect(&rc);
+
+    pSize->cx = rc.right - rc.left;
+    pSize->cy = rc.bottom - rc.top;
+
+    ::SelectObject(hDC, hFontOld);
+    ::ReleaseDC(m_hWnd, hDC);
+}
+
+inline void
+CUIFToolTip::GetTipWindowRect(LPRECT pRect, SIZE toolTipSize, LPCRECT prc)
+{
+    POINT Point;
+    GetCursorPos(&Point);
+
+    HCURSOR hCursor = ::GetCursor();
+    ICONINFO IconInfo;
+    INT yHotspot = 0;
+    INT cyCursor = ::GetSystemMetrics(SM_CYCURSOR);
+    if (hCursor && ::GetIconInfo(hCursor, &IconInfo))
+    {
+        BITMAP bm;
+        ::GetObject(IconInfo.hbmMask, sizeof(bm), &bm);
+        if (!IconInfo.fIcon)
+        {
+            cyCursor = bm.bmHeight;
+            yHotspot = IconInfo.yHotspot;
+            if (!IconInfo.hbmColor)
+                cyCursor = bm.bmHeight / 2;
+        }
+        if (IconInfo.hbmColor)
+            ::DeleteObject(IconInfo.hbmColor);
+        if (IconInfo.hbmMask)
+            ::DeleteObject(IconInfo.hbmMask);
+    }
+
+    RECT rcMonitor;
+    rcMonitor.left = 0;
+    rcMonitor.top = 0;
+    rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
+    rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
+
+    HMONITOR hMon = ::MonitorFromPoint(Point, MONITOR_DEFAULTTONEAREST);
+    MONITORINFO mi;
+    if (hMon)
+    {
+        mi.cbSize = sizeof(MONITORINFO);
+        if (::GetMonitorInfo(hMon, &mi))
+            rcMonitor = mi.rcMonitor;
+    }
+
+    pRect->left   = Point.x;
+    pRect->right  = pRect->left + toolTipSize.cx;
+    pRect->top    = Point.y + cyCursor - yHotspot;
+    pRect->bottom = pRect->top + toolTipSize.cy;
+
+    if (rcMonitor.right < pRect->right)
+    {
+        pRect->left = rcMonitor.right - toolTipSize.cx;
+        pRect->right = rcMonitor.right;
+    }
+    if (pRect->left < rcMonitor.left)
+    {
+        pRect->left = rcMonitor.left;
+        pRect->right = rcMonitor.left + toolTipSize.cx;
+    }
+    if (rcMonitor.bottom < pRect->bottom)
+    {
+        pRect->top = rcMonitor.bottom - toolTipSize.cy;
+        pRect->bottom = rcMonitor.bottom;
+    }
+    if (pRect->top < rcMonitor.top)
+    {
+        pRect->top = rcMonitor.top;
+        pRect->bottom = rcMonitor.top + toolTipSize.cy;
+    }
+}
+
+inline void
+CUIFToolTip::RelayEvent(LPMSG pMsg)
+{
+    if (!pMsg)
+        return;
+
+    switch (pMsg->message)
+    {
+        case WM_MOUSEMOVE:
+        {
+            if (m_bEnable &&
+                ::GetKeyState(VK_LBUTTON) >= 0 &&
+                ::GetKeyState(VK_MBUTTON) >= 0 &&
+                ::GetKeyState(VK_RBUTTON) >= 0)
+            {
+                POINT pt = { (SHORT)LOWORD(pMsg->lParam), 
(SHORT)HIWORD(pMsg->lParam) };
+                CUIFObject *pFound = CUIFToolTip::FindObject(pMsg->hwnd, pt);
+                if (pFound)
+                {
+                    if (m_pToolTipTarget != pFound)
+                    {
+                        HideTip();
+
+                        LONG DelayTime;
+                        if (!m_bVisible)
+                            DelayTime = GetDelayTime(3);
+                        else
+                            DelayTime = GetDelayTime(1);
+                        ::SetTimer(m_hWnd, TOOLTIP_TIMER_ID, DelayTime, NULL);
+                    }
+                }
+                else
+                {
+                    HideTip();
+                }
+                m_pToolTipTarget = pFound;
+            }
+            break;
+        }
+        case WM_LBUTTONDOWN:
+        case WM_RBUTTONDOWN:
+        case WM_MBUTTONDOWN:
+        {
+            HideTip();
+            break;
+        }
+    }
+}
+
+inline STDMETHODIMP_(void) CUIFToolTip::OnPaint(HDC hDC)
+{
+    HGDIOBJ hFontOld = SelectObject(hDC, m_hFont);
+    INT iBkModeOld = SetBkMode(hDC, TRANSPARENT);
+
+    COLORREF rgbTextColor = GetTipTextColor();
+    COLORREF rgbOldTextColor = ::SetTextColor(hDC, rgbTextColor);
+
+    COLORREF rgbBkColor = GetTipBkColor();
+    HBRUSH hbrBack = ::CreateSolidBrush(rgbBkColor);
+    RECT rc = m_rc;
+    if (hbrBack)
+    {
+        ::FillRect(hDC, &rc, hbrBack);
+        ::DeleteObject(hbrBack);
+    }
+
+    RECT rcMargin;
+    GetMargin(&rcMargin);
+
+    rc.left += rcMargin.left;
+    rc.top += rcMargin.top;
+    rc.right -= rcMargin.right;
+    rc.bottom -= rcMargin.bottom;
+
+    if (m_cxToolTipWidth <= 0)
+        ::DrawTextW(hDC, m_pszToolTipText, -1, &rc, DT_SINGLELINE);
+    else
+        ::DrawTextW(hDC, m_pszToolTipText, -1, &rc, DT_WORDBREAK);
+
+    ::SetTextColor(hDC, rgbOldTextColor);
+    ::SetBkMode(hDC, iBkModeOld);
+    ::SelectObject(hDC, hFontOld);
+}
+
+inline STDMETHODIMP_(void) CUIFToolTip::Enable(BOOL bEnable)
+{
+    if (!bEnable)
+        HideTip();
+    CUIFObject::Enable(bEnable);
+}
+
+inline STDMETHODIMP_(void) CUIFToolTip::OnTimer(WPARAM wParam)
+{
+    if (wParam == TOOLTIP_TIMER_ID)
+        ShowTip();
+}

Reply via email to