📄 pptooltip.cpp
字号:
//
//--- History ------------------------------
// 2004/03/01 *** Releases version 2.0 ***
//------------------------------------------
// 2004/04/04 [ADD] Added method SetCssStyles(DWORD dwIdCssStyle, LPCTSTR lpszPathDll /* = NULL */)
// 2004/04/14 [FIX] Fixed correct drawing for some tooltip's directions
// 2004/04/15 [FIX] Fixed changing a z-order of the some windows by show a tooltip on Win9x
// 2004/04/27 [FIX] Corrected a work with a tooltip's directions with a large tooltip
// 2004/04/28 [ADD] Disables a message translation if object was't created (thanks to Stoil Todorov)
// 2004/07/02 [UPD] Changes a GetWndFromPoint mechanism of the window's searching
// 2004/09/01 [ADD] New SetMaxTipWidth method was added
// 2004/10/12 [FIX] Now a tooltip has a different methods to show a menu's tooltip and other
// control's tooltip
////////////////////////////////////////////////////////////////////
//
// "SmoothMaskImage" and "GetPartialSums" functions by Denis Sarazhinsky (c)2003
// Modified by Eugene Pustovoyt to use with image's mask instead of full color image.
//
/////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "PPTooltip.h"
// allow multi-monitor-aware code on Win95 systems
// comment out the first line if you already define it in another file
// comment out both lines if you don't care about Win95
#define COMPILE_MULTIMON_STUBS
//#include "multimon.h" //hpxs add 存在此行就会出现连接错误 多显示器编程的支持文件
//nafxcwd.lib(wincore.obj) : error LNK2005: _g_fMultiMonInitDone already defined in PPTooltip.obj
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define TIMER_HIDE 0x101 //the identifier of the timer for hide the tooltip
#define TIMER_SHOWING 0x102 //the identifier of the timer for tooltip's fade in
#define TIMER_SHOW 0x100 //the identifier of the timer for show the tooltip
#define TIMER_HIDING 0x103 //the identifier of the timer for tooltip's fade out
#define TIMER_ANIMATION 0x104 //the identifier of the timer for animation
#define PERCENT_STEP_FADEIN 20 //How mush percent will adding during fade in
#define PERCENT_STEP_FADEOUT 20 //How mush percent will adding during fade out
#define PERCENT_MAX_TRANSPARENCY 100 //How mush percent by maximum transparency
#define PERCENT_MIN_TRANSPARENCY 0 //How mush percent by minimum transparency
#define MAX_LENGTH_DEBUG_STRING 25 //
/*
struct PPTOOLTIP_ENUM_CHILD
{
HWND hwndExclude;
HWND hWnd;
POINT ptScreen;
DWORD dwFlags;
};
BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
PPTOOLTIP_ENUM_CHILD * structEnum = (PPTOOLTIP_ENUM_CHILD*)lParam;
if (hwndChild != structEnum->hwndExclude)
{
DWORD dwStyle = ::GetWindowLong(hwndChild, GWL_STYLE);
if (!(dwStyle & WS_VISIBLE))
return TRUE;
if (structEnum->dwFlags & CWP_SKIPDISABLED)
{
if (dwStyle & WS_DISABLED)
return TRUE;
}
if ((dwStyle & 0xF) != BS_GROUPBOX)
{
RECT rcWindow;// = wi.rcWindow;
::GetWindowRect(hwndChild, &rcWindow);
if ((rcWindow.left <= structEnum->ptScreen.x) &&
(rcWindow.right > structEnum->ptScreen.x) &&
(rcWindow.top <= structEnum->ptScreen.y) &&
(rcWindow.bottom > structEnum->ptScreen.y))
{
structEnum->hWnd = hwndChild;
return FALSE;
} //if
} //if
} //if
return TRUE;
} //End EnumChildProc
*/
//////////////////
// Note that windows are enumerated in top-down Z-order, so the menu
// window should always be the first one found.
//
static BOOL CALLBACK MyEnumProc(HWND hwnd, LPARAM lParam)
{
TCHAR buf[16];
GetClassName(hwnd, buf, sizeof(buf) / sizeof(TCHAR));
if (_tcscmp(buf, _T("#32768")) == 0) // special classname for menus
{
*((HWND*)lParam) = hwnd; // found it
return FALSE;
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CPPToolTip
CPPToolTip::CPPToolTip()
{
// Default values
m_dwTimeAutoPop = 5000;
m_dwTimeInitial = 500;
m_dwTimeFadeIn = 500;
m_dwTimeFadeOut = 500;
m_dwBehaviour = 0; //PPTOOLTIP_CLOSE_LEAVEWND | PPTOOLTIP_NOCLOSE_OVER; //The tooltip's behaviour
m_dwEffectBk = 0;
m_dwDirection = 0;
m_dwStyles = 0;
m_nGranularity = 0;
m_nTransparency = 0;
m_bDelayNextTool = FALSE;
m_dwShowEffect = SHOWEFFECT_FADEINOUT;
m_dwHideEffect = SHOWEFFECT_FADEINOUT;
m_nTooltipState = PPTOOLTIP_STATE_HIDEN;
m_nTooltipType = PPTOOLTIP_NORMAL;
m_nNextTooltipType = PPTOOLTIP_NORMAL;
m_ptOriginal.x = m_ptOriginal.y = 0;
m_rcCurTool.SetRectEmpty();
m_hwndDisplayedTool = NULL;
m_hBitmapBk = NULL;
m_hUnderTooltipBk = NULL;
m_hbrBorder = NULL;
m_hrgnTooltip = NULL;
SetColorBk(::GetSysColor(COLOR_INFOBK));
SetBorder(::GetSysColor(COLOR_INFOTEXT));
EnableHyperlink();
SetNotify(FALSE);
SetDefaultSizes();
SetDirection();
SetBehaviour();
SetDebugMode(FALSE);
SetMaxTipWidth(0);
// EnableTextWrap(FALSE);
SetDelayTime(PPTOOLTIP_TIME_INITIAL, 500);
SetDelayTime(PPTOOLTIP_TIME_AUTOPOP, 5000);
SetDelayTime(PPTOOLTIP_TIME_FADEIN, 0);
SetDelayTime(PPTOOLTIP_TIME_FADEOUT, 0);
SetTooltipShadow(6, 6);
#ifdef PPTOOLTIP_USE_MENU
MenuToolPosition();
#endif //PPTOOLTIP_USE_MENU
// Register the window class if it has not already been registered.
WNDCLASS wndcls;
HINSTANCE hInst = AfxGetInstanceHandle();
if(!(::GetClassInfo(hInst, PPTOOLTIP_CLASSNAME, &wndcls)))
{
// otherwise we need to register a new class
wndcls.style = CS_SAVEBITS;
wndcls.lpfnWndProc = ::DefWindowProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = hInst;
wndcls.hIcon = NULL;
wndcls.hCursor = LoadCursor(hInst, IDC_ARROW);
wndcls.hbrBackground = NULL;
wndcls.lpszMenuName = NULL;
wndcls.lpszClassName = PPTOOLTIP_CLASSNAME;
if (!AfxRegisterClass(&wndcls))
AfxThrowResourceException();
} //if
}
CPPToolTip::~CPPToolTip()
{
FreeResources();
RemoveAllTools();
HideBorder();
}
BEGIN_MESSAGE_MAP(CPPToolTip, CWnd)
//{{AFX_MSG_MAP(CPPToolTip)
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_SETCURSOR()
ON_WM_ACTIVATEAPP()
//}}AFX_MSG_MAP
ON_MESSAGE(UDM_TOOLTIP_REPAINT, OnRepaintWindow)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPPToolTip message handlers
BOOL CPPToolTip::Create(CWnd* pParentWnd, BOOL bBalloon /* = TRUE */)
{
TRACE(_T("CPPToolTip::Create\n"));
ASSERT_VALID(pParentWnd);
DWORD dwStyle = WS_POPUP;
DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
m_hParentWnd = pParentWnd->GetSafeHwnd();
if (!CreateEx(dwExStyle, PPTOOLTIP_CLASSNAME, NULL, dwStyle, 0, 0, 0, 0, pParentWnd->GetSafeHwnd(), NULL, NULL))
return FALSE;
//
SetDefaultSizes(bBalloon);
m_drawer.SetCallbackRepaint(this->GetSafeHwnd(), UDM_TOOLTIP_REPAINT);
SetDelayTime(PPTOOLTIP_TIME_ANIMATION, 100);
return TRUE;
} //End of Create
BOOL CPPToolTip::DestroyWindow()
{
Pop();
SetDelayTime(PPTOOLTIP_TIME_ANIMATION, 0);
return CWnd::DestroyWindow();
} //End of DestroyWindow
/////////////////////////////////////////////////////////////////////
// A tooltip with PPTOOLTIP_DISABLE_AUTOPOP behaviour don't hide on
// change active application
//-------------------------------------------------------------------
// Fixed by vanhoopy (July 10, 2003)
/////////////////////////////////////////////////////////////////////
#if _MSC_VER < 1300
void CPPToolTip::OnActivateApp(BOOL bActive, HTASK hTask)
#else
void CPPToolTip::OnActivateApp(BOOL bActive, DWORD hTask)
#endif //_MSC_VER
{
CWnd::OnActivateApp(bActive, hTask);
if (!bActive)
Pop();
} //End of the WM_ACTIVATEAPP handler
LRESULT CPPToolTip::SendNotify(LPPOINT pt, PPTOOLTIP_INFO & ti)
{
TRACE(_T("CPPToolTip::SendNotify()\n"));
// Make sure this is a valid window
if (!IsWindow(GetSafeHwnd()))
return 0L;
// See if the user wants to be notified
if (!IsNotify())
return 0L;
NM_PPTOOLTIP_DISPLAY lpnm;
lpnm.hwndTool = m_hwndNextTool;
lpnm.pt = pt;
lpnm.ti = &ti;
lpnm.hdr.hwndFrom = m_hWnd;
lpnm.hdr.idFrom = GetDlgCtrlID();
lpnm.hdr.code = UDM_TOOLTIP_DISPLAY;
::SendMessage(m_hNotifyWnd, WM_NOTIFY, lpnm.hdr.idFrom, (LPARAM)&lpnm);
return 0L;
} //End of SendNotify
/////////////////////////////////////////////////////////////////////
// CPPToolTip::IsNotify()
// This function determines will be send the notification messages from
// the control or not before display.
//-------------------------------------------------------------------
// Return value:
// TRUE if the control will be notified the specified window
///////////////////////////////////////////////////////////////////////
BOOL CPPToolTip::IsNotify()
{
TRACE(_T("CPPToolTip::IsNotify\n"));
return (BOOL)(m_hNotifyWnd != NULL);
} //End of IsNotify
BOOL CPPToolTip::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
CPoint ptClient;
::GetCursorPos(&ptClient);
ScreenToClient(&ptClient);
TRACE (_T("CPPToolTip::OnSetCursor(x=%d, y=%d)\n"), ptClient.x, ptClient.y);
if (m_drawer.OnSetCursor(&ptClient))
return TRUE; //The cursor over the hyperlink
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
// return CWnd::OnSetCursor(pWnd, nHitTest, message);
return TRUE;
} //End of the WM_SETCURSOR handler
LRESULT CPPToolTip::OnRepaintWindow(WPARAM wParam, LPARAM lParam)
{
TRACE (_T("CPPToolTip::OnRepaintWindow()\n"));
if (m_bHyperlinkEnabled)
{
//Window's repaint enabled
CDC * pDC = GetDC();
OnRedrawTooltip(pDC->GetSafeHdc());
ReleaseDC(pDC);
}
return TRUE;
} //End of the UDM_TOOLTIP_REPAINT handler
void CPPToolTip::OnDrawBorder(HDC hDC, HRGN hRgn)
{
ASSERT (hDC);
ASSERT (hRgn);
::FrameRgn(hDC, hRgn, m_hbrBorder, m_szBorder.cx, m_szBorder.cy);
} //End OnDrawBorder
////////////////////////////////////////////////////////////////////////
//
// +-----------------+ +-------------------+ +-----------------+
// +->| Screen +--->| m_hUnderTooltipBk | | m_hBitmapBk |
// | +--------+--------+ +-------------------+ +--------+--------+
// | | |
// | +--------V--------+ +--------V--------+
// | | | +--------------+ | |
// | | | | DrawHTML |---->| |
// | | | +--------------+ | |
// | | | | MemDC |
// | | | +--------------+ | |
// | | | | OnDrawBorder |---->| |
// | | TempDC | +--------------+ +--------+--------+
// | | | |
// | | | +--------------+ |
// | | |<----+ DrawShadow | |
// | | | +--------------+ |
// | | | |
// | | |<--------ALPHA---------------------+
// | | |
// | +--------+--------+
// | |
// +-----------+
//
////////////////////////////////////////////////////////////////////////
void CPPToolTip::OnRedrawTooltip(HDC hDC, BYTE nTransparency /* = 0 */)
{
TRACE (_T("CPPToolTip::OnRedrawTooltip(Transparency = %d)\n"), nTransparency);
//ENG: If a transparency more then max value
//RUS: 篷腓 珥圜屙桢 镳铉疣黜铖蜩 犷朦
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -