ReactOS 0.4.16-dev-1405-gc14a14e
editor.c
Go to the documentation of this file.
1/*
2 * RichEdit - functions dealing with editor object
3 *
4 * Copyright 2004 by Krzysztof Foltman
5 * Copyright 2005 by Cihan Altinay
6 * Copyright 2005 by Phil Krylov
7 * Copyright 2008 Eric Pouech
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
24/*
25 API implementation status:
26
27 Messages (ANSI versions not done yet)
28 + EM_AUTOURLDETECT 2.0
29 + EM_CANPASTE
30 + EM_CANREDO 2.0
31 + EM_CANUNDO
32 + EM_CHARFROMPOS
33 - EM_DISPLAYBAND
34 + EM_EMPTYUNDOBUFFER
35 + EM_EXGETSEL
36 + EM_EXLIMITTEXT
37 + EM_EXLINEFROMCHAR
38 + EM_EXSETSEL
39 + EM_FINDTEXT (only FR_DOWN flag implemented)
40 + EM_FINDTEXTEX (only FR_DOWN flag implemented)
41 - EM_FINDWORDBREAK
42 - EM_FMTLINES
43 - EM_FORMATRANGE
44 + EM_GETAUTOURLDETECT 2.0
45 - EM_GETBIDIOPTIONS 3.0
46 - EM_GETCHARFORMAT (partly done)
47 - EM_GETEDITSTYLE
48 + EM_GETEVENTMASK
49 + EM_GETFIRSTVISIBLELINE (can be optimized if needed)
50 - EM_GETIMECOLOR 1.0asian
51 - EM_GETIMECOMPMODE 2.0
52 - EM_GETIMEOPTIONS 1.0asian
53 - EM_GETIMESTATUS
54 - EM_GETLANGOPTIONS 2.0
55 + EM_GETLIMITTEXT
56 + EM_GETLINE
57 + EM_GETLINECOUNT returns number of rows, not of paragraphs
58 + EM_GETMODIFY
59 + EM_GETOLEINTERFACE
60 + EM_GETOPTIONS
61 + EM_GETPARAFORMAT
62 + EM_GETPASSWORDCHAR 2.0
63 - EM_GETPUNCTUATION 1.0asian
64 + EM_GETRECT
65 - EM_GETREDONAME 2.0
66 + EM_GETSEL
67 + EM_GETSELTEXT (ANSI&Unicode)
68 + EM_GETSCROLLPOS 3.0
69! - EM_GETTHUMB
70 + EM_GETTEXTEX 2.0
71 + EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented)
72 + EM_GETTEXTMODE 2.0
73? + EM_GETTEXTRANGE (ANSI&Unicode)
74 - EM_GETTYPOGRAPHYOPTIONS 3.0
75 - EM_GETUNDONAME
76 + EM_GETWORDBREAKPROC
77 - EM_GETWORDBREAKPROCEX
78 - EM_GETWORDWRAPMODE 1.0asian
79 + EM_GETZOOM 3.0
80 + EM_HIDESELECTION
81 + EM_LIMITTEXT (Also called EM_SETLIMITTEXT)
82 + EM_LINEFROMCHAR
83 + EM_LINEINDEX
84 + EM_LINELENGTH
85 + EM_LINESCROLL
86 - EM_PASTESPECIAL
87 + EM_POSFROMCHAR
88 + EM_REDO 2.0
89 + EM_REQUESTRESIZE
90 + EM_REPLACESEL (proper style?) ANSI&Unicode
91 + EM_SCROLL
92 + EM_SCROLLCARET
93 + EM_SELECTIONTYPE
94 - EM_SETBIDIOPTIONS 3.0
95 + EM_SETBKGNDCOLOR
96 + EM_SETCHARFORMAT (partly done, no ANSI)
97 - EM_SETEDITSTYLE
98 + EM_SETEVENTMASK (few notifications supported)
99 + EM_SETFONTSIZE
100 - EM_SETIMECOLOR 1.0asian
101 - EM_SETIMEOPTIONS 1.0asian
102 - EM_SETIMESTATUS
103 - EM_SETLANGOPTIONS 2.0
104 - EM_SETLIMITTEXT
105 - EM_SETMARGINS
106 + EM_SETMODIFY (not sure if implementation is correct)
107 - EM_SETOLECALLBACK
108 + EM_SETOPTIONS (partially implemented)
109 - EM_SETPALETTE 2.0
110 + EM_SETPARAFORMAT
111 + EM_SETPASSWORDCHAR 2.0
112 - EM_SETPUNCTUATION 1.0asian
113 + EM_SETREADONLY no beep on modification attempt
114 + EM_SETRECT
115 + EM_SETRECTNP (EM_SETRECT without repainting)
116 + EM_SETSEL
117 + EM_SETSCROLLPOS 3.0
118 - EM_SETTABSTOPS 3.0
119 - EM_SETTARGETDEVICE (partial)
120 + EM_SETTEXTEX 3.0 (proper style?)
121 - EM_SETTEXTMODE 2.0
122 - EM_SETTYPOGRAPHYOPTIONS 3.0
123 + EM_SETUNDOLIMIT 2.0
124 + EM_SETWORDBREAKPROC (used only for word movement at the moment)
125 - EM_SETWORDBREAKPROCEX
126 - EM_SETWORDWRAPMODE 1.0asian
127 + EM_SETZOOM 3.0
128 + EM_SHOWSCROLLBAR 2.0
129 + EM_STOPGROUPTYPING 2.0
130 + EM_STREAMIN
131 + EM_STREAMOUT
132 + EM_UNDO
133 + WM_CHAR
134 + WM_CLEAR
135 + WM_COPY
136 + WM_CUT
137 + WM_GETDLGCODE (the current implementation is incomplete)
138 + WM_GETTEXT (ANSI&Unicode)
139 + WM_GETTEXTLENGTH (ANSI version sucks)
140 + WM_HSCROLL
141 + WM_PASTE
142 + WM_SETFONT
143 + WM_SETTEXT (resets undo stack !) (proper style?) ANSI&Unicode
144 + WM_STYLECHANGING (seems to do nothing)
145 + WM_STYLECHANGED (seems to do nothing)
146 + WM_UNICHAR
147 + WM_VSCROLL
148
149 Notifications
150
151 * EN_CHANGE (sent from the wrong place)
152 - EN_CORRECTTEXT
153 - EN_DROPFILES
154 - EN_ERRSPACE
155 - EN_HSCROLL
156 - EN_IMECHANGE
157 + EN_KILLFOCUS
158 - EN_LINK
159 - EN_MAXTEXT
160 - EN_MSGFILTER
161 - EN_OLEOPFAILED
162 - EN_PROTECTED
163 + EN_REQUESTRESIZE
164 - EN_SAVECLIPBOARD
165 + EN_SELCHANGE
166 + EN_SETFOCUS
167 - EN_STOPNOUNDO
168 * EN_UPDATE (sent from the wrong place)
169 - EN_VSCROLL
170
171 Styles
172
173 - ES_AUTOHSCROLL
174 - ES_AUTOVSCROLL
175 + ES_CENTER
176 + ES_DISABLENOSCROLL (scrollbar is always visible)
177 - ES_EX_NOCALLOLEINIT
178 + ES_LEFT
179 + ES_MULTILINE
180 - ES_NOIME
181 - ES_READONLY (I'm not sure if beeping is the proper behaviour)
182 + ES_RIGHT
183 - ES_SAVESEL
184 - ES_SELFIME
185 - ES_SUNKEN
186 - ES_VERTICAL
187 - ES_WANTRETURN (don't know how to do WM_GETDLGCODE part)
188 - WS_SETFONT
189 + WS_HSCROLL
190 + WS_VSCROLL
191*/
192
193/*
194 * RICHED20 TODO (incomplete):
195 *
196 * - messages/styles/notifications listed above
197 * - add remaining CHARFORMAT/PARAFORMAT fields
198 * - right/center align should strip spaces from the beginning
199 * - pictures/OLE objects (not just smiling faces that lack API support ;-) )
200 * - COM interface (looks like a major pain in the TODO list)
201 * - calculate heights of pictures (half-done)
202 * - hysteresis during wrapping (related to scrollbars appearing/disappearing)
203 * - find/replace
204 * - how to implement EM_FORMATRANGE and EM_DISPLAYBAND ? (Mission Impossible)
205 * - italic caret with italic fonts
206 * - IME
207 * - most notifications aren't sent at all (the most important ones are)
208 * - when should EN_SELCHANGE be sent after text change ? (before/after EN_UPDATE?)
209 * - WM_SETTEXT may use wrong style (but I'm 80% sure it's OK)
210 * - EM_GETCHARFORMAT with SCF_SELECTION may not behave 100% like in original (but very close)
211 * - full justification
212 * - hyphenation
213 * - tables
214 * - ListBox & ComboBox not implemented
215 *
216 * Bugs that are probably fixed, but not so easy to verify:
217 * - EN_UPDATE/EN_CHANGE are handled very incorrectly (should be OK now)
218 * - undo for ME_JoinParagraphs doesn't store paragraph format ? (it does)
219 * - check/fix artificial EOL logic (bCursorAtEnd, hardly logical)
220 * - caret shouldn't be displayed when selection isn't empty
221 * - check refcounting in style management functions (looks perfect now, but no bugs is suspicious)
222 * - undo for setting default format (done, might be buggy)
223 * - styles might be not released properly (looks like they work like charm, but who knows?
224 *
225 */
226
227#include "editor.h"
228#include "commdlg.h"
229#include "winreg.h"
230#define NO_SHLWAPI_STREAM
231#include "shlwapi.h"
232#include "rtf.h"
233#include "imm.h"
234#ifdef __REACTOS__
235 #include <immdev.h>
236 #include <imm32_undoc.h>
237#endif
238#include "res.h"
239
240#ifdef __REACTOS__
241#include <reactos/undocuser.h>
242#endif
243
244#define STACK_SIZE_DEFAULT 100
245#define STACK_SIZE_MAX 1000
246
247#define TEXT_LIMIT_DEFAULT 32767
248
250
251static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int nChars);
252
255
257 ME_TextBuffer *buf = malloc(sizeof(*buf));
260
261 p1->prev = NULL;
262 p1->next = p2;
263 p2->prev = p1;
264 p2->next = NULL;
265 p1->member.para.next_para = p2;
266 p2->member.para.prev_para = p1;
267 p2->member.para.nCharOfs = 0;
268
269 buf->pFirst = p1;
270 buf->pLast = p2;
271 buf->pCharStyle = NULL;
272
273 return buf;
274}
275
277{
278 return para_next( &editor->pBuffer->pFirst->member.para );
279}
280
281/* Note, returns the diTextEnd sentinel paragraph */
283{
284 return &editor->pBuffer->pLast->member.para;
285}
286
288{
289 return editor->props & TXTBIT_ALLOWBEEP && MessageBeep( type );
290}
291
293{
294 WCHAR *pText;
295 LRESULT total_bytes_read = 0;
296 BOOL is_read = FALSE;
297 DWORD cp = CP_ACP, copy = 0;
298 char conv_buf[4 + STREAMIN_BUFFER_SIZE]; /* up to 4 additional UTF-8 bytes */
299
300 static const char bom_utf8[] = {0xEF, 0xBB, 0xBF};
301
302 TRACE("%08lx %p\n", dwFormat, stream);
303
304 do {
305 LONG nWideChars = 0;
306 WCHAR wszText[STREAMIN_BUFFER_SIZE+1];
307
308 if (!stream->dwSize)
309 {
311 if (stream->editstream->dwError)
312 break;
313 if (!stream->dwSize)
314 break;
315 total_bytes_read += stream->dwSize;
316 }
317
318 if (!(dwFormat & SF_UNICODE))
319 {
320 char * buf = stream->buffer;
321 DWORD size = stream->dwSize, end;
322
323 if (!is_read)
324 {
325 is_read = TRUE;
326 if (stream->dwSize >= 3 && !memcmp(stream->buffer, bom_utf8, 3))
327 {
328 cp = CP_UTF8;
329 buf += 3;
330 size -= 3;
331 }
332 }
333
334 if (cp == CP_UTF8)
335 {
336 if (copy)
337 {
338 memcpy(conv_buf + copy, buf, size);
339 buf = conv_buf;
340 size += copy;
341 }
342 end = size;
343 while ((buf[end-1] & 0xC0) == 0x80)
344 {
345 --end;
346 --total_bytes_read; /* strange, but seems to match windows */
347 }
348 if (buf[end-1] & 0x80)
349 {
350 DWORD need = 0;
351 if ((buf[end-1] & 0xE0) == 0xC0)
352 need = 1;
353 if ((buf[end-1] & 0xF0) == 0xE0)
354 need = 2;
355 if ((buf[end-1] & 0xF8) == 0xF0)
356 need = 3;
357
358 if (size - end >= need)
359 {
360 /* we have enough bytes for this sequence */
361 end = size;
362 }
363 else
364 {
365 /* need more bytes, so don't transcode this sequence */
366 --end;
367 }
368 }
369 }
370 else
371 end = size;
372
373 nWideChars = MultiByteToWideChar(cp, 0, buf, end, wszText, STREAMIN_BUFFER_SIZE);
374 pText = wszText;
375
376 if (cp == CP_UTF8)
377 {
378 if (end != size)
379 {
380 memcpy(conv_buf, buf + end, size - end);
381 copy = size - end;
382 }
383 }
384 }
385 else
386 {
387 nWideChars = stream->dwSize >> 1;
388 pText = (WCHAR *)stream->buffer;
389 }
390
391 ME_InsertTextFromCursor(editor, 0, pText, nWideChars, style);
392 if (stream->dwSize == 0)
393 break;
394 stream->dwSize = 0;
395 } while(1);
396 return total_bytes_read;
397}
398
400 ME_BorderRect *borderRect,
401 RTFBorder *borderDef)
402{
403 int i, colorNum;
404 ME_Border *pBorders[] = {&borderRect->top,
405 &borderRect->left,
406 &borderRect->bottom,
407 &borderRect->right};
408 for (i = 0; i < 4; i++)
409 {
410 RTFColor *colorDef = info->colorList;
411 pBorders[i]->width = borderDef[i].width;
412 colorNum = borderDef[i].color;
413 while (colorDef && colorDef->rtfCNum != colorNum)
414 colorDef = colorDef->rtfNextColor;
415 if (colorDef)
416 pBorders[i]->colorRef = RGB(
417 colorDef->rtfCRed >= 0 ? colorDef->rtfCRed : 0,
418 colorDef->rtfCGreen >= 0 ? colorDef->rtfCGreen : 0,
419 colorDef->rtfCBlue >= 0 ? colorDef->rtfCBlue : 0);
420 else
421 pBorders[i]->colorRef = RGB(0, 0, 0);
422 }
423}
424
426{
428 fmt.cbSize = sizeof(fmt);
429 fmt.dwMask = 0;
430 fmt.dwEffects = 0;
431
432 switch(info->rtfMinor)
433 {
434 case rtfPlain:
435 /* FIXME add more flags once they're implemented */
438 fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
439 fmt.yHeight = 12*20; /* 12pt */
440 fmt.wWeight = FW_NORMAL;
441 fmt.bUnderlineType = CFU_UNDERLINE;
442 break;
443 case rtfBold:
444 fmt.dwMask = CFM_BOLD | CFM_WEIGHT;
445 fmt.dwEffects = info->rtfParam ? CFE_BOLD : 0;
446 fmt.wWeight = info->rtfParam ? FW_BOLD : FW_NORMAL;
447 break;
448 case rtfItalic:
449 fmt.dwMask = CFM_ITALIC;
450 fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
451 break;
452 case rtfUnderline:
454 fmt.bUnderlineType = CFU_UNDERLINE;
455 fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
456 break;
457 case rtfDotUnderline:
459 fmt.bUnderlineType = CFU_UNDERLINEDOTTED;
460 fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
461 break;
462 case rtfDbUnderline:
464 fmt.bUnderlineType = CFU_UNDERLINEDOUBLE;
465 fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
466 break;
467 case rtfWordUnderline:
469 fmt.bUnderlineType = CFU_UNDERLINEWORD;
470 fmt.dwEffects = info->rtfParam ? CFE_UNDERLINE : 0;
471 break;
472 case rtfNoUnderline:
473 fmt.dwMask = CFM_UNDERLINE;
474 fmt.dwEffects = 0;
475 break;
476 case rtfStrikeThru:
477 fmt.dwMask = CFM_STRIKEOUT;
478 fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
479 break;
480 case rtfSubScript:
481 case rtfSuperScript:
482 case rtfSubScrShrink:
484 case rtfNoSuperSub:
486 if (info->rtfMinor == rtfSubScrShrink) fmt.dwEffects = CFE_SUBSCRIPT;
487 if (info->rtfMinor == rtfSuperScrShrink) fmt.dwEffects = CFE_SUPERSCRIPT;
488 if (info->rtfMinor == rtfNoSuperSub) fmt.dwEffects = 0;
489 break;
490 case rtfInvisible:
491 fmt.dwMask = CFM_HIDDEN;
492 fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
493 break;
494 case rtfBackColor:
495 fmt.dwMask = CFM_BACKCOLOR;
496 fmt.dwEffects = 0;
497 if (info->rtfParam == 0)
498 fmt.dwEffects = CFE_AUTOBACKCOLOR;
499 else if (info->rtfParam != rtfNoParam)
500 {
501 RTFColor *c = RTFGetColor(info, info->rtfParam);
502 if (c && c->rtfCBlue >= 0)
503 fmt.crBackColor = (c->rtfCBlue<<16)|(c->rtfCGreen<<8)|(c->rtfCRed);
504 else
505 fmt.dwEffects = CFE_AUTOBACKCOLOR;
506 }
507 break;
508 case rtfForeColor:
509 fmt.dwMask = CFM_COLOR;
510 fmt.dwEffects = 0;
511 if (info->rtfParam == 0)
512 fmt.dwEffects = CFE_AUTOCOLOR;
513 else if (info->rtfParam != rtfNoParam)
514 {
515 RTFColor *c = RTFGetColor(info, info->rtfParam);
516 if (c && c->rtfCBlue >= 0)
517 fmt.crTextColor = (c->rtfCBlue<<16)|(c->rtfCGreen<<8)|(c->rtfCRed);
518 else {
519 fmt.dwEffects = CFE_AUTOCOLOR;
520 }
521 }
522 break;
523 case rtfFontNum:
524 if (info->rtfParam != rtfNoParam)
525 {
526 RTFFont *f = RTFGetFont(info, info->rtfParam);
527 if (f)
528 {
529 MultiByteToWideChar(CP_ACP, 0, f->rtfFName, -1, fmt.szFaceName, ARRAY_SIZE(fmt.szFaceName));
530 fmt.szFaceName[ARRAY_SIZE(fmt.szFaceName)-1] = '\0';
531 fmt.bCharSet = f->rtfFCharSet;
532 fmt.dwMask = CFM_FACE | CFM_CHARSET;
533 fmt.bPitchAndFamily = f->rtfFPitch | (f->rtfFFamily << 4);
534 }
535 }
536 break;
537 case rtfFontSize:
538 fmt.dwMask = CFM_SIZE;
539 if (info->rtfParam != rtfNoParam)
540 fmt.yHeight = info->rtfParam*10;
541 break;
542 }
543 if (fmt.dwMask) {
544 ME_Style *style2;
546 /* FIXME too slow ? how come ? */
547 style2 = ME_ApplyStyle(info->editor, info->style, &fmt);
548 ME_ReleaseStyle(info->style);
549 info->style = style2;
550 info->styleChanged = TRUE;
551 }
552}
553
554/* FIXME this function doesn't get any information about context of the RTF tag, which is very bad,
555 the same tags mean different things in different contexts */
557{
558 switch(info->rtfMinor)
559 {
560 case rtfParDef: /* restores default paragraph attributes */
561 if (!info->editor->bEmulateVersion10) /* v4.1 */
562 info->borderType = RTFBorderParaLeft;
563 else /* v1.0 - 3.0 */
564 info->borderType = RTFBorderParaTop;
569 /* TODO: shading */
570 info->fmt.wAlignment = PFA_LEFT;
571 info->fmt.cTabCount = 0;
572 info->fmt.dxOffset = info->fmt.dxStartIndent = info->fmt.dxRightIndent = 0;
573 info->fmt.wBorderWidth = info->fmt.wBorders = 0;
574 info->fmt.wBorderSpace = 0;
575 info->fmt.bLineSpacingRule = 0;
576 info->fmt.dySpaceBefore = info->fmt.dySpaceAfter = 0;
577 info->fmt.dyLineSpacing = 0;
578 info->fmt.wEffects &= ~PFE_RTLPARA;
579 info->fmt.wNumbering = 0;
580 info->fmt.wNumberingStart = 0;
581 info->fmt.wNumberingStyle = 0;
582 info->fmt.wNumberingTab = 0;
583
584 if (!info->editor->bEmulateVersion10) /* v4.1 */
585 {
586 if (info->tableDef && info->tableDef->row_start &&
587 info->tableDef->row_start->nFlags & MEPF_ROWEND)
588 {
590 ME_Paragraph *para;
591 /* We are just after a table row. */
593 cursor = info->editor->pCursors[0];
594 para = cursor.para;
595 if (para == para_next( info->tableDef->row_start )
596 && !cursor.nOffset && !cursor.run->nCharOfs)
597 {
598 /* Since the table row end, no text has been inserted, and the \intbl
599 * control word has not be used. We can confirm that we are not in a
600 * table anymore.
601 */
602 info->tableDef->row_start = NULL;
603 info->canInheritInTbl = FALSE;
604 }
605 }
606 }
607 else /* v1.0 - v3.0 */
608 {
609 info->fmt.dwMask |= PFM_TABLE;
610 info->fmt.wEffects &= ~PFE_TABLE;
611 }
612 break;
613 case rtfNestLevel:
614 if (!info->editor->bEmulateVersion10) /* v4.1 */
615 {
616 while (info->rtfParam > info->nestingLevel)
617 {
618 RTFTable *tableDef = calloc(1, sizeof(*tableDef));
619 tableDef->parent = info->tableDef;
620 info->tableDef = tableDef;
621
623 if (tableDef->row_start && tableDef->row_start->nFlags & MEPF_ROWEND)
624 {
625 ME_Paragraph *para = para_next( tableDef->row_start );
626 tableDef->row_start = table_insert_row_start_at_para( info->editor, para );
627 }
628 else
629 {
631 cursor = info->editor->pCursors[0];
632 if (cursor.nOffset || cursor.run->nCharOfs)
633 ME_InsertTextFromCursor(info->editor, 0, L"\r", 1, info->style);
634 tableDef->row_start = table_insert_row_start( info->editor, info->editor->pCursors );
635 }
636
637 info->nestingLevel++;
638 }
639 info->canInheritInTbl = FALSE;
640 }
641 break;
642 case rtfInTable:
643 {
644 if (!info->editor->bEmulateVersion10) /* v4.1 */
645 {
646 if (info->nestingLevel < 1)
647 {
648 RTFTable *tableDef;
649 ME_Paragraph *para;
650
651 if (!info->tableDef)
652 info->tableDef = calloc(1, sizeof(*info->tableDef));
653 tableDef = info->tableDef;
655 if (tableDef->row_start && tableDef->row_start->nFlags & MEPF_ROWEND)
656 para = para_next( tableDef->row_start );
657 else
658 para = info->editor->pCursors[0].para;
659
660 tableDef->row_start = table_insert_row_start_at_para( info->editor, para );
661
662 info->nestingLevel = 1;
663 info->canInheritInTbl = TRUE;
664 }
665 return;
666 } else { /* v1.0 - v3.0 */
667 info->fmt.dwMask |= PFM_TABLE;
668 info->fmt.wEffects |= PFE_TABLE;
669 }
670 break;
671 }
672 case rtfFirstIndent:
673 case rtfLeftIndent:
674 if ((info->fmt.dwMask & (PFM_STARTINDENT | PFM_OFFSET)) != (PFM_STARTINDENT | PFM_OFFSET))
675 {
677 fmt.cbSize = sizeof(fmt);
679 info->fmt.dwMask |= PFM_STARTINDENT | PFM_OFFSET;
680 info->fmt.dxStartIndent = fmt.dxStartIndent;
681 info->fmt.dxOffset = fmt.dxOffset;
682 }
683 if (info->rtfMinor == rtfFirstIndent)
684 {
685 info->fmt.dxStartIndent += info->fmt.dxOffset + info->rtfParam;
686 info->fmt.dxOffset = -info->rtfParam;
687 }
688 else
689 info->fmt.dxStartIndent = info->rtfParam - info->fmt.dxOffset;
690 break;
691 case rtfRightIndent:
692 info->fmt.dwMask |= PFM_RIGHTINDENT;
693 info->fmt.dxRightIndent = info->rtfParam;
694 break;
695 case rtfQuadLeft:
696 case rtfQuadJust:
697 info->fmt.dwMask |= PFM_ALIGNMENT;
698 info->fmt.wAlignment = PFA_LEFT;
699 break;
700 case rtfQuadRight:
701 info->fmt.dwMask |= PFM_ALIGNMENT;
702 info->fmt.wAlignment = PFA_RIGHT;
703 break;
704 case rtfQuadCenter:
705 info->fmt.dwMask |= PFM_ALIGNMENT;
706 info->fmt.wAlignment = PFA_CENTER;
707 break;
708 case rtfTabPos:
709 if (!(info->fmt.dwMask & PFM_TABSTOPS))
710 {
712 fmt.cbSize = sizeof(fmt);
714 memcpy(info->fmt.rgxTabs, fmt.rgxTabs,
715 fmt.cTabCount * sizeof(fmt.rgxTabs[0]));
716 info->fmt.cTabCount = fmt.cTabCount;
717 info->fmt.dwMask |= PFM_TABSTOPS;
718 }
719 if (info->fmt.cTabCount < MAX_TAB_STOPS && info->rtfParam < 0x1000000)
720 info->fmt.rgxTabs[info->fmt.cTabCount++] = info->rtfParam;
721 break;
722 case rtfKeep:
723 info->fmt.dwMask |= PFM_KEEP;
724 info->fmt.wEffects |= PFE_KEEP;
725 break;
727 info->fmt.dwMask |= PFM_NOWIDOWCONTROL;
728 info->fmt.wEffects |= PFE_NOWIDOWCONTROL;
729 break;
730 case rtfKeepNext:
731 info->fmt.dwMask |= PFM_KEEPNEXT;
732 info->fmt.wEffects |= PFE_KEEPNEXT;
733 break;
734 case rtfSpaceAfter:
735 info->fmt.dwMask |= PFM_SPACEAFTER;
736 info->fmt.dySpaceAfter = info->rtfParam;
737 break;
738 case rtfSpaceBefore:
739 info->fmt.dwMask |= PFM_SPACEBEFORE;
740 info->fmt.dySpaceBefore = info->rtfParam;
741 break;
742 case rtfSpaceBetween:
743 info->fmt.dwMask |= PFM_LINESPACING;
744 if ((int)info->rtfParam > 0)
745 {
746 info->fmt.dyLineSpacing = info->rtfParam;
747 info->fmt.bLineSpacingRule = 3;
748 }
749 else
750 {
751 info->fmt.dyLineSpacing = info->rtfParam;
752 info->fmt.bLineSpacingRule = 4;
753 }
754 break;
755 case rtfSpaceMultiply:
756 info->fmt.dwMask |= PFM_LINESPACING;
757 info->fmt.dyLineSpacing = info->rtfParam * 20;
758 info->fmt.bLineSpacingRule = 5;
759 break;
760 case rtfParBullet:
761 info->fmt.dwMask |= PFM_NUMBERING;
762 info->fmt.wNumbering = PFN_BULLET;
763 break;
764 case rtfParSimple:
765 info->fmt.dwMask |= PFM_NUMBERING;
766 info->fmt.wNumbering = 2; /* FIXME: MSDN says it's not used ?? */
767 break;
768 case rtfBorderLeft:
769 info->borderType = RTFBorderParaLeft;
770 info->fmt.wBorders |= 1;
771 info->fmt.dwMask |= PFM_BORDER;
772 break;
773 case rtfBorderRight:
774 info->borderType = RTFBorderParaRight;
775 info->fmt.wBorders |= 2;
776 info->fmt.dwMask |= PFM_BORDER;
777 break;
778 case rtfBorderTop:
779 info->borderType = RTFBorderParaTop;
780 info->fmt.wBorders |= 4;
781 info->fmt.dwMask |= PFM_BORDER;
782 break;
783 case rtfBorderBottom:
784 info->borderType = RTFBorderParaBottom;
785 info->fmt.wBorders |= 8;
786 info->fmt.dwMask |= PFM_BORDER;
787 break;
788 case rtfBorderSingle:
789 info->fmt.wBorders &= ~0x700;
790 info->fmt.wBorders |= 1 << 8;
791 info->fmt.dwMask |= PFM_BORDER;
792 break;
793 case rtfBorderThick:
794 info->fmt.wBorders &= ~0x700;
795 info->fmt.wBorders |= 2 << 8;
796 info->fmt.dwMask |= PFM_BORDER;
797 break;
798 case rtfBorderShadow:
799 info->fmt.wBorders &= ~0x700;
800 info->fmt.wBorders |= 10 << 8;
801 info->fmt.dwMask |= PFM_BORDER;
802 break;
803 case rtfBorderDouble:
804 info->fmt.wBorders &= ~0x700;
805 info->fmt.wBorders |= 7 << 8;
806 info->fmt.dwMask |= PFM_BORDER;
807 break;
808 case rtfBorderDot:
809 info->fmt.wBorders &= ~0x700;
810 info->fmt.wBorders |= 11 << 8;
811 info->fmt.dwMask |= PFM_BORDER;
812 break;
813 case rtfBorderWidth:
814 {
815 int borderSide = info->borderType & RTFBorderSideMask;
816 RTFTable *tableDef = info->tableDef;
817 if ((info->borderType & RTFBorderTypeMask) == RTFBorderTypeCell)
818 {
820 if (!tableDef || tableDef->numCellsDefined >= MAX_TABLE_CELLS)
821 break;
822 border = &tableDef->cells[tableDef->numCellsDefined].border[borderSide];
823 border->width = info->rtfParam;
824 break;
825 }
826 info->fmt.wBorderWidth = info->rtfParam;
827 info->fmt.dwMask |= PFM_BORDER;
828 break;
829 }
830 case rtfBorderSpace:
831 info->fmt.wBorderSpace = info->rtfParam;
832 info->fmt.dwMask |= PFM_BORDER;
833 break;
834 case rtfBorderColor:
835 {
836 RTFTable *tableDef = info->tableDef;
837 int borderSide = info->borderType & RTFBorderSideMask;
838 int borderType = info->borderType & RTFBorderTypeMask;
839 switch(borderType)
840 {
842 if (!info->editor->bEmulateVersion10) /* v4.1 */
843 break;
844 /* v1.0 - 3.0 treat paragraph and row borders the same. */
845 case RTFBorderTypeRow:
846 if (tableDef) {
847 tableDef->border[borderSide].color = info->rtfParam;
848 }
849 break;
851 if (tableDef && tableDef->numCellsDefined < MAX_TABLE_CELLS) {
852 tableDef->cells[tableDef->numCellsDefined].border[borderSide].color = info->rtfParam;
853 }
854 break;
855 }
856 break;
857 }
858 case rtfRTLPar:
859 info->fmt.dwMask |= PFM_RTLPARA;
860 info->fmt.wEffects |= PFE_RTLPARA;
861 break;
862 case rtfLTRPar:
863 info->fmt.dwMask |= PFM_RTLPARA;
864 info->fmt.wEffects &= ~PFE_RTLPARA;
865 break;
866 }
867}
868
870{
871 switch (info->rtfMinor)
872 {
873 case rtfRowDef:
874 {
875 if (!info->editor->bEmulateVersion10) /* v4.1 */
876 info->borderType = 0; /* Not sure */
877 else /* v1.0 - 3.0 */
878 info->borderType = RTFBorderRowTop;
879 if (!info->tableDef) {
880 info->tableDef = ME_MakeTableDef(info->editor);
881 } else {
882 ME_InitTableDef(info->editor, info->tableDef);
883 }
884 break;
885 }
886 case rtfCellPos:
887 {
888 int cellNum;
889 if (!info->tableDef)
890 {
891 info->tableDef = ME_MakeTableDef(info->editor);
892 }
893 cellNum = info->tableDef->numCellsDefined;
894 if (cellNum >= MAX_TABLE_CELLS)
895 break;
896 info->tableDef->cells[cellNum].rightBoundary = info->rtfParam;
897 if (cellNum < MAX_TAB_STOPS)
898 {
899 /* Tab stops were used to store cell positions before v4.1 but v4.1
900 * still seems to set the tabstops without using them. */
901 PARAFORMAT2 *fmt = &info->editor->pCursors[0].para->fmt;
902 fmt->rgxTabs[cellNum] &= ~0x00FFFFFF;
903 fmt->rgxTabs[cellNum] |= 0x00FFFFFF & info->rtfParam;
904 }
905 info->tableDef->numCellsDefined++;
906 break;
907 }
908 case rtfRowBordTop:
909 info->borderType = RTFBorderRowTop;
910 break;
911 case rtfRowBordLeft:
912 info->borderType = RTFBorderRowLeft;
913 break;
914 case rtfRowBordBottom:
915 info->borderType = RTFBorderRowBottom;
916 break;
917 case rtfRowBordRight:
918 info->borderType = RTFBorderRowRight;
919 break;
920 case rtfCellBordTop:
921 info->borderType = RTFBorderCellTop;
922 break;
923 case rtfCellBordLeft:
924 info->borderType = RTFBorderCellLeft;
925 break;
927 info->borderType = RTFBorderCellBottom;
928 break;
929 case rtfCellBordRight:
930 info->borderType = RTFBorderCellRight;
931 break;
932 case rtfRowGapH:
933 if (info->tableDef)
934 info->tableDef->gapH = info->rtfParam;
935 break;
936 case rtfRowLeftEdge:
937 if (info->tableDef)
938 info->tableDef->leftEdge = info->rtfParam;
939 break;
940 }
941}
942
944{
945 RTFTable *tableDef = info->tableDef;
946 switch (info->rtfMinor)
947 {
948 case rtfNestCell:
949 if (info->editor->bEmulateVersion10) /* v1.0 - v3.0 */
950 break;
951 /* else fall through since v4.1 treats rtfNestCell and rtfCell the same */
952 case rtfCell:
953 if (!tableDef)
954 break;
956 if (!info->editor->bEmulateVersion10) /* v4.1 */
957 {
958 if (tableDef->row_start)
959 {
960 if (!info->nestingLevel && tableDef->row_start->nFlags & MEPF_ROWEND)
961 {
962 ME_Paragraph *para = para_next( tableDef->row_start );
963 tableDef->row_start = table_insert_row_start_at_para( info->editor, para );
964 info->nestingLevel = 1;
965 }
966 table_insert_cell( info->editor, info->editor->pCursors );
967 }
968 }
969 else /* v1.0 - v3.0 */
970 {
971 ME_Paragraph *para = info->editor->pCursors[0].para;
972
973 if (para_in_table( para ) && tableDef->numCellsInserted < tableDef->numCellsDefined)
974 {
975 WCHAR tab = '\t';
976 ME_InsertTextFromCursor(info->editor, 0, &tab, 1, info->style);
977 tableDef->numCellsInserted++;
978 }
979 }
980 break;
981 case rtfNestRow:
982 if (info->editor->bEmulateVersion10) /* v1.0 - v3.0 */
983 break;
984 /* else fall through since v4.1 treats rtfNestRow and rtfRow the same */
985 case rtfRow:
986 {
987 ME_Run *run;
988 ME_Paragraph *para;
989 ME_Cell *cell;
990 int i;
991
992 if (!tableDef)
993 break;
995 if (!info->editor->bEmulateVersion10) /* v4.1 */
996 {
997 if (!tableDef->row_start) break;
998 if (!info->nestingLevel && tableDef->row_start->nFlags & MEPF_ROWEND)
999 {
1000 para = para_next( tableDef->row_start );
1001 tableDef->row_start = table_insert_row_start_at_para( info->editor, para );
1002 info->nestingLevel++;
1003 }
1004 para = tableDef->row_start;
1005 cell = table_row_first_cell( para );
1006 assert( cell && !cell_prev( cell ) );
1007 if (tableDef->numCellsDefined < 1)
1008 {
1009 /* 2000 twips appears to be the cell size that native richedit uses
1010 * when no cell sizes are specified. */
1011 const int default_size = 2000;
1012 int right_boundary = default_size;
1013 cell->nRightBoundary = right_boundary;
1014 while (cell_next( cell ))
1015 {
1016 cell = cell_next( cell );
1017 right_boundary += default_size;
1018 cell->nRightBoundary = right_boundary;
1019 }
1020 para = table_insert_cell( info->editor, info->editor->pCursors );
1021 cell = para_cell( para );
1022 cell->nRightBoundary = right_boundary;
1023 }
1024 else
1025 {
1026 for (i = 0; i < tableDef->numCellsDefined; i++)
1027 {
1028 RTFCell *cellDef = &tableDef->cells[i];
1029 cell->nRightBoundary = cellDef->rightBoundary;
1030 ME_ApplyBorderProperties( info, &cell->border, cellDef->border );
1031 cell = cell_next( cell );
1032 if (!cell)
1033 {
1034 para = table_insert_cell( info->editor, info->editor->pCursors );
1035 cell = para_cell( para );
1036 }
1037 }
1038 /* Cell for table row delimiter is empty */
1039 cell->nRightBoundary = tableDef->cells[i - 1].rightBoundary;
1040 }
1041
1042 run = para_first_run( cell_first_para( cell ) );
1043 if (info->editor->pCursors[0].run != run || info->editor->pCursors[0].nOffset)
1044 {
1045 int nOfs, nChars;
1046 /* Delete inserted cells that aren't defined. */
1047 info->editor->pCursors[1].run = run;
1048 info->editor->pCursors[1].para = run->para;
1049 info->editor->pCursors[1].nOffset = 0;
1050 nOfs = ME_GetCursorOfs(&info->editor->pCursors[1]);
1051 nChars = ME_GetCursorOfs(&info->editor->pCursors[0]) - nOfs;
1052 ME_InternalDeleteText(info->editor, &info->editor->pCursors[1],
1053 nChars, TRUE);
1054 }
1055
1056 para = table_insert_row_end( info->editor, info->editor->pCursors );
1057 para->fmt.dxOffset = abs(info->tableDef->gapH);
1058 para->fmt.dxStartIndent = info->tableDef->leftEdge;
1059 ME_ApplyBorderProperties( info, &para->border, tableDef->border );
1060 info->nestingLevel--;
1061 if (!info->nestingLevel)
1062 {
1063 if (info->canInheritInTbl) tableDef->row_start = para;
1064 else
1065 {
1066 while (info->tableDef)
1067 {
1068 tableDef = info->tableDef;
1069 info->tableDef = tableDef->parent;
1070 free(tableDef);
1071 }
1072 }
1073 }
1074 else
1075 {
1076 info->tableDef = tableDef->parent;
1077 free(tableDef);
1078 }
1079 }
1080 else /* v1.0 - v3.0 */
1081 {
1082 para = info->editor->pCursors[0].para;
1083 para->fmt.dxOffset = info->tableDef->gapH;
1084 para->fmt.dxStartIndent = info->tableDef->leftEdge;
1085
1086 ME_ApplyBorderProperties( info, &para->border, tableDef->border );
1087 while (tableDef->numCellsInserted < tableDef->numCellsDefined)
1088 {
1089 WCHAR tab = '\t';
1090 ME_InsertTextFromCursor(info->editor, 0, &tab, 1, info->style);
1091 tableDef->numCellsInserted++;
1092 }
1093 para->fmt.cTabCount = min(tableDef->numCellsDefined, MAX_TAB_STOPS);
1094 if (!tableDef->numCellsDefined) para->fmt.wEffects &= ~PFE_TABLE;
1095 ME_InsertTextFromCursor(info->editor, 0, L"\r", 1, info->style);
1096 tableDef->numCellsInserted = 0;
1097 }
1098 break;
1099 }
1100 case rtfTab:
1101 case rtfPar:
1102 if (info->editor->bEmulateVersion10) /* v1.0 - 3.0 */
1103 {
1104 ME_Paragraph *para;
1105
1107 para = info->editor->pCursors[0].para;
1108 if (para_in_table( para ))
1109 {
1110 /* rtfPar is treated like a space within a table. */
1111 info->rtfClass = rtfText;
1112 info->rtfMajor = ' ';
1113 }
1114 else if (info->rtfMinor == rtfPar && tableDef)
1115 tableDef->numCellsInserted = 0;
1116 }
1117 break;
1118 }
1119}
1120
1121static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HBITMAP hbmp,
1122 const SIZEL* sz)
1123{
1124 LPOLEOBJECT lpObject = NULL;
1125 LPSTORAGE lpStorage = NULL;
1126 LPOLECLIENTSITE lpClientSite = NULL;
1127 LPDATAOBJECT lpDataObject = NULL;
1128 LPOLECACHE lpOleCache = NULL;
1129 STGMEDIUM stgm;
1130 FORMATETC fm;
1131 CLSID clsid;
1132 HRESULT hr = E_FAIL;
1133 DWORD conn;
1134
1135 if (hemf)
1136 {
1137 stgm.tymed = TYMED_ENHMF;
1138 stgm.hEnhMetaFile = hemf;
1139 fm.cfFormat = CF_ENHMETAFILE;
1140 }
1141 else if (hbmp)
1142 {
1143 stgm.tymed = TYMED_GDI;
1144 stgm.hBitmap = hbmp;
1145 fm.cfFormat = CF_BITMAP;
1146 }
1147 else return E_FAIL;
1148
1149 stgm.pUnkForRelease = NULL;
1150
1151 fm.ptd = NULL;
1152 fm.dwAspect = DVASPECT_CONTENT;
1153 fm.lindex = -1;
1154 fm.tymed = stgm.tymed;
1155
1156 if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK &&
1157 IRichEditOle_GetClientSite(editor->richole, &lpClientSite) == S_OK &&
1158 IOleObject_SetClientSite(lpObject, lpClientSite) == S_OK &&
1159 IOleObject_GetUserClassID(lpObject, &clsid) == S_OK &&
1160 IOleObject_QueryInterface(lpObject, &IID_IOleCache, (void**)&lpOleCache) == S_OK &&
1161 IOleCache_Cache(lpOleCache, &fm, 0, &conn) == S_OK &&
1162 IOleObject_QueryInterface(lpObject, &IID_IDataObject, (void**)&lpDataObject) == S_OK &&
1163 IDataObject_SetData(lpDataObject, &fm, &stgm, TRUE) == S_OK)
1164 {
1165 REOBJECT reobject;
1166
1167 reobject.cbStruct = sizeof(reobject);
1168 reobject.cp = REO_CP_SELECTION;
1169 reobject.clsid = clsid;
1170 reobject.poleobj = lpObject;
1171 reobject.pstg = lpStorage;
1172 reobject.polesite = lpClientSite;
1173 /* convert from twips to .01 mm */
1174 reobject.sizel.cx = MulDiv(sz->cx, 254, 144);
1175 reobject.sizel.cy = MulDiv(sz->cy, 254, 144);
1176 reobject.dvaspect = DVASPECT_CONTENT;
1177 reobject.dwFlags = 0; /* FIXME */
1178 reobject.dwUser = 0;
1179
1180 hr = editor_insert_oleobj(editor, &reobject);
1181 }
1182
1183 if (lpObject) IOleObject_Release(lpObject);
1184 if (lpClientSite) IOleClientSite_Release(lpClientSite);
1185 if (lpStorage) IStorage_Release(lpStorage);
1186 if (lpDataObject) IDataObject_Release(lpDataObject);
1187 if (lpOleCache) IOleCache_Release(lpOleCache);
1188
1189 return hr;
1190}
1191
1193{
1194 int level = 1;
1195
1196 for (;;)
1197 {
1198 RTFGetToken (info);
1199
1200 if (info->rtfClass == rtfEOF) return;
1202 {
1203 if (--level == 0) break;
1204 }
1205 else if (RTFCheckCM( info, rtfGroup, rtfBeginGroup ))
1206 {
1207 level++;
1208 }
1209 else
1210 {
1213 level--;
1214 }
1215 }
1216
1217 RTFRouteToken( info ); /* feed "}" back to router */
1218 return;
1219}
1220
1222{
1223 DWORD read = 0, size = 1024;
1224 BYTE *buf, val;
1225 BOOL flip;
1226
1227 *out = NULL;
1228
1229 if (info->rtfClass != rtfText)
1230 {
1231 ERR("Called with incorrect token\n");
1232 return 0;
1233 }
1234
1235 buf = malloc(size);
1236 if (!buf) return 0;
1237
1238 val = info->rtfMajor;
1239 for (flip = TRUE;; flip = !flip)
1240 {
1241 RTFGetToken( info );
1242 if (info->rtfClass == rtfEOF)
1243 {
1244 free(buf);
1245 return 0;
1246 }
1247 if (info->rtfClass != rtfText) break;
1248 if (flip)
1249 {
1250 if (read >= size)
1251 {
1252 size *= 2;
1253 buf = realloc(buf, size);
1254 if (!buf) return 0;
1255 }
1256 buf[read++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor);
1257 }
1258 else
1259 val = info->rtfMajor;
1260 }
1261 if (flip) FIXME("wrong hex string\n");
1262
1263 *out = buf;
1264 return read;
1265}
1266
1268{
1269 SIZEL sz;
1270 BYTE *buffer = NULL;
1271 DWORD size = 0;
1272 METAFILEPICT mfp;
1273 HENHMETAFILE hemf;
1274 HBITMAP hbmp;
1275 enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
1276 int level = 1;
1277
1278 mfp.mm = MM_TEXT;
1279 sz.cx = sz.cy = 0;
1280
1281 for (;;)
1282 {
1283 RTFGetToken( info );
1284
1285 if (info->rtfClass == rtfText)
1286 {
1287 if (level == 1)
1288 {
1289 if (!buffer)
1291 }
1292 else
1293 {
1294 RTFSkipGroup( info );
1295 }
1296 } /* We potentially have a new token so fall through. */
1297
1298 if (info->rtfClass == rtfEOF) return;
1299
1301 {
1302 if (--level == 0) break;
1303 continue;
1304 }
1306 {
1307 level++;
1308 continue;
1309 }
1311 {
1314 level--;
1315 continue;
1316 }
1317
1319 {
1320 mfp.mm = info->rtfParam;
1321 gfx = gfx_metafile;
1322 }
1324 {
1325 if (info->rtfParam != 0) FIXME("dibitmap should be 0 (%d)\n", info->rtfParam);
1326 gfx = gfx_dib;
1327 }
1328 else if (RTFCheckMM( info, rtfPictAttr, rtfEmfBlip ))
1329 gfx = gfx_enhmetafile;
1330 else if (RTFCheckMM( info, rtfPictAttr, rtfPicWid ))
1331 mfp.xExt = info->rtfParam;
1332 else if (RTFCheckMM( info, rtfPictAttr, rtfPicHt ))
1333 mfp.yExt = info->rtfParam;
1335 sz.cx = info->rtfParam;
1337 sz.cy = info->rtfParam;
1338 else
1339 FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor);
1340 }
1341
1342 if (buffer)
1343 {
1344 switch (gfx)
1345 {
1346 case gfx_enhmetafile:
1347 if ((hemf = SetEnhMetaFileBits( size, buffer )))
1348 insert_static_object( info->editor, hemf, NULL, &sz );
1349 break;
1350 case gfx_metafile:
1351 if ((hemf = SetWinMetaFileBits( size, buffer, NULL, &mfp )))
1352 insert_static_object( info->editor, hemf, NULL, &sz );
1353 break;
1354 case gfx_dib:
1355 {
1357 HDC hdc = GetDC(0);
1358 unsigned nc = bi->bmiHeader.biClrUsed;
1359
1360 /* not quite right, especially for bitfields type of compression */
1361 if (!nc && bi->bmiHeader.biBitCount <= 8)
1362 nc = 1 << bi->bmiHeader.biBitCount;
1363 if ((hbmp = CreateDIBitmap( hdc, &bi->bmiHeader,
1364 CBM_INIT, (char*)(bi + 1) + nc * sizeof(RGBQUAD),
1365 bi, DIB_RGB_COLORS)) )
1366 insert_static_object( info->editor, NULL, hbmp, &sz );
1367 ReleaseDC( 0, hdc );
1368 break;
1369 }
1370 default:
1371 break;
1372 }
1373 }
1374 free( buffer );
1375 RTFRouteToken( info ); /* feed "}" back to router */
1376 return;
1377}
1378
1379/* for now, lookup the \result part and use it, whatever the object */
1381{
1382 for (;;)
1383 {
1384 RTFGetToken (info);
1385 if (info->rtfClass == rtfEOF)
1386 return;
1388 break;
1390 {
1391 RTFGetToken (info);
1392 if (info->rtfClass == rtfEOF)
1393 return;
1395 {
1396 int level = 1;
1397
1398 while (RTFGetToken (info) != rtfEOF)
1399 {
1400 if (info->rtfClass == rtfGroup)
1401 {
1402 if (info->rtfMajor == rtfBeginGroup) level++;
1403 else if (info->rtfMajor == rtfEndGroup && --level < 0) break;
1404 }
1406 }
1407 }
1408 else RTFSkipGroup(info);
1409 continue;
1410 }
1412 {
1413 FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor);
1414 return;
1415 }
1416 }
1417 RTFRouteToken(info); /* feed "}" back to router */
1418}
1419
1421{
1422 int level = 1, type = -1;
1423 WORD indent = 0, start = 1;
1424 WCHAR txt_before = 0, txt_after = 0;
1425
1426 for (;;)
1427 {
1428 RTFGetToken( info );
1429
1432 {
1433 int loc = info->rtfMinor;
1434
1435 RTFGetToken( info );
1436 if (info->rtfClass == rtfText)
1437 {
1438 if (loc == rtfParNumTextBefore)
1439 txt_before = info->rtfMajor;
1440 else
1441 txt_after = info->rtfMajor;
1442 continue;
1443 }
1444 /* falling through to catch EOFs and group level changes */
1445 }
1446
1447 if (info->rtfClass == rtfEOF)
1448 return;
1449
1451 {
1452 if (--level == 0) break;
1453 continue;
1454 }
1455
1457 {
1458 level++;
1459 continue;
1460 }
1461
1462 /* Ignore non para-attr */
1464 continue;
1465
1466 switch (info->rtfMinor)
1467 {
1468 case rtfParLevel: /* Para level is ignored */
1469 case rtfParSimple:
1470 break;
1471 case rtfParBullet:
1472 type = PFN_BULLET;
1473 break;
1474
1475 case rtfParNumDecimal:
1476 type = PFN_ARABIC;
1477 break;
1478 case rtfParNumULetter:
1480 break;
1481 case rtfParNumURoman:
1482 type = PFN_UCROMAN;
1483 break;
1484 case rtfParNumLLetter:
1486 break;
1487 case rtfParNumLRoman:
1488 type = PFN_LCROMAN;
1489 break;
1490
1491 case rtfParNumIndent:
1492 indent = info->rtfParam;
1493 break;
1494 case rtfParNumStartAt:
1495 start = info->rtfParam;
1496 break;
1497 }
1498 }
1499
1500 if (type != -1)
1501 {
1503 info->fmt.wNumbering = type;
1504 info->fmt.wNumberingStart = start;
1505 info->fmt.wNumberingStyle = PFNS_PAREN;
1506 if (type != PFN_BULLET)
1507 {
1508 if (txt_before == 0 && txt_after == 0)
1509 info->fmt.wNumberingStyle = PFNS_PLAIN;
1510 else if (txt_after == '.')
1511 info->fmt.wNumberingStyle = PFNS_PERIOD;
1512 else if (txt_before == '(' && txt_after == ')')
1513 info->fmt.wNumberingStyle = PFNS_PARENS;
1514 }
1515 info->fmt.wNumberingTab = indent;
1516 }
1517
1518 TRACE("type %d indent %d start %d txt before %04x txt after %04x\n",
1519 type, indent, start, txt_before, txt_after);
1520
1521 RTFRouteToken( info ); /* feed "}" back to router */
1522}
1523
1525{
1526 switch(info->rtfClass)
1527 {
1528 case rtfGroup:
1529 switch(info->rtfMajor)
1530 {
1531 case rtfBeginGroup:
1532 if (info->stackTop < maxStack) {
1533 info->stack[info->stackTop].style = info->style;
1534 ME_AddRefStyle(info->style);
1535 info->stack[info->stackTop].codePage = info->codePage;
1536 info->stack[info->stackTop].unicodeLength = info->unicodeLength;
1537 }
1538 info->stackTop++;
1539 info->styleChanged = FALSE;
1540 break;
1541 case rtfEndGroup:
1542 {
1544 info->stackTop--;
1545 if (info->stackTop <= 0)
1546 info->rtfClass = rtfEOF;
1547 if (info->stackTop < 0)
1548 return;
1549
1550 ME_ReleaseStyle(info->style);
1551 info->style = info->stack[info->stackTop].style;
1552 info->codePage = info->stack[info->stackTop].codePage;
1553 info->unicodeLength = info->stack[info->stackTop].unicodeLength;
1554 break;
1555 }
1556 }
1557 break;
1558 }
1559}
1560
1561void
1563{
1564 stream->editstream->dwError = stream->editstream->pfnCallback(stream->editstream->dwCookie,
1565 (BYTE *)stream->buffer,
1566 sizeof(stream->buffer),
1567 (LONG *)&stream->dwSize);
1568 stream->dwUsed = 0;
1569}
1570
1572{
1574 ME_Style *style;
1575 LONG from, to;
1576 int nUndoMode;
1577 int nEventMask = editor->nEventMask;
1578 ME_InStream inStream;
1579 BOOL invalidRTF = FALSE;
1580 ME_Cursor *selStart, *selEnd;
1581 LRESULT num_read = 0; /* bytes read for SF_TEXT, non-control chars inserted for SF_RTF */
1582
1583 TRACE("stream==%p editor==%p format==0x%lX\n", stream, editor, format);
1584 editor->nEventMask = 0;
1585
1586 ME_GetSelectionOfs(editor, &from, &to);
1587 if (format & SFF_SELECTION && editor->mode & TM_RICHTEXT)
1588 {
1589 ME_GetSelection(editor, &selStart, &selEnd);
1591
1592 ME_InternalDeleteText(editor, selStart, to - from, FALSE);
1593
1594 /* Don't insert text at the end of the table row */
1595 if (!editor->bEmulateVersion10) /* v4.1 */
1596 {
1597 ME_Paragraph *para = editor->pCursors->para;
1598 if (para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND))
1599 {
1600 para = para_next( para );
1601 editor->pCursors[0].para = para;
1602 editor->pCursors[0].run = para_first_run( para );
1603 editor->pCursors[0].nOffset = 0;
1604 }
1605 editor->pCursors[1] = editor->pCursors[0];
1606 }
1607 else /* v1.0 - 3.0 */
1608 {
1609 if (editor->pCursors[0].run->nFlags & MERF_ENDPARA &&
1610 para_in_table( editor->pCursors[0].para ))
1611 return 0;
1612 }
1613 }
1614 else
1615 {
1616 style = editor->pBuffer->pDefaultStyle;
1618 if (format & SFF_SELECTION)
1619 {
1620 ME_GetSelection(editor, &selStart, &selEnd);
1621 ME_InternalDeleteText(editor, selStart, to - from, FALSE);
1622 }
1623 else
1624 {
1625 set_selection_cursors(editor, 0, 0);
1626 ME_InternalDeleteText(editor, &editor->pCursors[1],
1627 ME_GetTextLength(editor), FALSE);
1628 }
1629 from = to = 0;
1630 ME_ClearTempStyle(editor);
1631 editor_set_default_para_fmt( editor, &editor->pCursors[0].para->fmt );
1632 }
1633
1634
1635 /* Back up undo mode to a local variable */
1636 nUndoMode = editor->nUndoMode;
1637
1638 /* Only create an undo if SFF_SELECTION is set */
1639 if (!(format & SFF_SELECTION))
1640 editor->nUndoMode = umIgnore;
1641
1642 inStream.editstream = stream;
1643 inStream.editstream->dwError = 0;
1644 inStream.dwSize = 0;
1645 inStream.dwUsed = 0;
1646
1647 if (format & SF_RTF)
1648 {
1649 /* Check if it's really RTF, and if it is not, use plain text */
1650 ME_StreamInFill(&inStream);
1651 if (!inStream.editstream->dwError)
1652 {
1653 if ((!editor->bEmulateVersion10 && strncmp(inStream.buffer, "{\\rtf", 5) && strncmp(inStream.buffer, "{\\urtf", 6))
1654 || (editor->bEmulateVersion10 && *inStream.buffer != '{'))
1655 {
1656 invalidRTF = TRUE;
1657 inStream.editstream->dwError = -16;
1658 }
1659 }
1660 }
1661
1662 if (!invalidRTF && !inStream.editstream->dwError)
1663 {
1665 from = ME_GetCursorOfs(&editor->pCursors[0]);
1666 if (format & SF_RTF) {
1667
1668 /* setup the RTF parser */
1669 memset(&parser, 0, sizeof parser);
1670 RTFSetEditStream(&parser, &inStream);
1671 parser.rtfFormat = format&(SF_TEXT|SF_RTF);
1672 parser.editor = editor;
1673 parser.style = style;
1675 RTFInit(&parser);
1681 if (!parser.editor->bEmulateVersion10) /* v4.1 */
1682 {
1685 }
1686 BeginFile(&parser);
1687
1688 /* do the parsing */
1689 RTFRead(&parser);
1691 if (!editor->bEmulateVersion10) /* v4.1 */
1692 {
1693 if (parser.tableDef && parser.tableDef->row_start &&
1694 (parser.nestingLevel > 0 || parser.canInheritInTbl))
1695 {
1696 /* Delete any incomplete table row at the end of the rich text. */
1697 int nOfs, nChars;
1698 ME_Paragraph *para;
1699
1700 parser.rtfMinor = rtfRow;
1701 /* Complete the table row before deleting it.
1702 * By doing it this way we will have the current paragraph format set
1703 * properly to reflect that is not in the complete table, and undo items
1704 * will be added for this change to the current paragraph format. */
1705 if (parser.nestingLevel > 0)
1706 {
1707 while (parser.nestingLevel > 1)
1708 ME_RTFSpecialCharHook(&parser); /* Decrements nestingLevel */
1709 para = parser.tableDef->row_start;
1711 }
1712 else
1713 {
1714 para = parser.tableDef->row_start;
1716 assert( para->nFlags & MEPF_ROWEND );
1717 para = para_next( para );
1718 }
1719
1720 editor->pCursors[1].para = para;
1721 editor->pCursors[1].run = para_first_run( para );
1722 editor->pCursors[1].nOffset = 0;
1723 nOfs = ME_GetCursorOfs(&editor->pCursors[1]);
1724 nChars = ME_GetCursorOfs(&editor->pCursors[0]) - nOfs;
1725 ME_InternalDeleteText(editor, &editor->pCursors[1], nChars, TRUE);
1726 if (parser.tableDef) parser.tableDef->row_start = NULL;
1727 }
1728 }
1730
1731 if (parser.stackTop > 0)
1732 {
1733 while (--parser.stackTop >= 0)
1734 {
1735 ME_ReleaseStyle(parser.style);
1736 parser.style = parser.stack[parser.stackTop].style;
1737 }
1738 if (!inStream.editstream->dwError)
1740 }
1741
1742 /* Remove last line break, as mandated by tests. This is not affected by
1743 CR/LF counters, since RTF streaming presents only \para tokens, which
1744 are converted according to the standard rules: \r for 2.0, \r\n for 1.0
1745 */
1746 if (stripLastCR && !(format & SFF_SELECTION)) {
1747 int newto;
1748 ME_GetSelection(editor, &selStart, &selEnd);
1749 newto = ME_GetCursorOfs(selEnd);
1750 if (newto > to + (editor->bEmulateVersion10 ? 1 : 0)) {
1751 WCHAR lastchar[3] = {'\0', '\0'};
1752 int linebreakSize = editor->bEmulateVersion10 ? 2 : 1;
1753 ME_Cursor linebreakCursor = *selEnd, lastcharCursor = *selEnd;
1755
1756 /* Set the final eop to the char fmt of the last char */
1757 cf.cbSize = sizeof(cf);
1758 cf.dwMask = CFM_ALL2;
1759 ME_MoveCursorChars(editor, &lastcharCursor, -1, FALSE);
1760 ME_GetCharFormat(editor, &lastcharCursor, &linebreakCursor, &cf);
1761 set_selection_cursors(editor, newto, -1);
1762 ME_SetSelectionCharFormat(editor, &cf);
1763 set_selection_cursors(editor, newto, newto);
1764
1765 ME_MoveCursorChars(editor, &linebreakCursor, -linebreakSize, FALSE);
1766 ME_GetTextW(editor, lastchar, 2, &linebreakCursor, linebreakSize, FALSE, FALSE);
1767 if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) {
1768 ME_InternalDeleteText(editor, &linebreakCursor, linebreakSize, FALSE);
1769 }
1770 }
1771 }
1772 to = ME_GetCursorOfs(&editor->pCursors[0]);
1773 num_read = to - from;
1774
1775 style = parser.style;
1776 }
1777 else if (format & SF_TEXT)
1778 {
1779 num_read = ME_StreamInText(editor, format, &inStream, style);
1780 to = ME_GetCursorOfs(&editor->pCursors[0]);
1781 }
1782 else
1783 ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n");
1784 /* put the cursor at the top */
1785 if (!(format & SFF_SELECTION))
1786 set_selection_cursors(editor, 0, 0);
1787 cursor_from_char_ofs( editor, from, &start );
1788 ME_UpdateLinkAttribute(editor, &start, to - from);
1789 }
1790
1791 /* Restore saved undo mode */
1792 editor->nUndoMode = nUndoMode;
1793
1794 /* even if we didn't add an undo, we need to commit anything on the stack */
1795 ME_CommitUndo(editor);
1796
1797 /* If SFF_SELECTION isn't set, delete any undos from before we started too */
1798 if (!(format & SFF_SELECTION))
1799 ME_EmptyUndoStack(editor);
1800
1802 editor->nEventMask = nEventMask;
1803 ME_UpdateRepaint(editor, FALSE);
1804 if (!(format & SFF_SELECTION)) {
1805 ME_ClearTempStyle(editor);
1806 }
1807 ME_SendSelChange(editor);
1808 ME_SendRequestResize(editor, FALSE);
1809
1810 return num_read;
1811}
1812
1813
1815{
1816 char *string;
1817 int pos;
1820
1822{
1824 int count;
1825
1826 count = min(cb, pStruct->length - pStruct->pos);
1827 memmove(lpBuff, pStruct->string + pStruct->pos, count);
1828 pStruct->pos += count;
1829 *pcb = count;
1830 return 0;
1831}
1832
1833static void
1835{
1836 EDITSTREAM es;
1838
1839 data.string = string;
1840 data.length = strlen(string);
1841 data.pos = 0;
1842 es.dwCookie = (DWORD_PTR)&data;
1843 es.pfnCallback = ME_ReadFromRTFString;
1844 ME_StreamIn(editor, SF_RTF | (selection ? SFF_SELECTION : 0), &es, TRUE);
1845}
1846
1847
1848static int
1849ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCHAR *text, CHARRANGE *chrgText)
1850{
1851 const int nLen = lstrlenW(text);
1852 const int nTextLen = ME_GetTextLength(editor);
1853 int nMin, nMax;
1855 WCHAR wLastChar = ' ';
1856
1857 TRACE("flags==0x%08lx, chrg->cpMin==%ld, chrg->cpMax==%ld text==%s\n",
1858 flags, chrg->cpMin, chrg->cpMax, debugstr_w(text));
1859
1861 FIXME("Flags 0x%08lx not implemented\n",
1863
1864 nMin = chrg->cpMin;
1865 if (chrg->cpMax == -1)
1866 nMax = nTextLen;
1867 else
1868 nMax = chrg->cpMax > nTextLen ? nTextLen : chrg->cpMax;
1869
1870 /* In 1.0 emulation, if cpMax reaches end of text, add the FR_DOWN flag */
1871 if (editor->bEmulateVersion10 && nMax == nTextLen)
1872 {
1873 flags |= FR_DOWN;
1874 }
1875
1876 /* In 1.0 emulation, cpMin must always be no greater than cpMax */
1877 if (editor->bEmulateVersion10 && nMax < nMin)
1878 {
1879 if (chrgText)
1880 {
1881 chrgText->cpMin = -1;
1882 chrgText->cpMax = -1;
1883 }
1884 return -1;
1885 }
1886
1887 /* when searching up, if cpMin < cpMax, then instead of searching
1888 * on [cpMin,cpMax], we search on [0,cpMin], otherwise, search on
1889 * [cpMax, cpMin]. The exception is when cpMax is -1, in which
1890 * case, it is always bigger than cpMin.
1891 */
1892 if (!editor->bEmulateVersion10 && !(flags & FR_DOWN))
1893 {
1894 int nSwap = nMax;
1895
1896 nMax = nMin > nTextLen ? nTextLen : nMin;
1897 if (nMin < nSwap || chrg->cpMax == -1)
1898 nMin = 0;
1899 else
1900 nMin = nSwap;
1901 }
1902
1903 if (!nLen || nMin < 0 || nMax < 0 || nMax < nMin)
1904 {
1905 if (chrgText)
1906 chrgText->cpMin = chrgText->cpMax = -1;
1907 return -1;
1908 }
1909
1910 if (flags & FR_DOWN) /* Forward search */
1911 {
1912 /* If possible, find the character before where the search starts */
1913 if ((flags & FR_WHOLEWORD) && nMin)
1914 {
1915 cursor_from_char_ofs( editor, nMin - 1, &cursor );
1916 wLastChar = *get_text( cursor.run, cursor.nOffset );
1917 ME_MoveCursorChars(editor, &cursor, 1, FALSE);
1918 }
1919 else cursor_from_char_ofs( editor, nMin, &cursor );
1920
1921 while (cursor.run && ME_GetCursorOfs(&cursor) + nLen <= nMax)
1922 {
1923 ME_Run *run = cursor.run;
1924 int nCurStart = cursor.nOffset;
1925 int nMatched = 0;
1926
1927 while (run && ME_CharCompare( *get_text( run, nCurStart + nMatched ), text[nMatched], (flags & FR_MATCHCASE)))
1928 {
1929 if ((flags & FR_WHOLEWORD) && iswalnum(wLastChar))
1930 break;
1931
1932 nMatched++;
1933 if (nMatched == nLen)
1934 {
1935 ME_Run *next_run = run;
1936 int nNextStart = nCurStart;
1937 WCHAR wNextChar;
1938
1939 /* Check to see if next character is a whitespace */
1940 if (flags & FR_WHOLEWORD)
1941 {
1942 if (nCurStart + nMatched == run->len)
1943 {
1944 next_run = run_next_all_paras( run );
1945 nNextStart = -nMatched;
1946 }
1947
1948 if (next_run)
1949 wNextChar = *get_text( next_run, nNextStart + nMatched );
1950 else
1951 wNextChar = ' ';
1952
1953 if (iswalnum(wNextChar))
1954 break;
1955 }
1956
1957 cursor.nOffset += cursor.para->nCharOfs + cursor.run->nCharOfs;
1958 if (chrgText)
1959 {
1960 chrgText->cpMin = cursor.nOffset;
1961 chrgText->cpMax = cursor.nOffset + nLen;
1962 }
1963 TRACE("found at %d-%d\n", cursor.nOffset, cursor.nOffset + nLen);
1964 return cursor.nOffset;
1965 }
1966 if (nCurStart + nMatched == run->len)
1967 {
1968 run = run_next_all_paras( run );
1969 nCurStart = -nMatched;
1970 }
1971 }
1972 if (run)
1973 wLastChar = *get_text( run, nCurStart + nMatched );
1974 else
1975 wLastChar = ' ';
1976
1977 cursor.nOffset++;
1978 if (cursor.nOffset == cursor.run->len)
1979 {
1980 if (run_next_all_paras( cursor.run ))
1981 {
1982 cursor.run = run_next_all_paras( cursor.run );
1983 cursor.para = cursor.run->para;
1984 cursor.nOffset = 0;
1985 }
1986 else
1987 cursor.run = NULL;
1988 }
1989 }
1990 }
1991 else /* Backward search */
1992 {
1993 /* If possible, find the character after where the search ends */
1994 if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1)
1995 {
1996 cursor_from_char_ofs( editor, nMax + 1, &cursor );
1997 wLastChar = *get_text( cursor.run, cursor.nOffset );
1998 ME_MoveCursorChars(editor, &cursor, -1, FALSE);
1999 }
2000 else cursor_from_char_ofs( editor, nMax, &cursor );
2001
2002 while (cursor.run && ME_GetCursorOfs(&cursor) - nLen >= nMin)
2003 {
2004 ME_Run *run = cursor.run;
2005 ME_Paragraph *para = cursor.para;
2006 int nCurEnd = cursor.nOffset;
2007 int nMatched = 0;
2008
2009 if (nCurEnd == 0 && run_prev_all_paras( run ))
2010 {
2011 run = run_prev_all_paras( run );
2012 para = run->para;
2013 nCurEnd = run->len;
2014 }
2015
2016 while (run && ME_CharCompare( *get_text( run, nCurEnd - nMatched - 1 ),
2017 text[nLen - nMatched - 1], (flags & FR_MATCHCASE) ))
2018 {
2019 if ((flags & FR_WHOLEWORD) && iswalnum(wLastChar))
2020 break;
2021
2022 nMatched++;
2023 if (nMatched == nLen)
2024 {
2025 ME_Run *prev_run = run;
2026 int nPrevEnd = nCurEnd;
2027 WCHAR wPrevChar;
2028 int nStart;
2029
2030 /* Check to see if previous character is a whitespace */
2031 if (flags & FR_WHOLEWORD)
2032 {
2033 if (nPrevEnd - nMatched == 0)
2034 {
2035 prev_run = run_prev_all_paras( run );
2036 if (prev_run) nPrevEnd = prev_run->len + nMatched;
2037 }
2038
2039 if (prev_run) wPrevChar = *get_text( prev_run, nPrevEnd - nMatched - 1 );
2040 else wPrevChar = ' ';
2041
2042 if (iswalnum(wPrevChar))
2043 break;
2044 }
2045
2046 nStart = para->nCharOfs + run->nCharOfs + nCurEnd - nMatched;
2047 if (chrgText)
2048 {
2049 chrgText->cpMin = nStart;
2050 chrgText->cpMax = nStart + nLen;
2051 }
2052 TRACE("found at %d-%d\n", nStart, nStart + nLen);
2053 return nStart;
2054 }
2055 if (nCurEnd - nMatched == 0)
2056 {
2057 if (run_prev_all_paras( run ))
2058 {
2059 run = run_prev_all_paras( run );
2060 para = run->para;
2061 }
2062 /* Don't care about pCurItem becoming NULL here; it's already taken
2063 * care of in the exterior loop condition */
2064 nCurEnd = run->len + nMatched;
2065 }
2066 }
2067 if (run)
2068 wLastChar = *get_text( run, nCurEnd - nMatched - 1 );
2069 else
2070 wLastChar = ' ';
2071
2072 cursor.nOffset--;
2073 if (cursor.nOffset < 0)
2074 {
2075 if (run_prev_all_paras( cursor.run ) )
2076 {
2077 cursor.run = run_prev_all_paras( cursor.run );
2078 cursor.para = cursor.run->para;
2079 cursor.nOffset = cursor.run->len;
2080 }
2081 else
2082 cursor.run = NULL;
2083 }
2084 }
2085 }
2086 TRACE("not found\n");
2087 if (chrgText)
2088 chrgText->cpMin = chrgText->cpMax = -1;
2089 return -1;
2090}
2091
2093{
2094 int nChars;
2096
2097 if (!ex->cb || !pText) return 0;
2098
2099 if (ex->flags & ~(GT_SELECTION | GT_USECRLF))
2100 FIXME("GETTEXTEX flags 0x%08lx not supported\n", ex->flags & ~(GT_SELECTION | GT_USECRLF));
2101
2102 if (ex->flags & GT_SELECTION)
2103 {
2104 LONG from, to;
2105 int nStartCur = ME_GetSelectionOfs(editor, &from, &to);
2106 start = editor->pCursors[nStartCur];
2107 nChars = to - from;
2108 }
2109 else
2110 {
2111 ME_SetCursorToStart(editor, &start);
2112 nChars = INT_MAX;
2113 }
2114 if (ex->codepage == CP_UNICODE)
2115 {
2116 return ME_GetTextW(editor, (LPWSTR)pText, ex->cb / sizeof(WCHAR) - 1,
2117 &start, nChars, ex->flags & GT_USECRLF, FALSE);
2118 }
2119 else
2120 {
2121 /* potentially each char may be a CR, why calculate the exact value with O(N) when
2122 we can just take a bigger buffer? :)
2123 The above assumption still holds with CR/LF counters, since CR->CRLF expansion
2124 occurs only in richedit 2.0 mode, in which line breaks have only one CR
2125 */
2126 int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
2127 DWORD buflen;
2128 LPWSTR buffer;
2129 LRESULT rc;
2130
2131 buflen = min(crlfmul * nChars, ex->cb - 1);
2132 buffer = malloc((buflen + 1) * sizeof(WCHAR));
2133
2134 nChars = ME_GetTextW(editor, buffer, buflen, &start, nChars, ex->flags & GT_USECRLF, FALSE);
2135 rc = WideCharToMultiByte(ex->codepage, 0, buffer, nChars + 1,
2136 (LPSTR)pText, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
2137 if (rc) rc--; /* do not count 0 terminator */
2138
2139 free(buffer);
2140 return rc;
2141 }
2142}
2143
2145 const ME_Cursor *start, int len )
2146{
2147 if (!buffer) return 0;
2148 return ME_GetTextW( editor, buffer, INT_MAX, start, len, FALSE, FALSE );
2149}
2150
2151int set_selection( ME_TextEditor *editor, int to, int from )
2152{
2153 int end;
2154
2155 TRACE("%d - %d\n", to, from );
2156
2157 if (!editor->bHideSelection) ME_InvalidateSelection( editor );
2158 end = set_selection_cursors( editor, to, from );
2159 editor_ensure_visible( editor, &editor->pCursors[0] );
2160 if (!editor->bHideSelection) ME_InvalidateSelection( editor );
2161 update_caret( editor );
2162 ME_Repaint( editor );
2163 ME_SendSelChange( editor );
2164
2165 return end;
2166}
2167
2168typedef struct tagME_GlobalDestStruct
2169{
2170 HGLOBAL hData;
2171 int nLength;
2173
2175{
2177 int i;
2178 WORD *pSrc, *pDest;
2179
2180 cb = cb >> 1;
2181 pDest = (WORD *)lpBuff;
2182 pSrc = GlobalLock(pData->hData);
2183 for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
2184 pDest[i] = pSrc[pData->nLength+i];
2185 }
2186 pData->nLength += i;
2187 *pcb = 2*i;
2188 GlobalUnlock(pData->hData);
2189 return 0;
2190}
2191
2193{
2195 int i;
2196 BYTE *pSrc, *pDest;
2197
2198 pDest = lpBuff;
2199 pSrc = GlobalLock(pData->hData);
2200 for (i = 0; i<cb && pSrc[pData->nLength+i]; i++) {
2201 pDest[i] = pSrc[pData->nLength+i];
2202 }
2203 pData->nLength += i;
2204 *pcb = i;
2205 GlobalUnlock(pData->hData);
2206 return 0;
2207}
2208
2209static HRESULT paste_rtf(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med)
2210{
2211 EDITSTREAM es;
2213 HRESULT hr;
2214
2215 gds.hData = med->hGlobal;
2216 gds.nLength = 0;
2217 es.dwCookie = (DWORD_PTR)&gds;
2218 es.pfnCallback = ME_ReadFromHGLOBALRTF;
2219 hr = ME_StreamIn( editor, SF_RTF | SFF_SELECTION, &es, FALSE ) == 0 ? E_FAIL : S_OK;
2220 ReleaseStgMedium( med );
2221 return hr;
2222}
2223
2224static HRESULT paste_text(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med)
2225{
2226 EDITSTREAM es;
2228 HRESULT hr;
2229
2230 gds.hData = med->hGlobal;
2231 gds.nLength = 0;
2232 es.dwCookie = (DWORD_PTR)&gds;
2233 es.pfnCallback = ME_ReadFromHGLOBALUnicode;
2234 hr = ME_StreamIn( editor, SF_TEXT | SF_UNICODE | SFF_SELECTION, &es, FALSE ) == 0 ? E_FAIL : S_OK;
2235 ReleaseStgMedium( med );
2236 return hr;
2237}
2238
2239static HRESULT paste_emf(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med)
2240{
2241 HRESULT hr;
2242 SIZEL sz = {0, 0};
2243
2244 hr = insert_static_object( editor, med->hEnhMetaFile, NULL, &sz );
2245 if (SUCCEEDED(hr))
2246 {
2247 ME_CommitUndo( editor );
2248 ME_UpdateRepaint( editor, FALSE );
2249 }
2250 else
2251 ReleaseStgMedium( med );
2252
2253 return hr;
2254}
2255
2256static struct paste_format
2257{
2258 FORMATETC fmt;
2259 HRESULT (*paste)(ME_TextEditor *, FORMATETC *, STGMEDIUM *);
2260 const WCHAR *name;
2261} paste_formats[] =
2262{
2263 {{ -1, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_rtf, L"Rich Text Format" },
2264 {{ CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_text },
2265 {{ CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF }, paste_emf },
2266 {{ 0 }}
2268
2269static void init_paste_formats(void)
2270{
2271 struct paste_format *format;
2272 static int done;
2273
2274 if (!done)
2275 {
2276 for (format = paste_formats; format->fmt.cfFormat; format++)
2277 {
2278 if (format->name)
2279 format->fmt.cfFormat = RegisterClipboardFormatW( format->name );
2280 }
2281 done = 1;
2282 }
2283}
2284
2285static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BOOL check_only)
2286{
2287 HRESULT hr;
2288 STGMEDIUM med;
2289 struct paste_format *format;
2291
2292 /* Protect read-only edit control from modification */
2293 if (editor->props & TXTBIT_READONLY)
2294 {
2295 if (!check_only) editor_beep( editor, MB_ICONERROR );
2296 return FALSE;
2297 }
2298
2300
2301 if (ps && ps->dwAspect != DVASPECT_CONTENT)
2302 FIXME("Ignoring aspect %lx\n", ps->dwAspect);
2303
2304 hr = OleGetClipboard( &data );
2305 if (hr != S_OK) return FALSE;
2306
2307 if (cf == CF_TEXT) cf = CF_UNICODETEXT;
2308
2309 hr = S_FALSE;
2310 for (format = paste_formats; format->fmt.cfFormat; format++)
2311 {
2312 if (cf && cf != format->fmt.cfFormat) continue;
2313 hr = IDataObject_QueryGetData( data, &format->fmt );
2314 if (hr == S_OK)
2315 {
2316 if (!check_only)
2317 {
2318 hr = IDataObject_GetData( data, &format->fmt, &med );
2319 if (hr != S_OK) goto done;
2320 hr = format->paste( editor, &format->fmt, &med );
2321 }
2322 break;
2323 }
2324 }
2325
2326done:
2327 IDataObject_Release( data );
2328
2329 return hr == S_OK;
2330}
2331
2332static HRESULT editor_copy( ME_TextEditor *editor, ME_Cursor *start, int chars, IDataObject **data_out )
2333{
2335 HRESULT hr = S_OK;
2336
2337 if (editor->lpOleCallback)
2338 {
2340 range.cpMin = ME_GetCursorOfs( start );
2341 range.cpMax = range.cpMin + chars;
2342 hr = IRichEditOleCallback_GetClipboardData( editor->lpOleCallback, &range, RECO_COPY, &data );
2343 }
2344
2345 if (FAILED( hr ) || !data)
2346 hr = ME_GetDataObject( editor, start, chars, &data );
2347
2348 if (SUCCEEDED( hr ))
2349 {
2350 if (data_out)
2351 *data_out = data;
2352 else
2353 {
2354 hr = OleSetClipboard( data );
2355 IDataObject_Release( data );
2356 }
2357 }
2358
2359 return hr;
2360}
2361
2363 IDataObject **data_out )
2364{
2365 HRESULT hr;
2366
2367 if (cut && (editor->props & TXTBIT_READONLY))
2368 {
2369 return E_ACCESSDENIED;
2370 }
2371
2372 hr = editor_copy( editor, start, count, data_out );
2373 if (SUCCEEDED(hr) && cut)
2374 {
2376 ME_CommitUndo( editor );
2377 ME_UpdateRepaint( editor, TRUE );
2378 }
2379 return hr;
2380}
2381
2382static BOOL copy_or_cut( ME_TextEditor *editor, BOOL cut )
2383{
2384 HRESULT hr;
2385 LONG offs, count;
2386 int start_cursor = ME_GetSelectionOfs( editor, &offs, &count );
2387 ME_Cursor *sel_start = &editor->pCursors[start_cursor];
2388
2389 if (editor->password_char) return FALSE;
2390
2391 count -= offs;
2392 hr = editor_copy_or_cut( editor, cut, sel_start, count, NULL );
2393 if (FAILED( hr )) editor_beep( editor, MB_ICONERROR );
2394
2395 return SUCCEEDED( hr );
2396}
2397
2399{
2400 ME_Paragraph *start_para, *end_para;
2401 ME_Cursor *from, *to, start;
2402 int num_chars;
2403
2404 if (!editor->AutoURLDetect_bEnable) return;
2405
2406 ME_GetSelection(editor, &from, &to);
2407
2408 /* Find paragraph previous to the one that contains start cursor */
2409 start_para = from->para;
2410 if (para_prev( start_para )) start_para = para_prev( start_para );
2411
2412 /* Find paragraph that contains end cursor */
2413 end_para = para_next( to->para );
2414
2415 start.para = start_para;
2416 start.run = para_first_run( start_para );
2417 start.nOffset = 0;
2418 num_chars = end_para->nCharOfs - start_para->nCharOfs;
2419
2420 ME_UpdateLinkAttribute( editor, &start, num_chars );
2421}
2422
2424{
2425 BOOL shift_is_down = GetKeyState(VK_SHIFT) & 0x8000;
2426
2427 if (editor->props & TXTBIT_MULTILINE)
2428 {
2429 ME_Cursor cursor = editor->pCursors[0];
2430 ME_Paragraph *para = cursor.para;
2431 LONG from, to;
2432 ME_Style *style, *eop_style;
2433
2434 if (editor->props & TXTBIT_READONLY)
2435 {
2436 editor_beep( editor, MB_ICONERROR );
2437 return TRUE;
2438 }
2439
2440 ME_GetSelectionOfs(editor, &from, &to);
2441 if (editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
2442 {
2443 if (!editor->bEmulateVersion10) /* v4.1 */
2444 {
2445 if (para->nFlags & MEPF_ROWEND)
2446 {
2447 /* Add a new table row after this row. */
2448 para = table_append_row( editor, para );
2449 para = para_next( para );
2450 editor->pCursors[0].para = para;
2451 editor->pCursors[0].run = para_first_run( para );
2452 editor->pCursors[0].nOffset = 0;
2453 editor->pCursors[1] = editor->pCursors[0];
2454 ME_CommitUndo(editor);
2455 ME_UpdateRepaint(editor, FALSE);
2456 return TRUE;
2457 }
2458 else if (para == editor->pCursors[1].para &&
2459 cursor.nOffset + cursor.run->nCharOfs == 0 &&
2460 para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART &&
2461 !para_prev( para )->nCharOfs)
2462 {
2463 /* Insert a newline before the table. */
2464 para = para_prev( para );
2465 para->nFlags &= ~MEPF_ROWSTART;
2466 editor->pCursors[0].para = para;
2467 editor->pCursors[0].run = para_first_run( para );
2468 editor->pCursors[1] = editor->pCursors[0];
2469 ME_InsertTextFromCursor( editor, 0, L"\r", 1, editor->pCursors[0].run->style );
2470 para = editor_first_para( editor );
2471 editor_set_default_para_fmt( editor, &para->fmt );
2472 para->nFlags = 0;
2473 para_mark_rewrap( editor, para );
2474 editor->pCursors[0].para = para;
2475 editor->pCursors[0].run = para_first_run( para );
2476 editor->pCursors[1] = editor->pCursors[0];
2477 para_next( para )->nFlags |= MEPF_ROWSTART;
2479 ME_UpdateRepaint(editor, FALSE);
2480 return TRUE;
2481 }
2482 }
2483 else /* v1.0 - 3.0 */
2484 {
2485 ME_Paragraph *para = cursor.para;
2486 if (para_in_table( para ))
2487 {
2488 if (cursor.run->nFlags & MERF_ENDPARA)
2489 {
2490 if (from == to)
2491 {
2493 para = table_append_row( editor, para );
2494 editor->pCursors[0].para = para;
2495 editor->pCursors[0].run = para_first_run( para );
2496 editor->pCursors[0].nOffset = 0;
2497 editor->pCursors[1] = editor->pCursors[0];
2499 ME_UpdateRepaint(editor, FALSE);
2500 return TRUE;
2501 }
2502 }
2503 else
2504 {
2506 if (cursor.run->nCharOfs + cursor.nOffset == 0 &&
2507 para_prev( para ) && !para_in_table( para_prev( para ) ))
2508 {
2509 /* Insert newline before table */
2510 cursor.run = para_end_run( para_prev( para ) );
2511 if (cursor.run)
2512 {
2513 editor->pCursors[0].run = cursor.run;
2514 editor->pCursors[0].para = para_prev( para );
2515 }
2516 editor->pCursors[0].nOffset = 0;
2517 editor->pCursors[1] = editor->pCursors[0];
2518 ME_InsertTextFromCursor( editor, 0, L"\r", 1, editor->pCursors[0].run->style );
2519 }
2520 else
2521 {
2522 editor->pCursors[1] = editor->pCursors[0];
2523 para = table_append_row( editor, para );
2524 editor->pCursors[0].para = para;
2525 editor->pCursors[0].run = para_first_run( para );
2526 editor->pCursors[0].nOffset = 0;
2527 editor->pCursors[1] = editor->pCursors[0];
2528 }
2530 ME_UpdateRepaint(editor, FALSE);
2531 return TRUE;
2532 }
2533 }
2534 }
2535
2536 style = style_get_insert_style( editor, editor->pCursors );
2537
2538 /* Normally the new eop style is the insert style, however in a list it is copied from the existing
2539 eop style (this prevents the list label style changing when the new eop is inserted).
2540 No extra ref is taken here on eop_style. */
2541 if (para->fmt.wNumbering)
2542 eop_style = para->eop_run->style;
2543 else
2544 eop_style = style;
2546 if (shift_is_down)
2547 ME_InsertEndRowFromCursor(editor, 0);
2548 else
2549 if (!editor->bEmulateVersion10)
2550 ME_InsertTextFromCursor(editor, 0, L"\r", 1, eop_style);
2551 else
2552 ME_InsertTextFromCursor(editor, 0, L"\r\n", 2, eop_style);
2554 SetCursor(NULL);
2555
2557 ME_UpdateRepaint(editor, FALSE);
2558 ME_SaveTempStyle(editor, style); /* set the temp insert style for the new para */
2560 }
2561 return TRUE;
2562 }
2563 return FALSE;
2564}
2565
2566static BOOL
2568{
2569 BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
2570 BOOL shift_is_down = GetKeyState(VK_SHIFT) & 0x8000;
2571
2572 if (editor->bMouseCaptured)
2573 return FALSE;
2574 if (nKey != VK_SHIFT && nKey != VK_CONTROL && nKey != VK_MENU)
2575 editor->nSelectionType = stPosition;
2576
2577 switch (nKey)
2578 {
2579 case VK_LEFT:
2580 case VK_RIGHT:
2581 case VK_HOME:
2582 case VK_END:
2583 editor->nUDArrowX = -1;
2584 /* fall through */
2585 case VK_UP:
2586 case VK_DOWN:
2587 case VK_PRIOR:
2588 case VK_NEXT:
2589 ME_CommitUndo(editor); /* End coalesced undos for typed characters */
2590 ME_ArrowKey(editor, nKey, shift_is_down, ctrl_is_down);
2591 return TRUE;
2592 case VK_BACK:
2593 case VK_DELETE:
2594 editor->nUDArrowX = -1;
2595 /* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */
2596 if (editor->props & TXTBIT_READONLY)
2597 return FALSE;
2598 if (ME_IsSelection(editor))
2599 {
2600 ME_DeleteSelection(editor);
2601 ME_CommitUndo(editor);
2602 }
2603 else if (nKey == VK_DELETE)
2604 {
2605 /* Delete stops group typing.
2606 * (See MSDN remarks on EM_STOPGROUPTYPING message) */
2607 ME_DeleteTextAtCursor(editor, 1, 1);
2608 ME_CommitUndo(editor);
2609 }
2610 else if (ME_ArrowKey(editor, VK_LEFT, FALSE, FALSE))
2611 {
2612 BOOL bDeletionSucceeded;
2613 /* Backspace can be grouped for a single undo */
2615 bDeletionSucceeded = ME_DeleteTextAtCursor(editor, 1, 1);
2616 if (!bDeletionSucceeded && !editor->bEmulateVersion10) { /* v4.1 */
2617 /* Deletion was prevented so the cursor is moved back to where it was.
2618 * (e.g. this happens when trying to delete cell boundaries)
2619 */
2620 ME_ArrowKey(editor, VK_RIGHT, FALSE, FALSE);
2621 }
2623 }
2624 else
2625 return TRUE;
2626 table_move_from_row_start( editor );
2628 ME_UpdateRepaint(editor, FALSE);
2629 ME_SendRequestResize(editor, FALSE);
2630 return TRUE;
2631 case VK_RETURN:
2632 if (!editor->bEmulateVersion10)
2633 return handle_enter(editor);
2634 break;
2635 case 'A':
2636 if (ctrl_is_down)
2637 {
2638 set_selection( editor, 0, -1 );
2639 return TRUE;
2640 }
2641 break;
2642 case 'V':
2643 if (ctrl_is_down)
2644 return paste_special( editor, 0, NULL, FALSE );
2645 break;
2646 case 'C':
2647 case 'X':
2648 if (ctrl_is_down)
2649 return copy_or_cut(editor, nKey == 'X');
2650 break;
2651 case 'Z':
2652 if (ctrl_is_down)
2653 {
2654 ME_Undo(editor);
2655 return TRUE;
2656 }
2657 break;
2658 case 'Y':
2659 if (ctrl_is_down)
2660 {
2661 ME_Redo(editor);
2662 return TRUE;
2663 }
2664 break;
2665
2666 default:
2667 if (nKey != VK_SHIFT && nKey != VK_CONTROL && nKey && nKey != VK_MENU)
2668 editor->nUDArrowX = -1;
2669 if (ctrl_is_down)
2670 {
2671 if (nKey == 'W')
2672 {
2673 CHARFORMAT2W chf;
2674 char buf[2048];
2675 chf.cbSize = sizeof(chf);
2676
2677 ME_GetSelectionCharFormat(editor, &chf);
2678 ME_DumpStyleToBuf(&chf, buf);
2679 MessageBoxA(NULL, buf, "Style dump", MB_OK);
2680 }
2681 if (nKey == 'Q')
2682 {
2683 ME_CheckCharOffsets(editor);
2684 }
2685 }
2686 }
2687 return FALSE;
2688}
2689
2691{
2692 if (editor->bMouseCaptured)
2693 return 0;
2694
2695 if (editor->props & TXTBIT_READONLY)
2696 {
2697 editor_beep( editor, MB_ICONERROR );
2698 return 0; /* FIXME really 0 ? */
2699 }
2700
2701 if (editor->bEmulateVersion10 && wstr == '\r')
2702 handle_enter(editor);
2703
2704 if ((unsigned)wstr >= ' ' || wstr == '\t')
2705 {
2706 ME_Cursor cursor = editor->pCursors[0];
2707 ME_Paragraph *para = cursor.para;
2708 LONG from, to;
2709 BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000;
2710 ME_GetSelectionOfs(editor, &from, &to);
2711 if (wstr == '\t' &&
2712 /* v4.1 allows tabs to be inserted with ctrl key down */
2713 !(ctrl_is_down && !editor->bEmulateVersion10))
2714 {
2715 BOOL selected_row = FALSE;
2716
2717 if (ME_IsSelection(editor) &&
2718 cursor.run->nCharOfs + cursor.nOffset == 0 &&
2719 to == ME_GetCursorOfs(&editor->pCursors[0]) && para_prev( para ))
2720 {
2721 para = para_prev( para );
2722 selected_row = TRUE;
2723 }
2724 if (para_in_table( para ))
2725 {
2726 table_handle_tab( editor, selected_row );
2727 ME_CommitUndo(editor);
2728 return 0;
2729 }
2730 }
2731 else if (!editor->bEmulateVersion10) /* v4.1 */
2732 {
2733 if (para->nFlags & MEPF_ROWEND)
2734 {
2735 if (from == to)
2736 {
2737 para = para_next( para );
2738 if (para->nFlags & MEPF_ROWSTART) para = para_next( para );
2739 editor->pCursors[0].para = para;
2740 editor->pCursors[0].run = para_first_run( para );
2741 editor->pCursors[0].nOffset = 0;
2742 editor->pCursors[1] = editor->pCursors[0];
2743 }
2744 }
2745 }
2746 else /* v1.0 - 3.0 */
2747 {
2748 if (para_in_table( para ) && cursor.run->nFlags & MERF_ENDPARA && from == to)
2749 {
2750 /* Text should not be inserted at the end of the table. */
2751 editor_beep( editor, -1 );
2752 return 0;
2753 }
2754 }
2755 /* FIXME maybe it would make sense to call EM_REPLACESEL instead ? */
2756 /* WM_CHAR is restricted to nTextLimit */
2757 if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from))
2758 {
2759 ME_Style *style = style_get_insert_style( editor, editor->pCursors );
2761 ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
2765 }
2766
2768 ME_UpdateRepaint(editor, FALSE);
2769 }
2770 return 0;
2771}
2772
2773/* Process the message and calculate the new click count.
2774 *
2775 * returns: The click count if it is mouse down event, else returns 0. */
2777 LPARAM lParam)
2778{
2779 static int clickNum = 0;
2780 if (msg < WM_MOUSEFIRST || msg > WM_MOUSELAST)
2781 return 0;
2782
2783 if ((msg == WM_LBUTTONDBLCLK) ||
2784 (msg == WM_RBUTTONDBLCLK) ||
2785 (msg == WM_MBUTTONDBLCLK) ||
2786 (msg == WM_XBUTTONDBLCLK))
2787 {
2789 }
2790
2791 if ((msg == WM_LBUTTONDOWN) ||
2792 (msg == WM_RBUTTONDOWN) ||
2793 (msg == WM_MBUTTONDOWN) ||
2794 (msg == WM_XBUTTONDOWN))
2795 {
2796 static MSG prevClickMsg;
2797 MSG clickMsg;
2798 /* Compare the editor instead of the hwnd so that the this
2799 * can still be done for windowless richedit controls. */
2800 clickMsg.hwnd = (HWND)editor;
2801 clickMsg.message = msg;
2802 clickMsg.wParam = wParam;
2803 clickMsg.lParam = lParam;
2804 clickMsg.time = GetMessageTime();
2805 clickMsg.pt.x = (short)LOWORD(lParam);
2806 clickMsg.pt.y = (short)HIWORD(lParam);
2807 if ((clickNum != 0) &&
2808 (clickMsg.message == prevClickMsg.message) &&
2809 (clickMsg.hwnd == prevClickMsg.hwnd) &&
2810 (clickMsg.wParam == prevClickMsg.wParam) &&
2811 (clickMsg.time - prevClickMsg.time < GetDoubleClickTime()) &&
2812 (abs(clickMsg.pt.x - prevClickMsg.pt.x) < GetSystemMetrics(SM_CXDOUBLECLK)/2) &&
2813 (abs(clickMsg.pt.y - prevClickMsg.pt.y) < GetSystemMetrics(SM_CYDOUBLECLK)/2))
2814 {
2815 clickNum++;
2816 } else {
2817 clickNum = 1;
2818 }
2819 prevClickMsg = clickMsg;
2820 } else {
2821 return 0;
2822 }
2823 return clickNum;
2824}
2825
2826static BOOL is_link( ME_Run *run )
2827{
2828 return (run->style->fmt.dwMask & CFM_LINK) && (run->style->fmt.dwEffects & CFE_LINK);
2829}
2830
2831void editor_set_cursor( ME_TextEditor *editor, int x, int y )
2832{
2833 ME_Cursor pos;
2834 static HCURSOR cursor_arrow, cursor_hand, cursor_ibeam, cursor_reverse;
2836
2837 if (!cursor_arrow)
2838 {
2839 cursor_arrow = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_ARROW ) );
2840 cursor_hand = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_HAND ) );
2841 cursor_ibeam = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_IBEAM ) );
2842 cursor_reverse = LoadCursorW( dll_instance, MAKEINTRESOURCEW( OCR_REVERSE ) );
2843 }
2844
2845 cursor = cursor_ibeam;
2846
2847 if ((editor->nSelectionType == stLine && editor->bMouseCaptured) ||
2848 (!editor->bEmulateVersion10 && y < editor->rcFormat.top && x < editor->rcFormat.left))
2849 cursor = cursor_reverse;
2850 else if (y < editor->rcFormat.top || y > editor->rcFormat.bottom)
2851 {
2852 if (editor->bEmulateVersion10) cursor = cursor_arrow;
2853 else cursor = cursor_ibeam;
2854 }
2855 else if (x < editor->rcFormat.left) cursor = cursor_reverse;
2856 else if (cursor_from_coords( editor, x, y, &pos ))
2857 {
2858 ME_Run *run = pos.run;
2859
2860 if (is_link( run )) cursor = cursor_hand;
2861
2862 else if (ME_IsSelection( editor ))
2863 {
2864 LONG start, end;
2865 int offset = ME_GetCursorOfs( &pos );
2866
2867 ME_GetSelectionOfs( editor, &start, &end );
2868 if (start <= offset && end >= offset) cursor = cursor_arrow;
2869 }
2870 }
2871
2872 ITextHost_TxSetCursor( editor->texthost, cursor, cursor == cursor_ibeam );
2873}
2874
2876{
2877 LONG sel_type = SEL_EMPTY;
2878 LONG start, end;
2879
2880 ME_GetSelectionOfs(editor, &start, &end);
2881 if (start == end)
2882 sel_type = SEL_EMPTY;
2883 else
2884 {
2886 int i;
2887
2888 for (i = 0; i < end - start; i++)
2889 {
2891
2892 cursor_from_char_ofs( editor, start + i, &cursor );
2893 if (cursor.run->reobj) object_count++;
2894 else character_count++;
2895 if (character_count >= 2 && object_count >= 2)
2897 }
2898 if (character_count)
2899 {
2900 sel_type |= SEL_TEXT;
2901 if (character_count >= 2)
2902 sel_type |= SEL_MULTICHAR;
2903 }
2904 if (object_count)
2905 {
2906 sel_type |= SEL_OBJECT;
2907 if (object_count >= 2)
2908 sel_type |= SEL_MULTIOBJECT;
2909 }
2910 }
2911 return sel_type;
2912}
2913
2914static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
2915{
2916 CHARRANGE selrange;
2917 HMENU menu;
2918 int seltype;
2919 HWND hwnd, parent;
2920
2921 if (!editor->lpOleCallback || !editor->have_texthost2) return FALSE;
2922 if (FAILED( ITextHost2_TxGetWindow( editor->texthost, &hwnd ))) return FALSE;
2923 parent = GetParent( hwnd );
2924 if (!parent) parent = hwnd;
2925
2926 ME_GetSelectionOfs( editor, &selrange.cpMin, &selrange.cpMax );
2927 seltype = ME_GetSelectionType( editor );
2928 if (SUCCEEDED( IRichEditOleCallback_GetContextMenu( editor->lpOleCallback, seltype, NULL, &selrange, &menu ) ))
2929 {
2931 DestroyMenu( menu );
2932 }
2933 return TRUE;
2934}
2935
2936ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
2937{
2938 ME_TextEditor *ed = malloc( sizeof(*ed) );
2939 int i;
2940 LONG selbarwidth;
2941 HRESULT hr;
2942 HDC hdc;
2943
2944 ed->sizeWindow.cx = ed->sizeWindow.cy = 0;
2945 if (ITextHost_QueryInterface( texthost, &IID_ITextHost2, (void **)&ed->texthost ) == S_OK)
2946 {
2947 ITextHost_Release( texthost );
2948 ed->have_texthost2 = TRUE;
2949 }
2950 else
2951 {
2952 ed->texthost = (ITextHost2 *)texthost;
2953 ed->have_texthost2 = FALSE;
2954 }
2955
2956 ed->bEmulateVersion10 = bEmulateVersion10;
2957 ed->in_place_active = FALSE;
2958 ed->total_rows = 0;
2963 &ed->props );
2965 ed->pBuffer = ME_MakeText();
2966 ed->nZoomNumerator = ed->nZoomDenominator = 0;
2967 ed->nAvailWidth = 0; /* wrap to client area */
2968 list_init( &ed->style_list );
2969
2972 /* The four cursors are for:
2973 * 0 - The position where the caret is shown
2974 * 1 - The anchored end of the selection (for normal selection)
2975 * 2 & 3 - The anchored start and end respectively for word, line,
2976 * or paragraph selection.
2977 */
2978 ed->nCursors = 4;
2979 ed->pCursors = malloc( ed->nCursors * sizeof(*ed->pCursors) );
2980 ME_SetCursorToStart(ed, &ed->pCursors[0]);
2981 ed->pCursors[1] = ed->pCursors[0];
2982 ed->pCursors[2] = ed->pCursors[0];
2983 ed->pCursors[3] = ed->pCursors[1];
2984 ed->nLastTotalLength = ed->nTotalLength = 0;
2985 ed->nLastTotalWidth = ed->nTotalWidth = 0;
2986 ed->nUDArrowX = -1;
2987 ed->nEventMask = 0;
2988 ed->nModifyStep = 0;
2990 list_init( &ed->undo_stack );
2991 list_init( &ed->redo_stack );
2992 ed->nUndoStackSize = 0;
2994 ed->nUndoMode = umAddToUndo;
2996 ed->nParagraphs = 1;
2997 ed->nLastSelStart = ed->nLastSelEnd = 0;
2999 ed->bHideSelection = FALSE;
3000 ed->pfnWordBreak = NULL;
3001 ed->richole = NULL;
3002 ed->lpOleCallback = NULL;
3006 ed->bHaveFocus = FALSE;
3007 ed->freeze_count = 0;
3008 ed->bMouseCaptured = FALSE;
3009 ed->caret_hidden = FALSE;
3010 ed->caret_height = 0;
3011 for (i=0; i<HFONT_CACHE_SIZE; i++)
3012 {
3013 ed->pFontCache[i].nRefs = 0;
3014 ed->pFontCache[i].nAge = 0;
3015 ed->pFontCache[i].hFont = NULL;
3016 }
3017
3019 SetRectEmpty(&ed->rcFormat);
3020 hr = ITextHost_TxGetSelectionBarWidth( ed->texthost, &selbarwidth );
3021 /* FIXME: Convert selbarwidth from HIMETRIC to pixels */
3022 if (hr == S_OK && selbarwidth) ed->selofs = SELECTIONBAR_WIDTH;
3023 else ed->selofs = 0;
3025
3026 ed->password_char = 0;
3027 if (ed->props & TXTBIT_USEPASSWORD)
3029
3030 ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) && (ed->props & TXTBIT_MULTILINE);
3031
3032 ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
3033
3034 /* Default scrollbar information */
3035 ed->vert_si.cbSize = sizeof(SCROLLINFO);
3036 ed->vert_si.nMin = 0;
3037 ed->vert_si.nMax = 0;
3038 ed->vert_si.nPage = 0;
3039 ed->vert_si.nPos = 0;
3040 ed->vert_sb_enabled = 0;
3041
3042 ed->horz_si.cbSize = sizeof(SCROLLINFO);
3043 ed->horz_si.nMin = 0;
3044 ed->horz_si.nMax = 0;
3045 ed->horz_si.nPage = 0;
3046 ed->horz_si.nPos = 0;
3047 ed->horz_sb_enabled = 0;
3048
3050 {
3051 if (ed->scrollbars & WS_VSCROLL)
3052 {
3055 }
3056 if (ed->scrollbars & WS_HSCROLL)
3057 {
3060 }
3061 }
3062
3063 ed->wheel_remain = 0;
3064
3067
3068 list_init( &ed->reobj_list );
3070
3073
3074 return ed;
3075}
3076
3078{
3079 ME_DisplayItem *p = editor->pBuffer->pFirst, *pNext = NULL;
3080 ME_Style *s, *cursor2;
3081 int i;
3082
3083 ME_ClearTempStyle(editor);
3084 ME_EmptyUndoStack(editor);
3085 editor->pBuffer->pFirst = NULL;
3086 while(p)
3087 {
3088 pNext = p->next;
3089 if (p->type == diParagraph)
3090 para_destroy( editor, &p->member.para );
3091 else
3093 p = pNext;
3094 }
3095
3096 LIST_FOR_EACH_ENTRY_SAFE( s, cursor2, &editor->style_list, ME_Style, entry )
3097 ME_DestroyStyle( s );
3098
3100 for (i=0; i<HFONT_CACHE_SIZE; i++)
3101 {
3102 if (editor->pFontCache[i].hFont)
3103 DeleteObject(editor->pFontCache[i].hFont);
3104 }
3105 if(editor->lpOleCallback)
3106 IRichEditOleCallback_Release(editor->lpOleCallback);
3107
3109
3110 free(editor->pBuffer);
3111 free(editor->pCursors);
3112 free(editor);
3113}
3114
3115static inline int get_default_line_height( ME_TextEditor *editor )
3116{
3117 int height = 0;
3118
3119 if (editor->pBuffer && editor->pBuffer->pDefaultStyle)
3121 if (height <= 0) height = 24;
3122
3123 return height;
3124}
3125
3126static inline int calc_wheel_change( int *remain, int amount_per_click )
3127{
3128 int change = amount_per_click * (float)*remain / WHEEL_DELTA;
3129 *remain -= WHEEL_DELTA * change / amount_per_click;
3130 return change;
3131}
3132
3134{
3135 int x,y;
3136 ME_Cursor cursor; /* The start of the clicked text. */
3137 ME_Run *run;
3138 ENLINK info;
3139
3140 x = (short)LOWORD(lParam);
3141 y = (short)HIWORD(lParam);
3142 if (!cursor_from_coords( editor, x, y, &cursor )) return;
3143
3144 if (is_link( cursor.run ))
3145 { /* The clicked run has CFE_LINK set */
3146 info.nmhdr.hwndFrom = NULL;
3147 info.nmhdr.idFrom = 0;
3148 info.nmhdr.code = EN_LINK;
3149 info.msg = msg;
3150 info.wParam = wParam;
3151 info.lParam = lParam;
3152 cursor.nOffset = 0;
3153
3154 /* find the first contiguous run with CFE_LINK set */
3155 info.chrg.cpMin = ME_GetCursorOfs(&cursor);
3156 run = cursor.run;
3157 while ((run = run_prev( run )) && is_link( run ))
3158 info.chrg.cpMin -= run->len;
3159
3160 /* find the last contiguous run with CFE_LINK set */
3161 info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.run->len;
3162 run = cursor.run;
3163 while ((run = run_next( run )) && is_link( run ))
3164 info.chrg.cpMax += run->len;
3165
3166 ITextHost_TxNotify(editor->texthost, info.nmhdr.code, &info);
3167 }
3168}
3169
3170void ME_ReplaceSel(ME_TextEditor *editor, BOOL can_undo, const WCHAR *str, int len)
3171{
3172 LONG from, to;
3173 int nStartCursor;
3174 ME_Style *style;
3175
3176 nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
3178 ME_InternalDeleteText(editor, &editor->pCursors[nStartCursor], to-from, FALSE);
3179 ME_InsertTextFromCursor(editor, 0, str, len, style);
3181 /* drop temporary style if line end */
3182 /*
3183 * FIXME question: does abc\n mean: put abc,
3184 * clear temp style, put \n? (would require a change)
3185 */
3186 if (len>0 && str[len-1] == '\n')
3187 ME_ClearTempStyle(editor);
3188 ME_CommitUndo(editor);
3190 if (!can_undo)
3191 ME_EmptyUndoStack(editor);
3192 ME_UpdateRepaint(editor, FALSE);
3193}
3194
3195static void ME_SetText(ME_TextEditor *editor, void *text, BOOL unicode)
3196{
3197 LONG codepage = unicode ? CP_UNICODE : CP_ACP;
3198 int textLen;
3199
3200 LPWSTR wszText = ME_ToUnicode(codepage, text, &textLen);
3201 ME_InsertTextFromCursor(editor, 0, wszText, textLen, editor->pBuffer->pDefaultStyle);
3202 ME_EndToUnicode(codepage, wszText);
3203}
3204
3206{
3208 BOOL changed = TRUE;
3210
3211 if (!cfany_to_cf2w( &fmt, fmt_in )) return 0;
3212
3213 if (flags & SCF_ALL)
3214 {
3215 if (editor->mode & TM_PLAINTEXT)
3216 {
3217 ME_SetDefaultCharFormat( editor, &fmt );
3218 }
3219 else
3220 {
3221 ME_SetCursorToStart( editor, &start );
3222 ME_SetCharFormat( editor, &start, NULL, &fmt );
3223 editor->nModifyStep = 1;
3224 }
3225 }
3226 else if (flags & SCF_SELECTION)
3227 {
3228 if (editor->mode & TM_PLAINTEXT) return 0;
3229 if (flags & SCF_WORD)
3230 {
3231 end = editor->pCursors[0];
3232 ME_MoveCursorWords( editor, &end, +1 );
3233 start = end;
3234 ME_MoveCursorWords( editor, &start, -1 );
3235 ME_SetCharFormat( editor, &start, &end, &fmt );
3236 }
3237 changed = ME_IsSelection( editor );
3238 ME_SetSelectionCharFormat( editor, &fmt );
3239 if (changed) editor->nModifyStep = 1;
3240 }
3241 else /* SCF_DEFAULT */
3242 {
3243 ME_SetDefaultCharFormat( editor, &fmt );
3244 }
3245
3246 ME_CommitUndo( editor );
3247 if (changed)
3248 {
3249 ME_WrapMarkedParagraphs( editor );
3250 ME_UpdateScrollBar( editor );
3251 }
3252 return 1;
3253}
3254
3255#define UNSUPPORTED_MSG(e) \
3256 case e: \
3257 FIXME(#e ": stub\n"); \
3258 *phresult = S_FALSE; \
3259 return 0;
3260
3261/* Handle messages for windowless and windowed richedit controls.
3262 *
3263 * The LRESULT that is returned is a return value for window procs,
3264 * and the phresult parameter is the COM return code needed by the
3265 * text services interface. */
3267 LPARAM lParam, HRESULT* phresult )
3268{
3269 *phresult = S_OK;
3270
3271 switch(msg) {
3272
3295
3296/* Messages specific to Richedit controls */
3297
3298 case EM_STREAMIN:
3299 return ME_StreamIn(editor, wParam, (EDITSTREAM*)lParam, TRUE);
3300 case EM_STREAMOUT:
3301 return ME_StreamOut(editor, wParam, (EDITSTREAM *)lParam);
3302 case EM_EMPTYUNDOBUFFER:
3303 ME_EmptyUndoStack(editor);
3304 return 0;
3305 case EM_GETSEL:
3306 {
3307 /* Note: wParam/lParam can be NULL */
3308 LONG from, to;
3309 LONG *pfrom = wParam ? (LONG *)wParam : &from;
3310 LONG *pto = lParam ? (LONG *)lParam : &to;
3311 ME_GetSelectionOfs(editor, pfrom, pto);
3312 if ((*pfrom|*pto) & 0xFFFF0000)
3313 return -1;
3314 return MAKELONG(*pfrom,*pto);
3315 }
3316 case EM_EXGETSEL:
3317 {
3318 CHARRANGE *pRange = (CHARRANGE *)lParam;
3319 ME_GetSelectionOfs(editor, &pRange->cpMin, &pRange->cpMax);
3320 TRACE("EM_EXGETSEL = (%ld,%ld)\n", pRange->cpMin, pRange->cpMax);
3321 return 0;
3322 }
3323 case EM_SETUNDOLIMIT:
3324 {
3325 editor_enable_undo(editor);
3326 if ((int)wParam < 0)
3328 else
3329 editor->nUndoLimit = min(wParam, STACK_SIZE_MAX);
3330 /* Setting a max stack size keeps wine from getting killed
3331 for hogging memory. Windows allocates all this memory at once, so
3332 no program would realistically set a value above our maximum. */
3333 return editor->nUndoLimit;
3334 }
3335 case EM_CANUNDO:
3336 return !list_empty( &editor->undo_stack );
3337 case EM_CANREDO:
3338 return !list_empty( &editor->redo_stack );
3339 case WM_UNDO: /* FIXME: actually not the same */
3340 case EM_UNDO:
3341 return ME_Undo(editor);
3342 case EM_REDO:
3343 return ME_Redo(editor);
3344 case EM_SETFONTSIZE:
3345 {
3347 LONG tmp_size, size;
3348 BOOL is_increase = ((LONG)wParam > 0);
3349
3350 if (editor->mode & TM_PLAINTEXT)
3351 return FALSE;
3352
3353 cf.cbSize = sizeof(cf);
3354 cf.dwMask = CFM_SIZE;
3355 ME_GetSelectionCharFormat(editor, &cf);
3356 tmp_size = (cf.yHeight / 20) + wParam;
3357
3358 if (tmp_size <= 1)
3359 size = 1;
3360 else if (tmp_size > 12 && tmp_size < 28 && tmp_size % 2)
3361 size = tmp_size + (is_increase ? 1 : -1);
3362 else if (tmp_size > 28 && tmp_size < 36)
3363 size = is_increase ? 36 : 28;
3364 else if (tmp_size > 36 && tmp_size < 48)
3365 size = is_increase ? 48 : 36;
3366 else if (tmp_size > 48 && tmp_size < 72)
3367 size = is_increase ? 72 : 48;
3368 else if (tmp_size > 72 && tmp_size < 80)
3369 size = is_increase ? 80 : 72;
3370 else if (tmp_size > 80 && tmp_size < 1638)
3371 size = 10 * (is_increase ? (tmp_size / 10 + 1) : (tmp_size / 10));
3372 else if (tmp_size >= 1638)
3373 size = 1638;
3374 else
3375 size = tmp_size;
3376
3377 cf.yHeight = size * 20; /* convert twips to points */
3378 ME_SetSelectionCharFormat(editor, &cf);
3379 ME_CommitUndo(editor);
3381 ME_UpdateScrollBar(editor);
3382
3383 return TRUE;
3384 }
3385 case EM_SETSEL:
3386 {
3387 return set_selection( editor, wParam, lParam );
3388 }
3389 case EM_SETSCROLLPOS:
3390 {
3391 POINT *point = (POINT *)lParam;
3392 scroll_abs( editor, point->x, point->y, TRUE );
3393 return 0;
3394 }
3395 case EM_AUTOURLDETECT:
3396 {
3397 if (wParam==1 || wParam ==0)
3398 {
3400 return 0;
3401 }
3402 return E_INVALIDARG;
3403 }
3405 {
3406 return editor->AutoURLDetect_bEnable;
3407 }
3408 case EM_EXSETSEL:
3409 {
3411
3412 return set_selection( editor, range.cpMin, range.cpMax );
3413 }
3414 case EM_SETTEXTEX:
3415 {
3416 LPWSTR wszText;
3417 SETTEXTEX *pStruct = (SETTEXTEX *)wParam;
3418 LONG from, to;
3419 int len;
3420 ME_Style *style;
3421 BOOL bRtf, bUnicode, bSelection, bUTF8;
3422 int oldModify = editor->nModifyStep;
3423 static const char utf8_bom[] = {0xef, 0xbb, 0xbf};
3424
3425 if (!pStruct) return 0;
3426
3427 /* If we detect ascii rtf at the start of the string,
3428 * we know it isn't unicode. */
3429 bRtf = (lParam && (!strncmp((char *)lParam, "{\\rtf", 5) ||
3430 !strncmp((char *)lParam, "{\\urtf", 6)));
3431 bUnicode = !bRtf && pStruct->codepage == CP_UNICODE;
3432 bUTF8 = (lParam && (!strncmp((char *)lParam, utf8_bom, 3)));
3433
3434 TRACE("EM_SETTEXTEX - %s, flags %ld, cp %d\n",
3436 pStruct->flags, pStruct->codepage);
3437
3438 bSelection = (pStruct->flags & ST_SELECTION) != 0;
3439 if (bSelection) {
3440 int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
3442 ME_InternalDeleteText(editor, &editor->pCursors[nStartCursor], to - from, FALSE);
3443 } else {
3445 ME_SetCursorToStart(editor, &start);
3447 style = editor->pBuffer->pDefaultStyle;
3448 }
3449
3450 if (bRtf) {
3451 ME_StreamInRTFString(editor, bSelection, (char *)lParam);
3452 if (bSelection) {
3453 /* FIXME: The length returned doesn't include the rtf control
3454 * characters, only the actual text. */
3455 len = lParam ? strlen((char *)lParam) : 0;
3456 }
3457 } else {
3458 if (bUTF8 && !bUnicode) {
3459 wszText = ME_ToUnicode(CP_UTF8, (void *)(lParam+3), &len);
3460 ME_InsertTextFromCursor(editor, 0, wszText, len, style);
3461 ME_EndToUnicode(CP_UTF8, wszText);
3462 } else {
3463 wszText = ME_ToUnicode(pStruct->codepage, (void *)lParam, &len);
3464 ME_InsertTextFromCursor(editor, 0, wszText, len, style);
3465 ME_EndToUnicode(pStruct->codepage, wszText);
3466 }
3467 }
3468
3469 if (bSelection) {
3472 } else {
3474 len = 1;
3475 ME_SetCursorToStart(editor, &cursor);
3477 }
3478 ME_CommitUndo(editor);
3479 if (!(pStruct->flags & ST_KEEPUNDO))
3480 {
3481 editor->nModifyStep = oldModify;
3482 ME_EmptyUndoStack(editor);
3483 }
3484 ME_UpdateRepaint(editor, FALSE);
3485 return len;
3486 }
3487 case EM_SELECTIONTYPE:
3488 return ME_GetSelectionType(editor);
3489 case EM_GETMODIFY:
3490 return editor->nModifyStep == 0 ? 0 : -1;
3491 case EM_SETMODIFY:
3492 {
3493 if (wParam)
3494 editor->nModifyStep = 1;
3495 else
3496 editor->nModifyStep = 0;
3497
3498 return 0;
3499 }
3500 case EM_SETEVENTMASK:
3501 {
3502 DWORD nOldMask = editor->nEventMask;
3503
3504 editor->nEventMask = lParam;
3505 return nOldMask;
3506 }
3507 case EM_GETEVENTMASK:
3508 return editor->nEventMask;
3509 case EM_SETCHARFORMAT:
3510 return handle_EM_SETCHARFORMAT( editor, wParam, (CHARFORMAT2W *)lParam );
3511 case EM_GETCHARFORMAT:
3512 {
3514 if (dst->cbSize != sizeof(CHARFORMATA) &&
3515 dst->cbSize != sizeof(CHARFORMATW) &&
3516 dst->cbSize != sizeof(CHARFORMAT2A) &&
3517 dst->cbSize != sizeof(CHARFORMAT2W))
3518 return 0;
3519 tmp.cbSize = sizeof(tmp);
3520 if (!wParam)
3521 ME_GetDefaultCharFormat(editor, &tmp);
3522 else
3523 ME_GetSelectionCharFormat(editor, &tmp);
3524 cf2w_to_cfany(dst, &tmp);
3525 return tmp.dwMask;
3526 }
3527 case EM_SETPARAFORMAT:
3528 {
3531 ME_UpdateScrollBar(editor);
3532 ME_CommitUndo(editor);
3533 return result;
3534 }
3535 case EM_GETPARAFORMAT:
3537 return ((PARAFORMAT2 *)lParam)->dwMask;
3539 {
3540 ME_Paragraph *para = editor_first_para( editor );
3541 ME_Row *row;
3542 int y = editor->vert_si.nPos;
3543 int count = 0;
3544
3545 while (para_next( para ))
3546 {
3547 if (y < para->pt.y + para->nHeight) break;
3548 count += para->nRows;
3549 para = para_next( para );
3550 }
3551
3552 row = para_first_row( para );
3553 while (row)
3554 {
3555 if (y < para->pt.y + row->pt.y + row->nHeight) break;
3556 count++;
3557 row = row_next( row );
3558 }
3559 return count;
3560 }
3561 case EM_HIDESELECTION:
3562 {
3563 editor->bHideSelection = (wParam != 0);
3564 ME_InvalidateSelection(editor);
3565 return 0;
3566 }
3567 case EM_LINESCROLL:
3568 {
3569 if (!(editor->props & TXTBIT_MULTILINE))
3570 return FALSE;
3571 ME_ScrollDown( editor, lParam * get_default_line_height( editor ) );
3572 return TRUE;
3573 }
3574 case WM_CLEAR:
3575 {
3576 LONG from, to;
3577 int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
3578 ME_InternalDeleteText(editor, &editor->pCursors[nStartCursor], to-from, FALSE);
3579 ME_CommitUndo(editor);
3580 ME_UpdateRepaint(editor, TRUE);
3581 return 0;
3582 }
3583 case EM_REPLACESEL:
3584 {
3585 WCHAR *text = (WCHAR *)lParam;
3586 int len = text ? lstrlenW( text ) : 0;
3587
3588 TRACE( "EM_REPLACESEL - %s\n", debugstr_w( text ) );
3589 ME_ReplaceSel( editor, !!wParam, text, len );
3590 return len;
3591 }
3592 case EM_SCROLLCARET:
3593 editor_ensure_visible( editor, &editor->pCursors[0] );
3594 return 0;
3595 case WM_SETFONT:
3596 {
3597 LOGFONTW lf;
3599 HDC hDC;
3600 BOOL bRepaint = LOWORD(lParam);
3601
3602 if (!wParam)
3604
3605 if (!GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf))
3606 return 0;
3607
3608 hDC = ITextHost_TxGetDC(editor->texthost);
3611 if (editor->mode & TM_RICHTEXT) {
3613 ME_SetCursorToStart(editor, &start);
3614 ME_SetCharFormat(editor, &start, NULL, &fmt);
3615 }
3616 ME_SetDefaultCharFormat(editor, &fmt);
3617
3618 ME_CommitUndo(editor);
3619 editor_mark_rewrap_all( editor );
3621 ME_UpdateScrollBar(editor);
3622 if (bRepaint)
3623 ME_Repaint(editor);
3624#ifdef __REACTOS__
3626 {
3627 HIMC hIMC = ImmGetContext(editor->hWnd);
3628 ImmSetCompositionFontW(hIMC, &lf);
3629 ImmReleaseContext(editor->hWnd, hIMC);
3630 }
3631#endif
3632 return 0;
3633 }
3634 case WM_SETTEXT:
3635 {
3637 ME_SetCursorToStart(editor, &cursor);
3639 if (lParam)
3640 {
3641 TRACE("WM_SETTEXT lParam==%Ix\n",lParam);
3642 if (!strncmp((char *)lParam, "{\\rtf", 5) ||
3643 !strncmp((char *)lParam, "{\\urtf", 6))
3644 {
3645 /* Undocumented: WM_SETTEXT supports RTF text */
3646 ME_StreamInRTFString(editor, 0, (char *)lParam);
3647 }
3648 else
3649 ME_SetText( editor, (void*)lParam, TRUE );
3650 }
3651 else
3652 TRACE("WM_SETTEXT - NULL\n");
3653 ME_SetCursorToStart(editor, &cursor);
3655 set_selection_cursors(editor, 0, 0);
3656 editor->nModifyStep = 0;
3657 ME_CommitUndo(editor);
3658 ME_EmptyUndoStack(editor);
3659 ME_UpdateRepaint(editor, FALSE);
3660 return 1;
3661 }
3662 case EM_CANPASTE:
3663 return paste_special( editor, 0, NULL, TRUE );
3664 case WM_PASTE:
3665 case WM_MBUTTONDOWN:
3666 wParam = 0;
3667 lParam = 0;
3668 /* fall through */
3669 case EM_PASTESPECIAL:
3671 return 0;
3672 case WM_CUT:
3673 case WM_COPY:
3674 copy_or_cut(editor, msg == WM_CUT);
3675 return 0;
3676 case WM_GETTEXTLENGTH:
3677 {
3678 GETTEXTLENGTHEX how;
3679 how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS;
3680 how.codepage = CP_UNICODE;
3681 return ME_GetTextLengthEx(editor, &how);
3682 }
3683 case EM_GETTEXTLENGTHEX:
3684 return ME_GetTextLengthEx(editor, (GETTEXTLENGTHEX *)wParam);
3685 case WM_GETTEXT:
3686 {
3687 GETTEXTEX ex;
3688 ex.cb = wParam * sizeof(WCHAR);
3689 ex.flags = GT_USECRLF;
3690 ex.codepage = CP_UNICODE;
3691 ex.lpDefaultChar = NULL;
3692 ex.lpUsedDefChar = NULL;
3693 return ME_GetTextEx(editor, &ex, lParam);
3694 }
3695 case EM_GETTEXTEX:
3696 return ME_GetTextEx(editor, (GETTEXTEX*)wParam, lParam);
3697 case EM_GETSELTEXT:
3698 {
3699 LONG nFrom, nTo;
3700 int nStartCur = ME_GetSelectionOfs(editor, &nFrom, &nTo);
3701 ME_Cursor *from = &editor->pCursors[nStartCur];
3702 return get_text_range( editor, (WCHAR *)lParam, from, nTo - nFrom );
3703 }
3704 case EM_GETSCROLLPOS:
3705 {
3706 POINT *point = (POINT *)lParam;
3707 point->x = editor->horz_si.nPos;
3708 point->y = editor->vert_si.nPos;
3709 /* 16-bit scaled value is returned as stored in scrollinfo */
3710 if (editor->horz_si.nMax > 0xffff)
3711 point->x = MulDiv(point->x, 0xffff, editor->horz_si.nMax);
3712 if (editor->vert_si.nMax > 0xffff)
3713 point->y = MulDiv(point->y, 0xffff, editor->vert_si.nMax);
3714 return 1;
3715 }
3716 case EM_GETTEXTRANGE:
3717 {
3718 TEXTRANGEW *rng = (TEXTRANGEW *)lParam;
3720 int nStart = rng->chrg.cpMin;
3721 int nEnd = rng->chrg.cpMax;
3722 int textlength = ME_GetTextLength(editor);
3723
3724 TRACE( "EM_GETTEXTRANGE min = %ld max = %ld textlength = %d\n", rng->chrg.cpMin, rng->chrg.cpMax, textlength );
3725 if (nStart < 0) return 0;
3726 if ((nStart == 0 && nEnd == -1) || nEnd > textlength)
3727 nEnd = textlength;
3728 if (nStart >= nEnd) return 0;
3729
3730 cursor_from_char_ofs( editor, nStart, &start );
3731 return get_text_range( editor, rng->lpstrText, &start, nEnd - nStart );
3732 }
3733 case EM_GETLINE:
3734 {
3735 ME_Row *row;
3736 ME_Run *run;
3737 const unsigned int nMaxChars = *(WORD *) lParam;
3738 unsigned int nCharsLeft = nMaxChars;
3739 char *dest = (char *) lParam;
3741
3742 TRACE( "EM_GETLINE: row=%d, nMaxChars=%d\n", (int)wParam, nMaxChars );
3743
3744 row = row_from_row_number( editor, wParam );
3745 if (row == NULL) return 0;
3746
3748 row_end_cursor( row, &end, TRUE );
3749 run = start.run;
3750 while (nCharsLeft)
3751 {
3752 WCHAR *str;
3753 unsigned int nCopy;
3754 int ofs = (run == start.run) ? start.nOffset : 0;
3755 int len = (run == end.run) ? end.nOffset : run->len;
3756
3757 str = get_text( run, ofs );
3758 nCopy = min( nCharsLeft, len );
3759
3760 memcpy(dest, str, nCopy * sizeof(WCHAR));
3761 dest += nCopy * sizeof(WCHAR);
3762 nCharsLeft -= nCopy;
3763 if (run == end.run) break;
3764 run = row_next_run( row, run );
3765 }
3766
3767 /* append line termination, space allowing */
3768 if (nCharsLeft > 0) *((WCHAR *)dest) = '\0';
3769
3770 TRACE("EM_GETLINE: got %u characters\n", nMaxChars - nCharsLeft);
3771 return nMaxChars - nCharsLeft;
3772 }
3773 case EM_GETLINECOUNT:
3774 {
3775 int count = editor->total_rows;
3776 ME_Run *prev_run, *last_run;
3777
3778 last_run = para_end_run( para_prev( editor_end_para( editor ) ) );
3779 prev_run = run_prev_all_paras( last_run );
3780
3781 if (editor->bEmulateVersion10 && prev_run && last_run->nCharOfs == 0 &&
3782 prev_run->len == 1 && *get_text( prev_run, 0 ) == '\r')
3783 {
3784 /* In 1.0 emulation, the last solitary \r at the very end of the text
3785 (if one exists) is NOT a line break.
3786 FIXME: this is an ugly hack. This should have a more regular model. */
3787 count--;
3788 }
3789
3790 count = max(1, count);
3791 TRACE("EM_GETLINECOUNT: count==%d\n", count);
3792 return count;
3793 }
3794 case EM_LINEFROMCHAR:
3795 {
3796 if (wParam == -1) wParam = ME_GetCursorOfs( editor->pCursors + 1 );
3797 return row_number_from_char_ofs( editor, wParam );
3798 }
3799 case EM_EXLINEFROMCHAR:
3800 {
3801 if (lParam == -1) lParam = ME_GetCursorOfs( editor->pCursors + 1 );
3802 return row_number_from_char_ofs( editor, lParam );
3803 }
3804 case EM_LINEINDEX:
3805 {
3806 ME_Row *row;
3808 int ofs;
3809
3810 if (wParam == -1) row = row_from_cursor( editor->pCursors );
3811 else row = row_from_row_number( editor, wParam );
3812 if (!row) return -1;
3813
3815 ofs = ME_GetCursorOfs( &cursor );
3816 TRACE( "EM_LINEINDEX: nCharOfs==%d\n", ofs );
3817 return ofs;
3818 }
3819 case EM_LINELENGTH:
3820 {
3821 ME_Row *row;
3822 int start_ofs, end_ofs;
3824
3825 if (wParam > ME_GetTextLength(editor))
3826 return 0;
3827 if (wParam == -1)
3828 {
3829 FIXME("EM_LINELENGTH: returning number of unselected characters on lines with selection unsupported.\n");
3830 return 0;
3831 }
3832 cursor_from_char_ofs( editor, wParam, &cursor );
3835 start_ofs = ME_GetCursorOfs( &cursor );
3837 end_ofs = ME_GetCursorOfs( &cursor );
3838 TRACE( "EM_LINELENGTH(%Id)==%d\n", wParam, end_ofs - start_ofs );
3839 return end_ofs - start_ofs;
3840 }
3841 case EM_EXLIMITTEXT:
3842 {
3843 if ((int)lParam < 0)
3844 return 0;
3845 if (lParam == 0)
3846 editor->nTextLimit = 65536;
3847 else
3848 editor->nTextLimit = (int) lParam;
3849 return 0;
3850 }
3851 case EM_LIMITTEXT:
3852 {
3853 if (wParam == 0)
3854 editor->nTextLimit = 65536;
3855 else
3856 editor->nTextLimit = (int) wParam;
3857 return 0;
3858 }
3859 case EM_GETLIMITTEXT:
3860 {
3861 return editor->nTextLimit;
3862 }
3863 case EM_FINDTEXT:
3864 case EM_FINDTEXTW:
3865 {
3866 FINDTEXTW *ft = (FINDTEXTW *)lParam;
3867 return ME_FindText(editor, wParam, &ft->chrg, ft->lpstrText, NULL);
3868 }
3869 case EM_FINDTEXTEX:
3870 case EM_FINDTEXTEXW:
3871 {
3873 return ME_FindText(editor, wParam, &ex->chrg, ex->lpstrText, &ex->chrgText);
3874 }
3875 case EM_GETZOOM:
3876 if (!wParam || !lParam)
3877 return FALSE;
3878 *(int *)wParam = editor->nZoomNumerator;
3879 *(int *)lParam = editor->nZoomDenominator;
3880 return TRUE;
3881 case EM_SETZOOM:
3882 return ME_SetZoom(editor, wParam, lParam);
3883 case EM_CHARFROMPOS:
3884 {
3886 POINTL *pt = (POINTL *)lParam;
3887
3888 cursor_from_coords(editor, pt->x, pt->y, &cursor);
3889 return ME_GetCursorOfs(&cursor);
3890 }
3891 case EM_POSFROMCHAR:
3892 {
3894 int nCharOfs, nLength;
3895 POINTL pt = {0,0};
3896
3897 nCharOfs = wParam;
3898 /* detect which API version we're dealing with */
3899 if (wParam >= 0x40000)
3900 nCharOfs = lParam;
3901 nLength = ME_GetTextLength(editor);
3902 nCharOfs = min(nCharOfs, nLength);
3903 nCharOfs = max(nCharOfs, 0);
3904
3905 cursor_from_char_ofs( editor, nCharOfs, &cursor );
3906 pt.y = cursor.run->pt.y;
3907 pt.x = cursor.run->pt.x +
3908 ME_PointFromChar( editor, cursor.run, cursor.nOffset, TRUE );
3909 pt.y += cursor.para->pt.y + editor->rcFormat.top;
3910 pt.x += editor->rcFormat.left;
3911
3912 pt.x -= editor->horz_si.nPos;
3913 pt.y -= editor->vert_si.nPos;
3914
3915 if (wParam >= 0x40000) *(POINTL *)wParam = pt;
3916
3917 return (wParam >= 0x40000) ? 0 : MAKELONG( pt.x, pt.y );
3918 }
3919 case WM_LBUTTONDBLCLK:
3920 case WM_LBUTTONDOWN:
3921 {
3922 ME_CommitUndo(editor); /* End coalesced undos for typed characters */
3924 ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam),
3927 editor->bMouseCaptured = TRUE;
3928 link_notify( editor, msg, wParam, lParam );
3929 break;
3930 }
3931 case WM_MOUSEMOVE:
3932 if (editor->bMouseCaptured)
3933 ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
3934 else
3935 link_notify( editor, msg, wParam, lParam );
3936 break;
3937 case WM_LBUTTONUP:
3938 if (editor->bMouseCaptured) {
3940 editor->bMouseCaptured = FALSE;
3941 }
3942 if (editor->nSelectionType == stDocument)
3943 editor->nSelectionType = stPosition;
3944 else
3945 {
3946 link_notify( editor, msg, wParam, lParam );
3947 }
3948 break;
3949 case WM_RBUTTONUP:
3950 case WM_RBUTTONDOWN:
3951 case WM_RBUTTONDBLCLK:
3952 ME_CommitUndo(editor); /* End coalesced undos for typed characters */
3953 link_notify( editor, msg, wParam, lParam );
3954 goto do_default;
3955 case WM_CONTEXTMENU:
3956 if (!ME_ShowContextMenu(editor, (short)LOWORD(lParam), (short)HIWORD(lParam)))
3957 goto do_default;
3958 break;
3959 case WM_SETFOCUS:
3960 editor->bHaveFocus = TRUE;
3961 create_caret(editor);
3962 update_caret(editor);
3964 if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION))
3965 ME_InvalidateSelection( editor );
3966 return 0;
3967 case WM_KILLFOCUS:
3968 ME_CommitUndo(editor); /* End coalesced undos for typed characters */
3969 editor->bHaveFocus = FALSE;
3970 editor->wheel_remain = 0;
3971 hide_caret(editor);
3972 DestroyCaret();
3974 if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION))
3975 ME_InvalidateSelection( editor );
3976 return 0;
3977 case WM_COMMAND:
3978 TRACE("editor wnd command = %d\n", LOWORD(wParam));
3979 return 0;
3980 case WM_KEYDOWN:
3981 if (ME_KeyDown(editor, LOWORD(wParam)))
3982 return 0;
3983 goto do_default;
3984 case WM_CHAR:
3985 return handle_wm_char( editor, wParam, lParam );
3986 case WM_UNICHAR:
3987 if (wParam == UNICODE_NOCHAR) return TRUE;
3988 if (wParam <= 0x000fffff)
3989 {
3990 if (wParam > 0xffff) /* convert to surrogates */
3991 {
3992 wParam -= 0x10000;
3993 handle_wm_char( editor, (wParam >> 10) + 0xd800, 0 );
3994 handle_wm_char( editor, (wParam & 0x03ff) + 0xdc00, 0 );
3995 }
3996 else
3997 handle_wm_char( editor, wParam, 0 );
3998 }
3999 return 0;
4000 case EM_STOPGROUPTYPING:
4001 ME_CommitUndo(editor); /* End coalesced undos for typed characters */
4002 return 0;
4003 case WM_HSCROLL:
4004 {
4005 const int scrollUnit = 7;
4006
4007 switch(LOWORD(wParam))
4008 {
4009 case SB_LEFT:
4010 scroll_abs( editor, 0, 0, TRUE );
4011 break;
4012 case SB_RIGHT:
4013 scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage,
4014 editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE );
4015 break;
4016 case SB_LINELEFT:
4017 ME_ScrollLeft(editor, scrollUnit);
4018 break;
4019 case SB_LINERIGHT:
4020 ME_ScrollRight(editor, scrollUnit);
4021 break;
4022 case SB_PAGELEFT:
4023 ME_ScrollLeft(editor, editor->sizeWindow.cx);
4024 break;
4025 case SB_PAGERIGHT:
4026 ME_ScrollRight(editor, editor->sizeWindow.cx);
4027 break;
4028 case SB_THUMBTRACK:
4029 case SB_THUMBPOSITION:
4030 {
4031 int pos = HIWORD(wParam);
4032 if (editor->horz_si.nMax > 0xffff)
4033 pos = MulDiv(pos, editor->horz_si.nMax, 0xffff);
4034 scroll_h_abs( editor, pos, FALSE );
4035 break;
4036 }
4037 }
4038 break;
4039 }
4040 case EM_SCROLL: /* fall through */
4041 case WM_VSCROLL:
4042 {
4043 int origNPos;
4044 int lineHeight = get_default_line_height( editor );
4045
4046 origNPos = editor->vert_si.nPos;
4047
4048 switch(LOWORD(wParam))
4049 {
4050 case SB_TOP:
4051 scroll_abs( editor, 0, 0, TRUE );
4052 break;
4053 case SB_BOTTOM:
4054 scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage,
4055 editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE );
4056 break;
4057 case SB_LINEUP:
4058 ME_ScrollUp(editor,lineHeight);
4059 break;
4060 case SB_LINEDOWN:
4061 ME_ScrollDown(editor,lineHeight);
4062 break;
4063 case SB_PAGEUP:
4064 ME_ScrollUp(editor,editor->sizeWindow.cy);
4065 break;
4066 case SB_PAGEDOWN:
4067 ME_ScrollDown(editor,editor->sizeWindow.cy);
4068 break;
4069 case SB_THUMBTRACK:
4070 case SB_THUMBPOSITION:
4071 {
4072 int pos = HIWORD(wParam);
4073 if (editor->vert_si.nMax > 0xffff)
4074 pos = MulDiv(pos, editor->vert_si.nMax, 0xffff);
4075 scroll_v_abs( editor, pos, FALSE );
4076 break;
4077 }
4078 }
4079 if (msg == EM_SCROLL)
4080 return 0x00010000 | (((editor->vert_si.nPos - origNPos)/lineHeight) & 0xffff);
4081 break;
4082 }
4083 case WM_MOUSEWHEEL:
4084 {
4085 int delta = GET_WHEEL_DELTA_WPARAM( wParam );
4086 BOOL ctrl_is_down = GetKeyState( VK_CONTROL ) & 0x8000;
4087
4088 /* if scrolling changes direction, ignore left overs */
4089 if ((delta < 0 && editor->wheel_remain < 0) ||
4090 (delta > 0 && editor->wheel_remain > 0))
4091 editor->wheel_remain += delta;
4092 else
4093 editor->wheel_remain = delta;
4094
4095 if (editor->wheel_remain)
4096 {
4097 if (ctrl_is_down) {
4098 int numerator;
4099 if (!editor->nZoomNumerator || !editor->nZoomDenominator)
4100 {
4101 numerator = 100;
4102 } else {
4103 numerator = editor->nZoomNumerator * 100 / editor->nZoomDenominator;
4104 }
4105 numerator += calc_wheel_change( &editor->wheel_remain, 10 );
4106 if (numerator >= 10 && numerator <= 500)
4107 ME_SetZoom(editor, numerator, 100);
4108 } else {
4109 UINT max_lines = 3;
4110 int lines = 0;
4111
4112 SystemParametersInfoW( SPI_GETWHEELSCROLLLINES, 0, &max_lines, 0 );
4113 if (max_lines)
4114 lines = calc_wheel_change( &editor->wheel_remain, (int)max_lines );
4115 if (lines)
4116 ME_ScrollDown( editor, -lines * get_default_line_height( editor ) );
4117 }
4118 }
4119 break;
4120 }
4121 case EM_REQUESTRESIZE:
4122 ME_SendRequestResize(editor, TRUE);
4123 return 0;
4124#ifndef __REACTOS__
4125 /* IME messages to make richedit controls IME aware */
4126#endif
4127 case WM_IME_SETCONTEXT:
4128#ifdef __REACTOS__
4129 {
4130 if (FALSE) /* FIXME: Condition */
4131 lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
4132
4133 if (wParam)
4134 {
4135 HIMC hIMC = ImmGetContext(editor->hWnd);
4137 if (pIC)
4138 {
4139 pIC->dwUIFlags &= ~0x40000;
4140 ImmUnlockIMC(hIMC);
4141 }
4142 if (FALSE) /* FIXME: Condition */
4144 ImmReleaseContext(editor->hWnd, hIMC);
4145 }
4146
4147 return DefWindowProcW(editor->hWnd, msg, wParam, lParam);
4148 }
4149#endif
4150 case WM_IME_CONTROL:
4151#ifdef __REACTOS__
4152 return DefWindowProcW(editor->hWnd, msg, wParam, lParam);
4153#endif
4154 case WM_IME_SELECT:
4155#ifdef __REACTOS__
4156 return DefWindowProcW(editor->hWnd, msg, wParam, lParam);
4157#endif
4159 return 0;
4160 case WM_IME_STARTCOMPOSITION:
4161 {
4162#ifdef __REACTOS__
4163 return DefWindowProcW(editor->hWnd, msg, wParam, lParam);
4164#else
4165 editor->imeStartIndex=ME_GetCursorOfs(&editor->pCursors[0]);
4166 ME_DeleteSelection(editor);
4167 ME_CommitUndo(editor);
4168 ME_UpdateRepaint(editor, FALSE);
4169#endif
4170 return 0;
4171 }
4172 case WM_IME_COMPOSITION:
4173 {
4174 HIMC hIMC;
4175
4176 ME_Style *style = style_get_insert_style( editor, editor->pCursors );
4177 hIMC = ITextHost_TxImmGetContext(editor->texthost);
4178 ME_DeleteSelection(editor);
4179 ME_SaveTempStyle(editor, style);
4181 {
4182 LPWSTR lpCompStr = NULL;
4184 DWORD dwIndex = lParam & GCS_RESULTSTR;
4185 if (!dwIndex)
4186 dwIndex = GCS_COMPSTR;
4187
4188 dwBufLen = ImmGetCompositionStringW(hIMC, dwIndex, NULL, 0);
4189 lpCompStr = malloc(dwBufLen + sizeof(WCHAR));
4190 ImmGetCompositionStringW(hIMC, dwIndex, lpCompStr, dwBufLen);
4191 lpCompStr[dwBufLen/sizeof(WCHAR)] = 0;
4192#ifndef __REACTOS__
4193 ME_InsertTextFromCursor(editor,0,lpCompStr,dwBufLen/sizeof(WCHAR),style);
4194#endif
4195 free(lpCompStr);
4196
4197#ifndef __REACTOS__
4198 if (dwIndex == GCS_COMPSTR)
4199 set_selection_cursors(editor,editor->imeStartIndex,
4200 editor->imeStartIndex + dwBufLen/sizeof(WCHAR));
4201 else
4202 editor->imeStartIndex = ME_GetCursorOfs(&editor->pCursors[0]);
4203#endif
4204 }
4207 ME_CommitUndo(editor);
4208 ME_UpdateRepaint(editor, FALSE);
4209#ifdef __REACTOS__
4210 return DefWindowProcW(editor->hWnd, msg, wParam, lParam);
4211#else
4212 return 0;
4213#endif
4214 }
4215 case WM_IME_ENDCOMPOSITION:
4216 {
4217#ifdef __REACTOS__
4218 return DefWindowProcW(editor->hWnd, msg, wParam, lParam);
4219#else
4220 ME_DeleteSelection(editor);
4221 editor->imeStartIndex=-1;
4222 return 0;
4223#endif
4224 }
4225 case EM_GETOLEINTERFACE:
4226 IRichEditOle_AddRef( editor->richole );
4227 *(IRichEditOle **)lParam = editor->richole;
4228 return 1;
4229
4230 case EM_SETOLECALLBACK:
4231 if(editor->lpOleCallback)
4232 IRichEditOleCallback_Release(editor->lpOleCallback);
4234 if(editor->lpOleCallback)
4235 IRichEditOleCallback_AddRef(editor->lpOleCallback);
4236 return TRUE;
4238 return (LRESULT)editor->pfnWordBreak;
4240 {
4241 EDITWORDBREAKPROCW pfnOld = editor->pfnWordBreak;
4242
4244 return (LRESULT)pfnOld;
4245 }
4246 case EM_GETTEXTMODE:
4247 return editor->mode;
4248 case EM_SETTEXTMODE:
4249 {
4250 int mask = 0;
4251 int changes = 0;
4252
4253 if (ME_GetTextLength(editor) ||
4254 !list_empty( &editor->undo_stack ) || !list_empty( &editor->redo_stack ))
4255 return E_UNEXPECTED;
4256
4257 /* Check for mutually exclusive flags in adjacent bits of wParam */
4260 return E_INVALIDARG;
4261
4263 {
4266 if (wParam & TM_PLAINTEXT) {
4267 /* Clear selection since it should be possible to select the
4268 * end of text run for rich text */
4269 ME_InvalidateSelection(editor);
4270 ME_SetCursorToStart(editor, &editor->pCursors[0]);
4271 editor->pCursors[1] = editor->pCursors[0];
4272 /* plain text can only have the default style. */
4273 ME_ClearTempStyle(editor);
4275 ME_ReleaseStyle( editor->pCursors[0].run->style );
4276 editor->pCursors[0].run->style = editor->pBuffer->pDefaultStyle;
4277 }
4278 }
4279 /* FIXME: Currently no support for undo level and code page options */
4280 editor->mode = (editor->mode & ~mask) | changes;
4281 return 0;
4282 }
4283 case EM_SETTARGETDEVICE:
4284 if (wParam == 0)
4285 {
4286 BOOL new = (lParam == 0 && (editor->props & TXTBIT_MULTILINE));
4287 if (editor->nAvailWidth || editor->bWordWrap != new)
4288 {
4289 editor->bWordWrap = new;
4290 editor->nAvailWidth = 0; /* wrap to client area */
4291 ME_RewrapRepaint(editor);
4292 }
4293 } else {
4294 int width = max(0, lParam);
4295 if ((editor->props & TXTBIT_MULTILINE) &&
4296 (!editor->bWordWrap || editor->nAvailWidth != width))
4297 {
4298 editor->nAvailWidth = width;
4299 editor->bWordWrap = TRUE;
4300 ME_RewrapRepaint(editor);
4301 }
4302 FIXME("EM_SETTARGETDEVICE doesn't use non-NULL target devices\n");
4303 }
4304 return TRUE;
4305 default:
4306 do_default:
4307 *phresult = S_FALSE;
4308 break;
4309 }
4310 return 0L;
4311}
4312
4313/* Fill buffer with srcChars unicode characters from the start cursor.
4314 *
4315 * buffer: destination buffer
4316 * buflen: length of buffer in characters excluding the NULL terminator.
4317 * start: start of editor text to copy into buffer.
4318 * srcChars: Number of characters to use from the editor text.
4319 * bCRLF: if true, replaces all end of lines with \r\n pairs.
4320 *
4321 * returns the number of characters written excluding the NULL terminator.
4322 *
4323 * The written text is always NULL terminated.
4324 */
4325int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
4326 const ME_Cursor *start, int srcChars, BOOL bCRLF,
4327 BOOL bEOP)
4328{
4329 ME_Run *run, *next_run;
4330 const WCHAR *pStart = buffer;
4331 const WCHAR *str;
4332 int nLen;
4333
4334 /* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */
4335 if (editor->bEmulateVersion10) bCRLF = FALSE;
4336
4337 run = start->run;
4338 next_run = run_next_all_paras( run );
4339
4340 nLen = run->len - start->nOffset;
4341 str = get_text( run, start->nOffset );
4342
4343 while (srcChars && buflen && next_run)
4344 {
4345 if (bCRLF && run->nFlags & MERF_ENDPARA && ~run->nFlags & MERF_ENDCELL)
4346 {
4347 if (buflen == 1) break;
4348 /* FIXME: native fails to reduce srcChars here for WM_GETTEXT or
4349 * EM_GETTEXTEX, however, this is done for copying text which
4350 * also uses this function. */
4351 srcChars -= min(nLen, srcChars);
4352 nLen = 2;
4353 str = L"\r\n";
4354 }
4355 else
4356 {
4357 nLen = min(nLen, srcChars);
4358 srcChars -= nLen;
4359 }
4360
4361 nLen = min(nLen, buflen);
4362 buflen -= nLen;
4363
4364 CopyMemory(buffer, str, sizeof(WCHAR) * nLen);
4365
4366 buffer += nLen;
4367
4368 run = next_run;
4369 next_run = run_next_all_paras( run );
4370
4371 nLen = run->len;
4372 str = get_text( run, 0 );
4373 }
4374 /* append '\r' to the last paragraph. */
4375 if (run == para_end_run( para_prev( editor_end_para( editor ) ) ) && bEOP && buflen)
4376 {
4377 *buffer = '\r';
4378 buffer ++;
4379 }
4380 *buffer = 0;
4381 return buffer - pStart;
4382}
4383
4384static int __cdecl wchar_comp( const void *key, const void *elem )
4385{
4386 return *(const WCHAR *)key - *(const WCHAR *)elem;
4387}
4388
4389/* neutral characters end the url if the next non-neutral character is a space character,
4390 otherwise they are included in the url. */
4392{
4393 /* NB this list is sorted */
4394 static const WCHAR neutral_chars[] = L"!\"'(),-.:;<>?[]{}";
4395
4396 /* Some shortcuts */
4397 if (isalnum( c )) return FALSE;
4398 if (c > L'}') return FALSE;
4399
4400 return !!bsearch( &c, neutral_chars, ARRAY_SIZE( neutral_chars ) - 1, sizeof(c), wchar_comp );
4401}
4402
4411 const ME_Cursor *start,
4412 int nChars,
4413 ME_Cursor *candidate_min,
4414 ME_Cursor *candidate_max)
4415{
4416 ME_Cursor cursor = *start, neutral_end, space_end;
4417 BOOL candidateStarted = FALSE, quoted = FALSE;
4418 WCHAR c;
4419
4420 while (nChars > 0)
4421 {
4422 WCHAR *str = get_text( cursor.run, 0 );
4423 int run_len = cursor.run->len;
4424
4425 nChars -= run_len - cursor.nOffset;
4426
4427 /* Find start of candidate */
4428 if (!candidateStarted)
4429 {
4430 while (cursor.nOffset < run_len)
4431 {
4432 c = str[cursor.nOffset];
4433 if (!iswspace( c ) && !isurlneutral( c ))
4434 {
4435 *candidate_min = cursor;
4436 candidateStarted = TRUE;
4437 neutral_end.para = NULL;
4438 space_end.para = NULL;
4439 cursor.nOffset++;
4440 break;
4441 }
4442 quoted = (c == '<');
4443 cursor.nOffset++;
4444 }
4445 }
4446
4447 /* Find end of candidate */
4448 if (candidateStarted)
4449 {
4450 while (cursor.nOffset < run_len)
4451 {
4452 c = str[cursor.nOffset];
4453 if (iswspace( c ))
4454 {
4455 if (quoted && c != '\r')
4456 {
4457 if (!space_end.para)
4458 {
4459 if (neutral_end.para)
4460 space_end = neutral_end;
4461 else
4462 space_end = cursor;
4463 }
4464 }
4465 else
4466 goto done;
4467 }
4468 else if (isurlneutral( c ))
4469 {
4470 if (quoted && c == '>')
4471 {
4472 neutral_end.para = NULL;
4473 space_end.para = NULL;
4474 goto done;
4475 }
4476 if (!neutral_end.para)
4477 neutral_end = cursor;
4478 }
4479 else
4480 neutral_end.para = NULL;
4481
4482 cursor.nOffset++;
4483 }
4484 }
4485
4486 cursor.nOffset = 0;
4487 if (!cursor_next_run( &cursor, TRUE ))
4488 goto done;
4489 }
4490
4491done:
4492 if (candidateStarted)
4493 {
4494 if (space_end.para)
4495 *candidate_max = space_end;
4496 else if (neutral_end.para)
4497 *candidate_max = neutral_end;
4498 else
4499 *candidate_max = cursor;
4500 return TRUE;
4501 }
4502 *candidate_max = *candidate_min = cursor;
4503 return FALSE;
4504}
4505
4509static BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
4510{
4511#define MAX_PREFIX_LEN 9
4512#define X(str) str, ARRAY_SIZE(str) - 1
4513 struct prefix_s {
4514#ifdef __REACTOS__
4515 const WCHAR text[MAX_PREFIX_LEN + 1];
4516#else
4517 const WCHAR text[MAX_PREFIX_LEN];
4518#endif
4519 int length;
4520 }prefixes[] = {
4521 {X(L"prospero:")},
4522 {X(L"telnet:")},
4523 {X(L"gopher:")},
4524 {X(L"mailto:")},
4525 {X(L"https:")},
4526 {X(L"file:")},
4527 {X(L"news:")},
4528 {X(L"wais:")},
4529 {X(L"nntp:")},
4530 {X(L"http:")},
4531 {X(L"www.")},
4532 {X(L"ftp:")},
4533 };
4534#undef X
4535 WCHAR bufferW[MAX_PREFIX_LEN + 1];
4536 unsigned int i;
4537
4538 ME_GetTextW(editor, bufferW, MAX_PREFIX_LEN, start, nChars, FALSE, FALSE);
4539 for (i = 0; i < ARRAY_SIZE(prefixes); i++)
4540 {
4541 if (nChars < prefixes[i].length) continue;
4542 if (!memcmp(prefixes[i].text, bufferW, prefixes[i].length * sizeof(WCHAR)))
4543 return TRUE;
4544 }
4545 return FALSE;
4546#undef MAX_PREFIX_LEN
4547}
4548
4563{
4564 BOOL modified = FALSE;
4565 ME_Cursor startCur = *start;
4566
4567 if (!editor->AutoURLDetect_bEnable) return FALSE;
4568
4569 do
4570 {
4572 ME_Cursor candidateStart, candidateEnd;
4573
4574 if (ME_FindNextURLCandidate(editor, &startCur, nChars,
4575 &candidateStart, &candidateEnd))
4576 {
4577 /* Section before candidate is not an URL */
4578 int cMin = ME_GetCursorOfs(&candidateStart);
4579 int cMax = ME_GetCursorOfs(&candidateEnd);
4580
4581 if (!ME_IsCandidateAnURL(editor, &candidateStart, cMax - cMin))
4582 candidateStart = candidateEnd;
4583 nChars -= cMax - ME_GetCursorOfs(&startCur);
4584 }
4585 else
4586 {
4587 /* No more candidates until end of selection */
4588 nChars = 0;
4589 }
4590
4591 if (startCur.run != candidateStart.run ||
4592 startCur.nOffset != candidateStart.nOffset)
4593 {
4594 /* CFE_LINK effect should be consistently unset */
4595 link.cbSize = sizeof(link);
4596 ME_GetCharFormat(editor, &startCur, &candidateStart, &link);
4597 if (!(link.dwMask & CFM_LINK) || (link.dwEffects & CFE_LINK))
4598 {
4599 /* CFE_LINK must be unset from this range */
4600 memset(&link, 0, sizeof(CHARFORMAT2W));
4601 link.cbSize = sizeof(link);
4602 link.dwMask = CFM_LINK;
4603 link.dwEffects = 0;
4604 ME_SetCharFormat(editor, &startCur, &candidateStart, &link);
4605 /* Update candidateEnd since setting character formats may split
4606 * runs, which can cause a cursor to be at an invalid offset within
4607 * a split run. */
4608 while (candidateEnd.nOffset >= candidateEnd.run->len)
4609 {
4610 candidateEnd.nOffset -= candidateEnd.run->len;
4611 candidateEnd.run = run_next_all_paras( candidateEnd.run );
4612 }
4613 modified = TRUE;
4614 }
4615 }
4616 if (candidateStart.run != candidateEnd.run ||
4617 candidateStart.nOffset != candidateEnd.nOffset)
4618 {
4619 /* CFE_LINK effect should be consistently set */
4620 link.cbSize = sizeof(link);
4621 ME_GetCharFormat(editor, &candidateStart, &candidateEnd, &link);
4622 if (!(link.dwMask & CFM_LINK) || !(link.dwEffects & CFE_LINK))
4623 {
4624 /* CFE_LINK must be set on this range */
4625 memset(&link, 0, sizeof(CHARFORMAT2W));
4626 link.cbSize = sizeof(link);
4627 link.dwMask = CFM_LINK;
4628 link.dwEffects = CFE_LINK;
4629 ME_SetCharFormat(editor, &candidateStart, &candidateEnd, &link);
4630 modified = TRUE;
4631 }
4632 }
4633 startCur = candidateEnd;
4634 } while (nChars > 0);
4635 return modified;
4636}
static HDC hDC
Definition: 3dtext.c:33
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define __cdecl
Definition: accygwin.h:79
#define read
Definition: acwin.h:96
Arabic default style
Definition: afstyles.h:94
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define CF_UNICODETEXT
Definition: constants.h:408
#define CF_BITMAP
Definition: constants.h:397
#define CF_ENHMETAFILE
Definition: constants.h:409
#define CF_TEXT
Definition: constants.h:396
#define ARRAY_SIZE(A)
Definition: main.h:20
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_init(struct list_entry *head)
Definition: list.h:51
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
HBITMAP hbmp
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define FR_WHOLEWORD
Definition: commdlg.h:145
#define FR_MATCHCASE
Definition: commdlg.h:136
#define FR_DOWN
Definition: commdlg.h:127
_In_ size_t character_count
int selection
Definition: ctm.c:92
const WCHAR * link
Definition: db.cpp:997
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
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 const WCHAR indent[]
Definition: object.c:1156
#define CP_ACP
Definition: compat.h:109
HANDLE HWND
Definition: compat.h:19
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
static const char bom_utf8[]
Definition: profile.c:51
const WCHAR * text
Definition: package.c:1794
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2199
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2249
HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
#define CP_UNICODE
Definition: stg_prop.c:74
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor)
Definition: caret.c:568
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:27
BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
Definition: caret.c:481
BOOL ME_IsSelection(ME_TextEditor *editor)
Definition: caret.c:1419
void ME_DeleteSelection(ME_TextEditor *editor)
Definition: caret.c:1425
int ME_GetCursorOfs(const ME_Cursor *cursor)
Definition: caret.c:923
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, const WCHAR *str, int len, ME_Style *style)
Definition: caret.c:584
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:709
BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
Definition: caret.c:789
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum)
Definition: caret.c:1156
int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
Definition: caret.c:91
BOOL cursor_from_coords(ME_TextEditor *editor, int x, int y, ME_Cursor *cursor)
Definition: caret.c:1070
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
void ME_MouseMove(ME_TextEditor *editor, int x, int y)
Definition: caret.c:1218
HRESULT editor_insert_oleobj(ME_TextEditor *editor, const REOBJECT *reo)
Definition: caret.c:504
void ME_SendSelChange(ME_TextEditor *editor)
Definition: caret.c:1439
int set_selection_cursors(ME_TextEditor *editor, int from, int to)
Definition: caret.c:132
int ME_GetSelectionOfs(ME_TextEditor *editor, LONG *from, LONG *to)
Definition: caret.c:42
BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
Definition: caret.c:1471
void create_caret(ME_TextEditor *editor)
Definition: caret.c:251
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
void update_caret(ME_TextEditor *editor)
Definition: caret.c:277
ME_Style * ME_GetSelectionInsertStyle(ME_TextEditor *editor)
Definition: caret.c:1434
HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start, int nChars, IDataObject **dataobj)
Definition: clipboard.c:402
static struct paste_format paste_formats[]
static void ME_StreamInRTFString(ME_TextEditor *editor, BOOL selection, char *string)
Definition: editor.c:1834
static void ME_RTFReadParnumGroup(RTF_Info *info)
Definition: editor.c:1420
static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BOOL check_only)
Definition: editor.c:2285
#define UNSUPPORTED_MSG(e)
Definition: editor.c:3255
static int ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCHAR *text, CHARRANGE *chrgText)
Definition: editor.c:1849
static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HBITMAP hbmp, const SIZEL *sz)
Definition: editor.c:1121
static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream, BOOL stripLastCR)
Definition: editor.c:1571
static void ME_RTFReadShpPictGroup(RTF_Info *info)
Definition: editor.c:1192
static void ME_SetText(ME_TextEditor *editor, void *text, BOOL unicode)
Definition: editor.c:3195
static HRESULT paste_emf(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med)
Definition: editor.c:2239
void ME_ReplaceSel(ME_TextEditor *editor, BOOL can_undo, const WCHAR *str, int len)
Definition: editor.c:3170
static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
Definition: editor.c:2398
static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
Definition: editor.c:2192
struct tagME_RTFStringStreamStruct ME_RTFStringStreamStruct
ME_Paragraph * editor_first_para(ME_TextEditor *editor)
Definition: editor.c:276
static BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
Definition: editor.c:4509
static DWORD CALLBACK ME_ReadFromHGLOBALUnicode(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
Definition: editor.c:2174
static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
Definition: editor.c:2914
static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, const ME_Cursor *start, int nChars, ME_Cursor *candidate_min, ME_Cursor *candidate_max)
Definition: editor.c:4410
#define STACK_SIZE_MAX
Definition: editor.c:245
static BOOL editor_beep(ME_TextEditor *editor, UINT type)
Definition: editor.c:287
void ME_StreamInFill(ME_InStream *stream)
Definition: editor.c:1562
static void ME_RTFReadHook(RTF_Info *info)
Definition: editor.c:1524
static LRESULT handle_EM_SETCHARFORMAT(ME_TextEditor *editor, WPARAM flags, const CHARFORMAT2W *fmt_in)
Definition: editor.c:3205
static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText)
Definition: editor.c:2092
static HRESULT paste_rtf(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med)
Definition: editor.c:2209
static int calc_wheel_change(int *remain, int amount_per_click)
Definition: editor.c:3126
void ME_RTFTblAttrHook(RTF_Info *info)
Definition: editor.c:869
HINSTANCE dll_instance
Definition: editor.c:253
ME_TextEditor * ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
Definition: editor.c:2936
static ME_TextBuffer * ME_MakeText(void)
Definition: editor.c:256
#define MAX_PREFIX_LEN
static int get_text_range(ME_TextEditor *editor, WCHAR *buffer, const ME_Cursor *start, int len)
Definition: editor.c:2144
#define STACK_SIZE_DEFAULT
Definition: editor.c:244
static BOOL copy_or_cut(ME_TextEditor *editor, BOOL cut)
Definition: editor.c:2382
void ME_RTFCharAttrHook(RTF_Info *info)
Definition: editor.c:425
static int get_default_line_height(ME_TextEditor *editor)
Definition: editor.c:3115
static HRESULT paste_text(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med)
Definition: editor.c:2224
static void init_paste_formats(void)
Definition: editor.c:2269
HRESULT editor_copy_or_cut(ME_TextEditor *editor, BOOL cut, ME_Cursor *start, int count, IDataObject **data_out)
Definition: editor.c:2362
static void ME_ApplyBorderProperties(RTF_Info *info, ME_BorderRect *borderRect, RTFBorder *borderDef)
Definition: editor.c:399
#define TEXT_LIMIT_DEFAULT
Definition: editor.c:247
static BOOL isurlneutral(WCHAR c)
Definition: editor.c:4391
static void ME_RTFReadPictGroup(RTF_Info *info)
Definition: editor.c:1267
static LONG ME_GetSelectionType(ME_TextEditor *editor)
Definition: editor.c:2875
void editor_set_cursor(ME_TextEditor *editor, int x, int y)
Definition: editor.c:2831
struct tagME_GlobalDestStruct ME_GlobalDestStruct
static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int nChars)
Definition: editor.c:4562
void ME_RTFSpecialCharHook(RTF_Info *info)
Definition: editor.c:943
static DWORD CALLBACK ME_ReadFromRTFString(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG cb, LONG *pcb)
Definition: editor.c:1821
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, const ME_Cursor *start, int srcChars, BOOL bCRLF, BOOL bEOP)
Definition: editor.c:4325
static BOOL is_link(ME_Run *run)
Definition: editor.c:2826
void ME_RTFParAttrHook(RTF_Info *info)
Definition: editor.c:556
LRESULT editor_handle_message(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam, HRESULT *phresult)
Definition: editor.c:3266
static void ME_RTFReadObjectGroup(RTF_Info *info)
Definition: editor.c:1380
BOOL me_debug
Definition: editor.c:254
static LRESULT handle_wm_char(ME_TextEditor *editor, WCHAR wstr, LPARAM flags)
Definition: editor.c:2690
void ME_DestroyEditor(ME_TextEditor *editor)
Definition: editor.c:3077
static int __cdecl wchar_comp(const void *key, const void *elem)
Definition: editor.c:4384
static BOOL ME_KeyDown(ME_TextEditor *editor, WORD nKey)
Definition: editor.c:2567
static HRESULT editor_copy(ME_TextEditor *editor, ME_Cursor *start, int chars, IDataObject **data_out)
Definition: editor.c:2332
#define X(str)
static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStream *stream, ME_Style *style)
Definition: editor.c:292
static DWORD read_hex_data(RTF_Info *info, BYTE **out)
Definition: editor.c:1221
void link_notify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: editor.c:3133
ME_Paragraph * editor_end_para(ME_TextEditor *editor)
Definition: editor.c:282
static BOOL handle_enter(ME_TextEditor *editor)
Definition: editor.c:2423
static int ME_CalculateClickCount(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: editor.c:2776
int RTFCheckCM(const RTF_Info *info, int class, int major)
Definition: reader.c:2256
void RTFDestroy(RTF_Info *info)
Definition: reader.c:144
void RTFSetEditStream(RTF_Info *info, ME_InStream *stream)
Definition: reader.c:99
int RTFCharToHex(char c)
Definition: reader.c:2277
int BeginFile(RTF_Info *info)
Definition: reader.c:2315
int RTFGetToken(RTF_Info *info)
Definition: reader.c:389
void RTFRead(RTF_Info *info)
Definition: reader.c:291
RTFFont * RTFGetFont(const RTF_Info *info, int num)
Definition: reader.c:1205
void RTFRouteToken(RTF_Info *info)
Definition: reader.c:304
void RTFInit(RTF_Info *info)
Definition: reader.c:195
int RTFCheckMM(const RTF_Info *info, int major, int minor)
Definition: reader.c:2268
void RTFFlushOutputBuffer(RTF_Info *info)
Definition: reader.c:2606
RTFColor * RTFGetColor(const RTF_Info *info, int num)
Definition: reader.c:1220
void RTFSetReadHook(RTF_Info *info, RTFFuncPtr f)
Definition: reader.c:371
void RTFSkipGroup(RTF_Info *info)
Definition: reader.c:337
void RTFSetDestinationCallback(RTF_Info *info, int dest, RTFFuncPtr callback)
Definition: reader.c:264
int RTFCheckCMM(const RTF_Info *info, int class, int major, int minor)
Definition: reader.c:2262
void WriterInit(RTF_Info *info)
Definition: reader.c:2309
void RTFReadGroup(RTF_Info *info)
Definition: reader.c:362
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
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 assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
#define RGB(r, g, b)
Definition: precomp.h:71
ULONG RGBQUAD
Definition: precomp.h:59
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
void ME_InvalidateSelection(ME_TextEditor *editor)
Definition: paint.c:1253
void ME_RewrapRepaint(ME_TextEditor *editor)
Definition: paint.c:160
#define ITextHost_TxSetScrollRange(This, a, b, c, d)
Definition: editor.h:336
ME_Row * para_first_row(ME_Paragraph *para)
Definition: para.c:132
#define ITextHost_TxSetFocus(This)
Definition: editor.h:347
ME_Run * run_next(ME_Run *run)
Definition: run.c:68
void ME_ScrollRight(ME_TextEditor *editor, int cx)
Definition: paint.c:1146
void editor_get_selection_para_fmt(ME_TextEditor *editor, PARAFORMAT2 *fmt)
Definition: para.c:903
void ME_AddRefStyle(ME_Style *item)
Definition: style.c:454
void editor_set_default_para_fmt(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
Definition: para.c:958
void table_handle_tab(ME_TextEditor *editor, BOOL selected_row)
Definition: table.c:473
void ME_ScrollLeft(ME_TextEditor *editor, int cx)
Definition: paint.c:1141
ME_Style * style_get_insert_style(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: style.c:476
static int ME_CharCompare(WCHAR a, WCHAR b, int caseSensitive)
Definition: editor.h:103
ME_Paragraph * cell_first_para(ME_Cell *cell)
Definition: table.c:202
ME_Cell * cell_next(ME_Cell *cell)
Definition: table.c:192
#define ITextHost_TxGetPropertyBits(This, a, b)
Definition: editor.h:366
void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt)
Definition: run.c:782
void ME_ReleaseStyle(ME_Style *item)
Definition: style.c:462
void ME_ContinueCoalescingTransaction(ME_TextEditor *editor)
Definition: undo.c:265
#define ITextHost_TxImmReleaseContext(This, a)
Definition: editor.h:369
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator)
Definition: paint.c:1310
void para_destroy(ME_TextEditor *editor, ME_Paragraph *item)
Definition: para.c:42
ME_Cell * cell_prev(ME_Cell *cell)
Definition: table.c:197
#define ITextHost_TxGetBackStyle(This, a)
Definition: editor.h:358
BOOL cursor_next_run(ME_Cursor *cursor, BOOL all_para)
Definition: run.c:30
ME_Row * row_from_cursor(ME_Cursor *cursor)
Definition: row.c:74
void ME_UpdateScrollBar(ME_TextEditor *editor)
Definition: paint.c:1151
int row_number_from_char_ofs(ME_TextEditor *editor, int ofs)
Definition: row.c:131
void ME_CommitUndo(ME_TextEditor *editor)
Definition: undo.c:227
void ME_CommitCoalescingUndo(ME_TextEditor *editor)
Definition: undo.c:301
void ME_EndToUnicode(LONG codepage, LPVOID psz)
Definition: string.c:248
void ME_Repaint(ME_TextEditor *editor)
Definition: paint.c:121
BOOL cfany_to_cf2w(CHARFORMAT2W *to, const CHARFORMAT2W *from)
Definition: style.c:36
void ME_SaveTempStyle(ME_TextEditor *editor, ME_Style *style)
Definition: style.c:498
ME_Run * run_prev(ME_Run *run)
Definition: run.c:82
void scroll_h_abs(ME_TextEditor *editor, int x, BOOL notify)
Definition: paint.c:1121
BOOL ME_Undo(ME_TextEditor *editor)
Definition: undo.c:410
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
Definition: wrap.c:1103
#define ITextHost_TxSetCapture(This, a)
Definition: editor.h:346
ME_Style * ME_ApplyStyle(ME_TextEditor *ed, ME_Style *sSrc, CHARFORMAT2W *style)
Definition: style.c:156
ME_Paragraph * table_insert_row_end(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: table.c:119
void row_first_cursor(ME_Row *row, ME_Cursor *cursor)
Definition: row.c:82
#define ITextHost_TxNotify(This, a, b)
Definition: editor.h:367
void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048])
Definition: style.c:250
void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now)
Definition: paint.c:132
void ME_SendRequestResize(ME_TextEditor *editor, BOOL force)
Definition: wrap.c:1137
ME_Run * para_end_run(ME_Paragraph *para)
Definition: para.c:117
void ME_ScrollDown(ME_TextEditor *editor, int cy)
Definition: paint.c:1136
void editor_enable_undo(ME_TextEditor *editor)
Definition: undo.c:489
BOOL wrap_marked_paras_dc(ME_TextEditor *editor, HDC hdc, BOOL invalidate)
Definition: wrap.c:1032
ME_Cell * table_row_first_cell(ME_Paragraph *para)
Definition: table.c:170
ME_Paragraph * table_insert_row_start(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: table.c:72
ME_Cell * para_cell(ME_Paragraph *para)
Definition: para.c:127
void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from, const ME_Cursor *to, CHARFORMAT2W *pFmt)
Definition: run.c:876
ME_Paragraph * table_insert_cell(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: table.c:112
BOOL editor_set_selection_para_fmt(ME_TextEditor *editor, const PARAFORMAT2 *fmt)
Definition: para.c:873
#define ITextHost_TxGetDC(This)
Definition: editor.h:332
ME_Paragraph * table_append_row(ME_TextEditor *editor, ME_Paragraph *table_row)
Definition: table.c:327
BOOL ME_Redo(ME_TextEditor *editor)
Definition: undo.c:448
ME_Paragraph * table_insert_row_start_at_para(ME_TextEditor *editor, ME_Paragraph *para)
Definition: table.c:80
ME_Run * run_prev_all_paras(ME_Run *run)
Definition: run.c:110
void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt)
Definition: style.c:331
void scroll_v_abs(ME_TextEditor *editor, int y, BOOL notify)
Definition: paint.c:1126
BOOL cf2w_to_cfany(CHARFORMAT2W *to, const CHARFORMAT2W *from)
Definition: style.c:79
#define ITextHost_TxGetScrollBars(This, a)
Definition: editor.h:360
BOOL para_in_table(ME_Paragraph *para)
Definition: para.c:122
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order)
Definition: run.c:654
void row_end_cursor(ME_Row *row, ME_Cursor *cursor, BOOL include_eop)
Definition: row.c:92
#define ITextHost_TxGetSelectionBarWidth(This, a)
Definition: editor.h:370
ME_Run * row_next_run(ME_Row *row, ME_Run *run)
Definition: row.c:63
void table_move_from_row_start(ME_TextEditor *editor)
Definition: table.c:531
#define ITextHost_TxGetPasswordChar(This, a)
Definition: editor.h:361
LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
Definition: writer.c:1193
#define ITextHost_TxReleaseDC(This, a)
Definition: editor.h:333
#define ITextHost2_TxGetWindow(This, a)
Definition: editor.h:373
void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod)
Definition: style.c:524
void editor_mark_rewrap_all(ME_TextEditor *editor)
Definition: para.c:235
#define ITextHost_TxSetCursor(This, a, b)
Definition: editor.h:348
void para_mark_rewrap(ME_TextEditor *editor, ME_Paragraph *para)
Definition: para.c:26
void ME_MakeFirstParagraph(ME_TextEditor *editor, HDC hdc)
Definition: para.c:151
#define ITextHost_TxEnableScrollBar(This, a, b)
Definition: editor.h:335
ME_Run * para_first_run(ME_Paragraph *para)
Definition: para.c:104
#define ITextHost_TxImmGetContext(This)
Definition: editor.h:368
void cursor_from_char_ofs(ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor)
Definition: run.c:245
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
Definition: run.c:753
ME_Paragraph * para_prev(ME_Paragraph *para)
Definition: para.c:63
void ME_ClearTempStyle(ME_TextEditor *editor)
Definition: style.c:507
ME_Row * row_next(ME_Row *row)
Definition: row.c:27
struct RTFTable * ME_MakeTableDef(ME_TextEditor *editor)
Definition: table.c:547
void ME_ScrollUp(ME_TextEditor *editor, int cy)
Definition: paint.c:1131
void ME_EmptyUndoStack(ME_TextEditor *editor)
Definition: undo.c:53
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
Definition: run.c:858
void ME_DestroyDisplayItem(ME_DisplayItem *item)
Definition: list.c:115
void ME_CheckCharOffsets(ME_TextEditor *editor)
Definition: run.c:178
void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef)
Definition: table.c:556
void scroll_abs(ME_TextEditor *editor, int x, int y, BOOL notify)
Definition: paint.c:1091
ME_Paragraph * para_next(ME_Paragraph *para)
Definition: para.c:57
void ME_DestroyStyle(ME_Style *item)
Definition: style.c:442
ME_Row * row_from_row_number(ME_TextEditor *editor, int row_num)
Definition: row.c:111
LPWSTR ME_ToUnicode(LONG codepage, LPVOID psz, INT *len)
Definition: string.c:226
ME_Run * run_next_all_paras(ME_Run *run)
Definition: run.c:96
void editor_ensure_visible(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: paint.c:1210
ME_DisplayItem * ME_MakeDI(ME_DIType type)
Definition: list.c:133
void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
Definition: run.c:847
#define HFONT_CACHE_SIZE
Definition: editstr.h:67
#define MERF_ENDPARA
Definition: editstr.h:120
#define MERF_ENDCELL
Definition: editstr.h:107
#define MEPF_ROWSTART
Definition: editstr.h:142
#define MEPF_ROWEND
Definition: editstr.h:143
@ diTextEnd
Definition: editstr.h:87
@ diTextStart
Definition: editstr.h:82
@ diParagraph
Definition: editstr.h:83
#define STREAMIN_BUFFER_SIZE
Definition: editstr.h:376
@ umAddToUndo
Definition: editstr.h:281
@ umIgnore
Definition: editstr.h:283
@ undoActive
Definition: editstr.h:288
#define SELECTIONBAR_WIDTH
Definition: editstr.h:98
@ stPosition
Definition: editstr.h:363
@ stLine
Definition: editstr.h:365
@ stDocument
Definition: editstr.h:367
POINTL point
Definition: edittest.c:50
#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()
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: gl.h:1546
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
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 GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLenum GLint GLuint mask
Definition: glext.h:6028
GLfloat f
Definition: glext.h:7540
GLenum GLint * range
Definition: glext.h:7539
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
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
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define es
Definition: i386-dis.c:440
static int prefixes
Definition: i386-dis.c:276
const char cursor[]
Definition: icontest.c:13
BOOL WINAPI ImmSetCompositionFontW(_In_ HIMC hIMC, _In_ LPLOGFONTW lplf)
Definition: ime.c:1322
struct INPUTCONTEXTDX * LPINPUTCONTEXTDX
#define CPS_CANCEL
Definition: imm.h:181
#define GCS_RESULTSTR
Definition: imm.h:234
HIMC WINAPI ImmGetContext(_In_ HWND hWnd)
Definition: imm.c:1065
BOOL WINAPI ImmReleaseContext(_In_ HWND hWnd, _In_ HIMC hIMC)
Definition: imm.c:1109
#define GCS_COMPSTR
Definition: imm.h:227
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 iswspace(_c)
Definition: ctype.h:669
#define iswalnum(_c)
Definition: ctype.h:671
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define INT_MAX
Definition: intsafe.h:150
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
JSAMPARRAY JDIMENSION max_lines
Definition: jpeglib.h:1058
#define c
Definition: ke_i.h:80
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
char string[160]
Definition: util.h:11
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static size_t elem
Definition: string.c:71
static char * dest
Definition: rtl.c:135
static float(__cdecl *square_half_float)(float x
static UINT PSTR DWORD UINT * need
Definition: parser.c:36
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define set_selection(hctl, start, end)
#define min(a, b)
Definition: monoChain.cc:55
REFCLSID clsid
Definition: msctf.c:82
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
long object_count
Definition: nc_alloc.cpp:37
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
interface IStorage * LPSTORAGE
Definition: objfwd.h:30
interface IDataObject * LPDATAOBJECT
Definition: objfwd.h:21
const GUID IID_IOleCache
const GUID IID_IDataObject
const GUID IID_IOleObject
#define LOWORD(l)
Definition: pedump.c:82
#define WS_VSCROLL
Definition: pedump.c:627
long LONG
Definition: pedump.c:60
#define WS_HSCROLL
Definition: pedump.c:628
#define CLSID_NULL
Definition: guiddef.h:99
#define OCR_REVERSE
Definition: res.h:23
#define PFN_UCLETTER
Definition: richedit.h:908
#define PFM_SPACEBEFORE
Definition: richedit.h:847
#define TM_RICHTEXT
Definition: richedit.h:1029
#define MAX_TAB_STOPS
Definition: richedit.h:218
#define PFNS_PLAIN
Definition: richedit.h:916
#define SEL_EMPTY
Definition: richedit.h:822
#define TM_MULTILEVELUNDO
Definition: richedit.h:1031
#define EM_GETAUTOURLDETECT
Definition: richedit.h:126
#define EM_CANREDO
Definition: richedit.h:118
#define EM_SCROLLCARET
Definition: richedit.h:81
#define SEL_OBJECT
Definition: richedit.h:824
#define CFU_UNDERLINEDOUBLE
Definition: richedit.h:430
#define PFA_RIGHT
Definition: richedit.h:922
#define SFF_SELECTION
Definition: richedit.h:979
#define PFA_CENTER
Definition: richedit.h:923
#define EM_SETPALETTE
Definition: richedit.h:127
#define EM_SETOLECALLBACK
Definition: richedit.h:103
#define EM_GETREDONAME
Definition: richedit.h:120
#define GTL_CLOSE
Definition: richedit.h:1057
#define PFE_RTLPARA
Definition: richedit.h:932
#define EM_GETEVENTMASK
Definition: richedit.h:92
#define EM_REDO
Definition: richedit.h:117
#define PFM_NUMBERING
Definition: richedit.h:843
#define CFM_STRIKEOUT
Definition: richedit.h:335
#define PFE_KEEP
Definition: richedit.h:933
#define EM_REQUESTRESIZE
Definition: richedit.h:98
#define EM_GETSELTEXT
Definition: richedit.h:95
#define PFN_ARABIC
Definition: richedit.h:906
#define EM_SETBIDIOPTIONS
Definition: richedit.h:154
#define EM_AUTOURLDETECT
Definition: richedit.h:125
#define SCF_WORD
Definition: richedit.h:236
#define CFE_BOLD
Definition: richedit.h:406
#define MAX_TABLE_CELLS
Definition: richedit.h:220
#define PFE_NOWIDOWCONTROL
Definition: richedit.h:937
#define EM_FORMATRANGE
Definition: richedit.h:90
#define PFA_LEFT
Definition: richedit.h:921
#define CFE_AUTOCOLOR
Definition: richedit.h:414
#define EM_SETZOOM
Definition: richedit.h:170
#define EM_STREAMIN
Definition: richedit.h:106
#define EM_SETSCROLLPOS
Definition: richedit.h:166
#define ST_SELECTION
Definition: richedit.h:1072
#define EM_SETEVENTMASK
Definition: richedit.h:102
#define PFM_KEEPNEXT
Definition: richedit.h:858
#define PFM_NUMBERINGSTYLE
Definition: richedit.h:853
#define EM_CANPASTE
Definition: richedit.h:83
#define CFU_UNDERLINEWORD
Definition: richedit.h:429
#define WM_UNICHAR
Definition: richedit.h:67
#define CFM_WEIGHT
Definition: richedit.h:354
#define ST_KEEPUNDO
Definition: richedit.h:1071
#define EM_GETUNDONAME
Definition: richedit.h:119
#define EM_GETTEXTMODE
Definition: richedit.h:124
#define SF_RTF
Definition: richedit.h:721
#define SEL_MULTICHAR
Definition: richedit.h:825
#define SCF_SELECTION
Definition: richedit.h:235
#define EM_GETWORDBREAKPROCEX
Definition: richedit.h:113
#define EM_GETBIDIOPTIONS
Definition: richedit.h:155
#define PFM_LINESPACING
Definition: richedit.h:849
#define PFM_OFFSET
Definition: richedit.h:840
#define EM_SETTEXTEX
Definition: richedit.h:131
#define PFN_LCLETTER
Definition: richedit.h:907
#define EM_HIDESELECTION
Definition: richedit.h:96
#define EM_POSFROMCHAR
Definition: richedit.h:77
#define EM_GETCHARFORMAT
Definition: richedit.h:91
#define CFE_SUPERSCRIPT
Definition: richedit.h:413
#define GTL_NUMCHARS
Definition: richedit.h:1058
#define TM_SINGLECODEPAGE
Definition: richedit.h:1032
struct _charformatw CHARFORMATW
#define SEL_TEXT
Definition: richedit.h:823
#define EM_SETCHARFORMAT
Definition: richedit.h:101
#define CFM_SUBSCRIPT
Definition: richedit.h:348
#define PFN_UCROMAN
Definition: richedit.h:910
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define EM_SETFONTSIZE
Definition: richedit.h:168
#define EM_GETLANGOPTIONS
Definition: richedit.h:144
#define EM_GETPARAFORMAT
Definition: richedit.h:94
#define CFM_CHARSET
Definition: richedit.h:358
#define CFM_HIDDEN
Definition: richedit.h:340
#define EM_SETWORDBREAKPROCEX
Definition: richedit.h:114
#define EM_DISPLAYBAND
Definition: richedit.h:84
#define PFM_RIGHTINDENT
Definition: richedit.h:839
#define EM_SETLANGOPTIONS
Definition: richedit.h:143
#define CFE_UNDERLINE
Definition: richedit.h:408
#define CFM_BACKCOLOR
Definition: richedit.h:357
#define EM_CHARFROMPOS
Definition: richedit.h:78
#define CFE_SUBSCRIPT
Definition: richedit.h:412
#define EM_GETEDITSTYLE
Definition: richedit.h:161
#define PFM_TABLE
Definition: richedit.h:870
#define PFNS_PAREN
Definition: richedit.h:913
#define ES_DISABLENOSCROLL
Definition: richedit.h:224
#define PFN_BULLET
Definition: richedit.h:905
#define CFM_ITALIC
Definition: richedit.h:333
#define EM_GETTEXTRANGE
Definition: richedit.h:108
#define CFU_UNDERLINE
Definition: richedit.h:428
#define CFE_LINK
Definition: richedit.h:411
#define CFM_LINK
Definition: richedit.h:337
#define EM_SETTEXTMODE
Definition: richedit.h:123
#define CFM_SIZE
Definition: richedit.h:362
#define EM_FINDTEXTW
Definition: richedit.h:147
#define PFM_NOWIDOWCONTROL
Definition: richedit.h:861
#define EM_GETZOOM
Definition: richedit.h:169
#define EM_EXSETSEL
Definition: richedit.h:88
#define GT_SELECTION
Definition: richedit.h:1038
#define EM_GETSCROLLPOS
Definition: richedit.h:165
#define CFM_ALL2
Definition: richedit.h:393
#define PFE_TABLE
Definition: richedit.h:944
#define PFM_BORDER
Definition: richedit.h:851
#define EM_EXLIMITTEXT
Definition: richedit.h:86
#define PFM_ALIGNMENT
Definition: richedit.h:841
#define EM_PASTESPECIAL
Definition: richedit.h:97
#define SF_TEXT
Definition: richedit.h:720
#define CFE_AUTOBACKCOLOR
Definition: richedit.h:425
#define EM_SELECTIONTYPE
Definition: richedit.h:99
#define EM_FINDTEXT
Definition: richedit.h:89
#define PFM_TABSTOPS
Definition: richedit.h:842
#define TM_PLAINTEXT
Definition: richedit.h:1028
#define EM_STOPGROUPTYPING
Definition: richedit.h:121
#define PFN_LCROMAN
Definition: richedit.h:909
#define EM_SETTYPOGRAPHYOPTIONS
Definition: richedit.h:157
#define EM_GETTEXTLENGTHEX
Definition: richedit.h:129
#define SCF_ALL
Definition: richedit.h:237
#define SF_UNICODE
Definition: richedit.h:724
#define EM_SETTARGETDEVICE
Definition: richedit.h:105
#define PFNS_PARENS
Definition: richedit.h:914
struct _charformat2w CHARFORMAT2W
#define SEL_MULTIOBJECT
Definition: richedit.h:826
#define CFM_BOLD
Definition: richedit.h:332
#define EM_GETLIMITTEXT
Definition: richedit.h:74
#define CFM_UNDERLINETYPE
Definition: richedit.h:355
#define PFM_KEEP
Definition: richedit.h:857
#define EN_LINK
Definition: richedit.h:202
#define EM_EXLINEFROMCHAR
Definition: richedit.h:87
#define GT_USECRLF
Definition: richedit.h:1037
#define EM_GETIMECOMPMODE
Definition: richedit.h:145
#define CFM_FACE
Definition: richedit.h:360
#define EM_GETOLEINTERFACE
Definition: richedit.h:93
#define PFM_RTLPARA
Definition: richedit.h:856
#define EM_GETTEXTEX
Definition: richedit.h:128
#define PFM_SPACEAFTER
Definition: richedit.h:848
#define PFE_KEEPNEXT
Definition: richedit.h:934
#define EM_SETPARAFORMAT
Definition: richedit.h:104
#define CFU_UNDERLINEDOTTED
Definition: richedit.h:431
#define CFM_UNDERLINE
Definition: richedit.h:334
#define CFM_COLOR
Definition: richedit.h:361
#define EM_FINDTEXTEXW
Definition: richedit.h:148
#define TM_SINGLELEVELUNDO
Definition: richedit.h:1030
#define PFM_STARTINDENT
Definition: richedit.h:838
#define EM_EXGETSEL
Definition: richedit.h:85
#define EM_GETTYPOGRAPHYOPTIONS
Definition: richedit.h:158
#define EM_FINDTEXTEX
Definition: richedit.h:112
#define PFNS_PERIOD
Definition: richedit.h:915
#define EM_SETUNDOLIMIT
Definition: richedit.h:116
#define GTL_USECRLF
Definition: richedit.h:1055
#define EM_FINDWORDBREAK
Definition: richedit.h:109
#define TM_MULTICODEPAGE
Definition: richedit.h:1033
#define EM_SETEDITSTYLE
Definition: richedit.h:160
#define PFM_NUMBERINGSTART
Definition: richedit.h:855
#define PFM_NUMBERINGTAB
Definition: richedit.h:854
#define CFM_SUPERSCRIPT
Definition: richedit.h:349
#define EM_STREAMOUT
Definition: richedit.h:107
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#define rtfPar
Definition: rtf.h:237
#define rtfBorderWidth
Definition: rtf.h:542
#define rtfBorderDouble
Definition: rtf.h:538
#define rtfKeepNext
Definition: rtf.h:462
#define rtfParNumbering
Definition: rtf.h:149
#define rtfQuadLeft
Definition: rtf.h:467
#define rtfUnderline
Definition: rtf.h:583
#define rtfSuperScrShrink
Definition: rtf.h:589
#define rtfParNumTextBefore
Definition: rtf.h:151
#define rtfQuadRight
Definition: rtf.h:468
#define RTFBorderTypeMask
Definition: rtf.h:1052
#define rtfRowGapH
Definition: rtf.h:416
#define rtfBorderRight
Definition: rtf.h:531
#define rtfBeginGroup
Definition: rtf.h:89
#define RTFBorderRowTop
Definition: rtf.h:1070
#define rtfRowBordLeft
Definition: rtf.h:430
#define rtfNoWidowControl
Definition: rtf.h:461
#define rtfWordUnderline
Definition: rtf.h:587
#define rtfLTRPar
Definition: rtf.h:480
#define rtfParNumTextAfter
Definition: rtf.h:150
#define rtfRowBordTop
Definition: rtf.h:429
#define rtfWinMetafile
Definition: rtf.h:604
#define rtfBorderShadow
Definition: rtf.h:537
#define rtfParBullet
Definition: rtf.h:493
#define rtfEndGroup
Definition: rtf.h:90
#define rtfKeep
Definition: rtf.h:460
#define rtfDbUnderline
Definition: rtf.h:585
#define rtfEmfBlip
Definition: rtf.h:607
#define RTFBorderParaRight
Definition: rtf.h:1069
#define rtfNestTableProps
Definition: rtf.h:185
#define rtfBorderSingle
Definition: rtf.h:535
#define rtfParLevel
Definition: rtf.h:492
#define rtfQuadCenter
Definition: rtf.h:470
#define rtfCellBordBottom
Definition: rtf.h:435
#define rtfSubScrShrink
Definition: rtf.h:568
#define RTFBorderCellTop
Definition: rtf.h:1076
#define rtfShpPict
Definition: rtf.h:187
#define rtfBorderBottom
Definition: rtf.h:529
#define rtfPicGoalWid
Definition: rtf.h:613
#define rtfSuperScript
Definition: rtf.h:588
#define rtfRowBordBottom
Definition: rtf.h:431
#define rtfNoUnderline
Definition: rtf.h:586
#define rtfBorderLeft
Definition: rtf.h:530
#define rtfStrikeThru
Definition: rtf.h:582
#define rtfItalic
Definition: rtf.h:575
#define rtfQuadJust
Definition: rtf.h:469
#define rtfRowDef
Definition: rtf.h:415
#define RTFBorderCellRight
Definition: rtf.h:1079
#define rtfPicGoalHt
Definition: rtf.h:614
#define rtfEOF
Definition: rtf.h:82
#define rtfParDef
Definition: rtf.h:456
#define rtfParNumLRoman
Definition: rtf.h:505
#define rtfRowLeftEdge
Definition: rtf.h:423
#define maxStack
Definition: rtf.h:1083
#define rtfParNumStartAt
Definition: rtf.h:527
#define rtfBorderColor
Definition: rtf.h:543
#define rtfObjResult
Definition: rtf.h:162
#define rtfCellBordRight
Definition: rtf.h:438
#define rtfSpaceMultiply
Definition: rtf.h:477
#define RTFBorderSideMask
Definition: rtf.h:1063
#define rtfParNumULetter
Definition: rtf.h:502
#define RTFBorderParaTop
Definition: rtf.h:1066
#define rtfObject
Definition: rtf.h:155
#define rtfParSimple
Definition: rtf.h:494
#define rtfNestLevel
Definition: rtf.h:560
#define rtfCell
Definition: rtf.h:235
#define rtfPictAttr
Definition: rtf.h:601
#define rtfPlain
Definition: rtf.h:563
#define rtfRightIndent
Definition: rtf.h:473
#define rtfForeColor
Definition: rtf.h:591
#define rtfSubScript
Definition: rtf.h:567
#define rtfCellBordLeft
Definition: rtf.h:437
#define RTFBorderCellLeft
Definition: rtf.h:1077
#define rtfParNumLLetter
Definition: rtf.h:504
#define rtfNoParam
Definition: rtf.h:62
#define rtfText
Definition: rtf.h:80
#define rtfRTLPar
Definition: rtf.h:479
#define rtfRow
Definition: rtf.h:236
#define rtfTab
Definition: rtf.h:246
#define rtfCellPos
Definition: rtf.h:417
#define RTFBorderRowBottom
Definition: rtf.h:1072
#define rtfSpaceBetween
Definition: rtf.h:476
#define rtfNestRow
Definition: rtf.h:269
#define RTFBorderParaBottom
Definition: rtf.h:1068
#define rtfParAttr
Definition: rtf.h:455
#define rtfNestCell
Definition: rtf.h:268
#define rtfSpaceBefore
Definition: rtf.h:474
#define rtfBold
Definition: rtf.h:564
#define rtfPict
Definition: rtf.h:154
#define rtfBorderTop
Definition: rtf.h:528
#define rtfInTable
Definition: rtf.h:459
#define RTFBorderTypePara
Definition: rtf.h:1049
#define rtfNoNestTables
Definition: rtf.h:186
#define RTFBorderTypeRow
Definition: rtf.h:1050
#define rtfPicHt
Definition: rtf.h:612
#define rtfControl
Definition: rtf.h:81
#define rtfBorderThick
Definition: rtf.h:536
#define RTFBorderTypeCell
Definition: rtf.h:1051
#define rtfFirstIndent
Definition: rtf.h:471
#define rtfFontSize
Definition: rtf.h:574
#define rtfBorderDot
Definition: rtf.h:539
#define rtfPicWid
Definition: rtf.h:611
#define rtfBackColor
Definition: rtf.h:592
#define rtfTabPos
Definition: rtf.h:481
#define rtfParNumIndent
Definition: rtf.h:521
#define rtfGroup
Definition: rtf.h:79
#define rtfSpaceAfter
Definition: rtf.h:475
#define RTFBorderRowLeft
Definition: rtf.h:1071
#define rtfNoSuperSub
Definition: rtf.h:569
#define rtfDestination
Definition: rtf.h:109
#define rtfInvisible
Definition: rtf.h:590
#define rtfFontNum
Definition: rtf.h:573
#define RTFBorderParaLeft
Definition: rtf.h:1067
#define rtfDevIndBitmap
Definition: rtf.h:605
#define rtfCellBordTop
Definition: rtf.h:436
#define rtfParNumURoman
Definition: rtf.h:503
#define rtfParNumDecimal
Definition: rtf.h:501
#define RTFBorderRowRight
Definition: rtf.h:1073
#define rtfRowBordRight
Definition: rtf.h:432
#define rtfBorderSpace
Definition: rtf.h:544
#define RTFBorderCellBottom
Definition: rtf.h:1078
#define rtfObjAttr
Definition: rtf.h:675
#define rtfDotUnderline
Definition: rtf.h:584
#define rtfLeftIndent
Definition: rtf.h:472
#define CP_UTF8
Definition: nls.h:20
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
static char utf8_bom[3]
Definition: file.c:108
static CHANGE * changes
Definition: io.c:49
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
int color
Definition: rtf.h:1015
int width
Definition: rtf.h:1014
Definition: rtf.h:1019
RTFBorder border[4]
Definition: rtf.h:1021
int rightBoundary
Definition: rtf.h:1020
Definition: rtf.h:979
int rtfCNum
Definition: rtf.h:980
int rtfCBlue
Definition: rtf.h:983
RTFColor * rtfNextColor
Definition: rtf.h:984
int rtfCRed
Definition: rtf.h:981
int rtfCGreen
Definition: rtf.h:982
Definition: rtf.h:960
Definition: rtf.h:1026
RTFCell cells[MAX_TABLE_CELLS]
Definition: rtf.h:1027
int numCellsDefined
Definition: rtf.h:1028
ME_Paragraph * row_start
Definition: rtf.h:1041
RTFBorder border[6]
Definition: rtf.h:1032
RTFTable * parent
Definition: rtf.h:1044
int numCellsInserted
Definition: rtf.h:1035
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
DWORD dwMask
Definition: richedit.h:306
DWORD dwEffects
Definition: richedit.h:307
LONG cpMax
Definition: richedit.h:501
LONG cpMin
Definition: richedit.h:500
DWORD dwError
Definition: richedit.h:523
CHARRANGE chrg
Definition: richedit.h:586
LPCWSTR lpstrText
Definition: richedit.h:587
LONG dxOffset
Definition: richedit.h:672
WORD wNumbering
Definition: richedit.h:668
SHORT cTabCount
Definition: richedit.h:674
WORD wEffects
Definition: richedit.h:669
LONG dxStartIndent
Definition: richedit.h:670
DWORD dwUser
Definition: richole.idl:67
CLSID clsid
Definition: richole.idl:60
DWORD dwFlags
Definition: richole.idl:66
LPSTORAGE pstg
Definition: richole.idl:62
LPOLEOBJECT poleobj
Definition: richole.idl:61
DWORD dvaspect
Definition: richole.idl:65
LPOLECLIENTSITE polesite
Definition: richole.idl:63
DWORD cbStruct
Definition: richole.idl:58
LONG cp
Definition: richole.idl:59
SIZEL sizel
Definition: richole.idl:64
DWORD dwAspect
Definition: richedit.h:696
UINT codepage
Definition: richedit.h:1066
DWORD flags
Definition: richedit.h:1065
CHARRANGE chrg
Definition: richedit.h:514
LPWSTR lpstrText
Definition: richedit.h:515
struct define * next
Definition: compiler.c:65
Definition: comerr.c:44
Definition: dsound.c:943
Definition: format.c:58
Definition: copy.c:22
Definition: import.c:81
enum parser_state stack[4]
Definition: inffile.c:91
HRESULT(* paste)(ME_TextEditor *, FORMATETC *, STGMEDIUM *)
Definition: editor.c:2259
const WCHAR * name
Definition: editor.c:2260
FORMATETC fmt
Definition: editor.c:2258
Definition: parse.h:23
USHORT biBitCount
Definition: precomp.h:46
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
ME_Border bottom
Definition: editstr.h:190
ME_Border right
Definition: editstr.h:191
ME_Border left
Definition: editstr.h:189
ME_Border top
Definition: editstr.h:188
COLORREF colorRef
Definition: editstr.h:183
int nRightBoundary
Definition: editstr.h:224
ME_BorderRect border
Definition: editstr.h:225
ME_Paragraph * para
Definition: editstr.h:275
int nOffset
Definition: editstr.h:277
ME_Run * run
Definition: editstr.h:276
union tagME_DisplayItem::@595 member
struct tagME_DisplayItem * prev
Definition: editstr.h:257
struct tagME_DisplayItem * next
Definition: editstr.h:257
ME_Paragraph para
Definition: editstr.h:262
EDITSTREAM * editstream
Definition: editstr.h:379
char buffer[STREAMIN_BUFFER_SIZE]
Definition: editstr.h:382
DWORD dwUsed
Definition: editstr.h:381
DWORD dwSize
Definition: editstr.h:380
struct tagME_DisplayItem * next_para
Definition: editstr.h:217
ME_BorderRect border
Definition: editstr.h:208
struct tagME_DisplayItem * prev_para
Definition: editstr.h:217
PARAFORMAT2 fmt
Definition: editstr.h:204
ME_Run * eop_run
Definition: editstr.h:216
int nCharOfs
Definition: editstr.h:162
struct tagME_Paragraph * para
Definition: editstr.h:161
ME_Style * style
Definition: editstr.h:160
int nFlags
Definition: editstr.h:165
int len
Definition: editstr.h:163
CHARFORMAT2W fmt
Definition: editstr.h:71
TEXTMETRICW tm
Definition: editstr.h:74
ME_DisplayItem * pFirst
Definition: editstr.h:268
ME_Style * pDefaultStyle
Definition: editstr.h:270
ME_DisplayItem * pLast
Definition: editstr.h:268
unsigned int horz_sb_enabled
Definition: editstr.h:451
unsigned int have_texthost2
Definition: editstr.h:394
EDITWORDBREAKPROCW pfnWordBreak
Definition: editstr.h:425
ME_FontCacheItem pFontCache[HFONT_CACHE_SIZE]
Definition: editstr.h:420
struct list redo_stack
Definition: editstr.h:412
int nZoomNumerator
Definition: editstr.h:421
unsigned int vert_sb_enabled
Definition: editstr.h:450
SCROLLINFO vert_si
Definition: editstr.h:449
ME_Paragraph * last_sel_end_para
Definition: editstr.h:419
int nLastTotalWidth
Definition: editstr.h:405
int nUndoStackSize
Definition: editstr.h:413
ME_UndoControlState undo_ctl_state
Definition: editstr.h:416
DWORD scrollbars
Definition: editstr.h:401
ME_UndoMode nUndoMode
Definition: editstr.h:415
ITextHost2 * texthost
Definition: editstr.h:391
TXTBACKSTYLE back_style
Definition: editstr.h:457
DWORD freeze_count
Definition: editstr.h:437
ME_Paragraph * last_sel_start_para
Definition: editstr.h:419
struct list reobj_list
Definition: editstr.h:459
ME_SelectionType nSelectionType
Definition: editstr.h:443
BOOL AutoURLDetect_bEnable
Definition: editstr.h:434
ME_Cursor * pCursors
Definition: editstr.h:396
LONG nLastSelEnd
Definition: editstr.h:418
LPRICHEDITOLECALLBACK lpOleCallback
Definition: editstr.h:427
SCROLLINFO horz_si
Definition: editstr.h:449
ME_TextBuffer * pBuffer
Definition: editstr.h:395
int nZoomDenominator
Definition: editstr.h:421
WCHAR password_char
Definition: editstr.h:435
CHARRANGE notified_cr
Definition: editstr.h:446
IRichEditOle * richole
Definition: editstr.h:426
struct list style_list
Definition: editstr.h:458
BOOL caret_hidden
Definition: editstr.h:454
LONG nLastSelStart
Definition: editstr.h:418
BOOL bMouseCaptured
Definition: editstr.h:455
unsigned int bEmulateVersion10
Definition: editstr.h:392
struct list undo_stack
Definition: editstr.h:411
unsigned int in_place_active
Definition: editstr.h:393
int nLastTotalLength
Definition: editstr.h:404
BOOL bHideSelection
Definition: editstr.h:433
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
LONG tmHeight
Definition: wingdi.h:2383
#define max(a, b)
Definition: svc.c:63
#define TXTBIT_AUTOWORDSEL
Definition: textserv.h:192
#define TXTBIT_WORDWRAP
Definition: textserv.h:195
#define TXTBIT_MULTILINE
Definition: textserv.h:186
#define TXTBIT_VERTICAL
Definition: textserv.h:193
#define TXTBIT_ALLOWBEEP
Definition: textserv.h:196
#define TXTBIT_SAVESELECTION
Definition: textserv.h:191
#define TXTBIT_READONLY
Definition: textserv.h:187
@ TXTBACK_OPAQUE
Definition: textserv.h:165
#define TXTBIT_RICHTEXT
Definition: textserv.h:185
#define TXTBIT_USEPASSWORD
Definition: textserv.h:189
#define TXTBIT_HIDESELECTION
Definition: textserv.h:190
EXTERN_C const IID IID_ITextHost2
Definition: textserv.h:38
#define TXTBIT_DISABLEDRAG
Definition: textserv.h:197
#define bsearch
#define WHEEL_DELTA
Definition: treelist.c:99
#define WM_MOUSEWHEEL
Definition: treelist.c:96
#define DWORD_PTR
Definition: treelist.c:76
eMaj lines
Definition: tritemp.h:206
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
LPCSTR pText
Definition: txtscale.cpp:79
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
static struct wctab tab[]
int codepage
Definition: win_iconv.c:156
#define CopyMemory
Definition: winbase.h:1751
WINBASEAPI _In_ DWORD nLength
Definition: wincon.h:682
_In_ HCRYPTHASH _In_ BOOL _In_ DWORD _Inout_ DWORD _In_ DWORD dwBufLen
Definition: wincrypt.h:4246
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
HICON HCURSOR
Definition: windef.h:299
#define HRESULT
Definition: msvc.h:7
#define S_FALSE
Definition: winerror.h:2357
#define E_ACCESSDENIED
Definition: winerror.h:2849
#define ERROR_HANDLE_EOF
Definition: winerror.h:140
#define E_UNEXPECTED
Definition: winerror.h:2456
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define DIB_RGB_COLORS
Definition: wingdi.h:367
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define FW_BOLD
Definition: wingdi.h:378
#define MM_TEXT
Definition: wingdi.h:873
#define FW_NORMAL
Definition: wingdi.h:373
#define SYSTEM_FONT
Definition: wingdi.h:911
HENHMETAFILE WINAPI SetEnhMetaFileBits(_In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *pb)
#define CBM_INIT
Definition: wingdi.h:365
HBITMAP WINAPI CreateDIBitmap(_In_ HDC hdc, _In_opt_ const BITMAPINFOHEADER *pbmih, _In_ DWORD fdwInit, _In_opt_ const VOID *pvInit, _In_opt_ const BITMAPINFO *pbmi, _In_ UINT uUsage)
HENHMETAFILE WINAPI SetWinMetaFileBits(_In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *lpMeta16Data, _In_opt_ HDC hdcRef, _In_opt_ const METAFILEPICT *lpMFP)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define EM_GETIMESTATUS
Definition: winuser.h:2006
#define WM_GETTEXTLENGTH
Definition: winuser.h:1638
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define EM_LIMITTEXT
Definition: winuser.h:2019
#define SB_THUMBTRACK
Definition: winuser.h:573
#define EM_LINEFROMCHAR
Definition: winuser.h:2020
#define SB_LINEUP
Definition: winuser.h:564
#define WM_HSCROLL
Definition: winuser.h:1762
#define SM_CXDOUBLECLK
Definition: winuser.h:1010
#define WM_PASTE
Definition: winuser.h:1882
#define EN_KILLFOCUS
Definition: winuser.h:2044
#define EM_GETWORDBREAKPROC
Definition: winuser.h:2018
#define EM_FMTLINES
Definition: winuser.h:2005
#define WM_MOUSELAST
Definition: winuser.h:1820
LRESULT WINAPI DefWindowProcW(_In_ 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 EM_SETIMESTATUS
Definition: winuser.h:2029
#define EM_GETSEL
Definition: winuser.h:2016
#define EN_SETFOCUS
Definition: winuser.h:2046
#define EM_GETMODIFY
Definition: winuser.h:2013
#define SB_PAGERIGHT
Definition: winuser.h:571
int WINAPI MessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
#define SB_VERT
Definition: winuser.h:553
#define EM_EMPTYUNDOBUFFER
Definition: winuser.h:2004
#define SB_LEFT
Definition: winuser.h:575
#define SB_BOTTOM
Definition: winuser.h:577
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1797
#define ESB_DISABLE_BOTH
Definition: winuser.h:556
#define WM_COMMAND
Definition: winuser.h:1759
#define EM_REPLACESEL
Definition: winuser.h:2025
#define IDC_ARROW
Definition: winuser.h:695
#define VK_CONTROL
Definition: winuser.h:2222
#define WM_RBUTTONUP
Definition: winuser.h:1799
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
#define VK_UP
Definition: winuser.h:2244
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1800
#define SM_CYDOUBLECLK
Definition: winuser.h:1011
#define WM_SETFOCUS
Definition: winuser.h:1632
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define WM_MOUSEMOVE
Definition: winuser.h:1794
#define WM_GETTEXT
Definition: winuser.h:1637
#define WM_CUT
Definition: winuser.h:1880
#define SB_LINERIGHT
Definition: winuser.h:567
#define WM_LBUTTONDOWN
Definition: winuser.h:1795
#define EM_LINEINDEX
Definition: winuser.h:2021
BOOL WINAPI MessageBeep(_In_ UINT uType)
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2442
#define EM_LINESCROLL
Definition: winuser.h:2023
#define EM_GETFIRSTVISIBLELINE
Definition: winuser.h:2007
UINT WINAPI GetDoubleClickTime(void)
Definition: ntwrapper.h:314
#define WM_UNDO
Definition: winuser.h:1884
#define VK_NEXT
Definition: winuser.h:2240
#define MB_ICONERROR
Definition: winuser.h:798
#define WM_IME_SETCONTEXT
Definition: winuser.h:1848
#define WM_RBUTTONDOWN
Definition: winuser.h:1798
#define WM_SETTEXT
Definition: winuser.h:1636
#define EM_CANUNDO
Definition: winuser.h:2002
#define EM_LINELENGTH
Definition: winuser.h:2022
#define VK_RETURN
Definition: winuser.h:2220
#define EM_GETLINE
Definition: winuser.h:2010
#define SB_LINELEFT
Definition: winuser.h:566
#define WM_SETFONT
Definition: winuser.h:1669
#define VK_END
Definition: winuser.h:2241
#define TPM_LEFTALIGN
Definition: winuser.h:2396
#define VK_HOME
Definition: winuser.h:2242
#define EM_UNDO
Definition: winuser.h:2040
#define EM_SCROLL
Definition: winuser.h:2026
#define SB_PAGEDOWN
Definition: winuser.h:569
#define EM_SETWORDBREAKPROC
Definition: winuser.h:2039
#define IDC_IBEAM
Definition: winuser.h:696
#define WM_MBUTTONDBLCLK
Definition: winuser.h:1803
#define VK_BACK
Definition: winuser.h:2217
HDC WINAPI GetDC(_In_opt_ HWND)
#define SB_LINEDOWN
Definition: winuser.h:565
#define EM_SETSEL
Definition: winuser.h:2037
#define MB_OK
Definition: winuser.h:801
int(CALLBACK * EDITWORDBREAKPROCW)(LPWSTR, int, int, int)
Definition: winuser.h:2981
#define WM_LBUTTONUP
Definition: winuser.h:1796
LONG WINAPI GetMessageTime(void)
Definition: message.c:1361
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 VK_RIGHT
Definition: winuser.h:2245
#define SB_TOP
Definition: winuser.h:578
#define VK_DOWN
Definition: winuser.h:2246
#define WM_COPY
Definition: winuser.h:1881
#define WM_IME_CONTROL
Definition: winuser.h:1850
#define VK_SHIFT
Definition: winuser.h:2221
#define IDC_HAND
Definition: winuser.h:706
#define EM_SETTABSTOPS
Definition: winuser.h:2038
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
#define VK_PRIOR
Definition: winuser.h:2239
#define VK_DELETE
Definition: winuser.h:2252
#define WM_IME_SELECT
Definition: winuser.h:1852
#define WM_CLEAR
Definition: winuser.h:1883
#define WM_KEYDOWN
Definition: winuser.h:1734
#define EM_GETLINECOUNT
Definition: winuser.h:2011
#define SB_RIGHT
Definition: winuser.h:576
BOOL WINAPI DestroyCaret(void)
Definition: caret.c:35
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define EM_SETMARGINS
Definition: winuser.h:2031
#define WM_KILLFOCUS
Definition: winuser.h:1633
int WINAPI GetSystemMetrics(_In_ int)
#define SB_PAGEUP
Definition: winuser.h:568
#define WM_MBUTTONDOWN
Definition: winuser.h:1801
#define EM_SETMODIFY
Definition: winuser.h:2032
#define SB_HORZ
Definition: winuser.h:552
SHORT WINAPI GetKeyState(_In_ int)
#define VK_MENU
Definition: winuser.h:2223
#define SB_PAGELEFT
Definition: winuser.h:570
#define SB_THUMBPOSITION
Definition: winuser.h:572
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
unsigned char BYTE
Definition: xxhash.c:193