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