00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00034
00035 #include "stdafx.h"
00036 #include "gridctrl.h"
00037
00038 #ifndef GRIDCONTROL_NO_TITLETIPS
00039
00040 #include "TitleTip.h"
00041
00042 #ifdef _DEBUG
00043 #define new DEBUG_NEW
00044 #undef THIS_FILE
00045 static char THIS_FILE[] = __FILE__;
00046 #endif
00047
00049
00050
00051 CTitleTip::CTitleTip()
00052 {
00053
00054 WNDCLASS wndcls;
00055 HINSTANCE hInst = AfxGetInstanceHandle();
00056 if(!(::GetClassInfo(hInst, TITLETIP_CLASSNAME, &wndcls)))
00057 {
00058
00059 wndcls.style = CS_SAVEBITS;
00060 wndcls.lpfnWndProc = ::DefWindowProc;
00061 wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
00062 wndcls.hInstance = hInst;
00063 wndcls.hIcon = NULL;
00064 wndcls.hCursor = LoadCursor( hInst, IDC_ARROW );
00065 wndcls.hbrBackground = (HBRUSH)(COLOR_INFOBK +1);
00066 wndcls.lpszMenuName = NULL;
00067 wndcls.lpszClassName = TITLETIP_CLASSNAME;
00068
00069 if (!AfxRegisterClass(&wndcls))
00070 AfxThrowResourceException();
00071 }
00072
00073 m_dwLastLButtonDown = ULONG_MAX;
00074 m_dwDblClickMsecs = GetDoubleClickTime();
00075 m_bCreated = FALSE;
00076 m_pParentWnd = NULL;
00077 }
00078
00079 CTitleTip::~CTitleTip()
00080 {
00081 }
00082
00083
00084 BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
00085
00086 ON_WM_MOUSEMOVE()
00087
00088 END_MESSAGE_MAP()
00089
00090
00092
00093
00094 BOOL CTitleTip::Create(CWnd * pParentWnd)
00095 {
00096 ASSERT_VALID(pParentWnd);
00097
00098
00099 if (m_bCreated)
00100 return TRUE;
00101
00102 DWORD dwStyle = WS_BORDER | WS_POPUP;
00103 DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
00104 m_pParentWnd = pParentWnd;
00105
00106 m_bCreated = CreateEx(dwExStyle, TITLETIP_CLASSNAME, NULL, dwStyle,
00107 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
00108 NULL, NULL, NULL );
00109
00110 return m_bCreated;
00111 }
00112
00113 BOOL CTitleTip::DestroyWindow()
00114 {
00115 m_bCreated = FALSE;
00116
00117 return CWnd::DestroyWindow();
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 void CTitleTip::Show(CRect rectTitle, LPCTSTR lpszTitleText, int xoffset ,
00127 LPRECT lpHoverRect ,
00128 const LOGFONT* lpLogFont ,
00129 COLORREF crTextClr ,
00130 COLORREF crBackClr )
00131 {
00132 if (!IsWindow(m_hWnd))
00133 Create(m_pParentWnd);
00134
00135 ASSERT( ::IsWindow( GetSafeHwnd() ) );
00136
00137 if (rectTitle.IsRectEmpty())
00138 return;
00139
00140
00141 if( IsWindowVisible() )
00142 return;
00143
00144 m_rectHover = (lpHoverRect != NULL)? lpHoverRect : rectTitle;
00145 m_rectHover.right++; m_rectHover.bottom++;
00146
00147 m_pParentWnd->ClientToScreen( m_rectHover );
00148 ScreenToClient( m_rectHover );
00149
00150
00151 if( GetFocus() == NULL )
00152 return;
00153
00154
00155
00156 m_rectTitle.top = -1;
00157 m_rectTitle.left = -xoffset-1;
00158 m_rectTitle.right = rectTitle.Width()-xoffset;
00159 m_rectTitle.bottom = rectTitle.Height()*5+1;
00160
00161
00162 m_pParentWnd->ClientToScreen( rectTitle );
00163
00164 CClientDC dc(this);
00165 CString strTitle = _T("");
00166 strTitle += _T(" ");
00167 strTitle += lpszTitleText;
00168 strTitle += _T(" ");
00169
00170 CFont font, *pOldFont = NULL;
00171 if (lpLogFont)
00172 {
00173 font.CreateFontIndirect(lpLogFont);
00174 pOldFont = dc.SelectObject( &font );
00175 }
00176 else
00177 {
00178
00179 pOldFont = dc.SelectObject( m_pParentWnd->GetFont() );
00180 }
00181
00182 CSize size = dc.GetTextExtent( strTitle );
00183
00184 TEXTMETRIC tm;
00185 dc.GetTextMetrics(&tm);
00186 size.cx += tm.tmOverhang;
00187
00188 CRect rectDisplay = rectTitle;
00189 rectDisplay.left += xoffset;
00190 rectDisplay.right = rectDisplay.left + size.cx + xoffset;
00191
00192
00193 int position = 0;
00194 int count = -1;
00195 while(position != -1)
00196 {
00197 count++;
00198 position = strTitle.Find("\n",position+1);
00199
00200 }
00201 if (count > 0)
00202 {
00203 rectDisplay.right = rectDisplay.left + (2 * size.cx / count) + xoffset;
00204 }
00205 rectDisplay.bottom= rectDisplay.bottom +(size.cy*count);
00206 strTitle.Replace("\n","\n ");
00207
00208
00209
00210 if ((rectDisplay.right > rectTitle.right-xoffset) || (rectDisplay.bottom > rectTitle.bottom) )
00211 {
00212
00213 SetWindowPos( &wndTop, rectDisplay.left, rectDisplay.top,
00214 rectDisplay.Width(), rectDisplay.Height(),
00215 SWP_SHOWWINDOW|SWP_NOACTIVATE );
00216
00217
00218 if (crBackClr != CLR_DEFAULT)
00219 {
00220 CBrush backBrush(crBackClr);
00221 CBrush* pOldBrush = dc.SelectObject(&backBrush);
00222 CRect rect;
00223 dc.GetClipBox(&rect);
00224
00225 dc.PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);
00226 dc.SelectObject(pOldBrush);
00227 }
00228
00229 if (crTextClr != CLR_DEFAULT)
00230 dc.SetTextColor(crTextClr);
00231
00232 dc.SetBkMode( TRANSPARENT );
00233
00234
00235
00236 CRect wrect;
00237 GetClientRect(&wrect);
00238 dc.DrawText(strTitle, &wrect, DT_NOPREFIX);
00239
00240 SetCapture();
00241 }
00242
00243 dc.SelectObject( pOldFont );
00244 }
00245
00246 void CTitleTip::Hide()
00247 {
00248 if (!::IsWindow(GetSafeHwnd()))
00249 return;
00250
00251 if (GetCapture()->GetSafeHwnd() == GetSafeHwnd())
00252 ReleaseCapture();
00253
00254 ShowWindow( SW_HIDE );
00255 }
00256
00257 void CTitleTip::OnMouseMove(UINT nFlags, CPoint point)
00258 {
00259 if (!m_rectHover.PtInRect(point))
00260 {
00261 Hide();
00262
00263
00264 ClientToScreen( &point );
00265 CWnd *pWnd = WindowFromPoint( point );
00266 if ( pWnd == this )
00267 pWnd = m_pParentWnd;
00268
00269 int hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
00270
00271 if (hittest == HTCLIENT) {
00272 pWnd->ScreenToClient( &point );
00273 pWnd->PostMessage( WM_MOUSEMOVE, nFlags, MAKELONG(point.x,point.y) );
00274 } else {
00275 pWnd->PostMessage( WM_NCMOUSEMOVE, hittest, MAKELONG(point.x,point.y) );
00276 }
00277 }
00278 }
00279
00280 BOOL CTitleTip::PreTranslateMessage(MSG* pMsg)
00281 {
00282
00283 DWORD dwTick=0;
00284 BOOL bDoubleClick=FALSE;
00285
00286 CWnd *pWnd;
00287 int hittest;
00288 switch (pMsg->message)
00289 {
00290 case WM_LBUTTONDOWN:
00291
00292 dwTick = GetTickCount();
00293 bDoubleClick = ((dwTick - m_dwLastLButtonDown) <= m_dwDblClickMsecs);
00294 m_dwLastLButtonDown = dwTick;
00295
00296
00297 case WM_RBUTTONDOWN:
00298 case WM_MBUTTONDOWN:
00299 {
00300 POINTS pts = MAKEPOINTS( pMsg->lParam );
00301 POINT point;
00302 point.x = pts.x;
00303 point.y = pts.y;
00304
00305 ClientToScreen( &point );
00306 Hide();
00307
00308 pWnd = WindowFromPoint( point );
00309 if (!pWnd)
00310 return CWnd::PreTranslateMessage(pMsg);
00311
00312 if( pWnd->GetSafeHwnd() == GetSafeHwnd())
00313 pWnd = m_pParentWnd;
00314
00315 hittest = (int)pWnd->SendMessage(WM_NCHITTEST,0,MAKELONG(point.x,point.y));
00316
00317 if (hittest == HTCLIENT)
00318 {
00319 pWnd->ScreenToClient( &point );
00320 pMsg->lParam = MAKELONG(point.x,point.y);
00321 }
00322 else
00323 {
00324 switch (pMsg->message) {
00325 case WM_LBUTTONDOWN:
00326 pMsg->message = WM_NCLBUTTONDOWN;
00327 break;
00328 case WM_RBUTTONDOWN:
00329 pMsg->message = WM_NCRBUTTONDOWN;
00330 break;
00331 case WM_MBUTTONDOWN:
00332 pMsg->message = WM_NCMBUTTONDOWN;
00333 break;
00334 }
00335 pMsg->wParam = hittest;
00336 pMsg->lParam = MAKELONG(point.x,point.y);
00337 }
00338
00339
00340
00341
00342 pWnd->PostMessage( bDoubleClick ? WM_LBUTTONDBLCLK : pMsg->message,
00343 pMsg->wParam,
00344 pMsg->lParam);
00345 return TRUE;
00346 }
00347
00348 case WM_KEYDOWN:
00349 case WM_SYSKEYDOWN:
00350 Hide();
00351 m_pParentWnd->PostMessage( pMsg->message, pMsg->wParam, pMsg->lParam );
00352 return TRUE;
00353 }
00354
00355 if( GetFocus() == NULL )
00356 {
00357 Hide();
00358 return TRUE;
00359 }
00360
00361 return CWnd::PreTranslateMessage(pMsg);
00362 }
00363
00364 #endif // GRIDCONTROL_NO_TITLETIPS