1 /* 2 * RichEdit GUIDs and OLE interface 3 * 4 * Copyright 2004 by Krzysztof Foltman 5 * Copyright 2004 Aric Stewart 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include <stdarg.h> 23 24 #define NONAMELESSUNION 25 #define COBJMACROS 26 27 #include "windef.h" 28 #include "winbase.h" 29 #include "wingdi.h" 30 #include "winuser.h" 31 #include "ole2.h" 32 #include "richole.h" 33 #include "editor.h" 34 #include "richedit.h" 35 #include "tom.h" 36 #include "wine/debug.h" 37 38 WINE_DEFAULT_DEBUG_CHANNEL(richedit); 39 40 /* there is no way to be consistent across different sets of headers - mingw, Wine, Win32 SDK*/ 41 42 #include "initguid.h" 43 44 DEFINE_GUID(LIBID_tom, 0x8cc497c9, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); 45 DEFINE_GUID(IID_ITextServices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5); 46 DEFINE_GUID(IID_ITextHost, 0x13e670f4,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1); 47 DEFINE_GUID(IID_ITextHost2, 0x13e670f5,0x1a5a,0x11cf,0xab,0xeb,0x00,0xaa,0x00,0xb6,0x5e,0xa1); 48 DEFINE_GUID(IID_ITextDocument, 0x8cc497c0, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); 49 DEFINE_GUID(IID_ITextRange, 0x8cc497c2, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); 50 DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); 51 DEFINE_GUID(IID_ITextFont, 0x8cc497c3, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); 52 DEFINE_GUID(IID_ITextPara, 0x8cc497c4, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0xaa, 0x00, 0x47, 0xbe, 0x5d); 53 54 static ITypeLib *typelib; 55 56 enum tid_t { 57 NULL_tid, 58 ITextDocument_tid, 59 ITextRange_tid, 60 ITextSelection_tid, 61 ITextFont_tid, 62 ITextPara_tid, 63 LAST_tid 64 }; 65 66 static const IID * const tid_ids[] = 67 { 68 &IID_NULL, 69 &IID_ITextDocument, 70 &IID_ITextRange, 71 &IID_ITextSelection, 72 &IID_ITextFont, 73 &IID_ITextPara, 74 }; 75 static ITypeInfo *typeinfos[LAST_tid]; 76 77 static HRESULT load_typelib(void) 78 { 79 ITypeLib *tl; 80 HRESULT hr; 81 82 hr = LoadRegTypeLib(&LIBID_tom, 1, 0, LOCALE_SYSTEM_DEFAULT, &tl); 83 if (FAILED(hr)) { 84 ERR("LoadRegTypeLib failed: %08x\n", hr); 85 return hr; 86 } 87 88 if (InterlockedCompareExchangePointer((void**)&typelib, tl, NULL)) 89 ITypeLib_Release(tl); 90 return hr; 91 } 92 93 void release_typelib(void) 94 { 95 unsigned i; 96 97 if (!typelib) 98 return; 99 100 for (i = 0; i < sizeof(typeinfos)/sizeof(*typeinfos); i++) 101 if (typeinfos[i]) 102 ITypeInfo_Release(typeinfos[i]); 103 104 ITypeLib_Release(typelib); 105 } 106 107 static HRESULT get_typeinfo(enum tid_t tid, ITypeInfo **typeinfo) 108 { 109 HRESULT hr; 110 111 if (!typelib) 112 hr = load_typelib(); 113 if (!typelib) 114 return hr; 115 116 if (!typeinfos[tid]) 117 { 118 ITypeInfo *ti; 119 120 hr = ITypeLib_GetTypeInfoOfGuid(typelib, tid_ids[tid], &ti); 121 if (FAILED(hr)) 122 { 123 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(tid_ids[tid]), hr); 124 return hr; 125 } 126 127 if (InterlockedCompareExchangePointer((void**)(typeinfos+tid), ti, NULL)) 128 ITypeInfo_Release(ti); 129 } 130 131 *typeinfo = typeinfos[tid]; 132 return S_OK; 133 } 134 135 /* private IID used to get back IRichEditOleImpl pointer */ 136 DEFINE_GUID(IID_Igetrichole, 0xe3ce5c7a, 0x8247, 0x4622, 0x81, 0xad, 0x11, 0x81, 0x02, 0xaa, 0x01, 0x30); 137 138 typedef struct ITextSelectionImpl ITextSelectionImpl; 139 typedef struct IOleClientSiteImpl IOleClientSiteImpl; 140 typedef struct ITextRangeImpl ITextRangeImpl; 141 142 enum textfont_prop_id { 143 FONT_ALLCAPS = 0, 144 FONT_ANIMATION, 145 FONT_BACKCOLOR, 146 FONT_BOLD, 147 FONT_EMBOSS, 148 FONT_FORECOLOR, 149 FONT_HIDDEN, 150 FONT_ENGRAVE, 151 FONT_ITALIC, 152 FONT_KERNING, 153 FONT_LANGID, 154 FONT_NAME, 155 FONT_OUTLINE, 156 FONT_POSITION, 157 FONT_PROTECTED, 158 FONT_SHADOW, 159 FONT_SIZE, 160 FONT_SMALLCAPS, 161 FONT_SPACING, 162 FONT_STRIKETHROUGH, 163 FONT_SUBSCRIPT, 164 FONT_SUPERSCRIPT, 165 FONT_UNDERLINE, 166 FONT_WEIGHT, 167 FONT_PROPID_LAST, 168 FONT_PROPID_FIRST = FONT_ALLCAPS 169 }; 170 171 static const DWORD textfont_prop_masks[][2] = { 172 { CFM_ALLCAPS, CFE_ALLCAPS }, 173 { CFM_ANIMATION }, 174 { CFM_BACKCOLOR, CFE_AUTOBACKCOLOR }, 175 { CFM_BOLD, CFE_BOLD }, 176 { CFM_EMBOSS, CFE_EMBOSS }, 177 { CFM_COLOR, CFE_AUTOCOLOR }, 178 { CFM_HIDDEN, CFE_HIDDEN }, 179 { CFM_IMPRINT, CFE_IMPRINT }, 180 { CFM_ITALIC, CFE_ITALIC }, 181 { CFM_KERNING }, 182 { CFM_LCID }, 183 { CFM_FACE }, 184 { CFM_OUTLINE, CFE_OUTLINE }, 185 { CFM_OFFSET }, 186 { CFM_PROTECTED, CFE_PROTECTED }, 187 { CFM_SHADOW, CFE_SHADOW }, 188 { CFM_SIZE }, 189 { CFM_SMALLCAPS, CFE_SMALLCAPS }, 190 { CFM_SPACING }, 191 { CFM_STRIKEOUT, CFE_STRIKEOUT }, 192 { CFM_SUBSCRIPT, CFE_SUBSCRIPT }, 193 { CFM_SUPERSCRIPT, CFE_SUPERSCRIPT }, 194 { CFM_UNDERLINE, CFE_UNDERLINE }, 195 { CFM_WEIGHT } 196 }; 197 198 typedef union { 199 FLOAT f; 200 LONG l; 201 BSTR str; 202 } textfont_prop_val; 203 204 enum range_update_op { 205 RANGE_UPDATE_DELETE 206 }; 207 208 typedef struct IRichEditOleImpl { 209 IUnknown IUnknown_inner; 210 IRichEditOle IRichEditOle_iface; 211 ITextDocument ITextDocument_iface; 212 IUnknown *outer_unk; 213 LONG ref; 214 215 ME_TextEditor *editor; 216 ITextSelectionImpl *txtSel; 217 218 struct list rangelist; 219 struct list clientsites; 220 } IRichEditOleImpl; 221 222 struct reole_child { 223 struct list entry; 224 IRichEditOleImpl *reole; 225 }; 226 227 struct ITextRangeImpl { 228 struct reole_child child; 229 ITextRange ITextRange_iface; 230 LONG ref; 231 LONG start, end; 232 }; 233 234 struct ITextSelectionImpl { 235 ITextSelection ITextSelection_iface; 236 LONG ref; 237 238 IRichEditOleImpl *reOle; 239 }; 240 241 typedef struct ITextFontImpl { 242 ITextFont ITextFont_iface; 243 LONG ref; 244 245 ITextRange *range; 246 textfont_prop_val props[FONT_PROPID_LAST]; 247 BOOL get_cache_enabled; 248 BOOL set_cache_enabled; 249 } ITextFontImpl; 250 251 typedef struct ITextParaImpl { 252 ITextPara ITextPara_iface; 253 LONG ref; 254 255 ITextRange *range; 256 } ITextParaImpl; 257 258 struct IOleClientSiteImpl { 259 struct reole_child child; 260 IOleClientSite IOleClientSite_iface; 261 IOleInPlaceSite IOleInPlaceSite_iface; 262 LONG ref; 263 }; 264 265 static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface) 266 { 267 return CONTAINING_RECORD(iface, IRichEditOleImpl, IRichEditOle_iface); 268 } 269 270 static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface) 271 { 272 return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface); 273 } 274 275 static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface) 276 { 277 return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner); 278 } 279 280 static inline IOleClientSiteImpl *impl_from_IOleInPlaceSite(IOleInPlaceSite *iface) 281 { 282 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleInPlaceSite_iface); 283 } 284 285 static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface) 286 { 287 return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface); 288 } 289 290 static inline ITextSelectionImpl *impl_from_ITextSelection(ITextSelection *iface) 291 { 292 return CONTAINING_RECORD(iface, ITextSelectionImpl, ITextSelection_iface); 293 } 294 295 static inline ITextFontImpl *impl_from_ITextFont(ITextFont *iface) 296 { 297 return CONTAINING_RECORD(iface, ITextFontImpl, ITextFont_iface); 298 } 299 300 static inline ITextParaImpl *impl_from_ITextPara(ITextPara *iface) 301 { 302 return CONTAINING_RECORD(iface, ITextParaImpl, ITextPara_iface); 303 } 304 305 static HRESULT create_textfont(ITextRange*, const ITextFontImpl*, ITextFont**); 306 static HRESULT create_textpara(ITextRange*, ITextPara**); 307 static ITextSelectionImpl *CreateTextSelection(IRichEditOleImpl*); 308 309 static HRESULT textrange_get_storylength(ME_TextEditor *editor, LONG *length) 310 { 311 if (!length) 312 return E_INVALIDARG; 313 314 *length = ME_GetTextLength(editor) + 1; 315 return S_OK; 316 } 317 318 static void textranges_update_ranges(IRichEditOleImpl *reole, LONG start, LONG end, enum range_update_op op) 319 { 320 ITextRangeImpl *range; 321 322 LIST_FOR_EACH_ENTRY(range, &reole->rangelist, ITextRangeImpl, child.entry) { 323 switch (op) 324 { 325 case RANGE_UPDATE_DELETE: 326 /* range fully covered by deleted range - collapse to insertion point */ 327 if (range->start >= start && range->end <= end) 328 range->start = range->end = start; 329 /* deleted range cuts from the right */ 330 else if (range->start < start && range->end <= end) 331 range->end = start; 332 /* deleted range cuts from the left */ 333 else if (range->start >= start && range->end > end) { 334 range->start = start; 335 range->end -= end - start; 336 } 337 /* deleted range cuts within */ 338 else 339 range->end -= end - start; 340 break; 341 default: 342 FIXME("unknown update op, %d\n", op); 343 } 344 } 345 } 346 347 static inline BOOL is_equal_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *left, 348 textfont_prop_val *right) 349 { 350 switch (propid) 351 { 352 case FONT_ALLCAPS: 353 case FONT_ANIMATION: 354 case FONT_BACKCOLOR: 355 case FONT_BOLD: 356 case FONT_EMBOSS: 357 case FONT_FORECOLOR: 358 case FONT_HIDDEN: 359 case FONT_ENGRAVE: 360 case FONT_ITALIC: 361 case FONT_KERNING: 362 case FONT_LANGID: 363 case FONT_OUTLINE: 364 case FONT_PROTECTED: 365 case FONT_SHADOW: 366 case FONT_SMALLCAPS: 367 case FONT_STRIKETHROUGH: 368 case FONT_SUBSCRIPT: 369 case FONT_SUPERSCRIPT: 370 case FONT_UNDERLINE: 371 case FONT_WEIGHT: 372 return left->l == right->l; 373 case FONT_NAME: 374 return !strcmpW(left->str, right->str); 375 case FONT_POSITION: 376 case FONT_SIZE: 377 case FONT_SPACING: 378 return left->f == right->f; 379 default: 380 FIXME("unhandled font property %d\n", propid); 381 return FALSE; 382 } 383 } 384 385 static inline void init_textfont_prop_value(enum textfont_prop_id propid, textfont_prop_val *v) 386 { 387 switch (propid) 388 { 389 case FONT_ALLCAPS: 390 case FONT_ANIMATION: 391 case FONT_BACKCOLOR: 392 case FONT_BOLD: 393 case FONT_EMBOSS: 394 case FONT_FORECOLOR: 395 case FONT_HIDDEN: 396 case FONT_ENGRAVE: 397 case FONT_ITALIC: 398 case FONT_KERNING: 399 case FONT_LANGID: 400 case FONT_OUTLINE: 401 case FONT_PROTECTED: 402 case FONT_SHADOW: 403 case FONT_SMALLCAPS: 404 case FONT_STRIKETHROUGH: 405 case FONT_SUBSCRIPT: 406 case FONT_SUPERSCRIPT: 407 case FONT_UNDERLINE: 408 case FONT_WEIGHT: 409 v->l = tomUndefined; 410 return; 411 case FONT_NAME: 412 v->str = NULL; 413 return; 414 case FONT_POSITION: 415 case FONT_SIZE: 416 case FONT_SPACING: 417 v->f = tomUndefined; 418 return; 419 default: 420 FIXME("unhandled font property %d\n", propid); 421 v->l = tomUndefined; 422 return; 423 } 424 } 425 426 static inline FLOAT twips_to_points(LONG value) 427 { 428 return value * 72.0 / 1440; 429 } 430 431 static inline FLOAT points_to_twips(FLOAT value) 432 { 433 return value * 1440 / 72.0; 434 } 435 436 static HRESULT get_textfont_prop_for_pos(const IRichEditOleImpl *reole, int pos, enum textfont_prop_id propid, 437 textfont_prop_val *value) 438 { 439 ME_Cursor from, to; 440 CHARFORMAT2W fmt; 441 442 memset(&fmt, 0, sizeof(fmt)); 443 fmt.cbSize = sizeof(fmt); 444 fmt.dwMask = textfont_prop_masks[propid][0]; 445 446 ME_CursorFromCharOfs(reole->editor, pos, &from); 447 to = from; 448 ME_MoveCursorChars(reole->editor, &to, 1, FALSE); 449 ME_GetCharFormat(reole->editor, &from, &to, &fmt); 450 451 switch (propid) 452 { 453 case FONT_ALLCAPS: 454 case FONT_BOLD: 455 case FONT_EMBOSS: 456 case FONT_HIDDEN: 457 case FONT_ENGRAVE: 458 case FONT_ITALIC: 459 case FONT_OUTLINE: 460 case FONT_PROTECTED: 461 case FONT_SHADOW: 462 case FONT_SMALLCAPS: 463 case FONT_STRIKETHROUGH: 464 case FONT_SUBSCRIPT: 465 case FONT_SUPERSCRIPT: 466 case FONT_UNDERLINE: 467 value->l = fmt.dwEffects & textfont_prop_masks[propid][1] ? tomTrue : tomFalse; 468 break; 469 case FONT_ANIMATION: 470 value->l = fmt.bAnimation; 471 break; 472 case FONT_BACKCOLOR: 473 value->l = fmt.dwEffects & CFE_AUTOBACKCOLOR ? GetSysColor(COLOR_WINDOW) : fmt.crBackColor; 474 break; 475 case FONT_FORECOLOR: 476 value->l = fmt.dwEffects & CFE_AUTOCOLOR ? GetSysColor(COLOR_WINDOWTEXT) : fmt.crTextColor; 477 break; 478 case FONT_KERNING: 479 value->f = twips_to_points(fmt.wKerning); 480 break; 481 case FONT_LANGID: 482 value->l = fmt.lcid; 483 break; 484 case FONT_NAME: 485 /* this case is used exclusively by GetName() */ 486 value->str = SysAllocString(fmt.szFaceName); 487 if (!value->str) 488 return E_OUTOFMEMORY; 489 break; 490 case FONT_POSITION: 491 value->f = twips_to_points(fmt.yOffset); 492 break; 493 case FONT_SIZE: 494 value->f = twips_to_points(fmt.yHeight); 495 break; 496 case FONT_SPACING: 497 value->f = fmt.sSpacing; 498 break; 499 case FONT_WEIGHT: 500 value->l = fmt.wWeight; 501 break; 502 default: 503 FIXME("unhandled font property %d\n", propid); 504 return E_FAIL; 505 } 506 507 return S_OK; 508 } 509 510 static inline const IRichEditOleImpl *get_range_reole(ITextRange *range) 511 { 512 IRichEditOleImpl *reole = NULL; 513 ITextRange_QueryInterface(range, &IID_Igetrichole, (void**)&reole); 514 return reole; 515 } 516 517 static void textrange_set_font(ITextRange *range, ITextFont *font) 518 { 519 CHARFORMAT2W fmt; 520 HRESULT hr; 521 LONG value; 522 BSTR str; 523 FLOAT f; 524 525 #define CHARFORMAT_SET_B_FIELD(mask, value) \ 526 if (hr == S_OK && value != tomUndefined) { \ 527 fmt.dwMask |= CFM_##mask; \ 528 if (value == tomTrue) fmt.dwEffects |= CFE_##mask; \ 529 } \ 530 531 /* fill format data from font */ 532 memset(&fmt, 0, sizeof(fmt)); 533 fmt.cbSize = sizeof(fmt); 534 535 value = tomUndefined; 536 hr = ITextFont_GetAllCaps(font, &value); 537 CHARFORMAT_SET_B_FIELD(ALLCAPS, value); 538 539 value = tomUndefined; 540 hr = ITextFont_GetBold(font, &value); 541 CHARFORMAT_SET_B_FIELD(BOLD, value); 542 543 value = tomUndefined; 544 hr = ITextFont_GetEmboss(font, &value); 545 CHARFORMAT_SET_B_FIELD(EMBOSS, value); 546 547 value = tomUndefined; 548 hr = ITextFont_GetHidden(font, &value); 549 CHARFORMAT_SET_B_FIELD(HIDDEN, value); 550 551 value = tomUndefined; 552 hr = ITextFont_GetEngrave(font, &value); 553 CHARFORMAT_SET_B_FIELD(IMPRINT, value); 554 555 value = tomUndefined; 556 hr = ITextFont_GetItalic(font, &value); 557 CHARFORMAT_SET_B_FIELD(ITALIC, value); 558 559 value = tomUndefined; 560 hr = ITextFont_GetOutline(font, &value); 561 CHARFORMAT_SET_B_FIELD(OUTLINE, value); 562 563 value = tomUndefined; 564 hr = ITextFont_GetProtected(font, &value); 565 CHARFORMAT_SET_B_FIELD(PROTECTED, value); 566 567 value = tomUndefined; 568 hr = ITextFont_GetShadow(font, &value); 569 CHARFORMAT_SET_B_FIELD(SHADOW, value); 570 571 value = tomUndefined; 572 hr = ITextFont_GetSmallCaps(font, &value); 573 CHARFORMAT_SET_B_FIELD(SMALLCAPS, value); 574 575 value = tomUndefined; 576 hr = ITextFont_GetStrikeThrough(font, &value); 577 CHARFORMAT_SET_B_FIELD(STRIKEOUT, value); 578 579 value = tomUndefined; 580 hr = ITextFont_GetSubscript(font, &value); 581 CHARFORMAT_SET_B_FIELD(SUBSCRIPT, value); 582 583 value = tomUndefined; 584 hr = ITextFont_GetSuperscript(font, &value); 585 CHARFORMAT_SET_B_FIELD(SUPERSCRIPT, value); 586 587 value = tomUndefined; 588 hr = ITextFont_GetUnderline(font, &value); 589 CHARFORMAT_SET_B_FIELD(UNDERLINE, value); 590 591 #undef CHARFORMAT_SET_B_FIELD 592 593 value = tomUndefined; 594 hr = ITextFont_GetAnimation(font, &value); 595 if (hr == S_OK && value != tomUndefined) { 596 fmt.dwMask |= CFM_ANIMATION; 597 fmt.bAnimation = value; 598 } 599 600 value = tomUndefined; 601 hr = ITextFont_GetBackColor(font, &value); 602 if (hr == S_OK && value != tomUndefined) { 603 fmt.dwMask |= CFM_BACKCOLOR; 604 if (value == tomAutoColor) 605 fmt.dwEffects |= CFE_AUTOBACKCOLOR; 606 else 607 fmt.crBackColor = value; 608 } 609 610 value = tomUndefined; 611 hr = ITextFont_GetForeColor(font, &value); 612 if (hr == S_OK && value != tomUndefined) { 613 fmt.dwMask |= CFM_COLOR; 614 if (value == tomAutoColor) 615 fmt.dwEffects |= CFE_AUTOCOLOR; 616 else 617 fmt.crTextColor = value; 618 } 619 620 value = tomUndefined; 621 hr = ITextFont_GetKerning(font, &f); 622 if (hr == S_OK && f != tomUndefined) { 623 fmt.dwMask |= CFM_KERNING; 624 fmt.wKerning = points_to_twips(f); 625 } 626 627 value = tomUndefined; 628 hr = ITextFont_GetLanguageID(font, &value); 629 if (hr == S_OK && value != tomUndefined) { 630 fmt.dwMask |= CFM_LCID; 631 fmt.lcid = value; 632 } 633 634 if (ITextFont_GetName(font, &str) == S_OK) { 635 fmt.dwMask |= CFM_FACE; 636 lstrcpynW(fmt.szFaceName, str, sizeof(fmt.szFaceName)/sizeof(WCHAR)); 637 SysFreeString(str); 638 } 639 640 hr = ITextFont_GetPosition(font, &f); 641 if (hr == S_OK && f != tomUndefined) { 642 fmt.dwMask |= CFM_OFFSET; 643 fmt.yOffset = points_to_twips(f); 644 } 645 646 hr = ITextFont_GetSize(font, &f); 647 if (hr == S_OK && f != tomUndefined) { 648 fmt.dwMask |= CFM_SIZE; 649 fmt.yHeight = points_to_twips(f); 650 } 651 652 hr = ITextFont_GetSpacing(font, &f); 653 if (hr == S_OK && f != tomUndefined) { 654 fmt.dwMask |= CFM_SPACING; 655 fmt.sSpacing = f; 656 } 657 658 hr = ITextFont_GetWeight(font, &value); 659 if (hr == S_OK && value != tomUndefined) { 660 fmt.dwMask |= CFM_WEIGHT; 661 fmt.wWeight = value; 662 } 663 664 if (fmt.dwMask) { 665 const IRichEditOleImpl *reole = get_range_reole(range); 666 ME_Cursor from, to; 667 LONG start, end; 668 669 ITextRange_GetStart(range, &start); 670 ITextRange_GetEnd(range, &end); 671 672 ME_CursorFromCharOfs(reole->editor, start, &from); 673 ME_CursorFromCharOfs(reole->editor, end, &to); 674 ME_SetCharFormat(reole->editor, &from, &to, &fmt); 675 } 676 } 677 678 static HRESULT get_textfont_prop(const ITextFontImpl *font, enum textfont_prop_id propid, textfont_prop_val *value) 679 { 680 const IRichEditOleImpl *reole; 681 textfont_prop_val v; 682 LONG start, end, i; 683 HRESULT hr; 684 685 /* when font is not attached to any range use cached values */ 686 if (!font->range || font->get_cache_enabled) { 687 *value = font->props[propid]; 688 return S_OK; 689 } 690 691 if (!(reole = get_range_reole(font->range))) 692 return CO_E_RELEASED; 693 694 init_textfont_prop_value(propid, value); 695 696 ITextRange_GetStart(font->range, &start); 697 ITextRange_GetEnd(font->range, &end); 698 699 /* iterate trough a range to see if property value is consistent */ 700 hr = get_textfont_prop_for_pos(reole, start, propid, &v); 701 if (FAILED(hr)) 702 return hr; 703 704 for (i = start + 1; i < end; i++) { 705 textfont_prop_val cur; 706 707 hr = get_textfont_prop_for_pos(reole, i, propid, &cur); 708 if (FAILED(hr)) 709 return hr; 710 711 if (!is_equal_textfont_prop_value(propid, &v, &cur)) 712 return S_OK; 713 } 714 715 *value = v; 716 return S_OK; 717 } 718 719 static HRESULT get_textfont_propf(const ITextFontImpl *font, enum textfont_prop_id propid, FLOAT *value) 720 { 721 textfont_prop_val v; 722 HRESULT hr; 723 724 if (!value) 725 return E_INVALIDARG; 726 727 hr = get_textfont_prop(font, propid, &v); 728 *value = v.f; 729 return hr; 730 } 731 732 static HRESULT get_textfont_propl(const ITextFontImpl *font, enum textfont_prop_id propid, LONG *value) 733 { 734 textfont_prop_val v; 735 HRESULT hr; 736 737 if (!value) 738 return E_INVALIDARG; 739 740 hr = get_textfont_prop(font, propid, &v); 741 *value = v.l; 742 return hr; 743 } 744 745 /* Value should already have a terminal value, for boolean properties it means tomToggle is not handled */ 746 static HRESULT set_textfont_prop(ITextFontImpl *font, enum textfont_prop_id propid, const textfont_prop_val *value) 747 { 748 const IRichEditOleImpl *reole; 749 ME_Cursor from, to; 750 CHARFORMAT2W fmt; 751 LONG start, end; 752 753 /* when font is not attached to any range use cache */ 754 if (!font->range || font->set_cache_enabled) { 755 if (propid == FONT_NAME) { 756 SysFreeString(font->props[propid].str); 757 font->props[propid].str = SysAllocString(value->str); 758 } 759 else 760 font->props[propid] = *value; 761 return S_OK; 762 } 763 764 if (!(reole = get_range_reole(font->range))) 765 return CO_E_RELEASED; 766 767 memset(&fmt, 0, sizeof(fmt)); 768 fmt.cbSize = sizeof(fmt); 769 fmt.dwMask = textfont_prop_masks[propid][0]; 770 771 switch (propid) 772 { 773 case FONT_ALLCAPS: 774 case FONT_BOLD: 775 case FONT_EMBOSS: 776 case FONT_HIDDEN: 777 case FONT_ENGRAVE: 778 case FONT_ITALIC: 779 case FONT_OUTLINE: 780 case FONT_PROTECTED: 781 case FONT_SHADOW: 782 case FONT_SMALLCAPS: 783 case FONT_STRIKETHROUGH: 784 case FONT_SUBSCRIPT: 785 case FONT_SUPERSCRIPT: 786 case FONT_UNDERLINE: 787 fmt.dwEffects = value->l == tomTrue ? textfont_prop_masks[propid][1] : 0; 788 break; 789 case FONT_ANIMATION: 790 fmt.bAnimation = value->l; 791 break; 792 case FONT_BACKCOLOR: 793 case FONT_FORECOLOR: 794 if (value->l == tomAutoColor) 795 fmt.dwEffects = textfont_prop_masks[propid][1]; 796 else if (propid == FONT_BACKCOLOR) 797 fmt.crBackColor = value->l; 798 else 799 fmt.crTextColor = value->l; 800 break; 801 case FONT_KERNING: 802 fmt.wKerning = value->f; 803 break; 804 case FONT_LANGID: 805 fmt.lcid = value->l; 806 break; 807 case FONT_POSITION: 808 fmt.yOffset = value->f; 809 break; 810 case FONT_SIZE: 811 fmt.yHeight = value->f; 812 break; 813 case FONT_SPACING: 814 fmt.sSpacing = value->f; 815 break; 816 case FONT_WEIGHT: 817 fmt.wWeight = value->l; 818 break; 819 case FONT_NAME: 820 lstrcpynW(fmt.szFaceName, value->str, sizeof(fmt.szFaceName)/sizeof(WCHAR)); 821 break; 822 default: 823 FIXME("unhandled font property %d\n", propid); 824 return E_FAIL; 825 } 826 827 ITextRange_GetStart(font->range, &start); 828 ITextRange_GetEnd(font->range, &end); 829 830 ME_CursorFromCharOfs(reole->editor, start, &from); 831 ME_CursorFromCharOfs(reole->editor, end, &to); 832 ME_SetCharFormat(reole->editor, &from, &to, &fmt); 833 834 return S_OK; 835 } 836 837 static inline HRESULT set_textfont_propl(ITextFontImpl *font, enum textfont_prop_id propid, LONG value) 838 { 839 textfont_prop_val v; 840 v.l = value; 841 return set_textfont_prop(font, propid, &v); 842 } 843 844 static inline HRESULT set_textfont_propf(ITextFontImpl *font, enum textfont_prop_id propid, FLOAT value) 845 { 846 textfont_prop_val v; 847 v.f = value; 848 return set_textfont_prop(font, propid, &v); 849 } 850 851 static HRESULT set_textfont_propd(ITextFontImpl *font, enum textfont_prop_id propid, LONG value) 852 { 853 textfont_prop_val v; 854 855 switch (value) 856 { 857 case tomUndefined: 858 return S_OK; 859 case tomToggle: { 860 LONG oldvalue; 861 get_textfont_propl(font, propid, &oldvalue); 862 if (oldvalue == tomFalse) 863 value = tomTrue; 864 else if (oldvalue == tomTrue) 865 value = tomFalse; 866 else 867 return E_INVALIDARG; 868 /* fallthrough */ 869 } 870 case tomTrue: 871 case tomFalse: 872 v.l = value; 873 return set_textfont_prop(font, propid, &v); 874 default: 875 return E_INVALIDARG; 876 } 877 } 878 879 static HRESULT textfont_getname_from_range(ITextRange *range, BSTR *ret) 880 { 881 const IRichEditOleImpl *reole; 882 textfont_prop_val v; 883 HRESULT hr; 884 LONG start; 885 886 if (!(reole = get_range_reole(range))) 887 return CO_E_RELEASED; 888 889 ITextRange_GetStart(range, &start); 890 hr = get_textfont_prop_for_pos(reole, start, FONT_NAME, &v); 891 *ret = v.str; 892 return hr; 893 } 894 895 static void textfont_cache_range_props(ITextFontImpl *font) 896 { 897 enum textfont_prop_id propid; 898 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) { 899 if (propid == FONT_NAME) 900 textfont_getname_from_range(font->range, &font->props[propid].str); 901 else 902 get_textfont_prop(font, propid, &font->props[propid]); 903 } 904 } 905 906 static HRESULT textrange_expand(ITextRange *range, LONG unit, LONG *delta) 907 { 908 LONG expand_start, expand_end; 909 910 switch (unit) 911 { 912 case tomStory: 913 expand_start = 0; 914 ITextRange_GetStoryLength(range, &expand_end); 915 break; 916 default: 917 FIXME("unit %d is not supported\n", unit); 918 return E_NOTIMPL; 919 } 920 921 if (delta) { 922 LONG start, end; 923 924 ITextRange_GetStart(range, &start); 925 ITextRange_GetEnd(range, &end); 926 *delta = expand_end - expand_start - (end - start); 927 } 928 929 ITextRange_SetStart(range, expand_start); 930 ITextRange_SetEnd(range, expand_end); 931 932 return S_OK; 933 } 934 935 static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) 936 { 937 IRichEditOleImpl *This = impl_from_IUnknown(iface); 938 939 TRACE("%p %s\n", This, debugstr_guid(riid)); 940 941 *ppvObj = NULL; 942 if (IsEqualGUID(riid, &IID_IUnknown)) 943 *ppvObj = &This->IUnknown_inner; 944 else if (IsEqualGUID(riid, &IID_IRichEditOle)) 945 *ppvObj = &This->IRichEditOle_iface; 946 else if (IsEqualGUID(riid, &IID_ITextDocument)) 947 *ppvObj = &This->ITextDocument_iface; 948 if (*ppvObj) 949 { 950 IUnknown_AddRef((IUnknown *)*ppvObj); 951 return S_OK; 952 } 953 954 if (IsEqualGUID(riid, &IID_ITextServices)) 955 { 956 static int once; 957 if (!once++) FIXME("%p: unhandled interface IID_ITextServices\n", This); 958 return E_NOINTERFACE; 959 } 960 961 FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid)); 962 963 return E_NOINTERFACE; 964 } 965 966 static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface) 967 { 968 IRichEditOleImpl *This = impl_from_IUnknown(iface); 969 ULONG ref = InterlockedIncrement(&This->ref); 970 971 TRACE("%p ref = %u\n", This, ref); 972 973 return ref; 974 } 975 976 static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface) 977 { 978 IRichEditOleImpl *This = impl_from_IUnknown(iface); 979 ULONG ref = InterlockedDecrement(&This->ref); 980 981 TRACE ("%p ref=%u\n", This, ref); 982 983 if (!ref) 984 { 985 IOleClientSiteImpl *clientsite; 986 ITextRangeImpl *txtRge; 987 988 This->editor->reOle = NULL; 989 if (This->txtSel) { 990 This->txtSel->reOle = NULL; 991 ITextSelection_Release(&This->txtSel->ITextSelection_iface); 992 } 993 994 LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry) 995 txtRge->child.reole = NULL; 996 997 LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry) 998 clientsite->child.reole = NULL; 999 1000 heap_free(This); 1001 } 1002 return ref; 1003 } 1004 1005 static const IUnknownVtbl reo_unk_vtbl = 1006 { 1007 IRichEditOleImpl_inner_fnQueryInterface, 1008 IRichEditOleImpl_inner_fnAddRef, 1009 IRichEditOleImpl_inner_fnRelease 1010 }; 1011 1012 static HRESULT WINAPI 1013 IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) 1014 { 1015 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1016 return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); 1017 } 1018 1019 static ULONG WINAPI 1020 IRichEditOle_fnAddRef(IRichEditOle *me) 1021 { 1022 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1023 return IUnknown_AddRef(This->outer_unk); 1024 } 1025 1026 static ULONG WINAPI 1027 IRichEditOle_fnRelease(IRichEditOle *me) 1028 { 1029 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1030 return IUnknown_Release(This->outer_unk); 1031 } 1032 1033 static HRESULT WINAPI 1034 IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs) 1035 { 1036 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1037 FIXME("stub %p\n",This); 1038 return E_NOTIMPL; 1039 } 1040 1041 static HRESULT WINAPI 1042 IRichEditOle_fnContextSensitiveHelp(IRichEditOle *me, BOOL fEnterMode) 1043 { 1044 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1045 FIXME("stub %p\n",This); 1046 return E_NOTIMPL; 1047 } 1048 1049 static HRESULT WINAPI 1050 IRichEditOle_fnConvertObject(IRichEditOle *me, LONG iob, 1051 REFCLSID rclsidNew, LPCSTR lpstrUserTypeNew) 1052 { 1053 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1054 FIXME("stub %p\n",This); 1055 return E_NOTIMPL; 1056 } 1057 1058 static inline IOleClientSiteImpl *impl_from_IOleClientSite(IOleClientSite *iface) 1059 { 1060 return CONTAINING_RECORD(iface, IOleClientSiteImpl, IOleClientSite_iface); 1061 } 1062 1063 static HRESULT WINAPI 1064 IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj) 1065 { 1066 IOleClientSiteImpl *This = impl_from_IOleClientSite(me); 1067 TRACE("%p %s\n", me, debugstr_guid(riid) ); 1068 1069 *ppvObj = NULL; 1070 if (IsEqualGUID(riid, &IID_IUnknown) || 1071 IsEqualGUID(riid, &IID_IOleClientSite)) 1072 *ppvObj = me; 1073 else if (IsEqualGUID(riid, &IID_IOleWindow) || 1074 IsEqualGUID(riid, &IID_IOleInPlaceSite)) 1075 *ppvObj = &This->IOleInPlaceSite_iface; 1076 if (*ppvObj) 1077 { 1078 IOleClientSite_AddRef(me); 1079 return S_OK; 1080 } 1081 FIXME("%p: unhandled interface %s\n", me, debugstr_guid(riid) ); 1082 1083 return E_NOINTERFACE; 1084 } 1085 1086 static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface) 1087 { 1088 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1089 ULONG ref = InterlockedIncrement(&This->ref); 1090 TRACE("(%p)->(%u)\n", This, ref); 1091 return ref; 1092 } 1093 1094 static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface) 1095 { 1096 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1097 ULONG ref = InterlockedDecrement(&This->ref); 1098 1099 TRACE("(%p)->(%u)\n", This, ref); 1100 1101 if (ref == 0) { 1102 if (This->child.reole) { 1103 list_remove(&This->child.entry); 1104 This->child.reole = NULL; 1105 } 1106 heap_free(This); 1107 } 1108 return ref; 1109 } 1110 1111 static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface) 1112 { 1113 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1114 if (!This->child.reole) 1115 return CO_E_RELEASED; 1116 1117 FIXME("stub %p\n", iface); 1118 return E_NOTIMPL; 1119 } 1120 1121 static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign, 1122 DWORD dwWhichMoniker, IMoniker **ppmk) 1123 { 1124 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1125 if (!This->child.reole) 1126 return CO_E_RELEASED; 1127 1128 FIXME("stub %p\n", iface); 1129 return E_NOTIMPL; 1130 } 1131 1132 static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface, 1133 IOleContainer **ppContainer) 1134 { 1135 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1136 if (!This->child.reole) 1137 return CO_E_RELEASED; 1138 1139 FIXME("stub %p\n", iface); 1140 return E_NOTIMPL; 1141 } 1142 1143 static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface) 1144 { 1145 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1146 if (!This->child.reole) 1147 return CO_E_RELEASED; 1148 1149 FIXME("stub %p\n", iface); 1150 return E_NOTIMPL; 1151 } 1152 1153 static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow) 1154 { 1155 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1156 if (!This->child.reole) 1157 return CO_E_RELEASED; 1158 1159 FIXME("stub %p\n", iface); 1160 return E_NOTIMPL; 1161 } 1162 1163 static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface) 1164 { 1165 IOleClientSiteImpl *This = impl_from_IOleClientSite(iface); 1166 if (!This->child.reole) 1167 return CO_E_RELEASED; 1168 1169 FIXME("stub %p\n", iface); 1170 return E_NOTIMPL; 1171 } 1172 1173 static const IOleClientSiteVtbl ocst = { 1174 IOleClientSite_fnQueryInterface, 1175 IOleClientSite_fnAddRef, 1176 IOleClientSite_fnRelease, 1177 IOleClientSite_fnSaveObject, 1178 IOleClientSite_fnGetMoniker, 1179 IOleClientSite_fnGetContainer, 1180 IOleClientSite_fnShowObject, 1181 IOleClientSite_fnOnShowWindow, 1182 IOleClientSite_fnRequestNewObjectLayout 1183 }; 1184 1185 /* IOleInPlaceSite interface */ 1186 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnQueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppvObj) 1187 { 1188 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1189 return IOleClientSite_QueryInterface(&This->IOleClientSite_iface, riid, ppvObj); 1190 } 1191 1192 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnAddRef(IOleInPlaceSite *iface) 1193 { 1194 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1195 return IOleClientSite_AddRef(&This->IOleClientSite_iface); 1196 } 1197 1198 static ULONG STDMETHODCALLTYPE IOleInPlaceSite_fnRelease(IOleInPlaceSite *iface) 1199 { 1200 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1201 return IOleClientSite_Release(&This->IOleClientSite_iface); 1202 } 1203 1204 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindow(IOleInPlaceSite *iface, HWND *phwnd) 1205 { 1206 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1207 1208 TRACE("(%p)->(%p)\n", This, phwnd); 1209 1210 if (!This->child.reole) 1211 return CO_E_RELEASED; 1212 1213 if (!phwnd) 1214 return E_INVALIDARG; 1215 1216 *phwnd = This->child.reole->editor->hWnd; 1217 return S_OK; 1218 } 1219 1220 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode) 1221 { 1222 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1223 FIXME("not implemented: (%p)->(%d)\n", This, fEnterMode); 1224 return E_NOTIMPL; 1225 } 1226 1227 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnCanInPlaceActivate(IOleInPlaceSite *iface) 1228 { 1229 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1230 FIXME("not implemented: (%p)\n", This); 1231 return E_NOTIMPL; 1232 } 1233 1234 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceActivate(IOleInPlaceSite *iface) 1235 { 1236 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1237 FIXME("not implemented: (%p)\n", This); 1238 return E_NOTIMPL; 1239 } 1240 1241 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIActivate(IOleInPlaceSite *iface) 1242 { 1243 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1244 FIXME("not implemented: (%p)\n", This); 1245 return E_NOTIMPL; 1246 } 1247 1248 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnGetWindowContext(IOleInPlaceSite *iface, IOleInPlaceFrame **ppFrame, 1249 IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect, 1250 LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) 1251 { 1252 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1253 FIXME("not implemented: (%p)->(%p %p %p %p %p)\n", This, ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo); 1254 return E_NOTIMPL; 1255 } 1256 1257 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnScroll(IOleInPlaceSite *iface, SIZE scrollExtent) 1258 { 1259 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1260 FIXME("not implemented: (%p)\n", This); 1261 return E_NOTIMPL; 1262 } 1263 1264 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable) 1265 { 1266 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1267 FIXME("not implemented: (%p)->(%d)\n", This, fUndoable); 1268 return E_NOTIMPL; 1269 } 1270 1271 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnInPlaceDeactivate(IOleInPlaceSite *iface) 1272 { 1273 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1274 FIXME("not implemented: (%p)\n", This); 1275 return E_NOTIMPL; 1276 } 1277 1278 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDiscardUndoState(IOleInPlaceSite *iface) 1279 { 1280 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1281 FIXME("not implemented: (%p)\n", This); 1282 return E_NOTIMPL; 1283 } 1284 1285 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnDeactivateAndUndo(IOleInPlaceSite *iface) 1286 { 1287 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1288 FIXME("not implemented: (%p)\n", This); 1289 return E_NOTIMPL; 1290 } 1291 1292 static HRESULT STDMETHODCALLTYPE IOleInPlaceSite_fnOnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect) 1293 { 1294 IOleClientSiteImpl *This = impl_from_IOleInPlaceSite(iface); 1295 FIXME("not implemented: (%p)->(%p)\n", This, lprcPosRect); 1296 return E_NOTIMPL; 1297 } 1298 1299 static const IOleInPlaceSiteVtbl olestvt = 1300 { 1301 IOleInPlaceSite_fnQueryInterface, 1302 IOleInPlaceSite_fnAddRef, 1303 IOleInPlaceSite_fnRelease, 1304 IOleInPlaceSite_fnGetWindow, 1305 IOleInPlaceSite_fnContextSensitiveHelp, 1306 IOleInPlaceSite_fnCanInPlaceActivate, 1307 IOleInPlaceSite_fnOnInPlaceActivate, 1308 IOleInPlaceSite_fnOnUIActivate, 1309 IOleInPlaceSite_fnGetWindowContext, 1310 IOleInPlaceSite_fnScroll, 1311 IOleInPlaceSite_fnOnUIDeactivate, 1312 IOleInPlaceSite_fnOnInPlaceDeactivate, 1313 IOleInPlaceSite_fnDiscardUndoState, 1314 IOleInPlaceSite_fnDeactivateAndUndo, 1315 IOleInPlaceSite_fnOnPosRectChange 1316 }; 1317 1318 static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret) 1319 { 1320 IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite); 1321 1322 if (!clientSite) 1323 return E_OUTOFMEMORY; 1324 1325 clientSite->IOleClientSite_iface.lpVtbl = &ocst; 1326 clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt; 1327 clientSite->ref = 1; 1328 clientSite->child.reole = reOle; 1329 list_add_head(&reOle->clientsites, &clientSite->child.entry); 1330 1331 *ret = &clientSite->IOleClientSite_iface; 1332 return S_OK; 1333 } 1334 1335 static HRESULT WINAPI 1336 IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite) 1337 { 1338 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1339 1340 TRACE("(%p)->(%p)\n", This, clientsite); 1341 1342 if (!clientsite) 1343 return E_INVALIDARG; 1344 1345 return CreateOleClientSite(This, clientsite); 1346 } 1347 1348 static HRESULT WINAPI 1349 IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg, 1350 DWORD reco, LPDATAOBJECT *lplpdataobj) 1351 { 1352 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1353 ME_Cursor start; 1354 int nChars; 1355 1356 TRACE("(%p,%p,%d)\n",This, lpchrg, reco); 1357 if(!lplpdataobj) 1358 return E_INVALIDARG; 1359 if(!lpchrg) { 1360 int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo); 1361 start = This->editor->pCursors[nStartCur]; 1362 nChars = nTo - nFrom; 1363 } else { 1364 ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start); 1365 nChars = lpchrg->cpMax - lpchrg->cpMin; 1366 } 1367 return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj); 1368 } 1369 1370 static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me) 1371 { 1372 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1373 FIXME("stub %p\n",This); 1374 return E_NOTIMPL; 1375 } 1376 1377 static HRESULT WINAPI 1378 IRichEditOle_fnGetObject(IRichEditOle *me, LONG iob, 1379 REOBJECT *lpreobject, DWORD dwFlags) 1380 { 1381 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1382 FIXME("stub %p\n",This); 1383 return E_NOTIMPL; 1384 } 1385 1386 static LONG WINAPI 1387 IRichEditOle_fnGetObjectCount(IRichEditOle *me) 1388 { 1389 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1390 FIXME("stub %p\n",This); 1391 return 0; 1392 } 1393 1394 static HRESULT WINAPI 1395 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob) 1396 { 1397 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1398 FIXME("stub %p\n",This); 1399 return E_NOTIMPL; 1400 } 1401 1402 static HRESULT WINAPI 1403 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj, 1404 CLIPFORMAT cf, HGLOBAL hMetaPict) 1405 { 1406 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1407 FIXME("stub %p\n",This); 1408 return E_NOTIMPL; 1409 } 1410 1411 static HRESULT WINAPI 1412 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me) 1413 { 1414 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1415 FIXME("stub %p\n",This); 1416 return E_NOTIMPL; 1417 } 1418 1419 static HRESULT WINAPI 1420 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo) 1421 { 1422 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1423 1424 TRACE("(%p,%p)\n", This, reo); 1425 1426 if (!reo) 1427 return E_INVALIDARG; 1428 1429 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER; 1430 1431 ME_InsertOLEFromCursor(This->editor, reo, 0); 1432 ME_CommitUndo(This->editor); 1433 ME_UpdateRepaint(This->editor, FALSE); 1434 return S_OK; 1435 } 1436 1437 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob, 1438 LPSTORAGE lpstg) 1439 { 1440 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1441 FIXME("stub %p\n",This); 1442 return E_NOTIMPL; 1443 } 1444 1445 static HRESULT WINAPI 1446 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect) 1447 { 1448 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1449 FIXME("stub %p\n",This); 1450 return E_NOTIMPL; 1451 } 1452 1453 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me, 1454 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj) 1455 { 1456 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1457 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj); 1458 return E_NOTIMPL; 1459 } 1460 1461 static HRESULT WINAPI 1462 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable) 1463 { 1464 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1465 FIXME("stub %p\n",This); 1466 return E_NOTIMPL; 1467 } 1468 1469 static const IRichEditOleVtbl revt = { 1470 IRichEditOle_fnQueryInterface, 1471 IRichEditOle_fnAddRef, 1472 IRichEditOle_fnRelease, 1473 IRichEditOle_fnGetClientSite, 1474 IRichEditOle_fnGetObjectCount, 1475 IRichEditOle_fnGetLinkCount, 1476 IRichEditOle_fnGetObject, 1477 IRichEditOle_fnInsertObject, 1478 IRichEditOle_fnConvertObject, 1479 IRichEditOle_fnActivateAs, 1480 IRichEditOle_fnSetHostNames, 1481 IRichEditOle_fnSetLinkAvailable, 1482 IRichEditOle_fnSetDvaspect, 1483 IRichEditOle_fnHandsOffStorage, 1484 IRichEditOle_fnSaveCompleted, 1485 IRichEditOle_fnInPlaceDeactivate, 1486 IRichEditOle_fnContextSensitiveHelp, 1487 IRichEditOle_fnGetClipboardData, 1488 IRichEditOle_fnImportDataObject 1489 }; 1490 1491 /* ITextRange interface */ 1492 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj) 1493 { 1494 ITextRangeImpl *This = impl_from_ITextRange(me); 1495 1496 *ppvObj = NULL; 1497 if (IsEqualGUID(riid, &IID_IUnknown) 1498 || IsEqualGUID(riid, &IID_IDispatch) 1499 || IsEqualGUID(riid, &IID_ITextRange)) 1500 { 1501 *ppvObj = me; 1502 ITextRange_AddRef(me); 1503 return S_OK; 1504 } 1505 else if (IsEqualGUID(riid, &IID_Igetrichole)) 1506 { 1507 *ppvObj = This->child.reole; 1508 return S_OK; 1509 } 1510 1511 return E_NOINTERFACE; 1512 } 1513 1514 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me) 1515 { 1516 ITextRangeImpl *This = impl_from_ITextRange(me); 1517 return InterlockedIncrement(&This->ref); 1518 } 1519 1520 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me) 1521 { 1522 ITextRangeImpl *This = impl_from_ITextRange(me); 1523 ULONG ref = InterlockedDecrement(&This->ref); 1524 1525 TRACE ("%p ref=%u\n", This, ref); 1526 if (ref == 0) 1527 { 1528 if (This->child.reole) 1529 { 1530 list_remove(&This->child.entry); 1531 This->child.reole = NULL; 1532 } 1533 heap_free(This); 1534 } 1535 return ref; 1536 } 1537 1538 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo) 1539 { 1540 ITextRangeImpl *This = impl_from_ITextRange(me); 1541 TRACE("(%p)->(%p)\n", This, pctinfo); 1542 *pctinfo = 1; 1543 return S_OK; 1544 } 1545 1546 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid, 1547 ITypeInfo **ppTInfo) 1548 { 1549 ITextRangeImpl *This = impl_from_ITextRange(me); 1550 HRESULT hr; 1551 1552 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 1553 1554 hr = get_typeinfo(ITextRange_tid, ppTInfo); 1555 if (SUCCEEDED(hr)) 1556 ITypeInfo_AddRef(*ppTInfo); 1557 return hr; 1558 } 1559 1560 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames, 1561 UINT cNames, LCID lcid, DISPID *rgDispId) 1562 { 1563 ITextRangeImpl *This = impl_from_ITextRange(me); 1564 ITypeInfo *ti; 1565 HRESULT hr; 1566 1567 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, 1568 rgDispId); 1569 1570 hr = get_typeinfo(ITextRange_tid, &ti); 1571 if (SUCCEEDED(hr)) 1572 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 1573 return hr; 1574 } 1575 1576 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid, 1577 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 1578 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, 1579 UINT *puArgErr) 1580 { 1581 ITextRangeImpl *This = impl_from_ITextRange(me); 1582 ITypeInfo *ti; 1583 HRESULT hr; 1584 1585 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), 1586 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 1587 1588 hr = get_typeinfo(ITextRange_tid, &ti); 1589 if (SUCCEEDED(hr)) 1590 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 1591 return hr; 1592 } 1593 1594 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str) 1595 { 1596 ITextRangeImpl *This = impl_from_ITextRange(me); 1597 ME_TextEditor *editor; 1598 ME_Cursor start, end; 1599 int length; 1600 BOOL bEOP; 1601 1602 TRACE("(%p)->(%p)\n", This, str); 1603 1604 if (!This->child.reole) 1605 return CO_E_RELEASED; 1606 1607 if (!str) 1608 return E_INVALIDARG; 1609 1610 /* return early for degenerate range */ 1611 if (This->start == This->end) { 1612 *str = NULL; 1613 return S_OK; 1614 } 1615 1616 editor = This->child.reole->editor; 1617 ME_CursorFromCharOfs(editor, This->start, &start); 1618 ME_CursorFromCharOfs(editor, This->end, &end); 1619 1620 length = This->end - This->start; 1621 *str = SysAllocStringLen(NULL, length); 1622 if (!*str) 1623 return E_OUTOFMEMORY; 1624 1625 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor)); 1626 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP); 1627 return S_OK; 1628 } 1629 1630 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str) 1631 { 1632 ITextRangeImpl *This = impl_from_ITextRange(me); 1633 ME_TextEditor *editor; 1634 ME_Cursor cursor; 1635 ME_Style *style; 1636 int len; 1637 1638 TRACE("(%p)->(%s)\n", This, debugstr_w(str)); 1639 1640 if (!This->child.reole) 1641 return CO_E_RELEASED; 1642 1643 editor = This->child.reole->editor; 1644 1645 /* delete only where's something to delete */ 1646 if (This->start != This->end) { 1647 ME_CursorFromCharOfs(editor, This->start, &cursor); 1648 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE); 1649 } 1650 1651 if (!str || !*str) { 1652 /* will update this range as well */ 1653 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE); 1654 return S_OK; 1655 } 1656 1657 /* it's safer not to rely on stored BSTR length */ 1658 len = strlenW(str); 1659 cursor = editor->pCursors[0]; 1660 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]); 1661 style = ME_GetInsertStyle(editor, 0); 1662 ME_InsertTextFromCursor(editor, 0, str, len, style); 1663 ME_ReleaseStyle(style); 1664 editor->pCursors[0] = cursor; 1665 1666 if (len < This->end - This->start) 1667 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE); 1668 else 1669 This->end = len - This->start; 1670 1671 return S_OK; 1672 } 1673 1674 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch) 1675 { 1676 WCHAR wch[2]; 1677 1678 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd); 1679 *pch = wch[0]; 1680 1681 return S_OK; 1682 } 1683 1684 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch) 1685 { 1686 ITextRangeImpl *This = impl_from_ITextRange(me); 1687 ME_TextEditor *editor; 1688 ME_Cursor cursor; 1689 1690 TRACE("(%p)->(%p)\n", This, pch); 1691 1692 if (!This->child.reole) 1693 return CO_E_RELEASED; 1694 1695 if (!pch) 1696 return E_INVALIDARG; 1697 1698 editor = This->child.reole->editor; 1699 ME_CursorFromCharOfs(editor, This->start, &cursor); 1700 return range_GetChar(editor, &cursor, pch); 1701 } 1702 1703 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch) 1704 { 1705 ITextRangeImpl *This = impl_from_ITextRange(me); 1706 1707 FIXME("(%p)->(%x): stub\n", This, ch); 1708 1709 if (!This->child.reole) 1710 return CO_E_RELEASED; 1711 1712 return E_NOTIMPL; 1713 } 1714 1715 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange); 1716 1717 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange) 1718 { 1719 ITextRangeImpl *This = impl_from_ITextRange(me); 1720 1721 TRACE("(%p)->(%p)\n", This, ppRange); 1722 1723 if (!This->child.reole) 1724 return CO_E_RELEASED; 1725 1726 if (!ppRange) 1727 return E_INVALIDARG; 1728 1729 return CreateITextRange(This->child.reole, This->start, This->end, ppRange); 1730 } 1731 1732 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range) 1733 { 1734 ITextRangeImpl *This = impl_from_ITextRange(me); 1735 1736 FIXME("(%p)->(%p): stub\n", This, range); 1737 1738 if (!This->child.reole) 1739 return CO_E_RELEASED; 1740 1741 return E_NOTIMPL; 1742 } 1743 1744 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range) 1745 { 1746 ITextRangeImpl *This = impl_from_ITextRange(me); 1747 1748 FIXME("(%p)->(%p): stub\n", This, range); 1749 1750 if (!This->child.reole) 1751 return CO_E_RELEASED; 1752 1753 return E_NOTIMPL; 1754 } 1755 1756 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start) 1757 { 1758 ITextRangeImpl *This = impl_from_ITextRange(me); 1759 1760 TRACE("(%p)->(%p)\n", This, start); 1761 1762 if (!This->child.reole) 1763 return CO_E_RELEASED; 1764 1765 if (!start) 1766 return E_INVALIDARG; 1767 1768 *start = This->start; 1769 return S_OK; 1770 } 1771 1772 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) 1773 { 1774 int len; 1775 1776 if (value < 0) 1777 value = 0; 1778 1779 if (value == *start) 1780 return S_FALSE; 1781 1782 if (value <= *end) { 1783 *start = value; 1784 return S_OK; 1785 } 1786 1787 len = ME_GetTextLength(reole->editor); 1788 *start = *end = value > len ? len : value; 1789 return S_OK; 1790 } 1791 1792 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value) 1793 { 1794 ITextRangeImpl *This = impl_from_ITextRange(me); 1795 1796 TRACE("(%p)->(%d)\n", This, value); 1797 1798 if (!This->child.reole) 1799 return CO_E_RELEASED; 1800 1801 return textrange_setstart(This->child.reole, value, &This->start, &This->end); 1802 } 1803 1804 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end) 1805 { 1806 ITextRangeImpl *This = impl_from_ITextRange(me); 1807 1808 TRACE("(%p)->(%p)\n", This, end); 1809 1810 if (!This->child.reole) 1811 return CO_E_RELEASED; 1812 1813 if (!end) 1814 return E_INVALIDARG; 1815 1816 *end = This->end; 1817 return S_OK; 1818 } 1819 1820 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) 1821 { 1822 int len; 1823 1824 if (value == *end) 1825 return S_FALSE; 1826 1827 if (value < *start) { 1828 *start = *end = max(0, value); 1829 return S_OK; 1830 } 1831 1832 len = ME_GetTextLength(reole->editor); 1833 *end = value > len ? len + 1 : value; 1834 return S_OK; 1835 } 1836 1837 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value) 1838 { 1839 ITextRangeImpl *This = impl_from_ITextRange(me); 1840 1841 TRACE("(%p)->(%d)\n", This, value); 1842 1843 if (!This->child.reole) 1844 return CO_E_RELEASED; 1845 1846 return textrange_setend(This->child.reole, value, &This->start, &This->end); 1847 } 1848 1849 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font) 1850 { 1851 ITextRangeImpl *This = impl_from_ITextRange(me); 1852 1853 TRACE("(%p)->(%p)\n", This, font); 1854 1855 if (!This->child.reole) 1856 return CO_E_RELEASED; 1857 1858 if (!font) 1859 return E_INVALIDARG; 1860 1861 return create_textfont(me, NULL, font); 1862 } 1863 1864 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font) 1865 { 1866 ITextRangeImpl *This = impl_from_ITextRange(me); 1867 1868 TRACE("(%p)->(%p)\n", This, font); 1869 1870 if (!font) 1871 return E_INVALIDARG; 1872 1873 if (!This->child.reole) 1874 return CO_E_RELEASED; 1875 1876 textrange_set_font(me, font); 1877 return S_OK; 1878 } 1879 1880 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para) 1881 { 1882 ITextRangeImpl *This = impl_from_ITextRange(me); 1883 1884 TRACE("(%p)->(%p)\n", This, para); 1885 1886 if (!This->child.reole) 1887 return CO_E_RELEASED; 1888 1889 if (!para) 1890 return E_INVALIDARG; 1891 1892 return create_textpara(me, para); 1893 } 1894 1895 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para) 1896 { 1897 ITextRangeImpl *This = impl_from_ITextRange(me); 1898 1899 FIXME("(%p)->(%p): stub\n", This, para); 1900 1901 if (!This->child.reole) 1902 return CO_E_RELEASED; 1903 1904 return E_NOTIMPL; 1905 } 1906 1907 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length) 1908 { 1909 ITextRangeImpl *This = impl_from_ITextRange(me); 1910 1911 TRACE("(%p)->(%p)\n", This, length); 1912 1913 if (!This->child.reole) 1914 return CO_E_RELEASED; 1915 1916 return textrange_get_storylength(This->child.reole->editor, length); 1917 } 1918 1919 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value) 1920 { 1921 ITextRangeImpl *This = impl_from_ITextRange(me); 1922 1923 TRACE("(%p)->(%p)\n", This, value); 1924 1925 if (!This->child.reole) 1926 return CO_E_RELEASED; 1927 1928 if (!value) 1929 return E_INVALIDARG; 1930 1931 *value = tomUnknownStory; 1932 return S_OK; 1933 } 1934 1935 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end) 1936 { 1937 if (*end == *start) 1938 return S_FALSE; 1939 1940 if (bStart == tomEnd) 1941 *start = *end; 1942 else 1943 *end = *start; 1944 return S_OK; 1945 } 1946 1947 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart) 1948 { 1949 ITextRangeImpl *This = impl_from_ITextRange(me); 1950 1951 TRACE("(%p)->(%d)\n", This, bStart); 1952 1953 if (!This->child.reole) 1954 return CO_E_RELEASED; 1955 1956 return range_Collapse(bStart, &This->start, &This->end); 1957 } 1958 1959 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta) 1960 { 1961 ITextRangeImpl *This = impl_from_ITextRange(me); 1962 1963 TRACE("(%p)->(%d %p)\n", This, unit, delta); 1964 1965 if (!This->child.reole) 1966 return CO_E_RELEASED; 1967 1968 return textrange_expand(me, unit, delta); 1969 } 1970 1971 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index) 1972 { 1973 ITextRangeImpl *This = impl_from_ITextRange(me); 1974 1975 FIXME("(%p)->(%d %p): stub\n", This, unit, index); 1976 1977 if (!This->child.reole) 1978 return CO_E_RELEASED; 1979 1980 return E_NOTIMPL; 1981 } 1982 1983 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index, 1984 LONG extend) 1985 { 1986 ITextRangeImpl *This = impl_from_ITextRange(me); 1987 1988 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend); 1989 1990 if (!This->child.reole) 1991 return CO_E_RELEASED; 1992 1993 return E_NOTIMPL; 1994 } 1995 1996 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2) 1997 { 1998 int len = ME_GetTextLength(editor) + 1; 1999 *cp1 = max(*cp1, 0); 2000 *cp2 = max(*cp2, 0); 2001 *cp1 = min(*cp1, len); 2002 *cp2 = min(*cp2, len); 2003 if (*cp1 > *cp2) 2004 { 2005 int tmp = *cp1; 2006 *cp1 = *cp2; 2007 *cp2 = tmp; 2008 } 2009 if (*cp1 == len) 2010 *cp1 = *cp2 = len - 1; 2011 } 2012 2013 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active) 2014 { 2015 ITextRangeImpl *This = impl_from_ITextRange(me); 2016 2017 FIXME("(%p)->(%d %d): stub\n", This, anchor, active); 2018 2019 if (!This->child.reole) 2020 return CO_E_RELEASED; 2021 2022 cp2range(This->child.reole->editor, &anchor, &active); 2023 if (anchor == This->start && active == This->end) 2024 return S_FALSE; 2025 2026 This->start = anchor; 2027 This->end = active; 2028 return S_OK; 2029 } 2030 2031 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret) 2032 { 2033 LONG from, to, v; 2034 2035 if (!ret) 2036 ret = &v; 2037 2038 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) { 2039 *ret = tomFalse; 2040 } 2041 else 2042 *ret = (start >= from && end <= to) ? tomTrue : tomFalse; 2043 return *ret == tomTrue ? S_OK : S_FALSE; 2044 } 2045 2046 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret) 2047 { 2048 ITextRangeImpl *This = impl_from_ITextRange(me); 2049 2050 TRACE("(%p)->(%p %p)\n", This, range, ret); 2051 2052 if (ret) 2053 *ret = tomFalse; 2054 2055 if (!This->child.reole) 2056 return CO_E_RELEASED; 2057 2058 if (!range) 2059 return S_FALSE; 2060 2061 return textrange_inrange(This->start, This->end, range, ret); 2062 } 2063 2064 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret) 2065 { 2066 ITextRangeImpl *This = impl_from_ITextRange(me); 2067 2068 FIXME("(%p)->(%p): stub\n", This, ret); 2069 2070 if (!This->child.reole) 2071 return CO_E_RELEASED; 2072 2073 return E_NOTIMPL; 2074 } 2075 2076 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret) 2077 { 2078 LONG from, to, v; 2079 2080 if (!ret) 2081 ret = &v; 2082 2083 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) { 2084 *ret = tomFalse; 2085 } 2086 else 2087 *ret = (start == from && end == to) ? tomTrue : tomFalse; 2088 return *ret == tomTrue ? S_OK : S_FALSE; 2089 } 2090 2091 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret) 2092 { 2093 ITextRangeImpl *This = impl_from_ITextRange(me); 2094 2095 TRACE("(%p)->(%p %p)\n", This, range, ret); 2096 2097 if (ret) 2098 *ret = tomFalse; 2099 2100 if (!This->child.reole) 2101 return CO_E_RELEASED; 2102 2103 if (!range) 2104 return S_FALSE; 2105 2106 return textrange_isequal(This->start, This->end, range, ret); 2107 } 2108 2109 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me) 2110 { 2111 ITextRangeImpl *This = impl_from_ITextRange(me); 2112 2113 TRACE("(%p)\n", This); 2114 2115 if (!This->child.reole) 2116 return CO_E_RELEASED; 2117 2118 ME_SetSelection(This->child.reole->editor, This->start, This->end); 2119 return S_OK; 2120 } 2121 2122 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend, 2123 LONG *delta) 2124 { 2125 ITextRangeImpl *This = impl_from_ITextRange(me); 2126 2127 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 2128 2129 if (!This->child.reole) 2130 return CO_E_RELEASED; 2131 2132 return E_NOTIMPL; 2133 } 2134 2135 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend, 2136 LONG *delta) 2137 { 2138 ITextRangeImpl *This = impl_from_ITextRange(me); 2139 2140 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 2141 2142 if (!This->child.reole) 2143 return CO_E_RELEASED; 2144 2145 return E_NOTIMPL; 2146 } 2147 2148 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta) 2149 { 2150 ITextRangeImpl *This = impl_from_ITextRange(me); 2151 2152 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 2153 2154 if (!This->child.reole) 2155 return CO_E_RELEASED; 2156 2157 return E_NOTIMPL; 2158 } 2159 2160 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count, 2161 LONG *delta) 2162 { 2163 ITextRangeImpl *This = impl_from_ITextRange(me); 2164 2165 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 2166 2167 if (!This->child.reole) 2168 return CO_E_RELEASED; 2169 2170 return E_NOTIMPL; 2171 } 2172 2173 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count, 2174 LONG *delta) 2175 { 2176 ITextRangeImpl *This = impl_from_ITextRange(me); 2177 2178 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 2179 2180 if (!This->child.reole) 2181 return CO_E_RELEASED; 2182 2183 return E_NOTIMPL; 2184 } 2185 2186 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count, 2187 LONG *delta) 2188 { 2189 ITextRangeImpl *This = impl_from_ITextRange(me); 2190 2191 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2192 2193 if (!This->child.reole) 2194 return CO_E_RELEASED; 2195 2196 return E_NOTIMPL; 2197 } 2198 2199 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count, 2200 LONG *delta) 2201 { 2202 ITextRangeImpl *This = impl_from_ITextRange(me); 2203 2204 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2205 2206 if (!This->child.reole) 2207 return CO_E_RELEASED; 2208 2209 return E_NOTIMPL; 2210 } 2211 2212 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count, 2213 LONG *delta) 2214 { 2215 ITextRangeImpl *This = impl_from_ITextRange(me); 2216 2217 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2218 2219 if (!This->child.reole) 2220 return CO_E_RELEASED; 2221 2222 return E_NOTIMPL; 2223 } 2224 2225 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count, 2226 LONG *delta) 2227 { 2228 ITextRangeImpl *This = impl_from_ITextRange(me); 2229 2230 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2231 2232 if (!This->child.reole) 2233 return CO_E_RELEASED; 2234 2235 return E_NOTIMPL; 2236 } 2237 2238 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count, 2239 LONG *delta) 2240 { 2241 ITextRangeImpl *This = impl_from_ITextRange(me); 2242 2243 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2244 2245 if (!This->child.reole) 2246 return CO_E_RELEASED; 2247 2248 return E_NOTIMPL; 2249 } 2250 2251 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count, 2252 LONG *delta) 2253 { 2254 ITextRangeImpl *This = impl_from_ITextRange(me); 2255 2256 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2257 2258 if (!This->child.reole) 2259 return CO_E_RELEASED; 2260 2261 return E_NOTIMPL; 2262 } 2263 2264 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags, 2265 LONG *length) 2266 { 2267 ITextRangeImpl *This = impl_from_ITextRange(me); 2268 2269 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 2270 2271 if (!This->child.reole) 2272 return CO_E_RELEASED; 2273 2274 return E_NOTIMPL; 2275 } 2276 2277 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count, 2278 LONG flags, LONG *length) 2279 { 2280 ITextRangeImpl *This = impl_from_ITextRange(me); 2281 2282 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 2283 2284 if (!This->child.reole) 2285 return CO_E_RELEASED; 2286 2287 return E_NOTIMPL; 2288 } 2289 2290 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count, 2291 LONG flags, LONG *length) 2292 { 2293 ITextRangeImpl *This = impl_from_ITextRange(me); 2294 2295 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 2296 2297 if (!This->child.reole) 2298 return CO_E_RELEASED; 2299 2300 return E_NOTIMPL; 2301 } 2302 2303 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta) 2304 { 2305 ITextRangeImpl *This = impl_from_ITextRange(me); 2306 2307 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 2308 2309 if (!This->child.reole) 2310 return CO_E_RELEASED; 2311 2312 return E_NOTIMPL; 2313 } 2314 2315 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v) 2316 { 2317 ITextRangeImpl *This = impl_from_ITextRange(me); 2318 2319 FIXME("(%p)->(%p): stub\n", This, v); 2320 2321 if (!This->child.reole) 2322 return CO_E_RELEASED; 2323 2324 return E_NOTIMPL; 2325 } 2326 2327 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v) 2328 { 2329 ITextRangeImpl *This = impl_from_ITextRange(me); 2330 2331 FIXME("(%p)->(%p): stub\n", This, v); 2332 2333 if (!This->child.reole) 2334 return CO_E_RELEASED; 2335 2336 return E_NOTIMPL; 2337 } 2338 2339 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format) 2340 { 2341 ITextRangeImpl *This = impl_from_ITextRange(me); 2342 2343 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format); 2344 2345 if (!This->child.reole) 2346 return CO_E_RELEASED; 2347 2348 return E_NOTIMPL; 2349 } 2350 2351 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret) 2352 { 2353 ITextRangeImpl *This = impl_from_ITextRange(me); 2354 2355 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret); 2356 2357 if (!This->child.reole) 2358 return CO_E_RELEASED; 2359 2360 return E_NOTIMPL; 2361 } 2362 2363 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret) 2364 { 2365 ITextRangeImpl *This = impl_from_ITextRange(me); 2366 2367 FIXME("(%p)->(%p): stub\n", This, ret); 2368 2369 if (!This->child.reole) 2370 return CO_E_RELEASED; 2371 2372 return E_NOTIMPL; 2373 } 2374 2375 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type) 2376 { 2377 ITextRangeImpl *This = impl_from_ITextRange(me); 2378 2379 FIXME("(%p)->(%d): stub\n", This, type); 2380 2381 if (!This->child.reole) 2382 return CO_E_RELEASED; 2383 2384 return E_NOTIMPL; 2385 } 2386 2387 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy) 2388 { 2389 ITextRangeImpl *This = impl_from_ITextRange(me); 2390 2391 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy); 2392 2393 if (!This->child.reole) 2394 return CO_E_RELEASED; 2395 2396 return E_NOTIMPL; 2397 } 2398 2399 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type, 2400 LONG extend) 2401 { 2402 ITextRangeImpl *This = impl_from_ITextRange(me); 2403 2404 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend); 2405 2406 if (!This->child.reole) 2407 return CO_E_RELEASED; 2408 2409 return E_NOTIMPL; 2410 } 2411 2412 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value) 2413 { 2414 ITextRangeImpl *This = impl_from_ITextRange(me); 2415 ME_TextEditor *editor; 2416 ME_Cursor cursor; 2417 int x, y, height; 2418 2419 TRACE("(%p)->(%d)\n", This, value); 2420 2421 if (!This->child.reole) 2422 return CO_E_RELEASED; 2423 2424 editor = This->child.reole->editor; 2425 2426 switch (value) 2427 { 2428 case tomStart: 2429 ME_CursorFromCharOfs(editor, This->start, &cursor); 2430 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height); 2431 break; 2432 default: 2433 FIXME("bStart value %d not handled\n", value); 2434 return E_NOTIMPL; 2435 } 2436 ME_ScrollAbs(editor, x, y); 2437 return S_OK; 2438 } 2439 2440 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv) 2441 { 2442 ITextRangeImpl *This = impl_from_ITextRange(me); 2443 2444 FIXME("(%p)->(%p): stub\n", This, ppv); 2445 2446 if (!This->child.reole) 2447 return CO_E_RELEASED; 2448 2449 return E_NOTIMPL; 2450 } 2451 2452 static const ITextRangeVtbl trvt = { 2453 ITextRange_fnQueryInterface, 2454 ITextRange_fnAddRef, 2455 ITextRange_fnRelease, 2456 ITextRange_fnGetTypeInfoCount, 2457 ITextRange_fnGetTypeInfo, 2458 ITextRange_fnGetIDsOfNames, 2459 ITextRange_fnInvoke, 2460 ITextRange_fnGetText, 2461 ITextRange_fnSetText, 2462 ITextRange_fnGetChar, 2463 ITextRange_fnSetChar, 2464 ITextRange_fnGetDuplicate, 2465 ITextRange_fnGetFormattedText, 2466 ITextRange_fnSetFormattedText, 2467 ITextRange_fnGetStart, 2468 ITextRange_fnSetStart, 2469 ITextRange_fnGetEnd, 2470 ITextRange_fnSetEnd, 2471 ITextRange_fnGetFont, 2472 ITextRange_fnSetFont, 2473 ITextRange_fnGetPara, 2474 ITextRange_fnSetPara, 2475 ITextRange_fnGetStoryLength, 2476 ITextRange_fnGetStoryType, 2477 ITextRange_fnCollapse, 2478 ITextRange_fnExpand, 2479 ITextRange_fnGetIndex, 2480 ITextRange_fnSetIndex, 2481 ITextRange_fnSetRange, 2482 ITextRange_fnInRange, 2483 ITextRange_fnInStory, 2484 ITextRange_fnIsEqual, 2485 ITextRange_fnSelect, 2486 ITextRange_fnStartOf, 2487 ITextRange_fnEndOf, 2488 ITextRange_fnMove, 2489 ITextRange_fnMoveStart, 2490 ITextRange_fnMoveEnd, 2491 ITextRange_fnMoveWhile, 2492 ITextRange_fnMoveStartWhile, 2493 ITextRange_fnMoveEndWhile, 2494 ITextRange_fnMoveUntil, 2495 ITextRange_fnMoveStartUntil, 2496 ITextRange_fnMoveEndUntil, 2497 ITextRange_fnFindText, 2498 ITextRange_fnFindTextStart, 2499 ITextRange_fnFindTextEnd, 2500 ITextRange_fnDelete, 2501 ITextRange_fnCut, 2502 ITextRange_fnCopy, 2503 ITextRange_fnPaste, 2504 ITextRange_fnCanPaste, 2505 ITextRange_fnCanEdit, 2506 ITextRange_fnChangeCase, 2507 ITextRange_fnGetPoint, 2508 ITextRange_fnSetPoint, 2509 ITextRange_fnScrollIntoView, 2510 ITextRange_fnGetEmbeddedObject 2511 }; 2512 2513 /* ITextFont */ 2514 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv) 2515 { 2516 ITextFontImpl *This = impl_from_ITextFont(iface); 2517 2518 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 2519 2520 if (IsEqualIID(riid, &IID_ITextFont) || 2521 IsEqualIID(riid, &IID_IDispatch) || 2522 IsEqualIID(riid, &IID_IUnknown)) 2523 { 2524 *ppv = iface; 2525 ITextFont_AddRef(iface); 2526 return S_OK; 2527 } 2528 2529 *ppv = NULL; 2530 return E_NOINTERFACE; 2531 } 2532 2533 static ULONG WINAPI TextFont_AddRef(ITextFont *iface) 2534 { 2535 ITextFontImpl *This = impl_from_ITextFont(iface); 2536 ULONG ref = InterlockedIncrement(&This->ref); 2537 TRACE("(%p)->(%u)\n", This, ref); 2538 return ref; 2539 } 2540 2541 static ULONG WINAPI TextFont_Release(ITextFont *iface) 2542 { 2543 ITextFontImpl *This = impl_from_ITextFont(iface); 2544 ULONG ref = InterlockedDecrement(&This->ref); 2545 2546 TRACE("(%p)->(%u)\n", This, ref); 2547 2548 if (!ref) 2549 { 2550 if (This->range) 2551 ITextRange_Release(This->range); 2552 SysFreeString(This->props[FONT_NAME].str); 2553 heap_free(This); 2554 } 2555 2556 return ref; 2557 } 2558 2559 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo) 2560 { 2561 ITextFontImpl *This = impl_from_ITextFont(iface); 2562 TRACE("(%p)->(%p)\n", This, pctinfo); 2563 *pctinfo = 1; 2564 return S_OK; 2565 } 2566 2567 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid, 2568 ITypeInfo **ppTInfo) 2569 { 2570 ITextFontImpl *This = impl_from_ITextFont(iface); 2571 HRESULT hr; 2572 2573 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 2574 2575 hr = get_typeinfo(ITextFont_tid, ppTInfo); 2576 if (SUCCEEDED(hr)) 2577 ITypeInfo_AddRef(*ppTInfo); 2578 return hr; 2579 } 2580 2581 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid, 2582 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 2583 { 2584 ITextFontImpl *This = impl_from_ITextFont(iface); 2585 ITypeInfo *ti; 2586 HRESULT hr; 2587 2588 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), 2589 rgszNames, cNames, lcid, rgDispId); 2590 2591 hr = get_typeinfo(ITextFont_tid, &ti); 2592 if (SUCCEEDED(hr)) 2593 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 2594 return hr; 2595 } 2596 2597 static HRESULT WINAPI TextFont_Invoke( 2598 ITextFont *iface, 2599 DISPID dispIdMember, 2600 REFIID riid, 2601 LCID lcid, 2602 WORD wFlags, 2603 DISPPARAMS *pDispParams, 2604 VARIANT *pVarResult, 2605 EXCEPINFO *pExcepInfo, 2606 UINT *puArgErr) 2607 { 2608 ITextFontImpl *This = impl_from_ITextFont(iface); 2609 ITypeInfo *ti; 2610 HRESULT hr; 2611 2612 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), 2613 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 2614 2615 hr = get_typeinfo(ITextFont_tid, &ti); 2616 if (SUCCEEDED(hr)) 2617 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 2618 return hr; 2619 } 2620 2621 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret) 2622 { 2623 ITextFontImpl *This = impl_from_ITextFont(iface); 2624 2625 TRACE("(%p)->(%p)\n", This, ret); 2626 2627 if (!ret) 2628 return E_INVALIDARG; 2629 2630 *ret = NULL; 2631 if (This->range && !get_range_reole(This->range)) 2632 return CO_E_RELEASED; 2633 2634 return create_textfont(NULL, This, ret); 2635 } 2636 2637 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont) 2638 { 2639 ITextFontImpl *This = impl_from_ITextFont(iface); 2640 FIXME("(%p)->(%p): stub\n", This, pFont); 2641 2642 if (This->range && !get_range_reole(This->range)) 2643 return CO_E_RELEASED; 2644 2645 return E_NOTIMPL; 2646 } 2647 2648 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret) 2649 { 2650 ITextFontImpl *This = impl_from_ITextFont(iface); 2651 FIXME("(%p)->(%p): stub\n", This, ret); 2652 2653 if (This->range && !get_range_reole(This->range)) 2654 return CO_E_RELEASED; 2655 2656 return E_NOTIMPL; 2657 } 2658 2659 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret) 2660 { 2661 ITextFontImpl *This = impl_from_ITextFont(iface); 2662 FIXME("(%p)->(%p %p): stub\n", This, font, ret); 2663 2664 if (This->range && !get_range_reole(This->range)) 2665 return CO_E_RELEASED; 2666 2667 return E_NOTIMPL; 2668 } 2669 2670 static void textfont_reset_to_default(ITextFontImpl *font) 2671 { 2672 enum textfont_prop_id id; 2673 2674 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { 2675 switch (id) 2676 { 2677 case FONT_ALLCAPS: 2678 case FONT_ANIMATION: 2679 case FONT_BOLD: 2680 case FONT_EMBOSS: 2681 case FONT_HIDDEN: 2682 case FONT_ENGRAVE: 2683 case FONT_ITALIC: 2684 case FONT_OUTLINE: 2685 case FONT_PROTECTED: 2686 case FONT_SHADOW: 2687 case FONT_SMALLCAPS: 2688 case FONT_STRIKETHROUGH: 2689 case FONT_SUBSCRIPT: 2690 case FONT_SUPERSCRIPT: 2691 case FONT_UNDERLINE: 2692 font->props[id].l = tomFalse; 2693 break; 2694 case FONT_BACKCOLOR: 2695 case FONT_FORECOLOR: 2696 font->props[id].l = tomAutoColor; 2697 break; 2698 case FONT_KERNING: 2699 case FONT_POSITION: 2700 case FONT_SIZE: 2701 case FONT_SPACING: 2702 font->props[id].f = 0.0; 2703 break; 2704 case FONT_LANGID: 2705 font->props[id].l = GetSystemDefaultLCID(); 2706 break; 2707 case FONT_NAME: { 2708 static const WCHAR sysW[] = {'S','y','s','t','e','m',0}; 2709 SysFreeString(font->props[id].str); 2710 font->props[id].str = SysAllocString(sysW); 2711 break; 2712 } 2713 case FONT_WEIGHT: 2714 font->props[id].l = FW_NORMAL; 2715 break; 2716 default: 2717 FIXME("font property %d not handled\n", id); 2718 } 2719 } 2720 } 2721 2722 static void textfont_reset_to_undefined(ITextFontImpl *font) 2723 { 2724 enum textfont_prop_id id; 2725 2726 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { 2727 switch (id) 2728 { 2729 case FONT_ALLCAPS: 2730 case FONT_ANIMATION: 2731 case FONT_BOLD: 2732 case FONT_EMBOSS: 2733 case FONT_HIDDEN: 2734 case FONT_ENGRAVE: 2735 case FONT_ITALIC: 2736 case FONT_OUTLINE: 2737 case FONT_PROTECTED: 2738 case FONT_SHADOW: 2739 case FONT_SMALLCAPS: 2740 case FONT_STRIKETHROUGH: 2741 case FONT_SUBSCRIPT: 2742 case FONT_SUPERSCRIPT: 2743 case FONT_UNDERLINE: 2744 case FONT_BACKCOLOR: 2745 case FONT_FORECOLOR: 2746 case FONT_LANGID: 2747 case FONT_WEIGHT: 2748 font->props[id].l = tomUndefined; 2749 break; 2750 case FONT_KERNING: 2751 case FONT_POSITION: 2752 case FONT_SIZE: 2753 case FONT_SPACING: 2754 font->props[id].f = tomUndefined; 2755 break; 2756 case FONT_NAME: 2757 break; 2758 default: 2759 FIXME("font property %d not handled\n", id); 2760 } 2761 } 2762 } 2763 2764 static void textfont_apply_range_props(ITextFontImpl *font) 2765 { 2766 enum textfont_prop_id propid; 2767 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) 2768 set_textfont_prop(font, propid, &font->props[propid]); 2769 } 2770 2771 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value) 2772 { 2773 ITextFontImpl *This = impl_from_ITextFont(iface); 2774 2775 TRACE("(%p)->(%d)\n", This, value); 2776 2777 /* If font is attached to a range, released or not, we can't 2778 reset to undefined */ 2779 if (This->range) { 2780 if (!get_range_reole(This->range)) 2781 return CO_E_RELEASED; 2782 2783 switch (value) 2784 { 2785 case tomUndefined: 2786 return E_INVALIDARG; 2787 case tomCacheParms: 2788 textfont_cache_range_props(This); 2789 This->get_cache_enabled = TRUE; 2790 break; 2791 case tomTrackParms: 2792 This->get_cache_enabled = FALSE; 2793 break; 2794 case tomApplyLater: 2795 This->set_cache_enabled = TRUE; 2796 break; 2797 case tomApplyNow: 2798 This->set_cache_enabled = FALSE; 2799 textfont_apply_range_props(This); 2800 break; 2801 case tomUsePoints: 2802 case tomUseTwips: 2803 return E_INVALIDARG; 2804 default: 2805 FIXME("reset mode %d not supported\n", value); 2806 } 2807 2808 return S_OK; 2809 } 2810 else { 2811 switch (value) 2812 { 2813 /* reset to global defaults */ 2814 case tomDefault: 2815 textfont_reset_to_default(This); 2816 return S_OK; 2817 /* all properties are set to tomUndefined, font name is retained */ 2818 case tomUndefined: 2819 textfont_reset_to_undefined(This); 2820 return S_OK; 2821 case tomApplyNow: 2822 case tomApplyLater: 2823 case tomTrackParms: 2824 case tomCacheParms: 2825 return S_OK; 2826 case tomUsePoints: 2827 case tomUseTwips: 2828 return E_INVALIDARG; 2829 } 2830 } 2831 2832 FIXME("reset mode %d not supported\n", value); 2833 return E_NOTIMPL; 2834 } 2835 2836 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value) 2837 { 2838 ITextFontImpl *This = impl_from_ITextFont(iface); 2839 FIXME("(%p)->(%p): stub\n", This, value); 2840 2841 if (This->range && !get_range_reole(This->range)) 2842 return CO_E_RELEASED; 2843 2844 return E_NOTIMPL; 2845 } 2846 2847 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value) 2848 { 2849 ITextFontImpl *This = impl_from_ITextFont(iface); 2850 FIXME("(%p)->(%d): stub\n", This, value); 2851 2852 if (This->range && !get_range_reole(This->range)) 2853 return CO_E_RELEASED; 2854 2855 return E_NOTIMPL; 2856 } 2857 2858 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value) 2859 { 2860 ITextFontImpl *This = impl_from_ITextFont(iface); 2861 TRACE("(%p)->(%p)\n", This, value); 2862 return get_textfont_propl(This, FONT_ALLCAPS, value); 2863 } 2864 2865 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value) 2866 { 2867 ITextFontImpl *This = impl_from_ITextFont(iface); 2868 TRACE("(%p)->(%d)\n", This, value); 2869 return set_textfont_propd(This, FONT_ALLCAPS, value); 2870 } 2871 2872 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value) 2873 { 2874 ITextFontImpl *This = impl_from_ITextFont(iface); 2875 TRACE("(%p)->(%p)\n", This, value); 2876 return get_textfont_propl(This, FONT_ANIMATION, value); 2877 } 2878 2879 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value) 2880 { 2881 ITextFontImpl *This = impl_from_ITextFont(iface); 2882 2883 TRACE("(%p)->(%d)\n", This, value); 2884 2885 if (value < tomNoAnimation || value > tomAnimationMax) 2886 return E_INVALIDARG; 2887 2888 return set_textfont_propl(This, FONT_ANIMATION, value); 2889 } 2890 2891 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value) 2892 { 2893 ITextFontImpl *This = impl_from_ITextFont(iface); 2894 TRACE("(%p)->(%p)\n", This, value); 2895 return get_textfont_propl(This, FONT_BACKCOLOR, value); 2896 } 2897 2898 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value) 2899 { 2900 ITextFontImpl *This = impl_from_ITextFont(iface); 2901 TRACE("(%p)->(%d)\n", This, value); 2902 return set_textfont_propl(This, FONT_BACKCOLOR, value); 2903 } 2904 2905 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value) 2906 { 2907 ITextFontImpl *This = impl_from_ITextFont(iface); 2908 TRACE("(%p)->(%p)\n", This, value); 2909 return get_textfont_propl(This, FONT_BOLD, value); 2910 } 2911 2912 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value) 2913 { 2914 ITextFontImpl *This = impl_from_ITextFont(iface); 2915 TRACE("(%p)->(%d)\n", This, value); 2916 return set_textfont_propd(This, FONT_BOLD, value); 2917 } 2918 2919 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value) 2920 { 2921 ITextFontImpl *This = impl_from_ITextFont(iface); 2922 TRACE("(%p)->(%p)\n", This, value); 2923 return get_textfont_propl(This, FONT_EMBOSS, value); 2924 } 2925 2926 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value) 2927 { 2928 ITextFontImpl *This = impl_from_ITextFont(iface); 2929 TRACE("(%p)->(%d)\n", This, value); 2930 return set_textfont_propd(This, FONT_EMBOSS, value); 2931 } 2932 2933 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value) 2934 { 2935 ITextFontImpl *This = impl_from_ITextFont(iface); 2936 TRACE("(%p)->(%p)\n", This, value); 2937 return get_textfont_propl(This, FONT_FORECOLOR, value); 2938 } 2939 2940 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value) 2941 { 2942 ITextFontImpl *This = impl_from_ITextFont(iface); 2943 TRACE("(%p)->(%d)\n", This, value); 2944 return set_textfont_propl(This, FONT_FORECOLOR, value); 2945 } 2946 2947 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value) 2948 { 2949 ITextFontImpl *This = impl_from_ITextFont(iface); 2950 TRACE("(%p)->(%p)\n", This, value); 2951 return get_textfont_propl(This, FONT_HIDDEN, value); 2952 } 2953 2954 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value) 2955 { 2956 ITextFontImpl *This = impl_from_ITextFont(iface); 2957 TRACE("(%p)->(%d)\n", This, value); 2958 return set_textfont_propd(This, FONT_HIDDEN, value); 2959 } 2960 2961 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value) 2962 { 2963 ITextFontImpl *This = impl_from_ITextFont(iface); 2964 TRACE("(%p)->(%p)\n", This, value); 2965 return get_textfont_propl(This, FONT_ENGRAVE, value); 2966 } 2967 2968 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value) 2969 { 2970 ITextFontImpl *This = impl_from_ITextFont(iface); 2971 TRACE("(%p)->(%d)\n", This, value); 2972 return set_textfont_propd(This, FONT_ENGRAVE, value); 2973 } 2974 2975 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value) 2976 { 2977 ITextFontImpl *This = impl_from_ITextFont(iface); 2978 TRACE("(%p)->(%p)\n", This, value); 2979 return get_textfont_propl(This, FONT_ITALIC, value); 2980 } 2981 2982 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value) 2983 { 2984 ITextFontImpl *This = impl_from_ITextFont(iface); 2985 TRACE("(%p)->(%d)\n", This, value); 2986 return set_textfont_propd(This, FONT_ITALIC, value); 2987 } 2988 2989 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value) 2990 { 2991 ITextFontImpl *This = impl_from_ITextFont(iface); 2992 TRACE("(%p)->(%p)\n", This, value); 2993 return get_textfont_propf(This, FONT_KERNING, value); 2994 } 2995 2996 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value) 2997 { 2998 ITextFontImpl *This = impl_from_ITextFont(iface); 2999 TRACE("(%p)->(%.2f)\n", This, value); 3000 return set_textfont_propf(This, FONT_KERNING, value); 3001 } 3002 3003 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value) 3004 { 3005 ITextFontImpl *This = impl_from_ITextFont(iface); 3006 TRACE("(%p)->(%p)\n", This, value); 3007 return get_textfont_propl(This, FONT_LANGID, value); 3008 } 3009 3010 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value) 3011 { 3012 ITextFontImpl *This = impl_from_ITextFont(iface); 3013 TRACE("(%p)->(%d)\n", This, value); 3014 return set_textfont_propl(This, FONT_LANGID, value); 3015 } 3016 3017 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value) 3018 { 3019 ITextFontImpl *This = impl_from_ITextFont(iface); 3020 3021 TRACE("(%p)->(%p)\n", This, value); 3022 3023 if (!value) 3024 return E_INVALIDARG; 3025 3026 *value = NULL; 3027 3028 if (!This->range) { 3029 if (This->props[FONT_NAME].str) 3030 *value = SysAllocString(This->props[FONT_NAME].str); 3031 else 3032 *value = SysAllocStringLen(NULL, 0); 3033 return *value ? S_OK : E_OUTOFMEMORY; 3034 } 3035 3036 return textfont_getname_from_range(This->range, value); 3037 } 3038 3039 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value) 3040 { 3041 ITextFontImpl *This = impl_from_ITextFont(iface); 3042 textfont_prop_val v; 3043 3044 TRACE("(%p)->(%s)\n", This, debugstr_w(value)); 3045 3046 v.str = value; 3047 return set_textfont_prop(This, FONT_NAME, &v); 3048 } 3049 3050 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value) 3051 { 3052 ITextFontImpl *This = impl_from_ITextFont(iface); 3053 TRACE("(%p)->(%p)\n", This, value); 3054 return get_textfont_propl(This, FONT_OUTLINE, value); 3055 } 3056 3057 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value) 3058 { 3059 ITextFontImpl *This = impl_from_ITextFont(iface); 3060 TRACE("(%p)->(%d)\n", This, value); 3061 return set_textfont_propd(This, FONT_OUTLINE, value); 3062 } 3063 3064 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value) 3065 { 3066 ITextFontImpl *This = impl_from_ITextFont(iface); 3067 TRACE("(%p)->(%p)\n", This, value); 3068 return get_textfont_propf(This, FONT_POSITION, value); 3069 } 3070 3071 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value) 3072 { 3073 ITextFontImpl *This = impl_from_ITextFont(iface); 3074 TRACE("(%p)->(%.2f)\n", This, value); 3075 return set_textfont_propf(This, FONT_POSITION, value); 3076 } 3077 3078 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value) 3079 { 3080 ITextFontImpl *This = impl_from_ITextFont(iface); 3081 TRACE("(%p)->(%p)\n", This, value); 3082 return get_textfont_propl(This, FONT_PROTECTED, value); 3083 } 3084 3085 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value) 3086 { 3087 ITextFontImpl *This = impl_from_ITextFont(iface); 3088 TRACE("(%p)->(%d)\n", This, value); 3089 return set_textfont_propd(This, FONT_PROTECTED, value); 3090 } 3091 3092 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value) 3093 { 3094 ITextFontImpl *This = impl_from_ITextFont(iface); 3095 TRACE("(%p)->(%p)\n", This, value); 3096 return get_textfont_propl(This, FONT_SHADOW, value); 3097 } 3098 3099 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value) 3100 { 3101 ITextFontImpl *This = impl_from_ITextFont(iface); 3102 TRACE("(%p)->(%d)\n", This, value); 3103 return set_textfont_propd(This, FONT_SHADOW, value); 3104 } 3105 3106 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value) 3107 { 3108 ITextFontImpl *This = impl_from_ITextFont(iface); 3109 TRACE("(%p)->(%p)\n", This, value); 3110 return get_textfont_propf(This, FONT_SIZE, value); 3111 } 3112 3113 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value) 3114 { 3115 ITextFontImpl *This = impl_from_ITextFont(iface); 3116 TRACE("(%p)->(%.2f)\n", This, value); 3117 return set_textfont_propf(This, FONT_SIZE, value); 3118 } 3119 3120 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value) 3121 { 3122 ITextFontImpl *This = impl_from_ITextFont(iface); 3123 TRACE("(%p)->(%p)\n", This, value); 3124 return get_textfont_propl(This, FONT_SMALLCAPS, value); 3125 } 3126 3127 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value) 3128 { 3129 ITextFontImpl *This = impl_from_ITextFont(iface); 3130 TRACE("(%p)->(%d)\n", This, value); 3131 return set_textfont_propd(This, FONT_SMALLCAPS, value); 3132 } 3133 3134 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value) 3135 { 3136 ITextFontImpl *This = impl_from_ITextFont(iface); 3137 TRACE("(%p)->(%p)\n", This, value); 3138 return get_textfont_propf(This, FONT_SPACING, value); 3139 } 3140 3141 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value) 3142 { 3143 ITextFontImpl *This = impl_from_ITextFont(iface); 3144 TRACE("(%p)->(%.2f)\n", This, value); 3145 return set_textfont_propf(This, FONT_SPACING, value); 3146 } 3147 3148 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value) 3149 { 3150 ITextFontImpl *This = impl_from_ITextFont(iface); 3151 TRACE("(%p)->(%p)\n", This, value); 3152 return get_textfont_propl(This, FONT_STRIKETHROUGH, value); 3153 } 3154 3155 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value) 3156 { 3157 ITextFontImpl *This = impl_from_ITextFont(iface); 3158 TRACE("(%p)->(%d)\n", This, value); 3159 return set_textfont_propd(This, FONT_STRIKETHROUGH, value); 3160 } 3161 3162 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value) 3163 { 3164 ITextFontImpl *This = impl_from_ITextFont(iface); 3165 TRACE("(%p)->(%p)\n", This, value); 3166 return get_textfont_propl(This, FONT_SUBSCRIPT, value); 3167 } 3168 3169 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value) 3170 { 3171 ITextFontImpl *This = impl_from_ITextFont(iface); 3172 TRACE("(%p)->(%d)\n", This, value); 3173 return set_textfont_propd(This, FONT_SUBSCRIPT, value); 3174 } 3175 3176 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value) 3177 { 3178 ITextFontImpl *This = impl_from_ITextFont(iface); 3179 TRACE("(%p)->(%p)\n", This, value); 3180 return get_textfont_propl(This, FONT_SUPERSCRIPT, value); 3181 } 3182 3183 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value) 3184 { 3185 ITextFontImpl *This = impl_from_ITextFont(iface); 3186 TRACE("(%p)->(%d)\n", This, value); 3187 return set_textfont_propd(This, FONT_SUPERSCRIPT, value); 3188 } 3189 3190 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value) 3191 { 3192 ITextFontImpl *This = impl_from_ITextFont(iface); 3193 TRACE("(%p)->(%p)\n", This, value); 3194 return get_textfont_propl(This, FONT_UNDERLINE, value); 3195 } 3196 3197 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value) 3198 { 3199 ITextFontImpl *This = impl_from_ITextFont(iface); 3200 TRACE("(%p)->(%d)\n", This, value); 3201 return set_textfont_propd(This, FONT_UNDERLINE, value); 3202 } 3203 3204 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value) 3205 { 3206 ITextFontImpl *This = impl_from_ITextFont(iface); 3207 TRACE("(%p)->(%p)\n", This, value); 3208 return get_textfont_propl(This, FONT_WEIGHT, value); 3209 } 3210 3211 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value) 3212 { 3213 ITextFontImpl *This = impl_from_ITextFont(iface); 3214 TRACE("(%p)->(%d)\n", This, value); 3215 return set_textfont_propl(This, FONT_WEIGHT, value); 3216 } 3217 3218 static ITextFontVtbl textfontvtbl = { 3219 TextFont_QueryInterface, 3220 TextFont_AddRef, 3221 TextFont_Release, 3222 TextFont_GetTypeInfoCount, 3223 TextFont_GetTypeInfo, 3224 TextFont_GetIDsOfNames, 3225 TextFont_Invoke, 3226 TextFont_GetDuplicate, 3227 TextFont_SetDuplicate, 3228 TextFont_CanChange, 3229 TextFont_IsEqual, 3230 TextFont_Reset, 3231 TextFont_GetStyle, 3232 TextFont_SetStyle, 3233 TextFont_GetAllCaps, 3234 TextFont_SetAllCaps, 3235 TextFont_GetAnimation, 3236 TextFont_SetAnimation, 3237 TextFont_GetBackColor, 3238 TextFont_SetBackColor, 3239 TextFont_GetBold, 3240 TextFont_SetBold, 3241 TextFont_GetEmboss, 3242 TextFont_SetEmboss, 3243 TextFont_GetForeColor, 3244 TextFont_SetForeColor, 3245 TextFont_GetHidden, 3246 TextFont_SetHidden, 3247 TextFont_GetEngrave, 3248 TextFont_SetEngrave, 3249 TextFont_GetItalic, 3250 TextFont_SetItalic, 3251 TextFont_GetKerning, 3252 TextFont_SetKerning, 3253 TextFont_GetLanguageID, 3254 TextFont_SetLanguageID, 3255 TextFont_GetName, 3256 TextFont_SetName, 3257 TextFont_GetOutline, 3258 TextFont_SetOutline, 3259 TextFont_GetPosition, 3260 TextFont_SetPosition, 3261 TextFont_GetProtected, 3262 TextFont_SetProtected, 3263 TextFont_GetShadow, 3264 TextFont_SetShadow, 3265 TextFont_GetSize, 3266 TextFont_SetSize, 3267 TextFont_GetSmallCaps, 3268 TextFont_SetSmallCaps, 3269 TextFont_GetSpacing, 3270 TextFont_SetSpacing, 3271 TextFont_GetStrikeThrough, 3272 TextFont_SetStrikeThrough, 3273 TextFont_GetSubscript, 3274 TextFont_SetSubscript, 3275 TextFont_GetSuperscript, 3276 TextFont_SetSuperscript, 3277 TextFont_GetUnderline, 3278 TextFont_SetUnderline, 3279 TextFont_GetWeight, 3280 TextFont_SetWeight 3281 }; 3282 3283 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret) 3284 { 3285 ITextFontImpl *font; 3286 3287 *ret = NULL; 3288 font = heap_alloc(sizeof(*font)); 3289 if (!font) 3290 return E_OUTOFMEMORY; 3291 3292 font->ITextFont_iface.lpVtbl = &textfontvtbl; 3293 font->ref = 1; 3294 3295 if (src) { 3296 font->range = NULL; 3297 font->get_cache_enabled = TRUE; 3298 font->set_cache_enabled = TRUE; 3299 memcpy(&font->props, &src->props, sizeof(font->props)); 3300 if (font->props[FONT_NAME].str) 3301 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str); 3302 } 3303 else { 3304 font->range = range; 3305 ITextRange_AddRef(range); 3306 3307 /* cache current properties */ 3308 font->get_cache_enabled = FALSE; 3309 font->set_cache_enabled = FALSE; 3310 textfont_cache_range_props(font); 3311 } 3312 3313 *ret = &font->ITextFont_iface; 3314 return S_OK; 3315 } 3316 3317 /* ITextPara */ 3318 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv) 3319 { 3320 ITextParaImpl *This = impl_from_ITextPara(iface); 3321 3322 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 3323 3324 if (IsEqualIID(riid, &IID_ITextPara) || 3325 IsEqualIID(riid, &IID_IDispatch) || 3326 IsEqualIID(riid, &IID_IUnknown)) 3327 { 3328 *ppv = iface; 3329 ITextPara_AddRef(iface); 3330 return S_OK; 3331 } 3332 3333 *ppv = NULL; 3334 return E_NOINTERFACE; 3335 } 3336 3337 static ULONG WINAPI TextPara_AddRef(ITextPara *iface) 3338 { 3339 ITextParaImpl *This = impl_from_ITextPara(iface); 3340 ULONG ref = InterlockedIncrement(&This->ref); 3341 TRACE("(%p)->(%u)\n", This, ref); 3342 return ref; 3343 } 3344 3345 static ULONG WINAPI TextPara_Release(ITextPara *iface) 3346 { 3347 ITextParaImpl *This = impl_from_ITextPara(iface); 3348 ULONG ref = InterlockedDecrement(&This->ref); 3349 3350 TRACE("(%p)->(%u)\n", This, ref); 3351 3352 if (!ref) 3353 { 3354 ITextRange_Release(This->range); 3355 heap_free(This); 3356 } 3357 3358 return ref; 3359 } 3360 3361 static IRichEditOleImpl *para_get_reole(ITextParaImpl *This) 3362 { 3363 if (This->range) 3364 { 3365 ITextRangeImpl *rng = impl_from_ITextRange(This->range); 3366 return rng->child.reole; 3367 } 3368 return NULL; 3369 } 3370 3371 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo) 3372 { 3373 ITextParaImpl *This = impl_from_ITextPara(iface); 3374 TRACE("(%p)->(%p)\n", This, pctinfo); 3375 *pctinfo = 1; 3376 return S_OK; 3377 } 3378 3379 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid, 3380 ITypeInfo **ppTInfo) 3381 { 3382 ITextParaImpl *This = impl_from_ITextPara(iface); 3383 HRESULT hr; 3384 3385 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 3386 3387 hr = get_typeinfo(ITextPara_tid, ppTInfo); 3388 if (SUCCEEDED(hr)) 3389 ITypeInfo_AddRef(*ppTInfo); 3390 return hr; 3391 } 3392 3393 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid, 3394 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 3395 { 3396 ITextParaImpl *This = impl_from_ITextPara(iface); 3397 ITypeInfo *ti; 3398 HRESULT hr; 3399 3400 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, 3401 cNames, lcid, rgDispId); 3402 3403 hr = get_typeinfo(ITextPara_tid, &ti); 3404 if (SUCCEEDED(hr)) 3405 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 3406 return hr; 3407 } 3408 3409 static HRESULT WINAPI TextPara_Invoke( 3410 ITextPara *iface, 3411 DISPID dispIdMember, 3412 REFIID riid, 3413 LCID lcid, 3414 WORD wFlags, 3415 DISPPARAMS *pDispParams, 3416 VARIANT *pVarResult, 3417 EXCEPINFO *pExcepInfo, 3418 UINT *puArgErr) 3419 { 3420 ITextParaImpl *This = impl_from_ITextPara(iface); 3421 ITypeInfo *ti; 3422 HRESULT hr; 3423 3424 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, 3425 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, 3426 pExcepInfo, puArgErr); 3427 3428 hr = get_typeinfo(ITextPara_tid, &ti); 3429 if (SUCCEEDED(hr)) 3430 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 3431 return hr; 3432 } 3433 3434 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret) 3435 { 3436 ITextParaImpl *This = impl_from_ITextPara(iface); 3437 FIXME("(%p)->(%p)\n", This, ret); 3438 3439 if (!para_get_reole(This)) 3440 return CO_E_RELEASED; 3441 3442 return E_NOTIMPL; 3443 } 3444 3445 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para) 3446 { 3447 ITextParaImpl *This = impl_from_ITextPara(iface); 3448 FIXME("(%p)->(%p)\n", This, para); 3449 3450 if (!para_get_reole(This)) 3451 return CO_E_RELEASED; 3452 3453 return E_NOTIMPL; 3454 } 3455 3456 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret) 3457 { 3458 ITextParaImpl *This = impl_from_ITextPara(iface); 3459 FIXME("(%p)->(%p)\n", This, ret); 3460 3461 if (!para_get_reole(This)) 3462 return CO_E_RELEASED; 3463 3464 return E_NOTIMPL; 3465 } 3466 3467 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret) 3468 { 3469 ITextParaImpl *This = impl_from_ITextPara(iface); 3470 FIXME("(%p)->(%p %p)\n", This, para, ret); 3471 3472 if (!para_get_reole(This)) 3473 return CO_E_RELEASED; 3474 3475 return E_NOTIMPL; 3476 } 3477 3478 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value) 3479 { 3480 ITextParaImpl *This = impl_from_ITextPara(iface); 3481 FIXME("(%p)->(%d)\n", This, value); 3482 3483 if (!para_get_reole(This)) 3484 return CO_E_RELEASED; 3485 3486 return E_NOTIMPL; 3487 } 3488 3489 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value) 3490 { 3491 ITextParaImpl *This = impl_from_ITextPara(iface); 3492 FIXME("(%p)->(%p)\n", This, value); 3493 3494 if (!para_get_reole(This)) 3495 return CO_E_RELEASED; 3496 3497 return E_NOTIMPL; 3498 } 3499 3500 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value) 3501 { 3502 ITextParaImpl *This = impl_from_ITextPara(iface); 3503 FIXME("(%p)->(%d)\n", This, value); 3504 3505 if (!para_get_reole(This)) 3506 return CO_E_RELEASED; 3507 3508 return E_NOTIMPL; 3509 } 3510 3511 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value) 3512 { 3513 ITextParaImpl *This = impl_from_ITextPara(iface); 3514 static int once; 3515 3516 if (!once++) FIXME("(%p)->(%p)\n", This, value); 3517 3518 if (!para_get_reole(This)) 3519 return CO_E_RELEASED; 3520 3521 return E_NOTIMPL; 3522 } 3523 3524 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value) 3525 { 3526 ITextParaImpl *This = impl_from_ITextPara(iface); 3527 FIXME("(%p)->(%d)\n", This, value); 3528 3529 if (!para_get_reole(This)) 3530 return CO_E_RELEASED; 3531 3532 return E_NOTIMPL; 3533 } 3534 3535 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value) 3536 { 3537 ITextParaImpl *This = impl_from_ITextPara(iface); 3538 FIXME("(%p)->(%p)\n", This, value); 3539 3540 if (!para_get_reole(This)) 3541 return CO_E_RELEASED; 3542 3543 return E_NOTIMPL; 3544 } 3545 3546 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value) 3547 { 3548 ITextParaImpl *This = impl_from_ITextPara(iface); 3549 FIXME("(%p)->(%d)\n", This, value); 3550 3551 if (!para_get_reole(This)) 3552 return CO_E_RELEASED; 3553 3554 return E_NOTIMPL; 3555 } 3556 3557 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value) 3558 { 3559 ITextParaImpl *This = impl_from_ITextPara(iface); 3560 FIXME("(%p)->(%p)\n", This, value); 3561 3562 if (!para_get_reole(This)) 3563 return CO_E_RELEASED; 3564 3565 return E_NOTIMPL; 3566 } 3567 3568 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value) 3569 { 3570 ITextParaImpl *This = impl_from_ITextPara(iface); 3571 FIXME("(%p)->(%p)\n", This, value); 3572 3573 if (!para_get_reole(This)) 3574 return CO_E_RELEASED; 3575 3576 return E_NOTIMPL; 3577 } 3578 3579 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value) 3580 { 3581 ITextParaImpl *This = impl_from_ITextPara(iface); 3582 FIXME("(%p)->(%d)\n", This, value); 3583 3584 if (!para_get_reole(This)) 3585 return CO_E_RELEASED; 3586 3587 return E_NOTIMPL; 3588 } 3589 3590 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value) 3591 { 3592 ITextParaImpl *This = impl_from_ITextPara(iface); 3593 FIXME("(%p)->(%p)\n", This, value); 3594 3595 if (!para_get_reole(This)) 3596 return CO_E_RELEASED; 3597 3598 return E_NOTIMPL; 3599 } 3600 3601 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value) 3602 { 3603 ITextParaImpl *This = impl_from_ITextPara(iface); 3604 FIXME("(%p)->(%d)\n", This, value); 3605 3606 if (!para_get_reole(This)) 3607 return CO_E_RELEASED; 3608 3609 return E_NOTIMPL; 3610 } 3611 3612 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value) 3613 { 3614 ITextParaImpl *This = impl_from_ITextPara(iface); 3615 FIXME("(%p)->(%p)\n", This, value); 3616 3617 if (!para_get_reole(This)) 3618 return CO_E_RELEASED; 3619 3620 return E_NOTIMPL; 3621 } 3622 3623 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value) 3624 { 3625 ITextParaImpl *This = impl_from_ITextPara(iface); 3626 FIXME("(%p)->(%p)\n", This, value); 3627 3628 if (!para_get_reole(This)) 3629 return CO_E_RELEASED; 3630 3631 return E_NOTIMPL; 3632 } 3633 3634 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value) 3635 { 3636 ITextParaImpl *This = impl_from_ITextPara(iface); 3637 FIXME("(%p)->(%p)\n", This, value); 3638 3639 if (!para_get_reole(This)) 3640 return CO_E_RELEASED; 3641 3642 return E_NOTIMPL; 3643 } 3644 3645 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value) 3646 { 3647 ITextParaImpl *This = impl_from_ITextPara(iface); 3648 FIXME("(%p)->(%p)\n", This, value); 3649 3650 if (!para_get_reole(This)) 3651 return CO_E_RELEASED; 3652 3653 return E_NOTIMPL; 3654 } 3655 3656 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value) 3657 { 3658 ITextParaImpl *This = impl_from_ITextPara(iface); 3659 FIXME("(%p)->(%d)\n", This, value); 3660 3661 if (!para_get_reole(This)) 3662 return CO_E_RELEASED; 3663 3664 return E_NOTIMPL; 3665 } 3666 3667 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value) 3668 { 3669 ITextParaImpl *This = impl_from_ITextPara(iface); 3670 FIXME("(%p)->(%p)\n", This, value); 3671 3672 if (!para_get_reole(This)) 3673 return CO_E_RELEASED; 3674 3675 return E_NOTIMPL; 3676 } 3677 3678 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value) 3679 { 3680 ITextParaImpl *This = impl_from_ITextPara(iface); 3681 FIXME("(%p)->(%d)\n", This, value); 3682 3683 if (!para_get_reole(This)) 3684 return CO_E_RELEASED; 3685 3686 return E_NOTIMPL; 3687 } 3688 3689 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value) 3690 { 3691 ITextParaImpl *This = impl_from_ITextPara(iface); 3692 FIXME("(%p)->(%p)\n", This, value); 3693 3694 if (!para_get_reole(This)) 3695 return CO_E_RELEASED; 3696 3697 return E_NOTIMPL; 3698 } 3699 3700 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value) 3701 { 3702 ITextParaImpl *This = impl_from_ITextPara(iface); 3703 FIXME("(%p)->(%d)\n", This, value); 3704 3705 if (!para_get_reole(This)) 3706 return CO_E_RELEASED; 3707 3708 return E_NOTIMPL; 3709 } 3710 3711 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value) 3712 { 3713 ITextParaImpl *This = impl_from_ITextPara(iface); 3714 FIXME("(%p)->(%p)\n", This, value); 3715 3716 if (!para_get_reole(This)) 3717 return CO_E_RELEASED; 3718 3719 return E_NOTIMPL; 3720 } 3721 3722 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value) 3723 { 3724 ITextParaImpl *This = impl_from_ITextPara(iface); 3725 FIXME("(%p)->(%.2f)\n", This, value); 3726 3727 if (!para_get_reole(This)) 3728 return CO_E_RELEASED; 3729 3730 return E_NOTIMPL; 3731 } 3732 3733 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value) 3734 { 3735 ITextParaImpl *This = impl_from_ITextPara(iface); 3736 FIXME("(%p)->(%p)\n", This, value); 3737 3738 if (!para_get_reole(This)) 3739 return CO_E_RELEASED; 3740 3741 return E_NOTIMPL; 3742 } 3743 3744 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value) 3745 { 3746 ITextParaImpl *This = impl_from_ITextPara(iface); 3747 FIXME("(%p)->(%d)\n", This, value); 3748 3749 if (!para_get_reole(This)) 3750 return CO_E_RELEASED; 3751 3752 return E_NOTIMPL; 3753 } 3754 3755 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value) 3756 { 3757 ITextParaImpl *This = impl_from_ITextPara(iface); 3758 FIXME("(%p)->(%p)\n", This, value); 3759 3760 if (!para_get_reole(This)) 3761 return CO_E_RELEASED; 3762 3763 return E_NOTIMPL; 3764 } 3765 3766 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value) 3767 { 3768 ITextParaImpl *This = impl_from_ITextPara(iface); 3769 FIXME("(%p)->(%d)\n", This, value); 3770 3771 if (!para_get_reole(This)) 3772 return CO_E_RELEASED; 3773 3774 return E_NOTIMPL; 3775 } 3776 3777 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value) 3778 { 3779 ITextParaImpl *This = impl_from_ITextPara(iface); 3780 FIXME("(%p)->(%p)\n", This, value); 3781 3782 if (!para_get_reole(This)) 3783 return CO_E_RELEASED; 3784 3785 return E_NOTIMPL; 3786 } 3787 3788 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value) 3789 { 3790 ITextParaImpl *This = impl_from_ITextPara(iface); 3791 FIXME("(%p)->(%d)\n", This, value); 3792 3793 if (!para_get_reole(This)) 3794 return CO_E_RELEASED; 3795 3796 return E_NOTIMPL; 3797 } 3798 3799 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value) 3800 { 3801 ITextParaImpl *This = impl_from_ITextPara(iface); 3802 FIXME("(%p)->(%p)\n", This, value); 3803 3804 if (!para_get_reole(This)) 3805 return CO_E_RELEASED; 3806 3807 return E_NOTIMPL; 3808 } 3809 3810 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value) 3811 { 3812 ITextParaImpl *This = impl_from_ITextPara(iface); 3813 FIXME("(%p)->(%.2f)\n", This, value); 3814 3815 if (!para_get_reole(This)) 3816 return CO_E_RELEASED; 3817 3818 return E_NOTIMPL; 3819 } 3820 3821 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent) 3822 { 3823 ITextParaImpl *This = impl_from_ITextPara(iface); 3824 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent); 3825 3826 if (!para_get_reole(This)) 3827 return CO_E_RELEASED; 3828 3829 return E_NOTIMPL; 3830 } 3831 3832 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing) 3833 { 3834 ITextParaImpl *This = impl_from_ITextPara(iface); 3835 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing); 3836 3837 if (!para_get_reole(This)) 3838 return CO_E_RELEASED; 3839 3840 return E_NOTIMPL; 3841 } 3842 3843 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value) 3844 { 3845 ITextParaImpl *This = impl_from_ITextPara(iface); 3846 FIXME("(%p)->(%p)\n", This, value); 3847 3848 if (!para_get_reole(This)) 3849 return CO_E_RELEASED; 3850 3851 return E_NOTIMPL; 3852 } 3853 3854 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value) 3855 { 3856 ITextParaImpl *This = impl_from_ITextPara(iface); 3857 FIXME("(%p)->(%.2f)\n", This, value); 3858 3859 if (!para_get_reole(This)) 3860 return CO_E_RELEASED; 3861 3862 return E_NOTIMPL; 3863 } 3864 3865 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value) 3866 { 3867 ITextParaImpl *This = impl_from_ITextPara(iface); 3868 FIXME("(%p)->(%p)\n", This, value); 3869 3870 if (!para_get_reole(This)) 3871 return CO_E_RELEASED; 3872 3873 return E_NOTIMPL; 3874 } 3875 3876 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value) 3877 { 3878 ITextParaImpl *This = impl_from_ITextPara(iface); 3879 FIXME("(%p)->(%.2f)\n", This, value); 3880 3881 if (!para_get_reole(This)) 3882 return CO_E_RELEASED; 3883 3884 return E_NOTIMPL; 3885 } 3886 3887 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value) 3888 { 3889 ITextParaImpl *This = impl_from_ITextPara(iface); 3890 FIXME("(%p)->(%p)\n", This, value); 3891 3892 if (!para_get_reole(This)) 3893 return CO_E_RELEASED; 3894 3895 return E_NOTIMPL; 3896 } 3897 3898 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value) 3899 { 3900 ITextParaImpl *This = impl_from_ITextPara(iface); 3901 FIXME("(%p)->(%d)\n", This, value); 3902 3903 if (!para_get_reole(This)) 3904 return CO_E_RELEASED; 3905 3906 return E_NOTIMPL; 3907 } 3908 3909 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value) 3910 { 3911 ITextParaImpl *This = impl_from_ITextPara(iface); 3912 FIXME("(%p)->(%p)\n", This, value); 3913 3914 if (!para_get_reole(This)) 3915 return CO_E_RELEASED; 3916 3917 return E_NOTIMPL; 3918 } 3919 3920 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader) 3921 { 3922 ITextParaImpl *This = impl_from_ITextPara(iface); 3923 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader); 3924 3925 if (!para_get_reole(This)) 3926 return CO_E_RELEASED; 3927 3928 return E_NOTIMPL; 3929 } 3930 3931 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface) 3932 { 3933 ITextParaImpl *This = impl_from_ITextPara(iface); 3934 FIXME("(%p)\n", This); 3935 3936 if (!para_get_reole(This)) 3937 return CO_E_RELEASED; 3938 3939 return E_NOTIMPL; 3940 } 3941 3942 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos) 3943 { 3944 ITextParaImpl *This = impl_from_ITextPara(iface); 3945 FIXME("(%p)->(%.2f)\n", This, pos); 3946 3947 if (!para_get_reole(This)) 3948 return CO_E_RELEASED; 3949 3950 return E_NOTIMPL; 3951 } 3952 3953 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader) 3954 { 3955 ITextParaImpl *This = impl_from_ITextPara(iface); 3956 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader); 3957 3958 if (!para_get_reole(This)) 3959 return CO_E_RELEASED; 3960 3961 return E_NOTIMPL; 3962 } 3963 3964 static ITextParaVtbl textparavtbl = { 3965 TextPara_QueryInterface, 3966 TextPara_AddRef, 3967 TextPara_Release, 3968 TextPara_GetTypeInfoCount, 3969 TextPara_GetTypeInfo, 3970 TextPara_GetIDsOfNames, 3971 TextPara_Invoke, 3972 TextPara_GetDuplicate, 3973 TextPara_SetDuplicate, 3974 TextPara_CanChange, 3975 TextPara_IsEqual, 3976 TextPara_Reset, 3977 TextPara_GetStyle, 3978 TextPara_SetStyle, 3979 TextPara_GetAlignment, 3980 TextPara_SetAlignment, 3981 TextPara_GetHyphenation, 3982 TextPara_SetHyphenation, 3983 TextPara_GetFirstLineIndent, 3984 TextPara_GetKeepTogether, 3985 TextPara_SetKeepTogether, 3986 TextPara_GetKeepWithNext, 3987 TextPara_SetKeepWithNext, 3988 TextPara_GetLeftIndent, 3989 TextPara_GetLineSpacing, 3990 TextPara_GetLineSpacingRule, 3991 TextPara_GetListAlignment, 3992 TextPara_SetListAlignment, 3993 TextPara_GetListLevelIndex, 3994 TextPara_SetListLevelIndex, 3995 TextPara_GetListStart, 3996 TextPara_SetListStart, 3997 TextPara_GetListTab, 3998 TextPara_SetListTab, 3999 TextPara_GetListType, 4000 TextPara_SetListType, 4001 TextPara_GetNoLineNumber, 4002 TextPara_SetNoLineNumber, 4003 TextPara_GetPageBreakBefore, 4004 TextPara_SetPageBreakBefore, 4005 TextPara_GetRightIndent, 4006 TextPara_SetRightIndent, 4007 TextPara_SetIndents, 4008 TextPara_SetLineSpacing, 4009 TextPara_GetSpaceAfter, 4010 TextPara_SetSpaceAfter, 4011 TextPara_GetSpaceBefore, 4012 TextPara_SetSpaceBefore, 4013 TextPara_GetWidowControl, 4014 TextPara_SetWidowControl, 4015 TextPara_GetTabCount, 4016 TextPara_AddTab, 4017 TextPara_ClearAllTabs, 4018 TextPara_DeleteTab, 4019 TextPara_GetTab 4020 }; 4021 4022 static HRESULT create_textpara(ITextRange *range, ITextPara **ret) 4023 { 4024 ITextParaImpl *para; 4025 4026 *ret = NULL; 4027 para = heap_alloc(sizeof(*para)); 4028 if (!para) 4029 return E_OUTOFMEMORY; 4030 4031 para->ITextPara_iface.lpVtbl = &textparavtbl; 4032 para->ref = 1; 4033 para->range = range; 4034 ITextRange_AddRef(range); 4035 4036 *ret = ¶->ITextPara_iface; 4037 return S_OK; 4038 } 4039 4040 /* ITextDocument */ 4041 static HRESULT WINAPI 4042 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid, 4043 void** ppvObject) 4044 { 4045 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4046 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject); 4047 } 4048 4049 static ULONG WINAPI 4050 ITextDocument_fnAddRef(ITextDocument* me) 4051 { 4052 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4053 return IRichEditOle_AddRef(&This->IRichEditOle_iface); 4054 } 4055 4056 static ULONG WINAPI 4057 ITextDocument_fnRelease(ITextDocument* me) 4058 { 4059 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4060 return IRichEditOle_Release(&This->IRichEditOle_iface); 4061 } 4062 4063 static HRESULT WINAPI 4064 ITextDocument_fnGetTypeInfoCount(ITextDocument* me, 4065 UINT* pctinfo) 4066 { 4067 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4068 TRACE("(%p)->(%p)\n", This, pctinfo); 4069 *pctinfo = 1; 4070 return S_OK; 4071 } 4072 4073 static HRESULT WINAPI 4074 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid, 4075 ITypeInfo** ppTInfo) 4076 { 4077 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4078 HRESULT hr; 4079 4080 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 4081 4082 hr = get_typeinfo(ITextDocument_tid, ppTInfo); 4083 if (SUCCEEDED(hr)) 4084 ITypeInfo_AddRef(*ppTInfo); 4085 return hr; 4086 } 4087 4088 static HRESULT WINAPI 4089 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid, 4090 LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) 4091 { 4092 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4093 ITypeInfo *ti; 4094 HRESULT hr; 4095 4096 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), 4097 rgszNames, cNames, lcid, rgDispId); 4098 4099 hr = get_typeinfo(ITextDocument_tid, &ti); 4100 if (SUCCEEDED(hr)) 4101 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 4102 return hr; 4103 } 4104 4105 static HRESULT WINAPI 4106 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember, 4107 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, 4108 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) 4109 { 4110 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4111 ITypeInfo *ti; 4112 HRESULT hr; 4113 4114 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, 4115 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, 4116 pExcepInfo, puArgErr); 4117 4118 hr = get_typeinfo(ITextDocument_tid, &ti); 4119 if (SUCCEEDED(hr)) 4120 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 4121 return hr; 4122 } 4123 4124 static HRESULT WINAPI 4125 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName) 4126 { 4127 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4128 FIXME("stub %p\n",This); 4129 return E_NOTIMPL; 4130 } 4131 4132 static HRESULT WINAPI 4133 ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection) 4134 { 4135 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4136 4137 TRACE("(%p)->(%p)\n", me, selection); 4138 4139 if (!selection) 4140 return E_INVALIDARG; 4141 4142 if (!This->txtSel) { 4143 This->txtSel = CreateTextSelection(This); 4144 if (!This->txtSel) { 4145 *selection = NULL; 4146 return E_OUTOFMEMORY; 4147 } 4148 } 4149 4150 *selection = &This->txtSel->ITextSelection_iface; 4151 ITextSelection_AddRef(*selection); 4152 return S_OK; 4153 } 4154 4155 static HRESULT WINAPI 4156 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount) 4157 { 4158 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4159 FIXME("stub %p\n",This); 4160 return E_NOTIMPL; 4161 } 4162 4163 static HRESULT WINAPI 4164 ITextDocument_fnGetStoryRanges(ITextDocument* me, 4165 ITextStoryRanges** ppStories) 4166 { 4167 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4168 FIXME("stub %p\n",This); 4169 return E_NOTIMPL; 4170 } 4171 4172 static HRESULT WINAPI 4173 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue) 4174 { 4175 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4176 FIXME("stub %p\n",This); 4177 return E_NOTIMPL; 4178 } 4179 4180 static HRESULT WINAPI 4181 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value) 4182 { 4183 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4184 FIXME("stub %p\n",This); 4185 return E_NOTIMPL; 4186 } 4187 4188 static HRESULT WINAPI 4189 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue) 4190 { 4191 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4192 FIXME("stub %p\n",This); 4193 return E_NOTIMPL; 4194 } 4195 4196 static HRESULT WINAPI 4197 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value) 4198 { 4199 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4200 FIXME("stub %p\n",This); 4201 return E_NOTIMPL; 4202 } 4203 4204 static HRESULT WINAPI 4205 ITextDocument_fnNew(ITextDocument* me) 4206 { 4207 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4208 FIXME("stub %p\n",This); 4209 return E_NOTIMPL; 4210 } 4211 4212 static HRESULT WINAPI 4213 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags, 4214 LONG CodePage) 4215 { 4216 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4217 FIXME("stub %p\n",This); 4218 return E_NOTIMPL; 4219 } 4220 4221 static HRESULT WINAPI 4222 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags, 4223 LONG CodePage) 4224 { 4225 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4226 FIXME("stub %p\n",This); 4227 return E_NOTIMPL; 4228 } 4229 4230 static HRESULT WINAPI 4231 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount) 4232 { 4233 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4234 FIXME("stub %p\n",This); 4235 return E_NOTIMPL; 4236 } 4237 4238 static HRESULT WINAPI 4239 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount) 4240 { 4241 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4242 FIXME("stub %p\n",This); 4243 return E_NOTIMPL; 4244 } 4245 4246 static HRESULT WINAPI 4247 ITextDocument_fnBeginEditCollection(ITextDocument* me) 4248 { 4249 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4250 FIXME("stub %p\n",This); 4251 return E_NOTIMPL; 4252 } 4253 4254 static HRESULT WINAPI 4255 ITextDocument_fnEndEditCollection(ITextDocument* me) 4256 { 4257 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4258 FIXME("stub %p\n",This); 4259 return E_NOTIMPL; 4260 } 4261 4262 static HRESULT WINAPI 4263 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop) 4264 { 4265 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4266 FIXME("stub %p\n",This); 4267 return E_NOTIMPL; 4268 } 4269 4270 static HRESULT WINAPI 4271 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop) 4272 { 4273 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4274 FIXME("stub %p\n",This); 4275 return E_NOTIMPL; 4276 } 4277 4278 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange) 4279 { 4280 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl)); 4281 4282 if (!txtRge) 4283 return E_OUTOFMEMORY; 4284 txtRge->ITextRange_iface.lpVtbl = &trvt; 4285 txtRge->ref = 1; 4286 txtRge->child.reole = reOle; 4287 txtRge->start = start; 4288 txtRge->end = end; 4289 list_add_head(&reOle->rangelist, &txtRge->child.entry); 4290 *ppRange = &txtRge->ITextRange_iface; 4291 return S_OK; 4292 } 4293 4294 static HRESULT WINAPI 4295 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2, 4296 ITextRange** ppRange) 4297 { 4298 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4299 4300 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2); 4301 if (!ppRange) 4302 return E_INVALIDARG; 4303 4304 cp2range(This->editor, &cp1, &cp2); 4305 return CreateITextRange(This, cp1, cp2, ppRange); 4306 } 4307 4308 static HRESULT WINAPI 4309 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y, 4310 ITextRange** ppRange) 4311 { 4312 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4313 FIXME("stub %p\n",This); 4314 return E_NOTIMPL; 4315 } 4316 4317 static const ITextDocumentVtbl tdvt = { 4318 ITextDocument_fnQueryInterface, 4319 ITextDocument_fnAddRef, 4320 ITextDocument_fnRelease, 4321 ITextDocument_fnGetTypeInfoCount, 4322 ITextDocument_fnGetTypeInfo, 4323 ITextDocument_fnGetIDsOfNames, 4324 ITextDocument_fnInvoke, 4325 ITextDocument_fnGetName, 4326 ITextDocument_fnGetSelection, 4327 ITextDocument_fnGetStoryCount, 4328 ITextDocument_fnGetStoryRanges, 4329 ITextDocument_fnGetSaved, 4330 ITextDocument_fnSetSaved, 4331 ITextDocument_fnGetDefaultTabStop, 4332 ITextDocument_fnSetDefaultTabStop, 4333 ITextDocument_fnNew, 4334 ITextDocument_fnOpen, 4335 ITextDocument_fnSave, 4336 ITextDocument_fnFreeze, 4337 ITextDocument_fnUnfreeze, 4338 ITextDocument_fnBeginEditCollection, 4339 ITextDocument_fnEndEditCollection, 4340 ITextDocument_fnUndo, 4341 ITextDocument_fnRedo, 4342 ITextDocument_fnRange, 4343 ITextDocument_fnRangeFromPoint 4344 }; 4345 4346 /* ITextSelection */ 4347 static HRESULT WINAPI ITextSelection_fnQueryInterface( 4348 ITextSelection *me, 4349 REFIID riid, 4350 void **ppvObj) 4351 { 4352 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4353 4354 *ppvObj = NULL; 4355 if (IsEqualGUID(riid, &IID_IUnknown) 4356 || IsEqualGUID(riid, &IID_IDispatch) 4357 || IsEqualGUID(riid, &IID_ITextRange) 4358 || IsEqualGUID(riid, &IID_ITextSelection)) 4359 { 4360 *ppvObj = me; 4361 ITextSelection_AddRef(me); 4362 return S_OK; 4363 } 4364 else if (IsEqualGUID(riid, &IID_Igetrichole)) 4365 { 4366 *ppvObj = This->reOle; 4367 return S_OK; 4368 } 4369 4370 return E_NOINTERFACE; 4371 } 4372 4373 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me) 4374 { 4375 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4376 return InterlockedIncrement(&This->ref); 4377 } 4378 4379 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me) 4380 { 4381 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4382 ULONG ref = InterlockedDecrement(&This->ref); 4383 if (ref == 0) 4384 heap_free(This); 4385 return ref; 4386 } 4387 4388 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo) 4389 { 4390 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4391 TRACE("(%p)->(%p)\n", This, pctinfo); 4392 *pctinfo = 1; 4393 return S_OK; 4394 } 4395 4396 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid, 4397 ITypeInfo **ppTInfo) 4398 { 4399 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4400 HRESULT hr; 4401 4402 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 4403 4404 hr = get_typeinfo(ITextSelection_tid, ppTInfo); 4405 if (SUCCEEDED(hr)) 4406 ITypeInfo_AddRef(*ppTInfo); 4407 return hr; 4408 } 4409 4410 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid, 4411 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 4412 { 4413 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4414 ITypeInfo *ti; 4415 HRESULT hr; 4416 4417 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, 4418 rgDispId); 4419 4420 hr = get_typeinfo(ITextSelection_tid, &ti); 4421 if (SUCCEEDED(hr)) 4422 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 4423 return hr; 4424 } 4425 4426 static HRESULT WINAPI ITextSelection_fnInvoke( 4427 ITextSelection *me, 4428 DISPID dispIdMember, 4429 REFIID riid, 4430 LCID lcid, 4431 WORD wFlags, 4432 DISPPARAMS *pDispParams, 4433 VARIANT *pVarResult, 4434 EXCEPINFO *pExcepInfo, 4435 UINT *puArgErr) 4436 { 4437 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4438 ITypeInfo *ti; 4439 HRESULT hr; 4440 4441 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, 4442 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 4443 4444 hr = get_typeinfo(ITextSelection_tid, &ti); 4445 if (SUCCEEDED(hr)) 4446 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 4447 return hr; 4448 } 4449 4450 /*** ITextRange methods ***/ 4451 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) 4452 { 4453 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4454 ME_Cursor *start = NULL, *end = NULL; 4455 int nChars, endOfs; 4456 BOOL bEOP; 4457 4458 TRACE("(%p)->(%p)\n", This, pbstr); 4459 4460 if (!This->reOle) 4461 return CO_E_RELEASED; 4462 4463 if (!pbstr) 4464 return E_INVALIDARG; 4465 4466 ME_GetSelection(This->reOle->editor, &start, &end); 4467 endOfs = ME_GetCursorOfs(end); 4468 nChars = endOfs - ME_GetCursorOfs(start); 4469 if (!nChars) 4470 { 4471 *pbstr = NULL; 4472 return S_OK; 4473 } 4474 4475 *pbstr = SysAllocStringLen(NULL, nChars); 4476 if (!*pbstr) 4477 return E_OUTOFMEMORY; 4478 4479 bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor)); 4480 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP); 4481 TRACE("%s\n", wine_dbgstr_w(*pbstr)); 4482 4483 return S_OK; 4484 } 4485 4486 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str) 4487 { 4488 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4489 ME_TextEditor *editor; 4490 int len, to, from; 4491 4492 TRACE("(%p)->(%s)\n", This, debugstr_w(str)); 4493 4494 if (!This->reOle) 4495 return CO_E_RELEASED; 4496 4497 editor = This->reOle->editor; 4498 len = strlenW(str); 4499 ME_GetSelectionOfs(editor, &from, &to); 4500 ME_ReplaceSel(editor, FALSE, str, len); 4501 4502 if (len < to - from) 4503 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE); 4504 4505 return S_OK; 4506 } 4507 4508 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch) 4509 { 4510 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4511 ME_Cursor *start = NULL, *end = NULL; 4512 4513 TRACE("(%p)->(%p)\n", This, pch); 4514 4515 if (!This->reOle) 4516 return CO_E_RELEASED; 4517 4518 if (!pch) 4519 return E_INVALIDARG; 4520 4521 ME_GetSelection(This->reOle->editor, &start, &end); 4522 return range_GetChar(This->reOle->editor, start, pch); 4523 } 4524 4525 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch) 4526 { 4527 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4528 4529 FIXME("(%p)->(%x): stub\n", This, ch); 4530 4531 if (!This->reOle) 4532 return CO_E_RELEASED; 4533 4534 return E_NOTIMPL; 4535 } 4536 4537 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range) 4538 { 4539 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4540 LONG start, end; 4541 4542 TRACE("(%p)->(%p)\n", This, range); 4543 4544 if (!This->reOle) 4545 return CO_E_RELEASED; 4546 4547 if (!range) 4548 return E_INVALIDARG; 4549 4550 ITextSelection_GetStart(me, &start); 4551 ITextSelection_GetEnd(me, &end); 4552 return CreateITextRange(This->reOle, start, end, range); 4553 } 4554 4555 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range) 4556 { 4557 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4558 4559 FIXME("(%p)->(%p): stub\n", This, range); 4560 4561 if (!This->reOle) 4562 return CO_E_RELEASED; 4563 4564 return E_NOTIMPL; 4565 } 4566 4567 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range) 4568 { 4569 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4570 4571 FIXME("(%p)->(%p): stub\n", This, range); 4572 4573 if (!This->reOle) 4574 return CO_E_RELEASED; 4575 4576 FIXME("not implemented\n"); 4577 return E_NOTIMPL; 4578 } 4579 4580 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst) 4581 { 4582 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4583 LONG lim; 4584 4585 TRACE("(%p)->(%p)\n", This, pcpFirst); 4586 4587 if (!This->reOle) 4588 return CO_E_RELEASED; 4589 4590 if (!pcpFirst) 4591 return E_INVALIDARG; 4592 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim); 4593 return S_OK; 4594 } 4595 4596 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value) 4597 { 4598 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4599 LONG start, end; 4600 HRESULT hr; 4601 4602 TRACE("(%p)->(%d)\n", This, value); 4603 4604 if (!This->reOle) 4605 return CO_E_RELEASED; 4606 4607 ME_GetSelectionOfs(This->reOle->editor, &start, &end); 4608 hr = textrange_setstart(This->reOle, value, &start, &end); 4609 if (hr == S_OK) 4610 ME_SetSelection(This->reOle->editor, start, end); 4611 4612 return hr; 4613 } 4614 4615 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim) 4616 { 4617 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4618 LONG first; 4619 4620 TRACE("(%p)->(%p)\n", This, pcpLim); 4621 4622 if (!This->reOle) 4623 return CO_E_RELEASED; 4624 4625 if (!pcpLim) 4626 return E_INVALIDARG; 4627 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim); 4628 return S_OK; 4629 } 4630 4631 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value) 4632 { 4633 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4634 LONG start, end; 4635 HRESULT hr; 4636 4637 TRACE("(%p)->(%d)\n", This, value); 4638 4639 if (!This->reOle) 4640 return CO_E_RELEASED; 4641 4642 ME_GetSelectionOfs(This->reOle->editor, &start, &end); 4643 hr = textrange_setend(This->reOle, value, &start, &end); 4644 if (hr == S_OK) 4645 ME_SetSelection(This->reOle->editor, start, end); 4646 4647 return hr; 4648 } 4649 4650 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font) 4651 { 4652 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4653 4654 TRACE("(%p)->(%p)\n", This, font); 4655 4656 if (!This->reOle) 4657 return CO_E_RELEASED; 4658 4659 if (!font) 4660 return E_INVALIDARG; 4661 4662 return create_textfont((ITextRange*)me, NULL, font); 4663 } 4664 4665 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font) 4666 { 4667 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4668 4669 TRACE("(%p)->(%p)\n", This, font); 4670 4671 if (!font) 4672 return E_INVALIDARG; 4673 4674 if (!This->reOle) 4675 return CO_E_RELEASED; 4676 4677 textrange_set_font((ITextRange*)me, font); 4678 return S_OK; 4679 } 4680 4681 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para) 4682 { 4683 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4684 4685 TRACE("(%p)->(%p)\n", This, para); 4686 4687 if (!This->reOle) 4688 return CO_E_RELEASED; 4689 4690 if (!para) 4691 return E_INVALIDARG; 4692 4693 return create_textpara((ITextRange*)me, para); 4694 } 4695 4696 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para) 4697 { 4698 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4699 4700 FIXME("(%p)->(%p): stub\n", This, para); 4701 4702 if (!This->reOle) 4703 return CO_E_RELEASED; 4704 4705 FIXME("not implemented\n"); 4706 return E_NOTIMPL; 4707 } 4708 4709 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length) 4710 { 4711 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4712 4713 TRACE("(%p)->(%p)\n", This, length); 4714 4715 if (!This->reOle) 4716 return CO_E_RELEASED; 4717 4718 return textrange_get_storylength(This->reOle->editor, length); 4719 } 4720 4721 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value) 4722 { 4723 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4724 4725 TRACE("(%p)->(%p)\n", This, value); 4726 4727 if (!This->reOle) 4728 return CO_E_RELEASED; 4729 4730 if (!value) 4731 return E_INVALIDARG; 4732 4733 *value = tomUnknownStory; 4734 return S_OK; 4735 } 4736 4737 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart) 4738 { 4739 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4740 LONG start, end; 4741 HRESULT hres; 4742 4743 TRACE("(%p)->(%d)\n", This, bStart); 4744 4745 if (!This->reOle) 4746 return CO_E_RELEASED; 4747 4748 ME_GetSelectionOfs(This->reOle->editor, &start, &end); 4749 hres = range_Collapse(bStart, &start, &end); 4750 if (SUCCEEDED(hres)) 4751 ME_SetSelection(This->reOle->editor, start, end); 4752 return hres; 4753 } 4754 4755 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta) 4756 { 4757 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4758 4759 TRACE("(%p)->(%d %p)\n", This, unit, delta); 4760 4761 if (!This->reOle) 4762 return CO_E_RELEASED; 4763 4764 return textrange_expand((ITextRange*)me, unit, delta); 4765 } 4766 4767 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index) 4768 { 4769 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4770 4771 FIXME("(%p)->(%d %p): stub\n", This, unit, index); 4772 4773 if (!This->reOle) 4774 return CO_E_RELEASED; 4775 4776 return E_NOTIMPL; 4777 } 4778 4779 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index, 4780 LONG extend) 4781 { 4782 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4783 4784 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend); 4785 4786 if (!This->reOle) 4787 return CO_E_RELEASED; 4788 4789 return E_NOTIMPL; 4790 } 4791 4792 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active) 4793 { 4794 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4795 4796 FIXME("(%p)->(%d %d): stub\n", This, anchor, active); 4797 4798 if (!This->reOle) 4799 return CO_E_RELEASED; 4800 4801 return E_NOTIMPL; 4802 } 4803 4804 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret) 4805 { 4806 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4807 ITextSelection *selection = NULL; 4808 LONG start, end; 4809 4810 TRACE("(%p)->(%p %p)\n", This, range, ret); 4811 4812 if (ret) 4813 *ret = tomFalse; 4814 4815 if (!This->reOle) 4816 return CO_E_RELEASED; 4817 4818 if (!range) 4819 return S_FALSE; 4820 4821 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection); 4822 if (!selection) 4823 return S_FALSE; 4824 ITextSelection_Release(selection); 4825 4826 ITextSelection_GetStart(me, &start); 4827 ITextSelection_GetEnd(me, &end); 4828 return textrange_inrange(start, end, range, ret); 4829 } 4830 4831 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret) 4832 { 4833 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4834 4835 FIXME("(%p)->(%p %p): stub\n", This, range, ret); 4836 4837 if (!This->reOle) 4838 return CO_E_RELEASED; 4839 4840 return E_NOTIMPL; 4841 } 4842 4843 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret) 4844 { 4845 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4846 ITextSelection *selection = NULL; 4847 LONG start, end; 4848 4849 TRACE("(%p)->(%p %p)\n", This, range, ret); 4850 4851 if (ret) 4852 *ret = tomFalse; 4853 4854 if (!This->reOle) 4855 return CO_E_RELEASED; 4856 4857 if (!range) 4858 return S_FALSE; 4859 4860 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection); 4861 if (!selection) 4862 return S_FALSE; 4863 ITextSelection_Release(selection); 4864 4865 ITextSelection_GetStart(me, &start); 4866 ITextSelection_GetEnd(me, &end); 4867 return textrange_isequal(start, end, range, ret); 4868 } 4869 4870 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me) 4871 { 4872 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4873 4874 TRACE("(%p)\n", This); 4875 4876 if (!This->reOle) 4877 return CO_E_RELEASED; 4878 4879 /* nothing to do */ 4880 return S_OK; 4881 } 4882 4883 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend, 4884 LONG *delta) 4885 { 4886 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4887 4888 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 4889 4890 if (!This->reOle) 4891 return CO_E_RELEASED; 4892 4893 return E_NOTIMPL; 4894 } 4895 4896 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend, 4897 LONG *delta) 4898 { 4899 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4900 4901 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 4902 4903 if (!This->reOle) 4904 return CO_E_RELEASED; 4905 4906 return E_NOTIMPL; 4907 } 4908 4909 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta) 4910 { 4911 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4912 4913 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 4914 4915 if (!This->reOle) 4916 return CO_E_RELEASED; 4917 4918 return E_NOTIMPL; 4919 } 4920 4921 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count, 4922 LONG *delta) 4923 { 4924 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4925 4926 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 4927 4928 if (!This->reOle) 4929 return CO_E_RELEASED; 4930 4931 return E_NOTIMPL; 4932 } 4933 4934 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count, 4935 LONG *delta) 4936 { 4937 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4938 4939 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 4940 4941 if (!This->reOle) 4942 return CO_E_RELEASED; 4943 4944 return E_NOTIMPL; 4945 } 4946 4947 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count, 4948 LONG *delta) 4949 { 4950 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4951 4952 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 4953 4954 if (!This->reOle) 4955 return CO_E_RELEASED; 4956 4957 return E_NOTIMPL; 4958 } 4959 4960 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count, 4961 LONG *delta) 4962 { 4963 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4964 4965 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 4966 4967 if (!This->reOle) 4968 return CO_E_RELEASED; 4969 4970 return E_NOTIMPL; 4971 } 4972 4973 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count, 4974 LONG *delta) 4975 { 4976 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4977 4978 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 4979 4980 if (!This->reOle) 4981 return CO_E_RELEASED; 4982 4983 return E_NOTIMPL; 4984 } 4985 4986 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count, 4987 LONG *delta) 4988 { 4989 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4990 4991 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 4992 4993 if (!This->reOle) 4994 return CO_E_RELEASED; 4995 4996 return E_NOTIMPL; 4997 } 4998 4999 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count, 5000 LONG *delta) 5001 { 5002 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5003 5004 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5005 5006 if (!This->reOle) 5007 return CO_E_RELEASED; 5008 5009 return E_NOTIMPL; 5010 } 5011 5012 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count, 5013 LONG *delta) 5014 { 5015 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5016 5017 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5018 5019 if (!This->reOle) 5020 return CO_E_RELEASED; 5021 5022 return E_NOTIMPL; 5023 } 5024 5025 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags, 5026 LONG *length) 5027 { 5028 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5029 5030 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 5031 5032 if (!This->reOle) 5033 return CO_E_RELEASED; 5034 5035 FIXME("not implemented\n"); 5036 return E_NOTIMPL; 5037 } 5038 5039 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count, 5040 LONG flags, LONG *length) 5041 { 5042 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5043 5044 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 5045 5046 if (!This->reOle) 5047 return CO_E_RELEASED; 5048 5049 return E_NOTIMPL; 5050 } 5051 5052 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count, 5053 LONG flags, LONG *length) 5054 { 5055 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5056 5057 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 5058 5059 if (!This->reOle) 5060 return CO_E_RELEASED; 5061 5062 return E_NOTIMPL; 5063 } 5064 5065 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count, 5066 LONG *delta) 5067 { 5068 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5069 5070 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 5071 5072 if (!This->reOle) 5073 return CO_E_RELEASED; 5074 5075 return E_NOTIMPL; 5076 } 5077 5078 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v) 5079 { 5080 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5081 5082 FIXME("(%p)->(%p): stub\n", This, v); 5083 5084 if (!This->reOle) 5085 return CO_E_RELEASED; 5086 5087 return E_NOTIMPL; 5088 } 5089 5090 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v) 5091 { 5092 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5093 5094 FIXME("(%p)->(%p): stub\n", This, v); 5095 5096 if (!This->reOle) 5097 return CO_E_RELEASED; 5098 5099 return E_NOTIMPL; 5100 } 5101 5102 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format) 5103 { 5104 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5105 5106 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format); 5107 5108 if (!This->reOle) 5109 return CO_E_RELEASED; 5110 5111 return E_NOTIMPL; 5112 } 5113 5114 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format, 5115 LONG *ret) 5116 { 5117 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5118 5119 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret); 5120 5121 if (!This->reOle) 5122 return CO_E_RELEASED; 5123 5124 return E_NOTIMPL; 5125 } 5126 5127 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret) 5128 { 5129 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5130 5131 FIXME("(%p)->(%p): stub\n", This, ret); 5132 5133 if (!This->reOle) 5134 return CO_E_RELEASED; 5135 5136 return E_NOTIMPL; 5137 } 5138 5139 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type) 5140 { 5141 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5142 5143 FIXME("(%p)->(%d): stub\n", This, type); 5144 5145 if (!This->reOle) 5146 return CO_E_RELEASED; 5147 5148 return E_NOTIMPL; 5149 } 5150 5151 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy) 5152 { 5153 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5154 5155 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy); 5156 5157 if (!This->reOle) 5158 return CO_E_RELEASED; 5159 5160 return E_NOTIMPL; 5161 } 5162 5163 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type, 5164 LONG extend) 5165 { 5166 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5167 5168 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend); 5169 5170 if (!This->reOle) 5171 return CO_E_RELEASED; 5172 5173 return E_NOTIMPL; 5174 } 5175 5176 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value) 5177 { 5178 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5179 5180 FIXME("(%p)->(%d): stub\n", This, value); 5181 5182 if (!This->reOle) 5183 return CO_E_RELEASED; 5184 5185 return E_NOTIMPL; 5186 } 5187 5188 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv) 5189 { 5190 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5191 5192 FIXME("(%p)->(%p): stub\n", This, ppv); 5193 5194 if (!This->reOle) 5195 return CO_E_RELEASED; 5196 5197 return E_NOTIMPL; 5198 } 5199 5200 /*** ITextSelection methods ***/ 5201 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags) 5202 { 5203 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5204 5205 FIXME("(%p)->(%p): stub\n", This, flags); 5206 5207 if (!This->reOle) 5208 return CO_E_RELEASED; 5209 5210 return E_NOTIMPL; 5211 } 5212 5213 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags) 5214 { 5215 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5216 5217 FIXME("(%p)->(%x): stub\n", This, flags); 5218 5219 if (!This->reOle) 5220 return CO_E_RELEASED; 5221 5222 return E_NOTIMPL; 5223 } 5224 5225 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type) 5226 { 5227 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5228 5229 FIXME("(%p)->(%p): stub\n", This, type); 5230 5231 if (!This->reOle) 5232 return CO_E_RELEASED; 5233 5234 return E_NOTIMPL; 5235 } 5236 5237 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count, 5238 LONG extend, LONG *delta) 5239 { 5240 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5241 5242 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5243 5244 if (!This->reOle) 5245 return CO_E_RELEASED; 5246 5247 return E_NOTIMPL; 5248 } 5249 5250 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count, 5251 LONG extend, LONG *delta) 5252 { 5253 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5254 5255 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5256 5257 if (!This->reOle) 5258 return CO_E_RELEASED; 5259 5260 return E_NOTIMPL; 5261 } 5262 5263 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count, 5264 LONG extend, LONG *delta) 5265 { 5266 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5267 5268 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5269 5270 if (!This->reOle) 5271 return CO_E_RELEASED; 5272 5273 return E_NOTIMPL; 5274 } 5275 5276 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count, 5277 LONG extend, LONG *delta) 5278 { 5279 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5280 5281 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5282 5283 if (!This->reOle) 5284 return CO_E_RELEASED; 5285 5286 return E_NOTIMPL; 5287 } 5288 5289 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend, 5290 LONG *delta) 5291 { 5292 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5293 5294 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 5295 5296 if (!This->reOle) 5297 return CO_E_RELEASED; 5298 5299 return E_NOTIMPL; 5300 } 5301 5302 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend, 5303 LONG *delta) 5304 { 5305 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5306 5307 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 5308 5309 if (!This->reOle) 5310 return CO_E_RELEASED; 5311 5312 return E_NOTIMPL; 5313 } 5314 5315 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text) 5316 { 5317 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5318 5319 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text)); 5320 5321 if (!This->reOle) 5322 return CO_E_RELEASED; 5323 5324 return E_NOTIMPL; 5325 } 5326 5327 static const ITextSelectionVtbl tsvt = { 5328 ITextSelection_fnQueryInterface, 5329 ITextSelection_fnAddRef, 5330 ITextSelection_fnRelease, 5331 ITextSelection_fnGetTypeInfoCount, 5332 ITextSelection_fnGetTypeInfo, 5333 ITextSelection_fnGetIDsOfNames, 5334 ITextSelection_fnInvoke, 5335 ITextSelection_fnGetText, 5336 ITextSelection_fnSetText, 5337 ITextSelection_fnGetChar, 5338 ITextSelection_fnSetChar, 5339 ITextSelection_fnGetDuplicate, 5340 ITextSelection_fnGetFormattedText, 5341 ITextSelection_fnSetFormattedText, 5342 ITextSelection_fnGetStart, 5343 ITextSelection_fnSetStart, 5344 ITextSelection_fnGetEnd, 5345 ITextSelection_fnSetEnd, 5346 ITextSelection_fnGetFont, 5347 ITextSelection_fnSetFont, 5348 ITextSelection_fnGetPara, 5349 ITextSelection_fnSetPara, 5350 ITextSelection_fnGetStoryLength, 5351 ITextSelection_fnGetStoryType, 5352 ITextSelection_fnCollapse, 5353 ITextSelection_fnExpand, 5354 ITextSelection_fnGetIndex, 5355 ITextSelection_fnSetIndex, 5356 ITextSelection_fnSetRange, 5357 ITextSelection_fnInRange, 5358 ITextSelection_fnInStory, 5359 ITextSelection_fnIsEqual, 5360 ITextSelection_fnSelect, 5361 ITextSelection_fnStartOf, 5362 ITextSelection_fnEndOf, 5363 ITextSelection_fnMove, 5364 ITextSelection_fnMoveStart, 5365 ITextSelection_fnMoveEnd, 5366 ITextSelection_fnMoveWhile, 5367 ITextSelection_fnMoveStartWhile, 5368 ITextSelection_fnMoveEndWhile, 5369 ITextSelection_fnMoveUntil, 5370 ITextSelection_fnMoveStartUntil, 5371 ITextSelection_fnMoveEndUntil, 5372 ITextSelection_fnFindText, 5373 ITextSelection_fnFindTextStart, 5374 ITextSelection_fnFindTextEnd, 5375 ITextSelection_fnDelete, 5376 ITextSelection_fnCut, 5377 ITextSelection_fnCopy, 5378 ITextSelection_fnPaste, 5379 ITextSelection_fnCanPaste, 5380 ITextSelection_fnCanEdit, 5381 ITextSelection_fnChangeCase, 5382 ITextSelection_fnGetPoint, 5383 ITextSelection_fnSetPoint, 5384 ITextSelection_fnScrollIntoView, 5385 ITextSelection_fnGetEmbeddedObject, 5386 ITextSelection_fnGetFlags, 5387 ITextSelection_fnSetFlags, 5388 ITextSelection_fnGetType, 5389 ITextSelection_fnMoveLeft, 5390 ITextSelection_fnMoveRight, 5391 ITextSelection_fnMoveUp, 5392 ITextSelection_fnMoveDown, 5393 ITextSelection_fnHomeKey, 5394 ITextSelection_fnEndKey, 5395 ITextSelection_fnTypeText 5396 }; 5397 5398 static ITextSelectionImpl * 5399 CreateTextSelection(IRichEditOleImpl *reOle) 5400 { 5401 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel); 5402 if (!txtSel) 5403 return NULL; 5404 5405 txtSel->ITextSelection_iface.lpVtbl = &tsvt; 5406 txtSel->ref = 1; 5407 txtSel->reOle = reOle; 5408 return txtSel; 5409 } 5410 5411 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) 5412 { 5413 IRichEditOleImpl *reo; 5414 5415 reo = heap_alloc(sizeof(IRichEditOleImpl)); 5416 if (!reo) 5417 return 0; 5418 5419 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl; 5420 reo->IRichEditOle_iface.lpVtbl = &revt; 5421 reo->ITextDocument_iface.lpVtbl = &tdvt; 5422 reo->ref = 1; 5423 reo->editor = editor; 5424 reo->txtSel = NULL; 5425 5426 TRACE("Created %p\n",reo); 5427 list_init(&reo->rangelist); 5428 list_init(&reo->clientsites); 5429 if (outer_unk) 5430 reo->outer_unk = outer_unk; 5431 else 5432 reo->outer_unk = &reo->IUnknown_inner; 5433 *ppvObj = &reo->IRichEditOle_iface; 5434 5435 return 1; 5436 } 5437 5438 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz) 5439 { 5440 /* sizel is in .01 millimeters, sz in pixels */ 5441 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540); 5442 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540); 5443 } 5444 5445 /****************************************************************************** 5446 * ME_GetOLEObjectSize 5447 * 5448 * Sets run extent for OLE objects. 5449 */ 5450 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) 5451 { 5452 IDataObject* ido; 5453 FORMATETC fmt; 5454 STGMEDIUM stgm; 5455 DIBSECTION dibsect; 5456 ENHMETAHEADER emh; 5457 5458 assert(run->nFlags & MERF_GRAPHICS); 5459 assert(run->ole_obj); 5460 5461 if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0) 5462 { 5463 convert_sizel(c, &run->ole_obj->sizel, pSize); 5464 if (c->editor->nZoomNumerator != 0) 5465 { 5466 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5467 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5468 } 5469 return; 5470 } 5471 5472 if (!run->ole_obj->poleobj) 5473 { 5474 pSize->cx = pSize->cy = 0; 5475 return; 5476 } 5477 5478 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK) 5479 { 5480 FIXME("Query Interface IID_IDataObject failed!\n"); 5481 pSize->cx = pSize->cy = 0; 5482 return; 5483 } 5484 fmt.cfFormat = CF_BITMAP; 5485 fmt.ptd = NULL; 5486 fmt.dwAspect = DVASPECT_CONTENT; 5487 fmt.lindex = -1; 5488 fmt.tymed = TYMED_GDI; 5489 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5490 { 5491 fmt.cfFormat = CF_ENHMETAFILE; 5492 fmt.tymed = TYMED_ENHMF; 5493 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5494 { 5495 FIXME("unsupported format\n"); 5496 pSize->cx = pSize->cy = 0; 5497 IDataObject_Release(ido); 5498 return; 5499 } 5500 } 5501 IDataObject_Release(ido); 5502 5503 switch (stgm.tymed) 5504 { 5505 case TYMED_GDI: 5506 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); 5507 pSize->cx = dibsect.dsBm.bmWidth; 5508 pSize->cy = dibsect.dsBm.bmHeight; 5509 break; 5510 case TYMED_ENHMF: 5511 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); 5512 pSize->cx = emh.rclBounds.right - emh.rclBounds.left; 5513 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top; 5514 break; 5515 default: 5516 FIXME("Unsupported tymed %d\n", stgm.tymed); 5517 break; 5518 } 5519 ReleaseStgMedium(&stgm); 5520 if (c->editor->nZoomNumerator != 0) 5521 { 5522 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5523 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5524 } 5525 } 5526 5527 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) 5528 { 5529 IDataObject* ido; 5530 FORMATETC fmt; 5531 STGMEDIUM stgm; 5532 DIBSECTION dibsect; 5533 ENHMETAHEADER emh; 5534 HDC hMemDC; 5535 SIZE sz; 5536 BOOL has_size; 5537 HBITMAP old_bm; 5538 RECT rc; 5539 5540 assert(run->nFlags & MERF_GRAPHICS); 5541 assert(run->ole_obj); 5542 if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK) 5543 { 5544 FIXME("Couldn't get interface\n"); 5545 return; 5546 } 5547 has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0; 5548 fmt.cfFormat = CF_BITMAP; 5549 fmt.ptd = NULL; 5550 fmt.dwAspect = DVASPECT_CONTENT; 5551 fmt.lindex = -1; 5552 fmt.tymed = TYMED_GDI; 5553 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5554 { 5555 fmt.cfFormat = CF_ENHMETAFILE; 5556 fmt.tymed = TYMED_ENHMF; 5557 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5558 { 5559 FIXME("Couldn't get storage medium\n"); 5560 IDataObject_Release(ido); 5561 return; 5562 } 5563 } 5564 IDataObject_Release(ido); 5565 5566 switch (stgm.tymed) 5567 { 5568 case TYMED_GDI: 5569 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); 5570 hMemDC = CreateCompatibleDC(c->hDC); 5571 old_bm = SelectObject(hMemDC, stgm.u.hBitmap); 5572 if (has_size) 5573 { 5574 convert_sizel(c, &run->ole_obj->sizel, &sz); 5575 } else { 5576 sz.cx = dibsect.dsBm.bmWidth; 5577 sz.cy = dibsect.dsBm.bmHeight; 5578 } 5579 if (c->editor->nZoomNumerator != 0) 5580 { 5581 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5582 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5583 } 5584 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, 5585 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY); 5586 5587 SelectObject(hMemDC, old_bm); 5588 DeleteDC(hMemDC); 5589 break; 5590 case TYMED_ENHMF: 5591 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); 5592 if (has_size) 5593 { 5594 convert_sizel(c, &run->ole_obj->sizel, &sz); 5595 } else { 5596 sz.cx = emh.rclBounds.right - emh.rclBounds.left; 5597 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top; 5598 } 5599 if (c->editor->nZoomNumerator != 0) 5600 { 5601 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5602 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5603 } 5604 5605 rc.left = x; 5606 rc.top = y - sz.cy; 5607 rc.right = x + sz.cx; 5608 rc.bottom = y; 5609 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc); 5610 break; 5611 default: 5612 FIXME("Unsupported tymed %d\n", stgm.tymed); 5613 selected = FALSE; 5614 break; 5615 } 5616 ReleaseStgMedium(&stgm); 5617 5618 if (selected && !c->editor->bHideSelection) 5619 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT); 5620 } 5621 5622 void ME_DeleteReObject(REOBJECT* reo) 5623 { 5624 if (reo->poleobj) IOleObject_Release(reo->poleobj); 5625 if (reo->pstg) IStorage_Release(reo->pstg); 5626 if (reo->polesite) IOleClientSite_Release(reo->polesite); 5627 heap_free(reo); 5628 } 5629 5630 void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) 5631 { 5632 *dst = *src; 5633 5634 if (dst->poleobj) IOleObject_AddRef(dst->poleobj); 5635 if (dst->pstg) IStorage_AddRef(dst->pstg); 5636 if (dst->polesite) IOleClientSite_AddRef(dst->polesite); 5637 } 5638 5639 void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) 5640 { 5641 IRichEditOleImpl *This = impl_from_IRichEditOle(iface); 5642 *ppvObj = &This->ITextDocument_iface; 5643 } 5644