windows-nt/Source/XPSP1/NT/shell/ext/logondui/eballoon.cpp
2020-09-26 16:20:57 +08:00

198 lines
4.9 KiB
C++

#include "priv.h"
#include <commctrl.h>
#include "EBalloon.h"
#undef ASSERT
#define ASSERT(x)
BOOL g_bMirroredOS = false;
CErrorBalloon::CErrorBalloon()
{
// our allocation function should have zeroed our memory. Check to make sure:
ASSERT(0==m_hwndToolTip);
ASSERT(0==m_uTimerID);
g_bMirroredOS = IS_MIRRORING_ENABLED();
}
CErrorBalloon::~CErrorBalloon()
{
}
LRESULT CALLBACK CErrorBalloon::SubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uID, ULONG_PTR dwRefData)
{
UNREFERENCED_PARAMETER(uID);
CErrorBalloon * pthis = (CErrorBalloon*)dwRefData;
switch (uMsg)
{
// Do not autodismiss until after markup has had a chance to
// parse the WM_LBUTTONUP to see if it's a link click or not
case WM_LBUTTONUP:
DefSubclassProc(hwnd, uMsg, wParam, lParam);
pthis->HideToolTip();
return 0;
case WM_TIMER:
if (wParam == ERRORBALLOONTIMERID)
{
pthis->HideToolTip();
return 0;
}
break;
default:
break;
}
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}
void CErrorBalloon::ShowToolTip(HINSTANCE hInstance, HWND hwndTarget, const POINT *ppt, LPTSTR pszMessage, LPTSTR pszTitle, DWORD dwIconIndex, DWORD dwFlags, int iTimeout)
{
hinst = hInstance;
if (m_hwndToolTip)
{
HideToolTip();
}
m_hwndTarget = hwndTarget;
m_dwIconIndex = dwIconIndex;
if ( !m_hwndToolTip )
{
CreateToolTipWindow();
}
int x, y;
x = ppt->x;
y = ppt->y;
SendMessage(m_hwndToolTip, TTM_TRACKPOSITION, 0, MAKELONG(x,y));
if (pszTitle)
{
SendMessage(m_hwndToolTip, TTM_SETTITLE, (WPARAM)dwIconIndex, (LPARAM)pszTitle);
}
TOOLINFO ti = {0};
ti.cbSize = TTTOOLINFOW_V2_SIZE;
ti.hwnd = m_hwndTarget;
ti.uId = 1;
SendMessage(m_hwndToolTip, TTM_GETTOOLINFO, 0, (LPARAM)&ti);
ti.uFlags &= ~TTF_PARSELINKS;
if (dwFlags & EB_MARKUP)
{
ti.uFlags |= TTF_PARSELINKS;
}
ti.lpszText = pszMessage;
SendMessage(m_hwndToolTip, TTM_SETTOOLINFO, 0, (LPARAM)&ti);
// Show the tooltip
SendMessage(m_hwndToolTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&ti);
// Set a timer to hide the tooltip
if ( m_uTimerID )
{
KillTimer(NULL,ERRORBALLOONTIMERID);
}
m_uTimerID = SetTimer(m_hwndToolTip, ERRORBALLOONTIMERID, iTimeout, NULL);
SetWindowSubclass(m_hwndToolTip, CErrorBalloon::SubclassProc, (UINT_PTR)this, (LONG_PTR)this);
}
void CErrorBalloon::ShowToolTip(HINSTANCE hInstance, HWND hwndTarget, LPTSTR pszMessage, LPTSTR pszTitle, DWORD dwIconIndex, DWORD dwFlags, int iTimeout)
{
// Set the tooltip display point
RECT rc;
GetWindowRect(hwndTarget, &rc);
POINT pt;
pt.x = (rc.left+rc.right)/2;
if ( EB_WARNINGABOVE & dwFlags )
{
pt.y = rc.top;
}
else if ( EB_WARNINGCENTERED & dwFlags )
{
pt.y = (rc.top+rc.bottom)/2;
}
else
{
pt.y = rc.bottom;
}
ShowToolTip(hInstance, hwndTarget, &pt, pszMessage, pszTitle, dwIconIndex, dwFlags, iTimeout);
}
// CreateToolTipWindow
//
// Creates our tooltip control. We share this one tooltip control and use it for all invalid
// input messages. The control is hiden when not in use and then shown when needed.
//
void CErrorBalloon::CreateToolTipWindow()
{
DWORD dwExStyle = 0;
if (IS_BIDI_LOCALIZED_SYSTEM())
dwExStyle |= WS_EX_LAYOUTRTL;
m_hwndToolTip = CreateWindowEx(
dwExStyle,
TOOLTIPS_CLASS,
NULL,
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP | TTS_BALLOON,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
m_hwndTarget,
NULL,
GetModuleHandle(NULL),
NULL);
if (m_hwndToolTip)
{
TOOLINFO ti = {0};
ti.cbSize = TTTOOLINFOW_V2_SIZE;
ti.uFlags = TTF_TRACK;
ti.hwnd = m_hwndTarget;
ti.uId = 1;
ti.hinst = hinst;
ti.lpszText = NULL;
// set the version so we can have non buggy mouse event forwarding
SendMessage(m_hwndToolTip, CCM_SETVERSION, COMCTL32_VERSION, 0);
SendMessage(m_hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
SendMessage(m_hwndToolTip, TTM_SETMAXTIPWIDTH, 0, 300);
}
else
{
// failed to create tool tip window, now what should we do? Unsubclass ourselves?
}
}
void CErrorBalloon::HideToolTip()
{
// When the timer fires we hide the tooltip window
if ( m_uTimerID )
{
KillTimer(m_hwndTarget,ERRORBALLOONTIMERID);
m_uTimerID = 0;
}
if ( m_hwndToolTip )
{
HWND hwndTip = m_hwndToolTip;
m_hwndToolTip = NULL;
SendMessage(hwndTip, TTM_TRACKACTIVATE, FALSE, 0);
DestroyWindow(hwndTip);
}
}