> for (int n = pDoc->GetCircleCount() – 1; n >= 0 && pCircleHit == NULL; n--) {
> if (pDoc->GetCircle(n).HitTest(Point)) {
> pCircleHit = &(pDoc->GetCircle(n));
> }
> }
> return pCircleHit;
>}
>/////////////////////////////////////////////////////////////////////////////
>// CDTDemoView drawing
>void CDTDemoView::OnDraw(CDC* pDC) {
> CDTDemoDoc* pDoc = GetDocument();
> ASSERT_VALID(pDoc);
> for (int n = 0; n < pDoc->GetCircleCount(); n++) {
> pDoc->GetCircle(n).Draw(pDC);
> }
>}
>/////////////////////////////////////////////////////////////////////////////
>// CDTDemoView diagnostics
>#ifdef _DEBUG
>void CDTDemoView::AssertValid() const {
> CView::AssertValid(); } void CDTDemoView::Dump(CDumpContext& dc) const {
> CView::Dump(dc);
>}
>CDTDemoDoc* CDTDemoView::GetDocument() // non-debug version is inline
>{
> ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDTDemoDoc)));
> return (CDTDemoDoc*)m_pDocument;
>}
>#endif //_DEBUG
>/////////////////////////////////////////////////////////////////////////////
>// CDTDemoView message handlers
>void CDTDemoView::OnInitialUpdate() {
> CView::OnInitialUpdate();
> CRect ClientRect(0, 0, 1000, 1000);
> if (m_ToolTip.Create(this, TTS_ALWAYSTIP) && m_ToolTip.AddTool(this)) {
> m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX);
> m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_AUTOPOP, SHRT_MAX);
> m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_INITIAL, 200);
> m_ToolTip.SendMessage(TTM_SETDELAYTIME, TTDT_RESHOW, 200);
> } else {
> TRACE("Error in creating ToolTip");
> }
>}
>BOOL CDTDemoView::OnToolTipNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult) {
> BOOL bHandledNotify = FALSE;
> CPoint CursorPos;
> VERIFY(::GetCursorPos(&CursorPos));
> ScreenToClient(&CursorPos);
> CRect ClientRect;
> GetClientRect(ClientRect);
> // Удостовериться, что курсор попадает в клиентскую область окна,
> // потому что библиотека тоже хочет получать эти сообщения для
> // показа подсказок на панели инструментов.
> if (ClientRect.PtInRect(CursorPos)) {
> TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
> m_pCircleHit = HitTest(CursorPos);
> if (m_pCircleHit) {
> // Adjust the text by filling in TOOLTIPTEXT
> CString strTip;
> const CPoint& Center = m_pCircleHit->GetCenter();
> COLORREF Color = m_pCircleHit->GetColor();
> strTip.Format("Center: (%d, %d)\nRadius: %d\nColor: (%d, %d, %d)", Center.x, Center.y, m_pCircleHit->GetRadius(), (int)GetRValue(Color), (int)GetGValue(Color), (int)GetBValue(Color));
> ASSERT(strTip.GetLength() < sizeof(pTTT->szText));
> ::strcpy(pTTT->szText, strTip);
> // Set the text color to same color as circle
> m_ToolTip.SendMessage(TTM_SETTIPTEXTCOLOR, Color, L);
> } else {
> pTTT->szText[0] = 0;
> }
> bHandledNotify = TRUE;
> }
> return bHandledNotify;
>}
>BOOL CDTDemoView::PreTranslateMessage(MSG* pMsg) {
> if (::IsWindow(m_ToolTip.m_hWnd) && pMsg->hwnd == m_hWnd) {
> switch(pMsg->message) {
> case WM_LBUTTONDOWN:
> case WM_MOUSEMOVE:
> case WM_LBUTTONUP:
> case WM_RBUTTONDOWN:
> case WM_MBUTTONDOWN:
> case WM_RBUTTONUP:
> case WM_MBUTTONUP:
> m_ToolTip.RelayEvent(pMsg);
> break;
> }
> }
> return CView::PreTranslateMessage(pMsg);
>}
>void CDTDemoView::OnMouseMove(UINT nFlags, CPoint point) {
> if (::IsWindow(m_ToolTip.m_hWnd)) {
> const CCircle* pCircleHit = HitTest(point);
> if (!pCircleHit || pCircleHit != m_pCircleHit) {
> // Activate() скрывает подсказку.
> m_ToolTip.Activate(FALSE);
> }
> if (pCircleHit) {
> m_ToolTip.Activate(TRUE);
> m_pCircleHit = pCircleHit;
> }
> }
> CView::OnMouseMove(nFlags, point);
>}
CDTDemoView::OnInitialUpdate создает DataTip и подготавливает его к использованию. Я вызываю m_ToolTip.Create и передаю ей TTS_ALWAYSTIP, чтобы DataTip показывался независимо от того, активно приложение или нет. Затем я вызываю m_ToolTip.AddTool и передаю ей CDTDemoView, как окно, содержащее инструмент. Из-за того, что последние параметры в CToolTipCtrl::AddTool имеют значения по умолчанию (LPSTR_TEXTCALLBACK как текст подсказки, NULL для параметра lpRectTool и 0 для nIDTool), все окно будет считаться инструментом и нотификационное сообщение TTN_NEEDTEXT будет послано CDTDemoView. Эта сообщение позволяет мне установить текст подсказки в функции CDTDemoView::OnToolTipNeedText.