175 lines
4.3 KiB
C++
175 lines
4.3 KiB
C++
#include "stdafx.h"
|
|
#include "TitleTip.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
CTitleTip::CTitleTip()
|
|
{
|
|
// Register the window class if it has not already been registered.
|
|
WNDCLASS wndcls;
|
|
HINSTANCE hInst = AfxGetInstanceHandle();
|
|
if(!(::GetClassInfo(hInst, TITLETIP_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 = (HBRUSH)(COLOR_INFOBK + 1);
|
|
wndcls.lpszMenuName = NULL;
|
|
wndcls.lpszClassName = TITLETIP_CLASSNAME;
|
|
if (!AfxRegisterClass(&wndcls))
|
|
AfxThrowResourceException();
|
|
}
|
|
}
|
|
|
|
CTitleTip::~CTitleTip()
|
|
{
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
|
|
//{{AFX_MSG_MAP(CTitleTip)
|
|
ON_WM_MOUSEMOVE()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
BOOL CTitleTip::Create(CWnd * pParentWnd)
|
|
{
|
|
ASSERT_VALID(pParentWnd);
|
|
|
|
DWORD dwStyle = WS_BORDER | WS_POPUP;
|
|
DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
|
|
m_pParentWnd = pParentWnd;
|
|
return CreateEx( dwExStyle, TITLETIP_CLASSNAME, NULL, dwStyle, 0, 0, 0, 0,
|
|
NULL, NULL, NULL );
|
|
}
|
|
|
|
|
|
// Show - Show the titletip if needed
|
|
// rectTitle - The rectangle within which the original
|
|
// title is constrained - in client coordinates
|
|
// lpszTitleText - The text to be displayed
|
|
// xoffset - Number of pixel that the text is offset from
|
|
// left border of the cell
|
|
void CTitleTip::Show(CRect rectTitle, LPCTSTR lpszTitleText, int xoffset /*=0*/)
|
|
{
|
|
ASSERT( ::IsWindow( m_hWnd ) );
|
|
ASSERT( !rectTitle.IsRectEmpty() );
|
|
|
|
// If titletip is already displayed, don't do anything.
|
|
if( IsWindowVisible() )
|
|
return;
|
|
|
|
// Do not display the titletip is app does not have focus
|
|
if( GetFocus() == NULL )
|
|
return;
|
|
|
|
// Determine the width of the text
|
|
m_pParentWnd->ClientToScreen( rectTitle );
|
|
|
|
CClientDC dc(this);
|
|
CString strTitle(lpszTitleText);
|
|
CFont *pFont = m_pParentWnd->GetFont(); // use same font as ctrl
|
|
CFont *pFontDC = dc.SelectObject( pFont );
|
|
|
|
CRect rectDisplay = rectTitle;
|
|
CSize size = dc.GetTextExtent( strTitle );
|
|
rectDisplay.left += xoffset;
|
|
rectDisplay.right = rectDisplay.left + size.cx + 3;
|
|
|
|
// Do not display if the text fits within available space
|
|
if( rectDisplay.right <= rectTitle.right-xoffset )
|
|
return;
|
|
|
|
int iCX = ::GetSystemMetrics(SM_CXSCREEN);
|
|
if (iCX < rectDisplay.right)
|
|
rectDisplay.OffsetRect(iCX - rectDisplay.right, 0);
|
|
|
|
// Show the titletip
|
|
SetWindowPos( &wndTop, rectDisplay.left, rectDisplay.top,
|
|
rectDisplay.Width(), rectDisplay.Height(),
|
|
SWP_SHOWWINDOW|SWP_NOACTIVATE );
|
|
|
|
dc.SetBkMode( TRANSPARENT );
|
|
dc.TextOut(1, 1, strTitle );
|
|
dc.SelectObject( pFontDC );
|
|
|
|
SetCapture();
|
|
}
|
|
|
|
void CTitleTip::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
CRect rc;
|
|
GetClientRect(&rc);
|
|
rc.InflateRect(1, 1);
|
|
if (IsWindowVisible() && !rc.PtInRect(point))
|
|
{
|
|
ReleaseCapture();
|
|
ShowWindow(SW_HIDE);
|
|
}
|
|
}
|
|
|
|
BOOL CTitleTip::PreTranslateMessage(MSG* pMsg)
|
|
{
|
|
switch( pMsg->message )
|
|
{
|
|
case WM_LBUTTONDOWN:
|
|
case WM_RBUTTONDOWN:
|
|
case WM_MBUTTONDOWN: {
|
|
POINTS pts = MAKEPOINTS( pMsg->lParam );
|
|
POINT point;
|
|
point.x = pts.x;
|
|
point.y = pts.y;
|
|
ClientToScreen( &point );
|
|
CWnd* pWnd = WindowFromPoint( point );
|
|
if( pWnd == this )
|
|
pWnd = m_pParentWnd;
|
|
|
|
int hittest = (int)pWnd->SendMessage(WM_NCHITTEST,
|
|
0,MAKELONG(point.x,point.y));
|
|
if (hittest == HTCLIENT) {
|
|
pWnd->ScreenToClient( &point );
|
|
pMsg->lParam = MAKELONG(point.x,point.y);
|
|
} else {
|
|
switch (pMsg->message) {
|
|
case WM_LBUTTONDOWN:
|
|
pMsg->message = WM_NCLBUTTONDOWN;
|
|
break;
|
|
case WM_RBUTTONDOWN:
|
|
pMsg->message = WM_NCRBUTTONDOWN;
|
|
break;
|
|
case WM_MBUTTONDOWN:
|
|
pMsg->message = WM_NCMBUTTONDOWN;
|
|
break;
|
|
}
|
|
pMsg->wParam = hittest;
|
|
pMsg->lParam = MAKELONG(point.x,point.y);
|
|
}
|
|
ReleaseCapture();
|
|
ShowWindow( SW_HIDE );
|
|
pWnd->PostMessage(pMsg->message,pMsg->wParam,pMsg->lParam);
|
|
return TRUE; }
|
|
case WM_KEYDOWN:
|
|
case WM_SYSKEYDOWN:
|
|
ReleaseCapture();
|
|
ShowWindow( SW_HIDE );
|
|
m_pParentWnd->PostMessage( pMsg->message, pMsg->wParam, pMsg->lParam );
|
|
return TRUE;
|
|
}
|
|
|
|
if( GetFocus() == NULL )
|
|
{
|
|
ReleaseCapture();
|
|
ShowWindow( SW_HIDE );
|
|
return TRUE;
|
|
}
|
|
|
|
return CWnd::PreTranslateMessage(pMsg);
|
|
}
|