Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何重新定义默认工具提示行为?_C++_User Interface_Winapi - Fatal编程技术网

C++ 如何重新定义默认工具提示行为?

C++ 如何重新定义默认工具提示行为?,c++,user-interface,winapi,C++,User Interface,Winapi,我创建了一个示例来检查工具提示控件。这是一个有点凌乱的程序,它创建窗口、按钮,并为按钮工具提示注册消息qwerty。将次要日志添加到每个窗口/按钮/工具提示窗口 #include <windows.h> #include <Windowsx.h> #include <CommCtrl.h> #include <string> #include <map> LRESULT CALLBACK WndProc(HWND, UINT, WPA

我创建了一个示例来检查
工具提示
控件。这是一个有点凌乱的程序,它创建窗口、按钮,并为按钮工具提示注册消息
qwerty
。将次要日志添加到每个
窗口
/
按钮
/
工具提示
窗口

#include <windows.h>
#include <Windowsx.h>
#include <CommCtrl.h>
#include <string>
#include <map>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static HWND hwndTip = 0;
static HWND tool = 0;
WNDPROC old_tooltip_proc = 0;
WNDPROC old_button_proc = 0;

std::string GetLastErrorAsString()
{
    //Get the error message, if any.
    DWORD errorMessageID = ::GetLastError();
    if (errorMessageID == 0)
        return std::string(); //No error message has been recorded

    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    std::string message(messageBuffer, size);

    //Free the buffer.
    LocalFree(messageBuffer);

    return message;
}

void log_msg(std::string prefix, UINT msg)
{
    std::map<UINT, std::string> table
    {
        {WM_NCHITTEST, "WM_NCHITTEST"},
        {TTM_WINDOWFROMPOINT, "TTM_WINDOWFROMPOINT"},
        {WM_SETCURSOR, "WM_SETCURSOR"},
        {WM_PAINT, "WM_PAINT"},
        {WM_NCPAINT, "WM_NCPAINT"},
        {WM_ERASEBKGND, "WM_ERASEBKGND"},
        {WM_SHOWWINDOW, "WM_SHOWWINDOW"},
        {WM_ACTIVATEAPP, "WM_ACTIVATEAPP"},
        {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING"},
        {WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED"},
        {WM_GETTEXT, "WM_GETTEXT"},
        {WM_MOUSELEAVE , "WM_MOUSELEAVE"},
        {WM_GETTEXTLENGTH, "WM_GETTEXTLENGTH"},
        {WM_NCCALCSIZE, "WM_NCCALCSIZE"},
        {WM_TIMER, "WM_TIMER"},
        {WM_MOVE, "WM_MOVE"},
        {WM_MOUSEMOVE, "WM_MOUSEMOVE"},
        {WM_LBUTTONDOWN, "WM_LBUTTONDOWN"},
        {TTM_RELAYEVENT, "TTM_RELAYEVENT"},
        {SB_SETTEXTA, "SB_SETTEXTA"}
    };
    if (table.find(msg) == table.end())
    {
        OutputDebugString((prefix + " " + std::to_string(msg) + "\n").c_str());
        return;
    }
    OutputDebugString((prefix + " " + table.at(msg) + "\n").c_str());
}

LRESULT CALLBACK tooltip_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    log_msg("TOOLTIP", message);
    return CallWindowProc(old_tooltip_proc, hwnd, message, wParam, lParam);
}

LRESULT CALLBACK button_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    log_msg("BUTTON", message);
    return CallWindowProc(old_button_proc, hwnd, message, wParam, lParam);
}


void createToolTip(HINSTANCE hInstance, HWND parent_window)
{
    hwndTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL,
        WS_POPUP | TTS_ALWAYSTIP,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
        parent_window, NULL, hInstance,
        NULL);
    old_tooltip_proc = (WNDPROC)SetWindowLongPtr(hwndTip, GWLP_WNDPROC, (LONG_PTR)tooltip_proc);
    if (!hwndTip)
    {
        MessageBox(parent_window, "CreateWindowEx TOOLTIPS_CLASS failed", "ERROR", MB_OK);
        return;
    }   
}

TOOLINFO get_tool_info(HWND tool)
{
    TOOLINFO g_toolItem = { 0 };
    g_toolItem.cbSize = sizeof(g_toolItem);
    g_toolItem.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
    g_toolItem.hwnd = GetParent(tool);
    g_toolItem.uId = (UINT_PTR)tool;
    g_toolItem.hinst = NULL;
    g_toolItem.lpszText = LPSTR_TEXTCALLBACK;
    return g_toolItem;
}

void register_tool(HWND _tool)
{
    std::string f("qwerty");
    TOOLINFO toolinfo = get_tool_info(_tool);
    toolinfo.lpszText = const_cast<char*>(f.c_str());
    if (SendMessage(hwndTip, TTM_ADDTOOL, 0, (LPARAM)&toolinfo) == FALSE)
    {
        MessageBox(toolinfo.hwnd, "TTM_ADDTOOL failed", "ERROR", MB_OK);
        return;
    }
    tool = _tool;
}

void unregister_tool(HWND tool)
{
    TOOLINFO toolinfo = get_tool_info(tool);
    SendMessage(hwndTip, TTM_DELTOOL, 0, (LPARAM)&toolinfo);
}

HWND createButton(HWND parent_window)
{
    auto handle =  CreateWindow(TEXT("button"), TEXT("Hellooooooooooooooooooooooooooooo"),
        WS_VISIBLE | WS_CHILD,
        10, 10, 800, 250,
        parent_window, NULL, NULL, NULL);
    old_button_proc = (WNDPROC)SetWindowLongPtr(handle, GWLP_WNDPROC, (LONG_PTR)button_proc);
    return handle;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    INITCOMMONCONTROLSEX ic;
    ic.dwSize = sizeof(INITCOMMONCONTROLSEX);
    ic.dwICC = ICC_TAB_CLASSES;
    InitCommonControlsEx(&ic);
    static TCHAR szAppName[] = TEXT("ToolTipApplication");
    HWND         hwnd;
    MSG          msg;
    WNDCLASS     wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"),
            szAppName, MB_ICONERROR);
        return 0;
    }
    hwnd = CreateWindow(szAppName,                  // window class name
        TEXT("The Hello Program"), // window caption
        WS_OVERLAPPEDWINDOW,        // window style
        CW_USEDEFAULT,              // initial x position
        CW_USEDEFAULT,              // initial y position
        CW_USEDEFAULT,              // initial x size
        CW_USEDEFAULT,              // initial y size
        NULL,                       // parent window handle
        NULL,                       // window menu handle
        hInstance,                  // program instance handle
        NULL);                     // creation parameters
    HWND button = createButton(hwnd);
    createToolTip(hInstance, ::GetDesktopWindow());
    register_tool(button);
    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    log_msg("window", message);
    return DefWindowProc(hwnd, message, wParam, lParam);
}
#包括
#包括
#包括
#包括
#包括
LRESULT回调WndProc(HWND、UINT、WPARAM、LPARAM);
静态HWND hwndTip=0;
静态HWND工具=0;
WNDPROC旧工具提示程序=0;
WNDPROC旧按钮程序=0;
std::string GetLastErrorAsString()
{
//获取错误消息(如果有)。
DWORD errorMessageID=::GetLastError();
如果(errorMessageID==0)
return std::string();//未记录任何错误消息
LPSTR messageBuffer=nullptr;
size_t size=FormatMessageA(格式化_消息_分配|格式化_消息|来自|系统|格式化_消息_忽略|插入,
NULL,errorMessageID,MAKELANGID(LANG_中立,SUBLANG_默认),(LPSTR)和messageBuffer,0,NULL);
std::字符串消息(messageBuffer,size);
//释放缓冲区。
LocalFree(messageBuffer);
返回消息;
}
无效日志消息(std::字符串前缀,UINT消息)
{
映射表
{
{WM_NCHITTEST,“WM_NCHITTEST”},
{TTM_WINDOWFROMPOINT,“TTM_WINDOWFROMPOINT”},
{WM_SETCURSOR,“WM_SETCURSOR”},
{WM_PAINT,“WM_PAINT”},
{WM_NCPAINT,“WM_NCPAINT”},
{WM_ERASEBKGND,“WM_ERASEBKGND”},
{WM_SHOWWINDOW,“WM_SHOWWINDOW”},
{WM_ACTIVATEAPP,“WM_ACTIVATEAPP”},
{WM_WINDOWPOSCHANGING,“WM_WINDOWPOSCHANGING”},
{WM_WINDOWPOSCHANGED,“WM_WINDOWPOSCHANGED”},
{WM_GETTEXT,“WM_GETTEXT”},
{WM_MOUSELEAVE,“WM_MOUSELEAVE”},
{WM_GETTEXTLENGTH,“WM_GETTEXTLENGTH”},
{WM_NCCALCSIZE,“WM_NCCALCSIZE”},
{WM_TIMER,“WM_TIMER”},
{WM_MOVE,“WM_MOVE”},
{WM_MOUSEMOVE,“WM_MOUSEMOVE”},
{WM_LBUTTONDOWN,“WM_LBUTTONDOWN”},
{TTM_RELAYEVENT,“TTM_RELAYEVENT”},
{SB_SETTEXTA,“SB_SETTEXTA”}
};
if(table.find(msg)=table.end())
{
OutputDebugString((前缀+“”+std::to_string(msg)+“\n”).c_str();
返回;
}
OutputDebugString((前缀+“”+table.at(msg)+“\n”).c_str());
}
LRESULT回调工具提示_proc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
日志消息(“工具提示”,消息);
返回CallWindowProc(旧的工具提示proc、hwnd、message、wParam、lParam);
}
LRESULT回调按钮\u进程(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
日志信息(“按钮”,信息);
返回CallWindowProc(旧按钮proc、hwnd、message、wParam、lParam);
}
无效创建工具提示(HINSTANCE HINSTANCE,HWND parent_窗口)
{
hwndTip=CreateWindowEx(WS_-EX_-top,工具提示_类,NULL,
WS|u POPUP | TTS|u ALWAYSTIP,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
父窗口,NULL,hInstance,
无效);
旧的工具提示程序=(WNDPROC)SetWindowLongPtr(hwndTip,GWLP_WNDPROC,(LONG_PTR)工具提示程序);
如果(!hwndTip)
{
MessageBox(父窗口,“CreateWindowEx工具提示”类失败,“错误”,MB\U确定);
返回;
}   
}
工具信息获取工具信息(HWND工具)
{
TOOLINFO g_toolItem={0};
g_toolItem.cbSize=sizeof(g_toolItem);
g_toolItem.uFlags=TTF_IDISHWND | TTF_子类;
g_toolItem.hwnd=GetParent(工具);
g_toolItem.uId=(UINT_PTR)工具;
g_toolItem.hinst=NULL;
g_toolItem.lpszText=LPSTR_TEXTCALLBACK;
返回g_工具项;
}
无效寄存器工具(HWND工具)
{
标准::字符串f(“qwerty”);
TOOLINFO TOOLINFO=获取工具信息(\u工具);
toolinfo.lpszText=const_cast(f.c_str());
if(SendMessage(hwndTip,TTM_ADDTOOL,0,(LPARAM)&工具信息)==FALSE)
{
消息框(toolnfo.hwnd,“TTM_ADDTOOL失败”,“错误”,MB_OK);
返回;
}
工具=_工具;
}
作废注销工具(HWND工具)
{
TOOLINFO TOOLINFO=获取工具信息(工具);
发送消息(hwndTip、TTM_DELTOOL、0、(LPRAM)和工具信息);
}
HWND createButton(HWND父窗口)
{
自动句柄=CreateWindow(文本(“按钮”)、文本(“hellooooooooooooooooo”),
WS|u可见| WS|u儿童,
10, 10, 800, 250,
父窗口,空,空,空);
旧按钮程序=(WNDPROC)设置窗口长PTR(手柄,GWLP_WNDPROC,(长PTR)按钮程序);
返回手柄;
}
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE HPPreInstance、,
PSTR szCmdLine,int iCmdShow)
{
初始控制性;
ic.dwSize=sizeof(INITCOMMONCONTROLSEX);
ic.dwICC=ICC\u TAB\u类;
初始控制性(&ic);
静态TCHAR szAppName[]=文本(“工具提示应用程序”);
HWND-HWND;
味精;
WNDCLASS WNDCLASS;
wndclass.style=CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc=WndProc;
wndclass.cbClsExtra=0;
wndclass.cbWndExtra=0;
wndclass.hInstance=hInstance;
wndclass.hIcon=LoadIcon(空,IDI_应用程序);
wndclass.hCursor=LoadCursor(空,IDC_箭头);
wndclass.hbrBackground=(HBRUSH)GetStockObject(白色画笔);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(空,文本(“此程序需要Windows NT!”),
szAppName,MB_i错误);
返回0;
}
hwnd=CreateWindow(szAppName,//窗口类名称
文本(“Hello程序”),//窗口标题
WS\u重叠窗口,//窗口样式
CW_USEDEFAULT,//初始x位置
CW\U USEFAULT,//初始y位置
CW\u usefault,//初始x大小
CW\u usefault,//初始y大小
NULL,//父窗口句柄
NULL,//窗口菜单句柄
hInstance,//程序实例句柄
NULL);//创建参数
TOOLINFO get_tool_info(HWND tool)
{
    TOOLINFO g_toolItem = { 0 };
    g_toolItem.cbSize = sizeof(g_toolItem);
    g_toolItem.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_TRANSPARENT;
    g_toolItem.hwnd = GetParent(tool);
    g_toolItem.uId = (UINT_PTR)tool;
    g_toolItem.hinst = NULL;
    g_toolItem.lpszText = LPSTR_TEXTCALLBACK;
    return g_toolItem;
}