From aba3b131bc6ab9f74e9ffcaaad0019253cb3f70d Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Fri, 24 Apr 2015 07:34:59 -0500 Subject: [PATCH] comctl32: TTM_SETTOOLINFO does not change subclassing flags. --- dlls/comctl32/tests/tooltips.c | 149 +++++++++++++++++++++++++++++++++ dlls/comctl32/tooltips.c | 24 +++--- 2 files changed, 162 insertions(+), 11 deletions(-) diff --git a/dlls/comctl32/tests/tooltips.c b/dlls/comctl32/tests/tooltips.c index a07a0542ba8..3382fcef76b 100644 --- a/dlls/comctl32/tests/tooltips.c +++ b/dlls/comctl32/tests/tooltips.c @@ -839,6 +839,154 @@ static void test_track(void) DestroyWindow(parent); } +static LRESULT CALLBACK info_wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) { + + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProcA(hWnd, msg, wParam, lParam); + } + return 0; +} + +static void test_setinfo(void) +{ + WNDCLASSA wc; + LRESULT lResult; + HWND parent, parent2, hwndTip, hwndTip2; + TTTOOLINFOA toolInfo = { 0 }; + TTTOOLINFOA toolInfo2 = { 0 }; + WNDPROC wndProc; + + /* Create a class to use the custom draw wndproc */ + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandleA(NULL); + wc.hIcon = NULL; + wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW); + wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW); + wc.lpszMenuName = NULL; + wc.lpszClassName = "SetInfoClass"; + wc.lpfnWndProc = info_wnd_proc; + RegisterClassA(&wc); + + /* Create a main window */ + parent = CreateWindowExA(0, "SetInfoClass", NULL, + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE, + 50, 50, + 300, 300, + NULL, NULL, NULL, 0); + ok(parent != NULL, "Creation of main window failed\n"); + + parent2 = CreateWindowExA(0, "SetInfoClass", NULL, + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE, + 50, 50, + 300, 300, + NULL, NULL, NULL, 0); + ok(parent2 != NULL, "Creation of main window failed\n"); + + /* Make it show */ + ShowWindow(parent2, SW_SHOWNORMAL); + flush_events(100); + + /* Create Tooltip */ + hwndTip = CreateWindowExA(WS_EX_TOPMOST, TOOLTIPS_CLASSA, + NULL, TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + parent, NULL, GetModuleHandleA(NULL), 0); + ok(hwndTip != NULL, "Creation of tooltip window failed\n"); + + hwndTip2 = CreateWindowExA(WS_EX_TOPMOST, TOOLTIPS_CLASSA, + NULL, TTS_NOPREFIX | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + parent, NULL, GetModuleHandleA(NULL), 0); + ok(hwndTip2 != NULL, "Creation of tooltip window failed\n"); + + + /* Make it topmost, as per the MSDN */ + SetWindowPos(hwndTip, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + /* Create a tool */ + toolInfo.cbSize = TTTOOLINFOA_V1_SIZE; + toolInfo.hwnd = parent; + toolInfo.hinst = GetModuleHandleA(NULL); + toolInfo.uFlags = TTF_SUBCLASS; + toolInfo.uId = 0x1234ABCD; + toolInfo.lpszText = (LPSTR)"This is a test tooltip"; + toolInfo.lParam = 0xdeadbeef; + GetClientRect (parent, &toolInfo.rect); + lResult = SendMessageA(hwndTip, TTM_ADDTOOLA, 0, (LPARAM)&toolInfo); + ok(lResult, "Adding the tool to the tooltip failed\n"); + + toolInfo.cbSize = TTTOOLINFOA_V1_SIZE; + toolInfo.hwnd = parent2; + toolInfo.hinst = GetModuleHandleA(NULL); + toolInfo.uFlags = 0; + toolInfo.uId = 0x1234ABCE; + toolInfo.lpszText = (LPSTR)"This is a test tooltip"; + toolInfo.lParam = 0xdeadbeef; + GetClientRect (parent, &toolInfo.rect); + lResult = SendMessageA(hwndTip, TTM_ADDTOOLA, 0, (LPARAM)&toolInfo); + ok(lResult, "Adding the tool to the tooltip failed\n"); + + /* Try to Remove Subclass */ + toolInfo2.cbSize = TTTOOLINFOA_V1_SIZE; + toolInfo2.hwnd = parent; + toolInfo2.uId = 0x1234ABCD; + lResult = SendMessageA(hwndTip, TTM_GETTOOLINFOA, 0, (LPARAM)&toolInfo2); + ok(lResult, "GetToolInfo failed\n"); + ok(toolInfo2.uFlags & TTF_SUBCLASS, "uFlags does not have subclass\n"); + wndProc = (WNDPROC)GetWindowLongPtrA(parent, GWLP_WNDPROC); + ok (wndProc != info_wnd_proc, "Window Proc is wrong\n"); + + toolInfo2.uFlags &= ~TTF_SUBCLASS; + SendMessageA(hwndTip, TTM_SETTOOLINFOA, 0, (LPARAM)&toolInfo2); + lResult = SendMessageA(hwndTip, TTM_GETTOOLINFOA, 0, (LPARAM)&toolInfo2); + ok(lResult, "GetToolInfo failed\n"); + ok(!(toolInfo2.uFlags & TTF_SUBCLASS), "uFlags has subclass\n"); + wndProc = (WNDPROC)GetWindowLongPtrA(parent, GWLP_WNDPROC); + ok (wndProc != info_wnd_proc, "Window Proc is wrong\n"); + + /* Try to Add Subclass */ + + /* Make it topmost, as per the MSDN */ + SetWindowPos(hwndTip2, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + toolInfo2.cbSize = TTTOOLINFOA_V1_SIZE; + toolInfo2.hwnd = parent2; + toolInfo2.uId = 0x1234ABCE; + lResult = SendMessageA(hwndTip, TTM_GETTOOLINFOA, 0, (LPARAM)&toolInfo2); + ok(lResult, "GetToolInfo failed\n"); + ok(!(toolInfo2.uFlags & TTF_SUBCLASS), "uFlags has subclass\n"); + wndProc = (WNDPROC)GetWindowLongPtrA(parent2, GWLP_WNDPROC); + ok (wndProc == info_wnd_proc, "Window Proc is wrong\n"); + + toolInfo2.uFlags |= TTF_SUBCLASS; + SendMessageA(hwndTip, TTM_SETTOOLINFOA, 0, (LPARAM)&toolInfo2); + lResult = SendMessageA(hwndTip, TTM_GETTOOLINFOA, 0, (LPARAM)&toolInfo2); + ok(lResult, "GetToolInfo failed\n"); + ok(toolInfo2.uFlags & TTF_SUBCLASS, "uFlags does not have subclass\n"); + wndProc = (WNDPROC)GetWindowLongPtrA(parent2, GWLP_WNDPROC); + ok (wndProc == info_wnd_proc, "Window Proc is wrong\n"); + + /* Clean up */ + DestroyWindow(hwndTip); + DestroyWindow(hwndTip2); + DestroyWindow(parent); + DestroyWindow(parent2); +} + START_TEST(tooltips) { InitCommonControls(); @@ -850,4 +998,5 @@ START_TEST(tooltips) test_longtextA(); test_longtextW(); test_track(); + test_setinfo(); } diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c index 5423ca59535..8bf6919a1d8 100644 --- a/dlls/comctl32/tooltips.c +++ b/dlls/comctl32/tooltips.c @@ -111,6 +111,7 @@ static HICON hTooltipIcons[TTI_ERROR+1]; typedef struct { UINT uFlags; + UINT uInternalFlags; HWND hwnd; BOOL bNotifyUnicode; UINT_PTR uId; @@ -1057,11 +1058,12 @@ TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW) infoPtr->uNumTools++; /* copy tool data */ - toolPtr->uFlags = ti->uFlags; - toolPtr->hwnd = ti->hwnd; - toolPtr->uId = ti->uId; - toolPtr->rect = ti->rect; - toolPtr->hinst = ti->hinst; + toolPtr->uFlags = ti->uFlags; + toolPtr->uInternalFlags = (ti->uFlags & (TTF_SUBCLASS | TTF_IDISHWND)); + toolPtr->hwnd = ti->hwnd; + toolPtr->uId = ti->uId; + toolPtr->rect = ti->rect; + toolPtr->hinst = ti->hinst; if (ti->cbSize >= TTTOOLINFOW_V1_SIZE) { if (IS_INTRESOURCE(ti->lpszText)) { @@ -1092,8 +1094,8 @@ TOOLTIPS_AddToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW) toolPtr->lParam = ti->lParam; /* install subclassing hook */ - if (toolPtr->uFlags & TTF_SUBCLASS) { - if (toolPtr->uFlags & TTF_IDISHWND) { + if (toolPtr->uInternalFlags & TTF_SUBCLASS) { + if (toolPtr->uInternalFlags & TTF_IDISHWND) { SetWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1, (DWORD_PTR)infoPtr->hwndSelf); } @@ -1152,8 +1154,8 @@ TOOLTIPS_DelToolT (TOOLTIPS_INFO *infoPtr, const TTTOOLINFOW *ti, BOOL isW) } /* remove subclassing */ - if (toolPtr->uFlags & TTF_SUBCLASS) { - if (toolPtr->uFlags & TTF_IDISHWND) { + if (toolPtr->uInternalFlags & TTF_SUBCLASS) { + if (toolPtr->uInternalFlags & TTF_IDISHWND) { RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1); } else { @@ -1918,8 +1920,8 @@ TOOLTIPS_Destroy (TOOLTIPS_INFO *infoPtr) } /* remove subclassing */ - if (toolPtr->uFlags & TTF_SUBCLASS) { - if (toolPtr->uFlags & TTF_IDISHWND) { + if (toolPtr->uInternalFlags & TTF_SUBCLASS) { + if (toolPtr->uInternalFlags & TTF_IDISHWND) { RemoveWindowSubclass((HWND)toolPtr->uId, TOOLTIPS_SubclassProc, 1); } else {