Mercurial > vim
annotate src/gui_w48.c @ 8122:39532ee7dd43 v7.4.1355
commit https://github.com/vim/vim/commit/ed5a78e11c80c7b13b233149fd4273b71fc96262
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Feb 19 21:05:03 2016 +0100
patch 7.4.1355
Problem: Win32 console and GUI handle channels differently.
Solution: Consolidate code between Win32 console and GUI.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 19 Feb 2016 21:15:05 +0100 |
parents | 441298d72f3c |
children | f52504c10387 |
rev | line source |
---|---|
7 | 1 /* vi:set ts=8 sts=4 sw=4: |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * GUI support by Robert Webb | |
5 * | |
6 * Do ":help uganda" in Vim to read copying and usage conditions. | |
7 * Do ":help credits" in Vim to see a list of people who contributed. | |
8 * See README.txt for an overview of the Vim source code. | |
9 */ | |
10 /* | |
11 * gui_w48.c: This file is included in gui_w16.c and gui_w32.c. | |
12 * | |
13 * GUI support for Microsoft Windows (Win16 + Win32 = Win48 :-) | |
14 * | |
15 * The combined efforts of: | |
16 * George V. Reilly <george@reilly.org> | |
17 * Robert Webb | |
18 * Vince Negri | |
19 * ...and contributions from many others | |
20 * | |
21 */ | |
22 | |
23 #include "vim.h" | |
24 #include "version.h" /* used by dialog box routine for default title */ | |
25 #ifdef DEBUG | |
26 # include <tchar.h> | |
27 #endif | |
3927 | 28 |
29 /* cproto fails on missing include files */ | |
30 #ifndef PROTO | |
31 | |
7 | 32 #ifndef __MINGW32__ |
33 # include <shellapi.h> | |
34 #endif | |
810 | 35 #if defined(FEAT_TOOLBAR) || defined(FEAT_BEVAL) || defined(FEAT_GUI_TABLINE) |
7 | 36 # include <commctrl.h> |
37 #endif | |
38 #ifdef WIN16 | |
39 # include <commdlg.h> | |
40 # include <shellapi.h> | |
41 # ifdef WIN16_3DLOOK | |
42 # include <ctl3d.h> | |
43 # endif | |
44 #endif | |
45 #include <windowsx.h> | |
46 | |
47 #ifdef GLOBAL_IME | |
48 # include "glbl_ime.h" | |
49 #endif | |
50 | |
3927 | 51 #endif /* PROTO */ |
52 | |
7 | 53 #ifdef FEAT_MENU |
54 # define MENUHINTS /* show menu hints in command line */ | |
55 #endif | |
56 | |
57 /* Some parameters for dialog boxes. All in pixels. */ | |
58 #define DLG_PADDING_X 10 | |
59 #define DLG_PADDING_Y 10 | |
60 #define DLG_OLD_STYLE_PADDING_X 5 | |
61 #define DLG_OLD_STYLE_PADDING_Y 5 | |
62 #define DLG_VERT_PADDING_X 4 /* For vertical buttons */ | |
63 #define DLG_VERT_PADDING_Y 4 | |
64 #define DLG_ICON_WIDTH 34 | |
65 #define DLG_ICON_HEIGHT 34 | |
66 #define DLG_MIN_WIDTH 150 | |
67 #define DLG_FONT_NAME "MS Sans Serif" | |
68 #define DLG_FONT_POINT_SIZE 8 | |
69 #define DLG_MIN_MAX_WIDTH 400 | |
153 | 70 #define DLG_MIN_MAX_HEIGHT 400 |
7 | 71 |
72 #define DLG_NONBUTTON_CONTROL 5000 /* First ID of non-button controls */ | |
73 | |
74 #ifndef WM_XBUTTONDOWN /* For Win2K / winME ONLY */ | |
75 # define WM_XBUTTONDOWN 0x020B | |
76 # define WM_XBUTTONUP 0x020C | |
77 # define WM_XBUTTONDBLCLK 0x020D | |
78 # define MK_XBUTTON1 0x0020 | |
79 # define MK_XBUTTON2 0x0040 | |
80 #endif | |
81 | |
82 #ifdef PROTO | |
83 /* | |
84 * Define a few things for generating prototypes. This is just to avoid | |
85 * syntax errors, the defines do not need to be correct. | |
86 */ | |
87 # define APIENTRY | |
88 # define CALLBACK | |
89 # define CONST | |
90 # define FAR | |
91 # define NEAR | |
92 # define _cdecl | |
93 typedef int BOOL; | |
94 typedef int BYTE; | |
95 typedef int DWORD; | |
96 typedef int WCHAR; | |
97 typedef int ENUMLOGFONT; | |
98 typedef int FINDREPLACE; | |
99 typedef int HANDLE; | |
100 typedef int HBITMAP; | |
101 typedef int HBRUSH; | |
102 typedef int HDROP; | |
103 typedef int INT; | |
104 typedef int LOGFONT[]; | |
105 typedef int LPARAM; | |
106 typedef int LPCREATESTRUCT; | |
107 typedef int LPCSTR; | |
108 typedef int LPCTSTR; | |
109 typedef int LPRECT; | |
110 typedef int LPSTR; | |
111 typedef int LPWINDOWPOS; | |
112 typedef int LPWORD; | |
113 typedef int LRESULT; | |
502 | 114 typedef int HRESULT; |
7 | 115 # undef MSG |
116 typedef int MSG; | |
117 typedef int NEWTEXTMETRIC; | |
118 typedef int OSVERSIONINFO; | |
119 typedef int PWORD; | |
120 typedef int RECT; | |
121 typedef int UINT; | |
122 typedef int WORD; | |
123 typedef int WPARAM; | |
124 typedef int POINT; | |
125 typedef void *HINSTANCE; | |
126 typedef void *HMENU; | |
127 typedef void *HWND; | |
128 typedef void *HDC; | |
129 typedef void VOID; | |
130 typedef int LPNMHDR; | |
131 typedef int LONG; | |
5294 | 132 typedef int WNDPROC; |
7 | 133 #endif |
134 | |
135 #ifndef GET_X_LPARAM | |
136 # define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) | |
137 #endif | |
138 | |
139 static void _OnPaint( HWND hwnd); | |
140 static void clear_rect(RECT *rcp); | |
141 static int gui_mswin_get_menu_height(int fix_window); | |
142 | |
143 static WORD s_dlgfntheight; /* height of the dialog font */ | |
144 static WORD s_dlgfntwidth; /* width of the dialog font */ | |
145 | |
146 #ifdef FEAT_MENU | |
147 static HMENU s_menuBar = NULL; | |
148 #endif | |
149 #ifdef FEAT_TEAROFF | |
150 static void rebuild_tearoff(vimmenu_T *menu); | |
151 static HBITMAP s_htearbitmap; /* bitmap used to indicate tearoff */ | |
152 #endif | |
153 | |
1198 | 154 /* Flag that is set while processing a message that must not be interrupted by |
7 | 155 * processing another message. */ |
156 static int s_busy_processing = FALSE; | |
157 | |
158 static int destroying = FALSE; /* call DestroyWindow() ourselves */ | |
159 | |
160 #ifdef MSWIN_FIND_REPLACE | |
161 static UINT s_findrep_msg = 0; /* set in gui_w[16/32].c */ | |
162 static FINDREPLACE s_findrep_struct; | |
1795 | 163 # if defined(FEAT_MBYTE) && defined(WIN3264) |
164 static FINDREPLACEW s_findrep_struct_w; | |
165 # endif | |
7 | 166 static HWND s_findrep_hwnd = NULL; |
167 static int s_findrep_is_find; /* TRUE for find dialog, FALSE | |
168 for find/replace dialog */ | |
169 #endif | |
170 | |
171 static HINSTANCE s_hinst = NULL; | |
172 #if !defined(FEAT_SNIFF) && !defined(FEAT_GUI) | |
173 static | |
174 #endif | |
175 HWND s_hwnd = NULL; | |
176 static HDC s_hdc = NULL; | |
177 static HBRUSH s_brush = NULL; | |
178 | |
179 #ifdef FEAT_TOOLBAR | |
180 static HWND s_toolbarhwnd = NULL; | |
5223
91d478da863e
updated for version 7.4a.037
Bram Moolenaar <bram@vim.org>
parents:
5216
diff
changeset
|
181 static WNDPROC s_toolbar_wndproc = NULL; |
7 | 182 #endif |
183 | |
810 | 184 #ifdef FEAT_GUI_TABLINE |
185 static HWND s_tabhwnd = NULL; | |
5223
91d478da863e
updated for version 7.4a.037
Bram Moolenaar <bram@vim.org>
parents:
5216
diff
changeset
|
186 static WNDPROC s_tabline_wndproc = NULL; |
810 | 187 static int showing_tabline = 0; |
188 #endif | |
189 | |
7 | 190 static WPARAM s_wParam = 0; |
191 static LPARAM s_lParam = 0; | |
192 | |
193 static HWND s_textArea = NULL; | |
194 static UINT s_uMsg = 0; | |
195 | |
196 static char_u *s_textfield; /* Used by dialogs to pass back strings */ | |
197 | |
198 static int s_need_activate = FALSE; | |
199 | |
200 /* This variable is set when waiting for an event, which is the only moment | |
201 * scrollbar dragging can be done directly. It's not allowed while commands | |
202 * are executed, because it may move the cursor and that may cause unexpected | |
203 * problems (e.g., while ":s" is working). | |
204 */ | |
205 static int allow_scrollbar = FALSE; | |
206 | |
207 #ifdef GLOBAL_IME | |
208 # define MyTranslateMessage(x) global_ime_TranslateMessage(x) | |
209 #else | |
210 # define MyTranslateMessage(x) TranslateMessage(x) | |
211 #endif | |
212 | |
213 #if (defined(WIN3264) && defined(FEAT_MBYTE)) || defined(GLOBAL_IME) | |
214 /* use of WindowProc depends on wide_WindowProc */ | |
215 # define MyWindowProc vim_WindowProc | |
216 #else | |
217 /* use ordinary WindowProc */ | |
218 # define MyWindowProc DefWindowProc | |
219 #endif | |
220 | |
221 extern int current_font_height; /* this is in os_mswin.c */ | |
222 | |
223 static struct | |
224 { | |
225 UINT key_sym; | |
226 char_u vim_code0; | |
227 char_u vim_code1; | |
228 } special_keys[] = | |
229 { | |
230 {VK_UP, 'k', 'u'}, | |
231 {VK_DOWN, 'k', 'd'}, | |
232 {VK_LEFT, 'k', 'l'}, | |
233 {VK_RIGHT, 'k', 'r'}, | |
234 | |
235 {VK_F1, 'k', '1'}, | |
236 {VK_F2, 'k', '2'}, | |
237 {VK_F3, 'k', '3'}, | |
238 {VK_F4, 'k', '4'}, | |
239 {VK_F5, 'k', '5'}, | |
240 {VK_F6, 'k', '6'}, | |
241 {VK_F7, 'k', '7'}, | |
242 {VK_F8, 'k', '8'}, | |
243 {VK_F9, 'k', '9'}, | |
244 {VK_F10, 'k', ';'}, | |
245 | |
246 {VK_F11, 'F', '1'}, | |
247 {VK_F12, 'F', '2'}, | |
248 {VK_F13, 'F', '3'}, | |
249 {VK_F14, 'F', '4'}, | |
250 {VK_F15, 'F', '5'}, | |
251 {VK_F16, 'F', '6'}, | |
252 {VK_F17, 'F', '7'}, | |
253 {VK_F18, 'F', '8'}, | |
254 {VK_F19, 'F', '9'}, | |
255 {VK_F20, 'F', 'A'}, | |
256 | |
257 {VK_F21, 'F', 'B'}, | |
258 #ifdef FEAT_NETBEANS_INTG | |
259 {VK_PAUSE, 'F', 'B'}, /* Pause == F21 (see gui_gtk_x11.c) */ | |
260 #endif | |
261 {VK_F22, 'F', 'C'}, | |
262 {VK_F23, 'F', 'D'}, | |
263 {VK_F24, 'F', 'E'}, /* winuser.h defines up to F24 */ | |
264 | |
265 {VK_HELP, '%', '1'}, | |
266 {VK_BACK, 'k', 'b'}, | |
267 {VK_INSERT, 'k', 'I'}, | |
268 {VK_DELETE, 'k', 'D'}, | |
269 {VK_HOME, 'k', 'h'}, | |
270 {VK_END, '@', '7'}, | |
271 {VK_PRIOR, 'k', 'P'}, | |
272 {VK_NEXT, 'k', 'N'}, | |
273 {VK_PRINT, '%', '9'}, | |
274 {VK_ADD, 'K', '6'}, | |
275 {VK_SUBTRACT, 'K', '7'}, | |
276 {VK_DIVIDE, 'K', '8'}, | |
277 {VK_MULTIPLY, 'K', '9'}, | |
278 {VK_SEPARATOR, 'K', 'A'}, /* Keypad Enter */ | |
279 {VK_DECIMAL, 'K', 'B'}, | |
280 | |
281 {VK_NUMPAD0, 'K', 'C'}, | |
282 {VK_NUMPAD1, 'K', 'D'}, | |
283 {VK_NUMPAD2, 'K', 'E'}, | |
284 {VK_NUMPAD3, 'K', 'F'}, | |
285 {VK_NUMPAD4, 'K', 'G'}, | |
286 {VK_NUMPAD5, 'K', 'H'}, | |
287 {VK_NUMPAD6, 'K', 'I'}, | |
288 {VK_NUMPAD7, 'K', 'J'}, | |
289 {VK_NUMPAD8, 'K', 'K'}, | |
290 {VK_NUMPAD9, 'K', 'L'}, | |
291 | |
292 /* Keys that we want to be able to use any modifier with: */ | |
293 {VK_SPACE, ' ', NUL}, | |
294 {VK_TAB, TAB, NUL}, | |
295 {VK_ESCAPE, ESC, NUL}, | |
296 {NL, NL, NUL}, | |
297 {CAR, CAR, NUL}, | |
298 | |
299 /* End of list marker: */ | |
300 {0, 0, 0} | |
301 }; | |
302 | |
303 /* Local variables */ | |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
304 static int s_button_pending = -1; |
1453 | 305 |
306 /* s_getting_focus is set when we got focus but didn't see mouse-up event yet, | |
307 * so don't reset s_button_pending. */ | |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
308 static int s_getting_focus = FALSE; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
309 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
310 static int s_x_pending; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
311 static int s_y_pending; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
312 static UINT s_kFlags_pending; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
313 static UINT s_wait_timer = 0; /* Timer for get char from user */ |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
314 static int s_timed_out = FALSE; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
315 static int dead_key = 0; /* 0: no dead key, 1: dead key pressed */ |
7 | 316 |
317 #ifdef WIN3264 | |
318 static OSVERSIONINFO os_version; /* like it says. Init in gui_mch_init() */ | |
319 #endif | |
320 | |
321 #ifdef FEAT_BEVAL | |
322 /* balloon-eval WM_NOTIFY_HANDLER */ | |
7801
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7780
diff
changeset
|
323 static void Handle_WM_Notify(HWND hwnd, LPNMHDR pnmh); |
a1e71a01dbd6
commit https://github.com/vim/vim/commit/d25c16e2f2776d50245bf31d6e4d5364f12d188e
Christian Brabandt <cb@256bit.org>
parents:
7780
diff
changeset
|
324 static void TrackUserActivity(UINT uMsg); |
7 | 325 #endif |
326 | |
327 /* | |
328 * For control IME. | |
4055 | 329 * |
330 * These LOGFONT used for IME. | |
7 | 331 */ |
332 #ifdef FEAT_MBYTE | |
333 # ifdef USE_IM_CONTROL | |
4055 | 334 /* holds LOGFONT for 'guifontwide' if available, otherwise 'guifont' */ |
7 | 335 static LOGFONT norm_logfont; |
4055 | 336 /* holds LOGFONT for 'guifont' always. */ |
337 static LOGFONT sub_logfont; | |
7 | 338 # endif |
339 #endif | |
340 | |
341 #ifdef FEAT_MBYTE_IME | |
342 static LRESULT _OnImeNotify(HWND hWnd, DWORD dwCommand, DWORD dwData); | |
343 #endif | |
344 | |
3275 | 345 #if defined(FEAT_MBYTE) && defined(WIN3264) |
346 static char_u *convert_filter(char_u *s); | |
347 #endif | |
348 | |
323 | 349 #ifdef DEBUG_PRINT_ERROR |
7 | 350 /* |
351 * Print out the last Windows error message | |
352 */ | |
353 static void | |
354 print_windows_error(void) | |
355 { | |
356 LPVOID lpMsgBuf; | |
357 | |
358 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, | |
359 NULL, GetLastError(), | |
360 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
361 (LPTSTR) &lpMsgBuf, 0, NULL); | |
362 TRACE1("Error: %s\n", lpMsgBuf); | |
363 LocalFree(lpMsgBuf); | |
364 } | |
323 | 365 #endif |
7 | 366 |
367 /* | |
368 * Cursor blink functions. | |
369 * | |
370 * This is a simple state machine: | |
371 * BLINK_NONE not blinking at all | |
372 * BLINK_OFF blinking, cursor is not shown | |
373 * BLINK_ON blinking, cursor is shown | |
374 */ | |
375 | |
376 #define BLINK_NONE 0 | |
377 #define BLINK_OFF 1 | |
378 #define BLINK_ON 2 | |
379 | |
380 static int blink_state = BLINK_NONE; | |
381 static long_u blink_waittime = 700; | |
382 static long_u blink_ontime = 400; | |
383 static long_u blink_offtime = 250; | |
384 static UINT blink_timer = 0; | |
385 | |
386 void | |
387 gui_mch_set_blinking(long wait, long on, long off) | |
388 { | |
389 blink_waittime = wait; | |
390 blink_ontime = on; | |
391 blink_offtime = off; | |
392 } | |
393 | |
394 /* ARGSUSED */ | |
395 static VOID CALLBACK | |
396 _OnBlinkTimer( | |
397 HWND hwnd, | |
398 UINT uMsg, | |
399 UINT idEvent, | |
400 DWORD dwTime) | |
401 { | |
402 MSG msg; | |
403 | |
404 /* | |
405 TRACE2("Got timer event, id %d, blink_timer %d\n", idEvent, blink_timer); | |
406 */ | |
407 | |
408 KillTimer(NULL, idEvent); | |
409 | |
410 /* Eat spurious WM_TIMER messages */ | |
3010 | 411 while (pPeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)) |
7 | 412 ; |
413 | |
414 if (blink_state == BLINK_ON) | |
415 { | |
416 gui_undraw_cursor(); | |
417 blink_state = BLINK_OFF; | |
418 blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_offtime, | |
419 (TIMERPROC)_OnBlinkTimer); | |
420 } | |
421 else | |
422 { | |
423 gui_update_cursor(TRUE, FALSE); | |
424 blink_state = BLINK_ON; | |
425 blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime, | |
426 (TIMERPROC)_OnBlinkTimer); | |
427 } | |
428 } | |
429 | |
430 static void | |
431 gui_mswin_rm_blink_timer(void) | |
432 { | |
433 MSG msg; | |
434 | |
435 if (blink_timer != 0) | |
436 { | |
437 KillTimer(NULL, blink_timer); | |
438 /* Eat spurious WM_TIMER messages */ | |
3010 | 439 while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)) |
7 | 440 ; |
441 blink_timer = 0; | |
442 } | |
443 } | |
444 | |
445 /* | |
446 * Stop the cursor blinking. Show the cursor if it wasn't shown. | |
447 */ | |
448 void | |
449 gui_mch_stop_blink(void) | |
450 { | |
451 gui_mswin_rm_blink_timer(); | |
452 if (blink_state == BLINK_OFF) | |
453 gui_update_cursor(TRUE, FALSE); | |
454 blink_state = BLINK_NONE; | |
455 } | |
456 | |
457 /* | |
458 * Start the cursor blinking. If it was already blinking, this restarts the | |
459 * waiting time and shows the cursor. | |
460 */ | |
461 void | |
462 gui_mch_start_blink(void) | |
463 { | |
464 gui_mswin_rm_blink_timer(); | |
465 | |
466 /* Only switch blinking on if none of the times is zero */ | |
467 if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus) | |
468 { | |
469 blink_timer = (UINT)SetTimer(NULL, 0, (UINT)blink_waittime, | |
470 (TIMERPROC)_OnBlinkTimer); | |
471 blink_state = BLINK_ON; | |
472 gui_update_cursor(TRUE, FALSE); | |
473 } | |
474 } | |
475 | |
476 /* | |
477 * Call-back routines. | |
478 */ | |
479 | |
323 | 480 /*ARGSUSED*/ |
7 | 481 static VOID CALLBACK |
482 _OnTimer( | |
483 HWND hwnd, | |
484 UINT uMsg, | |
485 UINT idEvent, | |
486 DWORD dwTime) | |
487 { | |
488 MSG msg; | |
489 | |
490 /* | |
491 TRACE2("Got timer event, id %d, s_wait_timer %d\n", idEvent, s_wait_timer); | |
492 */ | |
493 KillTimer(NULL, idEvent); | |
494 s_timed_out = TRUE; | |
495 | |
496 /* Eat spurious WM_TIMER messages */ | |
3010 | 497 while (pPeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)) |
7 | 498 ; |
499 if (idEvent == s_wait_timer) | |
500 s_wait_timer = 0; | |
501 } | |
502 | |
323 | 503 /*ARGSUSED*/ |
7 | 504 static void |
505 _OnDeadChar( | |
506 HWND hwnd, | |
507 UINT ch, | |
508 int cRepeat) | |
509 { | |
510 dead_key = 1; | |
511 } | |
512 | |
513 /* | |
514 * Convert Unicode character "ch" to bytes in "string[slen]". | |
1443 | 515 * When "had_alt" is TRUE the ALT key was included in "ch". |
7 | 516 * Return the length. |
517 */ | |
518 static int | |
1443 | 519 char_to_string(int ch, char_u *string, int slen, int had_alt) |
7 | 520 { |
521 int len; | |
522 int i; | |
523 #ifdef FEAT_MBYTE | |
524 WCHAR wstring[2]; | |
525 char_u *ws = NULL;; | |
526 | |
36 | 527 if (os_version.dwPlatformId != VER_PLATFORM_WIN32_NT) |
528 { | |
529 /* On Windows 95/98 we apparently get the character in the active | |
530 * codepage, not in UCS-2. If conversion is needed convert it to | |
531 * UCS-2 first. */ | |
532 if ((int)GetACP() == enc_codepage) | |
533 len = 0; /* no conversion required */ | |
534 else | |
535 { | |
536 string[0] = ch; | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
537 len = MultiByteToWideChar(GetACP(), 0, (LPCSTR)string, |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
538 1, wstring, 2); |
36 | 539 } |
540 } | |
7 | 541 else |
542 { | |
36 | 543 wstring[0] = ch; |
7 | 544 len = 1; |
36 | 545 } |
546 | |
547 if (len > 0) | |
548 { | |
549 /* "ch" is a UTF-16 character. Convert it to a string of bytes. When | |
550 * "enc_codepage" is non-zero use the standard Win32 function, | |
551 * otherwise use our own conversion function (e.g., for UTF-8). */ | |
552 if (enc_codepage > 0) | |
1443 | 553 { |
36 | 554 len = WideCharToMultiByte(enc_codepage, 0, wstring, len, |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
555 (LPSTR)string, slen, 0, NULL); |
1443 | 556 /* If we had included the ALT key into the character but now the |
557 * upper bit is no longer set, that probably means the conversion | |
558 * failed. Convert the original character and set the upper bit | |
559 * afterwards. */ | |
560 if (had_alt && len == 1 && ch >= 0x80 && string[0] < 0x80) | |
561 { | |
562 wstring[0] = ch & 0x7f; | |
563 len = WideCharToMultiByte(enc_codepage, 0, wstring, len, | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
564 (LPSTR)string, slen, 0, NULL); |
1443 | 565 if (len == 1) /* safety check */ |
566 string[0] |= 0x80; | |
567 } | |
568 } | |
7 | 569 else |
570 { | |
36 | 571 len = 1; |
1752 | 572 ws = utf16_to_enc(wstring, &len); |
36 | 573 if (ws == NULL) |
574 len = 0; | |
575 else | |
576 { | |
577 if (len > slen) /* just in case */ | |
578 len = slen; | |
579 mch_memmove(string, ws, len); | |
580 vim_free(ws); | |
581 } | |
7 | 582 } |
583 } | |
36 | 584 |
7 | 585 if (len == 0) |
586 #endif | |
587 { | |
588 string[0] = ch; | |
589 len = 1; | |
590 } | |
591 | |
592 for (i = 0; i < len; ++i) | |
593 if (string[i] == CSI && len <= slen - 2) | |
594 { | |
595 /* Insert CSI as K_CSI. */ | |
596 mch_memmove(string + i + 3, string + i + 1, len - i - 1); | |
597 string[++i] = KS_EXTRA; | |
598 string[++i] = (int)KE_CSI; | |
599 len += 2; | |
600 } | |
601 | |
602 return len; | |
603 } | |
604 | |
605 /* | |
606 * Key hit, add it to the input buffer. | |
607 */ | |
323 | 608 /*ARGSUSED*/ |
7 | 609 static void |
610 _OnChar( | |
611 HWND hwnd, | |
612 UINT ch, | |
613 int cRepeat) | |
614 { | |
615 char_u string[40]; | |
616 int len = 0; | |
617 | |
6151 | 618 dead_key = 0; |
619 | |
1443 | 620 len = char_to_string(ch, string, 40, FALSE); |
7 | 621 if (len == 1 && string[0] == Ctrl_C && ctrl_c_interrupts) |
622 { | |
623 trash_input_buf(); | |
624 got_int = TRUE; | |
625 } | |
626 | |
627 add_to_input_buf(string, len); | |
628 } | |
629 | |
630 /* | |
631 * Alt-Key hit, add it to the input buffer. | |
632 */ | |
323 | 633 /*ARGSUSED*/ |
7 | 634 static void |
635 _OnSysChar( | |
636 HWND hwnd, | |
637 UINT cch, | |
638 int cRepeat) | |
639 { | |
640 char_u string[40]; /* Enough for multibyte character */ | |
641 int len; | |
642 int modifiers; | |
643 int ch = cch; /* special keys are negative */ | |
644 | |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
645 dead_key = 0; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
646 |
7 | 647 /* TRACE("OnSysChar(%d, %c)\n", ch, ch); */ |
648 | |
649 /* OK, we have a character key (given by ch) which was entered with the | |
650 * ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note | |
651 * that the system distinguishes Alt-a and Alt-A (Alt-Shift-a unless | |
652 * CAPSLOCK is pressed) at this point. | |
653 */ | |
654 modifiers = MOD_MASK_ALT; | |
655 if (GetKeyState(VK_SHIFT) & 0x8000) | |
656 modifiers |= MOD_MASK_SHIFT; | |
657 if (GetKeyState(VK_CONTROL) & 0x8000) | |
658 modifiers |= MOD_MASK_CTRL; | |
659 | |
660 ch = simplify_key(ch, &modifiers); | |
661 /* remove the SHIFT modifier for keys where it's already included, e.g., | |
662 * '(' and '*' */ | |
663 if (ch < 0x100 && !isalpha(ch) && isprint(ch)) | |
664 modifiers &= ~MOD_MASK_SHIFT; | |
665 | |
666 /* Interpret the ALT key as making the key META, include SHIFT, etc. */ | |
667 ch = extract_modifiers(ch, &modifiers); | |
668 if (ch == CSI) | |
669 ch = K_CSI; | |
670 | |
671 len = 0; | |
672 if (modifiers) | |
673 { | |
674 string[len++] = CSI; | |
675 string[len++] = KS_MODIFIER; | |
676 string[len++] = modifiers; | |
677 } | |
678 | |
679 if (IS_SPECIAL((int)ch)) | |
680 { | |
681 string[len++] = CSI; | |
682 string[len++] = K_SECOND((int)ch); | |
683 string[len++] = K_THIRD((int)ch); | |
684 } | |
685 else | |
686 { | |
687 /* Although the documentation isn't clear about it, we assume "ch" is | |
688 * a Unicode character. */ | |
1443 | 689 len += char_to_string(ch, string + len, 40 - len, TRUE); |
7 | 690 } |
691 | |
692 add_to_input_buf(string, len); | |
693 } | |
694 | |
695 static void | |
696 _OnMouseEvent( | |
697 int button, | |
698 int x, | |
699 int y, | |
700 int repeated_click, | |
701 UINT keyFlags) | |
702 { | |
703 int vim_modifiers = 0x0; | |
704 | |
1453 | 705 s_getting_focus = FALSE; |
706 | |
7 | 707 if (keyFlags & MK_SHIFT) |
708 vim_modifiers |= MOUSE_SHIFT; | |
709 if (keyFlags & MK_CONTROL) | |
710 vim_modifiers |= MOUSE_CTRL; | |
711 if (GetKeyState(VK_MENU) & 0x8000) | |
712 vim_modifiers |= MOUSE_ALT; | |
713 | |
714 gui_send_mouse_event(button, x, y, repeated_click, vim_modifiers); | |
715 } | |
716 | |
323 | 717 /*ARGSUSED*/ |
7 | 718 static void |
719 _OnMouseButtonDown( | |
720 HWND hwnd, | |
721 BOOL fDoubleClick, | |
722 int x, | |
723 int y, | |
724 UINT keyFlags) | |
725 { | |
726 static LONG s_prevTime = 0; | |
727 | |
728 LONG currentTime = GetMessageTime(); | |
729 int button = -1; | |
730 int repeated_click; | |
731 | |
732 /* Give main window the focus: this is so the cursor isn't hollow. */ | |
733 (void)SetFocus(s_hwnd); | |
734 | |
735 if (s_uMsg == WM_LBUTTONDOWN || s_uMsg == WM_LBUTTONDBLCLK) | |
736 button = MOUSE_LEFT; | |
737 else if (s_uMsg == WM_MBUTTONDOWN || s_uMsg == WM_MBUTTONDBLCLK) | |
738 button = MOUSE_MIDDLE; | |
739 else if (s_uMsg == WM_RBUTTONDOWN || s_uMsg == WM_RBUTTONDBLCLK) | |
740 button = MOUSE_RIGHT; | |
741 #ifndef WIN16 /*<VN>*/ | |
742 else if (s_uMsg == WM_XBUTTONDOWN || s_uMsg == WM_XBUTTONDBLCLK) | |
743 { | |
744 #ifndef GET_XBUTTON_WPARAM | |
745 # define GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam)) | |
746 #endif | |
747 button = ((GET_XBUTTON_WPARAM(s_wParam) == 1) ? MOUSE_X1 : MOUSE_X2); | |
748 } | |
749 else if (s_uMsg == WM_CAPTURECHANGED) | |
750 { | |
751 /* on W95/NT4, somehow you get in here with an odd Msg | |
752 * if you press one button while holding down the other..*/ | |
753 if (s_button_pending == MOUSE_LEFT) | |
754 button = MOUSE_RIGHT; | |
755 else | |
756 button = MOUSE_LEFT; | |
757 } | |
758 #endif | |
759 if (button >= 0) | |
760 { | |
761 repeated_click = ((int)(currentTime - s_prevTime) < p_mouset); | |
762 | |
763 /* | |
764 * Holding down the left and right buttons simulates pushing the middle | |
765 * button. | |
766 */ | |
36 | 767 if (repeated_click |
768 && ((button == MOUSE_LEFT && s_button_pending == MOUSE_RIGHT) | |
769 || (button == MOUSE_RIGHT | |
770 && s_button_pending == MOUSE_LEFT))) | |
7 | 771 { |
772 /* | |
773 * Hmm, gui.c will ignore more than one button down at a time, so | |
774 * pretend we let go of it first. | |
775 */ | |
776 gui_send_mouse_event(MOUSE_RELEASE, x, y, FALSE, 0x0); | |
777 button = MOUSE_MIDDLE; | |
778 repeated_click = FALSE; | |
779 s_button_pending = -1; | |
780 _OnMouseEvent(button, x, y, repeated_click, keyFlags); | |
781 } | |
782 else if ((repeated_click) | |
783 || (mouse_model_popup() && (button == MOUSE_RIGHT))) | |
784 { | |
785 if (s_button_pending > -1) | |
786 { | |
787 _OnMouseEvent(s_button_pending, x, y, FALSE, keyFlags); | |
788 s_button_pending = -1; | |
789 } | |
790 /* TRACE("Button down at x %d, y %d\n", x, y); */ | |
791 _OnMouseEvent(button, x, y, repeated_click, keyFlags); | |
792 } | |
793 else | |
794 { | |
795 /* | |
796 * If this is the first press (i.e. not a multiple click) don't | |
797 * action immediately, but store and wait for: | |
798 * i) button-up | |
799 * ii) mouse move | |
800 * iii) another button press | |
801 * before using it. | |
802 * This enables us to make left+right simulate middle button, | |
803 * without left or right being actioned first. The side-effect is | |
804 * that if you click and hold the mouse without dragging, the | |
805 * cursor doesn't move until you release the button. In practice | |
806 * this is hardly a problem. | |
807 */ | |
808 s_button_pending = button; | |
809 s_x_pending = x; | |
810 s_y_pending = y; | |
811 s_kFlags_pending = keyFlags; | |
812 } | |
813 | |
814 s_prevTime = currentTime; | |
815 } | |
816 } | |
817 | |
323 | 818 /*ARGSUSED*/ |
7 | 819 static void |
820 _OnMouseMoveOrRelease( | |
821 HWND hwnd, | |
822 int x, | |
823 int y, | |
824 UINT keyFlags) | |
825 { | |
826 int button; | |
827 | |
1453 | 828 s_getting_focus = FALSE; |
7 | 829 if (s_button_pending > -1) |
830 { | |
831 /* Delayed action for mouse down event */ | |
832 _OnMouseEvent(s_button_pending, s_x_pending, | |
36 | 833 s_y_pending, FALSE, s_kFlags_pending); |
7 | 834 s_button_pending = -1; |
835 } | |
836 if (s_uMsg == WM_MOUSEMOVE) | |
837 { | |
838 /* | |
839 * It's only a MOUSE_DRAG if one or more mouse buttons are being held | |
840 * down. | |
841 */ | |
842 if (!(keyFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON | |
843 | MK_XBUTTON1 | MK_XBUTTON2))) | |
844 { | |
845 gui_mouse_moved(x, y); | |
846 return; | |
847 } | |
848 | |
849 /* | |
850 * While button is down, keep grabbing mouse move events when | |
851 * the mouse goes outside the window | |
852 */ | |
853 SetCapture(s_textArea); | |
854 button = MOUSE_DRAG; | |
855 /* TRACE(" move at x %d, y %d\n", x, y); */ | |
856 } | |
857 else | |
858 { | |
859 ReleaseCapture(); | |
860 button = MOUSE_RELEASE; | |
861 /* TRACE(" up at x %d, y %d\n", x, y); */ | |
862 } | |
863 | |
864 _OnMouseEvent(button, x, y, FALSE, keyFlags); | |
865 } | |
866 | |
867 #ifdef FEAT_MENU | |
868 /* | |
869 * Find the vimmenu_T with the given id | |
870 */ | |
871 static vimmenu_T * | |
872 gui_mswin_find_menu( | |
873 vimmenu_T *pMenu, | |
874 int id) | |
875 { | |
876 vimmenu_T *pChildMenu; | |
877 | |
878 while (pMenu) | |
879 { | |
880 if (pMenu->id == (UINT)id) | |
881 break; | |
882 if (pMenu->children != NULL) | |
883 { | |
884 pChildMenu = gui_mswin_find_menu(pMenu->children, id); | |
885 if (pChildMenu) | |
886 { | |
887 pMenu = pChildMenu; | |
888 break; | |
889 } | |
890 } | |
891 pMenu = pMenu->next; | |
892 } | |
893 return pMenu; | |
894 } | |
895 | |
323 | 896 /*ARGSUSED*/ |
7 | 897 static void |
898 _OnMenu( | |
899 HWND hwnd, | |
900 int id, | |
901 HWND hwndCtl, | |
902 UINT codeNotify) | |
903 { | |
904 vimmenu_T *pMenu; | |
905 | |
906 pMenu = gui_mswin_find_menu(root_menu, id); | |
907 if (pMenu) | |
908 gui_menu_cb(pMenu); | |
909 } | |
910 #endif | |
911 | |
912 #ifdef MSWIN_FIND_REPLACE | |
1795 | 913 # if defined(FEAT_MBYTE) && defined(WIN3264) |
914 /* | |
915 * copy useful data from structure LPFINDREPLACE to structure LPFINDREPLACEW | |
916 */ | |
917 static void | |
918 findrep_atow(LPFINDREPLACEW lpfrw, LPFINDREPLACE lpfr) | |
919 { | |
920 WCHAR *wp; | |
921 | |
922 lpfrw->hwndOwner = lpfr->hwndOwner; | |
923 lpfrw->Flags = lpfr->Flags; | |
924 | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
925 wp = enc_to_utf16((char_u *)lpfr->lpstrFindWhat, NULL); |
1795 | 926 wcsncpy(lpfrw->lpstrFindWhat, wp, lpfrw->wFindWhatLen - 1); |
927 vim_free(wp); | |
928 | |
929 /* the field "lpstrReplaceWith" doesn't need to be copied */ | |
930 } | |
931 | |
932 /* | |
933 * copy useful data from structure LPFINDREPLACEW to structure LPFINDREPLACE | |
934 */ | |
935 static void | |
936 findrep_wtoa(LPFINDREPLACE lpfr, LPFINDREPLACEW lpfrw) | |
937 { | |
938 char_u *p; | |
939 | |
940 lpfr->Flags = lpfrw->Flags; | |
941 | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
942 p = utf16_to_enc((short_u*)lpfrw->lpstrFindWhat, NULL); |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
943 vim_strncpy((char_u *)lpfr->lpstrFindWhat, p, lpfr->wFindWhatLen - 1); |
1795 | 944 vim_free(p); |
945 | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
946 p = utf16_to_enc((short_u*)lpfrw->lpstrReplaceWith, NULL); |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
947 vim_strncpy((char_u *)lpfr->lpstrReplaceWith, p, lpfr->wReplaceWithLen - 1); |
1795 | 948 vim_free(p); |
949 } | |
950 # endif | |
951 | |
7 | 952 /* |
953 * Handle a Find/Replace window message. | |
954 */ | |
955 static void | |
956 _OnFindRepl(void) | |
957 { | |
958 int flags = 0; | |
959 int down; | |
960 | |
1795 | 961 # if defined(FEAT_MBYTE) && defined(WIN3264) |
962 /* If the OS is Windows NT, and 'encoding' differs from active codepage: | |
963 * convert text from wide string. */ | |
964 if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT | |
965 && enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
966 { | |
2311
ccda151dde4e
Support completion for ":find". (Nazri Ramliy)
Bram Moolenaar <bram@vim.org>
parents:
2215
diff
changeset
|
967 findrep_wtoa(&s_findrep_struct, &s_findrep_struct_w); |
1795 | 968 } |
969 # endif | |
970 | |
7 | 971 if (s_findrep_struct.Flags & FR_DIALOGTERM) |
972 /* Give main window the focus back. */ | |
973 (void)SetFocus(s_hwnd); | |
974 | |
975 if (s_findrep_struct.Flags & FR_FINDNEXT) | |
976 { | |
977 flags = FRD_FINDNEXT; | |
978 | |
979 /* Give main window the focus back: this is so the cursor isn't | |
980 * hollow. */ | |
981 (void)SetFocus(s_hwnd); | |
982 } | |
983 else if (s_findrep_struct.Flags & FR_REPLACE) | |
984 { | |
985 flags = FRD_REPLACE; | |
986 | |
987 /* Give main window the focus back: this is so the cursor isn't | |
988 * hollow. */ | |
989 (void)SetFocus(s_hwnd); | |
990 } | |
991 else if (s_findrep_struct.Flags & FR_REPLACEALL) | |
992 { | |
993 flags = FRD_REPLACEALL; | |
994 } | |
995 | |
996 if (flags != 0) | |
997 { | |
998 /* Call the generic GUI function to do the actual work. */ | |
999 if (s_findrep_struct.Flags & FR_WHOLEWORD) | |
1000 flags |= FRD_WHOLE_WORD; | |
1001 if (s_findrep_struct.Flags & FR_MATCHCASE) | |
1002 flags |= FRD_MATCH_CASE; | |
1003 down = (s_findrep_struct.Flags & FR_DOWN) != 0; | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
1004 gui_do_findrepl(flags, (char_u *)s_findrep_struct.lpstrFindWhat, |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
1005 (char_u *)s_findrep_struct.lpstrReplaceWith, down); |
7 | 1006 } |
1007 } | |
1008 #endif | |
1009 | |
1010 static void | |
1011 HandleMouseHide(UINT uMsg, LPARAM lParam) | |
1012 { | |
1013 static LPARAM last_lParam = 0L; | |
1014 | |
1015 /* We sometimes get a mousemove when the mouse didn't move... */ | |
5367 | 1016 if (uMsg == WM_MOUSEMOVE || uMsg == WM_NCMOUSEMOVE) |
7 | 1017 { |
1018 if (lParam == last_lParam) | |
1019 return; | |
1020 last_lParam = lParam; | |
1021 } | |
1022 | |
1023 /* Handle specially, to centralise coding. We need to be sure we catch all | |
1024 * possible events which should cause us to restore the cursor (as it is a | |
1025 * shared resource, we take full responsibility for it). | |
1026 */ | |
1027 switch (uMsg) | |
1028 { | |
1029 case WM_KEYUP: | |
1030 case WM_CHAR: | |
1031 /* | |
1032 * blank out the pointer if necessary | |
1033 */ | |
1034 if (p_mh) | |
1035 gui_mch_mousehide(TRUE); | |
1036 break; | |
1037 | |
1038 case WM_SYSKEYUP: /* show the pointer when a system-key is pressed */ | |
1039 case WM_SYSCHAR: | |
1040 case WM_MOUSEMOVE: /* show the pointer on any mouse action */ | |
1041 case WM_LBUTTONDOWN: | |
1042 case WM_LBUTTONUP: | |
1043 case WM_MBUTTONDOWN: | |
1044 case WM_MBUTTONUP: | |
1045 case WM_RBUTTONDOWN: | |
1046 case WM_RBUTTONUP: | |
1047 case WM_XBUTTONDOWN: | |
1048 case WM_XBUTTONUP: | |
1049 case WM_NCMOUSEMOVE: | |
1050 case WM_NCLBUTTONDOWN: | |
1051 case WM_NCLBUTTONUP: | |
1052 case WM_NCMBUTTONDOWN: | |
1053 case WM_NCMBUTTONUP: | |
1054 case WM_NCRBUTTONDOWN: | |
1055 case WM_NCRBUTTONUP: | |
1056 case WM_KILLFOCUS: | |
1057 /* | |
1058 * if the pointer is currently hidden, then we should show it. | |
1059 */ | |
1060 gui_mch_mousehide(FALSE); | |
1061 break; | |
1062 } | |
1063 } | |
1064 | |
1065 static LRESULT CALLBACK | |
1066 _TextAreaWndProc( | |
1067 HWND hwnd, | |
1068 UINT uMsg, | |
1069 WPARAM wParam, | |
1070 LPARAM lParam) | |
1071 { | |
1072 /* | |
1073 TRACE("TextAreaWndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n", | |
1074 hwnd, uMsg, wParam, lParam); | |
1075 */ | |
1076 | |
1077 HandleMouseHide(uMsg, lParam); | |
1078 | |
1079 s_uMsg = uMsg; | |
1080 s_wParam = wParam; | |
1081 s_lParam = lParam; | |
1082 | |
1083 #ifdef FEAT_BEVAL | |
1084 TrackUserActivity(uMsg); | |
1085 #endif | |
1086 | |
1087 switch (uMsg) | |
1088 { | |
1089 HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK,_OnMouseButtonDown); | |
1090 HANDLE_MSG(hwnd, WM_LBUTTONDOWN,_OnMouseButtonDown); | |
1091 HANDLE_MSG(hwnd, WM_LBUTTONUP, _OnMouseMoveOrRelease); | |
1092 HANDLE_MSG(hwnd, WM_MBUTTONDBLCLK,_OnMouseButtonDown); | |
1093 HANDLE_MSG(hwnd, WM_MBUTTONDOWN,_OnMouseButtonDown); | |
1094 HANDLE_MSG(hwnd, WM_MBUTTONUP, _OnMouseMoveOrRelease); | |
1095 HANDLE_MSG(hwnd, WM_MOUSEMOVE, _OnMouseMoveOrRelease); | |
1096 HANDLE_MSG(hwnd, WM_PAINT, _OnPaint); | |
1097 HANDLE_MSG(hwnd, WM_RBUTTONDBLCLK,_OnMouseButtonDown); | |
1098 HANDLE_MSG(hwnd, WM_RBUTTONDOWN,_OnMouseButtonDown); | |
1099 HANDLE_MSG(hwnd, WM_RBUTTONUP, _OnMouseMoveOrRelease); | |
1100 #ifndef WIN16 /*<VN>*/ | |
1101 HANDLE_MSG(hwnd, WM_XBUTTONDBLCLK,_OnMouseButtonDown); | |
1102 HANDLE_MSG(hwnd, WM_XBUTTONDOWN,_OnMouseButtonDown); | |
1103 HANDLE_MSG(hwnd, WM_XBUTTONUP, _OnMouseMoveOrRelease); | |
1104 #endif | |
1105 | |
1106 #ifdef FEAT_BEVAL | |
1107 case WM_NOTIFY: Handle_WM_Notify(hwnd, (LPNMHDR)lParam); | |
1108 return TRUE; | |
1109 #endif | |
2067
8e2d14a3e7d2
updated for version 7.2.352
Bram Moolenaar <bram@zimbu.org>
parents:
1795
diff
changeset
|
1110 default: |
8e2d14a3e7d2
updated for version 7.2.352
Bram Moolenaar <bram@zimbu.org>
parents:
1795
diff
changeset
|
1111 return MyWindowProc(hwnd, uMsg, wParam, lParam); |
7 | 1112 } |
1113 } | |
1114 | |
1115 #if (defined(WIN3264) && defined(FEAT_MBYTE)) \ | |
1116 || defined(GLOBAL_IME) \ | |
1117 || defined(PROTO) | |
1118 # ifdef PROTO | |
1119 typedef int WINAPI; | |
1120 # endif | |
1121 | |
1122 LRESULT WINAPI | |
1123 vim_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) | |
1124 { | |
1125 # ifdef GLOBAL_IME | |
1126 return global_ime_DefWindowProc(hwnd, message, wParam, lParam); | |
1127 # else | |
1128 if (wide_WindowProc) | |
1129 return DefWindowProcW(hwnd, message, wParam, lParam); | |
1130 return DefWindowProc(hwnd, message, wParam, lParam); | |
1131 #endif | |
1132 } | |
1133 #endif | |
1134 | |
1135 /* | |
1136 * Called when the foreground or background color has been changed. | |
1137 */ | |
1138 void | |
1139 gui_mch_new_colors(void) | |
1140 { | |
1141 /* nothing to do? */ | |
1142 } | |
1143 | |
1144 /* | |
1145 * Set the colors to their default values. | |
1146 */ | |
1147 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1148 gui_mch_def_colors(void) |
7 | 1149 { |
1150 gui.norm_pixel = GetSysColor(COLOR_WINDOWTEXT); | |
1151 gui.back_pixel = GetSysColor(COLOR_WINDOW); | |
1152 gui.def_norm_pixel = gui.norm_pixel; | |
1153 gui.def_back_pixel = gui.back_pixel; | |
1154 } | |
1155 | |
1156 /* | |
1157 * Open the GUI window which was created by a call to gui_mch_init(). | |
1158 */ | |
1159 int | |
1160 gui_mch_open(void) | |
1161 { | |
1162 #ifndef SW_SHOWDEFAULT | |
1163 # define SW_SHOWDEFAULT 10 /* Borland 5.0 doesn't have it */ | |
1164 #endif | |
1165 /* Actually open the window, if not already visible | |
1166 * (may be done already in gui_mch_set_shellsize) */ | |
1167 if (!IsWindowVisible(s_hwnd)) | |
1168 ShowWindow(s_hwnd, SW_SHOWDEFAULT); | |
1169 | |
818 | 1170 #ifdef MSWIN_FIND_REPLACE |
1171 /* Init replace string here, so that we keep it when re-opening the | |
1172 * dialog. */ | |
1173 s_findrep_struct.lpstrReplaceWith[0] = NUL; | |
1174 #endif | |
1175 | |
7 | 1176 return OK; |
1177 } | |
1178 | |
1179 /* | |
1180 * Get the position of the top left corner of the window. | |
1181 */ | |
1182 int | |
1183 gui_mch_get_winpos(int *x, int *y) | |
1184 { | |
1185 RECT rect; | |
1186 | |
1187 GetWindowRect(s_hwnd, &rect); | |
1188 *x = rect.left; | |
1189 *y = rect.top; | |
1190 return OK; | |
1191 } | |
1192 | |
1193 /* | |
1194 * Set the position of the top left corner of the window to the given | |
1195 * coordinates. | |
1196 */ | |
1197 void | |
1198 gui_mch_set_winpos(int x, int y) | |
1199 { | |
1200 SetWindowPos(s_hwnd, NULL, x, y, 0, 0, | |
1201 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); | |
1202 } | |
1203 void | |
1204 gui_mch_set_text_area_pos(int x, int y, int w, int h) | |
1205 { | |
1206 static int oldx = 0; | |
1207 static int oldy = 0; | |
1208 | |
1209 SetWindowPos(s_textArea, NULL, x, y, w, h, SWP_NOZORDER | SWP_NOACTIVATE); | |
1210 | |
1211 #ifdef FEAT_TOOLBAR | |
1212 if (vim_strchr(p_go, GO_TOOLBAR) != NULL) | |
1213 SendMessage(s_toolbarhwnd, WM_SIZE, | |
822 | 1214 (WPARAM)0, (LPARAM)(w + ((long)(TOOLBAR_BUTTON_HEIGHT+8)<<16))); |
7 | 1215 #endif |
810 | 1216 #if defined(FEAT_GUI_TABLINE) |
1217 if (showing_tabline) | |
1218 { | |
811 | 1219 int top = 0; |
824 | 1220 RECT rect; |
810 | 1221 |
843 | 1222 # ifdef FEAT_TOOLBAR |
810 | 1223 if (vim_strchr(p_go, GO_TOOLBAR) != NULL) |
1224 top = TOOLBAR_BUTTON_HEIGHT + TOOLBAR_BORDER_HEIGHT; | |
843 | 1225 # endif |
822 | 1226 GetClientRect(s_hwnd, &rect); |
843 | 1227 MoveWindow(s_tabhwnd, 0, top, rect.right, gui.tabline_height, TRUE); |
810 | 1228 } |
1229 #endif | |
1230 | |
7 | 1231 /* When side scroll bar is unshown, the size of window will change. |
1232 * then, the text area move left or right. thus client rect should be | |
4352 | 1233 * forcedly redrawn. (Yasuhiro Matsumoto) */ |
7 | 1234 if (oldx != x || oldy != y) |
1235 { | |
1236 InvalidateRect(s_hwnd, NULL, FALSE); | |
1237 oldx = x; | |
1238 oldy = y; | |
1239 } | |
1240 } | |
1241 | |
1242 | |
1243 /* | |
1244 * Scrollbar stuff: | |
1245 */ | |
1246 | |
1247 void | |
1248 gui_mch_enable_scrollbar( | |
1249 scrollbar_T *sb, | |
1250 int flag) | |
1251 { | |
1252 ShowScrollBar(sb->id, SB_CTL, flag); | |
1253 | |
1254 /* TODO: When the window is maximized, the size of the window stays the | |
1255 * same, thus the size of the text area changes. On Win98 it's OK, on Win | |
1256 * NT 4.0 it's not... */ | |
1257 } | |
1258 | |
1259 void | |
1260 gui_mch_set_scrollbar_pos( | |
1261 scrollbar_T *sb, | |
1262 int x, | |
1263 int y, | |
1264 int w, | |
1265 int h) | |
1266 { | |
444 | 1267 SetWindowPos(sb->id, NULL, x, y, w, h, |
1268 SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW); | |
7 | 1269 } |
1270 | |
1271 void | |
1272 gui_mch_create_scrollbar( | |
1273 scrollbar_T *sb, | |
1274 int orient) /* SBAR_VERT or SBAR_HORIZ */ | |
1275 { | |
1276 sb->id = CreateWindow( | |
1277 "SCROLLBAR", "Scrollbar", | |
1278 WS_CHILD | ((orient == SBAR_VERT) ? SBS_VERT : SBS_HORZ), 0, 0, | |
1279 10, /* Any value will do for now */ | |
1280 10, /* Any value will do for now */ | |
1281 s_hwnd, NULL, | |
1282 s_hinst, NULL); | |
1283 } | |
1284 | |
1285 /* | |
1286 * Find the scrollbar with the given hwnd. | |
1287 */ | |
1288 static scrollbar_T * | |
1289 gui_mswin_find_scrollbar(HWND hwnd) | |
1290 { | |
1291 win_T *wp; | |
1292 | |
1293 if (gui.bottom_sbar.id == hwnd) | |
1294 return &gui.bottom_sbar; | |
1295 FOR_ALL_WINDOWS(wp) | |
1296 { | |
1297 if (wp->w_scrollbars[SBAR_LEFT].id == hwnd) | |
1298 return &wp->w_scrollbars[SBAR_LEFT]; | |
1299 if (wp->w_scrollbars[SBAR_RIGHT].id == hwnd) | |
1300 return &wp->w_scrollbars[SBAR_RIGHT]; | |
1301 } | |
1302 return NULL; | |
1303 } | |
1304 | |
1305 /* | |
1306 * Get the character size of a font. | |
1307 */ | |
1308 static void | |
1309 GetFontSize(GuiFont font) | |
1310 { | |
1311 HWND hwnd = GetDesktopWindow(); | |
1312 HDC hdc = GetWindowDC(hwnd); | |
1313 HFONT hfntOld = SelectFont(hdc, (HFONT)font); | |
1314 TEXTMETRIC tm; | |
1315 | |
1316 GetTextMetrics(hdc, &tm); | |
1317 gui.char_width = tm.tmAveCharWidth + tm.tmOverhang; | |
1318 | |
1319 gui.char_height = tm.tmHeight | |
1320 #ifndef MSWIN16_FASTTEXT | |
444 | 1321 + p_linespace |
7 | 1322 #endif |
444 | 1323 ; |
7 | 1324 |
1325 SelectFont(hdc, hfntOld); | |
1326 | |
1327 ReleaseDC(hwnd, hdc); | |
1328 } | |
1329 | |
444 | 1330 /* |
1331 * Adjust gui.char_height (after 'linespace' was changed). | |
1332 */ | |
7 | 1333 int |
444 | 1334 gui_mch_adjust_charheight(void) |
7 | 1335 { |
1336 GetFontSize(gui.norm_font); | |
1337 return OK; | |
1338 } | |
1339 | |
1340 static GuiFont | |
1341 get_font_handle(LOGFONT *lf) | |
1342 { | |
1343 HFONT font = NULL; | |
1344 | |
1345 /* Load the font */ | |
1346 font = CreateFontIndirect(lf); | |
1347 | |
1348 if (font == NULL) | |
1349 return NOFONT; | |
1350 | |
1351 return (GuiFont)font; | |
1352 } | |
1353 | |
1354 static int | |
1355 pixels_to_points(int pixels, int vertical) | |
1356 { | |
1357 int points; | |
1358 HWND hwnd; | |
1359 HDC hdc; | |
1360 | |
1361 hwnd = GetDesktopWindow(); | |
1362 hdc = GetWindowDC(hwnd); | |
1363 | |
1364 points = MulDiv(pixels, 72, | |
1365 GetDeviceCaps(hdc, vertical ? LOGPIXELSY : LOGPIXELSX)); | |
1366 | |
1367 ReleaseDC(hwnd, hdc); | |
1368 | |
1369 return points; | |
1370 } | |
1371 | |
1372 GuiFont | |
1373 gui_mch_get_font( | |
1374 char_u *name, | |
1375 int giveErrorIfMissing) | |
1376 { | |
1377 LOGFONT lf; | |
37 | 1378 GuiFont font = NOFONT; |
1379 | |
1380 if (get_logfont(&lf, name, NULL, giveErrorIfMissing) == OK) | |
1381 font = get_font_handle(&lf); | |
7 | 1382 if (font == NOFONT && giveErrorIfMissing) |
1383 EMSG2(_(e_font), name); | |
1384 return font; | |
1385 } | |
37 | 1386 |
44 | 1387 #if defined(FEAT_EVAL) || defined(PROTO) |
37 | 1388 /* |
1389 * Return the name of font "font" in allocated memory. | |
1390 * Don't know how to get the actual name, thus use the provided name. | |
1391 */ | |
323 | 1392 /*ARGSUSED*/ |
37 | 1393 char_u * |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
1394 gui_mch_get_fontname(GuiFont font, char_u *name) |
37 | 1395 { |
1396 if (name == NULL) | |
1397 return NULL; | |
1398 return vim_strsave(name); | |
1399 } | |
44 | 1400 #endif |
37 | 1401 |
7 | 1402 void |
1403 gui_mch_free_font(GuiFont font) | |
1404 { | |
1405 if (font) | |
1406 DeleteObject((HFONT)font); | |
1407 } | |
1408 | |
1409 static int | |
1410 hex_digit(int c) | |
1411 { | |
1412 if (VIM_ISDIGIT(c)) | |
1413 return c - '0'; | |
1414 c = TOLOWER_ASC(c); | |
1415 if (c >= 'a' && c <= 'f') | |
1416 return c - 'a' + 10; | |
1417 return -1000; | |
1418 } | |
1419 /* | |
1420 * Return the Pixel value (color) for the given color name. | |
1421 * Return INVALCOLOR for error. | |
1422 */ | |
1423 guicolor_T | |
1424 gui_mch_get_color(char_u *name) | |
1425 { | |
1426 typedef struct guicolor_tTable | |
1427 { | |
1428 char *name; | |
1429 COLORREF color; | |
1430 } guicolor_tTable; | |
1431 | |
1432 static guicolor_tTable table[] = | |
1433 { | |
1434 {"Black", RGB(0x00, 0x00, 0x00)}, | |
3052 | 1435 {"DarkGray", RGB(0xA9, 0xA9, 0xA9)}, |
1436 {"DarkGrey", RGB(0xA9, 0xA9, 0xA9)}, | |
7 | 1437 {"Gray", RGB(0xC0, 0xC0, 0xC0)}, |
1438 {"Grey", RGB(0xC0, 0xC0, 0xC0)}, | |
3052 | 1439 {"LightGray", RGB(0xD3, 0xD3, 0xD3)}, |
1440 {"LightGrey", RGB(0xD3, 0xD3, 0xD3)}, | |
834 | 1441 {"Gray10", RGB(0x1A, 0x1A, 0x1A)}, |
1442 {"Grey10", RGB(0x1A, 0x1A, 0x1A)}, | |
1443 {"Gray20", RGB(0x33, 0x33, 0x33)}, | |
1444 {"Grey20", RGB(0x33, 0x33, 0x33)}, | |
1445 {"Gray30", RGB(0x4D, 0x4D, 0x4D)}, | |
1446 {"Grey30", RGB(0x4D, 0x4D, 0x4D)}, | |
1447 {"Gray40", RGB(0x66, 0x66, 0x66)}, | |
1448 {"Grey40", RGB(0x66, 0x66, 0x66)}, | |
1449 {"Gray50", RGB(0x7F, 0x7F, 0x7F)}, | |
1450 {"Grey50", RGB(0x7F, 0x7F, 0x7F)}, | |
1451 {"Gray60", RGB(0x99, 0x99, 0x99)}, | |
1452 {"Grey60", RGB(0x99, 0x99, 0x99)}, | |
1453 {"Gray70", RGB(0xB3, 0xB3, 0xB3)}, | |
1454 {"Grey70", RGB(0xB3, 0xB3, 0xB3)}, | |
1455 {"Gray80", RGB(0xCC, 0xCC, 0xCC)}, | |
1456 {"Grey80", RGB(0xCC, 0xCC, 0xCC)}, | |
818 | 1457 {"Gray90", RGB(0xE5, 0xE5, 0xE5)}, |
1458 {"Grey90", RGB(0xE5, 0xE5, 0xE5)}, | |
7 | 1459 {"White", RGB(0xFF, 0xFF, 0xFF)}, |
1460 {"DarkRed", RGB(0x80, 0x00, 0x00)}, | |
1461 {"Red", RGB(0xFF, 0x00, 0x00)}, | |
1462 {"LightRed", RGB(0xFF, 0xA0, 0xA0)}, | |
1463 {"DarkBlue", RGB(0x00, 0x00, 0x80)}, | |
1464 {"Blue", RGB(0x00, 0x00, 0xFF)}, | |
3052 | 1465 {"LightBlue", RGB(0xAD, 0xD8, 0xE6)}, |
7 | 1466 {"DarkGreen", RGB(0x00, 0x80, 0x00)}, |
1467 {"Green", RGB(0x00, 0xFF, 0x00)}, | |
3052 | 1468 {"LightGreen", RGB(0x90, 0xEE, 0x90)}, |
7 | 1469 {"DarkCyan", RGB(0x00, 0x80, 0x80)}, |
1470 {"Cyan", RGB(0x00, 0xFF, 0xFF)}, | |
3052 | 1471 {"LightCyan", RGB(0xE0, 0xFF, 0xFF)}, |
7 | 1472 {"DarkMagenta", RGB(0x80, 0x00, 0x80)}, |
1473 {"Magenta", RGB(0xFF, 0x00, 0xFF)}, | |
1474 {"LightMagenta", RGB(0xFF, 0xA0, 0xFF)}, | |
1475 {"Brown", RGB(0x80, 0x40, 0x40)}, | |
1476 {"Yellow", RGB(0xFF, 0xFF, 0x00)}, | |
3052 | 1477 {"LightYellow", RGB(0xFF, 0xFF, 0xE0)}, |
7 | 1478 {"DarkYellow", RGB(0xBB, 0xBB, 0x00)}, |
1479 {"SeaGreen", RGB(0x2E, 0x8B, 0x57)}, | |
1480 {"Orange", RGB(0xFF, 0xA5, 0x00)}, | |
1481 {"Purple", RGB(0xA0, 0x20, 0xF0)}, | |
1482 {"SlateBlue", RGB(0x6A, 0x5A, 0xCD)}, | |
1483 {"Violet", RGB(0xEE, 0x82, 0xEE)}, | |
1484 }; | |
1485 | |
1486 typedef struct SysColorTable | |
1487 { | |
1488 char *name; | |
1489 int color; | |
1490 } SysColorTable; | |
1491 | |
1492 static SysColorTable sys_table[] = | |
1493 { | |
1494 #ifdef WIN3264 | |
1495 {"SYS_3DDKSHADOW", COLOR_3DDKSHADOW}, | |
1496 {"SYS_3DHILIGHT", COLOR_3DHILIGHT}, | |
1497 #ifndef __MINGW32__ | |
1498 {"SYS_3DHIGHLIGHT", COLOR_3DHIGHLIGHT}, | |
1499 #endif | |
1500 {"SYS_BTNHILIGHT", COLOR_BTNHILIGHT}, | |
1501 {"SYS_BTNHIGHLIGHT", COLOR_BTNHIGHLIGHT}, | |
1502 {"SYS_3DLIGHT", COLOR_3DLIGHT}, | |
1503 {"SYS_3DSHADOW", COLOR_3DSHADOW}, | |
1504 {"SYS_DESKTOP", COLOR_DESKTOP}, | |
1505 {"SYS_INFOBK", COLOR_INFOBK}, | |
1506 {"SYS_INFOTEXT", COLOR_INFOTEXT}, | |
1507 {"SYS_3DFACE", COLOR_3DFACE}, | |
1508 #endif | |
1509 {"SYS_BTNFACE", COLOR_BTNFACE}, | |
1510 {"SYS_BTNSHADOW", COLOR_BTNSHADOW}, | |
1511 {"SYS_ACTIVEBORDER", COLOR_ACTIVEBORDER}, | |
1512 {"SYS_ACTIVECAPTION", COLOR_ACTIVECAPTION}, | |
1513 {"SYS_APPWORKSPACE", COLOR_APPWORKSPACE}, | |
1514 {"SYS_BACKGROUND", COLOR_BACKGROUND}, | |
1515 {"SYS_BTNTEXT", COLOR_BTNTEXT}, | |
1516 {"SYS_CAPTIONTEXT", COLOR_CAPTIONTEXT}, | |
1517 {"SYS_GRAYTEXT", COLOR_GRAYTEXT}, | |
1518 {"SYS_HIGHLIGHT", COLOR_HIGHLIGHT}, | |
1519 {"SYS_HIGHLIGHTTEXT", COLOR_HIGHLIGHTTEXT}, | |
1520 {"SYS_INACTIVEBORDER", COLOR_INACTIVEBORDER}, | |
1521 {"SYS_INACTIVECAPTION", COLOR_INACTIVECAPTION}, | |
1522 {"SYS_INACTIVECAPTIONTEXT", COLOR_INACTIVECAPTIONTEXT}, | |
1523 {"SYS_MENU", COLOR_MENU}, | |
1524 {"SYS_MENUTEXT", COLOR_MENUTEXT}, | |
1525 {"SYS_SCROLLBAR", COLOR_SCROLLBAR}, | |
1526 {"SYS_WINDOW", COLOR_WINDOW}, | |
1527 {"SYS_WINDOWFRAME", COLOR_WINDOWFRAME}, | |
1528 {"SYS_WINDOWTEXT", COLOR_WINDOWTEXT} | |
1529 }; | |
1530 | |
1531 int r, g, b; | |
1532 int i; | |
1533 | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
1534 if (name[0] == '#' && STRLEN(name) == 7) |
7 | 1535 { |
1536 /* Name is in "#rrggbb" format */ | |
1537 r = hex_digit(name[1]) * 16 + hex_digit(name[2]); | |
1538 g = hex_digit(name[3]) * 16 + hex_digit(name[4]); | |
1539 b = hex_digit(name[5]) * 16 + hex_digit(name[6]); | |
1540 if (r < 0 || g < 0 || b < 0) | |
1541 return INVALCOLOR; | |
1542 return RGB(r, g, b); | |
1543 } | |
1544 else | |
1545 { | |
1546 /* Check if the name is one of the colors we know */ | |
1547 for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) | |
1548 if (STRICMP(name, table[i].name) == 0) | |
1549 return table[i].color; | |
1550 } | |
1551 | |
1552 /* | |
1553 * Try to look up a system colour. | |
1554 */ | |
1555 for (i = 0; i < sizeof(sys_table) / sizeof(sys_table[0]); i++) | |
1556 if (STRICMP(name, sys_table[i].name) == 0) | |
1557 return GetSysColor(sys_table[i].color); | |
1558 | |
1559 /* | |
1560 * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt". | |
1561 */ | |
1562 { | |
1563 #define LINE_LEN 100 | |
1564 FILE *fd; | |
1565 char line[LINE_LEN]; | |
1566 char_u *fname; | |
1567 | |
1568 fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); | |
1569 if (fname == NULL) | |
1570 return INVALCOLOR; | |
1571 | |
822 | 1572 fd = mch_fopen((char *)fname, "rt"); |
7 | 1573 vim_free(fname); |
1574 if (fd == NULL) | |
1575 return INVALCOLOR; | |
1576 | |
1577 while (!feof(fd)) | |
1578 { | |
1579 int len; | |
1580 int pos; | |
1581 char *color; | |
1582 | |
1583 fgets(line, LINE_LEN, fd); | |
1584 len = (int)STRLEN(line); | |
1585 | |
1586 if (len <= 1 || line[len-1] != '\n') | |
1587 continue; | |
1588 | |
1589 line[len-1] = '\0'; | |
1590 | |
1591 i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); | |
1592 if (i != 3) | |
1593 continue; | |
1594 | |
1595 color = line + pos; | |
1596 | |
1597 if (STRICMP(color, name) == 0) | |
1598 { | |
1599 fclose(fd); | |
1600 return (guicolor_T) RGB(r, g, b); | |
1601 } | |
1602 } | |
1603 | |
1604 fclose(fd); | |
1605 } | |
1606 | |
1607 return INVALCOLOR; | |
1608 } | |
1609 /* | |
1610 * Return OK if the key with the termcap name "name" is supported. | |
1611 */ | |
1612 int | |
1613 gui_mch_haskey(char_u *name) | |
1614 { | |
1615 int i; | |
1616 | |
1617 for (i = 0; special_keys[i].vim_code1 != NUL; i++) | |
1618 if (name[0] == special_keys[i].vim_code0 && | |
1619 name[1] == special_keys[i].vim_code1) | |
1620 return OK; | |
1621 return FAIL; | |
1622 } | |
1623 | |
1624 void | |
1625 gui_mch_beep(void) | |
1626 { | |
1627 MessageBeep(MB_OK); | |
1628 } | |
1629 /* | |
1630 * Invert a rectangle from row r, column c, for nr rows and nc columns. | |
1631 */ | |
1632 void | |
1633 gui_mch_invert_rectangle( | |
1634 int r, | |
1635 int c, | |
1636 int nr, | |
1637 int nc) | |
1638 { | |
1639 RECT rc; | |
1640 | |
1641 /* | |
1642 * Note: InvertRect() excludes right and bottom of rectangle. | |
1643 */ | |
1644 rc.left = FILL_X(c); | |
1645 rc.top = FILL_Y(r); | |
1646 rc.right = rc.left + nc * gui.char_width; | |
1647 rc.bottom = rc.top + nr * gui.char_height; | |
1648 InvertRect(s_hdc, &rc); | |
1649 } | |
1650 | |
1651 /* | |
1652 * Iconify the GUI window. | |
1653 */ | |
1654 void | |
1655 gui_mch_iconify(void) | |
1656 { | |
1657 ShowWindow(s_hwnd, SW_MINIMIZE); | |
1658 } | |
1659 | |
1660 /* | |
1661 * Draw a cursor without focus. | |
1662 */ | |
1663 void | |
1664 gui_mch_draw_hollow_cursor(guicolor_T color) | |
1665 { | |
1666 HBRUSH hbr; | |
1667 RECT rc; | |
1668 | |
1669 /* | |
1670 * Note: FrameRect() excludes right and bottom of rectangle. | |
1671 */ | |
1672 rc.left = FILL_X(gui.col); | |
1673 rc.top = FILL_Y(gui.row); | |
1674 rc.right = rc.left + gui.char_width; | |
1675 #ifdef FEAT_MBYTE | |
1676 if (mb_lefthalve(gui.row, gui.col)) | |
1677 rc.right += gui.char_width; | |
1678 #endif | |
1679 rc.bottom = rc.top + gui.char_height; | |
1680 hbr = CreateSolidBrush(color); | |
1681 FrameRect(s_hdc, &rc, hbr); | |
1682 DeleteBrush(hbr); | |
1683 } | |
1684 /* | |
1685 * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using | |
1686 * color "color". | |
1687 */ | |
1688 void | |
1689 gui_mch_draw_part_cursor( | |
1690 int w, | |
1691 int h, | |
1692 guicolor_T color) | |
1693 { | |
1694 HBRUSH hbr; | |
1695 RECT rc; | |
1696 | |
1697 /* | |
1698 * Note: FillRect() excludes right and bottom of rectangle. | |
1699 */ | |
1700 rc.left = | |
1701 #ifdef FEAT_RIGHTLEFT | |
1702 /* vertical line should be on the right of current point */ | |
1703 CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w : | |
1704 #endif | |
1705 FILL_X(gui.col); | |
1706 rc.top = FILL_Y(gui.row) + gui.char_height - h; | |
1707 rc.right = rc.left + w; | |
1708 rc.bottom = rc.top + h; | |
1709 hbr = CreateSolidBrush(color); | |
1710 FillRect(s_hdc, &rc, hbr); | |
1711 DeleteBrush(hbr); | |
1712 } | |
1713 | |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1714 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1715 /* |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1716 * Generates a VK_SPACE when the internal dead_key flag is set to output the |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1717 * dead key's nominal character and re-post the original message. |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1718 */ |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1719 static void |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1720 outputDeadKey_rePost(MSG originalMsg) |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1721 { |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1722 static MSG deadCharExpel; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1723 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1724 if (!dead_key) |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1725 return; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1726 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1727 dead_key = 0; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1728 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1729 /* Make Windows generate the dead key's character */ |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1730 deadCharExpel.message = originalMsg.message; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1731 deadCharExpel.hwnd = originalMsg.hwnd; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1732 deadCharExpel.wParam = VK_SPACE; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1733 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1734 MyTranslateMessage(&deadCharExpel); |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1735 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1736 /* re-generate the current character free of the dead char influence */ |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1737 PostMessage(originalMsg.hwnd, originalMsg.message, originalMsg.wParam, |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1738 originalMsg.lParam); |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1739 } |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1740 |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1741 |
7 | 1742 /* |
1743 * Process a single Windows message. | |
1744 * If one is not available we hang until one is. | |
1745 */ | |
1746 static void | |
1747 process_message(void) | |
1748 { | |
1749 MSG msg; | |
1750 UINT vk = 0; /* Virtual key */ | |
1751 char_u string[40]; | |
1752 int i; | |
1753 int modifiers = 0; | |
1754 int key; | |
36 | 1755 #ifdef FEAT_MENU |
1756 static char_u k10[] = {K_SPECIAL, 'k', ';', 0}; | |
1757 #endif | |
7 | 1758 |
3010 | 1759 pGetMessage(&msg, NULL, 0, 0); |
7 | 1760 |
1761 #ifdef FEAT_OLE | |
1762 /* Look after OLE Automation commands */ | |
1763 if (msg.message == WM_OLE) | |
1764 { | |
1765 char_u *str = (char_u *)msg.lParam; | |
1791 | 1766 if (str == NULL || *str == NUL) |
1767 { | |
1768 /* Message can't be ours, forward it. Fixes problem with Ultramon | |
1769 * 3.0.4 */ | |
3010 | 1770 pDispatchMessage(&msg); |
1791 | 1771 } |
1772 else | |
1773 { | |
1774 add_to_input_buf(str, (int)STRLEN(str)); | |
1775 vim_free(str); /* was allocated in CVim::SendKeys() */ | |
1776 } | |
7 | 1777 return; |
1778 } | |
1779 #endif | |
1780 | |
7770
42c1a4e63d12
commit https://github.com/vim/vim/commit/d04a020a8a8d7a438b091d49218c438880beb50c
Christian Brabandt <cb@256bit.org>
parents:
7649
diff
changeset
|
1781 #ifdef FEAT_CHANNEL |
7 | 1782 if (msg.message == WM_NETBEANS) |
1783 { | |
8047
7c74cafac0a1
commit https://github.com/vim/vim/commit/7b3ca76a451b10d238ef946f3231762e0bd988e9
Christian Brabandt <cb@256bit.org>
parents:
8041
diff
changeset
|
1784 int what; |
7c74cafac0a1
commit https://github.com/vim/vim/commit/7b3ca76a451b10d238ef946f3231762e0bd988e9
Christian Brabandt <cb@256bit.org>
parents:
8041
diff
changeset
|
1785 channel_T *channel = channel_fd2channel((sock_T)msg.wParam, &what); |
8041
c6443e78cf2d
commit https://github.com/vim/vim/commit/7707344ddec9069b495b2a5ed41f2104466fc88b
Christian Brabandt <cb@256bit.org>
parents:
8037
diff
changeset
|
1786 |
c6443e78cf2d
commit https://github.com/vim/vim/commit/7707344ddec9069b495b2a5ed41f2104466fc88b
Christian Brabandt <cb@256bit.org>
parents:
8037
diff
changeset
|
1787 if (channel != NULL) |
8037
9dea1571b352
commit https://github.com/vim/vim/commit/bfa1ffca8bcce92c030d8366036a316954f1ee69
Christian Brabandt <cb@256bit.org>
parents:
8031
diff
changeset
|
1788 { |
9dea1571b352
commit https://github.com/vim/vim/commit/bfa1ffca8bcce92c030d8366036a316954f1ee69
Christian Brabandt <cb@256bit.org>
parents:
8031
diff
changeset
|
1789 /* Disable error messages, they can mess up the display and throw |
9dea1571b352
commit https://github.com/vim/vim/commit/bfa1ffca8bcce92c030d8366036a316954f1ee69
Christian Brabandt <cb@256bit.org>
parents:
8031
diff
changeset
|
1790 * an exception. */ |
9dea1571b352
commit https://github.com/vim/vim/commit/bfa1ffca8bcce92c030d8366036a316954f1ee69
Christian Brabandt <cb@256bit.org>
parents:
8031
diff
changeset
|
1791 ++emsg_off; |
8047
7c74cafac0a1
commit https://github.com/vim/vim/commit/7b3ca76a451b10d238ef946f3231762e0bd988e9
Christian Brabandt <cb@256bit.org>
parents:
8041
diff
changeset
|
1792 channel_read(channel, what, "process_message"); |
8037
9dea1571b352
commit https://github.com/vim/vim/commit/bfa1ffca8bcce92c030d8366036a316954f1ee69
Christian Brabandt <cb@256bit.org>
parents:
8031
diff
changeset
|
1793 --emsg_off; |
9dea1571b352
commit https://github.com/vim/vim/commit/bfa1ffca8bcce92c030d8366036a316954f1ee69
Christian Brabandt <cb@256bit.org>
parents:
8031
diff
changeset
|
1794 } |
7 | 1795 return; |
1796 } | |
1797 #endif | |
1798 | |
1799 #ifdef FEAT_SNIFF | |
1800 if (sniff_request_waiting && want_sniff_request) | |
1801 { | |
1802 static char_u bytes[3] = {CSI, (char_u)KS_EXTRA, (char_u)KE_SNIFF}; | |
1803 add_to_input_buf(bytes, 3); /* K_SNIFF */ | |
1804 sniff_request_waiting = 0; | |
1805 want_sniff_request = 0; | |
1806 /* request is handled in normal.c */ | |
1807 } | |
1808 if (msg.message == WM_USER) | |
901 | 1809 { |
906 | 1810 MyTranslateMessage(&msg); |
3010 | 1811 pDispatchMessage(&msg); |
7 | 1812 return; |
901 | 1813 } |
7 | 1814 #endif |
1815 | |
1816 #ifdef MSWIN_FIND_REPLACE | |
1817 /* Don't process messages used by the dialog */ | |
3010 | 1818 if (s_findrep_hwnd != NULL && pIsDialogMessage(s_findrep_hwnd, &msg)) |
7 | 1819 { |
1820 HandleMouseHide(msg.message, msg.lParam); | |
1821 return; | |
1822 } | |
1823 #endif | |
1824 | |
1825 /* | |
1826 * Check if it's a special key that we recognise. If not, call | |
1827 * TranslateMessage(). | |
1828 */ | |
1829 if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN) | |
1830 { | |
1831 vk = (int) msg.wParam; | |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1832 |
6151 | 1833 /* |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1834 * Handle dead keys in special conditions in other cases we let Windows |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1835 * handle them and do not interfere. |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1836 * |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1837 * The dead_key flag must be reset on several occasions: |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1838 * - in _OnChar() (or _OnSysChar()) as any dead key was necessarily |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1839 * consumed at that point (This is when we let Windows combine the |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1840 * dead character on its own) |
6151 | 1841 * |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1842 * - Before doing something special such as regenerating keypresses to |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1843 * expel the dead character as this could trigger an infinite loop if |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1844 * for some reason MyTranslateMessage() do not trigger a call |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1845 * immediately to _OnChar() (or _OnSysChar()). |
6151 | 1846 */ |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1847 if (dead_key) |
7 | 1848 { |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1849 /* |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1850 * If a dead key was pressed and the user presses VK_SPACE, |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1851 * VK_BACK, or VK_ESCAPE it means that he actually wants to deal |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1852 * with the dead char now, so do nothing special and let Windows |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1853 * handle it. |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1854 * |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1855 * Note that VK_SPACE combines with the dead_key's character and |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1856 * only one WM_CHAR will be generated by TranslateMessage(), in |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1857 * the two other cases two WM_CHAR will be generated: the dead |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1858 * char and VK_BACK or VK_ESCAPE. That is most likely what the |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1859 * user expects. |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1860 */ |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1861 if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE)) |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1862 { |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1863 dead_key = 0; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1864 MyTranslateMessage(&msg); |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1865 return; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1866 } |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1867 /* In modes where we are not typing, dead keys should behave |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1868 * normally */ |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1869 else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE))) |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1870 { |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1871 outputDeadKey_rePost(msg); |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1872 return; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1873 } |
7 | 1874 } |
1875 | |
1876 /* Check for CTRL-BREAK */ | |
1877 if (vk == VK_CANCEL) | |
1878 { | |
1879 trash_input_buf(); | |
1880 got_int = TRUE; | |
1881 string[0] = Ctrl_C; | |
1882 add_to_input_buf(string, 1); | |
1883 } | |
1884 | |
1885 for (i = 0; special_keys[i].key_sym != 0; i++) | |
1886 { | |
1887 /* ignore VK_SPACE when ALT key pressed: system menu */ | |
1888 if (special_keys[i].key_sym == vk | |
1889 && (vk != VK_SPACE || !(GetKeyState(VK_MENU) & 0x8000))) | |
1890 { | |
7649
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1891 /* |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1892 * Behave as exected if we have a dead key and the special key |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1893 * is a key that would normally trigger the dead key nominal |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1894 * character output (such as a NUMPAD printable character or |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1895 * the TAB key, etc...). |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1896 */ |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1897 if (dead_key && (special_keys[i].vim_code0 == 'K' |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1898 || vk == VK_TAB || vk == CAR)) |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1899 { |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1900 outputDeadKey_rePost(msg); |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1901 return; |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1902 } |
4d97a97495bb
commit https://github.com/vim/vim/commit/25b2b94ea73eff2aeef624d2ba7f59a1a265a0c1
Christian Brabandt <cb@256bit.org>
parents:
7125
diff
changeset
|
1903 |
7 | 1904 #ifdef FEAT_MENU |
36 | 1905 /* Check for <F10>: Windows selects the menu. When <F10> is |
1906 * mapped we want to use the mapping instead. */ | |
7 | 1907 if (vk == VK_F10 |
1908 && gui.menu_is_active | |
2610 | 1909 && check_map(k10, State, FALSE, TRUE, FALSE, |
1910 NULL, NULL) == NULL) | |
7 | 1911 break; |
1912 #endif | |
1913 if (GetKeyState(VK_SHIFT) & 0x8000) | |
1914 modifiers |= MOD_MASK_SHIFT; | |
1915 /* | |
1916 * Don't use caps-lock as shift, because these are special keys | |
1917 * being considered here, and we only want letters to get | |
1918 * shifted -- webb | |
1919 */ | |
1920 /* | |
1921 if (GetKeyState(VK_CAPITAL) & 0x0001) | |
1922 modifiers ^= MOD_MASK_SHIFT; | |
1923 */ | |
1924 if (GetKeyState(VK_CONTROL) & 0x8000) | |
1925 modifiers |= MOD_MASK_CTRL; | |
1926 if (GetKeyState(VK_MENU) & 0x8000) | |
1927 modifiers |= MOD_MASK_ALT; | |
1928 | |
1929 if (special_keys[i].vim_code1 == NUL) | |
1930 key = special_keys[i].vim_code0; | |
1931 else | |
1932 key = TO_SPECIAL(special_keys[i].vim_code0, | |
1933 special_keys[i].vim_code1); | |
1934 key = simplify_key(key, &modifiers); | |
1935 if (key == CSI) | |
1936 key = K_CSI; | |
1937 | |
1938 if (modifiers) | |
1939 { | |
1940 string[0] = CSI; | |
1941 string[1] = KS_MODIFIER; | |
1942 string[2] = modifiers; | |
1943 add_to_input_buf(string, 3); | |
1944 } | |
1945 | |
1946 if (IS_SPECIAL(key)) | |
1947 { | |
1948 string[0] = CSI; | |
1949 string[1] = K_SECOND(key); | |
1950 string[2] = K_THIRD(key); | |
1951 add_to_input_buf(string, 3); | |
1952 } | |
1953 else | |
1954 { | |
1955 int len; | |
1956 | |
1957 /* Handle "key" as a Unicode character. */ | |
1443 | 1958 len = char_to_string(key, string, 40, FALSE); |
7 | 1959 add_to_input_buf(string, len); |
1960 } | |
1961 break; | |
1962 } | |
1963 } | |
1964 if (special_keys[i].key_sym == 0) | |
1965 { | |
1966 /* Some keys need C-S- where they should only need C-. | |
1967 * Ignore 0xff, Windows XP sends it when NUMLOCK has changed since | |
1968 * system startup (Helmut Stiegler, 2003 Oct 3). */ | |
1969 if (vk != 0xff | |
1970 && (GetKeyState(VK_CONTROL) & 0x8000) | |
1971 && !(GetKeyState(VK_SHIFT) & 0x8000) | |
1972 && !(GetKeyState(VK_MENU) & 0x8000)) | |
1973 { | |
1974 /* CTRL-6 is '^'; Japanese keyboard maps '^' to vk == 0xDE */ | |
1975 if (vk == '6' || MapVirtualKey(vk, 2) == (UINT)'^') | |
1976 { | |
1977 string[0] = Ctrl_HAT; | |
1978 add_to_input_buf(string, 1); | |
1979 } | |
1980 /* vk == 0xBD AZERTY for CTRL-'-', but CTRL-[ for * QWERTY! */ | |
1981 else if (vk == 0xBD) /* QWERTY for CTRL-'-' */ | |
1982 { | |
1983 string[0] = Ctrl__; | |
1984 add_to_input_buf(string, 1); | |
1985 } | |
1986 /* CTRL-2 is '@'; Japanese keyboard maps '@' to vk == 0xC0 */ | |
1987 else if (vk == '2' || MapVirtualKey(vk, 2) == (UINT)'@') | |
1988 { | |
1989 string[0] = Ctrl_AT; | |
1990 add_to_input_buf(string, 1); | |
1991 } | |
1992 else | |
1993 MyTranslateMessage(&msg); | |
1994 } | |
1995 else | |
1996 MyTranslateMessage(&msg); | |
1997 } | |
1998 } | |
1999 #ifdef FEAT_MBYTE_IME | |
2000 else if (msg.message == WM_IME_NOTIFY) | |
2001 _OnImeNotify(msg.hwnd, (DWORD)msg.wParam, (DWORD)msg.lParam); | |
2002 else if (msg.message == WM_KEYUP && im_get_status()) | |
2003 /* added for non-MS IME (Yasuhiro Matsumoto) */ | |
2004 MyTranslateMessage(&msg); | |
2005 #endif | |
2006 #if !defined(FEAT_MBYTE_IME) && defined(GLOBAL_IME) | |
2007 /* GIME_TEST */ | |
2008 else if (msg.message == WM_IME_STARTCOMPOSITION) | |
2009 { | |
2010 POINT point; | |
2011 | |
2012 global_ime_set_font(&norm_logfont); | |
2013 point.x = FILL_X(gui.col); | |
2014 point.y = FILL_Y(gui.row); | |
2015 MapWindowPoints(s_textArea, s_hwnd, &point, 1); | |
2016 global_ime_set_position(&point); | |
2017 } | |
2018 #endif | |
2019 | |
2020 #ifdef FEAT_MENU | |
36 | 2021 /* Check for <F10>: Default effect is to select the menu. When <F10> is |
2022 * mapped we need to stop it here to avoid strange effects (e.g., for the | |
2023 * key-up event) */ | |
2610 | 2024 if (vk != VK_F10 || check_map(k10, State, FALSE, TRUE, FALSE, |
2025 NULL, NULL) == NULL) | |
7 | 2026 #endif |
3010 | 2027 pDispatchMessage(&msg); |
7 | 2028 } |
2029 | |
2030 /* | |
2031 * Catch up with any queued events. This may put keyboard input into the | |
2032 * input buffer, call resize call-backs, trigger timers etc. If there is | |
2033 * nothing in the event queue (& no timers pending), then we return | |
2034 * immediately. | |
2035 */ | |
2036 void | |
2037 gui_mch_update(void) | |
2038 { | |
2039 MSG msg; | |
2040 | |
2041 if (!s_busy_processing) | |
3010 | 2042 while (pPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) |
7 | 2043 && !vim_is_input_buf_full()) |
2044 process_message(); | |
2045 } | |
2046 | |
2047 /* | |
2048 * GUI input routine called by gui_wait_for_chars(). Waits for a character | |
2049 * from the keyboard. | |
2050 * wtime == -1 Wait forever. | |
2051 * wtime == 0 This should never happen. | |
2052 * wtime > 0 Wait wtime milliseconds for a character. | |
2053 * Returns OK if a character was found to be available within the given time, | |
2054 * or FAIL otherwise. | |
2055 */ | |
2056 int | |
2057 gui_mch_wait_for_chars(int wtime) | |
2058 { | |
2059 MSG msg; | |
2060 int focus; | |
2061 | |
2062 s_timed_out = FALSE; | |
2063 | |
2064 if (wtime > 0) | |
2065 { | |
2066 /* Don't do anything while processing a (scroll) message. */ | |
2067 if (s_busy_processing) | |
2068 return FAIL; | |
2069 s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)wtime, | |
2070 (TIMERPROC)_OnTimer); | |
2071 } | |
2072 | |
2073 allow_scrollbar = TRUE; | |
2074 | |
2075 focus = gui.in_focus; | |
2076 while (!s_timed_out) | |
2077 { | |
2078 /* Stop or start blinking when focus changes */ | |
2079 if (gui.in_focus != focus) | |
2080 { | |
2081 if (gui.in_focus) | |
2082 gui_mch_start_blink(); | |
2083 else | |
2084 gui_mch_stop_blink(); | |
2085 focus = gui.in_focus; | |
2086 } | |
2087 | |
2088 if (s_need_activate) | |
2089 { | |
2090 #ifdef WIN32 | |
2091 (void)SetForegroundWindow(s_hwnd); | |
2092 #else | |
2093 (void)SetActiveWindow(s_hwnd); | |
2094 #endif | |
2095 s_need_activate = FALSE; | |
2096 } | |
2097 | |
7109
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
6819
diff
changeset
|
2098 #ifdef MESSAGE_QUEUE |
fa95595fbc52
commit https://github.com/vim/vim/commit/93c88e0f6a4a8f7634ed84721daf4af46fc0d5db
Christian Brabandt <cb@256bit.org>
parents:
6819
diff
changeset
|
2099 parse_queued_messages(); |
1773 | 2100 #endif |
2101 | |
8122
39532ee7dd43
commit https://github.com/vim/vim/commit/ed5a78e11c80c7b13b233149fd4273b71fc96262
Christian Brabandt <cb@256bit.org>
parents:
8102
diff
changeset
|
2102 #ifdef FEAT_CHANNEL |
39532ee7dd43
commit https://github.com/vim/vim/commit/ed5a78e11c80c7b13b233149fd4273b71fc96262
Christian Brabandt <cb@256bit.org>
parents:
8102
diff
changeset
|
2103 channel_handle_events(); |
39532ee7dd43
commit https://github.com/vim/vim/commit/ed5a78e11c80c7b13b233149fd4273b71fc96262
Christian Brabandt <cb@256bit.org>
parents:
8102
diff
changeset
|
2104 #endif |
39532ee7dd43
commit https://github.com/vim/vim/commit/ed5a78e11c80c7b13b233149fd4273b71fc96262
Christian Brabandt <cb@256bit.org>
parents:
8102
diff
changeset
|
2105 |
7 | 2106 /* |
2107 * Don't use gui_mch_update() because then we will spin-lock until a | |
2108 * char arrives, instead we use GetMessage() to hang until an | |
2109 * event arrives. No need to check for input_buf_full because we are | |
2110 * returning as soon as it contains a single char -- webb | |
2111 */ | |
2112 process_message(); | |
2113 | |
2114 if (input_available()) | |
2115 { | |
2116 if (s_wait_timer != 0 && !s_timed_out) | |
2117 { | |
2118 KillTimer(NULL, s_wait_timer); | |
2119 | |
2120 /* Eat spurious WM_TIMER messages */ | |
3010 | 2121 while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)) |
7 | 2122 ; |
2123 s_wait_timer = 0; | |
2124 } | |
2125 allow_scrollbar = FALSE; | |
36 | 2126 |
2127 /* Clear pending mouse button, the release event may have been | |
1453 | 2128 * taken by the dialog window. But don't do this when getting |
2129 * focus, we need the mouse-up event then. */ | |
2130 if (!s_getting_focus) | |
2131 s_button_pending = -1; | |
36 | 2132 |
7 | 2133 return OK; |
2134 } | |
2135 } | |
2136 allow_scrollbar = FALSE; | |
2137 return FAIL; | |
2138 } | |
2139 | |
2140 /* | |
2141 * Clear a rectangular region of the screen from text pos (row1, col1) to | |
2142 * (row2, col2) inclusive. | |
2143 */ | |
2144 void | |
2145 gui_mch_clear_block( | |
2146 int row1, | |
2147 int col1, | |
2148 int row2, | |
2149 int col2) | |
2150 { | |
2151 RECT rc; | |
2152 | |
2153 /* | |
2154 * Clear one extra pixel at the far right, for when bold characters have | |
2155 * spilled over to the window border. | |
2156 * Note: FillRect() excludes right and bottom of rectangle. | |
2157 */ | |
2158 rc.left = FILL_X(col1); | |
2159 rc.top = FILL_Y(row1); | |
2160 rc.right = FILL_X(col2 + 1) + (col2 == Columns - 1); | |
2161 rc.bottom = FILL_Y(row2 + 1); | |
2162 clear_rect(&rc); | |
2163 } | |
2164 | |
2165 /* | |
2166 * Clear the whole text window. | |
2167 */ | |
2168 void | |
2169 gui_mch_clear_all(void) | |
2170 { | |
2171 RECT rc; | |
2172 | |
2173 rc.left = 0; | |
2174 rc.top = 0; | |
2175 rc.right = Columns * gui.char_width + 2 * gui.border_width; | |
2176 rc.bottom = Rows * gui.char_height + 2 * gui.border_width; | |
2177 clear_rect(&rc); | |
2178 } | |
2179 /* | |
2180 * Menu stuff. | |
2181 */ | |
2182 | |
2183 void | |
2184 gui_mch_enable_menu(int flag) | |
2185 { | |
2186 #ifdef FEAT_MENU | |
2187 SetMenu(s_hwnd, flag ? s_menuBar : NULL); | |
2188 #endif | |
2189 } | |
2190 | |
323 | 2191 /*ARGSUSED*/ |
7 | 2192 void |
2193 gui_mch_set_menu_pos( | |
2194 int x, | |
2195 int y, | |
2196 int w, | |
2197 int h) | |
2198 { | |
2199 /* It will be in the right place anyway */ | |
2200 } | |
2201 | |
2202 #if defined(FEAT_MENU) || defined(PROTO) | |
2203 /* | |
2204 * Make menu item hidden or not hidden | |
2205 */ | |
2206 void | |
2207 gui_mch_menu_hidden( | |
2208 vimmenu_T *menu, | |
2209 int hidden) | |
2210 { | |
2211 /* | |
2212 * This doesn't do what we want. Hmm, just grey the menu items for now. | |
2213 */ | |
2214 /* | |
2215 if (hidden) | |
2216 EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_DISABLED); | |
2217 else | |
2218 EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_ENABLED); | |
2219 */ | |
2220 gui_mch_menu_grey(menu, hidden); | |
2221 } | |
2222 | |
2223 /* | |
2224 * This is called after setting all the menus to grey/hidden or not. | |
2225 */ | |
2226 void | |
2227 gui_mch_draw_menubar(void) | |
2228 { | |
2229 DrawMenuBar(s_hwnd); | |
2230 } | |
2231 #endif /*FEAT_MENU*/ | |
2232 | |
2233 #ifndef PROTO | |
2234 void | |
2235 #ifdef VIMDLL | |
2236 _export | |
2237 #endif | |
2238 _cdecl | |
2239 SaveInst(HINSTANCE hInst) | |
2240 { | |
2241 s_hinst = hInst; | |
2242 } | |
2243 #endif | |
2244 | |
2245 /* | |
2246 * Return the RGB value of a pixel as a long. | |
2247 */ | |
2248 long_u | |
2249 gui_mch_get_rgb(guicolor_T pixel) | |
2250 { | |
2251 return (GetRValue(pixel) << 16) + (GetGValue(pixel) << 8) | |
2252 + GetBValue(pixel); | |
2253 } | |
2254 | |
2255 #if defined(FEAT_GUI_DIALOG) || defined(PROTO) | |
2256 /* Convert pixels in X to dialog units */ | |
2257 static WORD | |
2258 PixelToDialogX(int numPixels) | |
2259 { | |
2260 return (WORD)((numPixels * 4) / s_dlgfntwidth); | |
2261 } | |
2262 | |
2263 /* Convert pixels in Y to dialog units */ | |
2264 static WORD | |
2265 PixelToDialogY(int numPixels) | |
2266 { | |
2267 return (WORD)((numPixels * 8) / s_dlgfntheight); | |
2268 } | |
2269 | |
2270 /* Return the width in pixels of the given text in the given DC. */ | |
2271 static int | |
2272 GetTextWidth(HDC hdc, char_u *str, int len) | |
2273 { | |
2274 SIZE size; | |
2275 | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2276 GetTextExtentPoint(hdc, (LPCSTR)str, len, &size); |
7 | 2277 return size.cx; |
2278 } | |
2279 | |
2280 #ifdef FEAT_MBYTE | |
2281 /* | |
2282 * Return the width in pixels of the given text in the given DC, taking care | |
2283 * of 'encoding' to active codepage conversion. | |
2284 */ | |
2285 static int | |
2286 GetTextWidthEnc(HDC hdc, char_u *str, int len) | |
2287 { | |
2288 SIZE size; | |
2289 WCHAR *wstr; | |
2290 int n; | |
2291 int wlen = len; | |
2292 | |
2293 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
2294 { | |
2295 /* 'encoding' differs from active codepage: convert text and use wide | |
2296 * function */ | |
1752 | 2297 wstr = enc_to_utf16(str, &wlen); |
7 | 2298 if (wstr != NULL) |
2299 { | |
2300 n = GetTextExtentPointW(hdc, wstr, wlen, &size); | |
2301 vim_free(wstr); | |
2302 if (n) | |
2303 return size.cx; | |
2304 } | |
2305 } | |
2306 | |
2307 return GetTextWidth(hdc, str, len); | |
2308 } | |
2309 #else | |
2310 # define GetTextWidthEnc(h, s, l) GetTextWidth((h), (s), (l)) | |
2311 #endif | |
2312 | |
2313 /* | |
2314 * A quick little routine that will center one window over another, handy for | |
2315 * dialog boxes. Taken from the Win32SDK samples. | |
2316 */ | |
2317 static BOOL | |
2318 CenterWindow( | |
2319 HWND hwndChild, | |
2320 HWND hwndParent) | |
2321 { | |
2322 RECT rChild, rParent; | |
2323 int wChild, hChild, wParent, hParent; | |
2324 int wScreen, hScreen, xNew, yNew; | |
2325 HDC hdc; | |
2326 | |
2327 GetWindowRect(hwndChild, &rChild); | |
2328 wChild = rChild.right - rChild.left; | |
2329 hChild = rChild.bottom - rChild.top; | |
2330 | |
2331 /* If Vim is minimized put the window in the middle of the screen. */ | |
829 | 2332 if (hwndParent == NULL || IsMinimized(hwndParent)) |
7 | 2333 { |
2334 #ifdef WIN16 | |
2335 rParent.left = 0; | |
2336 rParent.top = 0; | |
2337 rParent.right = GetSystemMetrics(SM_CXSCREEN); | |
2338 rParent.bottom = GetSystemMetrics(SM_CYFULLSCREEN); | |
2339 #else | |
2340 SystemParametersInfo(SPI_GETWORKAREA, 0, &rParent, 0); | |
2341 #endif | |
2342 } | |
2343 else | |
2344 GetWindowRect(hwndParent, &rParent); | |
2345 wParent = rParent.right - rParent.left; | |
2346 hParent = rParent.bottom - rParent.top; | |
2347 | |
2348 hdc = GetDC(hwndChild); | |
2349 wScreen = GetDeviceCaps (hdc, HORZRES); | |
2350 hScreen = GetDeviceCaps (hdc, VERTRES); | |
2351 ReleaseDC(hwndChild, hdc); | |
2352 | |
2353 xNew = rParent.left + ((wParent - wChild) /2); | |
2354 if (xNew < 0) | |
2355 { | |
2356 xNew = 0; | |
2357 } | |
2358 else if ((xNew+wChild) > wScreen) | |
2359 { | |
2360 xNew = wScreen - wChild; | |
2361 } | |
2362 | |
2363 yNew = rParent.top + ((hParent - hChild) /2); | |
2364 if (yNew < 0) | |
2365 yNew = 0; | |
2366 else if ((yNew+hChild) > hScreen) | |
2367 yNew = hScreen - hChild; | |
2368 | |
2369 return SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0, | |
2370 SWP_NOSIZE | SWP_NOZORDER); | |
2371 } | |
2372 #endif /* FEAT_GUI_DIALOG */ | |
2373 | |
2374 void | |
2375 gui_mch_activate_window(void) | |
2376 { | |
2377 (void)SetActiveWindow(s_hwnd); | |
2378 } | |
2379 | |
2380 #if defined(FEAT_TOOLBAR) || defined(PROTO) | |
2381 void | |
2382 gui_mch_show_toolbar(int showit) | |
2383 { | |
2384 if (s_toolbarhwnd == NULL) | |
2385 return; | |
2386 | |
2387 if (showit) | |
948 | 2388 { |
2389 # ifdef FEAT_MBYTE | |
2390 # ifndef TB_SETUNICODEFORMAT | |
2391 /* For older compilers. We assume this never changes. */ | |
2392 # define TB_SETUNICODEFORMAT 0x2005 | |
2393 # endif | |
2394 /* Enable/disable unicode support */ | |
2395 int uu = (enc_codepage >= 0 && (int)GetACP() != enc_codepage); | |
2396 SendMessage(s_toolbarhwnd, TB_SETUNICODEFORMAT, (WPARAM)uu, (LPARAM)0); | |
2397 # endif | |
7 | 2398 ShowWindow(s_toolbarhwnd, SW_SHOW); |
948 | 2399 } |
7 | 2400 else |
2401 ShowWindow(s_toolbarhwnd, SW_HIDE); | |
2402 } | |
2403 | |
2404 /* Then number of bitmaps is fixed. Exit is missing! */ | |
2405 #define TOOLBAR_BITMAP_COUNT 31 | |
2406 | |
2407 #endif | |
2408 | |
810 | 2409 #if defined(FEAT_GUI_TABLINE) || defined(PROTO) |
811 | 2410 static void |
1035 | 2411 add_tabline_popup_menu_entry(HMENU pmenu, UINT item_id, char_u *item_text) |
2412 { | |
2413 #ifdef FEAT_MBYTE | |
2414 WCHAR *wn = NULL; | |
2415 int n; | |
2416 | |
2417 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
2418 { | |
2419 /* 'encoding' differs from active codepage: convert menu name | |
2420 * and use wide function */ | |
1752 | 2421 wn = enc_to_utf16(item_text, NULL); |
1035 | 2422 if (wn != NULL) |
2423 { | |
2424 MENUITEMINFOW infow; | |
2425 | |
2426 infow.cbSize = sizeof(infow); | |
2427 infow.fMask = MIIM_TYPE | MIIM_ID; | |
2428 infow.wID = item_id; | |
2429 infow.fType = MFT_STRING; | |
2430 infow.dwTypeData = wn; | |
2431 infow.cch = (UINT)wcslen(wn); | |
2432 n = InsertMenuItemW(pmenu, item_id, FALSE, &infow); | |
2433 vim_free(wn); | |
2434 if (n == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) | |
2435 /* Failed, try using non-wide function. */ | |
2436 wn = NULL; | |
2437 } | |
2438 } | |
2439 | |
2440 if (wn == NULL) | |
2441 #endif | |
2442 { | |
2443 MENUITEMINFO info; | |
2444 | |
2445 info.cbSize = sizeof(info); | |
2446 info.fMask = MIIM_TYPE | MIIM_ID; | |
2447 info.wID = item_id; | |
2448 info.fType = MFT_STRING; | |
8102
441298d72f3c
commit https://github.com/vim/vim/commit/a87e2c277eabf0134925c340e9dc4fe9446f3636
Christian Brabandt <cb@256bit.org>
parents:
8090
diff
changeset
|
2449 info.dwTypeData = (LPTSTR)item_text; |
1035 | 2450 info.cch = (UINT)STRLEN(item_text); |
2451 InsertMenuItem(pmenu, item_id, FALSE, &info); | |
2452 } | |
2453 } | |
2454 | |
2455 static void | |
811 | 2456 show_tabline_popup_menu(void) |
2457 { | |
2458 HMENU tab_pmenu; | |
2459 long rval; | |
2460 POINT pt; | |
2461 | |
844 | 2462 /* When ignoring events don't show the menu. */ |
2463 if (hold_gui_events | |
2464 # ifdef FEAT_CMDWIN | |
2465 || cmdwin_type != 0 | |
2466 # endif | |
2467 ) | |
2468 return; | |
2469 | |
811 | 2470 tab_pmenu = CreatePopupMenu(); |
2471 if (tab_pmenu == NULL) | |
2472 return; | |
2473 | |
6819 | 2474 if (first_tabpage->tp_next != NULL) |
7115
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
2475 add_tabline_popup_menu_entry(tab_pmenu, |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2476 TABLINE_MENU_CLOSE, (char_u *)_("Close tab")); |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2477 add_tabline_popup_menu_entry(tab_pmenu, |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2478 TABLINE_MENU_NEW, (char_u *)_("New tab")); |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2479 add_tabline_popup_menu_entry(tab_pmenu, |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2480 TABLINE_MENU_OPEN, (char_u *)_("Open tab...")); |
811 | 2481 |
2482 GetCursorPos(&pt); | |
2483 rval = TrackPopupMenuEx(tab_pmenu, TPM_RETURNCMD, pt.x, pt.y, s_tabhwnd, | |
2484 NULL); | |
2485 | |
2486 DestroyMenu(tab_pmenu); | |
2487 | |
2488 /* Add the string cmd into input buffer */ | |
2489 if (rval > 0) | |
2490 { | |
2491 TCHITTESTINFO htinfo; | |
2492 int idx; | |
2493 | |
2494 if (ScreenToClient(s_tabhwnd, &pt) == 0) | |
2495 return; | |
2496 | |
2497 htinfo.pt.x = pt.x; | |
2498 htinfo.pt.y = pt.y; | |
2499 idx = TabCtrl_HitTest(s_tabhwnd, &htinfo); | |
2500 if (idx == -1) | |
2501 idx = 0; | |
2502 else | |
2503 idx += 1; | |
2504 | |
824 | 2505 send_tabline_menu_event(idx, (int)rval); |
811 | 2506 } |
2507 } | |
2508 | |
810 | 2509 /* |
2510 * Show or hide the tabline. | |
2511 */ | |
2512 void | |
2513 gui_mch_show_tabline(int showit) | |
2514 { | |
2515 if (s_tabhwnd == NULL) | |
2516 return; | |
2517 | |
2518 if (!showit != !showing_tabline) | |
2519 { | |
2520 if (showit) | |
2521 ShowWindow(s_tabhwnd, SW_SHOW); | |
2522 else | |
2523 ShowWindow(s_tabhwnd, SW_HIDE); | |
2524 showing_tabline = showit; | |
2525 } | |
2526 } | |
2527 | |
2528 /* | |
2529 * Return TRUE when tabline is displayed. | |
2530 */ | |
2531 int | |
2532 gui_mch_showing_tabline(void) | |
2533 { | |
2534 return s_tabhwnd != NULL && showing_tabline; | |
2535 } | |
2536 | |
2537 /* | |
2538 * Update the labels of the tabline. | |
2539 */ | |
2540 void | |
2541 gui_mch_update_tabline(void) | |
2542 { | |
2543 tabpage_T *tp; | |
2544 TCITEM tie; | |
2545 int nr = 0; | |
2546 int curtabidx = 0; | |
5286
74a211a0d3a3
updated for version 7.4b.019
Bram Moolenaar <bram@vim.org>
parents:
5225
diff
changeset
|
2547 int tabadded = 0; |
837 | 2548 #ifdef FEAT_MBYTE |
838 | 2549 static int use_unicode = FALSE; |
2550 int uu; | |
837 | 2551 WCHAR *wstr = NULL; |
2552 #endif | |
810 | 2553 |
2554 if (s_tabhwnd == NULL) | |
2555 return; | |
2556 | |
838 | 2557 #if defined(FEAT_MBYTE) |
2558 # ifndef CCM_SETUNICODEFORMAT | |
2559 /* For older compilers. We assume this never changes. */ | |
2560 # define CCM_SETUNICODEFORMAT 0x2005 | |
2561 # endif | |
2562 uu = (enc_codepage >= 0 && (int)GetACP() != enc_codepage); | |
2563 if (uu != use_unicode) | |
2564 { | |
2565 /* Enable/disable unicode support */ | |
2566 SendMessage(s_tabhwnd, CCM_SETUNICODEFORMAT, (WPARAM)uu, (LPARAM)0); | |
2567 use_unicode = uu; | |
2568 } | |
837 | 2569 #endif |
2570 | |
810 | 2571 tie.mask = TCIF_TEXT; |
2572 tie.iImage = -1; | |
2573 | |
4009 | 2574 /* Disable redraw for tab updates to eliminate O(N^2) draws. */ |
2575 SendMessage(s_tabhwnd, WM_SETREDRAW, (WPARAM)FALSE, 0); | |
2576 | |
810 | 2577 /* Add a label for each tab page. They all contain the same text area. */ |
2578 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr) | |
2579 { | |
2580 if (tp == curtab) | |
2581 curtabidx = nr; | |
2582 | |
4009 | 2583 if (nr >= TabCtrl_GetItemCount(s_tabhwnd)) |
810 | 2584 { |
2585 /* Add the tab */ | |
2586 tie.pszText = "-Empty-"; | |
2587 TabCtrl_InsertItem(s_tabhwnd, nr, &tie); | |
5286
74a211a0d3a3
updated for version 7.4b.019
Bram Moolenaar <bram@vim.org>
parents:
5225
diff
changeset
|
2588 tabadded = 1; |
810 | 2589 } |
2590 | |
839 | 2591 get_tabline_label(tp, FALSE); |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2592 tie.pszText = (LPSTR)NameBuff; |
837 | 2593 #ifdef FEAT_MBYTE |
2594 wstr = NULL; | |
838 | 2595 if (use_unicode) |
837 | 2596 { |
2597 /* Need to go through Unicode. */ | |
1752 | 2598 wstr = enc_to_utf16(NameBuff, NULL); |
837 | 2599 if (wstr != NULL) |
2600 { | |
2601 TCITEMW tiw; | |
2602 | |
2603 tiw.mask = TCIF_TEXT; | |
2604 tiw.iImage = -1; | |
2605 tiw.pszText = wstr; | |
1044 | 2606 SendMessage(s_tabhwnd, TCM_SETITEMW, (WPARAM)nr, (LPARAM)&tiw); |
837 | 2607 vim_free(wstr); |
2608 } | |
2609 } | |
2610 if (wstr == NULL) | |
2611 #endif | |
2612 { | |
2613 TabCtrl_SetItem(s_tabhwnd, nr, &tie); | |
2614 } | |
810 | 2615 } |
2616 | |
2617 /* Remove any old labels. */ | |
4009 | 2618 while (nr < TabCtrl_GetItemCount(s_tabhwnd)) |
810 | 2619 TabCtrl_DeleteItem(s_tabhwnd, nr); |
2620 | |
5286
74a211a0d3a3
updated for version 7.4b.019
Bram Moolenaar <bram@vim.org>
parents:
5225
diff
changeset
|
2621 if (!tabadded && TabCtrl_GetCurSel(s_tabhwnd) != curtabidx) |
74a211a0d3a3
updated for version 7.4b.019
Bram Moolenaar <bram@vim.org>
parents:
5225
diff
changeset
|
2622 TabCtrl_SetCurSel(s_tabhwnd, curtabidx); |
74a211a0d3a3
updated for version 7.4b.019
Bram Moolenaar <bram@vim.org>
parents:
5225
diff
changeset
|
2623 |
4015 | 2624 /* Re-enable redraw and redraw. */ |
4009 | 2625 SendMessage(s_tabhwnd, WM_SETREDRAW, (WPARAM)TRUE, 0); |
4015 | 2626 RedrawWindow(s_tabhwnd, NULL, NULL, |
2627 RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); | |
5216
947edb6335d1
updated for version 7.4a.034
Bram Moolenaar <bram@vim.org>
parents:
5166
diff
changeset
|
2628 |
5286
74a211a0d3a3
updated for version 7.4b.019
Bram Moolenaar <bram@vim.org>
parents:
5225
diff
changeset
|
2629 if (tabadded && TabCtrl_GetCurSel(s_tabhwnd) != curtabidx) |
5216
947edb6335d1
updated for version 7.4a.034
Bram Moolenaar <bram@vim.org>
parents:
5166
diff
changeset
|
2630 TabCtrl_SetCurSel(s_tabhwnd, curtabidx); |
810 | 2631 } |
2632 | |
2633 /* | |
2634 * Set the current tab to "nr". First tab is 1. | |
2635 */ | |
2636 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
2637 gui_mch_set_curtab(int nr) |
810 | 2638 { |
2639 if (s_tabhwnd == NULL) | |
2640 return; | |
2641 | |
5216
947edb6335d1
updated for version 7.4a.034
Bram Moolenaar <bram@vim.org>
parents:
5166
diff
changeset
|
2642 if (TabCtrl_GetCurSel(s_tabhwnd) != nr - 1) |
947edb6335d1
updated for version 7.4a.034
Bram Moolenaar <bram@vim.org>
parents:
5166
diff
changeset
|
2643 TabCtrl_SetCurSel(s_tabhwnd, nr - 1); |
810 | 2644 } |
2645 | |
2646 #endif | |
2647 | |
7 | 2648 /* |
2649 * ":simalt" command. | |
2650 */ | |
2651 void | |
2652 ex_simalt(exarg_T *eap) | |
2653 { | |
2654 char_u *keys = eap->arg; | |
2655 | |
2656 PostMessage(s_hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)0); | |
2657 while (*keys) | |
2658 { | |
2659 if (*keys == '~') | |
2660 *keys = ' '; /* for showing system menu */ | |
2661 PostMessage(s_hwnd, WM_CHAR, (WPARAM)*keys, (LPARAM)0); | |
2662 keys++; | |
2663 } | |
2664 } | |
2665 | |
2666 /* | |
2667 * Create the find & replace dialogs. | |
2668 * You can't have both at once: ":find" when replace is showing, destroys | |
2669 * the replace dialog first, and the other way around. | |
2670 */ | |
2671 #ifdef MSWIN_FIND_REPLACE | |
2672 static void | |
2673 initialise_findrep(char_u *initial_string) | |
2674 { | |
2675 int wword = FALSE; | |
2676 int mcase = !p_ic; | |
2677 char_u *entry_text; | |
2678 | |
2679 /* Get the search string to use. */ | |
2680 entry_text = get_find_dialog_text(initial_string, &wword, &mcase); | |
2681 | |
2682 s_findrep_struct.hwndOwner = s_hwnd; | |
2683 s_findrep_struct.Flags = FR_DOWN; | |
2684 if (mcase) | |
2685 s_findrep_struct.Flags |= FR_MATCHCASE; | |
2686 if (wword) | |
2687 s_findrep_struct.Flags |= FR_WHOLEWORD; | |
2688 if (entry_text != NULL && *entry_text != NUL) | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
2689 vim_strncpy((char_u *)s_findrep_struct.lpstrFindWhat, entry_text, |
417 | 2690 s_findrep_struct.wFindWhatLen - 1); |
7 | 2691 vim_free(entry_text); |
2692 } | |
2693 #endif | |
2694 | |
1035 | 2695 static void |
2696 set_window_title(HWND hwnd, char *title) | |
2697 { | |
2698 #ifdef FEAT_MBYTE | |
2699 if (title != NULL && enc_codepage >= 0 && enc_codepage != (int)GetACP()) | |
2700 { | |
2701 WCHAR *wbuf; | |
2702 int n; | |
2703 | |
1752 | 2704 /* Convert the title from 'encoding' to UTF-16. */ |
2705 wbuf = (WCHAR *)enc_to_utf16((char_u *)title, NULL); | |
1035 | 2706 if (wbuf != NULL) |
2707 { | |
2708 n = SetWindowTextW(hwnd, wbuf); | |
2709 vim_free(wbuf); | |
2710 if (n != 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) | |
2711 return; | |
2712 /* Retry with non-wide function (for Windows 98). */ | |
2713 } | |
2714 } | |
2715 #endif | |
2716 (void)SetWindowText(hwnd, (LPCSTR)title); | |
2717 } | |
2718 | |
7 | 2719 void |
2720 gui_mch_find_dialog(exarg_T *eap) | |
2721 { | |
2722 #ifdef MSWIN_FIND_REPLACE | |
2723 if (s_findrep_msg != 0) | |
2724 { | |
2725 if (IsWindow(s_findrep_hwnd) && !s_findrep_is_find) | |
2726 DestroyWindow(s_findrep_hwnd); | |
2727 | |
2728 if (!IsWindow(s_findrep_hwnd)) | |
2729 { | |
2730 initialise_findrep(eap->arg); | |
1795 | 2731 # if defined(FEAT_MBYTE) && defined(WIN3264) |
2732 /* If the OS is Windows NT, and 'encoding' differs from active | |
2733 * codepage: convert text and use wide function. */ | |
2734 if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT | |
2735 && enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
2736 { | |
2311
ccda151dde4e
Support completion for ":find". (Nazri Ramliy)
Bram Moolenaar <bram@vim.org>
parents:
2215
diff
changeset
|
2737 findrep_atow(&s_findrep_struct_w, &s_findrep_struct); |
1795 | 2738 s_findrep_hwnd = FindTextW( |
2739 (LPFINDREPLACEW) &s_findrep_struct_w); | |
2740 } | |
2741 else | |
2742 # endif | |
2743 s_findrep_hwnd = FindText((LPFINDREPLACE) &s_findrep_struct); | |
7 | 2744 } |
2745 | |
1035 | 2746 set_window_title(s_findrep_hwnd, |
2747 _("Find string (use '\\\\' to find a '\\')")); | |
7 | 2748 (void)SetFocus(s_findrep_hwnd); |
2749 | |
2750 s_findrep_is_find = TRUE; | |
2751 } | |
2752 #endif | |
2753 } | |
2754 | |
2755 | |
2756 void | |
2757 gui_mch_replace_dialog(exarg_T *eap) | |
2758 { | |
2759 #ifdef MSWIN_FIND_REPLACE | |
2760 if (s_findrep_msg != 0) | |
2761 { | |
2762 if (IsWindow(s_findrep_hwnd) && s_findrep_is_find) | |
2763 DestroyWindow(s_findrep_hwnd); | |
2764 | |
2765 if (!IsWindow(s_findrep_hwnd)) | |
2766 { | |
2767 initialise_findrep(eap->arg); | |
1795 | 2768 # if defined(FEAT_MBYTE) && defined(WIN3264) |
2769 if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT | |
2770 && enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
2771 { | |
2772 findrep_atow(&s_findrep_struct_w, &s_findrep_struct); | |
2773 s_findrep_hwnd = ReplaceTextW( | |
2774 (LPFINDREPLACEW) &s_findrep_struct_w); | |
2775 } | |
2776 else | |
2777 # endif | |
2778 s_findrep_hwnd = ReplaceText( | |
2779 (LPFINDREPLACE) &s_findrep_struct); | |
7 | 2780 } |
2781 | |
1035 | 2782 set_window_title(s_findrep_hwnd, |
2783 _("Find & Replace (use '\\\\' to find a '\\')")); | |
7 | 2784 (void)SetFocus(s_findrep_hwnd); |
2785 | |
2786 s_findrep_is_find = FALSE; | |
2787 } | |
2788 #endif | |
2789 } | |
2790 | |
2791 | |
2792 /* | |
2793 * Set visibility of the pointer. | |
2794 */ | |
2795 void | |
2796 gui_mch_mousehide(int hide) | |
2797 { | |
2798 if (hide != gui.pointer_hidden) | |
2799 { | |
2800 ShowCursor(!hide); | |
2801 gui.pointer_hidden = hide; | |
2802 } | |
2803 } | |
2804 | |
2805 #ifdef FEAT_MENU | |
2806 static void | |
2807 gui_mch_show_popupmenu_at(vimmenu_T *menu, int x, int y) | |
2808 { | |
2809 /* Unhide the mouse, we don't get move events here. */ | |
2810 gui_mch_mousehide(FALSE); | |
2811 | |
2812 (void)TrackPopupMenu( | |
2813 (HMENU)menu->submenu_id, | |
2814 TPM_LEFTALIGN | TPM_LEFTBUTTON, | |
2815 x, y, | |
2816 (int)0, /*reserved param*/ | |
2817 s_hwnd, | |
2818 NULL); | |
2819 /* | |
2820 * NOTE: The pop-up menu can eat the mouse up event. | |
2821 * We deal with this in normal.c. | |
2822 */ | |
2823 } | |
2824 #endif | |
2825 | |
2826 /* | |
2827 * Got a message when the system will go down. | |
2828 */ | |
2829 static void | |
2830 _OnEndSession(void) | |
2831 { | |
2832 getout_preserve_modified(1); | |
2833 } | |
2834 | |
2835 /* | |
2836 * Get this message when the user clicks on the cross in the top right corner | |
2837 * of a Windows95 window. | |
2838 */ | |
323 | 2839 /*ARGSUSED*/ |
7 | 2840 static void |
2841 _OnClose( | |
2842 HWND hwnd) | |
2843 { | |
2844 gui_shell_closed(); | |
2845 } | |
2846 | |
2847 /* | |
2848 * Get a message when the window is being destroyed. | |
2849 */ | |
2850 static void | |
2851 _OnDestroy( | |
2852 HWND hwnd) | |
2853 { | |
2854 #ifdef WIN16_3DLOOK | |
2855 Ctl3dUnregister(s_hinst); | |
2856 #endif | |
2857 if (!destroying) | |
2858 _OnClose(hwnd); | |
2859 } | |
2860 | |
2861 static void | |
2862 _OnPaint( | |
2863 HWND hwnd) | |
2864 { | |
2865 if (!IsMinimized(hwnd)) | |
2866 { | |
2867 PAINTSTRUCT ps; | |
2868 | |
2869 out_flush(); /* make sure all output has been processed */ | |
2870 (void)BeginPaint(hwnd, &ps); | |
6110 | 2871 #if defined(FEAT_DIRECTX) |
2872 if (IS_ENABLE_DIRECTX()) | |
2873 DWriteContext_BeginDraw(s_dwc); | |
2874 #endif | |
7 | 2875 |
2876 #ifdef FEAT_MBYTE | |
2877 /* prevent multi-byte characters from misprinting on an invalid | |
2878 * rectangle */ | |
2879 if (has_mbyte) | |
2880 { | |
2881 RECT rect; | |
2882 | |
2883 GetClientRect(hwnd, &rect); | |
2884 ps.rcPaint.left = rect.left; | |
2885 ps.rcPaint.right = rect.right; | |
2886 } | |
2887 #endif | |
2888 | |
2889 if (!IsRectEmpty(&ps.rcPaint)) | |
6110 | 2890 { |
2891 #if defined(FEAT_DIRECTX) | |
2892 if (IS_ENABLE_DIRECTX()) | |
2893 DWriteContext_BindDC(s_dwc, s_hdc, &ps.rcPaint); | |
2894 #endif | |
7 | 2895 gui_redraw(ps.rcPaint.left, ps.rcPaint.top, |
2896 ps.rcPaint.right - ps.rcPaint.left + 1, | |
2897 ps.rcPaint.bottom - ps.rcPaint.top + 1); | |
6110 | 2898 } |
2899 | |
2900 #if defined(FEAT_DIRECTX) | |
2901 if (IS_ENABLE_DIRECTX()) | |
2902 DWriteContext_EndDraw(s_dwc); | |
2903 #endif | |
7 | 2904 EndPaint(hwnd, &ps); |
2905 } | |
2906 } | |
2907 | |
323 | 2908 /*ARGSUSED*/ |
7 | 2909 static void |
2910 _OnSize( | |
2911 HWND hwnd, | |
2912 UINT state, | |
2913 int cx, | |
2914 int cy) | |
2915 { | |
2916 if (!IsMinimized(hwnd)) | |
2917 { | |
2918 gui_resize_shell(cx, cy); | |
2919 | |
2920 #ifdef FEAT_MENU | |
2921 /* Menu bar may wrap differently now */ | |
2922 gui_mswin_get_menu_height(TRUE); | |
2923 #endif | |
2924 } | |
2925 } | |
2926 | |
2927 static void | |
2928 _OnSetFocus( | |
2929 HWND hwnd, | |
2930 HWND hwndOldFocus) | |
2931 { | |
2932 gui_focus_change(TRUE); | |
1453 | 2933 s_getting_focus = TRUE; |
7 | 2934 (void)MyWindowProc(hwnd, WM_SETFOCUS, (WPARAM)hwndOldFocus, 0); |
2935 } | |
2936 | |
2937 static void | |
2938 _OnKillFocus( | |
2939 HWND hwnd, | |
2940 HWND hwndNewFocus) | |
2941 { | |
2942 gui_focus_change(FALSE); | |
1453 | 2943 s_getting_focus = FALSE; |
7 | 2944 (void)MyWindowProc(hwnd, WM_KILLFOCUS, (WPARAM)hwndNewFocus, 0); |
2945 } | |
2946 | |
2947 /* | |
2948 * Get a message when the user switches back to vim | |
2949 */ | |
2950 #ifdef WIN16 | |
2951 static BOOL | |
2952 #else | |
2953 static LRESULT | |
2954 #endif | |
2955 _OnActivateApp( | |
2956 HWND hwnd, | |
2957 BOOL fActivate, | |
2958 #ifdef WIN16 | |
2959 HTASK dwThreadId | |
2960 #else | |
2961 DWORD dwThreadId | |
2962 #endif | |
2963 ) | |
2964 { | |
2965 /* we call gui_focus_change() in _OnSetFocus() */ | |
2966 /* gui_focus_change((int)fActivate); */ | |
2967 return MyWindowProc(hwnd, WM_ACTIVATEAPP, fActivate, (DWORD)dwThreadId); | |
2968 } | |
2969 | |
2970 #if defined(FEAT_WINDOWS) || defined(PROTO) | |
2971 void | |
2972 gui_mch_destroy_scrollbar(scrollbar_T *sb) | |
2973 { | |
2974 DestroyWindow(sb->id); | |
2975 } | |
2976 #endif | |
2977 | |
2978 /* | |
87 | 2979 * Get current mouse coordinates in text window. |
7 | 2980 */ |
87 | 2981 void |
89 | 2982 gui_mch_getmouse(int *x, int *y) |
7 | 2983 { |
2984 RECT rct; | |
2985 POINT mp; | |
2986 | |
2987 (void)GetWindowRect(s_textArea, &rct); | |
2988 (void)GetCursorPos((LPPOINT)&mp); | |
87 | 2989 *x = (int)(mp.x - rct.left); |
2990 *y = (int)(mp.y - rct.top); | |
7 | 2991 } |
2992 | |
2993 /* | |
2994 * Move mouse pointer to character at (x, y). | |
2995 */ | |
2996 void | |
2997 gui_mch_setmouse(int x, int y) | |
2998 { | |
2999 RECT rct; | |
3000 | |
3001 (void)GetWindowRect(s_textArea, &rct); | |
3002 (void)SetCursorPos(x + gui.border_offset + rct.left, | |
3003 y + gui.border_offset + rct.top); | |
3004 } | |
3005 | |
3006 static void | |
3007 gui_mswin_get_valid_dimensions( | |
3008 int w, | |
3009 int h, | |
3010 int *valid_w, | |
3011 int *valid_h) | |
3012 { | |
3013 int base_width, base_height; | |
3014 | |
3015 base_width = gui_get_base_width() | |
5225
8f983df0299f
updated for version 7.4a.038
Bram Moolenaar <bram@vim.org>
parents:
5223
diff
changeset
|
3016 + (GetSystemMetrics(SM_CXFRAME) + |
7115
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3017 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; |
7 | 3018 base_height = gui_get_base_height() |
5225
8f983df0299f
updated for version 7.4a.038
Bram Moolenaar <bram@vim.org>
parents:
5223
diff
changeset
|
3019 + (GetSystemMetrics(SM_CYFRAME) + |
7115
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3020 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 |
7 | 3021 + GetSystemMetrics(SM_CYCAPTION) |
3022 #ifdef FEAT_MENU | |
3023 + gui_mswin_get_menu_height(FALSE) | |
3024 #endif | |
3025 ; | |
3026 *valid_w = base_width + | |
3027 ((w - base_width) / gui.char_width) * gui.char_width; | |
3028 *valid_h = base_height + | |
3029 ((h - base_height) / gui.char_height) * gui.char_height; | |
3030 } | |
3031 | |
3032 void | |
3033 gui_mch_flash(int msec) | |
3034 { | |
3035 RECT rc; | |
3036 | |
3037 /* | |
3038 * Note: InvertRect() excludes right and bottom of rectangle. | |
3039 */ | |
3040 rc.left = 0; | |
3041 rc.top = 0; | |
3042 rc.right = gui.num_cols * gui.char_width; | |
3043 rc.bottom = gui.num_rows * gui.char_height; | |
3044 InvertRect(s_hdc, &rc); | |
3045 gui_mch_flush(); /* make sure it's displayed */ | |
3046 | |
3047 ui_delay((long)msec, TRUE); /* wait for a few msec */ | |
3048 | |
3049 InvertRect(s_hdc, &rc); | |
3050 } | |
3051 | |
3052 /* | |
3053 * Return flags used for scrolling. | |
3054 * The SW_INVALIDATE is required when part of the window is covered or | |
3055 * off-screen. Refer to MS KB Q75236. | |
3056 */ | |
3057 static int | |
3058 get_scroll_flags(void) | |
3059 { | |
3060 HWND hwnd; | |
3061 RECT rcVim, rcOther, rcDest; | |
3062 | |
3063 GetWindowRect(s_hwnd, &rcVim); | |
281 | 3064 |
3065 /* Check if the window is partly above or below the screen. We don't care | |
3066 * about partly left or right of the screen, it is not relevant when | |
3067 * scrolling up or down. */ | |
3068 if (rcVim.top < 0 || rcVim.bottom > GetSystemMetrics(SM_CYFULLSCREEN)) | |
3069 return SW_INVALIDATE; | |
3070 | |
3071 /* Check if there is an window (partly) on top of us. */ | |
7 | 3072 for (hwnd = s_hwnd; (hwnd = GetWindow(hwnd, GW_HWNDPREV)) != (HWND)0; ) |
3073 if (IsWindowVisible(hwnd)) | |
3074 { | |
3075 GetWindowRect(hwnd, &rcOther); | |
3076 if (IntersectRect(&rcDest, &rcVim, &rcOther)) | |
3077 return SW_INVALIDATE; | |
3078 } | |
3079 return 0; | |
3080 } | |
3081 | |
3082 /* | |
7115
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3083 * On some Intel GPUs, the regions drawn just prior to ScrollWindowEx() |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3084 * may not be scrolled out properly. |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3085 * For gVim, when _OnScroll() is repeated, the character at the |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3086 * previous cursor position may be left drawn after scroll. |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3087 * The problem can be avoided by calling GetPixel() to get a pixel in |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3088 * the region before ScrollWindowEx(). |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3089 */ |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3090 static void |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3091 intel_gpu_workaround(void) |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3092 { |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3093 GetPixel(s_hdc, FILL_X(gui.col), FILL_Y(gui.row)); |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3094 } |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3095 |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3096 /* |
7 | 3097 * Delete the given number of lines from the given row, scrolling up any |
3098 * text further down within the scroll region. | |
3099 */ | |
3100 void | |
3101 gui_mch_delete_lines( | |
3102 int row, | |
3103 int num_lines) | |
3104 { | |
3105 RECT rc; | |
3106 | |
7115
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3107 intel_gpu_workaround(); |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3108 |
7 | 3109 rc.left = FILL_X(gui.scroll_region_left); |
3110 rc.right = FILL_X(gui.scroll_region_right + 1); | |
3111 rc.top = FILL_Y(row); | |
3112 rc.bottom = FILL_Y(gui.scroll_region_bot + 1); | |
3113 | |
3114 ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height, | |
3115 &rc, &rc, NULL, NULL, get_scroll_flags()); | |
3116 | |
3117 UpdateWindow(s_textArea); | |
3118 /* This seems to be required to avoid the cursor disappearing when | |
3119 * scrolling such that the cursor ends up in the top-left character on | |
3120 * the screen... But why? (Webb) */ | |
3121 /* It's probably fixed by disabling drawing the cursor while scrolling. */ | |
3122 /* gui.cursor_is_valid = FALSE; */ | |
3123 | |
3124 gui_clear_block(gui.scroll_region_bot - num_lines + 1, | |
3125 gui.scroll_region_left, | |
3126 gui.scroll_region_bot, gui.scroll_region_right); | |
3127 } | |
3128 | |
3129 /* | |
3130 * Insert the given number of lines before the given row, scrolling down any | |
3131 * following text within the scroll region. | |
3132 */ | |
3133 void | |
3134 gui_mch_insert_lines( | |
3135 int row, | |
3136 int num_lines) | |
3137 { | |
3138 RECT rc; | |
3139 | |
7115
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3140 intel_gpu_workaround(); |
ec89519dfeea
commit https://github.com/vim/vim/commit/3b59755862f4604ded8155404a1fe4c84c606829
Christian Brabandt <cb@256bit.org>
parents:
7109
diff
changeset
|
3141 |
7 | 3142 rc.left = FILL_X(gui.scroll_region_left); |
3143 rc.right = FILL_X(gui.scroll_region_right + 1); | |
3144 rc.top = FILL_Y(row); | |
3145 rc.bottom = FILL_Y(gui.scroll_region_bot + 1); | |
3146 /* The SW_INVALIDATE is required when part of the window is covered or | |
3147 * off-screen. How do we avoid it when it's not needed? */ | |
3148 ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height, | |
3149 &rc, &rc, NULL, NULL, get_scroll_flags()); | |
3150 | |
3151 UpdateWindow(s_textArea); | |
3152 | |
3153 gui_clear_block(row, gui.scroll_region_left, | |
3154 row + num_lines - 1, gui.scroll_region_right); | |
3155 } | |
3156 | |
3157 | |
323 | 3158 /*ARGSUSED*/ |
7 | 3159 void |
3160 gui_mch_exit(int rc) | |
3161 { | |
6110 | 3162 #if defined(FEAT_DIRECTX) |
3163 DWriteContext_Close(s_dwc); | |
3164 DWrite_Final(); | |
3165 s_dwc = NULL; | |
3166 #endif | |
3167 | |
7 | 3168 ReleaseDC(s_textArea, s_hdc); |
3169 DeleteObject(s_brush); | |
3170 | |
3171 #ifdef FEAT_TEAROFF | |
3172 /* Unload the tearoff bitmap */ | |
3173 (void)DeleteObject((HGDIOBJ)s_htearbitmap); | |
3174 #endif | |
3175 | |
3176 /* Destroy our window (if we have one). */ | |
3177 if (s_hwnd != NULL) | |
3178 { | |
3179 destroying = TRUE; /* ignore WM_DESTROY message now */ | |
3180 DestroyWindow(s_hwnd); | |
3181 } | |
3182 | |
3183 #ifdef GLOBAL_IME | |
3184 global_ime_end(); | |
3185 #endif | |
3186 } | |
3187 | |
37 | 3188 static char_u * |
3189 logfont2name(LOGFONT lf) | |
3190 { | |
3191 char *p; | |
3192 char *res; | |
3193 char *charset_name; | |
5714 | 3194 char *font_name = lf.lfFaceName; |
37 | 3195 |
3196 charset_name = charset_id2name((int)lf.lfCharSet); | |
5714 | 3197 #ifdef FEAT_MBYTE |
3198 /* Convert a font name from the current codepage to 'encoding'. | |
3199 * TODO: Use Wide APIs (including LOGFONTW) instead of ANSI APIs. */ | |
3200 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | |
3201 { | |
3202 int len; | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3203 acp_to_enc((char_u *)lf.lfFaceName, (int)strlen(lf.lfFaceName), |
5714 | 3204 (char_u **)&font_name, &len); |
3205 } | |
3206 #endif | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3207 res = (char *)alloc((unsigned)(strlen(font_name) + 20 |
37 | 3208 + (charset_name == NULL ? 0 : strlen(charset_name) + 2))); |
3209 if (res != NULL) | |
3210 { | |
3211 p = res; | |
3212 /* make a normal font string out of the lf thing:*/ | |
5714 | 3213 sprintf((char *)p, "%s:h%d", font_name, pixels_to_points( |
37 | 3214 lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight, TRUE)); |
3215 while (*p) | |
3216 { | |
3217 if (*p == ' ') | |
3218 *p = '_'; | |
3219 ++p; | |
3220 } | |
3221 #ifndef MSWIN16_FASTTEXT | |
3222 if (lf.lfItalic) | |
3223 STRCAT(p, ":i"); | |
3224 if (lf.lfWeight >= FW_BOLD) | |
3225 STRCAT(p, ":b"); | |
3226 #endif | |
3227 if (lf.lfUnderline) | |
3228 STRCAT(p, ":u"); | |
3229 if (lf.lfStrikeOut) | |
3230 STRCAT(p, ":s"); | |
3231 if (charset_name != NULL) | |
3232 { | |
3233 STRCAT(p, ":c"); | |
3234 STRCAT(p, charset_name); | |
3235 } | |
3236 } | |
3237 | |
5714 | 3238 #ifdef FEAT_MBYTE |
3239 if (font_name != lf.lfFaceName) | |
3240 vim_free(font_name); | |
3241 #endif | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3242 return (char_u *)res; |
37 | 3243 } |
3244 | |
4055 | 3245 |
3246 #ifdef FEAT_MBYTE_IME | |
3247 /* | |
3248 * Set correct LOGFONT to IME. Use 'guifontwide' if available, otherwise use | |
3249 * 'guifont' | |
3250 */ | |
3251 static void | |
5166
467efeee8f9e
updated for version 7.4a.009
Bram Moolenaar <bram@vim.org>
parents:
4950
diff
changeset
|
3252 update_im_font(void) |
4055 | 3253 { |
3254 LOGFONT lf_wide; | |
3255 | |
3256 if (p_guifontwide != NULL && *p_guifontwide != NUL | |
4059 | 3257 && gui.wide_font != NOFONT |
3258 && GetObject((HFONT)gui.wide_font, sizeof(lf_wide), &lf_wide)) | |
4055 | 3259 norm_logfont = lf_wide; |
3260 else | |
3261 norm_logfont = sub_logfont; | |
3262 im_set_font(&norm_logfont); | |
3263 } | |
3264 #endif | |
3265 | |
3266 #ifdef FEAT_MBYTE | |
3267 /* | |
3268 * Handler of gui.wide_font (p_guifontwide) changed notification. | |
3269 */ | |
3270 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
3271 gui_mch_wide_font_changed(void) |
4055 | 3272 { |
4950
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3273 # ifndef MSWIN16_FASTTEXT |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3274 LOGFONT lf; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3275 # endif |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3276 |
4055 | 3277 # ifdef FEAT_MBYTE_IME |
3278 update_im_font(); | |
3279 # endif | |
4950
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3280 |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3281 # ifndef MSWIN16_FASTTEXT |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3282 gui_mch_free_font(gui.wide_ital_font); |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3283 gui.wide_ital_font = NOFONT; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3284 gui_mch_free_font(gui.wide_bold_font); |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3285 gui.wide_bold_font = NOFONT; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3286 gui_mch_free_font(gui.wide_boldital_font); |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3287 gui.wide_boldital_font = NOFONT; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3288 |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3289 if (gui.wide_font |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3290 && GetObject((HFONT)gui.wide_font, sizeof(lf), &lf)) |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3291 { |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3292 if (!lf.lfItalic) |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3293 { |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3294 lf.lfItalic = TRUE; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3295 gui.wide_ital_font = get_font_handle(&lf); |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3296 lf.lfItalic = FALSE; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3297 } |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3298 if (lf.lfWeight < FW_BOLD) |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3299 { |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3300 lf.lfWeight = FW_BOLD; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3301 gui.wide_bold_font = get_font_handle(&lf); |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3302 if (!lf.lfItalic) |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3303 { |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3304 lf.lfItalic = TRUE; |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3305 gui.wide_boldital_font = get_font_handle(&lf); |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3306 } |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3307 } |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3308 } |
ba7db05e1482
updated for version 7.3.1220
Bram Moolenaar <bram@vim.org>
parents:
4352
diff
changeset
|
3309 # endif |
4055 | 3310 } |
3311 #endif | |
3312 | |
7 | 3313 /* |
37 | 3314 * Initialise vim to use the font with the given name. |
3315 * Return FAIL if the font could not be loaded, OK otherwise. | |
7 | 3316 */ |
323 | 3317 /*ARGSUSED*/ |
7 | 3318 int |
3319 gui_mch_init_font(char_u *font_name, int fontset) | |
3320 { | |
3321 LOGFONT lf; | |
3322 GuiFont font = NOFONT; | |
37 | 3323 char_u *p; |
7 | 3324 |
3325 /* Load the font */ | |
37 | 3326 if (get_logfont(&lf, font_name, NULL, TRUE) == OK) |
7 | 3327 font = get_font_handle(&lf); |
3328 if (font == NOFONT) | |
3329 return FAIL; | |
37 | 3330 |
7 | 3331 if (font_name == NULL) |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3332 font_name = (char_u *)lf.lfFaceName; |
7 | 3333 #if defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME) |
3334 norm_logfont = lf; | |
4055 | 3335 sub_logfont = lf; |
7 | 3336 #endif |
3337 #ifdef FEAT_MBYTE_IME | |
4055 | 3338 update_im_font(); |
7 | 3339 #endif |
3340 gui_mch_free_font(gui.norm_font); | |
3341 gui.norm_font = font; | |
3342 current_font_height = lf.lfHeight; | |
3343 GetFontSize(font); | |
37 | 3344 |
3345 p = logfont2name(lf); | |
3346 if (p != NULL) | |
7 | 3347 { |
37 | 3348 hl_set_font_name(p); |
3349 | |
3350 /* When setting 'guifont' to "*" replace it with the actual font name. | |
3351 * */ | |
3352 if (STRCMP(font_name, "*") == 0 && STRCMP(p_guifont, "*") == 0) | |
7 | 3353 { |
3354 vim_free(p_guifont); | |
3355 p_guifont = p; | |
3356 } | |
37 | 3357 else |
3358 vim_free(p); | |
7 | 3359 } |
3360 | |
3361 #ifndef MSWIN16_FASTTEXT | |
3362 gui_mch_free_font(gui.ital_font); | |
3363 gui.ital_font = NOFONT; | |
3364 gui_mch_free_font(gui.bold_font); | |
3365 gui.bold_font = NOFONT; | |
3366 gui_mch_free_font(gui.boldital_font); | |
3367 gui.boldital_font = NOFONT; | |
3368 | |
3369 if (!lf.lfItalic) | |
3370 { | |
3371 lf.lfItalic = TRUE; | |
3372 gui.ital_font = get_font_handle(&lf); | |
3373 lf.lfItalic = FALSE; | |
3374 } | |
3375 if (lf.lfWeight < FW_BOLD) | |
3376 { | |
3377 lf.lfWeight = FW_BOLD; | |
3378 gui.bold_font = get_font_handle(&lf); | |
3379 if (!lf.lfItalic) | |
3380 { | |
3381 lf.lfItalic = TRUE; | |
3382 gui.boldital_font = get_font_handle(&lf); | |
3383 } | |
3384 } | |
3385 #endif | |
3386 | |
3387 return OK; | |
3388 } | |
3389 | |
1044 | 3390 #ifndef WPF_RESTORETOMAXIMIZED |
3391 # define WPF_RESTORETOMAXIMIZED 2 /* just in case someone doesn't have it */ | |
3392 #endif | |
3393 | |
7 | 3394 /* |
3395 * Return TRUE if the GUI window is maximized, filling the whole screen. | |
3396 */ | |
3397 int | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
3398 gui_mch_maximized(void) |
7 | 3399 { |
1044 | 3400 WINDOWPLACEMENT wp; |
3401 | |
3402 wp.length = sizeof(WINDOWPLACEMENT); | |
3403 if (GetWindowPlacement(s_hwnd, &wp)) | |
3404 return wp.showCmd == SW_SHOWMAXIMIZED | |
3405 || (wp.showCmd == SW_SHOWMINIMIZED | |
3406 && wp.flags == WPF_RESTORETOMAXIMIZED); | |
3407 | |
3408 return 0; | |
7 | 3409 } |
3410 | |
3411 /* | |
3412 * Called when the font changed while the window is maximized. Compute the | |
3413 * new Rows and Columns. This is like resizing the window. | |
3414 */ | |
3415 void | |
7823
bcef391c101c
commit https://github.com/vim/vim/commit/68c2f638e65d914dc6e84eb7ce2624f08af525c0
Christian Brabandt <cb@256bit.org>
parents:
7801
diff
changeset
|
3416 gui_mch_newfont(void) |
7 | 3417 { |
3418 RECT rect; | |
3419 | |
3420 GetWindowRect(s_hwnd, &rect); | |
7125
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3421 if (win_socket_id == 0) |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3422 { |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3423 gui_resize_shell(rect.right - rect.left |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3424 - (GetSystemMetrics(SM_CXFRAME) + |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3425 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2, |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3426 rect.bottom - rect.top |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3427 - (GetSystemMetrics(SM_CYFRAME) + |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3428 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3429 - GetSystemMetrics(SM_CYCAPTION) |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3430 #ifdef FEAT_MENU |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3431 - gui_mswin_get_menu_height(FALSE) |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3432 #endif |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3433 ); |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3434 } |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3435 else |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3436 { |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3437 /* Inside another window, don't use the frame and border. */ |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3438 gui_resize_shell(rect.right - rect.left, |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3439 rect.bottom - rect.top |
7 | 3440 #ifdef FEAT_MENU |
3441 - gui_mswin_get_menu_height(FALSE) | |
3442 #endif | |
7125
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3443 ); |
52a7ba315f03
commit https://github.com/vim/vim/commit/8919554fe17255cddbbce6b833fab9aba19c8b88
Christian Brabandt <cb@256bit.org>
parents:
7115
diff
changeset
|
3444 } |
7 | 3445 } |
3446 | |
3447 /* | |
3448 * Set the window title | |
3449 */ | |
323 | 3450 /*ARGSUSED*/ |
7 | 3451 void |
3452 gui_mch_settitle( | |
3453 char_u *title, | |
3454 char_u *icon) | |
3455 { | |
1035 | 3456 set_window_title(s_hwnd, (title == NULL ? "VIM" : (char *)title)); |
7 | 3457 } |
3458 | |
3459 #ifdef FEAT_MOUSESHAPE | |
3460 /* Table for shape IDCs. Keep in sync with the mshape_names[] table in | |
3461 * misc2.c! */ | |
3462 static LPCSTR mshape_idcs[] = | |
3463 { | |
4238 | 3464 IDC_ARROW, /* arrow */ |
3465 MAKEINTRESOURCE(0), /* blank */ | |
3466 IDC_IBEAM, /* beam */ | |
3467 IDC_SIZENS, /* updown */ | |
3468 IDC_SIZENS, /* udsizing */ | |
3469 IDC_SIZEWE, /* leftright */ | |
3470 IDC_SIZEWE, /* lrsizing */ | |
3471 IDC_WAIT, /* busy */ | |
7 | 3472 #ifdef WIN3264 |
4238 | 3473 IDC_NO, /* no */ |
7 | 3474 #else |
4238 | 3475 IDC_ICON, /* no */ |
7 | 3476 #endif |
4238 | 3477 IDC_ARROW, /* crosshair */ |
3478 IDC_ARROW, /* hand1 */ | |
3479 IDC_ARROW, /* hand2 */ | |
3480 IDC_ARROW, /* pencil */ | |
3481 IDC_ARROW, /* question */ | |
3482 IDC_ARROW, /* right-arrow */ | |
3483 IDC_UPARROW, /* up-arrow */ | |
3484 IDC_ARROW /* last one */ | |
7 | 3485 }; |
3486 | |
3487 void | |
3488 mch_set_mouse_shape(int shape) | |
3489 { | |
3490 LPCSTR idc; | |
3491 | |
3492 if (shape == MSHAPE_HIDE) | |
3493 ShowCursor(FALSE); | |
3494 else | |
3495 { | |
3496 if (shape >= MSHAPE_NUMBERED) | |
4238 | 3497 idc = IDC_ARROW; |
7 | 3498 else |
3499 idc = mshape_idcs[shape]; | |
1686 | 3500 #ifdef SetClassLongPtr |
3501 SetClassLongPtr(s_textArea, GCLP_HCURSOR, (__int3264)(LONG_PTR)LoadCursor(NULL, idc)); | |
7 | 3502 #else |
3503 # ifdef WIN32 | |
1686 | 3504 SetClassLong(s_textArea, GCL_HCURSOR, (long_u)LoadCursor(NULL, idc)); |
3505 # else /* Win16 */ | |
7 | 3506 SetClassWord(s_textArea, GCW_HCURSOR, (WORD)LoadCursor(NULL, idc)); |
3507 # endif | |
3508 #endif | |
3509 if (!p_mh) | |
3510 { | |
3511 POINT mp; | |
3512 | |
3513 /* Set the position to make it redrawn with the new shape. */ | |
3514 (void)GetCursorPos((LPPOINT)&mp); | |
3515 (void)SetCursorPos(mp.x, mp.y); | |
3516 ShowCursor(TRUE); | |
3517 } | |
3518 } | |
3519 } | |
3520 #endif | |
3521 | |
3522 #ifdef FEAT_BROWSE | |
3523 /* | |
3524 * The file browser exists in two versions: with "W" uses wide characters, | |
3525 * without "W" the current codepage. When FEAT_MBYTE is defined and on | |
3526 * Windows NT/2000/XP the "W" functions are used. | |
3527 */ | |
3528 | |
3529 # if defined(FEAT_MBYTE) && defined(WIN3264) | |
3530 /* | |
3275 | 3531 * Wide version of convert_filter(). |
7 | 3532 */ |
3533 static WCHAR * | |
3534 convert_filterW(char_u *s) | |
3535 { | |
3275 | 3536 char_u *tmp; |
3537 int len; | |
3279 | 3538 WCHAR *res; |
3275 | 3539 |
3540 tmp = convert_filter(s); | |
3541 if (tmp == NULL) | |
3542 return NULL; | |
3543 len = (int)STRLEN(s) + 3; | |
3544 res = enc_to_utf16(tmp, &len); | |
3545 vim_free(tmp); | |
7 | 3546 return res; |
3547 } | |
3548 | |
3549 /* | |
3550 * Wide version of gui_mch_browse(). Keep in sync! | |
3551 */ | |
3552 static char_u * | |
3553 gui_mch_browseW( | |
3554 int saving, | |
3555 char_u *title, | |
3556 char_u *dflt, | |
3557 char_u *ext, | |
3558 char_u *initdir, | |
3559 char_u *filter) | |
3560 { | |
1752 | 3561 /* We always use the wide function. This means enc_to_utf16() must work, |
7 | 3562 * otherwise it fails miserably! */ |
3563 OPENFILENAMEW fileStruct; | |
3564 WCHAR fileBuf[MAXPATHL]; | |
3565 WCHAR *wp; | |
3566 int i; | |
3567 WCHAR *titlep = NULL; | |
3568 WCHAR *extp = NULL; | |
3569 WCHAR *initdirp = NULL; | |
3570 WCHAR *filterp; | |
3571 char_u *p; | |
3572 | |
3573 if (dflt == NULL) | |
3574 fileBuf[0] = NUL; | |
3575 else | |
3576 { | |
1752 | 3577 wp = enc_to_utf16(dflt, NULL); |
7 | 3578 if (wp == NULL) |
3579 fileBuf[0] = NUL; | |
3580 else | |
3581 { | |
3582 for (i = 0; wp[i] != NUL && i < MAXPATHL - 1; ++i) | |
3583 fileBuf[i] = wp[i]; | |
3584 fileBuf[i] = NUL; | |
3585 vim_free(wp); | |
3586 } | |
3587 } | |
3588 | |
3589 /* Convert the filter to Windows format. */ | |
3590 filterp = convert_filterW(filter); | |
3591 | |
2215
cccb71c2c5c1
Fix uninit memory read in undo code. Fix uint32_t in proto file.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
3592 vim_memset(&fileStruct, 0, sizeof(OPENFILENAMEW)); |
7 | 3593 #ifdef OPENFILENAME_SIZE_VERSION_400 |
3594 /* be compatible with Windows NT 4.0 */ | |
3595 /* TODO: what to use for OPENFILENAMEW??? */ | |
2081
7b0e89b77216
updated for version 7.2.365
Bram Moolenaar <bram@zimbu.org>
parents:
2078
diff
changeset
|
3596 fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400; |
7 | 3597 #else |
3598 fileStruct.lStructSize = sizeof(fileStruct); | |
3599 #endif | |
3600 | |
3601 if (title != NULL) | |
1752 | 3602 titlep = enc_to_utf16(title, NULL); |
7 | 3603 fileStruct.lpstrTitle = titlep; |
3604 | |
3605 if (ext != NULL) | |
1752 | 3606 extp = enc_to_utf16(ext, NULL); |
7 | 3607 fileStruct.lpstrDefExt = extp; |
3608 | |
3609 fileStruct.lpstrFile = fileBuf; | |
3610 fileStruct.nMaxFile = MAXPATHL; | |
3611 fileStruct.lpstrFilter = filterp; | |
3612 fileStruct.hwndOwner = s_hwnd; /* main Vim window is owner*/ | |
3613 /* has an initial dir been specified? */ | |
3614 if (initdir != NULL && *initdir != NUL) | |
3615 { | |
3616 /* Must have backslashes here, no matter what 'shellslash' says */ | |
1752 | 3617 initdirp = enc_to_utf16(initdir, NULL); |
7 | 3618 if (initdirp != NULL) |
3619 { | |
3620 for (wp = initdirp; *wp != NUL; ++wp) | |
3621 if (*wp == '/') | |
3622 *wp = '\\'; | |
3623 } | |
3624 fileStruct.lpstrInitialDir = initdirp; | |
3625 } | |
3626 | |
3627 /* | |
3628 * TODO: Allow selection of multiple files. Needs another arg to this | |
3629 * function to ask for it, and need to use OFN_ALLOWMULTISELECT below. | |
3630 * Also, should we use OFN_FILEMUSTEXIST when opening? Vim can edit on | |
3631 * files that don't exist yet, so I haven't put it in. What about | |
3632 * OFN_PATHMUSTEXIST? | |
3633 * Don't use OFN_OVERWRITEPROMPT, Vim has its own ":confirm" dialog. | |
3634 */ | |
3635 fileStruct.Flags = (OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY); | |
3636 #ifdef FEAT_SHORTCUT | |
3637 if (curbuf->b_p_bin) | |
3638 fileStruct.Flags |= OFN_NODEREFERENCELINKS; | |
3639 #endif | |
3640 if (saving) | |
3641 { | |
3642 if (!GetSaveFileNameW(&fileStruct)) | |
3643 return NULL; | |
3644 } | |
3645 else | |
3646 { | |
3647 if (!GetOpenFileNameW(&fileStruct)) | |
3648 return NULL; | |
3649 } | |
3650 | |
3651 vim_free(filterp); | |
3652 vim_free(initdirp); | |
3653 vim_free(titlep); | |
3654 vim_free(extp); | |
3655 | |
3656 /* Convert from UCS2 to 'encoding'. */ | |
1752 | 3657 p = utf16_to_enc(fileBuf, NULL); |
7 | 3658 if (p != NULL) |
3659 /* when out of memory we get garbage for non-ASCII chars */ | |
3660 STRCPY(fileBuf, p); | |
3661 vim_free(p); | |
3662 | |
3663 /* Give focus back to main window (when using MDI). */ | |
3664 SetFocus(s_hwnd); | |
3665 | |
3666 /* Shorten the file name if possible */ | |
1411 | 3667 return vim_strsave(shorten_fname1((char_u *)fileBuf)); |
7 | 3668 } |
3669 # endif /* FEAT_MBYTE */ | |
3670 | |
3671 | |
3672 /* | |
3673 * Convert the string s to the proper format for a filter string by replacing | |
1738 | 3674 * the \t and \n delimiters with \0. |
7 | 3675 * Returns the converted string in allocated memory. |
3676 * | |
3677 * Keep in sync with convert_filterW() above! | |
3678 */ | |
3679 static char_u * | |
3680 convert_filter(char_u *s) | |
3681 { | |
3682 char_u *res; | |
3683 unsigned s_len = (unsigned)STRLEN(s); | |
3684 unsigned i; | |
3685 | |
3686 res = alloc(s_len + 3); | |
3687 if (res != NULL) | |
3688 { | |
3689 for (i = 0; i < s_len; ++i) | |
3690 if (s[i] == '\t' || s[i] == '\n') | |
3691 res[i] = '\0'; | |
3692 else | |
3693 res[i] = s[i]; | |
3694 res[s_len] = NUL; | |
3695 /* Add two extra NULs to make sure it's properly terminated. */ | |
3696 res[s_len + 1] = NUL; | |
3697 res[s_len + 2] = NUL; | |
3698 } | |
3699 return res; | |
3700 } | |
3701 | |
3702 /* | |
28 | 3703 * Select a directory. |
3704 */ | |
3705 char_u * | |
3706 gui_mch_browsedir(char_u *title, char_u *initdir) | |
3707 { | |
3708 /* We fake this: Use a filter that doesn't select anything and a default | |
3709 * file name that won't be used. */ | |
3710 return gui_mch_browse(0, title, (char_u *)_("Not Used"), NULL, | |
3711 initdir, (char_u *)_("Directory\t*.nothing\n")); | |
3712 } | |
3713 | |
3714 /* | |
7 | 3715 * Pop open a file browser and return the file selected, in allocated memory, |
3716 * or NULL if Cancel is hit. | |
3717 * saving - TRUE if the file will be saved to, FALSE if it will be opened. | |
3718 * title - Title message for the file browser dialog. | |
3719 * dflt - Default name of file. | |
3720 * ext - Default extension to be added to files without extensions. | |
3721 * initdir - directory in which to open the browser (NULL = current dir) | |
3722 * filter - Filter for matched files to choose from. | |
3723 * | |
3724 * Keep in sync with gui_mch_browseW() above! | |
3725 */ | |
3726 char_u * | |
3727 gui_mch_browse( | |
3728 int saving, | |
3729 char_u *title, | |
3730 char_u *dflt, | |
3731 char_u *ext, | |
3732 char_u *initdir, | |
3733 char_u *filter) | |
3734 { | |
3735 OPENFILENAME fileStruct; | |
3736 char_u fileBuf[MAXPATHL]; | |
3737 char_u *initdirp = NULL; | |
3738 char_u *filterp; | |
3739 char_u *p; | |
3740 | |
3741 # if defined(FEAT_MBYTE) && defined(WIN3264) | |
3742 if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT) | |
3743 return gui_mch_browseW(saving, title, dflt, ext, initdir, filter); | |
3744 # endif | |
3745 | |
3746 if (dflt == NULL) | |
3747 fileBuf[0] = NUL; | |
3748 else | |
417 | 3749 vim_strncpy(fileBuf, dflt, MAXPATHL - 1); |
7 | 3750 |
3751 /* Convert the filter to Windows format. */ | |
3752 filterp = convert_filter(filter); | |
3753 | |
2215
cccb71c2c5c1
Fix uninit memory read in undo code. Fix uint32_t in proto file.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
3754 vim_memset(&fileStruct, 0, sizeof(OPENFILENAME)); |
7 | 3755 #ifdef OPENFILENAME_SIZE_VERSION_400 |
3756 /* be compatible with Windows NT 4.0 */ | |
2081
7b0e89b77216
updated for version 7.2.365
Bram Moolenaar <bram@zimbu.org>
parents:
2078
diff
changeset
|
3757 fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400; |
7 | 3758 #else |
3759 fileStruct.lStructSize = sizeof(fileStruct); | |
3760 #endif | |
3761 | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3762 fileStruct.lpstrTitle = (LPSTR)title; |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3763 fileStruct.lpstrDefExt = (LPSTR)ext; |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3764 |
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3765 fileStruct.lpstrFile = (LPSTR)fileBuf; |
7 | 3766 fileStruct.nMaxFile = MAXPATHL; |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3767 fileStruct.lpstrFilter = (LPSTR)filterp; |
7 | 3768 fileStruct.hwndOwner = s_hwnd; /* main Vim window is owner*/ |
3769 /* has an initial dir been specified? */ | |
3770 if (initdir != NULL && *initdir != NUL) | |
3771 { | |
3772 /* Must have backslashes here, no matter what 'shellslash' says */ | |
3773 initdirp = vim_strsave(initdir); | |
3774 if (initdirp != NULL) | |
3775 for (p = initdirp; *p != NUL; ++p) | |
3776 if (*p == '/') | |
3777 *p = '\\'; | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3778 fileStruct.lpstrInitialDir = (LPSTR)initdirp; |
7 | 3779 } |
3780 | |
3781 /* | |
3782 * TODO: Allow selection of multiple files. Needs another arg to this | |
3783 * function to ask for it, and need to use OFN_ALLOWMULTISELECT below. | |
3784 * Also, should we use OFN_FILEMUSTEXIST when opening? Vim can edit on | |
3785 * files that don't exist yet, so I haven't put it in. What about | |
3786 * OFN_PATHMUSTEXIST? | |
3787 * Don't use OFN_OVERWRITEPROMPT, Vim has its own ":confirm" dialog. | |
3788 */ | |
3789 fileStruct.Flags = (OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY); | |
3790 #ifdef FEAT_SHORTCUT | |
3791 if (curbuf->b_p_bin) | |
3792 fileStruct.Flags |= OFN_NODEREFERENCELINKS; | |
3793 #endif | |
3794 if (saving) | |
3795 { | |
3796 if (!GetSaveFileName(&fileStruct)) | |
3797 return NULL; | |
3798 } | |
3799 else | |
3800 { | |
3801 if (!GetOpenFileName(&fileStruct)) | |
3802 return NULL; | |
3803 } | |
3804 | |
3805 vim_free(filterp); | |
3806 vim_free(initdirp); | |
3807 | |
3808 /* Give focus back to main window (when using MDI). */ | |
3809 SetFocus(s_hwnd); | |
3810 | |
3811 /* Shorten the file name if possible */ | |
1411 | 3812 return vim_strsave(shorten_fname1((char_u *)fileBuf)); |
7 | 3813 } |
3814 #endif /* FEAT_BROWSE */ | |
3815 | |
323 | 3816 /*ARGSUSED*/ |
7 | 3817 static void |
3818 _OnDropFiles( | |
3819 HWND hwnd, | |
3820 HDROP hDrop) | |
3821 { | |
3822 #ifdef FEAT_WINDOWS | |
3823 #ifdef WIN3264 | |
3824 # define BUFPATHLEN _MAX_PATH | |
3825 # define DRAGQVAL 0xFFFFFFFF | |
3826 #else | |
3827 # define BUFPATHLEN MAXPATHL | |
3828 # define DRAGQVAL 0xFFFF | |
3829 #endif | |
3830 #ifdef FEAT_MBYTE | |
3831 WCHAR wszFile[BUFPATHLEN]; | |
3832 #endif | |
3833 char szFile[BUFPATHLEN]; | |
3834 UINT cFiles = DragQueryFile(hDrop, DRAGQVAL, NULL, 0); | |
3835 UINT i; | |
3836 char_u **fnames; | |
3837 POINT pt; | |
3838 int_u modifiers = 0; | |
3839 | |
3840 /* TRACE("_OnDropFiles: %d files dropped\n", cFiles); */ | |
3841 | |
3842 /* Obtain dropped position */ | |
3843 DragQueryPoint(hDrop, &pt); | |
3844 MapWindowPoints(s_hwnd, s_textArea, &pt, 1); | |
3845 | |
3846 reset_VIsual(); | |
3847 | |
3848 fnames = (char_u **)alloc(cFiles * sizeof(char_u *)); | |
3849 | |
3850 if (fnames != NULL) | |
3851 for (i = 0; i < cFiles; ++i) | |
3852 { | |
3853 #ifdef FEAT_MBYTE | |
3854 if (DragQueryFileW(hDrop, i, wszFile, BUFPATHLEN) > 0) | |
1752 | 3855 fnames[i] = utf16_to_enc(wszFile, NULL); |
7 | 3856 else |
3857 #endif | |
3858 { | |
3859 DragQueryFile(hDrop, i, szFile, BUFPATHLEN); | |
8090
54cfe888c627
commit https://github.com/vim/vim/commit/418f81b5fa400ed59793384f2f3d9df45390f080
Christian Brabandt <cb@256bit.org>
parents:
8047
diff
changeset
|
3860 fnames[i] = vim_strsave((char_u *)szFile); |
7 | 3861 } |
3862 } | |
3863 | |
3864 DragFinish(hDrop); | |
3865 | |
3866 if (fnames != NULL) | |
3867 { | |
3868 if ((GetKeyState(VK_SHIFT) & 0x8000) != 0) | |
3869 modifiers |= MOUSE_SHIFT; | |
3870 if ((GetKeyState(VK_CONTROL) & 0x8000) != 0) | |
3871 modifiers |= MOUSE_CTRL; | |
3872 if ((GetKeyState(VK_MENU) & 0x8000) != 0) | |
3873 modifiers |= MOUSE_ALT; | |
3874 | |
3875 gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles); | |
3876 | |
3877 s_need_activate = TRUE; | |
3878 } | |
3879 #endif | |
3880 } | |
3881 | |
323 | 3882 /*ARGSUSED*/ |
7 | 3883 static int |
3884 _OnScroll( | |
3885 HWND hwnd, | |
3886 HWND hwndCtl, | |
3887 UINT code, | |
3888 int pos) | |
3889 { | |
3890 static UINT prev_code = 0; /* code of previous call */ | |
3891 scrollbar_T *sb, *sb_info; | |
3892 long val; | |
3893 int dragging = FALSE; | |
3894 int dont_scroll_save = dont_scroll; | |
3895 #ifndef WIN3264 | |
3896 int nPos; | |
3897 #else | |
3898 SCROLLINFO si; | |
3899 | |
3900 si.cbSize = sizeof(si); | |
3901 si.fMask = SIF_POS; | |
3902 #endif | |
3903 | |
3904 sb = gui_mswin_find_scrollbar(hwndCtl); | |
3905 if (sb == NULL) | |
3906 return 0; | |
3907 | |
3908 if (sb->wp != NULL) /* Left or right scrollbar */ | |
3909 { | |
3910 /* | |
3911 * Careful: need to get scrollbar info out of first (left) scrollbar | |
3912 * for window, but keep real scrollbar too because we must pass it to | |
3913 * gui_drag_scrollbar(). | |
3914 */ | |
3915 sb_info = &sb->wp->w_scrollbars[0]; | |
3916 } | |
3917 else /* Bottom scrollbar */ | |
3918 sb_info = sb; | |
3919 val = sb_info->value; | |
3920 | |
3921 switch (code) | |
3922 { | |
3923 case SB_THUMBTRACK: | |
3924 val = pos; | |
3925 dragging = TRUE; | |
3926 if (sb->scroll_shift > 0) | |
3927 val <<= sb->scroll_shift; | |
3928 break; | |
3929 case SB_LINEDOWN: | |
3930 val++; | |
3931 break; | |
3932 case SB_LINEUP: | |
3933 val--; | |
3934 break; | |
3935 case SB_PAGEDOWN: | |
3936 val += (sb_info->size > 2 ? sb_info->size - 2 : 1); | |
3937 break; | |
3938 case SB_PAGEUP: | |
3939 val -= (sb_info->size > 2 ? sb_info->size - 2 : 1); | |
3940 break; | |
3941 case SB_TOP: | |
3942 val = 0; | |
3943 break; | |
3944 case SB_BOTTOM: | |
3945 val = sb_info->max; | |
3946 break; | |
3947 case SB_ENDSCROLL: | |
3948 if (prev_code == SB_THUMBTRACK) | |
3949 { | |
3950 /* | |
3951 * "pos" only gives us 16-bit data. In case of large file, | |
3952 * use GetScrollPos() which returns 32-bit. Unfortunately it | |
3953 * is not valid while the scrollbar is being dragged. | |
3954 */ | |
3955 val = GetScrollPos(hwndCtl, SB_CTL); | |
3956 if (sb->scroll_shift > 0) | |
3957 val <<= sb->scroll_shift; | |
3958 } | |
3959 break; | |
3960 | |
3961 default: | |
3962 /* TRACE("Unknown scrollbar event %d\n", code); */ | |
3963 return 0; | |
3964 } | |
3965 prev_code = code; | |
3966 | |
3967 #ifdef WIN3264 | |
3968 si.nPos = (sb->scroll_shift > 0) ? val >> sb->scroll_shift : val; | |
3969 SetScrollInfo(hwndCtl, SB_CTL, &si, TRUE); | |
3970 #else | |
3971 nPos = (sb->scroll_shift > 0) ? val >> sb->scroll_shift : val; | |
3972 SetScrollPos(hwndCtl, SB_CTL, nPos, TRUE); | |
3973 #endif | |
3974 | |
3975 /* | |
3976 * When moving a vertical scrollbar, move the other vertical scrollbar too. | |
3977 */ | |
3978 if (sb->wp != NULL) | |
3979 { | |
3980 scrollbar_T *sba = sb->wp->w_scrollbars; | |
3981 HWND id = sba[ (sb == sba + SBAR_LEFT) ? SBAR_RIGHT : SBAR_LEFT].id; | |
3982 | |
3983 #ifdef WIN3264 | |
3984 SetScrollInfo(id, SB_CTL, &si, TRUE); | |
3985 #else | |
3986 SetScrollPos(id, SB_CTL, nPos, TRUE); | |
3987 #endif | |
3988 } | |
3989 | |
3990 /* Don't let us be interrupted here by another message. */ | |
3991 s_busy_processing = TRUE; | |
3992 | |
3993 /* When "allow_scrollbar" is FALSE still need to remember the new | |
3994 * position, but don't actually scroll by setting "dont_scroll". */ | |
3995 dont_scroll = !allow_scrollbar; | |
3996 | |
3997 gui_drag_scrollbar(sb, val, dragging); | |
3998 | |
3999 s_busy_processing = FALSE; | |
4000 dont_scroll = dont_scroll_save; | |
4001 | |
4002 return 0; | |
4003 } | |
4004 | |
26 | 4005 |
7 | 4006 /* |
4007 * Get command line arguments. | |
4008 * Use "prog" as the name of the program and "cmdline" as the arguments. | |
4009 * Copy the arguments to allocated memory. | |
4010 * Return the number of arguments (including program name). | |
1738 | 4011 * Return pointers to the arguments in "argvp". Memory is allocated with |
4012 * malloc(), use free() instead of vim_free(). | |
7 | 4013 * Return pointer to buffer in "tofree". |
4014 * Returns zero when out of memory. | |
4015 */ | |
323 | 4016 /*ARGSUSED*/ |
7 | 4017 int |
4018 get_cmd_args(char *prog, char *cmdline, char ***argvp, char **tofree) | |
4019 { | |
4020 int i; | |
4021 char *p; | |
4022 char *progp; | |
4023 char *pnew = NULL; | |
4024 char *newcmdline; | |
4025 int inquote; | |
4026 int argc; | |
4027 char **argv = NULL; | |
4028 int round; | |
4029 | |
1738 | 4030 *tofree = NULL; |
4031 | |
26 | 4032 #ifdef FEAT_MBYTE |
4033 /* Try using the Unicode version first, it takes care of conversion when | |
4034 * 'encoding' is changed. */ | |
4035 argc = get_cmd_argsW(&argv); | |
4036 if (argc != 0) | |
4037 goto done; | |
4038 #endif | |
4039 | |
7 | 4040 /* Handle the program name. Remove the ".exe" extension, and find the 1st |
4041 * non-space. */ | |
4042 p = strrchr(prog, '.'); | |
4043 if (p != NULL) | |
4044 *p = NUL; | |
4045 for (progp = prog; *progp == ' '; ++progp) | |
4046 ; | |
4047 | |
4048 /* The command line is copied to allocated memory, so that we can change | |
4049 * it. Add the size of the string, the separating NUL and a terminating | |
4050 * NUL. */ | |
4051 newcmdline = malloc(STRLEN(cmdline) + STRLEN(progp) + 2); | |
4052 if (newcmdline == NULL) | |
4053 return 0; | |
4054 | |
4055 /* | |
4056 * First round: count the number of arguments ("pnew" == NULL). | |
4057 * Second round: produce the arguments. | |
4058 */ | |
4059 for (round = 1; round <= 2; ++round) | |
4060 { | |
4061 /* First argument is the program name. */ | |
4062 if (pnew != NULL) | |
4063 { | |
4064 argv[0] = pnew; | |
4065 strcpy(pnew, progp); | |
4066 pnew += strlen(pnew); | |
4067 *pnew++ = NUL; | |
4068 } | |
4069 | |
4070 /* | |
4071 * Isolate each argument and put it in argv[]. | |
4072 */ | |
4073 p = cmdline; | |
4074 argc = 1; | |
4075 while (*p != NUL) | |
4076 { | |
4077 inquote = FALSE; | |
4078 if (pnew != NULL) | |
4079 argv[argc] = pnew; | |
4080 ++argc; | |
4081 while (*p != NUL && (inquote || (*p != ' ' && *p != '\t'))) | |
4082 { | |
4083 /* Backslashes are only special when followed by a double | |
4084 * quote. */ | |
835 | 4085 i = (int)strspn(p, "\\"); |
7 | 4086 if (p[i] == '"') |
4087 { | |
4088 /* Halve the number of backslashes. */ | |
4089 if (i > 1 && pnew != NULL) | |
4090 { | |
2215
cccb71c2c5c1
Fix uninit memory read in undo code. Fix uint32_t in proto file.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4091 vim_memset(pnew, '\\', i / 2); |
7 | 4092 pnew += i / 2; |
4093 } | |
4094 | |
4095 /* Even nr of backslashes toggles quoting, uneven copies | |
4096 * the double quote. */ | |
4097 if ((i & 1) == 0) | |
4098 inquote = !inquote; | |
4099 else if (pnew != NULL) | |
4100 *pnew++ = '"'; | |
4101 p += i + 1; | |
4102 } | |
4103 else if (i > 0) | |
4104 { | |
4105 /* Copy span of backslashes unmodified. */ | |
4106 if (pnew != NULL) | |
4107 { | |
2215
cccb71c2c5c1
Fix uninit memory read in undo code. Fix uint32_t in proto file.
Bram Moolenaar <bram@vim.org>
parents:
2210
diff
changeset
|
4108 vim_memset(pnew, '\\', i); |
7 | 4109 pnew += i; |
4110 } | |
4111 p += i; | |
4112 } | |
4113 else | |
4114 { | |
4115 if (pnew != NULL) | |
4116 *pnew++ = *p; | |
23 | 4117 #ifdef FEAT_MBYTE |
4118 /* Can't use mb_* functions, because 'encoding' is not | |
4119 * initialized yet here. */ | |
4120 if (IsDBCSLeadByte(*p)) | |
4121 { | |
4122 ++p; | |
4123 if (pnew != NULL) | |
4124 *pnew++ = *p; | |
4125 } | |
4126 #endif | |
7 | 4127 ++p; |
4128 } | |
4129 } | |
4130 | |
323 | 4131 if (pnew != NULL) |
7 | 4132 *pnew++ = NUL; |
4133 while (*p == ' ' || *p == '\t') | |
4134 ++p; /* advance until a non-space */ | |
4135 } | |
4136 | |
4137 if (round == 1) | |
4138 { | |
4139 argv = (char **)malloc((argc + 1) * sizeof(char *)); | |
4140 if (argv == NULL ) | |
377 | 4141 { |
1738 | 4142 free(newcmdline); |
7 | 4143 return 0; /* malloc error */ |
377 | 4144 } |
7 | 4145 pnew = newcmdline; |
1738 | 4146 *tofree = newcmdline; |
7 | 4147 } |
4148 } | |
4149 | |
2419
f579b934f51d
Fix build warnings and problems for tiny/small Win32 build. (Mike Williams)
Bram Moolenaar <bram@vim.org>
parents:
2311
diff
changeset
|
4150 #ifdef FEAT_MBYTE |
26 | 4151 done: |
2419
f579b934f51d
Fix build warnings and problems for tiny/small Win32 build. (Mike Williams)
Bram Moolenaar <bram@vim.org>
parents:
2311
diff
changeset
|
4152 #endif |
7 | 4153 argv[argc] = NULL; /* NULL-terminated list */ |
4154 *argvp = argv; | |
4155 return argc; | |
4156 } |