MFC tooltips are displayed only in special cases

I am tasked with assigning tooltips for each item in the configuration menu. I have completed the β€œadding” tooltip to each control on the page, but sometimes it seems that the tooltip appears, and sometimes not, depending on the position of the control on the screen.

For a tooltip, first create pages I

EnableToolTips(TRUE); 

In each method OnInitDialog CPropertyPage. Then I add a notification map

 ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipText) 

With the OnToolTipText function looking as such

 BOOL CCfgPrefPage::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) { TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; UINT nID = pNMHDR->idFrom; if (pTTT->uFlags & TTF_IDISHWND) { nID = ::GetDlgCtrlID((HWND)nID); if(nID) { if( nID == GetDlgItem(IDC_PICKDIST_EDIT)->GetDlgCtrlID()) _tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE); else if( nID == GetDlgItem(IDC_ENDPTTOL_EDIT)->GetDlgCtrlID()) _tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE); pTTT->lpszText = pTTT->szText; // Sanity Check pTTT->hinst = AfxGetResourceHandle(); // Don't think this is needed at all return TRUE; } } return FALSE; } 

It seems that for some of my controls a tooltip will not appear. For most of the control flags, a tooltip is displayed, but for some of them, they simply do not appear. No other controls except them are disabled.

Another thing, if I use non-standard cursor windows, the tip of the tool flashes repeatedly, so in some cases it is unreadable. How can i fix this? This is not a problem for CEdit controls, so why is it a problem elsewhere?

EDIT: update. The controls that have been on the pages for many years show the tips of the tool. Any control that I am trying to add now / today does not display any hints at all. Regardless of the position, type of control, settings, I can’t get one tooltip for displaying the just inserted control.

+6
source share
2 answers

If you do not want to use the helper class that I suggested, fix the problems in your code. First, use the ON_NOTIFY_EX_RANGE macro when matching an even handler like this (this will cover all identifiers):

 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText) 

Then you need to fix your function. I see several problems here. First, when testing the TTF_IDISHWND flag, you only need to reinitialize the nID. You do not need to apply this to the whole function. Secondly, after all the manipulations, your nID will be the actual identifier of the dialog. No need for GetDlgItem () function

 BOOL CCfgPrefPage::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) { TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; UINT nID = pNMHDR->idFrom; if (pTTT->uFlags & TTF_IDISHWND) { nID = ::GetDlgCtrlID((HWND)nID); } if(nID) { if( nID == IDC_PICKDIST_EDIT) _tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE); else if( nID == IDC_ENDPTTOL_EDIT) _tcsncpy_s(pTTT->szText, _T("Tool Tip Text"), _TRUNCATE); //pTTT->lpszText = pTTT->szText; // Sanity Check *pResult = 0; return TRUE; } return FALSE; } 
+6
source

Working with a toolbar that repeats some menu items from the menu of an older MFC application, I worked on this tool hint problem, as well as (1) modifying the toolbar bitmap to include additional icons and (2) providing the user with current feedback the state of the application. My problem is that I have to do most of this manually, and not use various wizards and tools.

What I did was (1) add new members to the CView class to handle additional messages, (2) change the toolbar bitmap to add additional icons using both MS Paint and the resource editor, and (3) Added new event identifiers and event handlers to the message map for the CView derived class.

One problem that I encountered changing the bitmap in the toolbar was that since I inserted the icon, I had to move the existing icon to the right in the bitmap. My first attempt at this led to the change icon being blank on the application toolbar. Then I realized that I needed to add a bit more length to the bitmap in the toolbar. After adding a few more columns to the last icon in the raster toolbar, to make it the standard width in pixels, the icon displays correctly.

For tooltips, I added the following to the message card:

 ON_NOTIFY_EX(TTN_NEEDTEXT, 0, OnToolTipText) 

Then I added the following method to my class to handle notifications for my menu items. As a side note, OnToolTipText() be the standard method used in the CFrameWnd and CMDIChildWnd , however, the CView comes from CWnd , like CFrameWnd , so I doubt that it matters with respect to what the method is named.

 inline BOOL CPCSampleView::OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ) { static wchar_t toolTextToggleExportSylk [64] = L"Toggle SYLK export."; static wchar_t toolTextClearWindow [64] = L"Clear the log displayed."; static wchar_t toolTextConnectLan [64] = L"Log on the POS terminal through the LAN."; TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR; switch (pNMHDR->idFrom) { case ID_TOGGLE_SYLK_EXPORT: pTTT->lpszText = toolTextToggleExportSylk; return TRUE; case ID_WINDOW_CLEAR: pTTT->lpszText = toolTextClearWindow; return TRUE; case ID_CONNECT_LAN_ON: pTTT->lpszText = toolTextConnectLan; return TRUE; } // if we do not handle the message then return FALSE to let someone else do it. return FALSE; } 

For user feedback on the menu item that switches the file export when executing reports, I presented the following changes on the message map, and then applied the necessary methods. There are two types of messages, so I had to add two methods and two entries for the new entry:

 // New message map entries to handle the menu item selection event // and to update the menu item and the toolbar icon with state changes ON_COMMAND(ID_TOGGLE_SYLK_EXPORT, OnToggleExportSylk) ON_UPDATE_COMMAND_UI(ID_TOGGLE_SYLK_EXPORT, OnUpdateToggleExportSylk) // New methods added to the CView derived class // handle the menu selection event generated by either selecting the menu item // from the menu or by clicking on the icon in the toolbar. void CPCSampleView::OnToggleExportSylk() { // Exclusive Or to toggle the indicator bit from 0 to 1 and 1 to 0. GetDocument()->ulReportOptionsMap ^= CPCSampleDoc::ulReportOptionsExportSylk; } // handle the request from the MFC framework to update the displayed state this // not only does a check mark against the menu item it also causes the toolbar // icon to appear depressed if click is set or non-depressed if click is not set inline void CPCSampleView::OnUpdateToggleExportSylk (CCmdUI* pCmdUI) { if (GetDocument()->ulReportOptionsMap & CPCSampleDoc::ulReportOptionsExportSylk) { // SYLK export is turned on so indicate status to the user. This will // put a check mark beside the menu item and show the toolbar button depressed pCmdUI->SetCheck (1); } else { // SYLK export is turned off so indicate status to the user. This will // remove the check mark beside the menu item and show the toolbar button as raised. pCmdUI->SetCheck (0); } } 

Changes to the resource file were necessary to create a new button for the switch action, and also to add a new menu item for the switch action. I use the same resource identifier for several different things, as they are all separate. Thus, the identifier of the resource string is the same as for the menu item, and the same for the toolbar button to simplify my life and simplify the search for all specific bits and parts.

The toolbar resource file definition looks like this:

 IDR_MAINFRAME TOOLBAR 16, 15 BEGIN BUTTON ID_CONNECT_LAN_ON SEPARATOR BUTTON ID_WINDOW_CLEAR SEPARATOR BUTTON ID_TOGGLE_SYLK_EXPORT SEPARATOR BUTTON ID_APP_ABOUT END 

And the specific part of the menu that uses the same resource identifier for the switch event identifier is as follows:

 MENUITEM "Export to SYLK file", ID_TOGGLE_SYLK_EXPORT 

Then, to provide the text of the status bar that is displayed with the mouse, there is the addition of a table of strings:

 ID_TOGGLE_SYLK_EXPORT "Toggle export of SYLK format report files for spreadsheets." 

A member of the lpszText structure lpszText described in the MSDN documentation for the TOOLINFO structure as follows:

A pointer to a buffer containing the text for the tool, or an identifier for a string resource that contains text. This member is sometimes used to return values. If you need to examine the return value, it must point to a valid buffer of sufficient size. Otherwise, it can be set to NULL. If lpszText is set to LPSTR_TEXTCALLBACK, the control sends a TTN_GETDISPINFO code notification to the owner window to receive the text.

Having examined the existing answer to this question, I wondered about checking the if for the TTF_IDISHWND flag. The MSDN documentation for the TOOLINFO structure says the following:

Indicates that the uId element is a handle to the tool window. If this flag is not set, uId is the identifier of the instrument.

0
source

All Articles