summaryrefslogtreecommitdiffstats
path: root/src/gui_w32.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-12-27 22:43:08 +0100
committerBram Moolenaar <Bram@vim.org>2018-12-27 22:43:08 +0100
commitd385b5d329a6a98539fa21cfb60ed632cd03d544 (patch)
tree8c36f6a03740673b2b165589e19a960010ec6da5 /src/gui_w32.c
parentb09c684195d803137d52c34fb4d3a410be5ac10f (diff)
patch 8.1.0647: MS-Windows: balloon_show() does not handle wide charactersv8.1.0647
Problem: MS-Windows: balloon_show() does not handle wide characters. Solution: Use CreateWindowExW(). (Yasuhiro Matsumoto, closes #3708)
Diffstat (limited to 'src/gui_w32.c')
-rw-r--r--src/gui_w32.c171
1 files changed, 150 insertions, 21 deletions
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 0db57acc94..c919243161 100644
--- a/src/gui_w32.c
+++ b/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
}
}
}