ReactOS 0.4.17-dev-1321-g5c122a9
edit.c
Go to the documentation of this file.
1/*
2 * Edit control
3 *
4 * Copyright David W. Metcalfe, 1994
5 * Copyright William Magro, 1995, 1996
6 * Copyright Frans van Dorsselaer, 1996, 1997
7 *
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 *
23 * TODO:
24 * - EN_ALIGN_LTR_EC
25 * - EN_ALIGN_RTL_EC
26 * - ES_OEMCONVERT
27 *
28 */
29
30#include <user32.h>
31#define WIN32_LEAN_AND_MEAN
32#include <usp10.h>
33
34#ifdef __REACTOS__
35#include <immdev.h>
36#define ImmGetCompositionStringW IMM_FN(ImmGetCompositionStringW)
37#define ImmGetCompositionWindow IMM_FN(ImmGetCompositionWindow)
38#define ImmGetContext IMM_FN(ImmGetContext)
39#define ImmIsIME IMM_FN(ImmIsIME)
40#define ImmLockIMC IMM_FN(ImmLockIMC)
41#define ImmNotifyIME IMM_FN(ImmNotifyIME)
42#define ImmReleaseContext IMM_FN(ImmReleaseContext)
43#define ImmSetCompositionFontW IMM_FN(ImmSetCompositionFontW)
44#define ImmSetCompositionWindow IMM_FN(ImmSetCompositionWindow)
45#define ImmUnlockIMC IMM_FN(ImmUnlockIMC)
46#endif
47
51
52#define BUFLIMIT_INITIAL 30000 /* initial buffer size */
53#define GROWLENGTH 32 /* buffers granularity in bytes: must be power of 2 */
54#define ROUND_TO_GROW(size) (((size) + (GROWLENGTH - 1)) & ~(GROWLENGTH - 1))
55#define HSCROLL_FRACTION 3 /* scroll window by 1/3 width */
56
57/*
58 * extra flags for EDITSTATE.flags field
59 */
60#define EF_MODIFIED 0x0001 /* text has been modified */
61#define EF_FOCUSED 0x0002 /* we have input focus */
62#define EF_UPDATE 0x0004 /* notify parent of changed state */
63#define EF_VSCROLL_TRACK 0x0008 /* don't SetScrollPos() since we are tracking the thumb */
64#define EF_HSCROLL_TRACK 0x0010 /* don't SetScrollPos() since we are tracking the thumb */
65#define EF_AFTER_WRAP 0x0080 /* the caret is displayed after the last character of a
66 wrapped line, instead of in front of the next character */
67#define EF_USE_SOFTBRK 0x0100 /* Enable soft breaks in text. */
68#define EF_DIALOGMODE 0x0200 /* Indicates that we are inside a dialog window */
70typedef enum
72 END_0 = 0, /* line ends with terminating '\0' character */
73 END_WRAP, /* line is wrapped */
74 END_HARD, /* line ends with a hard return '\r\n' */
75 END_SOFT, /* line ends with a soft return '\r\r\n' */
76 END_RICH /* line ends with a single '\n' */
77} LINE_END;
78
79typedef struct tagLINEDEF {
80 INT length; /* bruto length of a line in bytes */
81 INT net_length; /* netto length of a line in visible characters */
83 INT width; /* width of the line in pixels */
84 INT index; /* line index into the buffer */
85 SCRIPT_STRING_ANALYSIS ssa; /* Uniscribe Data */
87} LINEDEF;
88
89typedef struct
91 BOOL is_unicode; /* how the control was created */
92 LPWSTR text; /* the actual contents of the control */
93 UINT text_length; /* cached length of text buffer (in WCHARs) - use get_text_length() to retrieve */
94 UINT buffer_size; /* the size of the buffer in characters */
95 UINT buffer_limit; /* the maximum size to which the buffer may grow in characters */
96 HFONT font; /* NULL means standard system font */
97 INT x_offset; /* scroll offset for multi lines this is in pixels
98 for single lines it's in characters */
99#ifdef __REACTOS__
100 DWORD dwCaretWidth;
101#endif
102 INT line_height; /* height of a screen line in pixels */
103 INT char_width; /* average character width in pixels */
104 DWORD style; /* sane version of wnd->dwStyle */
105 WORD flags; /* flags that are not in es->style or wnd->flags (EF_XXX) */
106 INT undo_insert_count; /* number of characters inserted in sequence */
107 UINT undo_position; /* character index of the insertion and deletion */
108 LPWSTR undo_text; /* deleted text */
109 UINT undo_buffer_size; /* size of the deleted text buffer */
110 INT selection_start; /* == selection_end if no selection */
111 INT selection_end; /* == current caret position */
112 WCHAR password_char; /* == 0 if no password char, and for multi line controls */
113 INT left_margin; /* in pixels */
114 INT right_margin; /* in pixels */
115 RECT format_rect;
116 INT text_width; /* width of the widest line in pixels for multi line controls
117 and just line width for single line controls */
118 void *word_break_proc; /* 32-bit word break proc: ANSI or Unicode */
119 INT line_count; /* number of lines */
120 INT y_offset; /* scroll offset in number of lines */
121 BOOL bCaptureState; /* flag indicating whether mouse was captured */
122 BOOL bEnableState; /* flag keeping the enable state */
123 HWND hwndSelf; /* the our window handle */
124 HWND hwndParent; /* Handle of parent for sending EN_* messages.
125 Even if parent will change, EN_* messages
126 should be sent to the first parent. */
127 HWND hwndListBox; /* handle of ComboBox's listbox or NULL */
128 INT wheelDeltaRemainder; /* scroll wheel delta left over after scrolling whole lines */
129 BYTE lead_byte; /* DBCS lead byte store for WM_CHAR */
130 /*
131 * only for multi line controls
132 */
133 INT lock_count; /* amount of re-entries in the EditWndProc */
134 INT tabs_count;
135 LPINT tabs;
136 LINEDEF *first_line_def; /* linked list of (soft) linebreaks */
137 HLOCAL hloc32W; /* our unicode local memory block */
138 HLOCAL hloc32A; /* alias for ANSI control receiving EM_GETHANDLE
139 or EM_SETHANDLE */
140 HLOCAL hlocapp; /* The text buffer handle belongs to the app */
141 /*
142 * IME Data
143 */
144 UINT ime_status; /* IME status flag */
145
146 /*
147 * Uniscribe Data
148 */
149 SCRIPT_LOGATTR *logAttr;
150 SCRIPT_STRING_ANALYSIS ssa; /* Uniscribe Data for single line controls */
151} EDITSTATE;
152
154#define SWAP_UINT32(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
155#define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT32((x),(y)); } while(0)
157static inline BOOL notify_parent(const EDITSTATE *es, INT code)
158{
159 HWND hwnd = es->hwndSelf;
160 TRACE("notification %d sent to %p.\n", code, es->hwndParent);
161 SendMessageW(es->hwndParent, WM_COMMAND, MAKEWPARAM(GetWindowLongPtrW(es->hwndSelf, GWLP_ID), code), (LPARAM)es->hwndSelf);
162 return IsWindow(hwnd);
163}
166{
167 return (EDITSTATE *)NtUserGetPrivateData( hwnd, 0, sizeof(EDITSTATE *) );
168}
171{
172 return (EDITSTATE *)NtUserSetPrivateData( hwnd, 0, sizeof(EDITSTATE *), (LONG_PTR)state );
173}
174
175static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap);
176
177/*********************************************************************
178 *
179 * EM_CANUNDO
180 *
181 */
182static inline BOOL EDIT_EM_CanUndo(const EDITSTATE *es)
183{
184 return (es->undo_insert_count || lstrlenW(es->undo_text));
185}
186
187
188/*********************************************************************
189 *
190 * EM_EMPTYUNDOBUFFER
191 *
192 */
193static inline void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es)
194{
195 es->undo_insert_count = 0;
196 *es->undo_text = '\0';
197}
198
199
200/**********************************************************************
201 * get_app_version
202 *
203 * Returns the window version in case Wine emulates a later version
204 * of windows than the application expects.
205 *
206 * In a number of cases when windows runs an application that was
207 * designed for an earlier windows version, windows reverts
208 * to "old" behaviour of that earlier version.
209 *
210 * An example is a disabled edit control that needs to be painted.
211 * Old style behaviour is to send a WM_CTLCOLOREDIT message. This was
212 * changed in Win95, NT4.0 by a WM_CTLCOLORSTATIC message _only_ for
213 * applications with an expected version 0f 4.0 or higher.
214 *
215 */
217{
218 static DWORD version;
219 if (!version)
220 {
221 DWORD dwEmulatedVersion;
223 DWORD dwProcVersion = GetProcessVersion(0);
224
225 info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
227 dwEmulatedVersion = MAKELONG( info.dwMinorVersion, info.dwMajorVersion );
228 /* FIXME: this may not be 100% correct; see discussion on the
229 * wine developer list in Nov 1999 */
230 version = dwProcVersion < dwEmulatedVersion ? dwProcVersion : dwEmulatedVersion;
231 }
232 return version;
233}
235static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc)
236{
237 HBRUSH hbrush;
238 UINT msg;
239
240 if ( get_app_version() >= 0x40000 && (!es->bEnableState || (es->style & ES_READONLY)))
242 else
244
245 /* why do we notify to es->hwndParent, and we send this one to GetParent()? */
246#ifdef __REACTOS__
247 /* ReactOS r54259 */
248 hbrush = GetControlBrush(es->hwndSelf, hdc, msg);
249#else
250 hbrush = (HBRUSH)SendMessageW(GetParent(es->hwndSelf), msg, (WPARAM)hdc, (LPARAM)es->hwndSelf);
251 if (!hbrush)
252 hbrush = (HBRUSH)DefWindowProcW(GetParent(es->hwndSelf), msg, (WPARAM)hdc, (LPARAM)es->hwndSelf);
253#endif
254 return hbrush;
255}
256
258static inline UINT get_text_length(EDITSTATE *es)
259{
260 if(es->text_length == (UINT)-1)
261 es->text_length = lstrlenW(es->text);
262 return es->text_length;
263}
264
265
266/*********************************************************************
267 *
268 * EDIT_WordBreakProc
269 *
270 * Find the beginning of words.
271 * Note: unlike the specs for a WordBreakProc, this function can
272 * only be called without linebreaks between s[0] up to
273 * s[count - 1]. Remember it is only called
274 * internally, so we can decide this for ourselves.
275 * Additionally we will always be breaking the full string.
276 *
277 */
279{
280 INT ret = 0;
281
282 TRACE("s=%p, index=%d, count=%d, action=%d\n", s, index, count, action);
283
284 if(!s) return 0;
285
286 if (!es->logAttr)
287 {
288 SCRIPT_ANALYSIS psa;
289
290 memset(&psa,0,sizeof(SCRIPT_ANALYSIS));
292
293 es->logAttr = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPT_LOGATTR) * get_text_length(es));
294 ScriptBreak(es->text, get_text_length(es), &psa, es->logAttr);
295 }
296
297 switch (action) {
298 case WB_LEFT:
299 if (index)
300 index--;
301 while (index && !es->logAttr[index].fSoftBreak)
302 index--;
303 ret = index;
304 break;
305 case WB_RIGHT:
306 if (!count)
307 break;
308 while (index < count && s[index] && !es->logAttr[index].fSoftBreak)
309 index++;
310 ret = index;
311 break;
312 case WB_ISDELIMITER:
313 ret = es->logAttr[index].fWhiteSpace;
314 break;
315 default:
316 ERR("unknown action code, please report !\n");
317 break;
318 }
319 return ret;
320}
321
322
323/*********************************************************************
324 *
325 * EDIT_CallWordBreakProc
326 *
327 * Call appropriate WordBreakProc (internal or external).
328 *
329 * Note: The "start" argument should always be an index referring
330 * to es->text. The actual wordbreak proc might be
331 * 16 bit, so we can't always pass any 32 bit LPSTR.
332 * Hence we assume that es->text is the buffer that holds
333 * the string under examination (we can decide this for ourselves).
334 *
335 */
337{
338 INT ret;
339
340 if (es->word_break_proc)
341 {
342 if(es->is_unicode)
343 {
344 EDITWORDBREAKPROCW wbpW = (EDITWORDBREAKPROCW)es->word_break_proc;
345
346 TRACE_(relay)("\1Call wordbreakW %p (str=%s,idx=%d,cnt=%d,act=%d)\n",
347 es->word_break_proc, debugstr_wn(es->text + start, count), index, count, action);
348 ret = wbpW(es->text + start, index, count, action);
349 TRACE_(relay)("\1Ret wordbreakW %p retval=%d\n", es->word_break_proc, ret );
350 }
351 else
352 {
353 EDITWORDBREAKPROCA wbpA = (EDITWORDBREAKPROCA)es->word_break_proc;
354 INT countA;
355 CHAR *textA;
356
357 countA = WideCharToMultiByte(CP_ACP, 0, es->text + start, count, NULL, 0, NULL, NULL);
358 textA = HeapAlloc(GetProcessHeap(), 0, countA);
359#ifdef __REACTOS__
360 /* ReactOS r33503 */
361 if (textA == NULL) return 0;
362#endif
363 WideCharToMultiByte(CP_ACP, 0, es->text + start, count, textA, countA, NULL, NULL);
364 TRACE_(relay)("\1Call wordbreakA %p(str=%s,idx=%d,cnt=%d,act=%d)\n",
365 es->word_break_proc, debugstr_an(textA, countA), index, countA, action);
366 ret = wbpA(textA, index, countA, action);
368 TRACE_(relay)("\1Ret wordbreakA %p retval=%d\n", es->word_break_proc, ret );
369 }
370 }
371 else
373
374 return ret;
375}
377static inline void EDIT_InvalidateUniscribeData_linedef(LINEDEF *line_def)
378{
379 if (line_def->ssa)
380 {
381 ScriptStringFree(&line_def->ssa);
382 line_def->ssa = NULL;
383 }
384}
386static inline void EDIT_InvalidateUniscribeData(EDITSTATE *es)
387{
388 LINEDEF *line_def = es->first_line_def;
389 while (line_def)
390 {
392 line_def = line_def->next;
393 }
394 if (es->ssa)
395 {
396 ScriptStringFree(&es->ssa);
397 es->ssa = NULL;
398 }
399}
402{
403 if (!line_def)
404 return NULL;
405
406 if (line_def->net_length && !line_def->ssa)
407 {
408 int index = line_def->index;
409 HFONT old_font = NULL;
410 HDC udc = dc;
411 SCRIPT_TABDEF tabdef;
412 HRESULT hr;
413
414 if (!udc)
415 udc = NtUserGetDC(es->hwndSelf);
416 if (es->font)
417 old_font = SelectObject(udc, es->font);
418
419 tabdef.cTabStops = es->tabs_count;
420 tabdef.iScale = GdiGetCharDimensions(udc, NULL, NULL);
421 tabdef.pTabStops = es->tabs;
422 tabdef.iTabOrigin = 0;
423
424 if (es->style & ES_PASSWORD)
425 hr = ScriptStringAnalyse(udc, &es->password_char, line_def->net_length,
426#ifdef __REACTOS__
427 /* ReactOS r57679 */
428 (3*line_def->net_length/2+16), -1,
429#else
430 (1.5*line_def->net_length+16), -1,
431#endif
433 NULL, NULL, NULL, &tabdef, NULL, &line_def->ssa);
434 else
435 hr = ScriptStringAnalyse(udc, &es->text[index], line_def->net_length,
436#ifdef __REACTOS__
437 /* ReactOS r57679 */
438 (3*line_def->net_length/2+16), -1,
439#else
440 (1.5*line_def->net_length+16), -1,
441#endif
443 NULL, NULL, NULL, &tabdef, NULL, &line_def->ssa);
444
445 if (FAILED(hr))
446 {
447 WARN("ScriptStringAnalyse failed (%lx)\n",hr);
448 line_def->ssa = NULL;
449 }
450
451 if (es->font)
452 SelectObject(udc, old_font);
453 if (udc != dc)
454 NtUserReleaseDC( es->hwndSelf, udc );
455 }
456
457 return line_def->ssa;
458}
461{
462 LINEDEF *line_def;
463
464 if (!(es->style & ES_MULTILINE))
465 {
466 if (!es->ssa)
467 {
469 HFONT old_font = NULL;
470 HDC udc = dc;
471
472 if (!udc)
473 udc = NtUserGetDC(es->hwndSelf);
474 if (es->font)
475 old_font = SelectObject(udc, es->font);
476
477 if (es->style & ES_PASSWORD)
478#ifdef __REACTOS__
479 /* ReactOS r57677 */
480 ScriptStringAnalyse(udc, &es->password_char, length, (3*length/2+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_PASSWORD, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
481#else
482 ScriptStringAnalyse(udc, &es->password_char, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_PASSWORD, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
483#endif
484 else
485#ifdef __REACTOS__
486 /* ReactOS r57677 */
487 ScriptStringAnalyse(udc, es->text, length, (3*length/2+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
488#else
489 ScriptStringAnalyse(udc, es->text, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
490#endif
491
492 if (es->font)
493 SelectObject(udc, old_font);
494 if (udc != dc)
495 NtUserReleaseDC( es->hwndSelf, udc );
496 }
497 return es->ssa;
498 }
499 else
500 {
501 line_def = es->first_line_def;
502 while (line_def && line)
503 {
504 line_def = line_def->next;
505 line--;
506 }
507
508 return EDIT_UpdateUniscribeData_linedef(es,dc,line_def);
509 }
510}
513{
514 INT vlc = es->line_height ? (es->format_rect.bottom - es->format_rect.top) / es->line_height : 0;
515 return max(1,vlc);
516}
517
518/*********************************************************************
519 *
520 * EDIT_BuildLineDefs_ML
521 *
522 * Build linked list of text lines.
523 * Lines can end with '\0' (last line), a character (if it is wrapped),
524 * a soft return '\r\r\n' or a hard return '\r\n'
525 *
526 */
527static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta, HRGN hrgn)
528{
529 LPWSTR current_position, cp;
530 INT fw;
531 LINEDEF *current_line;
532 LINEDEF *previous_line;
533 LINEDEF *start_line;
534 INT line_index = 0, nstart_line, nstart_index;
535 INT line_count = es->line_count;
536 INT orig_net_length;
537 RECT rc;
538 INT vlc;
539
540 if (istart == iend && delta == 0)
541 return;
542
543 previous_line = NULL;
544 current_line = es->first_line_def;
545
546 /* Find starting line. istart must lie inside an existing line or
547 * at the end of buffer */
548 do {
549 if (istart < current_line->index + current_line->length ||
550 current_line->ending == END_0)
551 break;
552
553 previous_line = current_line;
554 current_line = current_line->next;
555 line_index++;
556 } while (current_line);
557
558 if (!current_line) /* Error occurred start is not inside previous buffer */
559 {
560 FIXME(" modification occurred outside buffer\n");
561 return;
562 }
563
564 /* Remember start of modifications in order to calculate update region */
565 nstart_line = line_index;
566 nstart_index = current_line->index;
567
568 /* We must start to reformat from the previous line since the modifications
569 * may have caused the line to wrap upwards. */
570 if (!(es->style & ES_AUTOHSCROLL) && line_index > 0)
571 {
572 line_index--;
573 current_line = previous_line;
574 }
575 start_line = current_line;
576
577 fw = es->format_rect.right - es->format_rect.left;
578 current_position = es->text + current_line->index;
580 do {
581 if (current_line != start_line)
582 {
583 if (!current_line || current_line->index + delta > current_position - es->text)
584 {
585 /* The buffer has been expanded, create a new line and
586 insert it into the link list */
588#ifdef __REACTOS__
589 /* ReactOS r33503 */
590 if (new_line == NULL)
591 break;
592#endif
593 new_line->next = previous_line->next;
594 previous_line->next = new_line;
595 current_line = new_line;
596 es->line_count++;
597 }
598 else if (current_line->index + delta < current_position - es->text)
599 {
600 /* The previous line merged with this line so we delete this extra entry */
601 previous_line->next = current_line->next;
602 HeapFree(GetProcessHeap(), 0, current_line);
603 current_line = previous_line->next;
604 es->line_count--;
605 continue;
606 }
607 else /* current_line->index + delta == current_position */
608 {
609 if (current_position - es->text > iend)
610 break; /* We reached end of line modifications */
611 /* else recalculate this line */
612 }
613 }
614
615 current_line->index = current_position - es->text;
616 orig_net_length = current_line->net_length;
617
618 /* Find end of line */
619 cp = current_position;
620 while (*cp) {
621 if (*cp == '\n') break;
622 if ((*cp == '\r') && (*(cp + 1) == '\n'))
623 break;
624 cp++;
625 }
626
627 /* Mark type of line termination */
628 if (!(*cp)) {
629 current_line->ending = END_0;
630 current_line->net_length = lstrlenW(current_position);
631 } else if ((cp > current_position) && (*(cp - 1) == '\r')) {
632 current_line->ending = END_SOFT;
633 current_line->net_length = cp - current_position - 1;
634 } else if (*cp == '\n') {
635 current_line->ending = END_RICH;
636 current_line->net_length = cp - current_position;
637 } else {
638 current_line->ending = END_HARD;
639 current_line->net_length = cp - current_position;
640 }
641
642 if (current_line->net_length)
643 {
644 const SIZE *sz;
647 if (current_line->ssa)
648 {
649 sz = ScriptString_pSize(current_line->ssa);
650 /* Calculate line width */
651 current_line->width = sz->cx;
652 }
653 else current_line->width = es->char_width * current_line->net_length;
654 }
655 else current_line->width = 0;
656
657 /* FIXME: check here for lines that are too wide even in AUTOHSCROLL (> 32767 ???) */
658
659/* Line breaks just look back from the end and find the next break and try that. */
660
661 if (!(es->style & ES_AUTOHSCROLL)) {
662 if (current_line->width > fw && fw > es->char_width) {
663
664 INT prev, next;
665 int w;
666 const SIZE *sz;
667 float d;
668
669 prev = current_line->net_length - 1;
670 w = current_line->net_length;
671 d = (float)current_line->width/(float)fw;
672 if (d > 1.2f) d -= 0.2f;
673 next = prev/d;
674 if (next >= prev) next = prev-1;
675 do {
676 prev = EDIT_CallWordBreakProc(es, current_position - es->text,
677 next, current_line->net_length, WB_LEFT);
678 current_line->net_length = prev;
681 if (current_line->ssa)
682 sz = ScriptString_pSize(current_line->ssa);
683 else sz = 0;
684 if (sz)
685 current_line->width = sz->cx;
686 else
687 prev = 0;
688 next = prev - 1;
689 } while (prev && current_line->width > fw);
690 current_line->net_length = w;
691
692 if (prev == 0) { /* Didn't find a line break so force a break */
693 INT *piDx;
694 const INT *count;
695
698
699 if (current_line->ssa)
700 {
701 count = ScriptString_pcOutChars(current_line->ssa);
702 piDx = HeapAlloc(GetProcessHeap(),0,sizeof(INT) * (*count));
703 ScriptStringGetLogicalWidths(current_line->ssa,piDx);
704
705 prev = current_line->net_length-1;
706 do {
707 current_line->width -= piDx[prev];
708 prev--;
709 } while ( prev > 0 && current_line->width > fw);
710 if (prev<=0)
711 prev = 1;
712 HeapFree(GetProcessHeap(),0,piDx);
713 }
714 else
715 prev = (fw / es->char_width);
716 }
717
718 /* If the first line we are calculating, wrapped before istart, we must
719 * adjust istart in order for this to be reflected in the update region. */
720 if (current_line->index == nstart_index && istart > current_line->index + prev)
721 istart = current_line->index + prev;
722 /* else if we are updating the previous line before the first line we
723 * are re-calculating and it expanded */
724 else if (current_line == start_line &&
725 current_line->index != nstart_index && orig_net_length < prev)
726 {
727 /* Line expanded due to an upwards line wrap so we must partially include
728 * previous line in update region */
729 nstart_line = line_index;
730 nstart_index = current_line->index;
731 istart = current_line->index + orig_net_length;
732 }
733
734 current_line->net_length = prev;
735 current_line->ending = END_WRAP;
736
737 if (current_line->net_length > 0)
738 {
740 if (current_line->ssa)
741 {
742 sz = ScriptString_pSize(current_line->ssa);
743 current_line->width = sz->cx;
744 }
745 else
746 current_line->width = 0;
747 }
748 else current_line->width = 0;
749 }
750 else if (current_line == start_line &&
751 current_line->index != nstart_index &&
752 orig_net_length < current_line->net_length) {
753 /* The previous line expanded but it's still not as wide as the client rect */
754 /* The expansion is due to an upwards line wrap so we must partially include
755 it in the update region */
756 nstart_line = line_index;
757 nstart_index = current_line->index;
758 istart = current_line->index + orig_net_length;
759 }
760 }
761
762
763 /* Adjust length to include line termination */
764 switch (current_line->ending) {
765 case END_SOFT:
766 current_line->length = current_line->net_length + 3;
767 break;
768 case END_RICH:
769 current_line->length = current_line->net_length + 1;
770 break;
771 case END_HARD:
772 current_line->length = current_line->net_length + 2;
773 break;
774 case END_WRAP:
775 case END_0:
776 current_line->length = current_line->net_length;
777 break;
778 }
779 es->text_width = max(es->text_width, current_line->width);
780 current_position += current_line->length;
781 previous_line = current_line;
782
783 /* Discard data for non-visible lines. It will be calculated as needed */
784 if ((line_index < es->y_offset) || (line_index > es->y_offset + vlc))
786
787 current_line = current_line->next;
788 line_index++;
789 } while (previous_line->ending != END_0);
790
791 /* Finish adjusting line indexes by delta or remove hanging lines */
792 if (previous_line->ending == END_0)
793 {
794 LINEDEF *pnext = NULL;
795
796 previous_line->next = NULL;
797 while (current_line)
798 {
799 pnext = current_line->next;
801 HeapFree(GetProcessHeap(), 0, current_line);
802 current_line = pnext;
803 es->line_count--;
804 }
805 }
806 else if (delta != 0)
807 {
808 while (current_line)
809 {
810 current_line->index += delta;
811 current_line = current_line->next;
812 }
813 }
814
815 /* Calculate rest of modification rectangle */
816 if (hrgn)
817 {
818 HRGN tmphrgn;
819 /*
820 * We calculate two rectangles. One for the first line which may have
821 * an indent with respect to the format rect. The other is a format-width
822 * rectangle that spans the rest of the lines that changed or moved.
823 */
824 rc.top = es->format_rect.top + nstart_line * es->line_height -
825 (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
826 rc.bottom = rc.top + es->line_height;
827 if ((es->style & ES_CENTER) || (es->style & ES_RIGHT))
828 rc.left = es->format_rect.left;
829 else
830#ifdef __REACTOS__ /* CORE-11475 */
831 rc.left = (short)LOWORD(EDIT_EM_PosFromChar(es, nstart_index, FALSE));
832#else
833 rc.left = LOWORD(EDIT_EM_PosFromChar(es, nstart_index, FALSE));
834#endif
835 rc.right = es->format_rect.right;
836 SetRectRgn(hrgn, rc.left, rc.top, rc.right, rc.bottom);
837
838 rc.top = rc.bottom;
839 rc.left = es->format_rect.left;
840 rc.right = es->format_rect.right;
841 /*
842 * If lines were added or removed we must re-paint the remainder of the
843 * lines since the remaining lines were either shifted up or down.
844 */
845 if (line_count < es->line_count) /* We added lines */
846 rc.bottom = es->line_count * es->line_height;
847 else if (line_count > es->line_count) /* We removed lines */
848 rc.bottom = line_count * es->line_height;
849 else
850 rc.bottom = line_index * es->line_height;
851 rc.bottom += es->format_rect.top;
852 rc.bottom -= (es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
853 tmphrgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
854 CombineRgn(hrgn, hrgn, tmphrgn, RGN_OR);
855 DeleteObject(tmphrgn);
856 }
857}
858
859/*********************************************************************
860 *
861 * EDIT_CalcLineWidth_SL
862 *
863 */
865{
867 if (es->ssa)
868 {
869 const SIZE *size;
870 size = ScriptString_pSize(es->ssa);
871 es->text_width = size->cx;
872 }
873 else
874 es->text_width = 0;
875}
876
877/*********************************************************************
878 *
879 * EDIT_CharFromPos
880 *
881 * Beware: This is not the function called on EM_CHARFROMPOS
882 * The position _can_ be outside the formatting / client
883 * rectangle
884 * The return value is only the character index
885 *
886 */
887static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap)
888{
889 INT index;
890
891 if (es->style & ES_MULTILINE) {
892 int trailing;
893 INT line = (y - es->format_rect.top) / es->line_height + es->y_offset;
894 INT line_index = 0;
895 LINEDEF *line_def = es->first_line_def;
897 while ((line > 0) && line_def->next) {
898 line_index += line_def->length;
899 line_def = line_def->next;
900 line--;
901 }
902
903 x += es->x_offset - es->format_rect.left;
904 if (es->style & ES_RIGHT)
905 x -= (es->format_rect.right - es->format_rect.left) - line_def->width;
906 else if (es->style & ES_CENTER)
907 x -= ((es->format_rect.right - es->format_rect.left) - line_def->width) / 2;
908 if (x >= line_def->width) {
909 if (after_wrap)
910 *after_wrap = (line_def->ending == END_WRAP);
911 return line_index + line_def->net_length;
912 }
913 if (x <= 0 || !line_def->ssa) {
914 if (after_wrap)
915 *after_wrap = FALSE;
916 return line_index;
917 }
918
919 ScriptStringXtoCP(line_def->ssa, x , &index, &trailing);
920 if (trailing) index++;
921 index += line_index;
922 if (after_wrap)
923 *after_wrap = ((index == line_index + line_def->net_length) &&
924 (line_def->ending == END_WRAP));
925 } else {
926 INT xoff = 0;
928 if (after_wrap)
929 *after_wrap = FALSE;
930 x -= es->format_rect.left;
931 if (!x)
932 return es->x_offset;
933
934 if (!es->x_offset)
935 {
936 INT indent = (es->format_rect.right - es->format_rect.left) - es->text_width;
937 if (es->style & ES_RIGHT)
938 x -= indent;
939 else if (es->style & ES_CENTER)
940 x -= indent / 2;
941 }
942
944 if (es->x_offset)
945 {
946 if (es->ssa)
947 {
948 if (es->x_offset>= get_text_length(es))
949 {
950 const SIZE *size;
951 size = ScriptString_pSize(es->ssa);
952 xoff = size->cx;
953 }
954 ScriptStringCPtoX(es->ssa, es->x_offset, FALSE, &xoff);
955 }
956 else
957 xoff = 0;
958 }
959 if (x < 0)
960 {
961 if (x + xoff > 0 || !es->ssa)
962 {
963 ScriptStringXtoCP(es->ssa, x+xoff, &index, &trailing);
964 if (trailing) index++;
965 }
966 else
967 index = 0;
968 }
969 else
970 {
971 if (x)
972 {
973 const SIZE *size = NULL;
974 if (es->ssa)
975 size = ScriptString_pSize(es->ssa);
976 if (!size)
977 index = 0;
978 else if (x > size->cx)
980 else if (es->ssa)
981 {
982 ScriptStringXtoCP(es->ssa, x+xoff, &index, &trailing);
983 if (trailing) index++;
984 }
985 else
986 index = 0;
987 }
988 else
989 index = es->x_offset;
990 }
991 }
992 return index;
993}
994
995
996/*********************************************************************
997 *
998 * EDIT_ConfinePoint
999 *
1000 * adjusts the point to be within the formatting rectangle
1001 * (so CharFromPos returns the nearest _visible_ character)
1002 *
1004static void EDIT_ConfinePoint(const EDITSTATE *es, LPINT x, LPINT y)
1005{
1006 *x = min(max(*x, es->format_rect.left), es->format_rect.right - 1);
1007 *y = min(max(*y, es->format_rect.top), es->format_rect.bottom - 1);
1008}
1009
1010
1011/*********************************************************************
1012 *
1013 * EM_LINEFROMCHAR
1014 *
1017{
1018 INT line;
1019 LINEDEF *line_def;
1020
1021 if (!(es->style & ES_MULTILINE))
1022 return 0;
1023 if (index > (INT)get_text_length(es))
1024 return es->line_count - 1;
1025 if (index == -1)
1026 index = min(es->selection_start, es->selection_end);
1027
1028 line = 0;
1029 line_def = es->first_line_def;
1030 index -= line_def->length;
1031 while ((index >= 0) && line_def->next) {
1032 line++;
1033 line_def = line_def->next;
1034 index -= line_def->length;
1035 }
1036 return line;
1037}
1038
1039
1040/*********************************************************************
1041 *
1042 * EM_LINEINDEX
1043 *
1045static INT EDIT_EM_LineIndex(const EDITSTATE *es, INT line)
1046{
1047 INT line_index;
1048 const LINEDEF *line_def;
1049
1050 if (!(es->style & ES_MULTILINE))
1051 return 0;
1052 if (line >= es->line_count)
1053 return -1;
1054
1055 line_index = 0;
1056 line_def = es->first_line_def;
1057 if (line == -1) {
1058 INT index = es->selection_end - line_def->length;
1059 while ((index >= 0) && line_def->next) {
1060 line_index += line_def->length;
1061 line_def = line_def->next;
1062 index -= line_def->length;
1063 }
1064 } else {
1065 while (line > 0) {
1066 line_index += line_def->length;
1067 line_def = line_def->next;
1068 line--;
1069 }
1070 }
1071 return line_index;
1072}
1073
1074
1075/*********************************************************************
1076 *
1077 * EM_LINELENGTH
1078 *
1081{
1082 LINEDEF *line_def;
1083
1084 if (!(es->style & ES_MULTILINE))
1085 return get_text_length(es);
1086
1087 if (index == -1) {
1088 /* get the number of remaining non-selected chars of selected lines */
1089 INT32 l; /* line number */
1090 INT32 li; /* index of first char in line */
1091 INT32 count;
1092 l = EDIT_EM_LineFromChar(es, es->selection_start);
1093 /* # chars before start of selection area */
1094 count = es->selection_start - EDIT_EM_LineIndex(es, l);
1095 l = EDIT_EM_LineFromChar(es, es->selection_end);
1096 /* # chars after end of selection */
1098 count += li + EDIT_EM_LineLength(es, li) - es->selection_end;
1099 return count;
1100 }
1101 line_def = es->first_line_def;
1102 index -= line_def->length;
1103 while ((index >= 0) && line_def->next) {
1104 line_def = line_def->next;
1105 index -= line_def->length;
1106 }
1107 return line_def->net_length;
1108}
1109
1110
1111/*********************************************************************
1112 *
1113 * EM_POSFROMCHAR
1114 *
1116static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap)
1117{
1119 INT l;
1120 INT li;
1121 INT x = 0;
1122 INT y = 0;
1123 INT w;
1124 INT lw;
1125 LINEDEF *line_def;
1126
1127 index = min(index, len);
1128 if (es->style & ES_MULTILINE) {
1131
1132 y = (l - es->y_offset) * es->line_height;
1134 if (after_wrap && (li == index) && l) {
1135 INT l2 = l - 1;
1136 line_def = es->first_line_def;
1137 while (l2) {
1138 line_def = line_def->next;
1139 l2--;
1140 }
1141 if (line_def->ending == END_WRAP) {
1142 l--;
1143 y -= es->line_height;
1145 }
1146 }
1147
1148 line_def = es->first_line_def;
1149 while (line_def->index != li)
1150 line_def = line_def->next;
1151
1152 lw = line_def->width;
1153 w = es->format_rect.right - es->format_rect.left;
1154 if (line_def->ssa)
1155 ScriptStringCPtoX(line_def->ssa, (index - 1) - li, TRUE, &x);
1156#ifdef __REACTOS__ /* CORE-15780 */
1157 x = (lw > 0 ? es->x_offset : x - es->x_offset);
1158#else
1159 x -= es->x_offset;
1160#endif
1161
1162 if (es->style & ES_RIGHT)
1163 x = w - (lw - x);
1164 else if (es->style & ES_CENTER)
1165 x += (w - lw) / 2;
1166 } else {
1167 INT xoff = 0;
1168 INT xi = 0;
1170 if (es->x_offset)
1171 {
1172 if (es->ssa)
1173 {
1174 if (es->x_offset >= get_text_length(es))
1175 {
1176 int leftover = es->x_offset - get_text_length(es);
1177 if (es->ssa)
1178 {
1179 const SIZE *size;
1180 size = ScriptString_pSize(es->ssa);
1181 xoff = size->cx;
1182 }
1183 else
1184 xoff = 0;
1185 xoff += es->char_width * leftover;
1186 }
1187 else
1188 ScriptStringCPtoX(es->ssa, es->x_offset, FALSE, &xoff);
1189 }
1190 else
1191 xoff = 0;
1192 }
1193 if (index)
1194 {
1195 if (index >= get_text_length(es))
1196 {
1197 if (es->ssa)
1198 {
1199 const SIZE *size;
1200 size = ScriptString_pSize(es->ssa);
1201 xi = size->cx;
1202 }
1203 else
1204 xi = 0;
1205 }
1206 else if (es->ssa)
1207 ScriptStringCPtoX(es->ssa, index, FALSE, &xi);
1208 else
1209 xi = 0;
1210 }
1211 x = xi - xoff;
1212
1213 if (index >= es->x_offset) {
1214 if (!es->x_offset && (es->style & (ES_RIGHT | ES_CENTER)))
1215 {
1216 w = es->format_rect.right - es->format_rect.left;
1217 if (w > es->text_width)
1218 {
1219 if (es->style & ES_RIGHT)
1220 x += w - es->text_width;
1221 else if (es->style & ES_CENTER)
1222 x += (w - es->text_width) / 2;
1223 }
1224 }
1225 }
1226 y = 0;
1227 }
1228 x += es->format_rect.left;
1229 y += es->format_rect.top;
1230 return MAKELONG((INT16)x, (INT16)y);
1231}
1232
1233
1234/*********************************************************************
1235 *
1236 * EDIT_GetLineRect
1237 *
1238 * Calculates the bounding rectangle for a line from a starting
1239 * column to an ending column.
1240 *
1242static void EDIT_GetLineRect(EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc)
1243{
1245 INT line_index = 0;
1246 INT pt1, pt2, pt3;
1247
1248 if (es->style & ES_MULTILINE)
1249 {
1250 const LINEDEF *line_def = NULL;
1251 rc->top = es->format_rect.top + (line - es->y_offset) * es->line_height;
1252 if (line >= es->line_count)
1253 return;
1254
1255 line_def = es->first_line_def;
1256 if (line == -1) {
1257 INT index = es->selection_end - line_def->length;
1258 while ((index >= 0) && line_def->next) {
1259 line_index += line_def->length;
1260 line_def = line_def->next;
1261 index -= line_def->length;
1262 }
1263 } else {
1264 while (line > 0) {
1265 line_index += line_def->length;
1266 line_def = line_def->next;
1267 line--;
1268 }
1269 }
1270 ssa = line_def->ssa;
1271 }
1272 else
1273 {
1274 line_index = 0;
1275 rc->top = es->format_rect.top;
1276 ssa = es->ssa;
1277 }
1278
1279 rc->bottom = rc->top + es->line_height;
1280 pt1 = (scol == 0) ? es->format_rect.left : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + scol, TRUE));
1281 pt2 = (ecol == -1) ? es->format_rect.right : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + ecol, TRUE));
1282 if (ssa)
1283 {
1284 ScriptStringCPtoX(ssa, scol, FALSE, &pt3);
1285 pt3+=es->format_rect.left;
1286 }
1287 else pt3 = pt1;
1288 rc->right = max(max(pt1 , pt2),pt3);
1289 rc->left = min(min(pt1, pt2),pt3);
1290}
1291
1293static inline void text_buffer_changed(EDITSTATE *es)
1294{
1295 es->text_length = (UINT)-1;
1296
1297 HeapFree( GetProcessHeap(), 0, es->logAttr );
1298 es->logAttr = NULL;
1300}
1301
1302/*********************************************************************
1303 * EDIT_LockBuffer
1304 *
1306static void EDIT_LockBuffer(EDITSTATE *es)
1307{
1308 if (!es->text) {
1309
1310#ifdef __REACTOS__
1311/* FIXME: What is this ? */
1312 CHAR *textA = NULL; // ReactOS Hacked! r45670
1313 //UINT countA = 0;
1314
1315 if(es->hloc32W)
1316 {
1317 if(es->hloc32A)
1318 {
1319 TRACE("Synchronizing with 32-bit ANSI buffer\n");
1320 textA = LocalLock(es->hloc32A);
1321 //countA = strlen(textA) + 1;
1322 }
1323 }
1324 else {
1325 ERR("no buffer ... please report\n");
1326 return;
1327 }
1328
1329 if (textA)
1330 {
1331#else
1332 if(!es->hloc32W) return;
1333
1334 if(es->hloc32A)
1335 {
1336 CHAR *textA = LocalLock(es->hloc32A);
1337#endif
1338 HLOCAL hloc32W_new;
1339 UINT countW_new = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
1340 if(countW_new > es->buffer_size + 1)
1341 {
1342 UINT alloc_size = ROUND_TO_GROW(countW_new * sizeof(WCHAR));
1343 TRACE("Resizing 32-bit UNICODE buffer from %d+1 to %d WCHARs\n", es->buffer_size, countW_new);
1344 hloc32W_new = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
1345 if(hloc32W_new)
1346 {
1347 es->hloc32W = hloc32W_new;
1348 es->buffer_size = LocalSize(hloc32W_new)/sizeof(WCHAR) - 1;
1349 TRACE("Real new size %d+1 WCHARs\n", es->buffer_size);
1350 }
1351 else
1352 WARN("FAILED! Will synchronize partially\n");
1353 }
1354 es->text = LocalLock(es->hloc32W);
1355 MultiByteToWideChar(CP_ACP, 0, textA, -1, es->text, es->buffer_size + 1);
1356 LocalUnlock(es->hloc32A);
1357 }
1358 else es->text = LocalLock(es->hloc32W);
1359 }
1360 es->lock_count++;
1361}
1362
1363
1364/*********************************************************************
1365 *
1366 * EDIT_UnlockBuffer
1367 *
1370{
1371 /* Edit window might be already destroyed */
1372 if(!IsWindow(es->hwndSelf))
1373 {
1374 WARN("edit hwnd %p already destroyed\n", es->hwndSelf);
1375 return;
1376 }
1377
1378 if (!es->lock_count) {
1379 ERR("lock_count == 0 ... please report\n");
1380 return;
1381 }
1382 if (!es->text) {
1383 ERR("es->text == 0 ... please report\n");
1384 return;
1385 }
1386 if (force || (es->lock_count == 1)) {
1387 if (es->hloc32W) {
1388 UINT countA = 0;
1389 UINT countW = get_text_length(es) + 1;
1390
1391 if(es->hloc32A)
1392 {
1393 UINT countA_new = WideCharToMultiByte(CP_ACP, 0, es->text, countW, NULL, 0, NULL, NULL);
1394 TRACE("Synchronizing with 32-bit ANSI buffer\n");
1395 TRACE("%d WCHARs translated to %d bytes\n", countW, countA_new);
1396 countA = LocalSize(es->hloc32A);
1397 if(countA_new > countA)
1398 {
1399 HLOCAL hloc32A_new;
1400 UINT alloc_size = ROUND_TO_GROW(countA_new);
1401 TRACE("Resizing 32-bit ANSI buffer from %d to %d bytes\n", countA, alloc_size);
1402 hloc32A_new = LocalReAlloc(es->hloc32A, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT);
1403 if(hloc32A_new)
1404 {
1405 es->hloc32A = hloc32A_new;
1406 countA = LocalSize(hloc32A_new);
1407 TRACE("Real new size %d bytes\n", countA);
1408 }
1409 else
1410 WARN("FAILED! Will synchronize partially\n");
1411 }
1412 WideCharToMultiByte(CP_ACP, 0, es->text, countW,
1413 LocalLock(es->hloc32A), countA, NULL, NULL);
1414 LocalUnlock(es->hloc32A);
1415 }
1416
1417 LocalUnlock(es->hloc32W);
1418 es->text = NULL;
1419 }
1420 else {
1421 ERR("no buffer ... please report\n");
1422 return;
1423 }
1424 }
1425 es->lock_count--;
1426}
1427
1428
1429/*********************************************************************
1430 *
1431 * EDIT_MakeFit
1432 *
1433 * Try to fit size + 1 characters in the buffer.
1436{
1437 HLOCAL hNew32W;
1438
1439 if (size <= es->buffer_size)
1440 return TRUE;
1441
1442 TRACE("trying to ReAlloc to %d+1 characters\n", size);
1443
1444 /* Force edit to unlock its buffer. es->text now NULL */
1446
1447 if (es->hloc32W) {
1448 UINT alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR));
1449 if ((hNew32W = LocalReAlloc(es->hloc32W, alloc_size, LMEM_MOVEABLE | LMEM_ZEROINIT))) {
1450 TRACE("Old 32 bit handle %p, new handle %p\n", es->hloc32W, hNew32W);
1451 es->hloc32W = hNew32W;
1452 es->buffer_size = LocalSize(hNew32W)/sizeof(WCHAR) - 1;
1453 }
1454 }
1455
1457
1458 if (es->buffer_size < size) {
1459 WARN("FAILED ! We now have %d+1\n", es->buffer_size);
1461 return FALSE;
1462 } else {
1463 TRACE("We now have %d+1\n", es->buffer_size);
1464 return TRUE;
1465 }
1466}
1467
1468
1469/*********************************************************************
1470 *
1471 * EDIT_MakeUndoFit
1472 *
1473 * Try to fit size + 1 bytes in the undo buffer.
1474 *
1477{
1478 UINT alloc_size;
1479
1480 if (size <= es->undo_buffer_size)
1481 return TRUE;
1482
1483 TRACE("trying to ReAlloc to %d+1\n", size);
1484
1485 alloc_size = ROUND_TO_GROW((size + 1) * sizeof(WCHAR));
1486 if ((es->undo_text = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, es->undo_text, alloc_size))) {
1487 es->undo_buffer_size = alloc_size/sizeof(WCHAR) - 1;
1488 return TRUE;
1489 }
1490 else
1491 {
1492 WARN("FAILED ! We now have %d+1\n", es->undo_buffer_size);
1493 return FALSE;
1494 }
1495}
1496
1497
1498/*********************************************************************
1499 *
1500 * EDIT_UpdateTextRegion
1501 *
1503static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase)
1504{
1505 if (es->flags & EF_UPDATE) {
1506 es->flags &= ~EF_UPDATE;
1507 if (!notify_parent(es, EN_UPDATE)) return;
1508 }
1509 NtUserInvalidateRgn(es->hwndSelf, hrgn, bErase);
1510}
1511
1512
1513/*********************************************************************
1514 *
1515 * EDIT_UpdateText
1516 *
1518static void EDIT_UpdateText(EDITSTATE *es, const RECT *rc, BOOL bErase)
1519{
1520 if (es->flags & EF_UPDATE) {
1521 es->flags &= ~EF_UPDATE;
1522 if (!notify_parent(es, EN_UPDATE)) return;
1523 }
1524 NtUserInvalidateRect(es->hwndSelf, rc, bErase);
1525}
1526
1527/*********************************************************************
1528 *
1529 * EDIT_SL_InvalidateText
1530 *
1531 * Called from EDIT_InvalidateText().
1532 * Does the job for single-line controls only.
1533 *
1536{
1537 RECT line_rect;
1538 RECT rc;
1539
1540 EDIT_GetLineRect(es, 0, start, end, &line_rect);
1541 if (IntersectRect(&rc, &line_rect, &es->format_rect))
1542 EDIT_UpdateText(es, &rc, TRUE);
1543}
1544
1545/*********************************************************************
1546 *
1547 * EDIT_ML_InvalidateText
1548 *
1549 * Called from EDIT_InvalidateText().
1550 * Does the job for multi-line controls only.
1551 *
1554{
1558 INT sc;
1559 INT ec;
1560 RECT rc1;
1561 RECT rcWnd;
1562 RECT rcLine;
1563 RECT rcUpdate;
1564 INT l;
1565
1566 if ((el < es->y_offset) || (sl > es->y_offset + vlc))
1567 return;
1568
1569 sc = start - EDIT_EM_LineIndex(es, sl);
1570 ec = end - EDIT_EM_LineIndex(es, el);
1571 if (sl < es->y_offset) {
1572 sl = es->y_offset;
1573 sc = 0;
1574 }
1575 if (el > es->y_offset + vlc) {
1576 el = es->y_offset + vlc;
1578 }
1579 GetClientRect(es->hwndSelf, &rc1);
1580 IntersectRect(&rcWnd, &rc1, &es->format_rect);
1581 if (sl == el) {
1582 EDIT_GetLineRect(es, sl, sc, ec, &rcLine);
1583 if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
1584 EDIT_UpdateText(es, &rcUpdate, TRUE);
1585 } else {
1586 EDIT_GetLineRect(es, sl, sc,
1588 EDIT_EM_LineIndex(es, sl)),
1589 &rcLine);
1590 if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
1591 EDIT_UpdateText(es, &rcUpdate, TRUE);
1592 for (l = sl + 1 ; l < el ; l++) {
1593 EDIT_GetLineRect(es, l, 0,
1596 &rcLine);
1597 if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
1598 EDIT_UpdateText(es, &rcUpdate, TRUE);
1599 }
1600 EDIT_GetLineRect(es, el, 0, ec, &rcLine);
1601 if (IntersectRect(&rcUpdate, &rcWnd, &rcLine))
1602 EDIT_UpdateText(es, &rcUpdate, TRUE);
1603 }
1604}
1605
1606
1607/*********************************************************************
1608 *
1609 * EDIT_InvalidateText
1610 *
1611 * Invalidate the text from offset start up to, but not including,
1612 * offset end. Useful for (re)painting the selection.
1613 * Regions outside the linewidth are not invalidated.
1614 * end == -1 means end == TextLength.
1615 * start and end need not be ordered.
1616 *
1619{
1620 if (end == start)
1621 return;
1622
1623 if (end == -1)
1625
1626 if (end < start) {
1627 INT tmp = start;
1628 start = end;
1629 end = tmp;
1630 }
1631
1632 if (es->style & ES_MULTILINE)
1634 else
1636}
1637
1638
1639/*********************************************************************
1640 *
1641 * EDIT_EM_SetSel
1642 *
1643 * note: unlike the specs say: the order of start and end
1644 * _is_ preserved in Windows. (i.e. start can be > end)
1645 * In other words: this handler is OK
1646 *
1648static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap)
1649{
1650 UINT old_start = es->selection_start;
1651 UINT old_end = es->selection_end;
1653
1654 if (start == (UINT)-1) {
1655 start = es->selection_end;
1656 end = es->selection_end;
1657 } else {
1658 start = min(start, len);
1659 end = min(end, len);
1660 }
1661 es->selection_start = start;
1662 es->selection_end = end;
1663 if (after_wrap)
1664 es->flags |= EF_AFTER_WRAP;
1665 else
1666 es->flags &= ~EF_AFTER_WRAP;
1667 /* Compute the necessary invalidation region. */
1668 /* Note that we don't need to invalidate regions which have
1669 * "never" been selected, or those which are "still" selected.
1670 * In fact, every time we hit a selection boundary, we can
1671 * *toggle* whether we need to invalidate. Thus we can optimize by
1672 * *sorting* the interval endpoints. Let's assume that we sort them
1673 * in this order:
1674 * start <= end <= old_start <= old_end
1675 * Knuth 5.3.1 (p 183) assures us that this can be done optimally
1676 * in 5 comparisons; i.e. it is impossible to do better than the
1677 * following: */
1678 ORDER_UINT(end, old_end);
1679 ORDER_UINT(start, old_start);
1680 ORDER_UINT(old_start, old_end);
1682 /* Note that at this point 'end' and 'old_start' are not in order, but
1683 * start is definitely the min. and old_end is definitely the max. */
1684 if (end != old_start)
1685 {
1686/*
1687 * One can also do
1688 * ORDER_UINT32(end, old_start);
1689 * EDIT_InvalidateText(es, start, end);
1690 * EDIT_InvalidateText(es, old_start, old_end);
1691 * in place of the following if statement.
1692 * (That would complete the optimal five-comparison four-element sort.)
1693 */
1694 if (old_start > end )
1695 {
1697 EDIT_InvalidateText(es, old_start, old_end);
1698 }
1699 else
1700 {
1701 EDIT_InvalidateText(es, start, old_start);
1702 EDIT_InvalidateText(es, end, old_end);
1703 }
1704 }
1705 else EDIT_InvalidateText(es, start, old_end);
1706}
1707
1708
1709/*********************************************************************
1710 *
1711 * EDIT_UpdateScrollInfo
1712 *
1715{
1716 if ((es->style & WS_VSCROLL) && !(es->flags & EF_VSCROLL_TRACK))
1717 {
1718 SCROLLINFO si;
1719 si.cbSize = sizeof(SCROLLINFO);
1721 si.nMin = 0;
1722 si.nMax = es->line_count - 1;
1723 si.nPage = es->line_height ? (es->format_rect.bottom - es->format_rect.top) / es->line_height : 0;
1724 si.nPos = es->y_offset;
1725 TRACE("SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
1726 si.nMin, si.nMax, si.nPage, si.nPos);
1727#ifdef __REACTOS__
1728 /* Unlike WINE, SetScrollInfo is more than just a NtUserSetScrollInfo wrapper on ReactOS. */
1729 SetScrollInfo(es->hwndSelf, SB_VERT, &si, TRUE);
1730#else
1731 NtUserSetScrollInfo(es->hwndSelf, SB_VERT, &si, TRUE);
1732#endif
1733 }
1734
1735 if ((es->style & WS_HSCROLL) && !(es->flags & EF_HSCROLL_TRACK))
1736 {
1737 SCROLLINFO si;
1738 si.cbSize = sizeof(SCROLLINFO);
1740 si.nMin = 0;
1741 si.nMax = es->text_width - 1;
1742 si.nPage = es->format_rect.right - es->format_rect.left;
1743 si.nPos = es->x_offset;
1744 TRACE("SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
1745 si.nMin, si.nMax, si.nPage, si.nPos);
1746#ifdef __REACTOS__
1747 SetScrollInfo(es->hwndSelf, SB_HORZ, &si, TRUE);
1748#else
1749 NtUserSetScrollInfo(es->hwndSelf, SB_HORZ, &si, TRUE);
1750#endif
1751 }
1752}
1753
1754
1755/*********************************************************************
1756 *
1757 * EDIT_EM_LineScroll_internal
1758 *
1759 * Version of EDIT_EM_LineScroll for internal use.
1760 * It doesn't refuse if ES_MULTILINE is set and assumes that
1761 * dx is in pixels, dy - in lines.
1762 *
1765{
1766 INT nyoff;
1767 INT x_offset_in_pixels;
1768 INT lines_per_page;
1769
1770 if (!es->line_height || !es->char_width)
1771 return TRUE;
1772
1773 lines_per_page = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
1774
1775 if (es->style & ES_MULTILINE)
1776 {
1777 x_offset_in_pixels = es->x_offset;
1778 }
1779 else
1780 {
1781 dy = 0;
1782 x_offset_in_pixels = (short)LOWORD(EDIT_EM_PosFromChar(es, es->x_offset, FALSE));
1783 }
1784
1785 if (-dx > x_offset_in_pixels)
1786 dx = -x_offset_in_pixels;
1787 if (dx > es->text_width - x_offset_in_pixels)
1788 dx = es->text_width - x_offset_in_pixels;
1789 nyoff = max(0, es->y_offset + dy);
1790 if (nyoff >= es->line_count - lines_per_page)
1791 nyoff = max(0, es->line_count - lines_per_page);
1792 dy = (es->y_offset - nyoff) * es->line_height;
1793 if (dx || dy) {
1794 RECT rc1;
1795 RECT rc;
1796
1797 es->y_offset = nyoff;
1798 if(es->style & ES_MULTILINE)
1799 es->x_offset += dx;
1800 else
1801 es->x_offset += dx / es->char_width;
1802
1803 GetClientRect(es->hwndSelf, &rc1);
1804 IntersectRect(&rc, &rc1, &es->format_rect);
1805 NtUserScrollWindowEx(es->hwndSelf, -dx, dy,
1806 NULL, &rc, NULL, NULL, SW_INVALIDATE);
1807 /* force scroll info update */
1809 }
1810 if (dx && !(es->flags & EF_HSCROLL_TRACK))
1812 if (dy && !(es->flags & EF_VSCROLL_TRACK))
1814 return TRUE;
1815}
1816
1817/*********************************************************************
1818 *
1819 * EM_LINESCROLL
1820 *
1821 * NOTE: dx is in average character widths, dy - in lines;
1822 *
1825{
1826 if (!(es->style & ES_MULTILINE))
1827 return FALSE;
1828
1829 dx *= es->char_width;
1831}
1832
1833
1834/*********************************************************************
1835 *
1836 * EM_SCROLL
1837 *
1840{
1841 INT dy;
1842
1843 if (!(es->style & ES_MULTILINE))
1844 return (LRESULT)FALSE;
1845
1846 dy = 0;
1847
1848 switch (action) {
1849 case SB_LINEUP:
1850 if (es->y_offset)
1851 dy = -1;
1852 break;
1853 case SB_LINEDOWN:
1854 if (es->y_offset < es->line_count - 1)
1855 dy = 1;
1856 break;
1857 case SB_PAGEUP:
1858 if (es->y_offset)
1859 dy = -(es->format_rect.bottom - es->format_rect.top) / es->line_height;
1860 break;
1861 case SB_PAGEDOWN:
1862 if (es->y_offset < es->line_count - 1)
1863 dy = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
1864 break;
1865 default:
1867 }
1868 if (dy) {
1870 /* check if we are going to move too far */
1871 if(es->y_offset + dy > es->line_count - vlc)
1872 dy = max(es->line_count - vlc, 0) - es->y_offset;
1873
1874 /* Notification is done in EDIT_EM_LineScroll */
1875 if(dy) {
1877 return MAKELONG(dy, TRUE);
1878 }
1879
1880 }
1881 return (LRESULT)FALSE;
1882}
1883
1884#ifdef __REACTOS__
1885static void EDIT_ImmSetCompositionWindow(EDITSTATE *es, POINT pt)
1886{
1887 COMPOSITIONFORM CompForm;
1888 HIMC hIMC = ImmGetContext(es->hwndSelf);
1889 if (!hIMC)
1890 {
1891 ERR("!hIMC\n");
1892 return;
1893 }
1894
1895 CompForm.ptCurrentPos = pt;
1896 if (es->style & ES_MULTILINE)
1897 {
1898 CompForm.dwStyle = CFS_RECT;
1899 CompForm.rcArea = es->format_rect;
1900 }
1901 else
1902 {
1903 CompForm.dwStyle = CFS_POINT;
1904 SetRectEmpty(&CompForm.rcArea);
1905 }
1906
1907 ImmSetCompositionWindow(hIMC, &CompForm);
1908 ImmReleaseContext(es->hwndSelf, hIMC);
1909}
1910#else
1912{
1914 {
1915 .dwStyle = CFS_RECT,
1916 .ptCurrentPos = {.x = x, .y = y},
1917 .rcArea = es->format_rect,
1918 };
1919 HIMC himc = ImmGetContext(es->hwndSelf);
1921 ImmReleaseContext(es->hwndSelf, himc);
1922}
1923#endif
1924
1925/*********************************************************************
1926 *
1927 * EDIT_SetCaretPos
1928 *
1930static void EDIT_SetCaretPos(EDITSTATE *es, INT pos,
1931 BOOL after_wrap)
1932{
1933 LRESULT res;
1934
1935 if (es->flags & EF_FOCUSED)
1936 {
1937 res = EDIT_EM_PosFromChar(es, pos, after_wrap);
1938#ifdef __REACTOS__
1939 HKL hKL = GetKeyboardLayout(0);
1940 POINT pt = { (short)LOWORD(res), (short)HIWORD(res) };
1941
1942 /* Don't set caret if not focused */
1943 if ((es->flags & EF_FOCUSED) == 0)
1944 return;
1945
1946 SetCaretPos(pt.x, pt.y);
1947
1948 if (ImmIsIME(hKL))
1949 EDIT_ImmSetCompositionWindow(es, pt);
1950#else
1951 TRACE("%d - %dx%d\n", pos, (short)LOWORD(res), (short)HIWORD(res));
1952 NtUserSetCaretPos((short)LOWORD(res), (short)HIWORD(res));
1954#endif
1955 }
1956}
1957
1958
1959/*********************************************************************
1960 *
1961 * EM_SCROLLCARET
1962 *
1964static void EDIT_EM_ScrollCaret(EDITSTATE *es)
1965{
1966 if (es->style & ES_MULTILINE) {
1967 INT l;
1968 INT vlc;
1969 INT ww;
1970 INT cw = es->char_width;
1971 INT x;
1972 INT dy = 0;
1973 INT dx = 0;
1974
1975 l = EDIT_EM_LineFromChar(es, es->selection_end);
1976 x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP));
1978 if (l >= es->y_offset + vlc)
1979 dy = l - vlc + 1 - es->y_offset;
1980 if (l < es->y_offset)
1981 dy = l - es->y_offset;
1982 ww = es->format_rect.right - es->format_rect.left;
1983 if (x < es->format_rect.left)
1984 dx = x - es->format_rect.left - ww / HSCROLL_FRACTION / cw * cw;
1985 if (x > es->format_rect.right)
1986 dx = x - es->format_rect.left - (HSCROLL_FRACTION - 1) * ww / HSCROLL_FRACTION / cw * cw;
1987 if (dy || dx || (es->y_offset && (es->line_count - es->y_offset < vlc)))
1988 {
1989 /* check if we are going to move too far */
1990 if(es->x_offset + dx + ww > es->text_width)
1991 dx = es->text_width - ww - es->x_offset;
1992 if(dx || dy || (es->y_offset && (es->line_count - es->y_offset < vlc)))
1994 }
1995 } else {
1996 INT x;
1997 INT goal;
1998 INT format_width;
1999
2000 x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, FALSE));
2001 format_width = es->format_rect.right - es->format_rect.left;
2002 if (x < es->format_rect.left) {
2003 goal = es->format_rect.left + format_width / HSCROLL_FRACTION;
2004 do {
2005 es->x_offset--;
2006 x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, FALSE));
2007 } while ((x < goal) && es->x_offset);
2008 /* FIXME: use ScrollWindow() somehow to improve performance */
2010 } else if (x > es->format_rect.right) {
2011 INT x_last;
2013 goal = es->format_rect.right - format_width / HSCROLL_FRACTION;
2014 do {
2015 es->x_offset++;
2016 x = (short)LOWORD(EDIT_EM_PosFromChar(es, es->selection_end, FALSE));
2018 } while ((x > goal) && (x_last > es->format_rect.right));
2019 /* FIXME: use ScrollWindow() somehow to improve performance */
2021 }
2022 }
2023
2024 EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP);
2025}
2026
2027
2028/*********************************************************************
2029 *
2030 * EDIT_MoveBackward
2031 *
2033static void EDIT_MoveBackward(EDITSTATE *es, BOOL extend)
2034{
2035 INT e = es->selection_end;
2036
2037 if (e) {
2038 e--;
2039 if ((es->style & ES_MULTILINE) && e &&
2040 (es->text[e - 1] == '\r') && (es->text[e] == '\n')) {
2041 e--;
2042 if (e && (es->text[e - 1] == '\r'))
2043 e--;
2044 }
2045 }
2046 EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE);
2048}
2049
2050
2051/*********************************************************************
2052 *
2053 * EDIT_MoveDown_ML
2054 *
2055 * Only for multi line controls
2056 * Move the caret one line down, on a column with the nearest
2057 * x coordinate on the screen (might be a different column).
2058 *
2060static void EDIT_MoveDown_ML(EDITSTATE *es, BOOL extend)
2061{
2062 INT s = es->selection_start;
2063 INT e = es->selection_end;
2064 BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
2065 LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap);
2066 INT x = (short)LOWORD(pos);
2067 INT y = (short)HIWORD(pos);
2068
2069 e = EDIT_CharFromPos(es, x, y + es->line_height, &after_wrap);
2070 if (!extend)
2071 s = e;
2072 EDIT_EM_SetSel(es, s, e, after_wrap);
2074}
2075
2076
2077/*********************************************************************
2078 *
2079 * EDIT_MoveEnd
2080 *
2082static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend, BOOL ctrl)
2083{
2084 BOOL after_wrap = FALSE;
2085 INT e;
2086
2087 /* Pass a high value in x to make sure of receiving the end of the line */
2088 if (!ctrl && (es->style & ES_MULTILINE))
2089 e = EDIT_CharFromPos(es, 0x3fffffff,
2090 HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)), &after_wrap);
2091 else
2092 e = get_text_length(es);
2093 EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, after_wrap);
2095}
2096
2097
2098/*********************************************************************
2099 *
2100 * EDIT_MoveForward
2101 *
2103static void EDIT_MoveForward(EDITSTATE *es, BOOL extend)
2104{
2105 INT e = es->selection_end;
2106
2107 if (es->text[e]) {
2108 e++;
2109 if ((es->style & ES_MULTILINE) && (es->text[e - 1] == '\r')) {
2110 if (es->text[e] == '\n')
2111 e++;
2112 else if ((es->text[e] == '\r') && (es->text[e + 1] == '\n'))
2113 e += 2;
2114 }
2115 }
2116 EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE);
2118}
2119
2120
2121/*********************************************************************
2122 *
2123 * EDIT_MoveHome
2124 *
2125 * Home key: move to beginning of line.
2126 *
2128static void EDIT_MoveHome(EDITSTATE *es, BOOL extend, BOOL ctrl)
2129{
2130 INT e;
2131
2132 /* Pass the x_offset in x to make sure of receiving the first position of the line */
2133 if (!ctrl && (es->style & ES_MULTILINE))
2134 e = EDIT_CharFromPos(es, -es->x_offset,
2135 HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)), NULL);
2136 else
2137 e = 0;
2138 EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE);
2140}
2141
2142
2143/*********************************************************************
2144 *
2145 * EDIT_MovePageDown_ML
2146 *
2147 * Only for multi line controls
2148 * Move the caret one page down, on a column with the nearest
2149 * x coordinate on the screen (might be a different column).
2150 *
2152static void EDIT_MovePageDown_ML(EDITSTATE *es, BOOL extend)
2153{
2154 INT s = es->selection_start;
2155 INT e = es->selection_end;
2156 BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
2157 LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap);
2158 INT x = (short)LOWORD(pos);
2159 INT y = (short)HIWORD(pos);
2160
2162 y + (es->format_rect.bottom - es->format_rect.top),
2163 &after_wrap);
2164 if (!extend)
2165 s = e;
2166 EDIT_EM_SetSel(es, s, e, after_wrap);
2168}
2169
2170
2171/*********************************************************************
2172 *
2173 * EDIT_MovePageUp_ML
2174 *
2175 * Only for multi line controls
2176 * Move the caret one page up, on a column with the nearest
2177 * x coordinate on the screen (might be a different column).
2178 *
2180static void EDIT_MovePageUp_ML(EDITSTATE *es, BOOL extend)
2181{
2182 INT s = es->selection_start;
2183 INT e = es->selection_end;
2184 BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
2185 LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap);
2186 INT x = (short)LOWORD(pos);
2187 INT y = (short)HIWORD(pos);
2188
2190 y - (es->format_rect.bottom - es->format_rect.top),
2191 &after_wrap);
2192 if (!extend)
2193 s = e;
2194 EDIT_EM_SetSel(es, s, e, after_wrap);
2196}
2197
2198
2199/*********************************************************************
2200 *
2201 * EDIT_MoveUp_ML
2202 *
2203 * Only for multi line controls
2204 * Move the caret one line up, on a column with the nearest
2205 * x coordinate on the screen (might be a different column).
2206 *
2208static void EDIT_MoveUp_ML(EDITSTATE *es, BOOL extend)
2209{
2210 INT s = es->selection_start;
2211 INT e = es->selection_end;
2212 BOOL after_wrap = (es->flags & EF_AFTER_WRAP);
2213 LRESULT pos = EDIT_EM_PosFromChar(es, e, after_wrap);
2214 INT x = (short)LOWORD(pos);
2215 INT y = (short)HIWORD(pos);
2216
2217 e = EDIT_CharFromPos(es, x, y - es->line_height, &after_wrap);
2218 if (!extend)
2219 s = e;
2220 EDIT_EM_SetSel(es, s, e, after_wrap);
2222}
2223
2224
2225/*********************************************************************
2226 *
2227 * EDIT_MoveWordBackward
2228 *
2230static void EDIT_MoveWordBackward(EDITSTATE *es, BOOL extend)
2231{
2232 INT s = es->selection_start;
2233 INT e = es->selection_end;
2234 INT l;
2235 INT ll;
2236 INT li;
2237
2241 if (e - li == 0) {
2242 if (l) {
2243 li = EDIT_EM_LineIndex(es, l - 1);
2244 e = li + EDIT_EM_LineLength(es, li);
2245 }
2246 } else {
2248 }
2249 if (!extend)
2250 s = e;
2253}
2254
2255
2256/*********************************************************************
2257 *
2258 * EDIT_MoveWordForward
2259 *
2261static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend)
2262{
2263 INT s = es->selection_start;
2264 INT e = es->selection_end;
2265 INT l;
2266 INT ll;
2267 INT li;
2268
2272 if (e - li == ll) {
2273 if ((es->style & ES_MULTILINE) && (l != es->line_count - 1))
2274 e = EDIT_EM_LineIndex(es, l + 1);
2275 } else {
2277 li, e - li + 1, ll, WB_RIGHT);
2278 }
2279 if (!extend)
2280 s = e;
2283}
2284
2285
2286/*********************************************************************
2287 *
2288 * EDIT_PaintText
2289 *
2292{
2293 COLORREF BkColor;
2294 COLORREF TextColor;
2295 INT ret;
2296 INT li;
2297 INT BkMode;
2298 SIZE size;
2299
2300 if (!count)
2301 return 0;
2302 BkMode = GetBkMode(dc);
2303 BkColor = GetBkColor(dc);
2304 TextColor = GetTextColor(dc);
2305 if (rev) {
2309 }
2311 if (es->style & ES_MULTILINE) {
2312 ret = (INT)LOWORD(TabbedTextOutW(dc, x, y, es->text + li + col, count,
2313 es->tabs_count, es->tabs, es->format_rect.left - es->x_offset));
2314 } else {
2315 TextOutW(dc, x, y, es->text + li + col, count);
2316 GetTextExtentPoint32W(dc, es->text + li + col, count, &size);
2317 ret = size.cx;
2318 }
2319 if (rev) {
2320 SetBkColor(dc, BkColor);
2321 SetTextColor(dc, TextColor);
2322 SetBkMode(dc, BkMode);
2323 }
2324 return ret;
2325}
2326
2327
2328/*********************************************************************
2329 *
2330 * EDIT_PaintLine
2331 *
2333static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev)
2334{
2335 INT s = 0;
2336 INT e = 0;
2337 INT li = 0;
2338 INT ll = 0;
2339 INT x;
2340 INT y;
2341 LRESULT pos;
2343
2344 if (es->style & ES_MULTILINE) {
2346
2347 if ((line < es->y_offset) || (line > es->y_offset + vlc) || (line >= es->line_count))
2348 return;
2349 } else if (line)
2350 return;
2351
2352 TRACE("line=%d\n", line);
2353
2356 x = (short)LOWORD(pos);
2357 y = (short)HIWORD(pos);
2358
2359 if (es->style & ES_MULTILINE)
2360 {
2361 int line_idx = line;
2362 x = -es->x_offset;
2363 if (es->style & ES_RIGHT || es->style & ES_CENTER)
2364 {
2365 LINEDEF *line_def = es->first_line_def;
2366 int w, lw;
2367
2368 while (line_def && line_idx)
2369 {
2370 line_def = line_def->next;
2371 line_idx--;
2372 }
2373 w = es->format_rect.right - es->format_rect.left;
2374 lw = line_def->width;
2375
2376 if (es->style & ES_RIGHT)
2377 x = w - (lw - x);
2378 else if (es->style & ES_CENTER)
2379 x += (w - lw) / 2;
2380 }
2381 x += es->format_rect.left;
2382 }
2383
2384 if (rev)
2385 {
2388 s = min(es->selection_start, es->selection_end);
2389 e = max(es->selection_start, es->selection_end);
2390 s = min(li + ll, max(li, s));
2391 e = min(li + ll, max(li, e));
2392 }
2393
2394 if (ssa)
2395 ScriptStringOut(ssa, x, y, 0, &es->format_rect, s - li, e - li, FALSE);
2396 else if (rev && (s != e) &&
2397 ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) {
2398 x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE);
2399 x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE);
2400 x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE);
2401 } else
2402 x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE);
2403}
2404
2405
2406/*********************************************************************
2407 *
2408 * EDIT_AdjustFormatRect
2409 *
2410 * Adjusts the format rectangle for the current font and the
2411 * current client rectangle.
2412 *
2415{
2416 RECT ClientRect;
2417
2418 es->format_rect.right = max(es->format_rect.right, es->format_rect.left + es->char_width);
2419 if (es->style & ES_MULTILINE)
2420 {
2421 INT fw, vlc, max_x_offset, max_y_offset;
2422
2424 es->format_rect.bottom = es->format_rect.top + vlc * es->line_height;
2425
2426 /* correct es->x_offset */
2427 fw = es->format_rect.right - es->format_rect.left;
2428 max_x_offset = es->text_width - fw;
2429 if(max_x_offset < 0) max_x_offset = 0;
2430 if(es->x_offset > max_x_offset)
2431 es->x_offset = max_x_offset;
2432
2433 /* correct es->y_offset */
2434 max_y_offset = es->line_count - vlc;
2435 if(max_y_offset < 0) max_y_offset = 0;
2436 if(es->y_offset > max_y_offset)
2437 es->y_offset = max_y_offset;
2438
2439 /* force scroll info update */
2441 }
2442 else
2443 {
2444 /* Windows doesn't care to fix text placement for SL controls */
2445 es->format_rect.bottom = es->format_rect.top + es->line_height;
2446
2447 /* Always stay within the client area */
2448 GetClientRect(es->hwndSelf, &ClientRect);
2449 es->format_rect.bottom = min(es->format_rect.bottom, ClientRect.bottom);
2450 }
2451
2452 if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL))
2454
2455 EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP);
2456}
2458static int EDIT_is_valid_format_rect(const EDITSTATE *es, const RECT *rc)
2459{
2460 if (IsRectEmpty(rc))
2461 return 0;
2462 if (es->text_width > (rc->right - rc->left) || (es->line_height * es->line_count) > (rc->bottom - rc->top))
2463 return 0;
2464 return 1;
2465}
2466
2467/*********************************************************************
2468 *
2469 * EDIT_SetRectNP
2470 *
2471 * note: this is not (exactly) the handler called on EM_SETRECTNP
2472 * it is also used to set the rect of a single line control
2473 *
2475static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc)
2476{
2478 INT bw, bh;
2479 BOOL too_large = FALSE;
2480 RECT edit_rect;
2481
2483
2485 {
2486 CopyRect(&es->format_rect, rc);
2487 GetClientRect(es->hwndSelf, &edit_rect);
2488 too_large = (rc->bottom - rc->top) > (edit_rect.bottom - edit_rect.top);
2489 }
2490 else
2491 {
2492 GetClientRect(es->hwndSelf, &es->format_rect);
2493 }
2494
2495 if (ExStyle & WS_EX_CLIENTEDGE && !too_large) {
2496 es->format_rect.left++;
2497 es->format_rect.right--;
2498
2499 if (es->format_rect.bottom - es->format_rect.top
2500 >= es->line_height + 2)
2501 {
2502 es->format_rect.top++;
2503 es->format_rect.bottom--;
2504 }
2505 }
2506 else if (es->style & WS_BORDER) {
2508 bh = GetSystemMetrics(SM_CYBORDER) + 1;
2509 es->format_rect.left += bw;
2510 es->format_rect.right -= bw;
2511 if (es->format_rect.bottom - es->format_rect.top
2512 >= es->line_height + 2 * bh)
2513 {
2514 es->format_rect.top += bh;
2515 es->format_rect.bottom -= bh;
2516 }
2517 }
2518
2519 es->format_rect.left += es->left_margin;
2520 es->format_rect.right -= es->right_margin;
2522}
2523
2524
2525/*********************************************************************
2526 *
2527 * EM_CHARFROMPOS
2528 *
2529 * returns line number (not index) in high-order word of result.
2530 * NB : Q137805 is unclear about this. POINT * pointer in lParam apply
2531 * to Richedit, not to the edit control. Original documentation is valid.
2532 * FIXME: do the specs mean to return -1 if outside client area or
2533 * if outside formatting rectangle ???
2534 *
2537{
2538 POINT pt;
2539 RECT rc;
2540 INT index;
2541
2542 pt.x = x;
2543 pt.y = y;
2544 GetClientRect(es->hwndSelf, &rc);
2545 if (!PtInRect(&rc, pt))
2546 return -1;
2547
2550}
2551
2552
2553/*********************************************************************
2554 *
2555 * EM_FMTLINES
2556 *
2557 * Enable or disable soft breaks.
2558 *
2559 * This means: insert or remove the soft linebreak character (\r\r\n).
2560 * Take care to check if the text still fits the buffer after insertion.
2561 * If not, notify with EN_ERRSPACE.
2562 *
2564static BOOL EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol)
2565{
2566 es->flags &= ~EF_USE_SOFTBRK;
2567 if (add_eol) {
2568 es->flags |= EF_USE_SOFTBRK;
2569 FIXME("soft break enabled, not implemented\n");
2570 }
2571 return add_eol;
2572}
2573
2574
2575/*********************************************************************
2576 *
2577 * EM_GETHANDLE
2578 *
2579 * Hopefully this won't fire back at us.
2580 * We always start with a fixed buffer in the local heap.
2581 * Despite of the documentation says that the local heap is used
2582 * only if DS_LOCALEDIT flag is set, NT and 2000 always allocate
2583 * buffer on the local heap.
2584 *
2587{
2588 HLOCAL hLocal;
2589
2590 if (!(es->style & ES_MULTILINE))
2591 return 0;
2592
2593 if(es->is_unicode)
2594 hLocal = es->hloc32W;
2595 else
2596 {
2597 if(!es->hloc32A)
2598 {
2599 CHAR *textA;
2600 UINT countA, alloc_size;
2601 TRACE("Allocating 32-bit ANSI alias buffer\n");
2602 countA = WideCharToMultiByte(CP_ACP, 0, es->text, -1, NULL, 0, NULL, NULL);
2603 alloc_size = ROUND_TO_GROW(countA);
2604 if(!(es->hloc32A = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size)))
2605 {
2606 ERR("Could not allocate %d bytes for 32-bit ANSI alias buffer\n", alloc_size);
2607 return 0;
2608 }
2609 textA = LocalLock(es->hloc32A);
2610 WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, countA, NULL, NULL);
2611 LocalUnlock(es->hloc32A);
2612 }
2613 hLocal = es->hloc32A;
2614 }
2615
2617
2618 /* The text buffer handle belongs to the app */
2619 es->hlocapp = hLocal;
2620
2621 TRACE("Returning %p, LocalSize() = %Id\n", hLocal, LocalSize(hLocal));
2622 return hLocal;
2623}
2624
2625
2626/*********************************************************************
2627 *
2628 * EM_GETLINE
2629 *
2631static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPWSTR dst, BOOL unicode)
2632{
2633 LPWSTR src;
2634 INT line_len, dst_len;
2635 INT i;
2636
2637 if (es->style & ES_MULTILINE) {
2638 if (line >= es->line_count)
2639 return 0;
2640 } else
2641 line = 0;
2643 src = es->text + i;
2644 line_len = EDIT_EM_LineLength(es, i);
2645 dst_len = *(WORD *)dst;
2646 if(unicode)
2647 {
2648 if(dst_len <= line_len)
2649 {
2650 memcpy(dst, src, dst_len * sizeof(WCHAR));
2651 return dst_len;
2652 }
2653 else /* Append 0 if enough space */
2654 {
2655 memcpy(dst, src, line_len * sizeof(WCHAR));
2656 dst[line_len] = 0;
2657 return line_len;
2658 }
2659 }
2660 else
2661 {
2662 INT ret = WideCharToMultiByte(CP_ACP, 0, src, line_len, (LPSTR)dst, dst_len, NULL, NULL);
2663 if(!ret && line_len) /* Insufficient buffer size */
2664 return dst_len;
2665 if(ret < dst_len) /* Append 0 if enough space */
2666 ((LPSTR)dst)[ret] = 0;
2667 return ret;
2668 }
2669}
2670
2671
2672/*********************************************************************
2673 *
2674 * EM_GETSEL
2675 *
2678{
2679 UINT s = es->selection_start;
2680 UINT e = es->selection_end;
2681
2682 ORDER_UINT(s, e);
2683 if (start)
2684 *start = s;
2685 if (end)
2686 *end = e;
2687 return MAKELONG(s, e);
2688}
2689
2690
2691/*********************************************************************
2692 *
2693 * EM_REPLACESEL
2694 *
2695 * FIXME: handle ES_NUMBER and ES_OEMCONVERT here
2696 *
2698static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_replace, UINT strl,
2699 BOOL send_update, BOOL honor_limit)
2700{
2701 UINT tl = get_text_length(es);
2702 UINT utl;
2703 UINT s;
2704 UINT e;
2705 UINT i;
2706 UINT size;
2707 LPWSTR p;
2708 HRGN hrgn = 0;
2709 LPWSTR buf = NULL;
2710 UINT bufl;
2711
2712 TRACE("%s, can_undo %d, send_update %d\n",
2713 debugstr_wn(lpsz_replace, strl), can_undo, send_update);
2714
2715 s = es->selection_start;
2716 e = es->selection_end;
2717
2719 if ((s == e) && !strl)
2720 return;
2721
2722 ORDER_UINT(s, e);
2723
2724 size = tl - (e - s) + strl;
2725 if (!size)
2726 es->text_width = 0;
2727
2728 /* Issue the EN_MAXTEXT notification and continue with replacing text
2729 * so that buffer limit is honored. */
2730 if ((honor_limit) && (size > es->buffer_limit))
2731 {
2732 if (!notify_parent(es, EN_MAXTEXT)) return;
2733 /* Buffer limit can be smaller than the actual length of text in combobox */
2734 if (es->buffer_limit < (tl - (e-s)))
2735 strl = 0;
2736 else
2737 strl = min(strl, es->buffer_limit - (tl - (e-s)));
2738 }
2739
2740 if (!EDIT_MakeFit(es, tl - (e - s) + strl))
2741 return;
2742
2743 if (e != s) {
2744 /* there is something to be deleted */
2745 TRACE("deleting stuff.\n");
2746 bufl = e - s;
2747 buf = HeapAlloc(GetProcessHeap(), 0, (bufl + 1) * sizeof(WCHAR));
2748 if (!buf) return;
2749 memcpy(buf, es->text + s, bufl * sizeof(WCHAR));
2750 buf[bufl] = 0; /* ensure 0 termination */
2751 /* now delete */
2752 lstrcpyW(es->text + s, es->text + e);
2754 }
2755 if (strl) {
2756 /* there is an insertion */
2757 tl = get_text_length(es);
2758 TRACE("inserting stuff (tl %d, strl %d, selstart %d (%s), text %s)\n", tl, strl, s, debugstr_w(es->text + s), debugstr_w(es->text));
2759 for (p = es->text + tl ; p >= es->text + s ; p--)
2760 p[strl] = p[0];
2761 for (i = 0 , p = es->text + s ; i < strl ; i++)
2762 p[i] = lpsz_replace[i];
2763 if(es->style & ES_UPPERCASE)
2764 CharUpperBuffW(p, strl);
2765 else if(es->style & ES_LOWERCASE)
2766 CharLowerBuffW(p, strl);
2768 }
2769 if (es->style & ES_MULTILINE)
2770 {
2771 INT st = min(es->selection_start, es->selection_end);
2773
2774 hrgn = CreateRectRgn(0, 0, 0, 0);
2775 EDIT_BuildLineDefs_ML(es, st, st + strl,
2776 strl - abs(es->selection_end - es->selection_start), hrgn);
2777 /* if text is too long undo all changes */
2778 if (honor_limit && !(es->style & ES_AUTOVSCROLL) && (es->line_count > vlc)) {
2779 if (strl)
2780 lstrcpyW(es->text + e, es->text + e + strl);
2781 if (e != s)
2782 for (i = 0 , p = es->text ; i < e - s ; i++)
2783 p[i + s] = buf[i];
2786 abs(es->selection_end - es->selection_start) - strl, hrgn);
2787 strl = 0;
2788 e = s;
2789 SetRectRgn(hrgn, 0, 0, 0, 0);
2790 if (!notify_parent(es, EN_MAXTEXT)) return;
2791 }
2792 }
2793 else {
2794 INT fw = es->format_rect.right - es->format_rect.left;
2797 /* remove chars that don't fit */
2798 if (honor_limit && !(es->style & ES_AUTOHSCROLL) && (es->text_width > fw)) {
2799 while ((es->text_width > fw) && s + strl >= s) {
2800 lstrcpyW(es->text + s + strl - 1, es->text + s + strl);
2801 strl--;
2802 es->text_length = -1;
2805 }
2807 if (!notify_parent(es, EN_MAXTEXT)) return;
2808 }
2809 }
2810
2811 if (e != s) {
2812 if (can_undo) {
2813 utl = lstrlenW(es->undo_text);
2814 if (!es->undo_insert_count && (*es->undo_text && (s == es->undo_position))) {
2815 /* undo-buffer is extended to the right */
2816 EDIT_MakeUndoFit(es, utl + e - s);
2817 memcpy(es->undo_text + utl, buf, (e - s)*sizeof(WCHAR));
2818 (es->undo_text + utl)[e - s] = 0; /* ensure 0 termination */
2819 } else if (!es->undo_insert_count && (*es->undo_text && (e == es->undo_position))) {
2820 /* undo-buffer is extended to the left */
2821 EDIT_MakeUndoFit(es, utl + e - s);
2822 for (p = es->undo_text + utl ; p >= es->undo_text ; p--)
2823 p[e - s] = p[0];
2824 for (i = 0 , p = es->undo_text ; i < e - s ; i++)
2825 p[i] = buf[i];
2826 es->undo_position = s;
2827 } else {
2828 /* new undo-buffer */
2829 EDIT_MakeUndoFit(es, e - s);
2830 memcpy(es->undo_text, buf, (e - s)*sizeof(WCHAR));
2831 es->undo_text[e - s] = 0; /* ensure 0 termination */
2832 es->undo_position = s;
2833 }
2834 /* any deletion makes the old insertion-undo invalid */
2835 es->undo_insert_count = 0;
2836 } else
2838 }
2839 if (strl) {
2840 if (can_undo) {
2841 if ((s == es->undo_position) ||
2842 ((es->undo_insert_count) &&
2843 (s == es->undo_position + es->undo_insert_count)))
2844 /*
2845 * insertion is new and at delete position or
2846 * an extension to either left or right
2847 */
2848 es->undo_insert_count += strl;
2849 else {
2850 /* new insertion undo */
2851 es->undo_position = s;
2852 es->undo_insert_count = strl;
2853 /* new insertion makes old delete-buffer invalid */
2854 *es->undo_text = '\0';
2855 }
2856 } else
2858 }
2859
2861
2862 s += strl;
2863
2864 /* If text has been deleted and we're right or center aligned then scroll rightward */
2865 if (es->style & (ES_RIGHT | ES_CENTER))
2866 {
2867 INT delta = strl - abs(es->selection_end - es->selection_start);
2868
2869 if (delta < 0 && es->x_offset)
2870 {
2871 if (abs(delta) > es->x_offset)
2872 es->x_offset = 0;
2873 else
2874 es->x_offset += delta;
2875 }
2876 }
2877
2879 es->flags |= EF_MODIFIED;
2880 if (send_update) es->flags |= EF_UPDATE;
2881 if (hrgn)
2882 {
2885 }
2886 else
2888
2890
2891 /* force scroll info update */
2893
2894
2895 if(send_update || (es->flags & EF_UPDATE))
2896 {
2897 es->flags &= ~EF_UPDATE;
2898 if (!notify_parent(es, EN_CHANGE)) return;
2899 }
2901}
2902
2903
2904/*********************************************************************
2905 *
2906 * EM_SETHANDLE
2907 *
2908 * FIXME: ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ???
2909 *
2911static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc)
2912{
2913 if (!(es->style & ES_MULTILINE))
2914 return;
2915
2916 if (!hloc) {
2917 WARN("called with NULL handle\n");
2918 return;
2919 }
2920
2921#ifdef __REACTOS__
2922 if (es->text)
2923#endif
2925
2926 if(es->is_unicode)
2927 {
2928 if(es->hloc32A)
2929 {
2930 LocalFree(es->hloc32A);
2931 es->hloc32A = NULL;
2932 }
2933 es->hloc32W = hloc;
2934 }
2935 else
2936 {
2937 INT countW, countA;
2938 HLOCAL hloc32W_new;
2939 WCHAR *textW;
2940 CHAR *textA;
2941
2942 countA = LocalSize(hloc);
2943 textA = LocalLock(hloc);
2944 countW = MultiByteToWideChar(CP_ACP, 0, textA, countA, NULL, 0);
2945 if(!(hloc32W_new = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, countW * sizeof(WCHAR))))
2946 {
2947 ERR("Could not allocate new unicode buffer\n");
2948 return;
2949 }
2950 textW = LocalLock(hloc32W_new);
2951 MultiByteToWideChar(CP_ACP, 0, textA, countA, textW, countW);
2952 LocalUnlock(hloc32W_new);
2953 LocalUnlock(hloc);
2954
2955 if(es->hloc32W)
2956 LocalFree(es->hloc32W);
2957
2958 es->hloc32W = hloc32W_new;
2959 es->hloc32A = hloc;
2960 }
2961
2962 es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
2963
2964 /* The text buffer handle belongs to the control */
2965 es->hlocapp = NULL;
2966
2969
2970 es->x_offset = es->y_offset = 0;
2971 es->selection_start = es->selection_end = 0;
2973 es->flags &= ~EF_MODIFIED;
2974 es->flags &= ~EF_UPDATE;
2978 /* force scroll info update */
2980}
2981
2982
2983/*********************************************************************
2984 *
2985 * EM_SETLIMITTEXT
2986 *
2987 * NOTE: this version currently implements WinNT limits
2988 *
2991{
2992 if (!limit) limit = ~0u;
2993 if (!(es->style & ES_MULTILINE)) limit = min(limit, 0x7ffffffe);
2994 es->buffer_limit = limit;
2995}
2997static BOOL is_cjk_charset(HDC dc)
2998{
2999 switch (GdiGetCodePage(dc)) {
3000 case 932: case 936: case 949: case 950: case 1361:
3001 return TRUE;
3002 default:
3003 return FALSE;
3004 }
3005}
3007static BOOL is_cjk_font(HDC dc)
3008{
3011 return (GetTextCharsetInfo(dc, &fs, 0) != DEFAULT_CHARSET &&
3012 (fs.fsCsb[0] & FS_DBCS_MASK));
3013}
3015static int get_cjk_fontinfo_margin(int width, int side_bearing)
3016{
3017 int margin;
3018 if (side_bearing < 0)
3019 margin = min(-side_bearing, width/2);
3020 else
3021 margin = 0;
3022 return margin;
3023}
3024
3025struct char_width_info {
3027};
3028
3029/* Undocumented gdi32 export */
3031
3032/*********************************************************************
3033 *
3034 * EM_SETMARGINS
3035 *
3036 * EC_USEFONTINFO is used as a left or right value i.e. lParam and not as an
3037 * action wParam despite what the docs say. EC_USEFONTINFO calculates the
3038 * margin according to the textmetrics of the current font.
3039 *
3040 * When EC_USEFONTINFO is used, the margins only change if the edit control is
3041 * equal to or larger than a certain size. The empty client rect is treated as
3042 * 80 pixels width.
3045 WORD left, WORD right, BOOL repaint)
3046{
3048 INT default_left_margin = 0; /* in pixels */
3049 INT default_right_margin = 0; /* in pixels */
3050
3051 /* Set the default margins depending on the font */
3052 if (es->font && (left == EC_USEFONTINFO || right == EC_USEFONTINFO)) {
3053 HDC dc = NtUserGetDC(es->hwndSelf);
3054 HFONT old_font = SelectObject(dc, es->font);
3055 LONG width = GdiGetCharDimensions(dc, &tm, NULL), rc_width;
3056 RECT rc;
3057
3058 /* The default margins are only non zero for TrueType or Vector fonts */
3059 if (tm.tmPitchAndFamily & ( TMPF_VECTOR | TMPF_TRUETYPE )) {
3060 struct char_width_info width_info;
3061
3062 if ((is_cjk_charset(dc) || is_cjk_font(dc)) &&
3063 GetCharWidthInfo(dc, &width_info))
3064 {
3065 default_left_margin = get_cjk_fontinfo_margin(width, width_info.min_lsb);
3066 default_right_margin = get_cjk_fontinfo_margin(width, width_info.min_rsb);
3067 }
3068 else
3069 {
3070 default_left_margin = width / 2;
3071 default_right_margin = width / 2;
3072 }
3073
3074 GetClientRect(es->hwndSelf, &rc);
3075 rc_width = !IsRectEmpty(&rc) ? rc.right - rc.left : 80;
3076 if (rc_width < default_left_margin + default_right_margin + width * 2) {
3077 default_left_margin = es->left_margin;
3078 default_right_margin = es->right_margin;
3079 }
3080 }
3081 SelectObject(dc, old_font);
3082 NtUserReleaseDC( es->hwndSelf, dc );
3083 }
3084
3085 if (action & EC_LEFTMARGIN) {
3086 es->format_rect.left -= es->left_margin;
3087 if (left != EC_USEFONTINFO)
3088 es->left_margin = left;
3089 else
3090 es->left_margin = default_left_margin;
3091 es->format_rect.left += es->left_margin;
3092 }
3093
3094 if (action & EC_RIGHTMARGIN) {
3095 es->format_rect.right += es->right_margin;
3096 if (right != EC_USEFONTINFO)
3097 es->right_margin = right;
3098 else
3099 es->right_margin = default_right_margin;
3100 es->format_rect.right -= es->right_margin;
3101 }
3102
3105 if (repaint) EDIT_UpdateText(es, NULL, TRUE);
3106 }
3107
3108 TRACE("left=%d, right=%d\n", es->left_margin, es->right_margin);
3109}
3110
3111
3112/*********************************************************************
3113 *
3114 * EM_SETPASSWORDCHAR
3115 *
3118{
3119 LONG style;
3120
3121 if (es->password_char == c)
3122 return TRUE;
3123
3124 style = GetWindowLongW( es->hwndSelf, GWL_STYLE );
3125 es->password_char = c;
3126 if (c) {
3127 SetWindowLongW( es->hwndSelf, GWL_STYLE, style | ES_PASSWORD );
3128 es->style |= ES_PASSWORD;
3129 } else {
3130 SetWindowLongW( es->hwndSelf, GWL_STYLE, style & ~ES_PASSWORD );
3131 es->style &= ~ES_PASSWORD;
3132 }
3135 return TRUE;
3136}
3137
3138
3139/*********************************************************************
3140 *
3141 * EM_SETTABSTOPS
3142 *
3144static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, const INT *tabs)
3145{
3146 if (!(es->style & ES_MULTILINE))
3147 return FALSE;
3148 HeapFree(GetProcessHeap(), 0, es->tabs);
3149 es->tabs_count = count;
3150 if (!count)
3151 es->tabs = NULL;
3152 else {
3153 es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
3154#ifdef __REACTOS__
3155 /* ReactOS r33503 */
3156 if (es->tabs == NULL)
3157 {
3158 es->tabs_count = 0;
3159 return FALSE;
3160 }
3161#endif
3162 memcpy(es->tabs, tabs, count * sizeof(INT));
3163 }
3165 return TRUE;
3166}
3167
3168
3169/*********************************************************************
3170 *
3171 * EM_SETWORDBREAKPROC
3172 *
3174static void EDIT_EM_SetWordBreakProc(EDITSTATE *es, void *wbp)
3175{
3176 if (es->word_break_proc == wbp)
3177 return;
3178
3179 es->word_break_proc = wbp;
3180
3181 if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) {
3184 }
3185}
3186
3187
3188/*********************************************************************
3189 *
3190 * EM_UNDO / WM_UNDO
3191 *
3194{
3195 INT ulength;
3196 LPWSTR utext;
3197
3198 /* As per MSDN spec, for a single-line edit control,
3199 the return value is always TRUE */
3200 if( es->style & ES_READONLY )
3201 return !(es->style & ES_MULTILINE);
3202
3203 ulength = lstrlenW(es->undo_text);
3204
3205 utext = HeapAlloc(GetProcessHeap(), 0, (ulength + 1) * sizeof(WCHAR));
3206#ifdef __REACTOS__
3207 /* ReactOS r33503 */
3208 if (utext == NULL)
3209 return FALSE;
3210#endif
3211
3212 lstrcpyW(utext, es->undo_text);
3213
3214 TRACE("before UNDO:insertion length = %d, deletion buffer = %s\n",
3215 es->undo_insert_count, debugstr_w(utext));
3216
3217 EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
3219 EDIT_EM_ReplaceSel(es, TRUE, utext, ulength, TRUE, TRUE);
3220 EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
3221 /* send the notification after the selection start and end are set */
3222 if (!notify_parent(es, EN_CHANGE)) return TRUE;
3224 HeapFree(GetProcessHeap(), 0, utext);
3225
3226 TRACE("after UNDO:insertion length = %d, deletion buffer = %s\n",
3227 es->undo_insert_count, debugstr_w(es->undo_text));
3228 return TRUE;
3229}
3230
3231
3232/* Helper function for WM_CHAR
3233 *
3234 * According to an MSDN blog article titled "Just because you're a control
3235 * doesn't mean that you're necessarily inside a dialog box," multiline edit
3236 * controls without ES_WANTRETURN would attempt to detect whether it is inside
3237 * a dialog box or not.
3239static inline BOOL EDIT_IsInsideDialog(EDITSTATE *es)
3240{
3241 return (es->flags & EF_DIALOGMODE);
3242}
3243
3244
3245/*********************************************************************
3246 *
3247 * WM_PASTE
3248 *
3250static void EDIT_WM_Paste(EDITSTATE *es)
3251{
3252 HGLOBAL hsrc;
3253 LPWSTR src, ptr;
3254 int len;
3255
3256 /* Protect read-only edit control from modification */
3257 if(es->style & ES_READONLY)
3258 return;
3259
3260 OpenClipboard(es->hwndSelf);
3261 if ((hsrc = GetClipboardData(CF_UNICODETEXT))) {
3262 src = GlobalLock(hsrc);
3263 len = lstrlenW(src);
3264 /* Protect single-line edit against pasting new line character */
3265 if (!(es->style & ES_MULTILINE) && ((ptr = wcschr(src, '\n')))) {
3266 len = ptr - src;
3267 if (len && src[len - 1] == '\r')
3268 --len;
3269 }
3271 GlobalUnlock(hsrc);
3272 }
3273 else if (es->style & ES_PASSWORD) {
3274 /* clear selected text in password edit box even with empty clipboard */
3276 }
3278}
3279
3280
3281/*********************************************************************
3282 *
3283 * WM_COPY
3284 *
3286static void EDIT_WM_Copy(EDITSTATE *es)
3287{
3288 INT s = min(es->selection_start, es->selection_end);
3289 INT e = max(es->selection_start, es->selection_end);
3290 HGLOBAL hdst;
3291 LPWSTR dst;
3292 DWORD len;
3293
3294 if (e == s) return;
3295
3296 len = e - s;
3297 hdst = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (len + 1) * sizeof(WCHAR));
3298 dst = GlobalLock(hdst);
3299 memcpy(dst, es->text + s, len * sizeof(WCHAR));
3300 dst[len] = 0; /* ensure 0 termination */
3301 TRACE("%s\n", debugstr_w(dst));
3302 GlobalUnlock(hdst);
3303 OpenClipboard(es->hwndSelf);
3307}
3308
3309
3310/*********************************************************************
3311 *
3312 * WM_CLEAR
3313 *
3315static inline void EDIT_WM_Clear(EDITSTATE *es)
3316{
3317 /* Protect read-only edit control from modification */
3318 if(es->style & ES_READONLY)
3319 return;
3320
3322}
3323
3324
3325/*********************************************************************
3326 *
3327 * WM_CUT
3328 *
3330static inline void EDIT_WM_Cut(EDITSTATE *es)
3331{
3334}
3335
3336
3337/*********************************************************************
3338 *
3339 * WM_CHAR
3340 *
3343{
3344 BOOL control;
3345
3346
3347 if (es->bCaptureState)
3348 return 1;
3349
3351
3352 switch (c) {
3353 case '\r':
3354 /* If it's not a multiline edit box, it would be ignored below.
3355 * For multiline edit without ES_WANTRETURN, we have to make a
3356 * special case.
3357 */
3358 if ((es->style & ES_MULTILINE) && !(es->style & ES_WANTRETURN))
3360 break;
3361 case '\n':
3362 if (es->style & ES_MULTILINE) {
3363 if (es->style & ES_READONLY) {
3366 } else {
3367 EDIT_EM_ReplaceSel(es, TRUE, L"\r\n", 2, TRUE, TRUE);
3368 }
3369 }
3370 break;
3371 case '\t':
3372 if ((es->style & ES_MULTILINE) && !(es->style & ES_READONLY))
3373 {
3375 break;
3376 EDIT_EM_ReplaceSel(es, TRUE, L"\t", 1, TRUE, TRUE);
3377 }
3378 break;
3379 case VK_BACK:
3380 if (!(es->style & ES_READONLY) && !control) {
3381 if (es->selection_start != es->selection_end)
3383 else {
3384 /* delete character left of caret */
3385 EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE);
3388 }
3389 }
3390 break;
3391 case 0x03: /* ^C */
3392 if (!(es->style & ES_PASSWORD))
3393 SendMessageW(es->hwndSelf, WM_COPY, 0, 0);
3394 break;
3395 case 0x16: /* ^V */
3396 if (!(es->style & ES_READONLY))
3397 SendMessageW(es->hwndSelf, WM_PASTE, 0, 0);
3398 break;
3399 case 0x18: /* ^X */
3400 if (!((es->style & ES_READONLY) || (es->style & ES_PASSWORD)))
3401 SendMessageW(es->hwndSelf, WM_CUT, 0, 0);
3402 break;
3403 case 0x1A: /* ^Z */
3404 if (!(es->style & ES_READONLY))
3405 SendMessageW(es->hwndSelf, WM_UNDO, 0, 0);
3406 break;
3407
3408 default:
3409 /*If Edit control style is ES_NUMBER allow users to key in only numeric values*/
3410 if( (es->style & ES_NUMBER) && !( c >= '0' && c <= '9') )
3411 break;
3412
3413 if (!(es->style & ES_READONLY) && (c >= ' ') && (c != 127))
3415 break;
3416 }
3417 return 1;
3418}
3419
3420
3421/*********************************************************************
3422 *
3423 * EDIT_ContextMenuCommand
3424 *
3426static void EDIT_ContextMenuCommand(EDITSTATE *es, UINT id)
3427{
3428 switch (id) {
3429 case EM_UNDO:
3430 SendMessageW(es->hwndSelf, WM_UNDO, 0, 0);
3431 break;
3432 case WM_CUT:
3433 SendMessageW(es->hwndSelf, WM_CUT, 0, 0);
3434 break;
3435 case WM_COPY:
3436 SendMessageW(es->hwndSelf, WM_COPY, 0, 0);
3437 break;
3438 case WM_PASTE:
3439 SendMessageW(es->hwndSelf, WM_PASTE, 0, 0);
3440 break;
3441 case WM_CLEAR:
3442 SendMessageW(es->hwndSelf, WM_CLEAR, 0, 0);
3443 break;
3444 case EM_SETSEL:
3445 SendMessageW(es->hwndSelf, EM_SETSEL, 0, -1);
3446 break;
3447 default:
3448 ERR("unknown menu item, please report\n");
3449 break;
3450 }
3451}
3452
3453
3454/*********************************************************************
3455 *
3456 * WM_CONTEXTMENU
3457 *
3458 * Note: the resource files resource/sysres_??.rc cannot define a
3459 * single popup menu. Hence we use a (dummy) menubar
3460 * containing the single popup menu as its first item.
3461 *
3462 * FIXME: the message identifiers have been chosen arbitrarily,
3463 * hence we use MF_BYPOSITION.
3464 * We might as well use the "real" values (anybody knows ?)
3465 * The menu definition is in resources/sysres_??.rc.
3466 * Once these are OK, we better use MF_BYCOMMAND here
3467 * (as we do in EDIT_WM_Command()).
3468 *
3470static void EDIT_WM_ContextMenu(EDITSTATE *es, INT x, INT y)
3471{
3472 HMENU menu = LoadMenuA(user32_module, "EDITMENU");
3473 HMENU popup = GetSubMenu(menu, 0);
3474 UINT start = es->selection_start;
3475 UINT end = es->selection_end;
3476 BOOL enabled;
3477 UINT cmd;
3478
3480
3481 /* undo */
3482 enabled = EDIT_EM_CanUndo(es) && !(es->style & ES_READONLY);
3484 /* cut */
3485 enabled = (end - start) && !(es->style & ES_PASSWORD) && !(es->style & ES_READONLY);
3487 /* copy */
3488 enabled = (end - start) && !(es->style & ES_PASSWORD);
3490 /* paste */
3493 /* delete */
3494 enabled = (end - start) && !(es->style & ES_READONLY);
3496 /* select all */
3499
3500 if (x == -1 && y == -1) /* passed via VK_APPS press/release */
3501 {
3502#ifdef __REACTOS__ /* Should be dropped */
3503 RECT rc;
3504
3505 /* ReactOS r29811 */
3506 GetClientRect(es->hwndSelf, &rc);
3507 MapWindowPoints(es->hwndSelf, 0, (POINT *)&rc, 2);
3508 x = rc.left + (rc.right - rc.left) / 2;
3509 y = rc.top + (rc.bottom - rc.top) / 2;
3510#else
3511 POINT pt;
3512 RECT rc;
3513
3514 /* Windows places the menu at the edit's center in this case */
3515 GetClientRect( es->hwndSelf, &rc );
3516 pt.x = rc.right / 2;
3517 pt.y = rc.bottom / 2;
3518 ClientToScreen( es->hwndSelf, &pt );
3519 x = pt.x;
3520 y = pt.y;
3521#endif
3522 }
3523
3524 if (!(es->flags & EF_FOCUSED))
3525 NtUserSetFocus(es->hwndSelf);
3526
3528 x, y, 0, es->hwndSelf, NULL);
3529
3530 if (cmd)
3532
3534}
3535
3536
3537/*********************************************************************
3538 *
3539 * WM_GETTEXT
3540 *
3542static INT EDIT_WM_GetText(const EDITSTATE *es, INT count, LPWSTR dst, BOOL unicode)
3543{
3544 if(!count) return 0;
3545
3546 if(unicode)
3547 {
3548 lstrcpynW(dst, es->text, count);
3549 return lstrlenW(dst);
3550 }
3551 else
3552 {
3553 LPSTR textA = (LPSTR)dst;
3554 if (!WideCharToMultiByte(CP_ACP, 0, es->text, -1, textA, count, NULL, NULL))
3555 textA[count - 1] = 0; /* ensure 0 termination */
3556 return strlen(textA);
3557 }
3558}
3559
3560/*********************************************************************
3561 *
3562 * EDIT_CheckCombo
3563 *
3566{
3567 HWND hLBox = es->hwndListBox;
3568 HWND hCombo;
3569 BOOL bDropped;
3570 int nEUI;
3571
3572 if (!hLBox)
3573 return FALSE;
3574
3575 hCombo = GetParent(es->hwndSelf);
3576 bDropped = TRUE;
3577 nEUI = 0;
3578
3579 TRACE_(combo)("[%p]: handling msg %x (%x)\n", es->hwndSelf, msg, key);
3580
3581 if (key == VK_UP || key == VK_DOWN)
3582 {
3583 if (SendMessageW(hCombo, CB_GETEXTENDEDUI, 0, 0))
3584 nEUI = 1;
3585
3586 if (msg == WM_KEYDOWN || nEUI)
3587 bDropped = (BOOL)SendMessageW(hCombo, CB_GETDROPPEDSTATE, 0, 0);
3588 }
3589
3590 switch (msg)
3591 {
3592 case WM_KEYDOWN:
3593 if (!bDropped && nEUI && (key == VK_UP || key == VK_DOWN))
3594 {
3595 /* make sure ComboLBox pops up */
3596 SendMessageW(hCombo, CB_SETEXTENDEDUI, FALSE, 0);
3597 key = VK_F4;
3598 nEUI = 2;
3599 }
3600
3601 SendMessageW(hLBox, WM_KEYDOWN, key, 0);
3602 break;
3603
3604 case WM_SYSKEYDOWN: /* Handle Alt+up/down arrows */
3605 if (nEUI)
3606 SendMessageW(hCombo, CB_SHOWDROPDOWN, !bDropped, 0);
3607 else
3608 SendMessageW(hLBox, WM_KEYDOWN, VK_F4, 0);
3609 break;
3610 }
3611
3612 if(nEUI == 2)
3613 SendMessageW(hCombo, CB_SETEXTENDEDUI, TRUE, 0);
3614
3615 return TRUE;
3616}
3617
3618
3619/*********************************************************************
3620 *
3621 * WM_KEYDOWN
3622 *
3623 * Handling of special keys that don't produce a WM_CHAR
3624 * (i.e. non-printable keys) & Backspace & Delete
3625 *
3628{
3629 BOOL shift;
3630 BOOL control;
3631
3632 if (es->bCaptureState)
3633 return 1;
3634
3635 if (NtUserGetKeyState(VK_MENU) & 0x8000)
3636 return 0;
3637
3638 shift = NtUserGetKeyState(VK_SHIFT) & 0x8000;
3640
3641 switch (key) {
3642 case VK_F4:
3643 case VK_UP:
3645 break;
3646
3647 /* fall through */
3648 case VK_LEFT:
3649 if ((es->style & ES_MULTILINE) && (key == VK_UP))
3651 else
3652 if (control)
3654 else
3656 break;
3657 case VK_DOWN:
3659 break;
3660 /* fall through */
3661 case VK_RIGHT:
3662 if ((es->style & ES_MULTILINE) && (key == VK_DOWN))
3664 else if (control)
3666 else
3668 break;
3669 case VK_HOME:
3671 break;
3672 case VK_END:
3674 break;
3675 case VK_PRIOR:
3676 if (es->style & ES_MULTILINE)
3678 else
3680 break;
3681 case VK_NEXT:
3682 if (es->style & ES_MULTILINE)
3684 else
3686 break;
3687 case VK_DELETE:
3688 if (!(es->style & ES_READONLY) && !(shift && control)) {
3689 if (es->selection_start != es->selection_end) {
3690 if (shift)
3691 EDIT_WM_Cut(es);
3692 else
3694 } else {
3695 EDIT_EM_SetSel(es, ~0u, 0, FALSE);
3696 if (shift)
3697 /* delete character left of caret */
3699 else if (control)
3700 /* delete to end of line */
3702 else
3703 /* delete character right of caret */
3706 }
3707 }
3708 break;
3709 case VK_INSERT:
3710 if (shift) {
3711 if (!(es->style & ES_READONLY))
3713 } else if (control)
3715 break;
3716 case VK_RETURN:
3717 /* If the edit doesn't want the return send a message to the default object */
3718 if(!(es->style & ES_MULTILINE) || !(es->style & ES_WANTRETURN))
3719 {
3720 DWORD dw;
3721
3722 if (!EDIT_IsInsideDialog(es)) break;
3723 if (control) break;
3724 dw = SendMessageW(es->hwndParent, DM_GETDEFID, 0, 0);
3725 if (HIWORD(dw) == DC_HASDEFID)
3726 {
3727 HWND hwDefCtrl = GetDlgItem(es->hwndParent, LOWORD(dw));
3728 if (hwDefCtrl)
3729 {
3730 SendMessageW(es->hwndParent, WM_NEXTDLGCTL, (WPARAM)hwDefCtrl, TRUE);
3731 PostMessageW(hwDefCtrl, WM_KEYDOWN, VK_RETURN, 0);
3732 }
3733 }
3734 }
3735 break;
3736 case VK_ESCAPE:
3737 if ((es->style & ES_MULTILINE) && EDIT_IsInsideDialog(es))
3738 PostMessageW(es->hwndParent, WM_CLOSE, 0, 0);
3739 break;
3740 case VK_TAB:
3741 if ((es->style & ES_MULTILINE) && EDIT_IsInsideDialog(es))
3742 SendMessageW(es->hwndParent, WM_NEXTDLGCTL, shift, 0);
3743 break;
3744#ifdef __REACTOS__
3745 /* ReactOS CORE-1419 */
3746 case VK_BACK:
3747 if (control)
3748 {
3749 FIXME("Ctrl+Backspace\n");
3750 }
3751 break;
3752#endif
3753 }
3754 return TRUE;
3755}
3756
3757
3758/*********************************************************************
3759 *
3760 * WM_KILLFOCUS
3761 *
3764{
3765#ifdef __REACTOS__
3766 HWND hCombo;
3767 LONG lStyles;
3768
3769 es->flags &= ~EF_FOCUSED;
3770 DestroyCaret();
3771 if(!(es->style & ES_NOHIDESEL))
3772 EDIT_InvalidateText(es, es->selection_start, es->selection_end);
3773
3774 /* throw away left over scroll when we lose focus */
3775 es->wheelDeltaRemainder = 0;
3776
3777 if (es->hwndListBox == NULL) {
3778 if (!notify_parent(es, EN_KILLFOCUS)) return 0;
3779 } else
3780 { /* send the undocumented WM_CBLOSTTEXTFOCUS message to combobox */
3781 hCombo = GetParent(es->hwndSelf);
3782 lStyles = GetWindowLong(hCombo, GWL_STYLE);
3783 if ((lStyles & CBS_DROPDOWN) || (lStyles & CBS_SIMPLE))
3784 SendMessage(hCombo, WM_CBLOSTTEXTFOCUS, 0, 0);
3785 }
3786#else
3787 es->flags &= ~EF_FOCUSED;
3788 NtUserDestroyCaret();
3789 if(!(es->style & ES_NOHIDESEL))
3790 EDIT_InvalidateText(es, es->selection_start, es->selection_end);
3791 if (!notify_parent(es, EN_KILLFOCUS)) return 0;
3792 /* throw away left over scroll when we lose focus */
3793 es->wheelDeltaRemainder = 0;
3794#endif
3795 return 0;
3796}
3797
3798
3799/*********************************************************************
3800 *
3801 * WM_LBUTTONDBLCLK
3802 *
3803 * The caret position has been set on the WM_LBUTTONDOWN message
3804 *
3807{
3808 INT s;
3809 INT e = es->selection_end;
3810 INT l;
3811 INT li;
3812 INT ll;
3813
3814 es->bCaptureState = TRUE;
3815 NtUserSetCapture(es->hwndSelf);
3816
3824 return 0;
3825}
3826
3827
3828/*********************************************************************
3829 *
3830 * WM_LBUTTONDOWN
3831 *
3834{
3835 INT e;
3836 BOOL after_wrap;
3837
3838 es->bCaptureState = TRUE;
3839 NtUserSetCapture(es->hwndSelf);
3840 EDIT_ConfinePoint(es, &x, &y);
3841 e = EDIT_CharFromPos(es, x, y, &after_wrap);
3842 EDIT_EM_SetSel(es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap);
3844 if (!(es->flags & EF_FOCUSED))
3845 NtUserSetFocus(es->hwndSelf);
3846
3847 return 0;
3848}
3849
3850
3851/*********************************************************************
3852 *
3853 * WM_LBUTTONUP
3854 *
3857{
3858 if (es->bCaptureState) {
3859 if (GetCapture() == es->hwndSelf) NtUserReleaseCapture();
3860 }
3861 es->bCaptureState = FALSE;
3862 return 0;
3863}
3864
3865
3866/*********************************************************************
3867 *
3868 * WM_MBUTTONDOWN
3869 *
3872{
3873 SendMessageW(es->hwndSelf, WM_PASTE, 0, 0);
3874 return 0;
3875}
3876
3877
3878/*********************************************************************
3879 *
3880 * WM_MOUSEMOVE
3881 *
3884{
3885 INT e;
3886 BOOL after_wrap;
3887
3888 /* If the mouse has been captured by process other than the edit control itself,
3889 * the windows edit controls will not select the strings with mouse move.
3890 */
3891 if (!es->bCaptureState || GetCapture() != es->hwndSelf)
3892 return 0;
3893
3894 e = EDIT_CharFromPos(es, x, y, &after_wrap);
3895 EDIT_EM_SetSel(es, es->selection_start, e, after_wrap);
3896 EDIT_SetCaretPos(es,es->selection_end,es->flags & EF_AFTER_WRAP);
3898 return 0;
3899}
3900
3901
3902/*********************************************************************
3903 *
3904 * WM_PAINT
3905 *
3907static void EDIT_WM_Paint(EDITSTATE *es, HDC hdc)
3908{
3909 PAINTSTRUCT ps;
3910 INT i;
3911 HDC dc;
3912 HFONT old_font = 0;
3913 RECT rc;
3914 RECT rcClient;
3915 RECT rcLine;
3916 RECT rcRgn;
3917 HBRUSH brush;
3918 HBRUSH old_brush;
3919 INT bw, bh;
3920 BOOL rev = es->bEnableState &&
3921 ((es->flags & EF_FOCUSED) ||
3922 (es->style & ES_NOHIDESEL));
3923 dc = hdc ? hdc : NtUserBeginPaint( es->hwndSelf, &ps );
3924
3925 /* The dc we use for calculating may not be the one we paint into.
3926 This is the safest action. */
3928 GetClientRect(es->hwndSelf, &rcClient);
3929
3930 /* get the background brush */
3931 brush = EDIT_NotifyCtlColor(es, dc);
3932
3933 /* paint the border and the background */
3934 IntersectClipRect(dc, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
3935
3936 if(es->style & WS_BORDER) {
3939 rc = rcClient;
3940 if(es->style & ES_MULTILINE) {
3941 if(es->style & WS_HSCROLL) rc.bottom+=bh;
3942 if(es->style & WS_VSCROLL) rc.right+=bw;
3943 }
3944
3945 /* Draw the frame. Same code as in nonclient.c */
3947 PatBlt(dc, rc.left, rc.top, rc.right - rc.left, bh, PATCOPY);
3948 PatBlt(dc, rc.left, rc.top, bw, rc.bottom - rc.top, PATCOPY);
3949 PatBlt(dc, rc.left, rc.bottom - 1, rc.right - rc.left, -bw, PATCOPY);
3950 PatBlt(dc, rc.right - 1, rc.top, -bw, rc.bottom - rc.top, PATCOPY);
3951 SelectObject(dc, old_brush);
3952
3953 /* Keep the border clean */
3954 IntersectClipRect(dc, rc.left+bw, rc.top+bh,
3955 max(rc.right-bw, rc.left+bw), max(rc.bottom-bh, rc.top+bh));
3956 }
3957
3958 GetClipBox(dc, &rc);
3959 FillRect(dc, &rc, brush);
3960
3961 IntersectClipRect(dc, es->format_rect.left,
3962 es->format_rect.top,
3963 es->format_rect.right,
3964 es->format_rect.bottom);
3965 if (es->style & ES_MULTILINE) {
3966 rc = rcClient;
3967 IntersectClipRect(dc, rc.left, rc.top, rc.right, rc.bottom);
3968 }
3969 if (es->font)
3970 old_font = SelectObject(dc, es->font);
3971
3972 if (!es->bEnableState)
3974 GetClipBox(dc, &rcRgn);
3975 if (es->style & ES_MULTILINE) {
3977 for (i = es->y_offset ; i <= min(es->y_offset + vlc, es->y_offset + es->line_count - 1) ; i++) {
3979 EDIT_GetLineRect(es, i, 0, -1, &rcLine);
3980 if (IntersectRect(&rc, &rcRgn, &rcLine))
3981 EDIT_PaintLine(es, dc, i, rev);
3982 }
3983 } else {
3985 EDIT_GetLineRect(es, 0, 0, -1, &rcLine);
3986 if (IntersectRect(&rc, &rcRgn, &rcLine))
3987 EDIT_PaintLine(es, dc, 0, rev);
3988 }
3989 if (es->font)
3990 SelectObject(dc, old_font);
3991
3992 if (!hdc)
3993 NtUserEndPaint( es->hwndSelf, &ps );
3994}
3995
3996
3997/*********************************************************************
3998 *
3999 * WM_SETFOCUS
4000 *
4002static void EDIT_WM_SetFocus(EDITSTATE *es)
4003{
4004 es->flags |= EF_FOCUSED;
4005
4006 if (!(es->style & ES_NOHIDESEL))
4007 EDIT_InvalidateText(es, es->selection_start, es->selection_end);
4008
4009 /* single line edit updates itself */
4010 if (IsWindowVisible(es->hwndSelf) && !(es->style & ES_MULTILINE))
4011 {
4012 HDC hdc = NtUserGetDC(es->hwndSelf);
4014 NtUserReleaseDC( es->hwndSelf, hdc );
4015 }
4016
4017#ifdef __REACTOS__
4018 SystemParametersInfo(SPI_GETCARETWIDTH, 0, &es->dwCaretWidth, 0);
4019 CreateCaret(es->hwndSelf, NULL, es->dwCaretWidth, es->line_height);
4020#else
4021 NtUserCreateCaret( es->hwndSelf, 0, 1, es->line_height );
4022#endif
4023 EDIT_SetCaretPos(es, es->selection_end,
4024 es->flags & EF_AFTER_WRAP);
4025 NtUserShowCaret( es->hwndSelf );
4027}
4029static DWORD get_font_margins(HDC hdc, const TEXTMETRICW *tm, BOOL unicode)
4030{
4031 ABC abc[256];
4032 SHORT left, right;
4033 UINT i;
4034
4035 if (!(tm->tmPitchAndFamily & (TMPF_VECTOR | TMPF_TRUETYPE)))
4037
4038 if (unicode) {
4039 if (!is_cjk_charset(hdc) && !is_cjk_font(hdc))
4041 if (!GetCharABCWidthsW(hdc, 0, 255, abc))
4042 return 0;
4043 }
4044 else if (is_cjk_charset(hdc)) {
4045 if (!GetCharABCWidthsA(hdc, 0, 255, abc))
4046 return 0;
4047 }
4048 else
4050
4051 left = right = 0;
4052 for (i = 0; i < ARRAY_SIZE(abc); i++) {
4053 if (-abc[i].abcA > right) right = -abc[i].abcA;
4054 if (-abc[i].abcC > left ) left = -abc[i].abcC;
4055 }
4056 return MAKELONG(left, right);
4057}
4058
4059#ifndef __REACTOS__
4061{
4062 LOGFONTW composition_font;
4063 HIMC himc = ImmGetContext(es->hwndSelf);
4064 GetObjectW(es->font, sizeof(LOGFONTW), &composition_font);
4065 ImmSetCompositionFontW(himc, &composition_font);
4066 ImmReleaseContext(es->hwndSelf, himc);
4067}
4068#endif
4069
4070/*********************************************************************
4071 *
4072 * WM_SETFONT
4073 *
4074 * With Win95 look the margins are set to default font value unless
4075 * the system font (font == 0) is being set, in which case they are left
4076 * unchanged.
4077 *
4079static void EDIT_WM_SetFont(EDITSTATE *es, HFONT font, BOOL redraw)
4080{
4082 HDC dc;
4083 HFONT old_font = 0;
4084 RECT clientRect;
4085 DWORD margins;
4086
4087 es->font = font;
4089 dc = NtUserGetDC(es->hwndSelf);
4090 if (font)
4091 old_font = SelectObject(dc, font);
4093 es->line_height = tm.tmHeight;
4094 es->char_width = tm.tmAveCharWidth;
4095 margins = get_font_margins(dc, &tm, es->is_unicode);
4096 if (font)
4097 SelectObject(dc, old_font);
4098 NtUserReleaseDC( es->hwndSelf, dc );
4099
4100 /* Reset the format rect and the margins */
4101 GetClientRect(es->hwndSelf, &clientRect);
4102 EDIT_SetRectNP(es, &clientRect);
4103 if (margins)
4106
4107 if (es->style & ES_MULTILINE)
4109 else
4111
4112 if (redraw)
4114 if (es->flags & EF_FOCUSED) {
4115 DestroyCaret();
4116#ifdef __REACTOS__
4117 CreateCaret(es->hwndSelf, NULL, es->dwCaretWidth, es->line_height);
4118#else
4119 NtUserCreateCaret( es->hwndSelf, 0, 1, es->line_height );
4120#endif
4121 EDIT_SetCaretPos(es, es->selection_end,
4122 es->flags & EF_AFTER_WRAP);
4123 NtUserShowCaret( es->hwndSelf );
4124 }
4125
4126#ifdef __REACTOS__
4128 {
4129 LOGFONTW lf;
4130 HIMC hIMC = ImmGetContext(es->hwndSelf);
4131 if (font == NULL)
4133 GetObjectW(font, sizeof(lf), &lf);
4134 ImmSetCompositionFontW(hIMC, &lf);
4135 ImmReleaseContext(es->hwndSelf, hIMC);
4136 }
4137#else
4139#endif
4140}
4141
4142
4143/*********************************************************************
4144 *
4145 * WM_SETTEXT
4146 *
4147 * NOTES
4148 * For multiline controls (ES_MULTILINE), reception of WM_SETTEXT triggers:
4149 * The modified flag is reset. No notifications are sent.
4150 *
4151 * For single-line controls, reception of WM_SETTEXT triggers:
4152 * The modified flag is reset. EN_UPDATE and EN_CHANGE notifications are sent.
4153 *
4155static void EDIT_WM_SetText(EDITSTATE *es, LPCWSTR text, BOOL unicode)
4156{
4157 LPWSTR textW = NULL;
4158 if (!unicode && text)
4159 {
4161 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
4162 textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR));
4163 if (textW)
4164 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
4165 text = textW;
4166 }
4167
4168 if (es->flags & EF_UPDATE)
4169 /* fixed this bug once; complain if we see it about to happen again. */
4170 ERR("SetSel may generate UPDATE message whose handler may reset "
4171 "selection.\n");
4172
4173 EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE);
4174 if (text)
4175 {
4176 TRACE("%s\n", debugstr_w(text));
4178 if(!unicode)
4180 }
4181 else
4182 {
4183 TRACE("<NULL>\n");
4185 }
4186 es->x_offset = 0;
4187 es->flags &= ~EF_MODIFIED;
4188 EDIT_EM_SetSel(es, 0, 0, FALSE);
4189
4190 /* Send the notification after the selection start and end have been set
4191 * edit control doesn't send notification on WM_SETTEXT
4192 * if it is multiline, or it is part of combobox
4193 */
4194 if( !((es->style & ES_MULTILINE) || es->hwndListBox))
4195 {
4196 if (!notify_parent(es, EN_UPDATE)) return;
4197 if (!notify_parent(es, EN_CHANGE)) return;
4198 }
4202}
4203
4204
4205/*********************************************************************
4206 *
4207 * WM_SIZE
4208 *
4210static void EDIT_WM_Size(EDITSTATE *es, UINT action)
4211{
4212 if ((action == SIZE_MAXIMIZED) || (action == SIZE_RESTORED)) {
4213 RECT rc;
4214 GetClientRect(es->hwndSelf, &rc);
4215 EDIT_SetRectNP(es, &rc);
4217 }
4218}
4219
4220
4221/*********************************************************************
4222 *
4223 * WM_STYLECHANGED
4224 *
4225 * This message is sent by SetWindowLong on having changed either the Style
4226 * or the extended style.
4227 *
4228 * We ensure that the window's version of the styles and the EDITSTATE's agree.
4229 *
4230 * See also EDIT_WM_NCCreate
4231 *
4232 * It appears that the Windows version of the edit control allows the style
4233 * (as retrieved by GetWindowLong) to be any value and maintains an internal
4234 * style variable which will generally be different. In this function we
4235 * update the internal style based on what changed in the externally visible
4236 * style.
4237 *
4238 * Much of this content as based upon the MSDN, especially:
4239 * Platform SDK Documentation -> User Interface Services ->
4240 * Windows User Interface -> Edit Controls -> Edit Control Reference ->
4241 * Edit Control Styles
4244{
4245 if (GWL_STYLE == which) {
4246 DWORD style_change_mask;
4247 DWORD new_style;
4248 /* Only a subset of changes can be applied after the control
4249 * has been created.
4250 */
4251#ifdef __REACTOS__
4252 style_change_mask = ES_UPPERCASE | ES_LOWERCASE |
4254#else
4255 style_change_mask = ES_UPPERCASE | ES_LOWERCASE |
4256 ES_NUMBER;
4257#endif
4258 if (es->style & ES_MULTILINE)
4259 style_change_mask |= ES_WANTRETURN;
4260
4261 new_style = style->styleNew & style_change_mask;
4262
4263 /* Number overrides lowercase overrides uppercase (at least it
4264 * does in Win95). However I'll bet that ES_NUMBER would be
4265 * invalid under Win 3.1.
4266 */
4267 if (new_style & ES_NUMBER) {
4268 ; /* do not override the ES_NUMBER */
4269 } else if (new_style & ES_LOWERCASE) {
4270 new_style &= ~ES_UPPERCASE;
4271 }
4272
4273 es->style = (es->style & ~style_change_mask) | new_style;
4274 } else if (GWL_EXSTYLE == which) {
4275 ; /* FIXME - what is needed here */
4276 } else {
4277 WARN ("Invalid style change %Id\n",which);
4278 }
4279
4280 return 0;
4281}
4282
4283/*********************************************************************
4284 *
4285 * WM_SYSKEYDOWN
4286 *
4289{
4290 if ((key == VK_BACK) && (key_data & 0x2000)) {
4291 if (EDIT_EM_CanUndo(es))
4293 return 0;
4294 } else if (key == VK_UP || key == VK_DOWN) {
4296 return 0;
4297 }
4298 return DefWindowProcW(es->hwndSelf, WM_SYSKEYDOWN, key, key_data);
4299}
4300
4301/*********************************************************************
4302 *
4303 * WM_HSCROLL
4304 *
4307{
4308 INT dx;
4309 INT fw;
4310
4311 if (!(es->style & ES_MULTILINE))
4312 return 0;
4313
4314 if (!(es->style & ES_AUTOHSCROLL))
4315 return 0;
4316
4317 dx = 0;
4318 fw = es->format_rect.right - es->format_rect.left;
4319 switch (action) {
4320 case SB_LINELEFT:
4321 TRACE("SB_LINELEFT\n");
4322 if (es->x_offset)
4323 dx = -es->char_width;
4324 break;
4325 case SB_LINERIGHT:
4326 TRACE("SB_LINERIGHT\n");
4327 if (es->x_offset < es->text_width)
4328 dx = es->char_width;
4329 break;
4330 case SB_PAGELEFT:
4331 TRACE("SB_PAGELEFT\n");
4332 if (es->x_offset)
4333 dx = -fw / HSCROLL_FRACTION / es->char_width * es->char_width;
4334 break;
4335 case SB_PAGERIGHT:
4336 TRACE("SB_PAGERIGHT\n");
4337 if (es->x_offset < es->text_width)
4338 dx = fw / HSCROLL_FRACTION / es->char_width * es->char_width;
4339 break;
4340 case SB_LEFT:
4341 TRACE("SB_LEFT\n");
4342 if (es->x_offset)
4343 dx = -es->x_offset;
4344 break;
4345 case SB_RIGHT:
4346 TRACE("SB_RIGHT\n");
4347 if (es->x_offset < es->text_width)
4348 dx = es->text_width - es->x_offset;
4349 break;
4350 case SB_THUMBTRACK:
4351 TRACE("SB_THUMBTRACK %d\n", pos);
4352 es->flags |= EF_HSCROLL_TRACK;
4353 if(es->style & WS_HSCROLL)
4354 dx = pos - es->x_offset;
4355 else
4356 {
4357 INT fw, new_x;
4358 /* Sanity check */
4359 if(pos < 0 || pos > 100) return 0;
4360 /* Assume default scroll range 0-100 */
4361 fw = es->format_rect.right - es->format_rect.left;
4362 new_x = pos * (es->text_width - fw) / 100;
4363 dx = es->text_width ? (new_x - es->x_offset) : 0;
4364 }
4365 break;
4366 case SB_THUMBPOSITION:
4367 TRACE("SB_THUMBPOSITION %d\n", pos);
4368 es->flags &= ~EF_HSCROLL_TRACK;
4369 if(GetWindowLongW( es->hwndSelf, GWL_STYLE ) & WS_HSCROLL)
4370 dx = pos - es->x_offset;
4371 else
4372 {
4373 INT fw, new_x;
4374 /* Sanity check */
4375 if(pos < 0 || pos > 100) return 0;
4376 /* Assume default scroll range 0-100 */
4377 fw = es->format_rect.right - es->format_rect.left;
4378 new_x = pos * (es->text_width - fw) / 100;
4379 dx = es->text_width ? (new_x - es->x_offset) : 0;
4380 }
4381 if (!dx) {
4382 /* force scroll info update */
4385 }
4386 break;
4387 case SB_ENDSCROLL:
4388 TRACE("SB_ENDSCROLL\n");
4389 break;
4390 /*
4391 * FIXME : the next two are undocumented !
4392 * Are we doing the right thing ?
4393 * At least Win 3.1 Notepad makes use of EM_GETTHUMB this way,
4394 * although it's also a regular control message.
4395 */
4396 case EM_GETTHUMB: /* this one is used by NT notepad */
4397 {
4398 LRESULT ret;
4399 if(GetWindowLongW( es->hwndSelf, GWL_STYLE ) & WS_HSCROLL)
4400 ret = GetScrollPos(es->hwndSelf, SB_HORZ);
4401 else
4402 {
4403 /* Assume default scroll range 0-100 */
4404 INT fw = es->format_rect.right - es->format_rect.left;
4405 ret = es->text_width ? es->x_offset * 100 / (es->text_width - fw) : 0;
4406 }
4407 TRACE("EM_GETTHUMB: returning %Id\n", ret);
4408 return ret;
4409 }
4410 case EM_LINESCROLL:
4411 TRACE("EM_LINESCROLL16\n");
4412 dx = pos;
4413 break;
4414
4415 default:
4416 ERR("undocumented WM_HSCROLL action %d (0x%04x), please report\n",
4417 action, action);
4418 return 0;
4419 }
4420 if (dx)
4421 {
4422 INT fw = es->format_rect.right - es->format_rect.left;
4423 /* check if we are going to move too far */
4424 if(es->x_offset + dx + fw > es->text_width)
4425 dx = es->text_width - fw - es->x_offset;
4426 if(dx)
4428 }
4429 return 0;
4430}
4431
4432
4433/*********************************************************************
4434 *
4435 * WM_VSCROLL
4436 *
4439{
4440 INT dy;
4441
4442 if (!(es->style & ES_MULTILINE))
4443 return 0;
4444
4445 if (!(es->style & ES_AUTOVSCROLL))
4446 return 0;
4447
4448 dy = 0;
4449 switch (action) {
4450 case SB_LINEUP:
4451 case SB_LINEDOWN:
4452 case SB_PAGEUP:
4453 case SB_PAGEDOWN:
4454 TRACE("action %d (%s)\n", action, (action == SB_LINEUP ? "SB_LINEUP" :
4455 (action == SB_LINEDOWN ? "SB_LINEDOWN" :
4456 (action == SB_PAGEUP ? "SB_PAGEUP" :
4457 "SB_PAGEDOWN"))));
4459 return 0;
4460 case SB_TOP:
4461 TRACE("SB_TOP\n");
4462 dy = -es->y_offset;
4463 break;
4464 case SB_BOTTOM:
4465 TRACE("SB_BOTTOM\n");
4466 dy = es->line_count - 1 - es->y_offset;
4467 break;
4468 case SB_THUMBTRACK:
4469 TRACE("SB_THUMBTRACK %d\n", pos);
4470 es->flags |= EF_VSCROLL_TRACK;
4471 if(es->style & WS_VSCROLL)
4472 dy = pos - es->y_offset;
4473 else
4474 {
4475 /* Assume default scroll range 0-100 */
4476 INT vlc, new_y;
4477 /* Sanity check */
4478 if(pos < 0 || pos > 100) return 0;
4480 new_y = pos * (es->line_count - vlc) / 100;
4481 dy = es->line_count ? (new_y - es->y_offset) : 0;
4482 TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
4483 es->line_count, es->y_offset, pos, dy);
4484 }
4485 break;
4486 case SB_THUMBPOSITION:
4487 TRACE("SB_THUMBPOSITION %d\n", pos);
4488 es->flags &= ~EF_VSCROLL_TRACK;
4489 if(es->style & WS_VSCROLL)
4490 dy = pos - es->y_offset;
4491 else
4492 {
4493 /* Assume default scroll range 0-100 */
4494 INT vlc, new_y;
4495 /* Sanity check */
4496 if(pos < 0 || pos > 100) return 0;
4498 new_y = pos * (es->line_count - vlc) / 100;
4499 dy = es->line_count ? (new_y - es->y_offset) : 0;
4500 TRACE("line_count=%d, y_offset=%d, pos=%d, dy = %d\n",
4501 es->line_count, es->y_offset, pos, dy);
4502 }
4503 if (!dy)
4504 {
4505 /* force scroll info update */
4508 }
4509 break;
4510 case SB_ENDSCROLL:
4511 TRACE("SB_ENDSCROLL\n");
4512 break;
4513 /*
4514 * FIXME : the next two are undocumented !
4515 * Are we doing the right thing ?
4516 * At least Win 3.1 Notepad makes use of EM_GETTHUMB this way,
4517 * although it's also a regular control message.
4518 */
4519 case EM_GETTHUMB: /* this one is used by NT notepad */
4520 {
4521 LRESULT ret;
4522 if(GetWindowLongW( es->hwndSelf, GWL_STYLE ) & WS_VSCROLL)
4523 ret = GetScrollPos(es->hwndSelf, SB_VERT);
4524 else
4525 {
4526 /* Assume default scroll range 0-100 */
4528 ret = es->line_count ? es->y_offset * 100 / (es->line_count - vlc) : 0;
4529 }
4530 TRACE("EM_GETTHUMB: returning %Id\n", ret);
4531 return ret;
4532 }
4533 case EM_LINESCROLL:
4534 TRACE("EM_LINESCROLL %d\n", pos);
4535 dy = pos;
4536 break;
4537
4538 default:
4539 ERR("undocumented WM_VSCROLL action %d (0x%04x), please report\n",
4540 action, action);
4541 return 0;
4542 }
4543 if (dy)
4545 return 0;
4546}
4547
4548/*********************************************************************
4549 *
4550 * EM_GETTHUMB
4551 *
4552 * FIXME: is this right ? (or should it be only VSCROLL)
4553 * (and maybe only for edit controls that really have their
4554 * own scrollbars) (and maybe only for multiline controls ?)
4555 * All in all: very poorly documented
4556 *
4559{
4562}
4563
4564
4565/********************************************************************
4566 *
4567 * The Following code is to handle inline editing from IMEs
4568 */
4570static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es)
4571{
4572 LONG buflen;
4573 LPWSTR lpResultStr;
4574
4575 buflen = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
4576 if (buflen <= 0)
4577 {
4578 return;
4579 }
4580
4581 lpResultStr = HeapAlloc(GetProcessHeap(),0, buflen);
4582 if (!lpResultStr)
4583 {
4584 ERR("Unable to alloc buffer for IME string\n");
4585 return;
4586 }
4587
4588 ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpResultStr, buflen);
4589 EDIT_EM_ReplaceSel(es, TRUE, lpResultStr, buflen / sizeof(WCHAR), TRUE, TRUE);
4590 HeapFree(GetProcessHeap(),0,lpResultStr);
4591}
4593static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es)
4594{
4595 HIMC hIMC;
4596
4597 hIMC = ImmGetContext(hwnd);
4598 if (!hIMC)
4599 return;
4600
4601 if (CompFlag & GCS_RESULTSTR)
4602 EDIT_GetResultStr(hIMC, es);
4603 ImmReleaseContext(hwnd, hIMC);
4604}
4605
4606
4607/*********************************************************************
4608 *
4609 * WM_NCCREATE
4610 *
4611 * See also EDIT_WM_StyleChanged
4614{
4615 EDITSTATE *es;
4616 UINT alloc_size;
4617
4618 TRACE("Creating %s edit control, style = %08lx\n",
4619 unicode ? "Unicode" : "ANSI", lpcs->style);
4620
4621 if (!(es = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*es))))
4622 return FALSE;
4624
4625 /*
4626 * Note: since the EDITSTATE has not been fully initialized yet,
4627 * we can't use any API calls that may send
4628 * WM_XXX messages before WM_NCCREATE is completed.
4629 */
4630
4631 es->is_unicode = unicode;
4632 es->style = lpcs->style;
4633
4634 es->bEnableState = !(es->style & WS_DISABLED);
4635
4636 es->hwndSelf = hwnd;
4637 /* Save parent, which will be notified by EN_* messages */
4638 es->hwndParent = lpcs->hwndParent;
4639
4640 if (es->style & ES_COMBO)
4641 es->hwndListBox = GetDlgItem(es->hwndParent, ID_CB_LISTBOX);
4642
4643 /* FIXME: should we handle changes to WS_EX_RIGHT style after creation? */
4644 if (lpcs->dwExStyle & WS_EX_RIGHT) es->style |= ES_RIGHT;
4645
4646 /* Number overrides lowercase overrides uppercase (at least it
4647 * does in Win95). However I'll bet that ES_NUMBER would be
4648 * invalid under Win 3.1.
4649 */
4650 if (es->style & ES_NUMBER) {
4651 ; /* do not override the ES_NUMBER */
4652 } else if (es->style & ES_LOWERCASE) {
4653 es->style &= ~ES_UPPERCASE;
4654 }
4655 if (es->style & ES_MULTILINE) {
4656 es->buffer_limit = BUFLIMIT_INITIAL;
4657 if (es->style & WS_VSCROLL)
4658 es->style |= ES_AUTOVSCROLL;
4659 if (es->style & WS_HSCROLL)
4660 es->style |= ES_AUTOHSCROLL;
4661 es->style &= ~ES_PASSWORD;
4662 if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) {
4663 /* Confirmed - RIGHT overrides CENTER */
4664 if (es->style & ES_RIGHT)
4665 es->style &= ~ES_CENTER;
4666 es->style &= ~WS_HSCROLL;
4667 es->style &= ~ES_AUTOHSCROLL;
4668 }
4669 } else {
4670 es->buffer_limit = BUFLIMIT_INITIAL;
4671 if ((es->style & ES_RIGHT) && (es->style & ES_CENTER))
4672 es->style &= ~ES_CENTER;
4673 es->style &= ~WS_HSCROLL;
4674 es->style &= ~WS_VSCROLL;
4675 if (es->style & ES_PASSWORD)
4676 es->password_char = '*';
4677 }
4678
4679 alloc_size = ROUND_TO_GROW((es->buffer_size + 1) * sizeof(WCHAR));
4680 if(!(es->hloc32W = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size)))
4681 goto cleanup;
4682 es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
4683
4684 if (!(es->undo_text = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (es->buffer_size + 1) * sizeof(WCHAR))))
4685 goto cleanup;
4686 es->undo_buffer_size = es->buffer_size;
4687
4688 if (es->style & ES_MULTILINE)
4689 if (!(es->first_line_def = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LINEDEF))))
4690 goto cleanup;
4691 es->line_count = 1;
4692
4693 /*
4694 * In Win95 look and feel, the WS_BORDER style is replaced by the
4695 * WS_EX_CLIENTEDGE style for the edit control. This gives the edit
4696 * control a nonclient area so we don't need to draw the border.
4697 * If WS_BORDER without WS_EX_CLIENTEDGE is specified we shouldn't have
4698 * a nonclient area and we should handle painting the border ourselves.
4699 *
4700 * When making modifications please ensure that the code still works
4701 * for edit controls created directly with style 0x50800000, exStyle 0
4702 * (which should have a single pixel border)
4703 */
4704 if (lpcs->dwExStyle & WS_EX_CLIENTEDGE)
4705 es->style &= ~WS_BORDER;
4706 else if (es->style & WS_BORDER)
4708
4709 return TRUE;
4710
4711cleanup:
4712 set_control_state( es->hwndSelf, NULL );
4714 HeapFree(GetProcessHeap(), 0, es->first_line_def);
4715 HeapFree(GetProcessHeap(), 0, es->undo_text);
4716 if (es->hloc32W) LocalFree(es->hloc32W);
4717 HeapFree(GetProcessHeap(), 0, es->logAttr);
4718 HeapFree(GetProcessHeap(), 0, es);
4719 return FALSE;
4720}
4721
4722
4723/*********************************************************************
4724 *
4725 * WM_CREATE
4726 *
4729{
4730 RECT clientRect;
4731
4732 TRACE("%s\n", debugstr_w(name));
4733 /*
4734 * To initialize some final structure members, we call some helper
4735 * functions. However, since the EDITSTATE is not consistent (i.e.
4736 * not fully initialized), we should be very careful which
4737 * functions can be called, and in what order.
4738 */
4741
4742 /* We need to calculate the format rect
4743 (applications may send EM_SETMARGINS before the control gets visible) */
4744 GetClientRect(es->hwndSelf, &clientRect);
4745 EDIT_SetRectNP(es, &clientRect);
4746
4747 if (name && *name) {
4749 /* if we insert text to the editline, the text scrolls out
4750 * of the window, as the caret is placed after the insert
4751 * pos normally; thus we reset es->selection... to 0 and
4752 * update caret
4753 */
4754 es->selection_start = es->selection_end = 0;
4755 /* Adobe Photoshop does NOT like this. and MSDN says that EN_CHANGE
4756 * Messages are only to be sent when the USER does something to
4757 * change the contents. So I am removing this EN_CHANGE
4758 *
4759 * EDIT_NOTIFY_PARENT(es, EN_CHANGE);
4760 */
4762 }
4763 /* force scroll info update */
4765 /* The rule seems to return 1 here for success */
4766 /* Power Builder masked edit controls will crash */
4767 /* if not. */
4768 /* FIXME: is that in all cases so ? */
4769 return 1;
4770}
4771
4772
4773/*********************************************************************
4774 *
4775 * WM_NCDESTROY
4776 *
4779{
4780 LINEDEF *pc, *pp;
4781
4782 /* The app can own the text buffer handle */
4783 if (es->hloc32W && (es->hloc32W != es->hlocapp)) {
4784 LocalFree(es->hloc32W);
4785 }
4786 if (es->hloc32A && (es->hloc32A != es->hlocapp)) {
4787 LocalFree(es->hloc32A);
4788 }
4790 pc = es->first_line_def;
4791 while (pc)
4792 {
4793 pp = pc->next;
4794 HeapFree(GetProcessHeap(), 0, pc);
4795 pc = pp;
4796 }
4797
4798 set_control_state( es->hwndSelf, NULL );
4799 HeapFree(GetProcessHeap(), 0, es->undo_text);
4800 HeapFree(GetProcessHeap(), 0, es);
4801
4802 return 0;
4803}
4804
4807{
4808 if(unicode)
4809 return DefWindowProcW(hwnd, msg, wParam, lParam);
4810 else
4811 return DefWindowProcA(hwnd, msg, wParam, lParam);
4812}
4813
4814/*********************************************************************
4815 *
4816 * EditWndProc_common
4817 *
4818 * The messages are in the order of the actual integer values
4819 * (which can be found in include/windows.h)
4822{
4824 LRESULT result = 0;
4825#ifndef __REACTOS__ /* WM_IME_SETCONTEXT */
4826 POINT pt;
4827#endif
4828
4829 TRACE("hwnd=%p msg=%x (%s) wparam=%Ix lparam=%Ix\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), wParam, lParam);
4830
4832
4833 if (!es && msg != WM_NCCREATE)
4834 return DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
4835
4836 if (es && (msg != WM_NCDESTROY)) EDIT_LockBuffer(es);
4837
4838 switch (msg) {
4839 case EM_GETSEL:
4841 break;
4842
4843 case EM_SETSEL:
4846 result = 1;
4847 break;
4848
4849 case EM_GETRECT:
4850 if (lParam)
4851 CopyRect((LPRECT)lParam, &es->format_rect);
4852 break;
4853
4854 case EM_SETRECT:
4855 if ((es->style & ES_MULTILINE) && lParam) {
4858 }
4859 break;
4860
4861 case EM_SETRECTNP:
4862 if ((es->style & ES_MULTILINE) && lParam)
4864 break;
4865
4866 case EM_SCROLL:
4868 break;
4869
4870 case EM_LINESCROLL:
4872 break;
4873
4874 case EM_SCROLLCARET:
4876 result = 1;
4877 break;
4878
4879 case EM_GETMODIFY:
4880 result = ((es->flags & EF_MODIFIED) != 0);
4881 break;
4882
4883 case EM_SETMODIFY:
4884 if (wParam)
4885 es->flags |= EF_MODIFIED;
4886 else
4887 es->flags &= ~(EF_MODIFIED | EF_UPDATE); /* reset pending updates */
4888 break;
4889
4890 case EM_GETLINECOUNT:
4891 result = (es->style & ES_MULTILINE) ? es->line_count : 1;
4892 break;
4893
4894 case EM_LINEINDEX:
4896 break;
4897
4898 case EM_SETHANDLE:
4900 break;
4901
4902 case EM_GETHANDLE:
4904 break;
4905
4906 case EM_GETTHUMB:
4908 break;
4909
4910 /* these messages missing from specs */
4911 case 0x00bf:
4912 case 0x00c0:
4913 case 0x00c3:
4914 case 0x00ca:
4915 FIXME("undocumented message 0x%x, please report\n", msg);
4917 break;
4918
4919 case EM_LINELENGTH:
4921 break;
4922
4923 case EM_REPLACESEL:
4924 {
4925 LPWSTR textW;
4926
4927 if(unicode)
4928 textW = (LPWSTR)lParam;
4929 else
4930 {
4932 INT countW = MultiByteToWideChar(CP_ACP, 0, textA, -1, NULL, 0);
4933 if (!(textW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)))) break;
4934 MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
4935 }
4936
4938 result = 1;
4939
4940 if(!unicode)
4942 break;
4943 }
4944
4945 case EM_GETLINE:
4947 break;
4948
4949 case EM_SETLIMITTEXT:
4951 break;
4952
4953 case EM_CANUNDO:
4955 break;
4956
4957 case EM_UNDO:
4958 case WM_UNDO:
4960 break;
4961
4962 case EM_FMTLINES:
4964 break;
4965
4966 case EM_LINEFROMCHAR:
4968 break;
4969
4970 case EM_SETTABSTOPS:
4972 break;
4973
4974 case EM_SETPASSWORDCHAR:
4975 {
4976 WCHAR charW = 0;
4977
4978 if(unicode)
4979 charW = (WCHAR)wParam;
4980 else
4981 {
4982 CHAR charA = wParam;
4983 MultiByteToWideChar(CP_ACP, 0, &charA, 1, &charW, 1);
4984 }
4985
4987 break;
4988 }
4989
4990 case EM_EMPTYUNDOBUFFER:
4992 break;
4993
4995 result = (es->style & ES_MULTILINE) ? es->y_offset : es->x_offset;
4996 break;
4997
4998 case EM_SETREADONLY:
4999 {
5000 DWORD old_style = es->style;
5001
5002 if (wParam) {
5005 es->style |= ES_READONLY;
5006 } else {
5009 es->style &= ~ES_READONLY;
5010 }
5011
5012 if (old_style ^ es->style)
5013 NtUserInvalidateRect(es->hwndSelf, NULL, TRUE);
5014
5015 result = 1;
5016 break;
5017 }
5018
5021 result = 1;
5022 break;
5023
5025 result = (LRESULT)es->word_break_proc;
5026 break;
5027
5028 case EM_GETPASSWORDCHAR:
5029 {
5030 if(unicode)
5031 result = es->password_char;
5032 else
5033 {
5034 WCHAR charW = es->password_char;
5035 CHAR charA = 0;
5036 WideCharToMultiByte(CP_ACP, 0, &charW, 1, &charA, 1, NULL, NULL);
5037 result = charA;
5038 }
5039 break;
5040 }
5041
5042 case EM_SETMARGINS:
5044 break;
5045
5046 case EM_GETMARGINS:
5047 result = MAKELONG(es->left_margin, es->right_margin);
5048 break;
5049
5050 case EM_GETLIMITTEXT:
5051 result = es->buffer_limit;
5052 break;
5053
5054 case EM_POSFROMCHAR:
5055 if ((INT)wParam >= get_text_length(es)) result = -1;
5057 break;
5058
5059 case EM_CHARFROMPOS:
5060 result = EDIT_EM_CharFromPos(es, (short)LOWORD(lParam), (short)HIWORD(lParam));
5061 break;
5062
5063 case EM_SETIMESTATUS:
5064 if (wParam == EMSIS_COMPOSITIONSTRING)
5065 es->ime_status = lParam & 0xFFFF;
5066
5067 result = 1;
5068 break;
5069
5070 case EM_GETIMESTATUS:
5071 result = wParam == EMSIS_COMPOSITIONSTRING ? es->ime_status : 1;
5072 break;
5073
5074 /* End of the EM_ messages which were in numerical order; what order
5075 * are these in? vaguely alphabetical?
5076 */
5077
5078 case WM_NCCREATE:
5080 break;
5081
5082 case WM_NCDESTROY:
5084#ifdef __REACTOS__
5086#endif
5087 es = NULL;
5088 break;
5089
5090 case WM_GETDLGCODE:
5092
5093 if (es->style & ES_MULTILINE)
5095
5096 if (lParam)
5097 {
5098 es->flags|=EF_DIALOGMODE;
5099
5100 if (((LPMSG)lParam)->message == WM_KEYDOWN)
5101 {
5102 int vk = (int)((LPMSG)lParam)->wParam;
5103
5104 if (es->hwndListBox)
5105 {
5106 if (vk == VK_RETURN || vk == VK_ESCAPE)
5109 }
5110 }
5111 }
5112 break;
5113
5114 case WM_CHAR:
5115 {
5116 WCHAR charW;
5117
5118 if(unicode)
5119 charW = wParam;
5120 else
5121 {
5122 BYTE low = wParam;
5124 if (es->lead_byte)
5125 {
5126 char ch[2];
5127 ch[0] = es->lead_byte;
5128 ch[1] = low;
5129 MultiByteToWideChar(cp, 0, ch, 2, &charW, 1);
5130 }
5131 else if (IsDBCSLeadByteEx(cp, low))
5132 {
5133 es->lead_byte = low;
5134 result = 1;
5135 break;
5136 }
5137 else
5138 MultiByteToWideChar(cp, 0, (char *)&low, 1, &charW, 1);
5139 es->lead_byte = 0;
5140 }
5141
5142 if (es->hwndListBox)
5143 {
5144 if (charW == VK_RETURN || charW == VK_ESCAPE)
5145 {
5148 break;
5149 }
5150 }
5151 result = EDIT_WM_Char(es, charW);
5152 break;
5153 }
5154
5155 case WM_UNICHAR:
5156 if (unicode)
5157 {
5158 if (wParam == UNICODE_NOCHAR) return TRUE;
5159 if (wParam <= 0x000fffff)
5160 {
5161 if(wParam > 0xffff) /* convert to surrogates */
5162 {
5163 wParam -= 0x10000;
5164 EDIT_WM_Char(es, (wParam >> 10) + 0xd800);
5165 EDIT_WM_Char(es, (wParam & 0x03ff) + 0xdc00);
5166 }
5167 else EDIT_WM_Char(es, wParam);
5168 }
5169 return 0;
5170 }
5171 break;
5172
5173 case WM_CLEAR:
5175 break;
5176
5177 case WM_CONTEXTMENU:
5178 EDIT_WM_ContextMenu(es, (short)LOWORD(lParam), (short)HIWORD(lParam));
5179 break;
5180
5181 case WM_COPY:
5183 break;
5184
5185 case WM_CREATE:
5186 if(unicode)
5188 else
5189 {
5190 LPCSTR nameA = ((LPCREATESTRUCTA)lParam)->lpszName;
5191 LPWSTR nameW = NULL;
5192 if(nameA)
5193 {
5194 INT countW = MultiByteToWideChar(CP_ACP, 0, nameA, -1, NULL, 0);
5195 if((nameW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR))))
5196 MultiByteToWideChar(CP_ACP, 0, nameA, -1, nameW, countW);
5197 }
5200 }
5201 break;
5202
5203 case WM_CUT:
5204 EDIT_WM_Cut(es);
5205 break;
5206
5207 case WM_ENABLE:
5208 es->bEnableState = (BOOL) wParam;
5210 break;
5211
5212 case WM_ERASEBKGND:
5213 /* we do the proper erase in EDIT_WM_Paint */
5214 result = 1;
5215 break;
5216
5217 case WM_GETFONT:
5218 result = (LRESULT)es->font;
5219 break;
5220
5221 case WM_GETTEXT:
5223 break;
5224
5225 case WM_GETTEXTLENGTH:
5226 if (unicode) result = get_text_length(es);
5228 NULL, 0, NULL, NULL );
5229 break;
5230
5231 case WM_HSCROLL:
5233 break;
5234
5235 case WM_KEYDOWN:
5237 break;
5238
5239 case WM_KILLFOCUS:
5241 break;
5242
5243 case WM_LBUTTONDBLCLK:
5245 break;
5246
5247 case WM_LBUTTONDOWN:
5249 break;
5250
5251 case WM_LBUTTONUP:
5253 break;
5254
5255 case WM_MBUTTONDOWN:
5257 break;
5258
5259 case WM_MOUSEMOVE:
5260 result = EDIT_WM_MouseMove(es, (short)LOWORD(lParam), (short)HIWORD(lParam));
5261 break;
5262
5263 case WM_PRINTCLIENT:
5264 case WM_PAINT:
5266 break;
5267
5268 case WM_PASTE:
5270 break;
5271
5272 case WM_SETFOCUS:
5274 break;
5275
5276 case WM_SETFONT:
5277 EDIT_WM_SetFont(es, (HFONT)wParam, LOWORD(lParam) != 0);
5278 break;
5279
5280 case WM_SETREDRAW:
5281 /* FIXME: actually set an internal flag and behave accordingly */
5282 break;
5283
5284 case WM_SETTEXT:
5285 EDIT_WM_SetText(es, (LPCWSTR)lParam, unicode);
5286 result = TRUE;
5287 break;
5288
5289 case WM_SIZE:
5291 break;
5292
5293 case WM_STYLECHANGED:
5295 break;
5296
5297 case WM_STYLECHANGING:
5298 result = 0; /* See EDIT_WM_StyleChanged */
5299 break;
5300
5301 case WM_SYSKEYDOWN:
5303 break;
5304
5305 case WM_VSCROLL:
5306#ifdef __REACTOS__
5307 {
5308 SCROLLINFO si;
5309
5310 si.cbSize = sizeof(si);
5311 si.fMask = SIF_TRACKPOS;
5312 if (!GetScrollInfo(hwnd, SB_VERT, &si))
5313 {
5314 result = 1;
5315 break;
5316 }
5317 result = EDIT_WM_VScroll(es, LOWORD(wParam), si.nTrackPos);
5318 }
5319#else
5321 break;
5322#endif
5323
5324 case WM_CAPTURECHANGED:
5325 es->bCaptureState = FALSE;
5326 break;
5327
5328 case WM_MOUSEWHEEL:
5329 {
5330 int wheelDelta;
5331 INT pulScrollLines = 3;
5332 SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
5333
5334 if (wParam & (MK_SHIFT | MK_CONTROL)) {
5336 break;
5337 }
5338 wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
5339 /* if scrolling changes direction, ignore left overs */
5340 if ((wheelDelta < 0 && es->wheelDeltaRemainder < 0) ||
5341 (wheelDelta > 0 && es->wheelDeltaRemainder > 0))
5342 es->wheelDeltaRemainder += wheelDelta;
5343 else
5344 es->wheelDeltaRemainder = wheelDelta;
5345 if (es->wheelDeltaRemainder && pulScrollLines)
5346 {
5347 int cLineScroll;
5348 pulScrollLines = min(es->line_count, pulScrollLines);
5349 cLineScroll = pulScrollLines * es->wheelDeltaRemainder / WHEEL_DELTA;
5350 es->wheelDeltaRemainder -= WHEEL_DELTA * cLineScroll / pulScrollLines;
5351 result = EDIT_EM_LineScroll(es, 0, -cLineScroll);
5352 }
5353 }
5354 break;
5355
5356
5357 /* IME messages to make the edit control IME aware */
5358 case WM_IME_SETCONTEXT:
5359#ifdef __REACTOS__
5360 {
5361 HKL hKL = GetKeyboardLayout(0);
5362
5363 /* Korean doesn't want composition window */
5364 if (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN)
5365 lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
5366
5367 if (wParam)
5368 {
5369 HIMC hIMC = ImmGetContext(hwnd);
5371 if (pIC)
5372 {
5373 pIC->dwUIFlags &= ~0x40000;
5374 ImmUnlockIMC(hIMC);
5375 }
5376 if (GetWin32ClientInfo()->CI_flags & CI_WOW)
5378 ImmReleaseContext(hwnd, hIMC);
5379 }
5380
5382 }
5383#else
5387#endif
5388 break;
5389
5390#ifdef __REACTOS__
5391 case WM_IME_STARTCOMPOSITION:
5392 {
5393 HKL hKL = GetKeyboardLayout(0);
5394
5395 /* Korean doesn't want composition window */
5396 if (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN)
5397 return TRUE;
5398
5399 result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
5400 }
5401 break;
5402#endif
5403
5404 case WM_IME_COMPOSITION:
5406 if ((lParam & GCS_RESULTSTR) && (es->ime_status & EIMES_GETCOMPSTRATONCE))
5408 return DefWindowProcW(hwnd, msg, wParam, lParam);
5409
5410 case WM_IME_SELECT:
5411#ifdef __REACTOS__
5412 result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
5413#endif
5414 break;
5415
5416 case WM_IME_CONTROL:
5417#ifdef __REACTOS__
5418 result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
5419#endif
5420 break;
5421
5422 case WM_IME_REQUEST:
5423 switch (wParam)
5424 {
5425 case IMR_QUERYCHARPOSITION:
5426 {
5427 LRESULT pos;
5428 IMECHARPOSITION *chpos = (IMECHARPOSITION *)lParam;
5429
5430 pos = EDIT_EM_PosFromChar(es, es->selection_start + chpos->dwCharPos, FALSE);
5431 chpos->pt.x = LOWORD(pos);
5432 chpos->pt.y = HIWORD(pos);
5433 chpos->cLineHeight = es->line_height;
5434 chpos->rcDocument = es->format_rect;
5435 MapWindowPoints(hwnd, 0, &chpos->pt, 1);
5436 MapWindowPoints(hwnd, 0, (POINT*)&chpos->rcDocument, 2);
5437 result = 1;
5438 break;
5439 }
5440 }
5441 break;
5442
5443 default:
5444 result = DefWindowProcT(hwnd, msg, wParam, lParam, unicode);
5445 break;
5446 }
5447
5448#ifdef __REACTOS__
5449 /* ReactOS: check GetWindowLong in case es has been destroyed during processing */
5450 if (IsWindow(hwnd) && es && msg != EM_GETHANDLE && GetWindowLongPtrW(hwnd, 0))
5451#else
5452 if (IsWindow(hwnd) && es && msg != EM_GETHANDLE)
5453#endif
5455
5456 TRACE("hwnd=%p msg=%x (%s) -- 0x%08Ix\n", hwnd, msg, SPY_GetMsgName(msg, hwnd), result);
5457
5458 return result;
5459}
5460
5461#ifdef __REACTOS__
5462
5463/*********************************************************************
5464 *
5465 * EditWndProc (USER32.@)
5466 */
5468{
5469 return EditWndProc_common(hWnd, uMsg, wParam, lParam, FALSE);
5470}
5471
5472/*********************************************************************
5473 *
5474 * EditWndProcW (USER32.@)
5475 */
5477{
5478 return EditWndProc_common(hWnd, uMsg, wParam, lParam, TRUE);
5479}
5480
5481/*********************************************************************
5482 * edit class descriptor
5483 */
5484static const WCHAR editW[] = {'E','d','i','t',0};
5486{
5487 editW, /* name */
5488 CS_DBLCLKS | CS_PARENTDC, /* style */
5489 &pfnClientA.pfnEditWndProc, /* procA */
5490 &pfnClientW.pfnEditWndProc, /* procW */
5491#ifndef _WIN64
5492 sizeof(EDITSTATE *) + sizeof(WORD), /* extra */
5493#else
5494 sizeof(EDITSTATE *), /* extra */
5495#endif
5496 IDC_IBEAM, /* cursor */
5497 0 /* brush */
5498};
5499#endif
static HRGN hrgn
static HBRUSH hbrush
short INT16
Definition: actypes.h:130
static int bw
Definition: maze.c:120
static int state
Definition: maze.c:121
const DWORD ExStyle
Definition: appswitch.c:73
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
int rev
Definition: sort.c:17
static const WCHAR nameW[]
Definition: main.c:49
#define CF_UNICODETEXT
Definition: constants.h:408
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
static RECT margins
Definition: print.c:55
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
w ll
Definition: byte_order.h:167
r l[0]
Definition: byte_order.h:168
return
Definition: dirsup.c:529
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static HWND hwndParent
Definition: cryptui.c:299
HDC dc
Definition: cylfrac.c:34
static float(WINAPI *pD2D1Tan)(float angle)
HRESULT hr
Definition: delayimp.cpp:582
DWORD HIMC
Definition: dimm.idl:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void EDIT_WM_Paint(EDITSTATE *es, HDC hdc)
Definition: edit.c:3628
static void EDIT_MoveEnd(EDITSTATE *es, BOOL extend, BOOL ctrl)
Definition: edit.c:1896
static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev)
Definition: edit.c:2179
static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es)
Definition: edit.c:4451
static BOOL EDIT_IsInsideDialog(EDITSTATE *es)
Definition: edit.c:2982
#define EF_MODIFIED
Definition: edit.c:65
static INT get_vertical_line_count(EDITSTATE *es)
Definition: edit.c:414
static INT EDIT_WordBreakProc(EDITSTATE *es, LPWSTR s, INT index, INT count, INT action)
Definition: edit.c:236
static LRESULT EDIT_WM_LButtonDblClk(EDITSTATE *es)
Definition: edit.c:3513
static void EDIT_MoveBackward(EDITSTATE *es, BOOL extend)
Definition: edit.c:1847
static LRESULT EDIT_WM_Char(EDITSTATE *es, WCHAR c)
Definition: edit.c:3085
BOOL WINAPI GetCharWidthInfo(HDC, struct char_width_info *)
static void EDIT_WM_SetFont(EDITSTATE *es, HFONT font, BOOL redraw)
Definition: edit.c:3837
static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData(EDITSTATE *es, HDC dc, INT line)
Definition: edit.c:372
static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_replace, UINT strl, BOOL send_update, BOOL honor_limit)
Definition: edit.c:2490
#define EF_AFTER_WRAP
Definition: edit.c:70
static void EDIT_CalcLineWidth_SL(EDITSTATE *es)
Definition: edit.c:761
static LRESULT EDIT_WM_MButtonDown(EDITSTATE *es)
Definition: edit.c:3584
static void EDIT_EM_ScrollCaret(EDITSTATE *es)
Definition: edit.c:1778
#define ID_CB_LISTBOX
Definition: edit.c:74
static void EDIT_InvalidateUniscribeData_linedef(LINEDEF *line_def)
Definition: edit.c:306
#define ROUND_TO_GROW(size)
Definition: edit.c:59
static BOOL EDIT_CheckCombo(EDITSTATE *es, UINT msg, INT key)
Definition: edit.c:3286
static void EDIT_SetRectNP(EDITSTATE *es, const RECT *rc)
Definition: edit.c:2317
static BOOL EDIT_EM_FmtLines(EDITSTATE *es, BOOL add_eol)
Definition: edit.c:2389
static void EDIT_WM_Copy(EDITSTATE *es)
Definition: edit.c:3029
static void EDIT_ML_InvalidateText(EDITSTATE *es, INT start, INT end)
Definition: edit.c:1394
static void EDIT_GetLineRect(EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc)
Definition: edit.c:1147
static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy)
Definition: edit.c:1601
static void EDIT_SetCaretPos(EDITSTATE *es, INT pos, BOOL after_wrap)
Definition: edit.c:1750
static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta, HRGN hrgn)
Definition: edit.c:429
static void EDIT_MoveUp_ML(EDITSTATE *es, BOOL extend)
Definition: edit.c:2022
static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col, INT count, BOOL rev)
Definition: edit.c:2105
static LRESULT EDIT_EM_CharFromPos(EDITSTATE *es, INT x, INT y)
Definition: edit.c:2361
static void EDIT_MoveHome(EDITSTATE *es, BOOL extend, BOOL ctrl)
Definition: edit.c:1942
static LRESULT EDIT_WM_HScroll(EDITSTATE *es, INT action, INT pos)
Definition: edit.c:4067
static void EDIT_WM_Cut(EDITSTATE *es)
Definition: edit.c:3073
static void EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c)
Definition: edit.c:2871
static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_linedef(EDITSTATE *es, HDC dc, LINEDEF *line_def)
Definition: edit.c:330
#define EF_FOCUSED
Definition: edit.c:66
struct tagLINEDEF LINEDEF
static void EDIT_AdjustFormatRect(EDITSTATE *es)
Definition: edit.c:2266
static INT EDIT_WM_GetText(const EDITSTATE *es, INT count, LPWSTR dst)
Definition: edit.c:3272
static void EDIT_WM_ContextMenu(EDITSTATE *es, INT x, INT y)
Definition: edit.c:3216
static LRESULT EDIT_WM_MouseMove(EDITSTATE *es, INT x, INT y)
Definition: edit.c:3596
static void EDIT_MovePageUp_ML(EDITSTATE *es, BOOL extend)
Definition: edit.c:1994
static void EDIT_LockBuffer(EDITSTATE *es)
Definition: edit.c:1211
static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force)
Definition: edit.c:1230
static LRESULT EDIT_WM_NCDestroy(EDITSTATE *es)
Definition: edit.c:4700
static LRESULT EDIT_WM_LButtonDown(EDITSTATE *es, DWORD keys, INT x, INT y)
Definition: edit.c:3542
static BOOL notify_parent(const EDITSTATE *es, INT code)
Definition: edit.c:166
static INT EDIT_EM_LineIndex(const EDITSTATE *es, INT line)
Definition: edit.c:942
static void EDIT_ConfinePoint(const EDITSTATE *es, LPINT x, LPINT y)
Definition: edit.c:901
static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es)
Definition: edit.c:2411
static INT EDIT_EM_GetLine(EDITSTATE *es, INT line, LPWSTR dst)
Definition: edit.c:2431
#define EF_UPDATE
Definition: edit.c:67
static BOOL EDIT_EM_Undo(EDITSTATE *es)
Definition: edit.c:2941
static UINT get_text_length(EDITSTATE *es)
Definition: edit.c:216
static void EDIT_InvalidateUniscribeData(EDITSTATE *es)
Definition: edit.c:315
static void EDIT_WM_Paste(EDITSTATE *es)
Definition: edit.c:2993
#define EF_HSCROLL_TRACK
Definition: edit.c:69
static void EDIT_UpdateScrollInfo(EDITSTATE *es)
Definition: edit.c:1560
static void EDIT_MovePageDown_ML(EDITSTATE *es, BOOL extend)
Definition: edit.c:1966
static LRESULT EDIT_WM_KillFocus(HTHEME theme, EDITSTATE *es)
Definition: edit.c:3485
static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend)
Definition: edit.c:2075
static int get_cjk_fontinfo_margin(int width, int side_bearing)
Definition: edit.c:2770
static LRESULT EDIT_WM_SysKeyDown(EDITSTATE *es, INT key, DWORD key_data)
Definition: edit.c:4030
static LRESULT EDIT_EM_GetThumb(EDITSTATE *es)
Definition: edit.c:4319
static LRESULT EDIT_WM_NCCreate(HWND hwnd, LPCREATESTRUCTW lpcs)
Definition: edit.c:4532
static LRESULT EDIT_WM_LButtonUp(EDITSTATE *es)
Definition: edit.c:3568
static void EDIT_WM_Clear(EDITSTATE *es)
Definition: edit.c:3058
static BOOL EDIT_EM_CanUndo(const EDITSTATE *es)
Definition: edit.c:181
static void EDIT_EM_EmptyUndoBuffer(EDITSTATE *es)
Definition: edit.c:192
static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap)
Definition: edit.c:784
static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, WORD left, WORD right, BOOL repaint)
Definition: edit.c:2799
static void EDIT_MoveWordBackward(EDITSTATE *es, BOOL extend)
Definition: edit.c:2044
static void text_buffer_changed(EDITSTATE *es)
Definition: edit.c:1198
#define EF_USE_SOFTBRK
Definition: edit.c:71
static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc)
Definition: edit.c:198
static void EDIT_WM_SetFocus(HTHEME theme, EDITSTATE *es)
Definition: edit.c:3779
#define HSCROLL_FRACTION
Definition: edit.c:60
static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc)
Definition: edit.c:2707
static LRESULT EDIT_WM_Create(EDITSTATE *es, const WCHAR *name)
Definition: edit.c:4645
static void EDIT_InvalidateText(EDITSTATE *es, INT start, INT end)
Definition: edit.c:1459
static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key)
Definition: edit.c:3348
static void EDIT_EM_SetLimitText(EDITSTATE *es, UINT limit)
Definition: edit.c:2749
static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap)
Definition: edit.c:1013
#define BUFLIMIT_INITIAL
Definition: edit.c:57
static void EDIT_MoveForward(EDITSTATE *es, BOOL extend)
Definition: edit.c:1917
#define EF_DIALOGMODE
Definition: edit.c:72
static LRESULT EDIT_EM_Scroll(EDITSTATE *es, INT action)
Definition: edit.c:1672
static LRESULT EDIT_EM_GetSel(const EDITSTATE *es, PUINT start, PUINT end)
Definition: edit.c:2469
static void EDIT_EM_SetWordBreakProc(EDITSTATE *es, EDITWORDBREAKPROCW wbp)
Definition: edit.c:2922
static void EDIT_SL_InvalidateText(EDITSTATE *es, INT start, INT end)
Definition: edit.c:1376
LINE_END
Definition: edit.c:77
@ END_SOFT
Definition: edit.c:81
@ END_RICH
Definition: edit.c:82
@ END_HARD
Definition: edit.c:80
@ END_0
Definition: edit.c:78
@ END_WRAP
Definition: edit.c:79
static void EDIT_MoveDown_ML(EDITSTATE *es, BOOL extend)
Definition: edit.c:1874
#define EF_VSCROLL_TRACK
Definition: edit.c:68
static LRESULT EDIT_WM_StyleChanged(EDITSTATE *es, WPARAM which, const STYLESTRUCT *style)
Definition: edit.c:3985
static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count, INT action)
Definition: edit.c:294
static INT EDIT_EM_LineFromChar(EDITSTATE *es, INT index)
Definition: edit.c:913
static void EDIT_ContextMenuCommand(EDITSTATE *es, UINT id)
Definition: edit.c:3172
#define ORDER_UINT(x, y)
Definition: edit.c:164
static LRESULT EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos)
Definition: edit.c:4199
static BOOL EDIT_MakeFit(EDITSTATE *es, UINT size)
Definition: edit.c:1276
static void EDIT_WM_SetText(EDITSTATE *es, LPCWSTR text)
Definition: edit.c:3910
static BOOL EDIT_MakeUndoFit(EDITSTATE *es, UINT size)
Definition: edit.c:1317
static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase)
Definition: edit.c:1344
static void EDIT_UpdateText(EDITSTATE *es, const RECT *rc, BOOL bErase)
Definition: edit.c:1359
static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, const INT *tabs)
Definition: edit.c:2900
static DWORD get_font_margins(HDC hdc, const TEXTMETRICW *tm)
Definition: edit.c:3805
static BOOL EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap)
Definition: edit.c:1489
static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es)
Definition: edit.c:4486
static BOOL EDIT_EM_LineScroll(EDITSTATE *es, INT dx, INT dy)
Definition: edit.c:1657
static void EDIT_WM_Size(EDITSTATE *es, UINT action)
Definition: edit.c:3952
static INT EDIT_EM_LineLength(EDITSTATE *es, INT index)
Definition: edit.c:977
static const WCHAR indent[]
Definition: object.c:1231
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define TRACE_(x)
Definition: compat.h:76
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WINE_DECLARE_DEBUG_CHANNEL(x)
Definition: compat.h:45
#define lstrcpyW
Definition: compat.h:749
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
static void cleanup(void)
Definition: main.c:1335
DWORD WINAPI GetProcessVersion(IN DWORD ProcessId)
Definition: proc.c:1661
BOOL WINAPI GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
Definition: version.c:37
BOOL WINAPI IsDBCSLeadByteEx(UINT codepage, BYTE testchar)
Definition: locale.c:2106
const UINT * keys
Definition: locale.c:418
DWORD WINAPI CharLowerBuffW(WCHAR *str, DWORD len)
Definition: string.c:1130
DWORD WINAPI CharUpperBuffW(WCHAR *str, DWORD len)
Definition: string.c:1243
BOOL force
Definition: metahost.c:100
const WCHAR * text
Definition: package.c:1826
unsigned char ch[4][2]
Definition: console.c:118
unsigned short vk
Definition: console.c:118
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa)
Definition: usp10.c:2561
HRESULT WINAPI ScriptStringGetLogicalWidths(SCRIPT_STRING_ANALYSIS ssa, int *piDx)
Definition: usp10.c:3815
HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, int cGlyphs, int iCharset, DWORD dwFlags, int iReqWidth, SCRIPT_CONTROL *psControl, SCRIPT_STATE *psState, const int *piDx, SCRIPT_TABDEF *pTabdef, const BYTE *pbInClass, SCRIPT_STRING_ANALYSIS *pssa)
Definition: usp10.c:1953
HRESULT WINAPI ScriptStringOut(SCRIPT_STRING_ANALYSIS ssa, int iX, int iY, UINT uOptions, const RECT *prc, int iMinSel, int iMaxSel, BOOL fDisabled)
Definition: usp10.c:2371
const SIZE *WINAPI ScriptString_pSize(SCRIPT_STRING_ANALYSIS ssa)
Definition: usp10.c:3887
const int *WINAPI ScriptString_pcOutChars(SCRIPT_STRING_ANALYSIS ssa)
Definition: usp10.c:3949
HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int *piCh, int *piTrailing)
Definition: usp10.c:2479
HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int *pX)
Definition: usp10.c:2416
HRESULT WINAPI ScriptBreak(const WCHAR *chars, int count, const SCRIPT_ANALYSIS *sa, SCRIPT_LOGATTR *la)
Definition: usp10.c:3051
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define pt(x, y)
Definition: drawing.c:79
return ret
Definition: mutex.c:147
action
Definition: namespace.c:714
#define L(x)
Definition: resources.c:13
struct FONTSIGNATURE FONTSIGNATURE
Definition: dwrite_3.idl:31
#define abs(i)
Definition: fconv.c:206
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
int form
Definition: main.c:89
pKey DeleteObject()
LARGE_INTEGER li
Definition: fxtimerapi.cpp:235
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glext.h:7750
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLbitfield flags
Definition: glext.h:7161
GLdouble GLdouble right
Definition: glext.h:10859
GLint limit
Definition: glext.h:10326
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint left
Definition: glext.h:7726
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
unsigned int UINT
Definition: sysinfo.c:13
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1625
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
LPVOID NTAPI LocalLock(HLOCAL hMem)
Definition: heapmem.c:1616
BOOL NTAPI LocalUnlock(HLOCAL hMem)
Definition: heapmem.c:1805
SIZE_T NTAPI LocalSize(HLOCAL hMem)
Definition: heapmem.c:1794
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
#define fs
Definition: i386-dis.c:444
#define es
Definition: i386-dis.c:440
BOOL WINAPI ImmSetCompositionFontW(_In_ HIMC hIMC, _In_ LPLOGFONTW lplf)
Definition: ime.c:1323
struct INPUTCONTEXTDX * LPINPUTCONTEXTDX
#define CFS_RECT
Definition: imm.h:324
#define CPS_CANCEL
Definition: imm.h:181
BOOL WINAPI ImmSetCompositionWindow(_In_ HIMC hIMC, _In_ LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1150
#define GCS_RESULTSTR
Definition: imm.h:234
HIMC WINAPI ImmGetContext(_In_ HWND hWnd)
Definition: imm.c:1066
#define CFS_POINT
Definition: imm.h:325
BOOL WINAPI ImmReleaseContext(_In_ HWND hWnd, _In_ HIMC hIMC)
Definition: imm.c:1110
LONG WINAPI ImmGetCompositionStringW(_In_ HIMC hIMC, _In_ DWORD dwIndex, _Out_writes_bytes_opt_(dwBufLen) LPVOID lpBuf, _In_ DWORD dwBufLen)
Definition: compstr.c:949
BOOL WINAPI ImmIsIME(_In_ HKL hKL)
Definition: ime.c:430
BOOL WINAPI ImmNotifyIME(_In_ HIMC hIMC, _In_ DWORD dwAction, _In_ DWORD dwIndex, _In_ DWORD_PTR dwValue)
Definition: ime.c:459
LPINPUTCONTEXT WINAPI ImmLockIMC(_In_ HIMC hIMC)
Definition: imm.c:1080
#define NI_COMPOSITIONSTR
Definition: immdev.h:363
BOOL WINAPI ImmUnlockIMC(_In_ HIMC hIMC)
Definition: imm.c:1090
DWORD NTAPI NtUserScrollWindowEx(HWND hWnd, INT dx, INT dy, const RECT *rect, const RECT *clipRect, HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags)
Definition: scrollex.c:571
#define FNID_DESTROY
Definition: ntuser.h:905
BOOL NTAPI NtUserShowCaret(HWND hWnd)
Definition: caret.c:422
HWND NTAPI NtUserSetFocus(HWND hWnd)
Definition: focus.c:1717
DWORD NTAPI NtUserSetScrollInfo(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL bRedraw)
Definition: scrollbar.c:1344
BOOL NTAPI NtUserInvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase)
Definition: painting.c:2541
BOOL NTAPI NtUserGetCaretPos(LPPOINT lpPoint)
Definition: caret.c:394
BOOL NTAPI NtUserCloseClipboard(VOID)
Definition: clipboard.c:589
BOOL NTAPI NtUserInvalidateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
Definition: painting.c:2557
BOOL NTAPI NtUserCreateCaret(HWND hWnd, HBITMAP hBitmap, int nWidth, int nHeight)
Definition: caret.c:307
BOOL NTAPI NtUserEmptyClipboard(VOID)
Definition: clipboard.c:722
UINT NTAPI NtUserEnableMenuItem(HMENU hMenu, UINT uIDEnableItem, UINT uEnable)
Definition: menu.c:5872
BOOL NTAPI NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT *lPs)
Definition: painting.c:1660
HDC NTAPI NtUserBeginPaint(HWND hWnd, PAINTSTRUCT *lPs)
Definition: painting.c:1614
HWND NTAPI NtUserSetCapture(HWND Wnd)
Definition: focus.c:1699
BOOL NTAPI NtUserDestroyMenu(HMENU hMenu)
Definition: menu.c:5842
SHORT NTAPI NtUserGetKeyState(INT VirtKey)
Definition: msgqueue.c:2573
#define GetWin32ClientInfo()
Definition: ntuser.h:356
#define CI_WOW
Definition: ntuser.h:306
BOOL NTAPI NtUserIsClipboardFormatAvailable(UINT format)
Definition: clipboard.c:872
BOOL NTAPI NtUserSetWindowFNID(HWND hWnd, WORD fnID)
Definition: window.c:4335
HDC NTAPI NtUserGetDC(HWND hWnd)
Definition: windc.c:1014
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define FAILED(hr)
Definition: intsafe.h:51
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define c
Definition: ke_i.h:80
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
GLint dy
Definition: linetemp.h:97
if(dx< 0)
Definition: linetemp.h:194
GLint dx
Definition: linetemp.h:97
POINT cp
Definition: magnifier.c:59
#define LMEM_MOVEABLE
Definition: minwinbase.h:82
#define LMEM_ZEROINIT
Definition: minwinbase.h:85
LONG_PTR LPARAM
Definition: minwindef.h:175
BOOL * LPBOOL
Definition: minwindef.h:138
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
int * LPINT
Definition: minwindef.h:151
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
HDC hdc
Definition: main.c:9
static const char textA[]
Definition: registrar.c:40
#define ES_COMBO
Definition: edit.c:29
static HDC
Definition: imagelist.c:88
static const WCHAR textW[]
Definition: itemdlg.c:1621
static SYSTEM_INFO si
Definition: virtual.c:39
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
static BOOL is_cjk_charset(HDC dc)
Definition: edit.c:1498
static BOOL is_cjk_font(HDC dc)
Definition: edit.c:1612
#define menu
Definition: input.c:3282
#define shift
Definition: input.c:3280
#define ctrl
Definition: input.c:3281
static DWORD get_input_codepage(void)
Definition: msg.c:16553
#define min(a, b)
Definition: monoChain.cc:55
UINT_PTR HKL
Definition: msctf.idl:125
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
Definition: mk_font.cpp:20
unsigned int * PUINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define LRESULT
Definition: ole.h:14
#define LOWORD(l)
Definition: pedump.c:82
#define ES_PASSWORD
Definition: pedump.c:670
#define ES_READONLY
Definition: pedump.c:675
#define ES_LOWERCASE
Definition: pedump.c:669
#define ES_AUTOVSCROLL
Definition: pedump.c:671
#define ES_WANTRETURN
Definition: pedump.c:676
#define ES_UPPERCASE
Definition: pedump.c:668
short WCHAR
Definition: pedump.c:58
#define WS_BORDER
Definition: pedump.c:625
#define ES_NOHIDESEL
Definition: pedump.c:673
#define WS_VSCROLL
Definition: pedump.c:627
#define ES_AUTOHSCROLL
Definition: pedump.c:672
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define WS_DISABLED
Definition: pedump.c:621
#define ES_LEFT
Definition: pedump.c:664
#define WS_HSCROLL
Definition: pedump.c:628
#define ES_CENTER
Definition: pedump.c:665
#define ES_RIGHT
Definition: pedump.c:666
char CHAR
Definition: pedump.c:57
#define ES_MULTILINE
Definition: pedump.c:667
#define INT
Definition: polytest.cpp:20
#define WM_PAINT
Definition: winuser.h:1648
#define EM_SETREADONLY
Definition: winuser.h:2044
#define WM_ERASEBKGND
Definition: winuser.h:1653
DWORD WINAPI GetSysColor(_In_ int)
#define MAKEWPARAM(l, h)
Definition: winuser.h:4117
BOOL WINAPI CopyRect(_Out_ LPRECT, _In_ LPCRECT)
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define EM_GETIMESTATUS
Definition: winuser.h:2016
#define WM_CTLCOLORSTATIC
Definition: winuser.h:1800
#define MK_SHIFT
Definition: winuser.h:2405
#define WM_GETTEXTLENGTH
Definition: winuser.h:1647
#define EM_GETRECT
Definition: winuser.h:2025
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define WM_IME_REQUEST
Definition: winuser.h:1864
#define WM_CLOSE
Definition: winuser.h:1649
#define SB_THUMBTRACK
Definition: winuser.h:573
#define GetWindowLongPtrW
Definition: winuser.h:4983
#define EM_LINEFROMCHAR
Definition: winuser.h:2030
#define VK_TAB
Definition: winuser.h:2235
#define WM_ENABLE
Definition: winuser.h:1643
#define SB_LINEUP
Definition: winuser.h:564
#define WM_HSCROLL
Definition: winuser.h:1771
#define WM_PASTE
Definition: winuser.h:1891
#define EN_KILLFOCUS
Definition: winuser.h:2054
#define COLOR_GRAYTEXT
Definition: winuser.h:943
#define EM_GETWORDBREAKPROC
Definition: winuser.h:2028
#define EM_FMTLINES
Definition: winuser.h:2015
#define EM_GETPASSWORDCHAR
Definition: winuser.h:2024
#define COLOR_WINDOWFRAME
Definition: winuser.h:930
int(CALLBACK * EDITWORDBREAKPROCA)(LPSTR, int, int, int)
Definition: winuser.h:3012
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define EC_RIGHTMARGIN
Definition: winuser.h:2643
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_CAPTURECHANGED
Definition: winuser.h:1836
struct tagSCROLLINFO SCROLLINFO
#define WM_VSCROLL
Definition: winuser.h:1772
#define TPM_RIGHTBUTTON
Definition: winuser.h:2416
#define SIF_RANGE
Definition: winuser.h:1246
#define WM_CREATE
Definition: winuser.h:1636
#define DLGC_WANTCHARS
Definition: winuser.h:2660
#define CB_SHOWDROPDOWN
Definition: winuser.h:1999
#define EM_SETIMESTATUS
Definition: winuser.h:2039
#define EM_GETSEL
Definition: winuser.h:2026
#define EN_SETFOCUS
Definition: winuser.h:2056
#define EM_SETPASSWORDCHAR
Definition: winuser.h:2043
#define EN_UPDATE
Definition: winuser.h:2057
#define EM_GETMODIFY
Definition: winuser.h:2023
#define SB_PAGERIGHT
Definition: winuser.h:571
#define WB_ISDELIMITER
Definition: winuser.h:549
#define WM_SIZE
Definition: winuser.h:1639
#define COLOR_HIGHLIGHT
Definition: winuser.h:937
HBRUSH WINAPI GetSysColorBrush(_In_ int)
HANDLE WINAPI SetClipboardData(_In_ UINT, _In_opt_ HANDLE)
#define SB_VERT
Definition: winuser.h:553
#define EM_EMPTYUNDOBUFFER
Definition: winuser.h:2014
#define SB_LEFT
Definition: winuser.h:575
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define SB_BOTTOM
Definition: winuser.h:577
#define DLGC_WANTALLKEYS
Definition: winuser.h:2654
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1806
#define WM_COMMAND
Definition: winuser.h:1768
#define SW_INVALIDATE
Definition: winuser.h:2615
#define EM_REPLACESEL
Definition: winuser.h:2035
struct tagCREATESTRUCTA * LPCREATESTRUCTA
#define EC_USEFONTINFO
Definition: winuser.h:2644
#define VK_CONTROL
Definition: winuser.h:2239
#define EM_SETRECT
Definition: winuser.h:2045
#define DC_HASDEFID
Definition: winuser.h:2651
#define VK_UP
Definition: winuser.h:2261
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
#define WM_SETFOCUS
Definition: winuser.h:1641
#define SIF_PAGE
Definition: winuser.h:1244
#define WM_MOUSEMOVE
Definition: winuser.h:1803
#define WM_GETTEXT
Definition: winuser.h:1646
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define TPM_NONOTIFY
Definition: winuser.h:2422
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
#define WM_CUT
Definition: winuser.h:1889
#define SB_LINERIGHT
Definition: winuser.h:567
#define CS_DBLCLKS
Definition: winuser.h:659
#define EN_MAXTEXT
Definition: winuser.h:2055
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
#define EM_LINEINDEX
Definition: winuser.h:2031
#define EN_HSCROLL
Definition: winuser.h:2053
HANDLE WINAPI GetClipboardData(_In_ UINT)
#define SIF_TRACKPOS
Definition: winuser.h:1248
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define WM_GETFONT
Definition: winuser.h:1679
#define EM_LINESCROLL
Definition: winuser.h:2033
#define EM_GETFIRSTVISIBLELINE
Definition: winuser.h:2017
#define EM_GETHANDLE
Definition: winuser.h:2018
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define WM_NEXTDLGCTL
Definition: winuser.h:1671
#define WM_UNDO
Definition: winuser.h:1893
#define VK_NEXT
Definition: winuser.h:2257
#define WM_NCCREATE
Definition: winuser.h:1711
#define WM_IME_SETCONTEXT
Definition: winuser.h:1857
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define WM_SETTEXT
Definition: winuser.h:1645
#define EM_CANUNDO
Definition: winuser.h:2012
#define EM_LINELENGTH
Definition: winuser.h:2032
#define CBS_SIMPLE
Definition: winuser.h:291
#define SM_CYBORDER
Definition: winuser.h:976
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define EM_SETHANDLE
Definition: winuser.h:2038
#define VK_RETURN
Definition: winuser.h:2237
#define EM_GETLINE
Definition: winuser.h:2020
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define EM_SETRECTNP
Definition: winuser.h:2046
#define SB_LINELEFT
Definition: winuser.h:566
#define SIZE_MAXIMIZED
Definition: winuser.h:2543
#define MF_ENABLED
Definition: winuser.h:128
#define MK_CONTROL
Definition: winuser.h:2406
#define EM_SETLIMITTEXT
Definition: winuser.h:2040
#define WB_LEFT
Definition: winuser.h:550
#define WM_SETFONT
Definition: winuser.h:1678
#define VK_END
Definition: winuser.h:2258
#define TPM_LEFTALIGN
Definition: winuser.h:2413
#define VK_HOME
Definition: winuser.h:2259
#define MF_BYPOSITION
Definition: winuser.h:203
#define EM_UNDO
Definition: winuser.h:2050
#define SM_CXBORDER
Definition: winuser.h:975
#define DLGC_WANTARROWS
Definition: winuser.h:2652
#define SIF_DISABLENOSCROLL
Definition: winuser.h:1247
#define EM_SCROLL
Definition: winuser.h:2036
BOOL WINAPI IntersectRect(_Out_ LPRECT, _In_ LPCRECT, _In_ LPCRECT)
#define SB_PAGEDOWN
Definition: winuser.h:569
#define EM_SETWORDBREAKPROC
Definition: winuser.h:2049
#define SendMessage
Definition: winuser.h:6009
#define IDC_IBEAM
Definition: winuser.h:696
#define VK_BACK
Definition: winuser.h:2234
#define COLOR_HIGHLIGHTTEXT
Definition: winuser.h:938
#define SB_LINEDOWN
Definition: winuser.h:565
#define EM_SETSEL
Definition: winuser.h:2047
#define CBS_DROPDOWN
Definition: winuser.h:283
#define GetWindowLong
Definition: winuser.h:5962
#define VK_F4
Definition: winuser.h:2294
int(CALLBACK * EDITWORDBREAKPROCW)(LPWSTR, int, int, int)
Definition: winuser.h:3013
#define CB_GETDROPPEDSTATE
Definition: winuser.h:1974
#define ES_NUMBER
Definition: winuser.h:301
#define WM_LBUTTONUP
Definition: winuser.h:1805
#define WB_RIGHT
Definition: winuser.h:551
BOOL WINAPI SystemParametersInfoW(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define WM_CHAR
Definition: winuser.h:1745
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
HWND WINAPI GetParent(_In_ HWND)
#define VK_LEFT
Definition: winuser.h:2260
#define WM_NCDESTROY
Definition: winuser.h:1712
#define VK_RIGHT
Definition: winuser.h:2262
#define SIZE_RESTORED
Definition: winuser.h:2541
#define SB_TOP
Definition: winuser.h:578
#define EN_VSCROLL
Definition: winuser.h:2058
#define CB_GETEXTENDEDUI
Definition: winuser.h:1977
#define SIF_POS
Definition: winuser.h:1245
#define VK_DOWN
Definition: winuser.h:2263
#define GWLP_ID
Definition: winuser.h:871
#define WM_COPY
Definition: winuser.h:1890
#define EM_GETTHUMB
Definition: winuser.h:2027
#define SB_ENDSCROLL
Definition: winuser.h:574
#define EM_GETMARGINS
Definition: winuser.h:2022
#define WM_IME_CONTROL
Definition: winuser.h:1859
#define VK_SHIFT
Definition: winuser.h:2238
#define EM_SETTABSTOPS
Definition: winuser.h:2048
#define DLGC_WANTMESSAGE
Definition: winuser.h:2655
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define VK_PRIOR
Definition: winuser.h:2256
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define VK_DELETE
Definition: winuser.h:2269
#define WM_IME_SELECT
Definition: winuser.h:1861
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define WM_CLEAR
Definition: winuser.h:1892
#define WM_KEYDOWN
Definition: winuser.h:1743
#define CB_SETEXTENDEDUI
Definition: winuser.h:1993
#define EM_GETLINECOUNT
Definition: winuser.h:2021
#define SB_RIGHT
Definition: winuser.h:576
BOOL WINAPI SetCaretPos(_In_ int, _In_ int)
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
BOOL WINAPI CreateCaret(_In_ HWND, _In_opt_ HBITMAP, _In_ int, _In_ int)
BOOL WINAPI DestroyCaret(void)
Definition: caret.c:35
#define EC_LEFTMARGIN
Definition: winuser.h:2642
#define DM_GETDEFID
Definition: winuser.h:2134
#define TPM_RETURNCMD
Definition: winuser.h:2423
#define SystemParametersInfo
Definition: winuser.h:6024
#define EN_ERRSPACE
Definition: winuser.h:2052
#define GWL_STYLE
Definition: winuser.h:863
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define CS_PARENTDC
Definition: winuser.h:664
#define EM_SETMARGINS
Definition: winuser.h:2041
#define WM_CTLCOLOREDIT
Definition: winuser.h:1795
#define VK_ESCAPE
Definition: winuser.h:2250
#define DLGC_HASSETSEL
Definition: winuser.h:2656
BOOL WINAPI IsWindowVisible(_In_ HWND)
#define WM_KILLFOCUS
Definition: winuser.h:1642
int WINAPI GetSystemMetrics(_In_ int)
#define SB_PAGEUP
Definition: winuser.h:568
#define WM_SYSKEYDOWN
Definition: winuser.h:1747
#define VK_INSERT
Definition: winuser.h:2268
#define WM_GETDLGCODE
Definition: winuser.h:1717
#define WM_MBUTTONDOWN
Definition: winuser.h:1810
#define EM_SETMODIFY
Definition: winuser.h:2042
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SB_HORZ
Definition: winuser.h:552
#define VK_MENU
Definition: winuser.h:2240
#define WS_EX_RIGHT
Definition: winuser.h:400
#define SB_PAGELEFT
Definition: winuser.h:570
#define GWL_EXSTYLE
Definition: winuser.h:862
#define MF_GRAYED
Definition: winuser.h:129
#define EN_CHANGE
Definition: winuser.h:2051
#define WM_SETREDRAW
Definition: winuser.h:1644
#define SB_THUMBPOSITION
Definition: winuser.h:572
LONG WINAPI TabbedTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(chCount) LPCWSTR lpString, _In_ int chCount, _In_ int nTabPositions, _In_reads_opt_(nTabPositions) CONST INT *lpnTabStopPositions, _In_ int nTabOrigin)
HMENU WINAPI LoadMenuA(_In_opt_ HINSTANCE, _In_ LPCSTR)
void redraw(int x, int y, int cx, int cy)
Definition: qtewin.cpp:1248
PFNCLIENT pfnClientA
Definition: regcontrol.c:15
PFNCLIENT pfnClientW
Definition: regcontrol.c:16
const struct builtin_class_descr EDIT_builtin_class
#define EM_SCROLLCARET
Definition: richedit.h:81
#define WM_UNICHAR
Definition: richedit.h:67
#define EM_POSFROMCHAR
Definition: richedit.h:77
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define EM_CHARFROMPOS
Definition: richedit.h:78
#define WM_PRINTCLIENT
Definition: richedit.h:70
#define EM_GETLIMITTEXT
Definition: richedit.h:74
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define LANG_KOREAN
Definition: nls.h:84
#define memset(x, y, z)
Definition: compat.h:39
#define UINT
Definition: utils.c:29
#define TRACE(s)
Definition: solgame.cpp:4
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
RECT rcArea
Definition: dimm.idl:88
DWORD dwStyle
Definition: dimm.idl:86
POINT ptCurrentPos
Definition: dimm.idl:87
Definition: edit.c:96
Definition: dcommon.idl:28
long bottom
Definition: dcommon.idl:29
long right
Definition: dcommon.idl:29
long left
Definition: dcommon.idl:29
long top
Definition: dcommon.idl:29
Definition: wingdi.h:1856
int abcA
Definition: wingdi.h:1857
int abcC
Definition: wingdi.h:1859
WNDPROC pfnEditWndProc
Definition: ntuser.h:811
LONG cx
Definition: kdterminal.h:27
Definition: ftp_var.h:139
Definition: inflate.c:139
Definition: dialog.c:52
Definition: ffs.h:70
Definition: copy.c:22
Definition: parser.c:49
Definition: tftpd.h:60
Definition: name.c:39
Definition: style.c:91
INT width
Definition: edit.c:89
struct tagLINEDEF * next
Definition: edit.c:92
INT length
Definition: edit.c:86
SCRIPT_STRING_ANALYSIS ssa
Definition: edit.c:91
INT index
Definition: edit.c:90
INT net_length
Definition: edit.c:87
LINE_END ending
Definition: edit.c:88
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
int * pTabStops
Definition: usp10.h:173
#define max(a, b)
Definition: svc.c:63
PSYMCRYPT_PARALLEL_HASH_OPERATION next
#define WHEEL_DELTA
Definition: treelist.c:99
#define WM_MOUSEWHEEL
Definition: treelist.c:96
else
Definition: tritemp.h:161
const char * LPCSTR
Definition: typedefs.h:52
int32_t INT32
Definition: typedefs.h:58
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
#define WM_CBLOSTTEXTFOCUS
Definition: undocuser.h:52
#define user32_module
Definition: user32p.h:40
const char * SPY_GetMsgName(UINT msg, HWND hWnd)
Definition: spy.c:2232
#define NtUserSetPrivateData(HWND, OFFSET, SIZE, VALUE)
Definition: user_x.h:132
#define NtUserReleaseDC(HWND, HDC)
Definition: user_x.h:120
#define NTUSER_WNDPROC_EDIT
Definition: user_x.h:140
#define MAKE_FNID(index)
Definition: user_x.h:143
#define NtUserGetPrivateData(HWND, OFFSET, SIZE)
Definition: user_x.h:131
#define NtUserReleaseCapture()
Definition: user_x.h:121
#define SSA_TAB
Definition: usp10.h:34
#define SSA_FALLBACK
Definition: usp10.h:38
#define SSA_LINK
Definition: usp10.h:45
#define SSA_PASSWORD
Definition: usp10.h:33
#define SSA_GLYPHS
Definition: usp10.h:40
#define SCRIPT_UNDEFINED
Definition: usp10.h:69
static GLenum which
Definition: wgl_font.c:159
HBRUSH FASTCALL GetControlBrush(PWND pwnd, HDC hdc, UINT ctlType)
Definition: misc.c:179
static void EDIT_UpdateImmCompositionWindow(EDITSTATE *es, UINT x, UINT y)
Definition: edit.c:1910
static EDITSTATE * get_control_state(HWND hwnd)
Definition: edit.c:164
LRESULT WINAPI EditWndProc_common(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode)
Definition: edit.c:4820
static LRESULT DefWindowProcT(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode)
Definition: edit.c:4805
static int EDIT_is_valid_format_rect(const EDITSTATE *es, const RECT *rc)
Definition: edit.c:2457
DWORD get_app_version(void)
Definition: edit.c:215
static void EDIT_UpdateImmCompositionFont(EDITSTATE *es)
Definition: edit.c:4059
static EDITSTATE * set_control_state(HWND hwnd, EDITSTATE *state)
Definition: edit.c:169
#define GMEM_MOVEABLE
Definition: winbase.h:318
#define GMEM_DDESHARE
Definition: winbase.h:322
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
DWORD COLORREF
Definition: windef.h:100
#define WINAPI
Definition: msvc.h:6
int WINAPI GetBkMode(_In_ HDC)
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define FS_JOHAB
Definition: wingdi.h:574
BOOL WINAPI GetCharABCWidthsA(_In_ HDC hdc, _In_ UINT wFirst, _In_ UINT wLast, _Out_writes_(wLast - wFirst+1) LPABC lpABC)
int WINAPI GetTextCharsetInfo(_In_ HDC, _Out_opt_ LPFONTSIGNATURE, _In_ DWORD)
int WINAPI GetClipBox(_In_ HDC, _Out_ LPRECT)
#define FS_WANSUNG
Definition: wingdi.h:572
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
LONG WINAPI GdiGetCharDimensions(HDC, LPTEXTMETRICW, LONG *)
Definition: font.c:2341
COLORREF WINAPI GetTextColor(_In_ HDC)
Definition: text.c:860
int WINAPI IntersectClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
#define DEFAULT_CHARSET
Definition: wingdi.h:384
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define TMPF_TRUETYPE
Definition: wingdi.h:1313
COLORREF WINAPI GetBkColor(_In_ HDC)
Definition: dc.c:978
#define PATCOPY
Definition: wingdi.h:335
#define TMPF_VECTOR
Definition: wingdi.h:1312
#define OPAQUE
Definition: wingdi.h:949
#define RGN_OR
Definition: wingdi.h:359
#define FS_JISJAPAN
Definition: wingdi.h:570
#define FS_CHINESETRAD
Definition: wingdi.h:573
#define FS_CHINESESIMP
Definition: wingdi.h:571
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
DWORD WINAPI GdiGetCodePage(HDC)
BOOL WINAPI TextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_reads_(c) LPCWSTR lpString, _In_ int c)
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:917
BOOL WINAPI SetRectRgn(_In_ HRGN, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
BOOL WINAPI GetCharABCWidthsW(_In_ HDC hdc, _In_ UINT wFirst, _In_ UINT wLast, _Out_writes_(wLast - wFirst+1) LPABC lpABC)
struct _OSVERSIONINFOW OSVERSIONINFOW
unsigned char BYTE
Definition: xxhash.c:193