Domanda

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

È stato utile?

Soluzione

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);

Altri suggerimenti

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top