سؤال

I have a problem, I hope you can help me out. Already out of my research luck... tried stackoverflow, google, even yahoo...

How can I force a tooltip to come out NOT using the mouse?

I am currently implementing some windows automatization and need to force the tooltips to appear.

Like this. Usually you have to hold your mouse over that bar for like 1 - 2 seconds.

I want to force these tooltips to appear using the WINAPI or something similar.

Somethink like "SendMessage/Postmessage(hwnd, "WM_COMEOUTTOOLTIP", 0, lParam (with x and y Position)".

Does something like this exist in WINAPI? Have googled crazy but found nothing.

Thanks guys for your help!

Jonathan

هل كانت مفيدة؟

المحلول

This SO Answer mentions that you can use the TTM_POPUP message to bring up a tooltip, using TTM_TRACKPOSITION to set the position of the tooltip.

EDIT: I got a bit curious about this and tried to make a working sample:

a) include common controls in the manifest or use the following line in the source

#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

b) create and set up the tooltip window

hWndtoolTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, 0, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, hWndParent, 0, hInstance, 0);
SetWindowPos(hWndtoolTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

TOOLINFO ti = {};
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_SUBCLASS;
ti.hwnd   = hWndParent;
ti.hinst  = hInstance;
ti.uId    = (UINT)hWndtoolTip;
ti.lpszText = L"tool-tip";
GetClientRect(hWndParent, &ti.rect);
SendMessage(hWndtoolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);

c) to show the tooltip at a specific postion (say, x=300, y=300):

SetCursorPos(300, 300);
SendMessage(hWndtoolTip, TTM_POPUP, 0, 0);

نصائح أخرى

Maybe this is what you are looking for?

And since tooltips are created with the CreateWindowEx function, can't you just use ShowWindow?

Hallelujah. I know how to manually display a tooltip!!! We do this by using tracking tooltips. But there is one trick/ pitfall.

Create tooltip

HWND createToolTip(HWND owner)
{
 INITCOMMONCONTROLSEX ic{ sizeof(ic), ICC_WIN95_CLASSES };
 InitCommonControlsEx(&ic);

 HWND tip = CreateWindowExA(
               WS_EX_TOPMOST|ex_style, //MSDN states that WS_EX_TOOLWINDOW is always apart of ToolTip style
               TOOLTIPS_CLASSA,
               NULL,
               style, // MSDN states that WS_POPUP is always apart of ToolTip style
               CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
               owner,
               NULL,
               (HINSTANCE)0x400000,
               NULL
           );

 //SetWindowPos(tip,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
 return tip;
}

Create and add Tracking Tool. Note that the tooltip itself is not tracking. It is the tool that is a tracking tool. Thus you can have multiple tools that are tracking and non-tracking registered for the same tool tip.

TOOLINFOA createTrackingTool(HWND owner,HWND tool)
{
    TOOLINFOA info = {};
    info.cbSize   = sizeof(info);
    info.uFlags   = TTF_IDISHWND | //dictates that TOOLINFO::uId is Window Handle of tool
                    TTF_TRACK |    //dictates that this is a tracking tool
                    TTF_ABSOLUTE;  //Required for TTF_TRACK, ass tracking tools use absolute co-ords; Don't ask why.
                                   //TTF_SUBCLASS is not needed for our case.
                                   //  but I think using TTF_SUBCLASS with TTF_TRACK can cause
                                   //  tooltip to automatically popup and balloon arrow pointing
                                   //  to a point we specify
    info.hwnd     = owner;
    info.uId      = (UINT_PTR)tool;

    return info;
}

TOOLINFOA createTrackingTool(HWND owner,uint id,const RECT &toolRect)
{
    TOOLINFOA info = {};
    info.cbSize   = sizeof(info);
    info.uFlags   = TTF_TRACK | TTF_ABSOLUTE;
    info.hwnd     = owner;
    info.uId      = id; // owner and id uniquely identifies a tool
    info.rect     = toolRect;

    return info;
}

void addTool(HWND toolTip,const TOOLINFOA &info)
{
 SendMessage(toolTip, TTM_ADDTOOL, 0, (LPARAM)&info);
}

Manipulate tool tip

void setText(HWND toolTip,TOOLINFOA &info,const char *text)
{
 info.lpszText = text;
 SendMessage(toolTip, TTM_SETTOOLINFO, 0, (LPARAM)&info);
}


void setPos(HWND toolTip,HWND relHwnd,int x,int y)
{
 SendMessage(widget,TTM_TRACKACTIVATE,true,(LPARAM)&info);

 POINT pt = {x,y};
 ClientToScreen(relHwnd,&pt);
 SendMessage(widget,TTM_TRACKPOSITION,0,MAKELPARAM(pt.x,pt.y));
}

void redraw(HWND toolTip)
{
 RedrawWindow(toolTip,NULL,NULL,RDW_INVALIDATE);
}

Put Every together

LRESULT CALLBACK proc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
    if(msg == WM_CREATE)
    {
        HWND tip = createToolTip(mainWindow);
        TOOLINFOA info = createTrackingTool(mainWindow,button);
        addTool(tip,info);
        
        // By causing the tooltip to draw itself now, it will be overdrawn
        // by this window once WM_CREATE is finished.
        // By redrawing the tooltip later you can see that the tooltip 
        // was really activated at this point.
        setText(tip,info,"MyText");
        setPos(tip,hwnd,20,20);
        
        return 0;
    }
    if(msg == WM_SHOWWINDOW)
    {
        redraw(tip); //Cause the tool tip to redraw so it is visible on screen
        return 0;
    }
    if(msg == WM_KEYDOWN)
    {
        // You can draw the tooltip now and not have to worry about this window 
        // drawing over the tooltip.
        setText(tip,info,"Time to activate track tooltip");
        setPos(tip,hwnd,20,20); 
    }
    
    return DefWindowProc(hwnd,msg,wparam,lparam);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top