ReactOS 0.4.16-dev-905-gc1b8c4f
caret.c
Go to the documentation of this file.
1/*
2 * RichEdit - Caret and selection functions.
3 *
4 * Copyright 2004 by Krzysztof Foltman
5 * Copyright 2005 by Phil Krylov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22
23#include "editor.h"
24
26
28{
29 cursor->para = editor_first_para( editor );
30 cursor->run = para_first_run( cursor->para );
31 cursor->nOffset = 0;
32}
33
34static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop)
35{
36 cursor->para = para_prev( editor_end_para( editor ) );
37 cursor->run = para_end_run( cursor->para );
38 cursor->nOffset = final_eop ? cursor->run->len : 0;
39}
40
41
42int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
43{
44 *from = ME_GetCursorOfs(&editor->pCursors[0]);
45 *to = ME_GetCursorOfs(&editor->pCursors[1]);
46
47 if (*from > *to)
48 {
49 int tmp = *from;
50 *from = *to;
51 *to = tmp;
52 return 1;
53 }
54 return 0;
55}
56
58{
59 int from_ofs = ME_GetCursorOfs( &editor->pCursors[0] );
60 int to_ofs = ME_GetCursorOfs( &editor->pCursors[1] );
61 BOOL swap = (from_ofs > to_ofs);
62
63 if (from_ofs == to_ofs)
64 {
65 /* If cursor[0] is at the beginning of a run and cursor[1] at the end
66 of the prev run then we need to swap. */
67 if (editor->pCursors[0].nOffset < editor->pCursors[1].nOffset)
68 swap = TRUE;
69 }
70
71 if (!swap)
72 {
73 *from = &editor->pCursors[0];
74 *to = &editor->pCursors[1];
75 return 0;
76 } else {
77 *from = &editor->pCursors[1];
78 *to = &editor->pCursors[0];
79 return 1;
80 }
81}
82
84{
87 return ME_GetCursorOfs(&cursor);
88}
89
90
92{
93 int length;
94
95 if (how->flags & GTL_PRECISE && how->flags & GTL_CLOSE)
96 return E_INVALIDARG;
97 if (how->flags & GTL_NUMCHARS && how->flags & GTL_NUMBYTES)
98 return E_INVALIDARG;
99
100 length = ME_GetTextLength(editor);
101
102 if ((editor->props & TXTBIT_MULTILINE)
103 && (how->flags & GTL_USECRLF)
104 && !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */
105 length += editor->nParagraphs - 1;
106
107 if (how->flags & GTL_NUMBYTES ||
108 (how->flags & GTL_PRECISE && /* GTL_PRECISE seems to imply GTL_NUMBYTES */
109 !(how->flags & GTL_NUMCHARS))) /* unless GTL_NUMCHARS is given */
110 {
111 CPINFO cpinfo;
112
113 if (how->codepage == 1200)
114 return length * 2;
115 if (how->flags & GTL_PRECISE)
116 FIXME("GTL_PRECISE flag unsupported. Using GTL_CLOSE\n");
117 if (GetCPInfo(how->codepage, &cpinfo))
118 return length * cpinfo.MaxCharSize;
119 ERR("Invalid codepage %u\n", how->codepage);
120 return E_INVALIDARG;
121 }
122 return length;
123}
124
125/******************************************************************
126 * set_selection_cursors
127 *
128 * Updates the selection cursors.
129 *
130 * Note that this does not invalidate either the old or the new selections.
131 */
132int set_selection_cursors(ME_TextEditor *editor, int from, int to)
133{
134 int selectionEnd = 0;
135 const int len = ME_GetTextLength(editor);
136
137 /* all negative values are effectively the same */
138 if (from < 0)
139 from = -1;
140 if (to < 0)
141 to = -1;
142
143 /* select all */
144 if (from == 0 && to == -1)
145 {
146 ME_SetCursorToStart(editor, &editor->pCursors[1]);
147 ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE);
148 return len + 1;
149 }
150
151 /* if both values are equal and also out of bound, that means to */
152 /* put the selection at the end of the text */
153 if ((from == to) && (to < 0 || to > len))
154 {
155 selectionEnd = 1;
156 }
157 else
158 {
159 /* if from is negative and to is positive then selection is */
160 /* deselected and caret moved to end of the current selection */
161 if (from < 0)
162 {
163 int start, end;
164 ME_GetSelectionOfs(editor, &start, &end);
165 if (start != end)
166 {
167 if (end > len)
168 {
169 editor->pCursors[0].nOffset = 0;
170 end --;
171 }
172 editor->pCursors[1] = editor->pCursors[0];
173 }
174 return end;
175 }
176
177 /* adjust to if it's a negative value */
178 if (to < 0)
179 to = len + 1;
180
181 /* flip from and to if they are reversed */
182 if (from>to)
183 {
184 int tmp = from;
185 from = to;
186 to = tmp;
187 }
188
189 /* after fiddling with the values, we find from > len && to > len */
190 if (from > len)
191 selectionEnd = 1;
192 /* special case with to too big */
193 else if (to > len)
194 to = len + 1;
195 }
196
197 if (selectionEnd)
198 {
199 ME_SetCursorToEnd(editor, &editor->pCursors[0], FALSE);
200 editor->pCursors[1] = editor->pCursors[0];
201 return len;
202 }
203
204 cursor_from_char_ofs( editor, from, &editor->pCursors[1] );
205 editor->pCursors[0] = editor->pCursors[1];
206 ME_MoveCursorChars(editor, &editor->pCursors[0], to - from, FALSE);
207 /* Selection is not allowed in the middle of an end paragraph run. */
208 if (editor->pCursors[1].run->nFlags & MERF_ENDPARA)
209 editor->pCursors[1].nOffset = 0;
210 if (editor->pCursors[0].run->nFlags & MERF_ENDPARA)
211 {
212 if (to > len)
213 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
214 else
215 editor->pCursors[0].nOffset = 0;
216 }
217 return to;
218}
219
220
222 int *x, int *y, int *height )
223{
224 ME_Row *row;
225 ME_Run *run = cursor->run;
226 ME_Paragraph *para = cursor->para;
227 ME_Run *size_run = run, *prev;
229 int run_x;
230 HDC hdc = ITextHost_TxGetDC( editor->texthost );
231
232 assert(~para->nFlags & MEPF_REWRAP);
233
235
236 ME_InitContext( &c, editor, hdc );
237
238 if (!cursor->nOffset && (prev = run_prev( run ))) size_run = prev;
239
240 run_x = ME_PointFromCharContext( &c, run, cursor->nOffset, TRUE );
241
242 *height = size_run->nAscent + size_run->nDescent;
243 *x = c.rcView.left + run->pt.x + run_x - editor->horz_si.nPos;
244 *y = c.rcView.top + para->pt.y + row->nBaseline
245 + run->pt.y - size_run->nAscent - editor->vert_si.nPos;
248 return;
249}
250
252{
253 int x, y, height;
254
255 cursor_coords( editor, &editor->pCursors[0], &x, &y, &height );
257 editor->caret_height = height;
258 editor->caret_hidden = TRUE;
259}
260
262{
264 editor->caret_hidden = FALSE;
265}
266
268{
269 /* calls to HideCaret are cumulative; do so only once */
270 if (!editor->caret_hidden)
271 {
273 editor->caret_hidden = TRUE;
274 }
275}
276
278{
279 int x, y, height;
280
281 if (!editor->bHaveFocus) return;
282 if (!ME_IsSelection(editor))
283 {
284 cursor_coords( editor, &editor->pCursors[0], &x, &y, &height );
285 if (height != editor->caret_height) create_caret(editor);
286 x = min(x, editor->rcFormat.right-1);
288 show_caret(editor);
289 }
290 else
291 hide_caret(editor);
292#ifdef __REACTOS__
294 {
295 HIMC hIMC = ImmGetContext(editor->hWnd);
296 if (hIMC)
297 {
299 LOGFONTW lf;
300 COMPOSITIONFORM CompForm;
301 POINT pt = { x, y };
302
303 CompForm.ptCurrentPos = pt;
304 if (editor->styleFlags & ES_MULTILINE)
305 {
306 CompForm.dwStyle = CFS_RECT;
307 CompForm.rcArea = editor->rcFormat;
308 }
309 else
310 {
311 CompForm.dwStyle = CFS_POINT;
312 SetRectEmpty(&CompForm.rcArea);
313 }
314 ImmSetCompositionWindow(hIMC, &CompForm);
315
316 fmt.cbSize = sizeof(fmt);
318
319 ZeroMemory(&lf, sizeof(lf));
321 if (fmt.dwMask & CFM_SIZE)
322 {
324 lf.lfHeight = -MulDiv(fmt.yHeight, GetDeviceCaps(hdc, LOGPIXELSY), 1440);
325 DeleteDC(hdc);
326 }
327 if (fmt.dwMask & CFM_CHARSET)
328 lf.lfCharSet = fmt.bCharSet;
329 if (fmt.dwMask & CFM_FACE)
330 lstrcpynW(lf.lfFaceName, fmt.szFaceName, ARRAY_SIZE(lf.lfFaceName));
331 ImmSetCompositionFontW(hIMC, &lf);
332
333 ImmReleaseContext(editor->hWnd, hIMC);
334 }
335 }
336#endif
337}
338
340 int nChars, BOOL bForce)
341{
342 ME_Cursor c = *start;
343 int nOfs = ME_GetCursorOfs(start), text_len = ME_GetTextLength( editor );
344 int shift = 0;
345 int totalChars = nChars;
346 ME_Paragraph *start_para;
347 BOOL delete_all = FALSE;
348
349 /* Prevent deletion past last end of paragraph run. */
350 nChars = min(nChars, text_len - nOfs);
351 if (nChars == text_len) delete_all = TRUE;
352 start_para = c.para;
353
354 if (!bForce)
355 {
356 table_protect_partial_deletion( editor, &c, &nChars );
357 if (nChars == 0) return FALSE;
358 }
359
360 while (nChars > 0)
361 {
362 ME_Run *run;
363 cursor_from_char_ofs( editor, nOfs + nChars, &c );
364 if (!c.nOffset)
365 {
366 /* We aren't deleting anything in this run, so we will go back to the
367 * last run we are deleting text in. */
368 c.run = run_prev_all_paras( c.run );
369 c.para = c.run->para;
370 c.nOffset = c.run->len;
371 }
372 run = c.run;
373 if (run->nFlags & MERF_ENDPARA)
374 {
375 int eollen = c.run->len;
376 BOOL keepFirstParaFormat;
377
378 if (!para_next( para_next( c.para ) )) return TRUE;
379
380 keepFirstParaFormat = (totalChars == nChars && nChars <= eollen &&
381 run->nCharOfs);
382 if (!editor->bEmulateVersion10) /* v4.1 */
383 {
384 ME_Paragraph *this_para = run->para;
385 ME_Paragraph *next_para = para_next( this_para );
386
387 /* The end of paragraph before a table row is only deleted if there
388 * is nothing else on the line before it. */
389 if (this_para == start_para && next_para->nFlags & MEPF_ROWSTART)
390 {
391 /* If the paragraph will be empty, then it should be deleted, however
392 * it still might have text right now which would inherit the
393 * MEPF_STARTROW property if we joined it right now.
394 * Instead we will delete it after the preceding text is deleted. */
395 if (nOfs > this_para->nCharOfs)
396 {
397 /* Skip this end of line. */
398 nChars -= (eollen < nChars) ? eollen : nChars;
399 continue;
400 }
401 keepFirstParaFormat = TRUE;
402 }
403 }
404 para_join( editor, c.para, keepFirstParaFormat );
405 /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
406 ME_CheckCharOffsets(editor);
407 nChars -= (eollen < nChars) ? eollen : nChars;
408 continue;
409 }
410 else
411 {
413 int nCharsToDelete = min(nChars, c.nOffset);
414 int i;
415
416 c.nOffset -= nCharsToDelete;
417
418 para_mark_rewrap( editor, c.run->para );
419
420 cursor = c;
421 /* nChars is the number of characters that should be deleted from the
422 PRECEDING runs (these BEFORE cursor.pRun)
423 nCharsToDelete is a number of chars to delete from THIS run */
424 nChars -= nCharsToDelete;
425 shift -= nCharsToDelete;
426 TRACE("Deleting %d (remaining %d) chars at %d in %s (%d)\n",
427 nCharsToDelete, nChars, c.nOffset,
428 debugstr_run( run ), run->len);
429
430 /* nOfs is a character offset (from the start of the document
431 to the current (deleted) run */
432 add_undo_insert_run( editor, nOfs + nChars, get_text( run, c.nOffset ), nCharsToDelete, run->nFlags, run->style );
433
434 ME_StrDeleteV(run->para->text, run->nCharOfs + c.nOffset, nCharsToDelete);
435 run->len -= nCharsToDelete;
436 TRACE("Post deletion string: %s (%d)\n", debugstr_run( run ), run->len);
437 TRACE("Shift value: %d\n", shift);
438
439 /* update cursors (including c) */
440 for (i=-1; i<editor->nCursors; i++) {
441 ME_Cursor *pThisCur = editor->pCursors + i;
442 if (i == -1) pThisCur = &c;
443 if (pThisCur->run == cursor.run) {
444 if (pThisCur->nOffset > cursor.nOffset) {
445 if (pThisCur->nOffset-cursor.nOffset < nCharsToDelete)
446 pThisCur->nOffset = cursor.nOffset;
447 else
448 pThisCur->nOffset -= nCharsToDelete;
449 assert(pThisCur->nOffset >= 0);
450 assert(pThisCur->nOffset <= run->len);
451 }
452 if (pThisCur->nOffset == run->len)
453 {
454 pThisCur->run = run_next( pThisCur->run );
455 assert( pThisCur->run );
456 pThisCur->nOffset = 0;
457 }
458 }
459 }
460
461 /* c = updated data now */
462
463 if (c.run == cursor.run) c.run->nCharOfs -= shift;
465
466 if (!cursor.run->len)
467 {
468 TRACE("Removing empty run\n");
469 ME_Remove( run_get_di( cursor.run ));
471 }
472
473 shift = 0;
474 continue;
475 }
476 }
477 if (delete_all) editor_set_default_para_fmt( editor, &start_para->fmt );
478 return TRUE;
479}
480
481BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
482{
483 assert(nCursor>=0 && nCursor<editor->nCursors);
484 /* text operations set modified state */
485 editor->nModifyStep = 1;
486 return ME_InternalDeleteText(editor, &editor->pCursors[nCursor],
487 nChars, FALSE);
488}
489
490static struct re_object* create_re_object(const REOBJECT *reo)
491{
492 struct re_object *reobj = heap_alloc(sizeof(*reobj));
493
494 if (!reobj)
495 {
496 WARN("Fail to allocate re_object.\n");
497 return NULL;
498 }
499 ME_CopyReObject(&reobj->obj, reo, REO_GETOBJ_ALL_INTERFACES);
500 return reobj;
501}
502
503void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor)
504{
505 ME_Run *run, *prev;
506 const WCHAR space = ' ';
507 struct re_object *reobj_prev = NULL;
508 ME_Cursor *cursor = editor->pCursors + nCursor;
510
511 /* FIXME no no no */
512 if (ME_IsSelection(editor))
513 ME_DeleteSelection(editor);
514
515 run = run_insert( editor, cursor, style, &space, 1, MERF_GRAPHICS );
516
517 run->reobj = create_re_object( reo );
518
519 prev = run;
520 while ((prev = run_prev_all_paras( prev )))
521 {
522 if (prev->reobj)
523 {
524 reobj_prev = prev->reobj;
525 break;
526 }
527 }
528 if (reobj_prev)
529 list_add_after(&reobj_prev->entry, &run->reobj->entry);
530 else
531 list_add_head(&editor->reobj_list, &run->reobj->entry);
532
534}
535
536
537void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor)
538{
539 const WCHAR space = ' ';
540 ME_Cursor *cursor = editor->pCursors + nCursor;
542
543 /* FIXME no no no */
544 if (ME_IsSelection(editor))
545 ME_DeleteSelection(editor);
546
547 run_insert( editor, cursor, style, &space, 1, MERF_ENDROW );
548
550}
551
552
553void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
554 const WCHAR *str, int len, ME_Style *style)
555{
556 const WCHAR *pos;
557 ME_Cursor *cursor = editor->pCursors + nCursor;
558 int oldLen;
559
560 /* FIXME really HERE ? */
561 if (ME_IsSelection(editor))
562 ME_DeleteSelection(editor);
563
564 oldLen = ME_GetTextLength(editor);
565
566 /* text operations set modified state */
567 editor->nModifyStep = 1;
568
569 assert(style);
570
571 if (len == -1) len = lstrlenW( str );
572
573 /* grow the text limit to fit our text */
574 if (editor->nTextLimit < oldLen + len) editor->nTextLimit = oldLen + len;
575
576 pos = str;
577
578 while (len)
579 {
580 /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */
581 while (pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t')
582 pos++;
583
584 if (pos != str) /* handle text */
585 run_insert( editor, cursor, style, str, pos - str, 0 );
586 else if (*pos == '\t') /* handle tabs */
587 {
588 const WCHAR tab = '\t';
589 run_insert( editor, cursor, style, &tab, 1, MERF_TAB );
590 pos++;
591 }
592 else /* handle EOLs */
593 {
594 ME_Run *end_run, *run, *prev;
595 ME_Paragraph *new_para;
596 int eol_len = 0;
597
598 /* Check if new line is allowed for this control */
599 if (!(editor->props & TXTBIT_MULTILINE))
600 break;
601
602 /* Find number of CR and LF in end of paragraph run */
603 if (*pos =='\r')
604 {
605 if (len > 1 && pos[1] == '\n')
606 eol_len = 2;
607 else if (len > 2 && pos[1] == '\r' && pos[2] == '\n')
608 eol_len = 3;
609 else
610 eol_len = 1;
611 }
612 else
613 {
614 assert(*pos == '\n');
615 eol_len = 1;
616 }
617 pos += eol_len;
618
619 if (!editor->bEmulateVersion10 && eol_len == 3)
620 {
621 /* handle special \r\r\n sequence (richedit 2.x and higher only) */
622 const WCHAR space = ' ';
623 run_insert( editor, cursor, style, &space, 1, 0 );
624 }
625 else
626 {
627 const WCHAR cr = '\r', *eol_str = str;
628
629 if (!editor->bEmulateVersion10)
630 {
631 eol_str = &cr;
632 eol_len = 1;
633 }
634
635 if (cursor->nOffset == cursor->run->len)
636 {
637 run = run_next( cursor->run );
638 if (!run) run = cursor->run;
639 }
640 else
641 {
642 if (cursor->nOffset) run_split( editor, cursor );
643 run = cursor->run;
644 }
645
646 new_para = para_split( editor, run, style, eol_str, eol_len, 0 );
647 end_run = para_end_run( para_prev( new_para ) );
648
649 /* Move any cursors that were at the end of the previous run to the beginning of the new para */
650 prev = run_prev( end_run );
651 if (prev)
652 {
653 int i;
654 for (i = 0; i < editor->nCursors; i++)
655 {
656 if (editor->pCursors[i].run == prev &&
657 editor->pCursors[i].nOffset == prev->len)
658 {
659 editor->pCursors[i].para = new_para;
660 editor->pCursors[i].run = run;
661 editor->pCursors[i].nOffset = 0;
662 }
663 }
664 }
665
666 }
667 }
668 len -= pos - str;
669 str = pos;
670 }
671}
672
673/* Move the cursor nRelOfs characters (either forwards or backwards)
674 * If final_eop is TRUE, allow moving the cursor to the end of the final eop.
675 *
676 * returns the actual number of characters moved.
677 **/
678int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
679{
680 cursor->nOffset += nRelOfs;
681 if (cursor->nOffset < 0)
682 {
683 cursor->nOffset += cursor->run->nCharOfs;
684 if (cursor->nOffset >= 0)
685 {
686 /* new offset in the same paragraph */
687 do {
688 cursor->run = run_prev( cursor->run );
689 } while (cursor->nOffset < cursor->run->nCharOfs);
690 cursor->nOffset -= cursor->run->nCharOfs;
691 return nRelOfs;
692 }
693
694 cursor->nOffset += cursor->para->nCharOfs;
695 if (cursor->nOffset <= 0)
696 {
697 /* moved to the start of the text */
698 nRelOfs -= cursor->nOffset;
700 return nRelOfs;
701 }
702
703 /* new offset in a previous paragraph */
704 do {
705 cursor->para = para_prev( cursor->para );
706 } while (cursor->nOffset < cursor->para->nCharOfs);
707 cursor->nOffset -= cursor->para->nCharOfs;
708
709 cursor->run = para_end_run( cursor->para );
710 while (cursor->nOffset < cursor->run->nCharOfs)
711 cursor->run = run_prev( cursor->run );
712 cursor->nOffset -= cursor->run->nCharOfs;
713 }
714 else if (cursor->nOffset >= cursor->run->len)
715 {
716 ME_Paragraph *next_para;
717 int new_offset;
718
719 new_offset = ME_GetCursorOfs(cursor);
720 next_para = para_next( cursor->para );
721 if (new_offset < next_para->nCharOfs)
722 {
723 /* new offset in the same paragraph */
724 do {
725 cursor->nOffset -= cursor->run->len;
726 cursor->run = run_next( cursor->run );
727 } while (cursor->nOffset >= cursor->run->len);
728 return nRelOfs;
729 }
730
731 if (new_offset >= ME_GetTextLength(editor) + (final_eop ? 1 : 0))
732 {
733 /* new offset at the end of the text */
734 ME_SetCursorToEnd(editor, cursor, final_eop);
735 nRelOfs -= new_offset - (ME_GetTextLength(editor) + (final_eop ? 1 : 0));
736 return nRelOfs;
737 }
738
739 /* new offset in a following paragraph */
740 do {
741 cursor->para = next_para;
742 next_para = para_next( next_para );
743 } while (new_offset >= next_para->nCharOfs);
744
745 cursor->nOffset = new_offset - cursor->para->nCharOfs;
746 cursor->run = para_first_run( cursor->para );
747 while (cursor->nOffset >= cursor->run->len)
748 {
749 cursor->nOffset -= cursor->run->len;
750 cursor->run = run_next( cursor->run );
751 }
752 } /* else new offset is in the same run */
753 return nRelOfs;
754}
755
756
757BOOL
759{
760 ME_Run *run = cursor->run, *other_run;
761 ME_Paragraph *para = cursor->para;
762 int nOffset = cursor->nOffset;
763
764 if (nRelOfs == -1)
765 {
766 /* Backward movement */
767 while (TRUE)
768 {
769 nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDLEFT );
770 if (nOffset) break;
771 other_run = run_prev( run );
772 if (other_run)
773 {
774 if (ME_CallWordBreakProc( editor, get_text( other_run, 0 ), other_run->len, other_run->len - 1, WB_ISDELIMITER )
775 && !(run->nFlags & MERF_ENDPARA)
776 && !(cursor->run == run && cursor->nOffset == 0)
777 && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, 0, WB_ISDELIMITER ))
778 break;
779 run = other_run;
780 nOffset = other_run->len;
781 }
782 else
783 {
784 if (cursor->run == run && cursor->nOffset == 0)
785 {
786 para = run->para;
787 /* Skip empty start of table row paragraph */
788 if (para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART)
789 para = para_prev( para );
790 /* Paragraph breaks are treated as separate words */
791 if (!para_prev( para )) return FALSE;
792 para = para_prev( para );
793 run = para_end_run( para );
794 }
795 break;
796 }
797 }
798 }
799 else
800 {
801 /* Forward movement */
802 BOOL last_delim = FALSE;
803
804 while (TRUE)
805 {
806 if (last_delim && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_ISDELIMITER ))
807 break;
808 nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDRIGHT );
809 if (nOffset < run->len) break;
810 other_run = run_next( run );
811 if (other_run)
812 {
813 last_delim = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset - 1, WB_ISDELIMITER );
814 run = other_run;
815 nOffset = 0;
816 }
817 else
818 {
819 para = para_next( para );
820 if (!para_next( para ))
821 {
822 if (cursor->run == run) return FALSE;
823 nOffset = 0;
824 break;
825 }
826 if (para->nFlags & MEPF_ROWSTART) para = para_next( para );
827 if (cursor->run == run) run = para_first_run( para );
828 nOffset = 0;
829 break;
830 }
831 }
832 }
833 cursor->para = para;
834 cursor->run = run;
835 cursor->nOffset = nOffset;
836 return TRUE;
837}
838
839
840static void
842{
843 /* pCursor[0] is the end of the selection
844 * pCursor[1] is the start of the selection (or the position selection anchor)
845 * pCursor[2] and [3] are the selection anchors that are backed up
846 * so they are kept when the selection changes for drag selection.
847 */
848
849 editor->nSelectionType = selectionType;
850 switch(selectionType)
851 {
852 case stPosition:
853 break;
854 case stWord:
855 ME_MoveCursorWords(editor, &editor->pCursors[0], +1);
856 editor->pCursors[1] = editor->pCursors[0];
857 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
858 break;
859 case stParagraph:
860 editor->pCursors[1] = editor->pCursors[0];
861
862 editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
863 editor->pCursors[0].para = editor->pCursors[0].run->para;
864 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
865
866 editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
867 editor->pCursors[1].nOffset = 0;
868 break;
869 case stLine:
870 {
871 ME_Row *row = row_from_cursor( editor->pCursors );
872
873 row_first_cursor( row, editor->pCursors + 1 );
874 row_end_cursor( row, editor->pCursors, TRUE );
875 break;
876 }
877 case stDocument:
878 /* Select everything with cursor anchored from the start of the text */
879 ME_SetCursorToStart(editor, &editor->pCursors[1]);
880 ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE);
881 break;
882 default: assert(0);
883 }
884 /* Store the anchor positions for extending the selection. */
885 editor->pCursors[2] = editor->pCursors[0];
886 editor->pCursors[3] = editor->pCursors[1];
887}
888
890{
891 return cursor->para->nCharOfs + cursor->run->nCharOfs + cursor->nOffset;
892}
893
894/* Helper function for cursor_from_virtual_coords() to find paragraph within tables */
896{
897 ME_Cell *cell, *next_cell;
898
899 assert( para->nFlags & MEPF_ROWSTART );
900 cell = table_row_first_cell( para );
901 assert( cell );
902
903 /* find the cell we are in */
904 while ((next_cell = cell_next( cell )) != NULL)
905 {
906 if (x < next_cell->pt.x)
907 {
908 para = cell_first_para( cell );
909 /* Found the cell, but there might be multiple paragraphs in
910 * the cell, so need to search down the cell for the paragraph. */
911 while (cell == para_cell( para ))
912 {
913 if (y < para->pt.y + para->nHeight)
914 {
915 if (para->nFlags & MEPF_ROWSTART) return pixel_pos_in_table_row( x, y, para );
916 else return para;
917 }
918 para = para_next( para );
919 }
920 /* Past the end of the cell, so go back to the last cell paragraph */
921 return para_prev( para );
922 }
923 cell = next_cell;
924 }
925 /* Return table row delimiter */
926 para = table_row_end( para );
927 assert( para->nFlags & MEPF_ROWEND );
930 return para;
931}
932
933static BOOL row_cursor( ME_TextEditor *editor, ME_Row *row, int x,
935{
936 ME_Run *run, *last;
937 BOOL exact = TRUE;
938
939 if (x < row->pt.x)
940 {
941 x = row->pt.x;
942 exact = FALSE;
943 }
944
945 run = row_first_run( row );
946 assert( run );
947 cursor->nOffset = 0;
948 do
949 {
950 if (x >= run->pt.x && x < run->pt.x + run->nWidth)
951 {
952 cursor->nOffset = ME_CharFromPoint( editor, x - run->pt.x, run, TRUE, TRUE );
953 cursor->run = run;
954 cursor->para = run->para;
955 return exact;
956 }
957 last = run;
958 run = row_next_run( row, run );
959 } while (run);
960
961 run = last;
962
963 cursor->run = run;
964 cursor->para = run->para;
965 return FALSE;
966}
967
968/* Finds the run and offset from the pixel position.
969 *
970 * x & y are pixel positions in virtual coordinates into the rich edit control,
971 * so client coordinates must first be adjusted by the scroll position.
972 *
973 * If final_eop is TRUE consider the final end-of-paragraph.
974 *
975 * returns TRUE if the result was exactly under the cursor, otherwise returns
976 * FALSE, and result is set to the closest position to the coordinates.
977 */
979 ME_Cursor *result, BOOL final_eop )
980{
981 ME_Paragraph *para = editor_first_para( editor );
982 ME_Row *row = NULL, *next_row;
983 BOOL isExact = TRUE;
984
985 x -= editor->rcFormat.left;
986 y -= editor->rcFormat.top;
987
988 /* find paragraph */
989 for (; para_next( para ); para = para_next( para ))
990 {
991 if (y < para->pt.y + para->nHeight)
992 {
993 if (para->nFlags & MEPF_ROWSTART)
994 para = pixel_pos_in_table_row( x, y, para );
995 y -= para->pt.y;
996 row = para_first_row( para );
997 break;
998 }
999 else if (para->nFlags & MEPF_ROWSTART)
1000 {
1001 para = table_row_end( para );
1002 }
1003 }
1004 /* find row */
1005 while (row)
1006 {
1007 if (y < row->pt.y + row->nHeight) break;
1008 next_row = row_next( row );
1009 if (!next_row) break;
1010 row = next_row;
1011 }
1012
1013 if (!row && !final_eop && para_prev( para ))
1014 {
1015 /* The position is below the last paragraph, so the last row will be used
1016 * rather than the end of the text, so the x position will be used to
1017 * determine the offset closest to the pixel position. */
1018 isExact = FALSE;
1019 row = para_end_row( para_prev( para ) );
1020 }
1021
1022 if (row) return row_cursor( editor, row, x, result ) && isExact;
1023
1024 ME_SetCursorToEnd(editor, result, TRUE);
1025 return FALSE;
1026}
1027
1028
1029/* Sets the cursor to the position closest to the pixel position
1030 *
1031 * x & y are pixel positions in client coordinates.
1032 *
1033 * isExact will be set to TRUE if the run is directly under the pixel
1034 * position, FALSE if it not, unless isExact is set to NULL.
1035 *
1036 * return FALSE if outside client area and the cursor is not set,
1037 * otherwise TRUE is returned.
1038 */
1040 ME_Cursor *cursor, BOOL *isExact)
1041{
1042 RECT rc;
1043 BOOL bResult;
1044
1045 ITextHost_TxGetClientRect(editor->texthost, &rc);
1046 if (x < 0 || y < 0 || x >= rc.right || y >= rc.bottom) {
1047 if (isExact) *isExact = FALSE;
1048 return FALSE;
1049 }
1050 x += editor->horz_si.nPos;
1051 y += editor->vert_si.nPos;
1052 bResult = cursor_from_virtual_coords( editor, x, y, cursor, FALSE );
1053 if (isExact) *isExact = bResult;
1054 return TRUE;
1055}
1056
1057
1058
1059/* Extends the selection with a word, line, or paragraph selection type.
1060 *
1061 * The selection is anchored by editor->pCursors[2-3] such that the text
1062 * between the anchors will remain selected, and one end will be extended.
1063 *
1064 * editor->pCursors[0] should have the position to extend the selection to
1065 * before this function is called.
1066 *
1067 * Nothing will be done if editor->nSelectionType equals stPosition.
1068 */
1070{
1071 ME_Cursor tmp_cursor;
1072 int curOfs, anchorStartOfs, anchorEndOfs;
1073 if (editor->nSelectionType == stPosition || editor->nSelectionType == stDocument)
1074 return;
1075 curOfs = ME_GetCursorOfs(&editor->pCursors[0]);
1076 anchorStartOfs = ME_GetCursorOfs(&editor->pCursors[3]);
1077 anchorEndOfs = ME_GetCursorOfs(&editor->pCursors[2]);
1078
1079 tmp_cursor = editor->pCursors[0];
1080 editor->pCursors[0] = editor->pCursors[2];
1081 editor->pCursors[1] = editor->pCursors[3];
1082 if (curOfs < anchorStartOfs)
1083 {
1084 /* Extend the left side of selection */
1085 editor->pCursors[1] = tmp_cursor;
1086 switch (editor->nSelectionType)
1087 {
1088 case stWord:
1089 ME_MoveCursorWords(editor, &editor->pCursors[1], -1);
1090 break;
1091
1092 case stLine:
1093 {
1094 ME_Row *row = row_from_cursor( editor->pCursors + 1 );
1095 row_first_cursor( row, editor->pCursors + 1 );
1096 break;
1097 }
1098
1099 case stParagraph:
1100 editor->pCursors[1].run = para_first_run( editor->pCursors[1].para );
1101 editor->pCursors[1].nOffset = 0;
1102 break;
1103
1104 default:
1105 break;
1106 }
1107 }
1108 else if (curOfs >= anchorEndOfs)
1109 {
1110 /* Extend the right side of selection */
1111 editor->pCursors[0] = tmp_cursor;
1112 switch (editor->nSelectionType)
1113 {
1114 case stWord:
1115 ME_MoveCursorWords( editor, &editor->pCursors[0], +1 );
1116 break;
1117
1118 case stLine:
1119 {
1120 ME_Row *row = row_from_cursor( editor->pCursors );
1121 row_end_cursor( row, editor->pCursors, TRUE );
1122 break;
1123 }
1124
1125 case stParagraph:
1126 editor->pCursors[0].run = para_end_run( editor->pCursors[0].para );
1127 editor->pCursors[0].para = editor->pCursors[0].run->para;
1128 editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
1129 break;
1130
1131 default:
1132 break;
1133 }
1134 }
1135}
1136
1137void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
1138{
1139 ME_Cursor tmp_cursor;
1140 BOOL is_selection = FALSE, is_shift;
1141
1142 editor->nUDArrowX = -1;
1143
1144 x += editor->horz_si.nPos;
1145 y += editor->vert_si.nPos;
1146
1147 tmp_cursor = editor->pCursors[0];
1148 is_selection = ME_IsSelection(editor);
1149 is_shift = GetKeyState(VK_SHIFT) < 0;
1150
1151 cursor_from_virtual_coords( editor, x, y, &editor->pCursors[0], FALSE );
1152
1153 if (x >= editor->rcFormat.left || is_shift)
1154 {
1155 if (clickNum > 1)
1156 {
1157 editor->pCursors[1] = editor->pCursors[0];
1158 if (is_shift) {
1159 if (x >= editor->rcFormat.left)
1160 ME_SelectByType(editor, stWord);
1161 else
1163 } else if (clickNum % 2 == 0) {
1164 ME_SelectByType(editor, stWord);
1165 } else {
1167 }
1168 }
1169 else if (!is_shift)
1170 {
1171 editor->nSelectionType = stPosition;
1172 editor->pCursors[1] = editor->pCursors[0];
1173 }
1174 else if (!is_selection)
1175 {
1176 editor->nSelectionType = stPosition;
1177 editor->pCursors[1] = tmp_cursor;
1178 }
1179 else if (editor->nSelectionType != stPosition)
1180 {
1182 }
1183 }
1184 else
1185 {
1186 if (clickNum < 2) {
1187 ME_SelectByType(editor, stLine);
1188 } else if (clickNum % 2 == 0 || is_shift) {
1190 } else {
1191 ME_SelectByType(editor, stDocument);
1192 }
1193 }
1194 ME_InvalidateSelection(editor);
1195 update_caret(editor);
1196 ME_SendSelChange(editor);
1197}
1198
1199void ME_MouseMove(ME_TextEditor *editor, int x, int y)
1200{
1201 ME_Cursor tmp_cursor;
1202
1203 if (editor->nSelectionType == stDocument)
1204 return;
1205 x += editor->horz_si.nPos;
1206 y += editor->vert_si.nPos;
1207
1208 tmp_cursor = editor->pCursors[0];
1209 /* FIXME: do something with the return value of cursor_from_virtual_coords */
1210 cursor_from_virtual_coords( editor, x, y, &tmp_cursor, TRUE );
1211
1212 ME_InvalidateSelection(editor);
1213 editor->pCursors[0] = tmp_cursor;
1215
1216 if (editor->nSelectionType != stPosition &&
1217 memcmp(&editor->pCursors[1], &editor->pCursors[3], sizeof(ME_Cursor)))
1218 /* The scroll the cursor towards the other end, since it was the one
1219 * extended by ME_ExtendAnchorSelection */
1220 editor_ensure_visible( editor, &editor->pCursors[1] );
1221 else
1222 editor_ensure_visible( editor, &editor->pCursors[0] );
1223
1224 ME_InvalidateSelection(editor);
1225 update_caret(editor);
1226 ME_SendSelChange(editor);
1227}
1228
1229static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
1230{
1231 ME_Run *run = pCursor->run;
1232 int x;
1233
1234 if (editor->nUDArrowX != -1)
1235 x = editor->nUDArrowX;
1236 else
1237 {
1238 x = run->pt.x;
1239 x += ME_PointFromChar( editor, run, pCursor->nOffset, TRUE );
1240 editor->nUDArrowX = x;
1241 }
1242 return x;
1243}
1244
1245
1246static void cursor_move_line( ME_TextEditor *editor, ME_Cursor *cursor, BOOL up, BOOL extend )
1247{
1248 ME_Paragraph *old_para = cursor->para, *new_para;
1250 int x = ME_GetXForArrow( editor, cursor );
1251
1252 if (up)
1253 {
1254 /* start of the previous row */
1256 if (!row)
1257 {
1258 if (extend) ME_SetCursorToStart( editor, cursor );
1259 return;
1260 }
1261 new_para = row_para( row );
1262 if (old_para->nFlags & MEPF_ROWEND ||
1263 (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para )))
1264 {
1265 /* Brought out of a cell */
1266 new_para = para_prev( table_row_start( old_para ));
1267 if (!new_para) return; /* At the top, so don't go anywhere. */
1268 row = para_first_row( new_para );
1269 }
1270 if (new_para->nFlags & MEPF_ROWEND)
1271 {
1272 /* Brought into a table row */
1273 ME_Cell *cell = table_row_end_cell( new_para );
1274 while (x < cell->pt.x && cell_prev( cell ))
1275 cell = cell_prev( cell );
1276 if (cell_next( cell )) /* else - we are still at the end of the row */
1277 row = para_end_row( cell_end_para( cell ) );
1278 }
1279 }
1280 else
1281 {
1282 /* start of the next row */
1284 if (!row)
1285 {
1286 if (extend) ME_SetCursorToEnd( editor, cursor, TRUE );
1287 return;
1288 }
1289 new_para = row_para( row );
1290 if (old_para->nFlags & MEPF_ROWSTART ||
1291 (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para )))
1292 {
1293 /* Brought out of a cell */
1294 new_para = para_next( table_row_end( old_para ) );
1295 if (!para_next( new_para )) return; /* At the bottom, so don't go anywhere. */
1296 row = para_first_row( new_para );
1297 }
1298 if (new_para->nFlags & MEPF_ROWSTART)
1299 {
1300 /* Brought into a table row */
1301 ME_Cell *cell = table_row_first_cell( new_para );
1302 while (cell_next( cell ) && x >= cell_next( cell )->pt.x)
1303 cell = cell_next( cell );
1304 row = para_first_row( cell_first_para( cell ) );
1305 }
1306 }
1307 if (!row) return;
1308
1309 row_cursor( editor, row, x, cursor );
1310}
1311
1313{
1314 ME_Row *row = para_first_row( editor_first_para( editor ) ), *last_row;
1315 int x, yd, old_scroll_pos = editor->vert_si.nPos;
1316
1317 if (editor->vert_si.nPos < row->nHeight)
1318 {
1319 ME_SetCursorToStart( editor, cursor );
1320 /* Native clears seems to clear this x value on page up at the top
1321 * of the text, but not on page down at the end of the text.
1322 * Doesn't make sense, but we try to be bug for bug compatible. */
1323 editor->nUDArrowX = -1;
1324 }
1325 else
1326 {
1327 x = ME_GetXForArrow( editor, cursor );
1329
1330 ME_ScrollUp( editor, editor->sizeWindow.cy );
1331 /* Only move the cursor by the amount scrolled. */
1332 yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos;
1333 last_row = row;
1334
1335 while ((row = row_prev_all_paras( row )))
1336 {
1337 if (row_para( row )->pt.y + row->pt.y < yd) break;
1338 last_row = row;
1339 }
1340
1341 row_cursor( editor, last_row, x, cursor );
1342 }
1343}
1344
1346{
1347 ME_Row *row = para_end_row( para_prev( editor_end_para( editor ) ) ), *last_row;
1348 int x, yd, old_scroll_pos = editor->vert_si.nPos;
1349
1350 x = ME_GetXForArrow( editor, cursor );
1351
1352 if (editor->vert_si.nPos >= row_para( row )->pt.y + row->pt.y - editor->sizeWindow.cy)
1353 ME_SetCursorToEnd( editor, cursor, FALSE );
1354 else
1355 {
1357
1358 /* For native richedit controls:
1359 * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us
1360 * v4.1 can scroll past this position here. */
1361 ME_ScrollDown( editor, editor->sizeWindow.cy );
1362 /* Only move the cursor by the amount scrolled. */
1363 yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos;
1364 last_row = row;
1365
1366 while ((row = row_next_all_paras( row )))
1367 {
1368 if (row_para( row )->pt.y + row->pt.y >= yd) break;
1369 last_row = row;
1370 }
1371
1372 row_cursor( editor, last_row, x, cursor );
1373 }
1374}
1375
1377{
1379
1381}
1382
1383static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
1384{
1385 ME_SetCursorToStart(editor, pCursor);
1386}
1387
1389{
1391
1393}
1394
1395static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
1396{
1397 ME_SetCursorToEnd(editor, pCursor, FALSE);
1398}
1399
1401{
1402 return editor->pCursors[0].run != editor->pCursors[1].run ||
1403 editor->pCursors[0].nOffset != editor->pCursors[1].nOffset;
1404}
1405
1407{
1408 int from, to;
1409 int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
1410 int nEndCursor = nStartCursor ^ 1;
1411 ME_DeleteTextAtCursor(editor, nStartCursor, to - from);
1412 editor->pCursors[nEndCursor] = editor->pCursors[nStartCursor];
1413}
1414
1416{
1417 return style_get_insert_style( editor, editor->pCursors );
1418}
1419
1421{
1422 SELCHANGE sc;
1423
1424 sc.nmhdr.hwndFrom = NULL;
1425 sc.nmhdr.idFrom = 0;
1426 sc.nmhdr.code = EN_SELCHANGE;
1427 ME_GetSelectionOfs(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
1428 sc.seltyp = SEL_EMPTY;
1429 if (sc.chrg.cpMin != sc.chrg.cpMax)
1430 sc.seltyp |= SEL_TEXT;
1431 if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* what were RICHEDIT authors thinking ? */
1432 sc.seltyp |= SEL_MULTICHAR;
1433
1434 if (sc.chrg.cpMin != editor->notified_cr.cpMin || sc.chrg.cpMax != editor->notified_cr.cpMax)
1435 {
1436 ME_ClearTempStyle(editor);
1437
1438 editor->notified_cr = sc.chrg;
1439
1440 if (editor->nEventMask & ENM_SELCHANGE)
1441 {
1442 TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n",
1443 sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp,
1444 (sc.seltyp & SEL_TEXT) ? "SEL_TEXT" : "",
1445 (sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : "");
1446 ITextHost_TxNotify(editor->texthost, sc.nmhdr.code, &sc);
1447 }
1448 }
1449}
1450
1451BOOL
1452ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
1453{
1454 int nCursor = 0;
1455 ME_Cursor *p = &editor->pCursors[nCursor];
1456 ME_Cursor tmp_curs = *p;
1457 BOOL success = FALSE;
1458
1459 ME_CheckCharOffsets(editor);
1460 switch(nVKey) {
1461 case VK_LEFT:
1462 if (ctrl)
1463 success = ME_MoveCursorWords(editor, &tmp_curs, -1);
1464 else
1465 success = ME_MoveCursorChars(editor, &tmp_curs, -1, extend);
1466 break;
1467 case VK_RIGHT:
1468 if (ctrl)
1469 success = ME_MoveCursorWords(editor, &tmp_curs, +1);
1470 else
1471 success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend);
1472 break;
1473 case VK_UP:
1474 cursor_move_line( editor, &tmp_curs, TRUE, extend );
1475 break;
1476 case VK_DOWN:
1477 cursor_move_line( editor, &tmp_curs, FALSE, extend );
1478 break;
1479 case VK_PRIOR:
1480 ME_ArrowPageUp(editor, &tmp_curs);
1481 break;
1482 case VK_NEXT:
1483 ME_ArrowPageDown(editor, &tmp_curs);
1484 break;
1485 case VK_HOME: {
1486 if (ctrl)
1487 ME_ArrowCtrlHome(editor, &tmp_curs);
1488 else
1489 ME_ArrowHome(editor, &tmp_curs);
1490 break;
1491 }
1492 case VK_END:
1493 if (ctrl)
1494 ME_ArrowCtrlEnd(editor, &tmp_curs);
1495 else
1496 ME_ArrowEnd(editor, &tmp_curs);
1497 break;
1498 }
1499
1500 if (!extend)
1501 editor->pCursors[1] = tmp_curs;
1502 *p = tmp_curs;
1503
1504 ME_InvalidateSelection(editor);
1505 ME_Repaint(editor);
1506 hide_caret(editor);
1507 editor_ensure_visible( editor, &tmp_curs );
1508 update_caret(editor);
1509 ME_SendSelChange(editor);
1510 return success;
1511}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
Arabic default style
Definition: afstyles.h:94
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define E_INVALIDARG
Definition: ddrawi.h:101
DWORD HIMC
Definition: dimm.idl:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
Definition: ime.c:1744
BOOL WINAPI ImmIsIME(HKL hKL)
Definition: ime.c:880
BOOL WINAPI ImmSetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
Definition: ime.c:1583
HIMC WINAPI ImmGetContext(HWND hWnd)
Definition: imm.c:1045
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
Definition: imm.c:1086
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2144
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor)
Definition: caret.c:537
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:27
static void cursor_move_line(ME_TextEditor *editor, ME_Cursor *cursor, BOOL up, BOOL extend)
Definition: caret.c:1246
BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
Definition: caret.c:481
static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1376
BOOL ME_IsSelection(ME_TextEditor *editor)
Definition: caret.c:1400
void ME_DeleteSelection(ME_TextEditor *editor)
Definition: caret.c:1406
static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1229
static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
Definition: caret.c:1069
int ME_GetCursorOfs(const ME_Cursor *cursor)
Definition: caret.c:889
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style)
Definition: caret.c:553
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:678
static BOOL row_cursor(ME_TextEditor *editor, ME_Row *row, int x, ME_Cursor *cursor)
Definition: caret.c:933
static ME_Paragraph * pixel_pos_in_table_row(int x, int y, ME_Paragraph *para)
Definition: caret.c:895
BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
Definition: caret.c:758
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT *reo, int nCursor)
Definition: caret.c:503
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
Definition: caret.c:1137
int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
Definition: caret.c:91
int ME_GetSelection(ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to)
Definition: caret.c:57
BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nChars, BOOL bForce)
Definition: caret.c:339
void hide_caret(ME_TextEditor *editor)
Definition: caret.c:267
static void ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
Definition: caret.c:841
static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1395
void ME_MouseMove(ME_TextEditor *editor, int x, int y)
Definition: caret.c:1199
BOOL ME_CharFromPos(ME_TextEditor *editor, int x, int y, ME_Cursor *cursor, BOOL *isExact)
Definition: caret.c:1039
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1420
int set_selection_cursors(ME_TextEditor *editor, int from, int to)
Definition: caret.c:132
void cursor_coords(ME_TextEditor *editor, ME_Cursor *cursor, int *x, int *y, int *height)
Definition: caret.c:221
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
Definition: caret.c:42
BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
Definition: caret.c:1452
static BOOL cursor_from_virtual_coords(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL final_eop)
Definition: caret.c:978
static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop)
Definition: caret.c:34
void create_caret(ME_TextEditor *editor)
Definition: caret.c:251
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
void show_caret(ME_TextEditor *editor)
Definition: caret.c:261
static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1312
static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1345
void update_caret(ME_TextEditor *editor)
Definition: caret.c:277
static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
Definition: caret.c:1383
ME_Style * ME_GetSelectionInsertStyle(ME_TextEditor *editor)
Definition: caret.c:1415
static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:1388
static struct re_object * create_re_object(const REOBJECT *reo)
Definition: caret.c:490
void ME_DestroyContext(ME_Context *c)
Definition: context.c:44
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
Definition: context.c:23
ME_Paragraph * editor_first_para(ME_TextEditor *editor)
Definition: editor.c:279
ME_Paragraph * editor_end_para(ME_TextEditor *editor)
Definition: editor.c:285
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN
Definition: style.c:462
ME_Paragraph * cell_end_para(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:207
int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:608
ME_Run * para_first_run(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:104
BOOL add_undo_insert_run(ME_TextEditor *, int pos, const WCHAR *str, int len, int flags, ME_Style *style) DECLSPEC_HIDDEN
Definition: undo.c:131
void row_first_cursor(ME_Row *row, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: row.c:82
ME_Paragraph * para_join(ME_TextEditor *editor, ME_Paragraph *para, BOOL use_first_fmt) DECLSPEC_HIDDEN
Definition: para.c:683
void ME_CheckCharOffsets(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: run.c:173
ME_Cell * para_cell(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:127
void table_protect_partial_deletion(ME_TextEditor *editor, ME_Cursor *c, int *num_chars) DECLSPEC_HIDDEN
Definition: table.c:217
void editor_propagate_char_ofs(ME_Paragraph *para, ME_Run *run, int shift) DECLSPEC_HIDDEN
Definition: run.c:147
void cursor_from_char_ofs(ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:240
#define ITextHost_TxCreateCaret(This, a, b, c)
Definition: editor.h:341
ME_Row * para_first_row(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:132
void ME_DestroyDisplayItem(ME_DisplayItem *item) DECLSPEC_HIDDEN
Definition: list.c:115
ME_Row * para_end_row(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:141
ME_Style * style_get_insert_style(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: style.c:476
ME_Run * row_next_run(ME_Row *row, ME_Run *run) DECLSPEC_HIDDEN
Definition: row.c:63
#define ITextHost_TxNotify(This, a, b)
Definition: editor.h:368
ME_Paragraph * table_row_start(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:142
ME_Row * row_next(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:27
void para_mark_rewrap(ME_TextEditor *editor, ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:26
ME_Run * run_prev_all_paras(ME_Run *run) DECLSPEC_HIDDEN
Definition: run.c:110
#define ITextHost_TxSetCaretPos(This, a, b)
Definition: editor.h:343
ME_Paragraph * para_next(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:57
void editor_set_default_para_fmt(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN
Definition: para.c:960
static ME_DisplayItem * run_get_di(ME_Run *run)
Definition: editor.h:163
int ME_CallWordBreakProc(ME_TextEditor *editor, WCHAR *str, INT len, INT start, INT code) DECLSPEC_HIDDEN
Definition: string.c:204
ME_Row * row_from_cursor(ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: row.c:74
#define ITextHost_TxGetClientRect(This, a)
Definition: editor.h:354
ME_Run * run_next(ME_Run *run) DECLSPEC_HIDDEN
Definition: run.c:68
#define ITextHost_TxGetDC(This)
Definition: editor.h:333
ME_Cell * table_row_first_cell(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:170
void ME_ScrollUp(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN
Definition: paint.c:1127
void ME_InvalidateSelection(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:1247
ME_Paragraph * cell_first_para(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:202
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN
Definition: run.c:853
void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) DECLSPEC_HIDDEN
Definition: richole.c:5829
ME_Row * row_next_all_paras(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:36
ME_Cell * cell_next(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:192
#define ITextHost_TxReleaseDC(This, a)
Definition: editor.h:334
void ME_Remove(ME_DisplayItem *diWhere) DECLSPEC_HIDDEN
Definition: list.c:35
ME_Paragraph * para_split(ME_TextEditor *editor, ME_Run *run, ME_Style *style, const WCHAR *eol_str, int eol_len, int paraFlags) DECLSPEC_HIDDEN
Definition: para.c:540
void editor_ensure_visible(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: paint.c:1206
ME_Paragraph * para_prev(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:63
ME_Run * run_prev(ME_Run *run) DECLSPEC_HIDDEN
Definition: run.c:82
void ME_ClearTempStyle(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: style.c:507
ME_Cell * table_row_end_cell(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:178
void ME_StrDeleteV(ME_String *s, int nVChar, int nChars) DECLSPEC_HIDDEN
Definition: string.c:147
void ME_Repaint(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: paint.c:119
ME_Run * run_split(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:305
ME_Run * para_end_run(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:117
ME_Cell * cell_prev(ME_Cell *cell) DECLSPEC_HIDDEN
Definition: table.c:197
ME_Row * row_prev_all_paras(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:45
void row_end_cursor(ME_Row *row, ME_Cursor *cursor, BOOL include_eop) DECLSPEC_HIDDEN
Definition: row.c:92
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:42
void ME_ScrollDown(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN
Definition: paint.c:1132
ME_Run * row_first_run(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:54
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:649
ME_Run * run_insert(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, const WCHAR *str, int len, int flags) DECLSPEC_HIDDEN
Definition: run.c:375
#define ITextHost_TxShowCaret(This, a)
Definition: editor.h:342
ME_Paragraph * table_row_end(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: table.c:127
static const char * debugstr_run(const ME_Run *run)
Definition: editor.h:47
ME_Paragraph * row_para(ME_Row *row) DECLSPEC_HIDDEN
Definition: row.c:103
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, BOOL visual_order) DECLSPEC_HIDDEN
Definition: run.c:570
#define MERF_TAB
Definition: editstr.h:106
#define MERF_ENDPARA
Definition: editstr.h:121
#define MERF_GRAPHICS
Definition: editstr.h:104
#define MEPF_ROWSTART
Definition: editstr.h:143
#define MEPF_ROWEND
Definition: editstr.h:144
#define MEPF_REWRAP
Definition: editstr.h:140
ME_SelectionType
Definition: editstr.h:355
@ stWord
Definition: editstr.h:357
@ stParagraph
Definition: editstr.h:359
@ stPosition
Definition: editstr.h:356
@ stLine
Definition: editstr.h:358
@ stDocument
Definition: editstr.h:360
#define MERF_ENDROW
Definition: editstr.h:123
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
const GLubyte * c
Definition: glext.h:8905
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
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
#define up(mutex)
Definition: glue.h:30
const char cursor[]
Definition: icontest.c:13
#define CFS_RECT
Definition: imm.h:324
#define CFS_POINT
Definition: imm.h:325
#define c
Definition: ke_i.h:80
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
static UINT UINT last
Definition: font.c:45
#define shift
Definition: input.c:1755
#define ctrl
Definition: input.c:1756
#define min(a, b)
Definition: monoChain.cc:55
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
#define ES_MULTILINE
Definition: pedump.c:667
#define swap(a, b)
Definition: qsort.c:63
#define WB_MOVEWORDRIGHT
Definition: richedit.h:1002
#define SEL_EMPTY
Definition: richedit.h:822
#define GTL_CLOSE
Definition: richedit.h:1057
#define SEL_MULTICHAR
Definition: richedit.h:825
#define EN_SELCHANGE
Definition: richedit.h:193
#define GTL_NUMCHARS
Definition: richedit.h:1058
#define SEL_TEXT
Definition: richedit.h:823
#define ENM_SELCHANGE
Definition: richedit.h:478
#define CFM_CHARSET
Definition: richedit.h:358
#define CFM_SIZE
Definition: richedit.h:362
#define GTL_PRECISE
Definition: richedit.h:1056
#define PFM_TABLEROWDELIMITER
Definition: richedit.h:868
#define CFM_FACE
Definition: richedit.h:360
#define GTL_NUMBYTES
Definition: richedit.h:1059
#define WB_MOVEWORDLEFT
Definition: richedit.h:1000
#define PFE_TABLEROWDELIMITER
Definition: richedit.h:942
#define GTL_USECRLF
Definition: richedit.h:1055
const WCHAR * str
__WINE_SERVER_LIST_INLINE void list_add_after(struct list *elem, struct list *to_add)
Definition: list.h:78
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
RECT rcArea
Definition: dimm.idl:88
DWORD dwStyle
Definition: dimm.idl:86
POINT ptCurrentPos
Definition: dimm.idl:87
LONG lfHeight
Definition: dimm.idl:59
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
BYTE lfCharSet
Definition: dimm.idl:67
LONG cy
Definition: kdterminal.h:28
LONG cpMax
Definition: richedit.h:501
LONG cpMin
Definition: richedit.h:500
UINT MaxCharSize
Definition: winnls.h:583
DWORD dwMask
Definition: richedit.h:667
WORD wEffects
Definition: richedit.h:669
NMHDR nmhdr
Definition: richedit.h:685
WORD seltyp
Definition: richedit.h:687
CHARRANGE chrg
Definition: richedit.h:686
Definition: dsound.c:943
struct list entry
Definition: editstr.h:153
REOBJECT obj
Definition: editstr.h:154
ME_Paragraph * para
Definition: editstr.h:274
int nOffset
Definition: editstr.h:276
ME_Run * run
Definition: editstr.h:275
PARAFORMAT2 fmt
Definition: editstr.h:203
int nAscent
Definition: editstr.h:165
POINT pt
Definition: editstr.h:166
int nCharOfs
Definition: editstr.h:161
int nDescent
Definition: editstr.h:165
struct tagME_Paragraph * para
Definition: editstr.h:160
ME_Style * style
Definition: editstr.h:159
int nWidth
Definition: editstr.h:163
struct re_object * reobj
Definition: editstr.h:167
int nFlags
Definition: editstr.h:164
int len
Definition: editstr.h:162
SCROLLINFO vert_si
Definition: editstr.h:440
ITextHost2 * texthost
Definition: editstr.h:384
struct list reobj_list
Definition: editstr.h:450
ME_SelectionType nSelectionType
Definition: editstr.h:434
ME_Cursor * pCursors
Definition: editstr.h:389
SCROLLINFO horz_si
Definition: editstr.h:440
CHARRANGE notified_cr
Definition: editstr.h:437
BOOL caret_hidden
Definition: editstr.h:445
unsigned int bEmulateVersion10
Definition: editstr.h:385
UINT_PTR idFrom
Definition: winuser.h:3161
UINT code
Definition: winuser.h:3162
HWND hwndFrom
Definition: winuser.h:3160
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define TXTBIT_MULTILINE
Definition: textserv.h:186
static struct wctab tab[]
#define success(from, fromstr, to, tostr)
#define ZeroMemory
Definition: winbase.h:1737
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define LOGPIXELSY
Definition: wingdi.h:719
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define DEFAULT_CHARSET
Definition: wingdi.h:384
BOOL WINAPI DeleteDC(_In_ HDC)
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define WB_ISDELIMITER
Definition: winuser.h:549
#define VK_UP
Definition: winuser.h:2228
#define VK_NEXT
Definition: winuser.h:2224
#define VK_END
Definition: winuser.h:2225
#define VK_HOME
Definition: winuser.h:2226
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define VK_LEFT
Definition: winuser.h:2227
#define VK_RIGHT
Definition: winuser.h:2229
#define VK_DOWN
Definition: winuser.h:2230
#define VK_SHIFT
Definition: winuser.h:2205
#define VK_PRIOR
Definition: winuser.h:2223
SHORT WINAPI GetKeyState(_In_ int)
__wchar_t WCHAR
Definition: xmlstorage.h:180