Some code ambiguity in tab control code.

John Found johnfound at asm32.info
Sat Oct 1 04:11:28 CDT 2016


So, the continuation of my story, how I fixed the tooltips for tab control and what problems and differences with Windows I found.
(It does not seems to be the bestseller of the year, but still can help someone)

At the end I was able to fix the missing tooltips by the following code:

   .ti TOOLINFO

        invoke  SendMessageW, [hEditorsHost], TCM_GETTOOLTIPS, 0, 0
        mov     esi, eax

        mov     [.ti.cbSize], sizeof.TOOLINFO
        mov     [.ti.uFlags], TTF_SUBCLASS or TTF_IDISHWND	; it does not work with the tab ctrl ID

        mov     eax, [hTabControl]
        mov     [.ti.uId], eax

        mov     eax, [.hParent]		; it handles the TTN_NEEDTEXTW
        mov     [.ti.hwnd], eax

        mov     [.ti.lpszText], LPSTR_TEXTCALLBACK

        lea     eax, [.ti]
        invoke  SendMessageW, esi, TTM_ADDTOOLW, 0, eax

Now I got TTN_NEEDTEXTW notifications and everything seemed to work ok, but when testing on Windows it didn't work at all.
After some investigation, I found out that the content of the NMHDR structure passed is different in WINE and Windows. 

The differences are in the .idFrom field:

WINE puts there the handle of the tab control window (maybe because of the above TTF_IFISHWND). 
Windows always puts there the index of the tab hovered.

(NB: Actually, the WINE approach of passing the handle of the tab control in .idFrom field is much better and natural, because it gives an easy way to identify which control have to provide the tooltip text)

In attempt to make the same behavior in WINE and Windows, I tried to remove the TTF_IDISHWND flag from the above code 
and to put in [.ti.uId] the unique ID of the tab control, but then the tooltips stopped to appear in WINE at all. 

As a result, in order to have the same behavior in Windows and WINE, one should never use .idFrom field, but instead,
identify the hovered tab, by using TCM_HITTEST:

        lea     ebx, [.pnt]
        invoke  GetCursorPos, ebx

        mov     ecx, [.pnt.x]
        mov     edx, [.pnt.y]
        mov     [.tchi.pt.x], ecx
        mov     [.tchi.pt.y], edx

        lea     ebx, [.tchi]
        invoke  ScreenToClient, esi, ebx
        invoke  SendMessageW, esi, TCM_HITTEST, 0, ebx



On Fri, 30 Sep 2016 00:49:14 +0300
John Found <johnfound at asm32.info> wrote:

> Hi.
> 
> Trying without success to show tooltips for a tabcontrol, I found the following problems in the source code. Notice, that my skills in C++ are poor, so it is very possible the following is a false alarm.
> 
> I am quote https://github.com/wine-mirror/wine/blob/master/dlls/comctl32/tab.c (hope it is the proper source code)
> 
> This seems to be a bug: WM_LBUTTONDOWN is relayed in the WM_MOUSEMOVE handler. But WM_LBUTTONDOWN will always hide the tooltip. WM_MOUSEMOVE instead will set the timer for showing the tooltip.
> 
> > static LRESULT
> > TAB_MouseMove (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
> > {
> >   int redrawLeave;
> >   int redrawEnter;
> > 
> >   if (infoPtr->hwndToolTip)
> >     TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
> > 		    WM_LBUTTONDOWN, wParam, lParam);
> > 
> >   /* Determine which tab to highlight.  Redraw tabs which change highlight
> >   ** status. */
> >   TAB_RecalcHotTrack(infoPtr, &lParam, &redrawLeave, &redrawEnter);
> > 
> >   hottrack_refresh (infoPtr, redrawLeave);
> >   hottrack_refresh (infoPtr, redrawEnter);
> > 
> >   return 0;
> > }
> 
> 
> The WM_LBUTTONDOWN is relayed twice? Why? It is not exactly a bug, but sub-optimal.
> 
> > static LRESULT
> > TAB_LButtonDown (TAB_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
> > {
> >   POINT pt;
> >   INT newItem;
> >   UINT dummy;
> > 
> >   if (infoPtr->hwndToolTip)
> >     TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
> > 		    WM_LBUTTONDOWN, wParam, lParam);
> > 
> >   if (!(infoPtr->dwStyle & TCS_FOCUSNEVER)) {
> >     SetFocus (infoPtr->hwnd);
> >   }
> > 
> >   if (infoPtr->hwndToolTip)
> >     TAB_RelayEvent (infoPtr->hwndToolTip, infoPtr->hwnd,
> > 		    WM_LBUTTONDOWN, wParam, lParam);
> > 

-- 
http://fresh.flatassembler.net
http://asm32.info
John Found <johnfound at asm32.info>



More information about the wine-devel mailing list