Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

733 lines
19 KiB

//
// cuiwnd.cpp
//
#include "private.h"
#include "cuitip.h"
#include "cuiobj.h"
#include "cuiutil.h"
// TIMER IDs
#define IDTIMER_TOOLTIP 0x3216
/*=============================================================================*/
/* */
/* C U I F W I N D O W */
/* */
/*=============================================================================*/
/* C U I F W I N D O W */
/*------------------------------------------------------------------------------
Constructor of CUIFWindow
------------------------------------------------------------------------------*/
CUIFToolTip::CUIFToolTip( HINSTANCE hInst, DWORD dwStyle, CUIFWindow *pWndOwner ) : CUIFWindow( hInst, dwStyle )
{
m_pWndOwner = pWndOwner;
m_pObjCur = NULL;
m_pwchToolTip = NULL;
m_fIgnore = FALSE;
m_iDelayAutoPop = -1;
m_iDelayInitial = -1;
m_iDelayReshow = -1;
m_rcMargin.left = 2;
m_rcMargin.top = 2;
m_rcMargin.right = 2;
m_rcMargin.bottom = 2;
m_iMaxTipWidth = -1;
m_fColBack = FALSE;
m_fColText = FALSE;
m_colBack = RGB( 0, 0, 0 );
m_colText = RGB( 0, 0, 0 );
}
/* ~ C U I F W I N D O W */
/*------------------------------------------------------------------------------
Destructor of CUIFWindow
------------------------------------------------------------------------------*/
CUIFToolTip::~CUIFToolTip( void )
{
if (m_pWndOwner)
m_pWndOwner->ClearToolTipWnd();
if (m_pwchToolTip != NULL) {
delete m_pwchToolTip;
}
}
/* I N I T I A L I Z E */
/*------------------------------------------------------------------------------
Initialize UI window object
(UIFObject method)
------------------------------------------------------------------------------*/
CUIFObject *CUIFToolTip::Initialize( void )
{
return CUIFWindow::Initialize();
}
/* P A I N T O B J E C T */
/*------------------------------------------------------------------------------
Paint window object
(UIFObject method)
------------------------------------------------------------------------------*/
void CUIFToolTip::OnPaint( HDC hDC )
{
HFONT hFontOld = (HFONT)SelectObject( hDC, GetFont() );
int iBkModeOld = SetBkMode( hDC, TRANSPARENT );
COLORREF colTextOld;
HBRUSH hBrush;
RECT rc = GetRectRef();
RECT rcMargin;
RECT rcText;
colTextOld = SetTextColor( hDC, (COLORREF) GetTipTextColor() );
//
hBrush = CreateSolidBrush( (COLORREF) GetTipBkColor() );
if (hBrush)
{
FillRect( hDC, &rc, hBrush );
DeleteObject( hBrush );
}
//
GetMargin( &rcMargin );
rcText.left = rc.left + rcMargin.left;
rcText.top = rc.top + rcMargin.top;
rcText.right = rc.right - rcMargin.right;
rcText.bottom = rc.bottom - rcMargin.bottom;
if (0 < GetMaxTipWidth()) {
CUIDrawText( hDC, m_pwchToolTip, -1, &rcText, DT_LEFT | DT_TOP | DT_WORDBREAK );
}
else {
CUIDrawText( hDC, m_pwchToolTip, -1, &rcText, DT_LEFT | DT_TOP | DT_SINGLELINE );
}
// restore DC
SetTextColor( hDC, colTextOld );
SetBkMode( hDC, iBkModeOld );
SelectObject( hDC, hFontOld );
}
/* O N T I M E R */
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void CUIFToolTip::OnTimer( UINT uiTimerID )
{
if (uiTimerID == IDTIMER_TOOLTIP) {
ShowTip();
}
}
/* E N A B L E */
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void CUIFToolTip::Enable( BOOL fEnable )
{
if (!fEnable) {
HideTip();
}
CUIFObject::Enable( fEnable );
}
/* G E T D E L A Y T I M E */
/*------------------------------------------------------------------------------
Retrieves the initial, pop-up, and reshow durations currently set for a
tooltip control.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::GetDelayTime( DWORD dwDuration )
{
switch (dwDuration) {
case TTDT_AUTOPOP: {
return ((m_iDelayAutoPop == -1) ? GetDoubleClickTime() * 10 : m_iDelayAutoPop);
}
case TTDT_INITIAL: {
return ((m_iDelayInitial == -1) ? GetDoubleClickTime() : m_iDelayInitial);
}
case TTDT_RESHOW: {
return ((m_iDelayReshow == -1) ? GetDoubleClickTime() / 5 : m_iDelayReshow);
}
}
return 0;
}
/* G E T M A R G I N */
/*------------------------------------------------------------------------------
Retrieves the top, left, bottom, and right margins set for a tooltip window.
A margin is the distance, in pixels, between the tooltip window border and
the text contained within the tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::GetMargin( RECT *prc )
{
if (prc == NULL) {
return 0;
}
*prc = m_rcMargin;
return 0;
}
/* G E T M A X T I P W I D T H */
/*------------------------------------------------------------------------------
Retrieves the maximum width for a tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::GetMaxTipWidth( void )
{
return m_iMaxTipWidth;
}
/* G E T T I P B K C O L O R */
/*------------------------------------------------------------------------------
Retrieves the background color in a tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::GetTipBkColor( void )
{
if (m_fColBack) {
return (LRESULT)m_colBack;
}
else {
return (LRESULT)GetSysColor( COLOR_INFOBK );
}
}
/* G E T T I P T E X T C O L O R */
/*------------------------------------------------------------------------------
Retrieves the text color in a tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::GetTipTextColor( void )
{
if (m_fColText) {
return (LRESULT)m_colText;
}
else {
return (LRESULT)GetSysColor( COLOR_INFOTEXT );
}
}
/* R E L A Y E V E N T */
/*------------------------------------------------------------------------------
Passes a mouse message to a tooltip control for processing.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::RelayEvent( MSG *pmsg )
{
if (pmsg == NULL) {
return 0;
}
switch (pmsg->message) {
case WM_MOUSEMOVE: {
CUIFObject *pUIObj;
POINT pt;
// ignore while disabled
if (!IsEnabled()) {
break;
}
// ignore mouse move while mouse down
if ((GetKeyState(VK_LBUTTON) & 0x8000) ||
(GetKeyState(VK_MBUTTON) & 0x8000) ||
(GetKeyState(VK_RBUTTON) & 0x8000)) {
break;
}
// get object from point
POINTSTOPOINT( pt, MAKEPOINTS( pmsg->lParam ) );
pUIObj = FindObject( pmsg->hwnd, pt );
//
if (pUIObj != NULL) {
if (m_pObjCur != pUIObj) {
BOOL fWasVisible = IsVisible();
HideTip();
if (fWasVisible) {
::SetTimer( GetWnd(), IDTIMER_TOOLTIP, (UINT)GetDelayTime( TTDT_RESHOW ), NULL );
}
else {
::SetTimer( GetWnd(), IDTIMER_TOOLTIP, (UINT)GetDelayTime( TTDT_INITIAL ), NULL );
}
}
}
else {
HideTip();
}
m_pObjCur = pUIObj;
break;
}
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN: {
HideTip();
break;
}
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP: {
break;
}
}
return 0;
}
/* P O P */
/*------------------------------------------------------------------------------
Removes a displayed tooltip window from view.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::Pop( void )
{
HideTip();
return 0;
}
/* S E T D E L A Y T I M E */
/*------------------------------------------------------------------------------
Sets the initial, pop-up, and reshow durations for a tooltip control.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::SetDelayTime( DWORD dwDuration, INT iTime )
{
switch (dwDuration) {
case TTDT_AUTOPOP: {
m_iDelayAutoPop = iTime;
break;
}
case TTDT_INITIAL: {
m_iDelayInitial = iTime;
break;
}
case TTDT_RESHOW: {
m_iDelayReshow = iTime;
break;
}
case TTDT_AUTOMATIC: {
if (0 <= iTime) {
m_iDelayAutoPop = iTime * 10;
m_iDelayInitial = iTime;
m_iDelayReshow = iTime / 5;
}
else {
m_iDelayAutoPop = -1;
m_iDelayInitial = -1;
m_iDelayReshow = -1;
}
break;
}
}
return 0;
}
/* S E T M A R G I N */
/*------------------------------------------------------------------------------
Sets the top, left, bottom, and right margins for a tooltip window. A margin
is the distance, in pixels, between the tooltip window border and the text
contained within the tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::SetMargin( RECT *prc )
{
if (prc == NULL) {
return 0;
}
m_rcMargin = *prc;
return 0;
}
/* S E T M A X T I P W I D T H */
/*------------------------------------------------------------------------------
Sets the maximum width for a tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::SetMaxTipWidth( INT iWidth )
{
m_iMaxTipWidth = iWidth;
return 0;
}
/* S E T T I P B K C O L O R */
/*------------------------------------------------------------------------------
Sets the background color in a tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::SetTipBkColor( COLORREF col )
{
m_fColBack = TRUE;
m_colBack = col;
return 0;
}
/* S E T T I P T E X T C O L O R */
/*------------------------------------------------------------------------------
Sets the text color in a tooltip window.
------------------------------------------------------------------------------*/
LRESULT CUIFToolTip::SetTipTextColor( COLORREF col )
{
m_fColText = TRUE;
m_colText = col;
return 0;
}
/* F I N D O B J E C T */
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
CUIFObject *CUIFToolTip::FindObject( HWND hWnd, POINT pt )
{
if (hWnd != m_pWndOwner->GetWnd()) {
return NULL;
}
return m_pWndOwner->ObjectFromPoint( pt );
}
/* S H O W T I P */
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void CUIFToolTip::ShowTip( void )
{
LPCWSTR pwchToolTip;
SIZE size;
RECT rc;
RECT rcObj;
POINT ptCursor;
::KillTimer( GetWnd(), IDTIMER_TOOLTIP );
if (m_pObjCur == NULL) {
return;
}
// if object has no tooltip, not open tooltip window
pwchToolTip = m_pObjCur->GetToolTip();
if (pwchToolTip == NULL) {
return;
}
//
// GetToolTip() might delete m_pObjCur. We need to check this again.
//
if (m_pObjCur == NULL) {
return;
}
//
// Start ToolTip notification.
//
if (m_pObjCur->OnShowToolTip())
return;
GetCursorPos( &ptCursor );
ScreenToClient(m_pObjCur->GetUIWnd()->GetWnd(),&ptCursor);
m_pObjCur->GetRect(&rcObj);
if (!PtInRect(&rcObj, ptCursor)) {
return;
}
// store tooltip text
m_pwchToolTip = new WCHAR[ StrLenW(pwchToolTip) + 1 ];
if (!m_pwchToolTip)
return;
StrCpyW( m_pwchToolTip, pwchToolTip );
// calc window size
GetTipWindowSize( &size );
// calc window position
ClientToScreen(m_pObjCur->GetUIWnd()->GetWnd(),(LPPOINT)&rcObj.left);
ClientToScreen(m_pObjCur->GetUIWnd()->GetWnd(),(LPPOINT)&rcObj.right);
GetTipWindowRect( &rc, size, &rcObj);
// show window
m_fBeingShown = TRUE;
Move( rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top );
Show( TRUE );
}
/* H I D E T I P */
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void CUIFToolTip::HideTip( void )
{
::KillTimer( GetWnd(), IDTIMER_TOOLTIP );
m_fBeingShown = FALSE;
//
// Hide ToolTip notification.
//
if (m_pObjCur)
m_pObjCur->OnHideToolTip();
if (!IsVisible()) {
return;
}
// dispose buffer
if (m_pwchToolTip != NULL) {
delete m_pwchToolTip;
m_pwchToolTip = NULL;
}
// hide window
Show( FALSE );
}
/* G E T T I P W I N D O W S I Z E */
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void CUIFToolTip::GetTipWindowSize( SIZE *psize )
{
HDC hDC = GetDC( GetWnd() );
HFONT hFontOld;
RECT rcMargin;
RECT rcText;
RECT rc;
int iTipWidth;
int iTipHeight;
Assert( psize != NULL );
if (m_pwchToolTip == NULL) {
return;
}
hFontOld = (HFONT)SelectObject( hDC, GetFont() );
// get text size
iTipWidth = (int)GetMaxTipWidth();
if (0 < iTipWidth) {
rcText.left = 0;
rcText.top = 0;
rcText.right = iTipWidth;
rcText.bottom = 0;
iTipHeight = CUIDrawText( hDC, m_pwchToolTip, -1, &rcText, DT_LEFT | DT_TOP | DT_CALCRECT | DT_WORDBREAK );
rcText.bottom = rcText.top + iTipHeight;
}
else {
rcText.left = 0;
rcText.top = 0;
rcText.right = 0;
rcText.bottom = 0;
iTipHeight = CUIDrawText( hDC, m_pwchToolTip, -1, &rcText, DT_LEFT | DT_TOP | DT_CALCRECT | DT_SINGLELINE );
rcText.bottom = rcText.top + iTipHeight;
}
// add margin size
GetMargin( &rcMargin );
rc.left = rcText.left - rcMargin.left;
rc.top = rcText.top - rcMargin.top;
rc.right = rcText.right + rcMargin.right;
rc.bottom = rcText.bottom + rcMargin.bottom;
// finally get window size
ClientRectToWindowRect( &rc );
psize->cx = (rc.right - rc.left);
psize->cy = (rc.bottom - rc.top);
SelectObject( hDC, hFontOld );
ReleaseDC( GetWnd(), hDC );
}
/* G E T T I P W I N D O W R E C T */
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void CUIFToolTip::GetTipWindowRect( RECT *prc, SIZE size, RECT *prcExclude)
{
POINT ptCursor;
POINT ptHotSpot;
SIZE sizeCursor;
HCURSOR hCursor;
ICONINFO IconInfo;
BITMAP bmp;
RECT rcScreen;
Assert( prc != NULL );
// get cursor pos
GetCursorPos( &ptCursor );
// get cursor size
sizeCursor.cx = GetSystemMetrics( SM_CXCURSOR );
sizeCursor.cy = GetSystemMetrics( SM_CYCURSOR );
ptHotSpot.x = 0;
ptHotSpot.y = 0;
hCursor = GetCursor();
if (hCursor != NULL && GetIconInfo( hCursor, &IconInfo )) {
GetObject( IconInfo.hbmMask, sizeof(bmp), &bmp );
if (!IconInfo.fIcon) {
ptHotSpot.x = IconInfo.xHotspot;
ptHotSpot.y = IconInfo.yHotspot;
sizeCursor.cx = bmp.bmWidth;
sizeCursor.cy = bmp.bmHeight;
if (IconInfo.hbmColor == NULL) {
sizeCursor.cy = sizeCursor.cy / 2;
}
}
if (IconInfo.hbmColor != NULL) {
DeleteObject( IconInfo.hbmColor );
}
DeleteObject( IconInfo.hbmMask );
}
// get screen rect
rcScreen.left = 0;
rcScreen.top = 0;
rcScreen.right = GetSystemMetrics( SM_CXSCREEN );
rcScreen.bottom = GetSystemMetrics( SM_CYSCREEN );
if (CUIIsMonitorAPIAvail()) {
HMONITOR hMonitor;
MONITORINFO MonitorInfo;
hMonitor = CUIMonitorFromPoint( ptCursor, MONITOR_DEFAULTTONEAREST );
if (hMonitor != NULL) {
MonitorInfo.cbSize = sizeof(MonitorInfo);
if (CUIGetMonitorInfo( hMonitor, &MonitorInfo )) {
rcScreen = MonitorInfo.rcMonitor;
}
}
}
// try to put it at bellow
prc->left = ptCursor.x;
prc->top = ptCursor.y - ptHotSpot.y + sizeCursor.cy;
prc->right = prc->left + size.cx;
prc->bottom = prc->top + size.cy;
if (rcScreen.bottom < prc->bottom) {
if (ptCursor.y < prcExclude->top)
prc->top = ptCursor.y - size.cy;
else
prc->top = prcExclude->top - size.cy;
prc->bottom = prc->top + size.cy;
}
if (prc->top < rcScreen.top) {
prc->top = rcScreen.top;
prc->bottom = prc->top + size.cy;
}
// check horizontal position
if (rcScreen.right < prc->right) {
prc->left = rcScreen.right - size.cx;
prc->right = prc->left + size.cx;
}
if (prc->left < rcScreen.left) {
prc->left = rcScreen.left;
prc->right = prc->left + size.cx;
}
}