mirror of
https://github.com/vim/vim.git
synced 2025-10-05 05:34:07 -04:00
patch 8.1.0647: MS-Windows: balloon_show() does not handle wide characters
Problem: MS-Windows: balloon_show() does not handle wide characters. Solution: Use CreateWindowExW(). (Yasuhiro Matsumoto, closes #3708)
This commit is contained in:
171
src/gui_w32.c
171
src/gui_w32.c
@@ -4367,14 +4367,14 @@ typedef struct _DllVersionInfo
|
||||
|
||||
typedef struct tagTOOLINFOA_NEW
|
||||
{
|
||||
UINT cbSize;
|
||||
UINT uFlags;
|
||||
HWND hwnd;
|
||||
UINT_PTR uId;
|
||||
RECT rect;
|
||||
HINSTANCE hinst;
|
||||
LPSTR lpszText;
|
||||
LPARAM lParam;
|
||||
UINT cbSize;
|
||||
UINT uFlags;
|
||||
HWND hwnd;
|
||||
UINT_PTR uId;
|
||||
RECT rect;
|
||||
HINSTANCE hinst;
|
||||
LPSTR lpszText;
|
||||
LPARAM lParam;
|
||||
} TOOLINFO_NEW;
|
||||
|
||||
typedef struct tagNMTTDISPINFO_NEW
|
||||
@@ -4387,6 +4387,32 @@ typedef struct tagNMTTDISPINFO_NEW
|
||||
LPARAM lParam;
|
||||
} NMTTDISPINFO_NEW;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
typedef struct tagTOOLINFOW_NEW
|
||||
{
|
||||
UINT cbSize;
|
||||
UINT uFlags;
|
||||
HWND hwnd;
|
||||
UINT_PTR uId;
|
||||
RECT rect;
|
||||
HINSTANCE hinst;
|
||||
LPWSTR lpszText;
|
||||
LPARAM lParam;
|
||||
void *lpReserved;
|
||||
} TOOLINFOW_NEW;
|
||||
|
||||
typedef struct tagNMTTDISPINFOW_NEW
|
||||
{
|
||||
NMHDR hdr;
|
||||
LPWSTR lpszText;
|
||||
WCHAR szText[80];
|
||||
HINSTANCE hinst;
|
||||
UINT uFlags;
|
||||
LPARAM lParam;
|
||||
} NMTTDISPINFOW_NEW;
|
||||
|
||||
#endif
|
||||
|
||||
typedef HRESULT (WINAPI* DLLGETVERSIONPROC)(DLLVERSIONINFO *);
|
||||
#ifndef TTM_SETMAXTIPWIDTH
|
||||
# define TTM_SETMAXTIPWIDTH (WM_USER+24)
|
||||
@@ -5502,6 +5528,15 @@ gui_mch_init(void)
|
||||
if (RegisterClassW(&wndclassw) == 0)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
s_textArea = CreateWindowExW(
|
||||
0,
|
||||
szTextAreaClassW, L"Vim text area",
|
||||
WS_CHILD | WS_VISIBLE, 0, 0,
|
||||
100, // Any value will do for now
|
||||
100, // Any value will do for now
|
||||
s_hwnd, NULL,
|
||||
s_hinst, NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -5520,15 +5555,16 @@ gui_mch_init(void)
|
||||
|
||||
if (RegisterClass(&wndclass) == 0)
|
||||
return FAIL;
|
||||
|
||||
s_textArea = CreateWindowEx(
|
||||
0,
|
||||
szTextAreaClass, "Vim text area",
|
||||
WS_CHILD | WS_VISIBLE, 0, 0,
|
||||
100, // Any value will do for now
|
||||
100, // Any value will do for now
|
||||
s_hwnd, NULL,
|
||||
s_hinst, NULL);
|
||||
}
|
||||
s_textArea = CreateWindowEx(
|
||||
0,
|
||||
szTextAreaClass, "Vim text area",
|
||||
WS_CHILD | WS_VISIBLE, 0, 0,
|
||||
100, /* Any value will do for now */
|
||||
100, /* Any value will do for now */
|
||||
s_hwnd, NULL,
|
||||
s_hinst, NULL);
|
||||
|
||||
if (s_textArea == NULL)
|
||||
return FAIL;
|
||||
@@ -6218,9 +6254,9 @@ RevOut( HDC s_hdc,
|
||||
static void
|
||||
draw_line(
|
||||
int x1,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
int y1,
|
||||
int x2,
|
||||
int y2,
|
||||
COLORREF color)
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
@@ -6241,7 +6277,7 @@ draw_line(
|
||||
static void
|
||||
set_pixel(
|
||||
int x,
|
||||
int y,
|
||||
int y,
|
||||
COLORREF color)
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
@@ -6255,7 +6291,7 @@ set_pixel(
|
||||
static void
|
||||
fill_rect(
|
||||
const RECT *rcp,
|
||||
HBRUSH hbr,
|
||||
HBRUSH hbr,
|
||||
COLORREF color)
|
||||
{
|
||||
#if defined(FEAT_DIRECTX)
|
||||
@@ -8745,12 +8781,95 @@ multiline_balloon_available(void)
|
||||
return multiline_tip;
|
||||
}
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
static void
|
||||
make_tooltipw(BalloonEval *beval, char *text, POINT pt)
|
||||
{
|
||||
TOOLINFOW *pti;
|
||||
int ToolInfoSize;
|
||||
WCHAR *tofree = NULL;
|
||||
|
||||
if (multiline_balloon_available() == TRUE)
|
||||
ToolInfoSize = sizeof(TOOLINFOW_NEW);
|
||||
else
|
||||
ToolInfoSize = sizeof(TOOLINFOW);
|
||||
|
||||
pti = (TOOLINFOW *)alloc(ToolInfoSize);
|
||||
if (pti == NULL)
|
||||
return;
|
||||
|
||||
beval->balloon = CreateWindowExW(WS_EX_TOPMOST, TOOLTIPS_CLASSW,
|
||||
NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
beval->target, NULL, s_hinst, NULL);
|
||||
|
||||
SetWindowPos(beval->balloon, HWND_TOPMOST, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
|
||||
pti->cbSize = ToolInfoSize;
|
||||
pti->uFlags = TTF_SUBCLASS;
|
||||
pti->hwnd = beval->target;
|
||||
pti->hinst = 0; // Don't use string resources
|
||||
pti->uId = ID_BEVAL_TOOLTIP;
|
||||
|
||||
if (multiline_balloon_available() == TRUE)
|
||||
{
|
||||
RECT rect;
|
||||
TOOLINFOW_NEW *ptin = (TOOLINFOW_NEW *)pti;
|
||||
pti->lpszText = LPSTR_TEXTCALLBACKW;
|
||||
tofree = enc_to_utf16((char_u*)text, NULL);
|
||||
ptin->lParam = (LPARAM)tofree;
|
||||
// switch multiline tooltips on
|
||||
if (GetClientRect(s_textArea, &rect))
|
||||
SendMessageW(beval->balloon, TTM_SETMAXTIPWIDTH, 0,
|
||||
(LPARAM)rect.right);
|
||||
}
|
||||
else
|
||||
{
|
||||
// do this old way
|
||||
tofree = enc_to_utf16((char_u*)text, NULL);
|
||||
pti->lpszText = tofree;
|
||||
}
|
||||
|
||||
// Limit ballooneval bounding rect to CursorPos neighbourhood.
|
||||
pti->rect.left = pt.x - 3;
|
||||
pti->rect.top = pt.y - 3;
|
||||
pti->rect.right = pt.x + 3;
|
||||
pti->rect.bottom = pt.y + 3;
|
||||
|
||||
SendMessageW(beval->balloon, TTM_ADDTOOLW, 0, (LPARAM)pti);
|
||||
// Make tooltip appear sooner.
|
||||
SendMessageW(beval->balloon, TTM_SETDELAYTIME, TTDT_INITIAL, 10);
|
||||
// I've performed some tests and it seems the longest possible life time
|
||||
// of tooltip is 30 seconds.
|
||||
SendMessageW(beval->balloon, TTM_SETDELAYTIME, TTDT_AUTOPOP, 30000);
|
||||
/*
|
||||
* HACK: force tooltip to appear, because it'll not appear until
|
||||
* first mouse move. D*mn M$
|
||||
* Amazingly moving (2, 2) and then (-1, -1) the mouse doesn't move.
|
||||
*/
|
||||
mouse_event(MOUSEEVENTF_MOVE, 2, 2, 0, 0);
|
||||
mouse_event(MOUSEEVENTF_MOVE, (DWORD)-1, (DWORD)-1, 0, 0);
|
||||
vim_free(pti);
|
||||
if (tofree != NULL)
|
||||
vim_free(tofree);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
make_tooltip(BalloonEval *beval, char *text, POINT pt)
|
||||
{
|
||||
TOOLINFO *pti;
|
||||
int ToolInfoSize;
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||
{
|
||||
make_tooltipw(beval, text, pt);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (multiline_balloon_available() == TRUE)
|
||||
ToolInfoSize = sizeof(TOOLINFO_NEW);
|
||||
else
|
||||
@@ -8961,6 +9080,16 @@ Handle_WM_Notify(HWND hwnd UNUSED, LPNMHDR pnmh)
|
||||
info->uFlags |= TTF_DI_SETITEM;
|
||||
}
|
||||
break;
|
||||
#ifdef FEAT_MBYTE
|
||||
case TTN_GETDISPINFOW:
|
||||
{
|
||||
// if we get here then we have new common controls
|
||||
NMTTDISPINFOW_NEW *info = (NMTTDISPINFOW_NEW *)pnmh;
|
||||
info->lpszText = (LPWSTR)info->lParam;
|
||||
info->uFlags |= TTF_DI_SETITEM;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -799,6 +799,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
647,
|
||||
/**/
|
||||
646,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user