From 7d32cfef27bdb9d661cfbdc6570c3d24138396c2 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 27 May 2009 23:01:51 +0400 Subject: [PATCH] comctl32/tooltips: Fix callback tip text retrieval. --- dlls/comctl32/tests/tooltips.c | 104 ++++++++++++++++++++++++++++++++++++++++- dlls/comctl32/tooltips.c | 64 +++++++++++++------------ 2 files changed, 136 insertions(+), 32 deletions(-) diff --git a/dlls/comctl32/tests/tooltips.c b/dlls/comctl32/tests/tooltips.c index 2b4f43ffd1b..6a927aa28e8 100644 --- a/dlls/comctl32/tests/tooltips.c +++ b/dlls/comctl32/tests/tooltips.c @@ -232,14 +232,63 @@ static void test_customdraw(void) { } +static const CHAR testcallbackA[] = "callback"; + +static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_NOTIFY && lParam) + { + NMTTDISPINFOA *ttnmdi = (NMTTDISPINFOA*)lParam; + + if (ttnmdi->hdr.code == TTN_GETDISPINFOA) + lstrcpy(ttnmdi->lpszText, testcallbackA); + } + + return DefWindowProcA(hwnd, message, wParam, lParam); +} + +static BOOL register_parent_wnd_class(void) +{ + WNDCLASSA cls; + + cls.style = 0; + cls.lpfnWndProc = parent_wnd_proc; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(NULL); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "Tooltips test parent class"; + return RegisterClassA(&cls); +} + +static HWND create_parent_window(void) +{ + if (!register_parent_wnd_class()) + return NULL; + + return CreateWindowEx(0, "Tooltips test parent class", + "Tooltips test parent window", + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE, + 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); +} + static void test_gettext(void) { - HWND hwnd; + HWND hwnd, notify; TTTOOLINFOA toolinfoA; TTTOOLINFOW toolinfoW; LRESULT r; - char bufA[10] = ""; + CHAR bufA[10] = ""; WCHAR bufW[10] = { 0 }; + static const CHAR testtipA[] = "testtip"; + + notify = create_parent_window(); + ok(notify != NULL, "Expected notification window to be created\n"); /* For bug 14790 - lpszText is NULL */ hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0, @@ -266,7 +315,58 @@ static void test_gettext(void) ok(strcmp(toolinfoA.lpszText, "") == 0, "lpszText should be an empty string\n"); } + /* add another tool with text */ + toolinfoA.cbSize = sizeof(TTTOOLINFOA); + toolinfoA.hwnd = NULL; + toolinfoA.hinst = GetModuleHandleA(NULL); + toolinfoA.uFlags = 0; + toolinfoA.uId = 0x1235ABCD; + strcpy(bufA, testtipA); + toolinfoA.lpszText = bufA; + toolinfoA.lParam = 0xdeadbeef; + GetClientRect(hwnd, &toolinfoA.rect); + r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA); + ok(r, "Adding the tool to the tooltip failed\n"); + if (r) + { + DWORD length; + + length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); + ok(length == 0, "Expected 0, got %d\n", length); + + toolinfoA.hwnd = NULL; + toolinfoA.uId = 0x1235ABCD; + toolinfoA.lpszText = bufA; + SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA); + ok(strcmp(toolinfoA.lpszText, testtipA) == 0, "lpszText should be an empty string\n"); + + length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0); + ok(length == 0, "Expected 0, got %d\n", length); + } + + /* add another with callback text */ + toolinfoA.cbSize = sizeof(TTTOOLINFOA); + toolinfoA.hwnd = notify; + toolinfoA.hinst = GetModuleHandleA(NULL); + toolinfoA.uFlags = 0; + toolinfoA.uId = 0x1236ABCD; + toolinfoA.lpszText = LPSTR_TEXTCALLBACKA; + toolinfoA.lParam = 0xdeadbeef; + GetClientRect(hwnd, &toolinfoA.rect); + r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA); + ok(r, "Adding the tool to the tooltip failed\n"); + if (r) + { + toolinfoA.hwnd = notify; + toolinfoA.uId = 0x1236ABCD; + toolinfoA.lpszText = bufA; + SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA); + ok(strcmp(toolinfoA.lpszText, testcallbackA) == 0, + "lpszText should be an (%s) string\n", testcallbackA); + } + DestroyWindow(hwnd); + DestroyWindow(notify); SetLastError(0xdeadbeef); hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0, diff --git a/dlls/comctl32/tooltips.c b/dlls/comctl32/tooltips.c index ee2700f91fb..9d7c327502a 100644 --- a/dlls/comctl32/tooltips.c +++ b/dlls/comctl32/tooltips.c @@ -359,7 +359,7 @@ TOOLTIPS_Refresh (const TOOLTIPS_INFO *infoPtr, HDC hdc) DeleteObject(hRgn); } -static void TOOLTIPS_GetDispInfoA(TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr) +static void TOOLTIPS_GetDispInfoA(const TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr, WCHAR *buffer) { NMTTDISPINFOA ttnmdi; @@ -377,45 +377,45 @@ static void TOOLTIPS_GetDispInfoA(TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr) if (IS_INTRESOURCE(ttnmdi.lpszText)) { LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText), - infoPtr->szTipText, INFOTIPSIZE); + buffer, INFOTIPSIZE); if (ttnmdi.uFlags & TTF_DI_SETITEM) { toolPtr->hinst = ttnmdi.hinst; toolPtr->lpszText = (LPWSTR)ttnmdi.lpszText; } } else if (ttnmdi.lpszText == 0) { - infoPtr->szTipText[0] = '\0'; + buffer[0] = '\0'; } else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) { - Str_GetPtrAtoW(ttnmdi.lpszText, infoPtr->szTipText, INFOTIPSIZE); + Str_GetPtrAtoW(ttnmdi.lpszText, buffer, INFOTIPSIZE); if (ttnmdi.uFlags & TTF_DI_SETITEM) { toolPtr->hinst = 0; toolPtr->lpszText = NULL; - Str_SetPtrW(&toolPtr->lpszText, infoPtr->szTipText); + Str_SetPtrW(&toolPtr->lpszText, buffer); } } else { ERR("recursive text callback!\n"); - infoPtr->szTipText[0] = '\0'; + buffer[0] = '\0'; } /* no text available - try calling parent instead as per native */ /* FIXME: Unsure if SETITEM should save the value or not */ - if (infoPtr->szTipText[0] == 0x00) { + if (buffer[0] == 0x00) { SendMessageW(GetParent(toolPtr->hwnd), WM_NOTIFY, toolPtr->uId, (LPARAM)&ttnmdi); if (IS_INTRESOURCE(ttnmdi.lpszText)) { LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText), - infoPtr->szTipText, INFOTIPSIZE); + buffer, INFOTIPSIZE); } else if (ttnmdi.lpszText && ttnmdi.lpszText != LPSTR_TEXTCALLBACKA) { - Str_GetPtrAtoW(ttnmdi.lpszText, infoPtr->szTipText, INFOTIPSIZE); + Str_GetPtrAtoW(ttnmdi.lpszText, buffer, INFOTIPSIZE); } } } -static void TOOLTIPS_GetDispInfoW(TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr) +static void TOOLTIPS_GetDispInfoW(const TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr, WCHAR *buffer) { NMTTDISPINFOW ttnmdi; @@ -433,47 +433,47 @@ static void TOOLTIPS_GetDispInfoW(TOOLTIPS_INFO *infoPtr, TTTOOL_INFO *toolPtr) if (IS_INTRESOURCE(ttnmdi.lpszText)) { LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText), - infoPtr->szTipText, INFOTIPSIZE); + buffer, INFOTIPSIZE); if (ttnmdi.uFlags & TTF_DI_SETITEM) { toolPtr->hinst = ttnmdi.hinst; toolPtr->lpszText = ttnmdi.lpszText; } } else if (ttnmdi.lpszText == 0) { - infoPtr->szTipText[0] = '\0'; + buffer[0] = '\0'; } else if (ttnmdi.lpszText != LPSTR_TEXTCALLBACKW) { - Str_GetPtrW(ttnmdi.lpszText, infoPtr->szTipText, INFOTIPSIZE); + Str_GetPtrW(ttnmdi.lpszText, buffer, INFOTIPSIZE); if (ttnmdi.uFlags & TTF_DI_SETITEM) { toolPtr->hinst = 0; toolPtr->lpszText = NULL; - Str_SetPtrW(&toolPtr->lpszText, infoPtr->szTipText); + Str_SetPtrW(&toolPtr->lpszText, buffer); } } else { ERR("recursive text callback!\n"); - infoPtr->szTipText[0] = '\0'; + buffer[0] = '\0'; } /* no text available - try calling parent instead as per native */ /* FIXME: Unsure if SETITEM should save the value or not */ - if (infoPtr->szTipText[0] == 0x00) { + if (buffer[0] == 0x00) { SendMessageW(GetParent(toolPtr->hwnd), WM_NOTIFY, toolPtr->uId, (LPARAM)&ttnmdi); if (IS_INTRESOURCE(ttnmdi.lpszText)) { LoadStringW(ttnmdi.hinst, LOWORD(ttnmdi.lpszText), - infoPtr->szTipText, INFOTIPSIZE); + buffer, INFOTIPSIZE); } else if (ttnmdi.lpszText && ttnmdi.lpszText != LPSTR_TEXTCALLBACKW) { - Str_GetPtrW(ttnmdi.lpszText, infoPtr->szTipText, INFOTIPSIZE); + Str_GetPtrW(ttnmdi.lpszText, buffer, INFOTIPSIZE); } } } static void -TOOLTIPS_GetTipText (TOOLTIPS_INFO *infoPtr, INT nTool) +TOOLTIPS_GetTipText (const TOOLTIPS_INFO *infoPtr, INT nTool, WCHAR *buffer) { TTTOOL_INFO *toolPtr = &infoPtr->tools[nTool]; @@ -482,26 +482,26 @@ TOOLTIPS_GetTipText (TOOLTIPS_INFO *infoPtr, INT nTool) TRACE("load res string %p %x\n", toolPtr->hinst, LOWORD(toolPtr->lpszText)); LoadStringW (toolPtr->hinst, LOWORD(toolPtr->lpszText), - infoPtr->szTipText, INFOTIPSIZE); + buffer, INFOTIPSIZE); } else if (toolPtr->lpszText) { if (toolPtr->lpszText == LPSTR_TEXTCALLBACKW) { if (toolPtr->bNotifyUnicode) - TOOLTIPS_GetDispInfoW(infoPtr, toolPtr); + TOOLTIPS_GetDispInfoW(infoPtr, toolPtr, buffer); else - TOOLTIPS_GetDispInfoA(infoPtr, toolPtr); + TOOLTIPS_GetDispInfoA(infoPtr, toolPtr, buffer); } else { /* the item is a usual (unicode) text */ - lstrcpynW (infoPtr->szTipText, toolPtr->lpszText, INFOTIPSIZE); + lstrcpynW (buffer, toolPtr->lpszText, INFOTIPSIZE); } } else { /* no text available */ - infoPtr->szTipText[0] = '\0'; + buffer[0] = '\0'; } - TRACE("%s\n", debugstr_w(infoPtr->szTipText)); + TRACE("%s\n", debugstr_w(buffer)); } @@ -597,7 +597,7 @@ TOOLTIPS_Show (TOOLTIPS_INFO *infoPtr, BOOL track_activate) TRACE("Show tooltip pre %d! (%p)\n", nTool, infoPtr->hwndSelf); - TOOLTIPS_GetTipText (infoPtr, nTool); + TOOLTIPS_GetTipText (infoPtr, nTool, infoPtr->szTipText); if (infoPtr->szTipText[0] == '\0') return; @@ -1506,6 +1506,7 @@ TOOLTIPS_GetMaxTipWidth (const TOOLTIPS_INFO *infoPtr) static LRESULT TOOLTIPS_GetTextA (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo) { + WCHAR buffer[INFOTIPSIZE]; INT nTool; if (lpToolInfo == NULL) @@ -1520,8 +1521,10 @@ TOOLTIPS_GetTextA (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOA lpToolInfo) what size buffer it requires nor a way to specify how long the one it supplies is. We'll assume it's up to INFOTIPSIZE */ - WideCharToMultiByte(CP_ACP, 0, infoPtr->tools[nTool].lpszText, -1, - lpToolInfo->lpszText, INFOTIPSIZE, NULL, NULL); + buffer[0] = '\0'; + TOOLTIPS_GetTipText(infoPtr, nTool, buffer); + WideCharToMultiByte(CP_ACP, 0, buffer, -1, lpToolInfo->lpszText, + INFOTIPSIZE, NULL, NULL); return 0; } @@ -1543,7 +1546,8 @@ TOOLTIPS_GetTextW (const TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo) if (infoPtr->tools[nTool].lpszText == NULL) return 0; - strcpyW (lpToolInfo->lpszText, infoPtr->tools[nTool].lpszText); + lpToolInfo->lpszText[0] = '\0'; + TOOLTIPS_GetTipText(infoPtr, nTool, lpToolInfo->lpszText); return 0; } @@ -2073,7 +2077,7 @@ TOOLTIPS_SetToolInfoW (TOOLTIPS_INFO *infoPtr, LPTTTOOLINFOW lpToolInfo) if (infoPtr->nCurrentTool == nTool) { - TOOLTIPS_GetTipText (infoPtr, infoPtr->nCurrentTool); + TOOLTIPS_GetTipText (infoPtr, infoPtr->nCurrentTool, infoPtr->szTipText); if (infoPtr->szTipText[0] == 0) TOOLTIPS_Hide(infoPtr); -- 2.11.4.GIT