ToolTips sometimes don't work
Jim Adams -- sasjaa@unx.sas.com Tuesday, October 15, 1996 Environment: VC++ 4.2 / NT 4.0 I have created a subclass of the CToolBar class which catches the TTN_NEEDTEXTW and TTN_NEEDTEXTA messages. The reason I have overridden this message is that I allow the user to add their own tools to my toolbar. The tooltip is thus a user entered string and not a resource in the string table. The toolbar resides in a frame that is in a CDialogBar so that it can be docked much like the tool palette in the VC++ Dialog Editor. My problem is that the tooltip does not always display. Sometimes it is there and sometimes it just flashes. I have put a breakpoint in the code and see that it breaks here twice when there going to be no tooltip. when there is one it keeps breaking over and over again. I can find no clue as to why it suddenly starts working. I have to open another MDIChild window or click on the owning frame or something. It doesn't always work. I am puzzled. I have used Spy++ to watch for timer messages that I may not know about but there are only the flyby timers and one to update the clock in the status bar. I am looking for clues. I have looked in the July 96 MSDN and found nothing. -- +--------------------------------+-------------------------------------+ |James Adams | Something's better than nothing | | sasjaa@unx.sas.com | but nothing's better than | | Bari - RTP General Assembly | more more more | | Barbershop Chorus | | | http://members.aol.com/rtpbbs | | +--------------------------------+-------------------------------------+
Randy Taylor -- drt@ebt.com Wednesday, October 16, 1996 Environment: VC++ 4.2 / NT 4.0 Part of the key to tooltips is in the implementation of BOOL CFrameWnd::OnToolTipText(UINT msg, NMHDR* pNMHDR, LRESULT* pResult). You should create this message map entries for your CMDIChildWnd and your CMDIFrameWnd: ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText) Then in your implemention of your CMDIFrameWnd::OnToolTipText you can send the TTN_NEEDTEXT message to the CMDIChildWnd which happens to be active. Make sure that you copy the code from the MFC's CFrameWnd::OnToolTipText that you may need... Below is my code. randy_taylor@ebt.com BOOL SmWebDisplayFrame::OnToolTipText(UINT msg, NMHDR* pNMHDR, LRESULT* pResult) { ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW); *pResult = 0; // allow top level routing frame to handle the message if (GetRoutingFrame() != NULL) return FALSE; TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; UINT nID = pNMHDR->idFrom; if (pTTTA->uFlags & TTF_IDISHWND) { // idFrom is actually the HWND of the tool nID = _AfxGetDlgCtrlID((HWND)nID); if (nID == AFX_IDW_TOOLBAR) ; // message handled below else { CWnd* wnd = CWnd::FromHandlePermanent((HWND)pNMHDR->idFrom); TCHAR *pText = NULL; POINT pt = GetCurrentMessage()->pt; wnd->SendMessage(WMSM_TTNEEDTEXT, (WPARAM)&pt, (LPARAM) &pText); if (pText) { _tcsncpy(pTTTA->szText, pText, sizeof pTTTA->szText); return TRUE; } else return FALSE; } } //************************************************************** // THE CODE BELOW IS COPIED VERBATIM FROM CFrameWnd::OnToolTipText() //*************************************************************** .... code ommitted here.... }
Jim Adams -- sasjaa@unx.sas.com Thursday, October 17, 1996 Environment: VC++ 4.2 / NT 4.0 > I have created a subclass of the CToolBar class which catches the > TTN_NEEDTEXTW and TTN_NEEDTEXTA messages. The reason I have overridden > this message is that I allow the user to add their own tools to my > toolbar. The tooltip is thus a user entered string and not a resource > in the string table. The toolbar resides in a frame that is in a > CDialogBar so that it can be docked much like the tool palette in the > VC++ Dialog Editor. > > My problem is that the tooltip does not always display. Sometimes it > is there and sometimes it just flashes. I have put a breakpoint in the > code and see that it breaks here twice when there going to be no > tooltip. when there is one it keeps breaking over and over again. I > can find no clue as to why it suddenly starts working. I have to open > another MDIChild window or click on the owning frame or something. It > doesn't always work. > > I am puzzled. I have used Spy++ to watch for timer messages that I may > not know about but there are only the flyby timers and one to update > the clock in the status bar. > > I am looking for clues. I have looked in the July 96 MSDN and found > nothing. > I hate to answer my own question but it turned out to be really simple. The code I used to put the string in the tool tip was taken from the online doc(Programming with MFC:ToolTips). It has lines like: TOOLTIPTEXT *pTTT = (TOOLTIPTEXT*) pNMHDR; if (pTTT->uFlags & TTF_IDISHWND) nID = ::GetDlgCtrlId((HWND)nID); My problem was that was using the TTN_NEEDTEXTA and TTN_NEEDTEXTW messages which don't pass in data in the same format. In particular, the uFlags datum is in different places in the two structures. I was looking at a pointer instead of a flag value and sometimes the pointer was an odd value and sometimes even. To work the code needed to be more like: TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; if (((pNMHDR->code == TTN_NEEDTEXTA) && (pTTTA->uFlags & TTF_IDISHWND) ) || ((pNMHDR->code == TTN_NEEDTEXTW) && (pTTTW->uFlags & TTF_IDISHWND) )) nID = ::GetDlgCtrlId((HWND)nID); -- +--------------------------------+-------------------------------------+ |James Adams | Something's better than nothing | | sasjaa@unx.sas.com | but nothing's better than | | Bari - RTP General Assembly | more more more | | Barbershop Chorus | | | http://members.aol.com/rtpbbs | | +--------------------------------+-------------------------------------+
| Вернуться в корень Архива |