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