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 struct re_object *reobj = NULL; 1383 LONG count = 0; 1384 1385 TRACE("(%p)->(%x, %p, %x)\n", This, iob, lpreobject, dwFlags); 1386 1387 if (!lpreobject || !lpreobject->cbStruct) 1388 return E_INVALIDARG; 1389 1390 if (iob == REO_IOB_USE_CP) 1391 { 1392 ME_Cursor cursor; 1393 1394 TRACE("character offset: %d\n", lpreobject->cp); 1395 ME_CursorFromCharOfs(This->editor, lpreobject->cp, &cursor); 1396 if (!cursor.pRun->member.run.reobj) 1397 return E_INVALIDARG; 1398 else 1399 reobj = cursor.pRun->member.run.reobj; 1400 } 1401 else 1402 { 1403 if (iob > IRichEditOle_GetObjectCount(me)) 1404 return E_INVALIDARG; 1405 LIST_FOR_EACH_ENTRY(reobj, &This->editor->reobj_list, struct re_object, entry) 1406 { 1407 if (count == iob) 1408 break; 1409 count++; 1410 } 1411 } 1412 ME_CopyReObject(lpreobject, &reobj->obj, dwFlags); 1413 return S_OK; 1414 } 1415 1416 static LONG WINAPI 1417 IRichEditOle_fnGetObjectCount(IRichEditOle *me) 1418 { 1419 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1420 TRACE("(%p)\n",This); 1421 return list_count(&This->editor->reobj_list); 1422 } 1423 1424 static HRESULT WINAPI 1425 IRichEditOle_fnHandsOffStorage(IRichEditOle *me, LONG iob) 1426 { 1427 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1428 FIXME("stub %p\n",This); 1429 return E_NOTIMPL; 1430 } 1431 1432 static HRESULT WINAPI 1433 IRichEditOle_fnImportDataObject(IRichEditOle *me, LPDATAOBJECT lpdataobj, 1434 CLIPFORMAT cf, HGLOBAL hMetaPict) 1435 { 1436 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1437 FIXME("stub %p\n",This); 1438 return E_NOTIMPL; 1439 } 1440 1441 static HRESULT WINAPI 1442 IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me) 1443 { 1444 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1445 FIXME("stub %p\n",This); 1446 return E_NOTIMPL; 1447 } 1448 1449 static HRESULT WINAPI 1450 IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo) 1451 { 1452 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1453 1454 TRACE("(%p,%p)\n", This, reo); 1455 1456 if (!reo) 1457 return E_INVALIDARG; 1458 1459 if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER; 1460 1461 ME_InsertOLEFromCursor(This->editor, reo, 0); 1462 ME_CommitUndo(This->editor); 1463 ME_UpdateRepaint(This->editor, FALSE); 1464 return S_OK; 1465 } 1466 1467 static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob, 1468 LPSTORAGE lpstg) 1469 { 1470 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1471 FIXME("stub %p\n",This); 1472 return E_NOTIMPL; 1473 } 1474 1475 static HRESULT WINAPI 1476 IRichEditOle_fnSetDvaspect(IRichEditOle *me, LONG iob, DWORD dvaspect) 1477 { 1478 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1479 FIXME("stub %p\n",This); 1480 return E_NOTIMPL; 1481 } 1482 1483 static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me, 1484 LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj) 1485 { 1486 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1487 FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj); 1488 return E_NOTIMPL; 1489 } 1490 1491 static HRESULT WINAPI 1492 IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable) 1493 { 1494 IRichEditOleImpl *This = impl_from_IRichEditOle(me); 1495 FIXME("stub %p\n",This); 1496 return E_NOTIMPL; 1497 } 1498 1499 static const IRichEditOleVtbl revt = { 1500 IRichEditOle_fnQueryInterface, 1501 IRichEditOle_fnAddRef, 1502 IRichEditOle_fnRelease, 1503 IRichEditOle_fnGetClientSite, 1504 IRichEditOle_fnGetObjectCount, 1505 IRichEditOle_fnGetLinkCount, 1506 IRichEditOle_fnGetObject, 1507 IRichEditOle_fnInsertObject, 1508 IRichEditOle_fnConvertObject, 1509 IRichEditOle_fnActivateAs, 1510 IRichEditOle_fnSetHostNames, 1511 IRichEditOle_fnSetLinkAvailable, 1512 IRichEditOle_fnSetDvaspect, 1513 IRichEditOle_fnHandsOffStorage, 1514 IRichEditOle_fnSaveCompleted, 1515 IRichEditOle_fnInPlaceDeactivate, 1516 IRichEditOle_fnContextSensitiveHelp, 1517 IRichEditOle_fnGetClipboardData, 1518 IRichEditOle_fnImportDataObject 1519 }; 1520 1521 /* ITextRange interface */ 1522 static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj) 1523 { 1524 ITextRangeImpl *This = impl_from_ITextRange(me); 1525 1526 *ppvObj = NULL; 1527 if (IsEqualGUID(riid, &IID_IUnknown) 1528 || IsEqualGUID(riid, &IID_IDispatch) 1529 || IsEqualGUID(riid, &IID_ITextRange)) 1530 { 1531 *ppvObj = me; 1532 ITextRange_AddRef(me); 1533 return S_OK; 1534 } 1535 else if (IsEqualGUID(riid, &IID_Igetrichole)) 1536 { 1537 *ppvObj = This->child.reole; 1538 return S_OK; 1539 } 1540 1541 return E_NOINTERFACE; 1542 } 1543 1544 static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me) 1545 { 1546 ITextRangeImpl *This = impl_from_ITextRange(me); 1547 return InterlockedIncrement(&This->ref); 1548 } 1549 1550 static ULONG WINAPI ITextRange_fnRelease(ITextRange *me) 1551 { 1552 ITextRangeImpl *This = impl_from_ITextRange(me); 1553 ULONG ref = InterlockedDecrement(&This->ref); 1554 1555 TRACE ("%p ref=%u\n", This, ref); 1556 if (ref == 0) 1557 { 1558 if (This->child.reole) 1559 { 1560 list_remove(&This->child.entry); 1561 This->child.reole = NULL; 1562 } 1563 heap_free(This); 1564 } 1565 return ref; 1566 } 1567 1568 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo) 1569 { 1570 ITextRangeImpl *This = impl_from_ITextRange(me); 1571 TRACE("(%p)->(%p)\n", This, pctinfo); 1572 *pctinfo = 1; 1573 return S_OK; 1574 } 1575 1576 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid, 1577 ITypeInfo **ppTInfo) 1578 { 1579 ITextRangeImpl *This = impl_from_ITextRange(me); 1580 HRESULT hr; 1581 1582 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 1583 1584 hr = get_typeinfo(ITextRange_tid, ppTInfo); 1585 if (SUCCEEDED(hr)) 1586 ITypeInfo_AddRef(*ppTInfo); 1587 return hr; 1588 } 1589 1590 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames, 1591 UINT cNames, LCID lcid, DISPID *rgDispId) 1592 { 1593 ITextRangeImpl *This = impl_from_ITextRange(me); 1594 ITypeInfo *ti; 1595 HRESULT hr; 1596 1597 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, 1598 rgDispId); 1599 1600 hr = get_typeinfo(ITextRange_tid, &ti); 1601 if (SUCCEEDED(hr)) 1602 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 1603 return hr; 1604 } 1605 1606 static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid, 1607 LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 1608 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, 1609 UINT *puArgErr) 1610 { 1611 ITextRangeImpl *This = impl_from_ITextRange(me); 1612 ITypeInfo *ti; 1613 HRESULT hr; 1614 1615 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), 1616 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 1617 1618 hr = get_typeinfo(ITextRange_tid, &ti); 1619 if (SUCCEEDED(hr)) 1620 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 1621 return hr; 1622 } 1623 1624 static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *str) 1625 { 1626 ITextRangeImpl *This = impl_from_ITextRange(me); 1627 ME_TextEditor *editor; 1628 ME_Cursor start, end; 1629 int length; 1630 BOOL bEOP; 1631 1632 TRACE("(%p)->(%p)\n", This, str); 1633 1634 if (!This->child.reole) 1635 return CO_E_RELEASED; 1636 1637 if (!str) 1638 return E_INVALIDARG; 1639 1640 /* return early for degenerate range */ 1641 if (This->start == This->end) { 1642 *str = NULL; 1643 return S_OK; 1644 } 1645 1646 editor = This->child.reole->editor; 1647 ME_CursorFromCharOfs(editor, This->start, &start); 1648 ME_CursorFromCharOfs(editor, This->end, &end); 1649 1650 length = This->end - This->start; 1651 *str = SysAllocStringLen(NULL, length); 1652 if (!*str) 1653 return E_OUTOFMEMORY; 1654 1655 bEOP = (end.pRun->next->type == diTextEnd && This->end > ME_GetTextLength(editor)); 1656 ME_GetTextW(editor, *str, length, &start, length, FALSE, bEOP); 1657 return S_OK; 1658 } 1659 1660 static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR str) 1661 { 1662 ITextRangeImpl *This = impl_from_ITextRange(me); 1663 ME_TextEditor *editor; 1664 ME_Cursor cursor; 1665 ME_Style *style; 1666 int len; 1667 1668 TRACE("(%p)->(%s)\n", This, debugstr_w(str)); 1669 1670 if (!This->child.reole) 1671 return CO_E_RELEASED; 1672 1673 editor = This->child.reole->editor; 1674 1675 /* delete only where's something to delete */ 1676 if (This->start != This->end) { 1677 ME_CursorFromCharOfs(editor, This->start, &cursor); 1678 ME_InternalDeleteText(editor, &cursor, This->end - This->start, FALSE); 1679 } 1680 1681 if (!str || !*str) { 1682 /* will update this range as well */ 1683 textranges_update_ranges(This->child.reole, This->start, This->end, RANGE_UPDATE_DELETE); 1684 return S_OK; 1685 } 1686 1687 /* it's safer not to rely on stored BSTR length */ 1688 len = strlenW(str); 1689 cursor = editor->pCursors[0]; 1690 ME_CursorFromCharOfs(editor, This->start, &editor->pCursors[0]); 1691 style = ME_GetInsertStyle(editor, 0); 1692 ME_InsertTextFromCursor(editor, 0, str, len, style); 1693 ME_ReleaseStyle(style); 1694 editor->pCursors[0] = cursor; 1695 1696 if (len < This->end - This->start) 1697 textranges_update_ranges(This->child.reole, This->start + len, This->end, RANGE_UPDATE_DELETE); 1698 else 1699 This->end = len - This->start; 1700 1701 return S_OK; 1702 } 1703 1704 static HRESULT range_GetChar(ME_TextEditor *editor, ME_Cursor *cursor, LONG *pch) 1705 { 1706 WCHAR wch[2]; 1707 1708 ME_GetTextW(editor, wch, 1, cursor, 1, FALSE, cursor->pRun->next->type == diTextEnd); 1709 *pch = wch[0]; 1710 1711 return S_OK; 1712 } 1713 1714 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch) 1715 { 1716 ITextRangeImpl *This = impl_from_ITextRange(me); 1717 ME_TextEditor *editor; 1718 ME_Cursor cursor; 1719 1720 TRACE("(%p)->(%p)\n", This, pch); 1721 1722 if (!This->child.reole) 1723 return CO_E_RELEASED; 1724 1725 if (!pch) 1726 return E_INVALIDARG; 1727 1728 editor = This->child.reole->editor; 1729 ME_CursorFromCharOfs(editor, This->start, &cursor); 1730 return range_GetChar(editor, &cursor, pch); 1731 } 1732 1733 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch) 1734 { 1735 ITextRangeImpl *This = impl_from_ITextRange(me); 1736 1737 FIXME("(%p)->(%x): stub\n", This, ch); 1738 1739 if (!This->child.reole) 1740 return CO_E_RELEASED; 1741 1742 return E_NOTIMPL; 1743 } 1744 1745 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange); 1746 1747 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange) 1748 { 1749 ITextRangeImpl *This = impl_from_ITextRange(me); 1750 1751 TRACE("(%p)->(%p)\n", This, ppRange); 1752 1753 if (!This->child.reole) 1754 return CO_E_RELEASED; 1755 1756 if (!ppRange) 1757 return E_INVALIDARG; 1758 1759 return CreateITextRange(This->child.reole, This->start, This->end, ppRange); 1760 } 1761 1762 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **range) 1763 { 1764 ITextRangeImpl *This = impl_from_ITextRange(me); 1765 1766 FIXME("(%p)->(%p): stub\n", This, range); 1767 1768 if (!This->child.reole) 1769 return CO_E_RELEASED; 1770 1771 return E_NOTIMPL; 1772 } 1773 1774 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *range) 1775 { 1776 ITextRangeImpl *This = impl_from_ITextRange(me); 1777 1778 FIXME("(%p)->(%p): stub\n", This, range); 1779 1780 if (!This->child.reole) 1781 return CO_E_RELEASED; 1782 1783 return E_NOTIMPL; 1784 } 1785 1786 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *start) 1787 { 1788 ITextRangeImpl *This = impl_from_ITextRange(me); 1789 1790 TRACE("(%p)->(%p)\n", This, start); 1791 1792 if (!This->child.reole) 1793 return CO_E_RELEASED; 1794 1795 if (!start) 1796 return E_INVALIDARG; 1797 1798 *start = This->start; 1799 return S_OK; 1800 } 1801 1802 static HRESULT textrange_setstart(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) 1803 { 1804 int len; 1805 1806 if (value < 0) 1807 value = 0; 1808 1809 if (value == *start) 1810 return S_FALSE; 1811 1812 if (value <= *end) { 1813 *start = value; 1814 return S_OK; 1815 } 1816 1817 len = ME_GetTextLength(reole->editor); 1818 *start = *end = value > len ? len : value; 1819 return S_OK; 1820 } 1821 1822 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG value) 1823 { 1824 ITextRangeImpl *This = impl_from_ITextRange(me); 1825 1826 TRACE("(%p)->(%d)\n", This, value); 1827 1828 if (!This->child.reole) 1829 return CO_E_RELEASED; 1830 1831 return textrange_setstart(This->child.reole, value, &This->start, &This->end); 1832 } 1833 1834 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *end) 1835 { 1836 ITextRangeImpl *This = impl_from_ITextRange(me); 1837 1838 TRACE("(%p)->(%p)\n", This, end); 1839 1840 if (!This->child.reole) 1841 return CO_E_RELEASED; 1842 1843 if (!end) 1844 return E_INVALIDARG; 1845 1846 *end = This->end; 1847 return S_OK; 1848 } 1849 1850 static HRESULT textrange_setend(const IRichEditOleImpl *reole, LONG value, LONG *start, LONG *end) 1851 { 1852 int len; 1853 1854 if (value == *end) 1855 return S_FALSE; 1856 1857 if (value < *start) { 1858 *start = *end = max(0, value); 1859 return S_OK; 1860 } 1861 1862 len = ME_GetTextLength(reole->editor); 1863 *end = value > len ? len + 1 : value; 1864 return S_OK; 1865 } 1866 1867 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG value) 1868 { 1869 ITextRangeImpl *This = impl_from_ITextRange(me); 1870 1871 TRACE("(%p)->(%d)\n", This, value); 1872 1873 if (!This->child.reole) 1874 return CO_E_RELEASED; 1875 1876 return textrange_setend(This->child.reole, value, &This->start, &This->end); 1877 } 1878 1879 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **font) 1880 { 1881 ITextRangeImpl *This = impl_from_ITextRange(me); 1882 1883 TRACE("(%p)->(%p)\n", This, font); 1884 1885 if (!This->child.reole) 1886 return CO_E_RELEASED; 1887 1888 if (!font) 1889 return E_INVALIDARG; 1890 1891 return create_textfont(me, NULL, font); 1892 } 1893 1894 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *font) 1895 { 1896 ITextRangeImpl *This = impl_from_ITextRange(me); 1897 1898 TRACE("(%p)->(%p)\n", This, font); 1899 1900 if (!font) 1901 return E_INVALIDARG; 1902 1903 if (!This->child.reole) 1904 return CO_E_RELEASED; 1905 1906 textrange_set_font(me, font); 1907 return S_OK; 1908 } 1909 1910 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **para) 1911 { 1912 ITextRangeImpl *This = impl_from_ITextRange(me); 1913 1914 TRACE("(%p)->(%p)\n", This, para); 1915 1916 if (!This->child.reole) 1917 return CO_E_RELEASED; 1918 1919 if (!para) 1920 return E_INVALIDARG; 1921 1922 return create_textpara(me, para); 1923 } 1924 1925 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *para) 1926 { 1927 ITextRangeImpl *This = impl_from_ITextRange(me); 1928 1929 FIXME("(%p)->(%p): stub\n", This, para); 1930 1931 if (!This->child.reole) 1932 return CO_E_RELEASED; 1933 1934 return E_NOTIMPL; 1935 } 1936 1937 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *length) 1938 { 1939 ITextRangeImpl *This = impl_from_ITextRange(me); 1940 1941 TRACE("(%p)->(%p)\n", This, length); 1942 1943 if (!This->child.reole) 1944 return CO_E_RELEASED; 1945 1946 return textrange_get_storylength(This->child.reole->editor, length); 1947 } 1948 1949 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *value) 1950 { 1951 ITextRangeImpl *This = impl_from_ITextRange(me); 1952 1953 TRACE("(%p)->(%p)\n", This, value); 1954 1955 if (!This->child.reole) 1956 return CO_E_RELEASED; 1957 1958 if (!value) 1959 return E_INVALIDARG; 1960 1961 *value = tomUnknownStory; 1962 return S_OK; 1963 } 1964 1965 static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end) 1966 { 1967 if (*end == *start) 1968 return S_FALSE; 1969 1970 if (bStart == tomEnd) 1971 *start = *end; 1972 else 1973 *end = *start; 1974 return S_OK; 1975 } 1976 1977 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart) 1978 { 1979 ITextRangeImpl *This = impl_from_ITextRange(me); 1980 1981 TRACE("(%p)->(%d)\n", This, bStart); 1982 1983 if (!This->child.reole) 1984 return CO_E_RELEASED; 1985 1986 return range_Collapse(bStart, &This->start, &This->end); 1987 } 1988 1989 static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG unit, LONG *delta) 1990 { 1991 ITextRangeImpl *This = impl_from_ITextRange(me); 1992 1993 TRACE("(%p)->(%d %p)\n", This, unit, delta); 1994 1995 if (!This->child.reole) 1996 return CO_E_RELEASED; 1997 1998 return textrange_expand(me, unit, delta); 1999 } 2000 2001 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG unit, LONG *index) 2002 { 2003 ITextRangeImpl *This = impl_from_ITextRange(me); 2004 2005 FIXME("(%p)->(%d %p): stub\n", This, unit, index); 2006 2007 if (!This->child.reole) 2008 return CO_E_RELEASED; 2009 2010 return E_NOTIMPL; 2011 } 2012 2013 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG unit, LONG index, 2014 LONG extend) 2015 { 2016 ITextRangeImpl *This = impl_from_ITextRange(me); 2017 2018 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend); 2019 2020 if (!This->child.reole) 2021 return CO_E_RELEASED; 2022 2023 return E_NOTIMPL; 2024 } 2025 2026 static void cp2range(ME_TextEditor *editor, LONG *cp1, LONG *cp2) 2027 { 2028 int len = ME_GetTextLength(editor) + 1; 2029 *cp1 = max(*cp1, 0); 2030 *cp2 = max(*cp2, 0); 2031 *cp1 = min(*cp1, len); 2032 *cp2 = min(*cp2, len); 2033 if (*cp1 > *cp2) 2034 { 2035 int tmp = *cp1; 2036 *cp1 = *cp2; 2037 *cp2 = tmp; 2038 } 2039 if (*cp1 == len) 2040 *cp1 = *cp2 = len - 1; 2041 } 2042 2043 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG anchor, LONG active) 2044 { 2045 ITextRangeImpl *This = impl_from_ITextRange(me); 2046 2047 FIXME("(%p)->(%d %d): stub\n", This, anchor, active); 2048 2049 if (!This->child.reole) 2050 return CO_E_RELEASED; 2051 2052 cp2range(This->child.reole->editor, &anchor, &active); 2053 if (anchor == This->start && active == This->end) 2054 return S_FALSE; 2055 2056 This->start = anchor; 2057 This->end = active; 2058 return S_OK; 2059 } 2060 2061 static HRESULT textrange_inrange(LONG start, LONG end, ITextRange *range, LONG *ret) 2062 { 2063 LONG from, to, v; 2064 2065 if (!ret) 2066 ret = &v; 2067 2068 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) { 2069 *ret = tomFalse; 2070 } 2071 else 2072 *ret = (start >= from && end <= to) ? tomTrue : tomFalse; 2073 return *ret == tomTrue ? S_OK : S_FALSE; 2074 } 2075 2076 static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *range, LONG *ret) 2077 { 2078 ITextRangeImpl *This = impl_from_ITextRange(me); 2079 2080 TRACE("(%p)->(%p %p)\n", This, range, ret); 2081 2082 if (ret) 2083 *ret = tomFalse; 2084 2085 if (!This->child.reole) 2086 return CO_E_RELEASED; 2087 2088 if (!range) 2089 return S_FALSE; 2090 2091 return textrange_inrange(This->start, This->end, range, ret); 2092 } 2093 2094 static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *ret) 2095 { 2096 ITextRangeImpl *This = impl_from_ITextRange(me); 2097 2098 FIXME("(%p)->(%p): stub\n", This, ret); 2099 2100 if (!This->child.reole) 2101 return CO_E_RELEASED; 2102 2103 return E_NOTIMPL; 2104 } 2105 2106 static HRESULT textrange_isequal(LONG start, LONG end, ITextRange *range, LONG *ret) 2107 { 2108 LONG from, to, v; 2109 2110 if (!ret) 2111 ret = &v; 2112 2113 if (FAILED(ITextRange_GetStart(range, &from)) || FAILED(ITextRange_GetEnd(range, &to))) { 2114 *ret = tomFalse; 2115 } 2116 else 2117 *ret = (start == from && end == to) ? tomTrue : tomFalse; 2118 return *ret == tomTrue ? S_OK : S_FALSE; 2119 } 2120 2121 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *range, LONG *ret) 2122 { 2123 ITextRangeImpl *This = impl_from_ITextRange(me); 2124 2125 TRACE("(%p)->(%p %p)\n", This, range, ret); 2126 2127 if (ret) 2128 *ret = tomFalse; 2129 2130 if (!This->child.reole) 2131 return CO_E_RELEASED; 2132 2133 if (!range) 2134 return S_FALSE; 2135 2136 return textrange_isequal(This->start, This->end, range, ret); 2137 } 2138 2139 static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me) 2140 { 2141 ITextRangeImpl *This = impl_from_ITextRange(me); 2142 2143 TRACE("(%p)\n", This); 2144 2145 if (!This->child.reole) 2146 return CO_E_RELEASED; 2147 2148 ME_SetSelection(This->child.reole->editor, This->start, This->end); 2149 return S_OK; 2150 } 2151 2152 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG unit, LONG extend, 2153 LONG *delta) 2154 { 2155 ITextRangeImpl *This = impl_from_ITextRange(me); 2156 2157 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 2158 2159 if (!This->child.reole) 2160 return CO_E_RELEASED; 2161 2162 return E_NOTIMPL; 2163 } 2164 2165 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG unit, LONG extend, 2166 LONG *delta) 2167 { 2168 ITextRangeImpl *This = impl_from_ITextRange(me); 2169 2170 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 2171 2172 if (!This->child.reole) 2173 return CO_E_RELEASED; 2174 2175 return E_NOTIMPL; 2176 } 2177 2178 static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG unit, LONG count, LONG *delta) 2179 { 2180 ITextRangeImpl *This = impl_from_ITextRange(me); 2181 2182 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 2183 2184 if (!This->child.reole) 2185 return CO_E_RELEASED; 2186 2187 return E_NOTIMPL; 2188 } 2189 2190 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG unit, LONG count, 2191 LONG *delta) 2192 { 2193 ITextRangeImpl *This = impl_from_ITextRange(me); 2194 2195 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 2196 2197 if (!This->child.reole) 2198 return CO_E_RELEASED; 2199 2200 return E_NOTIMPL; 2201 } 2202 2203 static HRESULT textrange_moveend(ITextRange *range, LONG unit, LONG count, LONG *delta) 2204 { 2205 LONG old_start, old_end, new_start, new_end; 2206 HRESULT hr = S_OK; 2207 2208 if (!count) 2209 { 2210 if (delta) 2211 *delta = 0; 2212 return S_FALSE; 2213 } 2214 2215 ITextRange_GetStart(range, &old_start); 2216 ITextRange_GetEnd(range, &old_end); 2217 switch (unit) 2218 { 2219 case tomStory: 2220 if (count < 0) 2221 new_start = new_end = 0; 2222 else 2223 { 2224 new_start = old_start; 2225 ITextRange_GetStoryLength(range, &new_end); 2226 } 2227 if (delta) 2228 { 2229 if (new_end < old_end) 2230 *delta = -1; 2231 else if (new_end == old_end) 2232 *delta = 0; 2233 else 2234 *delta = 1; 2235 } 2236 break; 2237 default: 2238 FIXME("unit %d is not supported\n", unit); 2239 return E_NOTIMPL; 2240 } 2241 if (new_end == old_end) 2242 hr = S_FALSE; 2243 ITextRange_SetStart(range, new_start); 2244 ITextRange_SetEnd(range, new_end); 2245 2246 return hr; 2247 } 2248 2249 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG unit, LONG count, 2250 LONG *delta) 2251 { 2252 ITextRangeImpl *This = impl_from_ITextRange(me); 2253 2254 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); 2255 2256 if (!This->child.reole) 2257 return CO_E_RELEASED; 2258 2259 return textrange_moveend(me, unit, count, delta); 2260 } 2261 2262 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *charset, LONG count, 2263 LONG *delta) 2264 { 2265 ITextRangeImpl *This = impl_from_ITextRange(me); 2266 2267 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2268 2269 if (!This->child.reole) 2270 return CO_E_RELEASED; 2271 2272 return E_NOTIMPL; 2273 } 2274 2275 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *charset, LONG count, 2276 LONG *delta) 2277 { 2278 ITextRangeImpl *This = impl_from_ITextRange(me); 2279 2280 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2281 2282 if (!This->child.reole) 2283 return CO_E_RELEASED; 2284 2285 return E_NOTIMPL; 2286 } 2287 2288 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *charset, LONG count, 2289 LONG *delta) 2290 { 2291 ITextRangeImpl *This = impl_from_ITextRange(me); 2292 2293 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2294 2295 if (!This->child.reole) 2296 return CO_E_RELEASED; 2297 2298 return E_NOTIMPL; 2299 } 2300 2301 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *charset, LONG count, 2302 LONG *delta) 2303 { 2304 ITextRangeImpl *This = impl_from_ITextRange(me); 2305 2306 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2307 2308 if (!This->child.reole) 2309 return CO_E_RELEASED; 2310 2311 return E_NOTIMPL; 2312 } 2313 2314 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *charset, LONG count, 2315 LONG *delta) 2316 { 2317 ITextRangeImpl *This = impl_from_ITextRange(me); 2318 2319 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2320 2321 if (!This->child.reole) 2322 return CO_E_RELEASED; 2323 2324 return E_NOTIMPL; 2325 } 2326 2327 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *charset, LONG count, 2328 LONG *delta) 2329 { 2330 ITextRangeImpl *This = impl_from_ITextRange(me); 2331 2332 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 2333 2334 if (!This->child.reole) 2335 return CO_E_RELEASED; 2336 2337 return E_NOTIMPL; 2338 } 2339 2340 static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR text, LONG count, LONG flags, 2341 LONG *length) 2342 { 2343 ITextRangeImpl *This = impl_from_ITextRange(me); 2344 2345 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 2346 2347 if (!This->child.reole) 2348 return CO_E_RELEASED; 2349 2350 return E_NOTIMPL; 2351 } 2352 2353 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR text, LONG count, 2354 LONG flags, LONG *length) 2355 { 2356 ITextRangeImpl *This = impl_from_ITextRange(me); 2357 2358 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 2359 2360 if (!This->child.reole) 2361 return CO_E_RELEASED; 2362 2363 return E_NOTIMPL; 2364 } 2365 2366 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR text, LONG count, 2367 LONG flags, LONG *length) 2368 { 2369 ITextRangeImpl *This = impl_from_ITextRange(me); 2370 2371 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 2372 2373 if (!This->child.reole) 2374 return CO_E_RELEASED; 2375 2376 return E_NOTIMPL; 2377 } 2378 2379 static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG unit, LONG count, LONG *delta) 2380 { 2381 ITextRangeImpl *This = impl_from_ITextRange(me); 2382 2383 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 2384 2385 if (!This->child.reole) 2386 return CO_E_RELEASED; 2387 2388 return E_NOTIMPL; 2389 } 2390 2391 static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *v) 2392 { 2393 ITextRangeImpl *This = impl_from_ITextRange(me); 2394 2395 FIXME("(%p)->(%p): stub\n", This, v); 2396 2397 if (!This->child.reole) 2398 return CO_E_RELEASED; 2399 2400 return E_NOTIMPL; 2401 } 2402 2403 static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *v) 2404 { 2405 ITextRangeImpl *This = impl_from_ITextRange(me); 2406 2407 FIXME("(%p)->(%p): stub\n", This, v); 2408 2409 if (!This->child.reole) 2410 return CO_E_RELEASED; 2411 2412 return E_NOTIMPL; 2413 } 2414 2415 static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *v, LONG format) 2416 { 2417 ITextRangeImpl *This = impl_from_ITextRange(me); 2418 2419 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format); 2420 2421 if (!This->child.reole) 2422 return CO_E_RELEASED; 2423 2424 return E_NOTIMPL; 2425 } 2426 2427 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *v, LONG format, LONG *ret) 2428 { 2429 ITextRangeImpl *This = impl_from_ITextRange(me); 2430 2431 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret); 2432 2433 if (!This->child.reole) 2434 return CO_E_RELEASED; 2435 2436 return E_NOTIMPL; 2437 } 2438 2439 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *ret) 2440 { 2441 ITextRangeImpl *This = impl_from_ITextRange(me); 2442 2443 FIXME("(%p)->(%p): stub\n", This, ret); 2444 2445 if (!This->child.reole) 2446 return CO_E_RELEASED; 2447 2448 return E_NOTIMPL; 2449 } 2450 2451 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG type) 2452 { 2453 ITextRangeImpl *This = impl_from_ITextRange(me); 2454 2455 FIXME("(%p)->(%d): stub\n", This, type); 2456 2457 if (!This->child.reole) 2458 return CO_E_RELEASED; 2459 2460 return E_NOTIMPL; 2461 } 2462 2463 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG type, LONG *cx, LONG *cy) 2464 { 2465 ITextRangeImpl *This = impl_from_ITextRange(me); 2466 2467 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy); 2468 2469 if (!This->child.reole) 2470 return CO_E_RELEASED; 2471 2472 return E_NOTIMPL; 2473 } 2474 2475 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG type, 2476 LONG extend) 2477 { 2478 ITextRangeImpl *This = impl_from_ITextRange(me); 2479 2480 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend); 2481 2482 if (!This->child.reole) 2483 return CO_E_RELEASED; 2484 2485 return E_NOTIMPL; 2486 } 2487 2488 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value) 2489 { 2490 ITextRangeImpl *This = impl_from_ITextRange(me); 2491 ME_TextEditor *editor; 2492 ME_Cursor cursor; 2493 int x, y, height; 2494 2495 TRACE("(%p)->(%d)\n", This, value); 2496 2497 if (!This->child.reole) 2498 return CO_E_RELEASED; 2499 2500 editor = This->child.reole->editor; 2501 2502 switch (value) 2503 { 2504 case tomStart: 2505 ME_CursorFromCharOfs(editor, This->start, &cursor); 2506 ME_GetCursorCoordinates(editor, &cursor, &x, &y, &height); 2507 break; 2508 default: 2509 FIXME("bStart value %d not handled\n", value); 2510 return E_NOTIMPL; 2511 } 2512 ME_ScrollAbs(editor, x, y); 2513 return S_OK; 2514 } 2515 2516 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv) 2517 { 2518 ITextRangeImpl *This = impl_from_ITextRange(me); 2519 2520 FIXME("(%p)->(%p): stub\n", This, ppv); 2521 2522 if (!This->child.reole) 2523 return CO_E_RELEASED; 2524 2525 return E_NOTIMPL; 2526 } 2527 2528 static const ITextRangeVtbl trvt = { 2529 ITextRange_fnQueryInterface, 2530 ITextRange_fnAddRef, 2531 ITextRange_fnRelease, 2532 ITextRange_fnGetTypeInfoCount, 2533 ITextRange_fnGetTypeInfo, 2534 ITextRange_fnGetIDsOfNames, 2535 ITextRange_fnInvoke, 2536 ITextRange_fnGetText, 2537 ITextRange_fnSetText, 2538 ITextRange_fnGetChar, 2539 ITextRange_fnSetChar, 2540 ITextRange_fnGetDuplicate, 2541 ITextRange_fnGetFormattedText, 2542 ITextRange_fnSetFormattedText, 2543 ITextRange_fnGetStart, 2544 ITextRange_fnSetStart, 2545 ITextRange_fnGetEnd, 2546 ITextRange_fnSetEnd, 2547 ITextRange_fnGetFont, 2548 ITextRange_fnSetFont, 2549 ITextRange_fnGetPara, 2550 ITextRange_fnSetPara, 2551 ITextRange_fnGetStoryLength, 2552 ITextRange_fnGetStoryType, 2553 ITextRange_fnCollapse, 2554 ITextRange_fnExpand, 2555 ITextRange_fnGetIndex, 2556 ITextRange_fnSetIndex, 2557 ITextRange_fnSetRange, 2558 ITextRange_fnInRange, 2559 ITextRange_fnInStory, 2560 ITextRange_fnIsEqual, 2561 ITextRange_fnSelect, 2562 ITextRange_fnStartOf, 2563 ITextRange_fnEndOf, 2564 ITextRange_fnMove, 2565 ITextRange_fnMoveStart, 2566 ITextRange_fnMoveEnd, 2567 ITextRange_fnMoveWhile, 2568 ITextRange_fnMoveStartWhile, 2569 ITextRange_fnMoveEndWhile, 2570 ITextRange_fnMoveUntil, 2571 ITextRange_fnMoveStartUntil, 2572 ITextRange_fnMoveEndUntil, 2573 ITextRange_fnFindText, 2574 ITextRange_fnFindTextStart, 2575 ITextRange_fnFindTextEnd, 2576 ITextRange_fnDelete, 2577 ITextRange_fnCut, 2578 ITextRange_fnCopy, 2579 ITextRange_fnPaste, 2580 ITextRange_fnCanPaste, 2581 ITextRange_fnCanEdit, 2582 ITextRange_fnChangeCase, 2583 ITextRange_fnGetPoint, 2584 ITextRange_fnSetPoint, 2585 ITextRange_fnScrollIntoView, 2586 ITextRange_fnGetEmbeddedObject 2587 }; 2588 2589 /* ITextFont */ 2590 static HRESULT WINAPI TextFont_QueryInterface(ITextFont *iface, REFIID riid, void **ppv) 2591 { 2592 ITextFontImpl *This = impl_from_ITextFont(iface); 2593 2594 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 2595 2596 if (IsEqualIID(riid, &IID_ITextFont) || 2597 IsEqualIID(riid, &IID_IDispatch) || 2598 IsEqualIID(riid, &IID_IUnknown)) 2599 { 2600 *ppv = iface; 2601 ITextFont_AddRef(iface); 2602 return S_OK; 2603 } 2604 2605 *ppv = NULL; 2606 return E_NOINTERFACE; 2607 } 2608 2609 static ULONG WINAPI TextFont_AddRef(ITextFont *iface) 2610 { 2611 ITextFontImpl *This = impl_from_ITextFont(iface); 2612 ULONG ref = InterlockedIncrement(&This->ref); 2613 TRACE("(%p)->(%u)\n", This, ref); 2614 return ref; 2615 } 2616 2617 static ULONG WINAPI TextFont_Release(ITextFont *iface) 2618 { 2619 ITextFontImpl *This = impl_from_ITextFont(iface); 2620 ULONG ref = InterlockedDecrement(&This->ref); 2621 2622 TRACE("(%p)->(%u)\n", This, ref); 2623 2624 if (!ref) 2625 { 2626 if (This->range) 2627 ITextRange_Release(This->range); 2628 SysFreeString(This->props[FONT_NAME].str); 2629 heap_free(This); 2630 } 2631 2632 return ref; 2633 } 2634 2635 static HRESULT WINAPI TextFont_GetTypeInfoCount(ITextFont *iface, UINT *pctinfo) 2636 { 2637 ITextFontImpl *This = impl_from_ITextFont(iface); 2638 TRACE("(%p)->(%p)\n", This, pctinfo); 2639 *pctinfo = 1; 2640 return S_OK; 2641 } 2642 2643 static HRESULT WINAPI TextFont_GetTypeInfo(ITextFont *iface, UINT iTInfo, LCID lcid, 2644 ITypeInfo **ppTInfo) 2645 { 2646 ITextFontImpl *This = impl_from_ITextFont(iface); 2647 HRESULT hr; 2648 2649 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 2650 2651 hr = get_typeinfo(ITextFont_tid, ppTInfo); 2652 if (SUCCEEDED(hr)) 2653 ITypeInfo_AddRef(*ppTInfo); 2654 return hr; 2655 } 2656 2657 static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid, 2658 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 2659 { 2660 ITextFontImpl *This = impl_from_ITextFont(iface); 2661 ITypeInfo *ti; 2662 HRESULT hr; 2663 2664 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), 2665 rgszNames, cNames, lcid, rgDispId); 2666 2667 hr = get_typeinfo(ITextFont_tid, &ti); 2668 if (SUCCEEDED(hr)) 2669 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 2670 return hr; 2671 } 2672 2673 static HRESULT WINAPI TextFont_Invoke( 2674 ITextFont *iface, 2675 DISPID dispIdMember, 2676 REFIID riid, 2677 LCID lcid, 2678 WORD wFlags, 2679 DISPPARAMS *pDispParams, 2680 VARIANT *pVarResult, 2681 EXCEPINFO *pExcepInfo, 2682 UINT *puArgErr) 2683 { 2684 ITextFontImpl *This = impl_from_ITextFont(iface); 2685 ITypeInfo *ti; 2686 HRESULT hr; 2687 2688 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), 2689 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 2690 2691 hr = get_typeinfo(ITextFont_tid, &ti); 2692 if (SUCCEEDED(hr)) 2693 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 2694 return hr; 2695 } 2696 2697 static HRESULT WINAPI TextFont_GetDuplicate(ITextFont *iface, ITextFont **ret) 2698 { 2699 ITextFontImpl *This = impl_from_ITextFont(iface); 2700 2701 TRACE("(%p)->(%p)\n", This, ret); 2702 2703 if (!ret) 2704 return E_INVALIDARG; 2705 2706 *ret = NULL; 2707 if (This->range && !get_range_reole(This->range)) 2708 return CO_E_RELEASED; 2709 2710 return create_textfont(NULL, This, ret); 2711 } 2712 2713 static HRESULT WINAPI TextFont_SetDuplicate(ITextFont *iface, ITextFont *pFont) 2714 { 2715 ITextFontImpl *This = impl_from_ITextFont(iface); 2716 FIXME("(%p)->(%p): stub\n", This, pFont); 2717 2718 if (This->range && !get_range_reole(This->range)) 2719 return CO_E_RELEASED; 2720 2721 return E_NOTIMPL; 2722 } 2723 2724 static HRESULT WINAPI TextFont_CanChange(ITextFont *iface, LONG *ret) 2725 { 2726 ITextFontImpl *This = impl_from_ITextFont(iface); 2727 FIXME("(%p)->(%p): stub\n", This, ret); 2728 2729 if (This->range && !get_range_reole(This->range)) 2730 return CO_E_RELEASED; 2731 2732 return E_NOTIMPL; 2733 } 2734 2735 static HRESULT WINAPI TextFont_IsEqual(ITextFont *iface, ITextFont *font, LONG *ret) 2736 { 2737 ITextFontImpl *This = impl_from_ITextFont(iface); 2738 FIXME("(%p)->(%p %p): stub\n", This, font, ret); 2739 2740 if (This->range && !get_range_reole(This->range)) 2741 return CO_E_RELEASED; 2742 2743 return E_NOTIMPL; 2744 } 2745 2746 static void textfont_reset_to_default(ITextFontImpl *font) 2747 { 2748 enum textfont_prop_id id; 2749 2750 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { 2751 switch (id) 2752 { 2753 case FONT_ALLCAPS: 2754 case FONT_ANIMATION: 2755 case FONT_BOLD: 2756 case FONT_EMBOSS: 2757 case FONT_HIDDEN: 2758 case FONT_ENGRAVE: 2759 case FONT_ITALIC: 2760 case FONT_OUTLINE: 2761 case FONT_PROTECTED: 2762 case FONT_SHADOW: 2763 case FONT_SMALLCAPS: 2764 case FONT_STRIKETHROUGH: 2765 case FONT_SUBSCRIPT: 2766 case FONT_SUPERSCRIPT: 2767 case FONT_UNDERLINE: 2768 font->props[id].l = tomFalse; 2769 break; 2770 case FONT_BACKCOLOR: 2771 case FONT_FORECOLOR: 2772 font->props[id].l = tomAutoColor; 2773 break; 2774 case FONT_KERNING: 2775 case FONT_POSITION: 2776 case FONT_SIZE: 2777 case FONT_SPACING: 2778 font->props[id].f = 0.0; 2779 break; 2780 case FONT_LANGID: 2781 font->props[id].l = GetSystemDefaultLCID(); 2782 break; 2783 case FONT_NAME: { 2784 static const WCHAR sysW[] = {'S','y','s','t','e','m',0}; 2785 SysFreeString(font->props[id].str); 2786 font->props[id].str = SysAllocString(sysW); 2787 break; 2788 } 2789 case FONT_WEIGHT: 2790 font->props[id].l = FW_NORMAL; 2791 break; 2792 default: 2793 FIXME("font property %d not handled\n", id); 2794 } 2795 } 2796 } 2797 2798 static void textfont_reset_to_undefined(ITextFontImpl *font) 2799 { 2800 enum textfont_prop_id id; 2801 2802 for (id = FONT_PROPID_FIRST; id < FONT_PROPID_LAST; id++) { 2803 switch (id) 2804 { 2805 case FONT_ALLCAPS: 2806 case FONT_ANIMATION: 2807 case FONT_BOLD: 2808 case FONT_EMBOSS: 2809 case FONT_HIDDEN: 2810 case FONT_ENGRAVE: 2811 case FONT_ITALIC: 2812 case FONT_OUTLINE: 2813 case FONT_PROTECTED: 2814 case FONT_SHADOW: 2815 case FONT_SMALLCAPS: 2816 case FONT_STRIKETHROUGH: 2817 case FONT_SUBSCRIPT: 2818 case FONT_SUPERSCRIPT: 2819 case FONT_UNDERLINE: 2820 case FONT_BACKCOLOR: 2821 case FONT_FORECOLOR: 2822 case FONT_LANGID: 2823 case FONT_WEIGHT: 2824 font->props[id].l = tomUndefined; 2825 break; 2826 case FONT_KERNING: 2827 case FONT_POSITION: 2828 case FONT_SIZE: 2829 case FONT_SPACING: 2830 font->props[id].f = tomUndefined; 2831 break; 2832 case FONT_NAME: 2833 break; 2834 default: 2835 FIXME("font property %d not handled\n", id); 2836 } 2837 } 2838 } 2839 2840 static void textfont_apply_range_props(ITextFontImpl *font) 2841 { 2842 enum textfont_prop_id propid; 2843 for (propid = FONT_PROPID_FIRST; propid < FONT_PROPID_LAST; propid++) 2844 set_textfont_prop(font, propid, &font->props[propid]); 2845 } 2846 2847 static HRESULT WINAPI TextFont_Reset(ITextFont *iface, LONG value) 2848 { 2849 ITextFontImpl *This = impl_from_ITextFont(iface); 2850 2851 TRACE("(%p)->(%d)\n", This, value); 2852 2853 /* If font is attached to a range, released or not, we can't 2854 reset to undefined */ 2855 if (This->range) { 2856 if (!get_range_reole(This->range)) 2857 return CO_E_RELEASED; 2858 2859 switch (value) 2860 { 2861 case tomUndefined: 2862 return E_INVALIDARG; 2863 case tomCacheParms: 2864 textfont_cache_range_props(This); 2865 This->get_cache_enabled = TRUE; 2866 break; 2867 case tomTrackParms: 2868 This->get_cache_enabled = FALSE; 2869 break; 2870 case tomApplyLater: 2871 This->set_cache_enabled = TRUE; 2872 break; 2873 case tomApplyNow: 2874 This->set_cache_enabled = FALSE; 2875 textfont_apply_range_props(This); 2876 break; 2877 case tomUsePoints: 2878 case tomUseTwips: 2879 return E_INVALIDARG; 2880 default: 2881 FIXME("reset mode %d not supported\n", value); 2882 } 2883 2884 return S_OK; 2885 } 2886 else { 2887 switch (value) 2888 { 2889 /* reset to global defaults */ 2890 case tomDefault: 2891 textfont_reset_to_default(This); 2892 return S_OK; 2893 /* all properties are set to tomUndefined, font name is retained */ 2894 case tomUndefined: 2895 textfont_reset_to_undefined(This); 2896 return S_OK; 2897 case tomApplyNow: 2898 case tomApplyLater: 2899 case tomTrackParms: 2900 case tomCacheParms: 2901 return S_OK; 2902 case tomUsePoints: 2903 case tomUseTwips: 2904 return E_INVALIDARG; 2905 } 2906 } 2907 2908 FIXME("reset mode %d not supported\n", value); 2909 return E_NOTIMPL; 2910 } 2911 2912 static HRESULT WINAPI TextFont_GetStyle(ITextFont *iface, LONG *value) 2913 { 2914 ITextFontImpl *This = impl_from_ITextFont(iface); 2915 FIXME("(%p)->(%p): stub\n", This, value); 2916 2917 if (This->range && !get_range_reole(This->range)) 2918 return CO_E_RELEASED; 2919 2920 return E_NOTIMPL; 2921 } 2922 2923 static HRESULT WINAPI TextFont_SetStyle(ITextFont *iface, LONG value) 2924 { 2925 ITextFontImpl *This = impl_from_ITextFont(iface); 2926 FIXME("(%p)->(%d): stub\n", This, value); 2927 2928 if (This->range && !get_range_reole(This->range)) 2929 return CO_E_RELEASED; 2930 2931 return E_NOTIMPL; 2932 } 2933 2934 static HRESULT WINAPI TextFont_GetAllCaps(ITextFont *iface, LONG *value) 2935 { 2936 ITextFontImpl *This = impl_from_ITextFont(iface); 2937 TRACE("(%p)->(%p)\n", This, value); 2938 return get_textfont_propl(This, FONT_ALLCAPS, value); 2939 } 2940 2941 static HRESULT WINAPI TextFont_SetAllCaps(ITextFont *iface, LONG value) 2942 { 2943 ITextFontImpl *This = impl_from_ITextFont(iface); 2944 TRACE("(%p)->(%d)\n", This, value); 2945 return set_textfont_propd(This, FONT_ALLCAPS, value); 2946 } 2947 2948 static HRESULT WINAPI TextFont_GetAnimation(ITextFont *iface, LONG *value) 2949 { 2950 ITextFontImpl *This = impl_from_ITextFont(iface); 2951 TRACE("(%p)->(%p)\n", This, value); 2952 return get_textfont_propl(This, FONT_ANIMATION, value); 2953 } 2954 2955 static HRESULT WINAPI TextFont_SetAnimation(ITextFont *iface, LONG value) 2956 { 2957 ITextFontImpl *This = impl_from_ITextFont(iface); 2958 2959 TRACE("(%p)->(%d)\n", This, value); 2960 2961 if (value < tomNoAnimation || value > tomAnimationMax) 2962 return E_INVALIDARG; 2963 2964 return set_textfont_propl(This, FONT_ANIMATION, value); 2965 } 2966 2967 static HRESULT WINAPI TextFont_GetBackColor(ITextFont *iface, LONG *value) 2968 { 2969 ITextFontImpl *This = impl_from_ITextFont(iface); 2970 TRACE("(%p)->(%p)\n", This, value); 2971 return get_textfont_propl(This, FONT_BACKCOLOR, value); 2972 } 2973 2974 static HRESULT WINAPI TextFont_SetBackColor(ITextFont *iface, LONG value) 2975 { 2976 ITextFontImpl *This = impl_from_ITextFont(iface); 2977 TRACE("(%p)->(%d)\n", This, value); 2978 return set_textfont_propl(This, FONT_BACKCOLOR, value); 2979 } 2980 2981 static HRESULT WINAPI TextFont_GetBold(ITextFont *iface, LONG *value) 2982 { 2983 ITextFontImpl *This = impl_from_ITextFont(iface); 2984 TRACE("(%p)->(%p)\n", This, value); 2985 return get_textfont_propl(This, FONT_BOLD, value); 2986 } 2987 2988 static HRESULT WINAPI TextFont_SetBold(ITextFont *iface, LONG value) 2989 { 2990 ITextFontImpl *This = impl_from_ITextFont(iface); 2991 TRACE("(%p)->(%d)\n", This, value); 2992 return set_textfont_propd(This, FONT_BOLD, value); 2993 } 2994 2995 static HRESULT WINAPI TextFont_GetEmboss(ITextFont *iface, LONG *value) 2996 { 2997 ITextFontImpl *This = impl_from_ITextFont(iface); 2998 TRACE("(%p)->(%p)\n", This, value); 2999 return get_textfont_propl(This, FONT_EMBOSS, value); 3000 } 3001 3002 static HRESULT WINAPI TextFont_SetEmboss(ITextFont *iface, LONG value) 3003 { 3004 ITextFontImpl *This = impl_from_ITextFont(iface); 3005 TRACE("(%p)->(%d)\n", This, value); 3006 return set_textfont_propd(This, FONT_EMBOSS, value); 3007 } 3008 3009 static HRESULT WINAPI TextFont_GetForeColor(ITextFont *iface, LONG *value) 3010 { 3011 ITextFontImpl *This = impl_from_ITextFont(iface); 3012 TRACE("(%p)->(%p)\n", This, value); 3013 return get_textfont_propl(This, FONT_FORECOLOR, value); 3014 } 3015 3016 static HRESULT WINAPI TextFont_SetForeColor(ITextFont *iface, LONG value) 3017 { 3018 ITextFontImpl *This = impl_from_ITextFont(iface); 3019 TRACE("(%p)->(%d)\n", This, value); 3020 return set_textfont_propl(This, FONT_FORECOLOR, value); 3021 } 3022 3023 static HRESULT WINAPI TextFont_GetHidden(ITextFont *iface, LONG *value) 3024 { 3025 ITextFontImpl *This = impl_from_ITextFont(iface); 3026 TRACE("(%p)->(%p)\n", This, value); 3027 return get_textfont_propl(This, FONT_HIDDEN, value); 3028 } 3029 3030 static HRESULT WINAPI TextFont_SetHidden(ITextFont *iface, LONG value) 3031 { 3032 ITextFontImpl *This = impl_from_ITextFont(iface); 3033 TRACE("(%p)->(%d)\n", This, value); 3034 return set_textfont_propd(This, FONT_HIDDEN, value); 3035 } 3036 3037 static HRESULT WINAPI TextFont_GetEngrave(ITextFont *iface, LONG *value) 3038 { 3039 ITextFontImpl *This = impl_from_ITextFont(iface); 3040 TRACE("(%p)->(%p)\n", This, value); 3041 return get_textfont_propl(This, FONT_ENGRAVE, value); 3042 } 3043 3044 static HRESULT WINAPI TextFont_SetEngrave(ITextFont *iface, LONG value) 3045 { 3046 ITextFontImpl *This = impl_from_ITextFont(iface); 3047 TRACE("(%p)->(%d)\n", This, value); 3048 return set_textfont_propd(This, FONT_ENGRAVE, value); 3049 } 3050 3051 static HRESULT WINAPI TextFont_GetItalic(ITextFont *iface, LONG *value) 3052 { 3053 ITextFontImpl *This = impl_from_ITextFont(iface); 3054 TRACE("(%p)->(%p)\n", This, value); 3055 return get_textfont_propl(This, FONT_ITALIC, value); 3056 } 3057 3058 static HRESULT WINAPI TextFont_SetItalic(ITextFont *iface, LONG value) 3059 { 3060 ITextFontImpl *This = impl_from_ITextFont(iface); 3061 TRACE("(%p)->(%d)\n", This, value); 3062 return set_textfont_propd(This, FONT_ITALIC, value); 3063 } 3064 3065 static HRESULT WINAPI TextFont_GetKerning(ITextFont *iface, FLOAT *value) 3066 { 3067 ITextFontImpl *This = impl_from_ITextFont(iface); 3068 TRACE("(%p)->(%p)\n", This, value); 3069 return get_textfont_propf(This, FONT_KERNING, value); 3070 } 3071 3072 static HRESULT WINAPI TextFont_SetKerning(ITextFont *iface, FLOAT value) 3073 { 3074 ITextFontImpl *This = impl_from_ITextFont(iface); 3075 TRACE("(%p)->(%.2f)\n", This, value); 3076 return set_textfont_propf(This, FONT_KERNING, value); 3077 } 3078 3079 static HRESULT WINAPI TextFont_GetLanguageID(ITextFont *iface, LONG *value) 3080 { 3081 ITextFontImpl *This = impl_from_ITextFont(iface); 3082 TRACE("(%p)->(%p)\n", This, value); 3083 return get_textfont_propl(This, FONT_LANGID, value); 3084 } 3085 3086 static HRESULT WINAPI TextFont_SetLanguageID(ITextFont *iface, LONG value) 3087 { 3088 ITextFontImpl *This = impl_from_ITextFont(iface); 3089 TRACE("(%p)->(%d)\n", This, value); 3090 return set_textfont_propl(This, FONT_LANGID, value); 3091 } 3092 3093 static HRESULT WINAPI TextFont_GetName(ITextFont *iface, BSTR *value) 3094 { 3095 ITextFontImpl *This = impl_from_ITextFont(iface); 3096 3097 TRACE("(%p)->(%p)\n", This, value); 3098 3099 if (!value) 3100 return E_INVALIDARG; 3101 3102 *value = NULL; 3103 3104 if (!This->range) { 3105 if (This->props[FONT_NAME].str) 3106 *value = SysAllocString(This->props[FONT_NAME].str); 3107 else 3108 *value = SysAllocStringLen(NULL, 0); 3109 return *value ? S_OK : E_OUTOFMEMORY; 3110 } 3111 3112 return textfont_getname_from_range(This->range, value); 3113 } 3114 3115 static HRESULT WINAPI TextFont_SetName(ITextFont *iface, BSTR value) 3116 { 3117 ITextFontImpl *This = impl_from_ITextFont(iface); 3118 textfont_prop_val v; 3119 3120 TRACE("(%p)->(%s)\n", This, debugstr_w(value)); 3121 3122 v.str = value; 3123 return set_textfont_prop(This, FONT_NAME, &v); 3124 } 3125 3126 static HRESULT WINAPI TextFont_GetOutline(ITextFont *iface, LONG *value) 3127 { 3128 ITextFontImpl *This = impl_from_ITextFont(iface); 3129 TRACE("(%p)->(%p)\n", This, value); 3130 return get_textfont_propl(This, FONT_OUTLINE, value); 3131 } 3132 3133 static HRESULT WINAPI TextFont_SetOutline(ITextFont *iface, LONG value) 3134 { 3135 ITextFontImpl *This = impl_from_ITextFont(iface); 3136 TRACE("(%p)->(%d)\n", This, value); 3137 return set_textfont_propd(This, FONT_OUTLINE, value); 3138 } 3139 3140 static HRESULT WINAPI TextFont_GetPosition(ITextFont *iface, FLOAT *value) 3141 { 3142 ITextFontImpl *This = impl_from_ITextFont(iface); 3143 TRACE("(%p)->(%p)\n", This, value); 3144 return get_textfont_propf(This, FONT_POSITION, value); 3145 } 3146 3147 static HRESULT WINAPI TextFont_SetPosition(ITextFont *iface, FLOAT value) 3148 { 3149 ITextFontImpl *This = impl_from_ITextFont(iface); 3150 TRACE("(%p)->(%.2f)\n", This, value); 3151 return set_textfont_propf(This, FONT_POSITION, value); 3152 } 3153 3154 static HRESULT WINAPI TextFont_GetProtected(ITextFont *iface, LONG *value) 3155 { 3156 ITextFontImpl *This = impl_from_ITextFont(iface); 3157 TRACE("(%p)->(%p)\n", This, value); 3158 return get_textfont_propl(This, FONT_PROTECTED, value); 3159 } 3160 3161 static HRESULT WINAPI TextFont_SetProtected(ITextFont *iface, LONG value) 3162 { 3163 ITextFontImpl *This = impl_from_ITextFont(iface); 3164 TRACE("(%p)->(%d)\n", This, value); 3165 return set_textfont_propd(This, FONT_PROTECTED, value); 3166 } 3167 3168 static HRESULT WINAPI TextFont_GetShadow(ITextFont *iface, LONG *value) 3169 { 3170 ITextFontImpl *This = impl_from_ITextFont(iface); 3171 TRACE("(%p)->(%p)\n", This, value); 3172 return get_textfont_propl(This, FONT_SHADOW, value); 3173 } 3174 3175 static HRESULT WINAPI TextFont_SetShadow(ITextFont *iface, LONG value) 3176 { 3177 ITextFontImpl *This = impl_from_ITextFont(iface); 3178 TRACE("(%p)->(%d)\n", This, value); 3179 return set_textfont_propd(This, FONT_SHADOW, value); 3180 } 3181 3182 static HRESULT WINAPI TextFont_GetSize(ITextFont *iface, FLOAT *value) 3183 { 3184 ITextFontImpl *This = impl_from_ITextFont(iface); 3185 TRACE("(%p)->(%p)\n", This, value); 3186 return get_textfont_propf(This, FONT_SIZE, value); 3187 } 3188 3189 static HRESULT WINAPI TextFont_SetSize(ITextFont *iface, FLOAT value) 3190 { 3191 ITextFontImpl *This = impl_from_ITextFont(iface); 3192 TRACE("(%p)->(%.2f)\n", This, value); 3193 return set_textfont_propf(This, FONT_SIZE, value); 3194 } 3195 3196 static HRESULT WINAPI TextFont_GetSmallCaps(ITextFont *iface, LONG *value) 3197 { 3198 ITextFontImpl *This = impl_from_ITextFont(iface); 3199 TRACE("(%p)->(%p)\n", This, value); 3200 return get_textfont_propl(This, FONT_SMALLCAPS, value); 3201 } 3202 3203 static HRESULT WINAPI TextFont_SetSmallCaps(ITextFont *iface, LONG value) 3204 { 3205 ITextFontImpl *This = impl_from_ITextFont(iface); 3206 TRACE("(%p)->(%d)\n", This, value); 3207 return set_textfont_propd(This, FONT_SMALLCAPS, value); 3208 } 3209 3210 static HRESULT WINAPI TextFont_GetSpacing(ITextFont *iface, FLOAT *value) 3211 { 3212 ITextFontImpl *This = impl_from_ITextFont(iface); 3213 TRACE("(%p)->(%p)\n", This, value); 3214 return get_textfont_propf(This, FONT_SPACING, value); 3215 } 3216 3217 static HRESULT WINAPI TextFont_SetSpacing(ITextFont *iface, FLOAT value) 3218 { 3219 ITextFontImpl *This = impl_from_ITextFont(iface); 3220 TRACE("(%p)->(%.2f)\n", This, value); 3221 return set_textfont_propf(This, FONT_SPACING, value); 3222 } 3223 3224 static HRESULT WINAPI TextFont_GetStrikeThrough(ITextFont *iface, LONG *value) 3225 { 3226 ITextFontImpl *This = impl_from_ITextFont(iface); 3227 TRACE("(%p)->(%p)\n", This, value); 3228 return get_textfont_propl(This, FONT_STRIKETHROUGH, value); 3229 } 3230 3231 static HRESULT WINAPI TextFont_SetStrikeThrough(ITextFont *iface, LONG value) 3232 { 3233 ITextFontImpl *This = impl_from_ITextFont(iface); 3234 TRACE("(%p)->(%d)\n", This, value); 3235 return set_textfont_propd(This, FONT_STRIKETHROUGH, value); 3236 } 3237 3238 static HRESULT WINAPI TextFont_GetSubscript(ITextFont *iface, LONG *value) 3239 { 3240 ITextFontImpl *This = impl_from_ITextFont(iface); 3241 TRACE("(%p)->(%p)\n", This, value); 3242 return get_textfont_propl(This, FONT_SUBSCRIPT, value); 3243 } 3244 3245 static HRESULT WINAPI TextFont_SetSubscript(ITextFont *iface, LONG value) 3246 { 3247 ITextFontImpl *This = impl_from_ITextFont(iface); 3248 TRACE("(%p)->(%d)\n", This, value); 3249 return set_textfont_propd(This, FONT_SUBSCRIPT, value); 3250 } 3251 3252 static HRESULT WINAPI TextFont_GetSuperscript(ITextFont *iface, LONG *value) 3253 { 3254 ITextFontImpl *This = impl_from_ITextFont(iface); 3255 TRACE("(%p)->(%p)\n", This, value); 3256 return get_textfont_propl(This, FONT_SUPERSCRIPT, value); 3257 } 3258 3259 static HRESULT WINAPI TextFont_SetSuperscript(ITextFont *iface, LONG value) 3260 { 3261 ITextFontImpl *This = impl_from_ITextFont(iface); 3262 TRACE("(%p)->(%d)\n", This, value); 3263 return set_textfont_propd(This, FONT_SUPERSCRIPT, value); 3264 } 3265 3266 static HRESULT WINAPI TextFont_GetUnderline(ITextFont *iface, LONG *value) 3267 { 3268 ITextFontImpl *This = impl_from_ITextFont(iface); 3269 TRACE("(%p)->(%p)\n", This, value); 3270 return get_textfont_propl(This, FONT_UNDERLINE, value); 3271 } 3272 3273 static HRESULT WINAPI TextFont_SetUnderline(ITextFont *iface, LONG value) 3274 { 3275 ITextFontImpl *This = impl_from_ITextFont(iface); 3276 TRACE("(%p)->(%d)\n", This, value); 3277 return set_textfont_propd(This, FONT_UNDERLINE, value); 3278 } 3279 3280 static HRESULT WINAPI TextFont_GetWeight(ITextFont *iface, LONG *value) 3281 { 3282 ITextFontImpl *This = impl_from_ITextFont(iface); 3283 TRACE("(%p)->(%p)\n", This, value); 3284 return get_textfont_propl(This, FONT_WEIGHT, value); 3285 } 3286 3287 static HRESULT WINAPI TextFont_SetWeight(ITextFont *iface, LONG value) 3288 { 3289 ITextFontImpl *This = impl_from_ITextFont(iface); 3290 TRACE("(%p)->(%d)\n", This, value); 3291 return set_textfont_propl(This, FONT_WEIGHT, value); 3292 } 3293 3294 static ITextFontVtbl textfontvtbl = { 3295 TextFont_QueryInterface, 3296 TextFont_AddRef, 3297 TextFont_Release, 3298 TextFont_GetTypeInfoCount, 3299 TextFont_GetTypeInfo, 3300 TextFont_GetIDsOfNames, 3301 TextFont_Invoke, 3302 TextFont_GetDuplicate, 3303 TextFont_SetDuplicate, 3304 TextFont_CanChange, 3305 TextFont_IsEqual, 3306 TextFont_Reset, 3307 TextFont_GetStyle, 3308 TextFont_SetStyle, 3309 TextFont_GetAllCaps, 3310 TextFont_SetAllCaps, 3311 TextFont_GetAnimation, 3312 TextFont_SetAnimation, 3313 TextFont_GetBackColor, 3314 TextFont_SetBackColor, 3315 TextFont_GetBold, 3316 TextFont_SetBold, 3317 TextFont_GetEmboss, 3318 TextFont_SetEmboss, 3319 TextFont_GetForeColor, 3320 TextFont_SetForeColor, 3321 TextFont_GetHidden, 3322 TextFont_SetHidden, 3323 TextFont_GetEngrave, 3324 TextFont_SetEngrave, 3325 TextFont_GetItalic, 3326 TextFont_SetItalic, 3327 TextFont_GetKerning, 3328 TextFont_SetKerning, 3329 TextFont_GetLanguageID, 3330 TextFont_SetLanguageID, 3331 TextFont_GetName, 3332 TextFont_SetName, 3333 TextFont_GetOutline, 3334 TextFont_SetOutline, 3335 TextFont_GetPosition, 3336 TextFont_SetPosition, 3337 TextFont_GetProtected, 3338 TextFont_SetProtected, 3339 TextFont_GetShadow, 3340 TextFont_SetShadow, 3341 TextFont_GetSize, 3342 TextFont_SetSize, 3343 TextFont_GetSmallCaps, 3344 TextFont_SetSmallCaps, 3345 TextFont_GetSpacing, 3346 TextFont_SetSpacing, 3347 TextFont_GetStrikeThrough, 3348 TextFont_SetStrikeThrough, 3349 TextFont_GetSubscript, 3350 TextFont_SetSubscript, 3351 TextFont_GetSuperscript, 3352 TextFont_SetSuperscript, 3353 TextFont_GetUnderline, 3354 TextFont_SetUnderline, 3355 TextFont_GetWeight, 3356 TextFont_SetWeight 3357 }; 3358 3359 static HRESULT create_textfont(ITextRange *range, const ITextFontImpl *src, ITextFont **ret) 3360 { 3361 ITextFontImpl *font; 3362 3363 *ret = NULL; 3364 font = heap_alloc(sizeof(*font)); 3365 if (!font) 3366 return E_OUTOFMEMORY; 3367 3368 font->ITextFont_iface.lpVtbl = &textfontvtbl; 3369 font->ref = 1; 3370 3371 if (src) { 3372 font->range = NULL; 3373 font->get_cache_enabled = TRUE; 3374 font->set_cache_enabled = TRUE; 3375 memcpy(&font->props, &src->props, sizeof(font->props)); 3376 if (font->props[FONT_NAME].str) 3377 font->props[FONT_NAME].str = SysAllocString(font->props[FONT_NAME].str); 3378 } 3379 else { 3380 font->range = range; 3381 ITextRange_AddRef(range); 3382 3383 /* cache current properties */ 3384 font->get_cache_enabled = FALSE; 3385 font->set_cache_enabled = FALSE; 3386 textfont_cache_range_props(font); 3387 } 3388 3389 *ret = &font->ITextFont_iface; 3390 return S_OK; 3391 } 3392 3393 /* ITextPara */ 3394 static HRESULT WINAPI TextPara_QueryInterface(ITextPara *iface, REFIID riid, void **ppv) 3395 { 3396 ITextParaImpl *This = impl_from_ITextPara(iface); 3397 3398 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 3399 3400 if (IsEqualIID(riid, &IID_ITextPara) || 3401 IsEqualIID(riid, &IID_IDispatch) || 3402 IsEqualIID(riid, &IID_IUnknown)) 3403 { 3404 *ppv = iface; 3405 ITextPara_AddRef(iface); 3406 return S_OK; 3407 } 3408 3409 *ppv = NULL; 3410 return E_NOINTERFACE; 3411 } 3412 3413 static ULONG WINAPI TextPara_AddRef(ITextPara *iface) 3414 { 3415 ITextParaImpl *This = impl_from_ITextPara(iface); 3416 ULONG ref = InterlockedIncrement(&This->ref); 3417 TRACE("(%p)->(%u)\n", This, ref); 3418 return ref; 3419 } 3420 3421 static ULONG WINAPI TextPara_Release(ITextPara *iface) 3422 { 3423 ITextParaImpl *This = impl_from_ITextPara(iface); 3424 ULONG ref = InterlockedDecrement(&This->ref); 3425 3426 TRACE("(%p)->(%u)\n", This, ref); 3427 3428 if (!ref) 3429 { 3430 ITextRange_Release(This->range); 3431 heap_free(This); 3432 } 3433 3434 return ref; 3435 } 3436 3437 static IRichEditOleImpl *para_get_reole(ITextParaImpl *This) 3438 { 3439 if (This->range) 3440 { 3441 ITextRangeImpl *rng = impl_from_ITextRange(This->range); 3442 return rng->child.reole; 3443 } 3444 return NULL; 3445 } 3446 3447 static HRESULT WINAPI TextPara_GetTypeInfoCount(ITextPara *iface, UINT *pctinfo) 3448 { 3449 ITextParaImpl *This = impl_from_ITextPara(iface); 3450 TRACE("(%p)->(%p)\n", This, pctinfo); 3451 *pctinfo = 1; 3452 return S_OK; 3453 } 3454 3455 static HRESULT WINAPI TextPara_GetTypeInfo(ITextPara *iface, UINT iTInfo, LCID lcid, 3456 ITypeInfo **ppTInfo) 3457 { 3458 ITextParaImpl *This = impl_from_ITextPara(iface); 3459 HRESULT hr; 3460 3461 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 3462 3463 hr = get_typeinfo(ITextPara_tid, ppTInfo); 3464 if (SUCCEEDED(hr)) 3465 ITypeInfo_AddRef(*ppTInfo); 3466 return hr; 3467 } 3468 3469 static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid, 3470 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 3471 { 3472 ITextParaImpl *This = impl_from_ITextPara(iface); 3473 ITypeInfo *ti; 3474 HRESULT hr; 3475 3476 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, 3477 cNames, lcid, rgDispId); 3478 3479 hr = get_typeinfo(ITextPara_tid, &ti); 3480 if (SUCCEEDED(hr)) 3481 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 3482 return hr; 3483 } 3484 3485 static HRESULT WINAPI TextPara_Invoke( 3486 ITextPara *iface, 3487 DISPID dispIdMember, 3488 REFIID riid, 3489 LCID lcid, 3490 WORD wFlags, 3491 DISPPARAMS *pDispParams, 3492 VARIANT *pVarResult, 3493 EXCEPINFO *pExcepInfo, 3494 UINT *puArgErr) 3495 { 3496 ITextParaImpl *This = impl_from_ITextPara(iface); 3497 ITypeInfo *ti; 3498 HRESULT hr; 3499 3500 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, 3501 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, 3502 pExcepInfo, puArgErr); 3503 3504 hr = get_typeinfo(ITextPara_tid, &ti); 3505 if (SUCCEEDED(hr)) 3506 hr = ITypeInfo_Invoke(ti, iface, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 3507 return hr; 3508 } 3509 3510 static HRESULT WINAPI TextPara_GetDuplicate(ITextPara *iface, ITextPara **ret) 3511 { 3512 ITextParaImpl *This = impl_from_ITextPara(iface); 3513 FIXME("(%p)->(%p)\n", This, ret); 3514 3515 if (!para_get_reole(This)) 3516 return CO_E_RELEASED; 3517 3518 return E_NOTIMPL; 3519 } 3520 3521 static HRESULT WINAPI TextPara_SetDuplicate(ITextPara *iface, ITextPara *para) 3522 { 3523 ITextParaImpl *This = impl_from_ITextPara(iface); 3524 FIXME("(%p)->(%p)\n", This, para); 3525 3526 if (!para_get_reole(This)) 3527 return CO_E_RELEASED; 3528 3529 return E_NOTIMPL; 3530 } 3531 3532 static HRESULT WINAPI TextPara_CanChange(ITextPara *iface, LONG *ret) 3533 { 3534 ITextParaImpl *This = impl_from_ITextPara(iface); 3535 FIXME("(%p)->(%p)\n", This, ret); 3536 3537 if (!para_get_reole(This)) 3538 return CO_E_RELEASED; 3539 3540 return E_NOTIMPL; 3541 } 3542 3543 static HRESULT WINAPI TextPara_IsEqual(ITextPara *iface, ITextPara *para, LONG *ret) 3544 { 3545 ITextParaImpl *This = impl_from_ITextPara(iface); 3546 FIXME("(%p)->(%p %p)\n", This, para, ret); 3547 3548 if (!para_get_reole(This)) 3549 return CO_E_RELEASED; 3550 3551 return E_NOTIMPL; 3552 } 3553 3554 static HRESULT WINAPI TextPara_Reset(ITextPara *iface, LONG value) 3555 { 3556 ITextParaImpl *This = impl_from_ITextPara(iface); 3557 FIXME("(%p)->(%d)\n", This, value); 3558 3559 if (!para_get_reole(This)) 3560 return CO_E_RELEASED; 3561 3562 return E_NOTIMPL; 3563 } 3564 3565 static HRESULT WINAPI TextPara_GetStyle(ITextPara *iface, LONG *value) 3566 { 3567 ITextParaImpl *This = impl_from_ITextPara(iface); 3568 FIXME("(%p)->(%p)\n", This, value); 3569 3570 if (!para_get_reole(This)) 3571 return CO_E_RELEASED; 3572 3573 return E_NOTIMPL; 3574 } 3575 3576 static HRESULT WINAPI TextPara_SetStyle(ITextPara *iface, LONG value) 3577 { 3578 ITextParaImpl *This = impl_from_ITextPara(iface); 3579 FIXME("(%p)->(%d)\n", This, value); 3580 3581 if (!para_get_reole(This)) 3582 return CO_E_RELEASED; 3583 3584 return E_NOTIMPL; 3585 } 3586 3587 static HRESULT WINAPI TextPara_GetAlignment(ITextPara *iface, LONG *value) 3588 { 3589 ITextParaImpl *This = impl_from_ITextPara(iface); 3590 static int once; 3591 3592 if (!once++) FIXME("(%p)->(%p)\n", This, value); 3593 3594 if (!para_get_reole(This)) 3595 return CO_E_RELEASED; 3596 3597 return E_NOTIMPL; 3598 } 3599 3600 static HRESULT WINAPI TextPara_SetAlignment(ITextPara *iface, LONG value) 3601 { 3602 ITextParaImpl *This = impl_from_ITextPara(iface); 3603 FIXME("(%p)->(%d)\n", This, value); 3604 3605 if (!para_get_reole(This)) 3606 return CO_E_RELEASED; 3607 3608 return E_NOTIMPL; 3609 } 3610 3611 static HRESULT WINAPI TextPara_GetHyphenation(ITextPara *iface, LONG *value) 3612 { 3613 ITextParaImpl *This = impl_from_ITextPara(iface); 3614 FIXME("(%p)->(%p)\n", This, value); 3615 3616 if (!para_get_reole(This)) 3617 return CO_E_RELEASED; 3618 3619 return E_NOTIMPL; 3620 } 3621 3622 static HRESULT WINAPI TextPara_SetHyphenation(ITextPara *iface, LONG value) 3623 { 3624 ITextParaImpl *This = impl_from_ITextPara(iface); 3625 FIXME("(%p)->(%d)\n", This, value); 3626 3627 if (!para_get_reole(This)) 3628 return CO_E_RELEASED; 3629 3630 return E_NOTIMPL; 3631 } 3632 3633 static HRESULT WINAPI TextPara_GetFirstLineIndent(ITextPara *iface, FLOAT *value) 3634 { 3635 ITextParaImpl *This = impl_from_ITextPara(iface); 3636 FIXME("(%p)->(%p)\n", This, value); 3637 3638 if (!para_get_reole(This)) 3639 return CO_E_RELEASED; 3640 3641 return E_NOTIMPL; 3642 } 3643 3644 static HRESULT WINAPI TextPara_GetKeepTogether(ITextPara *iface, LONG *value) 3645 { 3646 ITextParaImpl *This = impl_from_ITextPara(iface); 3647 FIXME("(%p)->(%p)\n", This, value); 3648 3649 if (!para_get_reole(This)) 3650 return CO_E_RELEASED; 3651 3652 return E_NOTIMPL; 3653 } 3654 3655 static HRESULT WINAPI TextPara_SetKeepTogether(ITextPara *iface, LONG value) 3656 { 3657 ITextParaImpl *This = impl_from_ITextPara(iface); 3658 FIXME("(%p)->(%d)\n", This, value); 3659 3660 if (!para_get_reole(This)) 3661 return CO_E_RELEASED; 3662 3663 return E_NOTIMPL; 3664 } 3665 3666 static HRESULT WINAPI TextPara_GetKeepWithNext(ITextPara *iface, LONG *value) 3667 { 3668 ITextParaImpl *This = impl_from_ITextPara(iface); 3669 FIXME("(%p)->(%p)\n", This, value); 3670 3671 if (!para_get_reole(This)) 3672 return CO_E_RELEASED; 3673 3674 return E_NOTIMPL; 3675 } 3676 3677 static HRESULT WINAPI TextPara_SetKeepWithNext(ITextPara *iface, LONG value) 3678 { 3679 ITextParaImpl *This = impl_from_ITextPara(iface); 3680 FIXME("(%p)->(%d)\n", This, value); 3681 3682 if (!para_get_reole(This)) 3683 return CO_E_RELEASED; 3684 3685 return E_NOTIMPL; 3686 } 3687 3688 static HRESULT WINAPI TextPara_GetLeftIndent(ITextPara *iface, FLOAT *value) 3689 { 3690 ITextParaImpl *This = impl_from_ITextPara(iface); 3691 FIXME("(%p)->(%p)\n", This, value); 3692 3693 if (!para_get_reole(This)) 3694 return CO_E_RELEASED; 3695 3696 return E_NOTIMPL; 3697 } 3698 3699 static HRESULT WINAPI TextPara_GetLineSpacing(ITextPara *iface, FLOAT *value) 3700 { 3701 ITextParaImpl *This = impl_from_ITextPara(iface); 3702 FIXME("(%p)->(%p)\n", This, value); 3703 3704 if (!para_get_reole(This)) 3705 return CO_E_RELEASED; 3706 3707 return E_NOTIMPL; 3708 } 3709 3710 static HRESULT WINAPI TextPara_GetLineSpacingRule(ITextPara *iface, LONG *value) 3711 { 3712 ITextParaImpl *This = impl_from_ITextPara(iface); 3713 FIXME("(%p)->(%p)\n", This, value); 3714 3715 if (!para_get_reole(This)) 3716 return CO_E_RELEASED; 3717 3718 return E_NOTIMPL; 3719 } 3720 3721 static HRESULT WINAPI TextPara_GetListAlignment(ITextPara *iface, LONG *value) 3722 { 3723 ITextParaImpl *This = impl_from_ITextPara(iface); 3724 FIXME("(%p)->(%p)\n", This, value); 3725 3726 if (!para_get_reole(This)) 3727 return CO_E_RELEASED; 3728 3729 return E_NOTIMPL; 3730 } 3731 3732 static HRESULT WINAPI TextPara_SetListAlignment(ITextPara *iface, LONG value) 3733 { 3734 ITextParaImpl *This = impl_from_ITextPara(iface); 3735 FIXME("(%p)->(%d)\n", This, value); 3736 3737 if (!para_get_reole(This)) 3738 return CO_E_RELEASED; 3739 3740 return E_NOTIMPL; 3741 } 3742 3743 static HRESULT WINAPI TextPara_GetListLevelIndex(ITextPara *iface, LONG *value) 3744 { 3745 ITextParaImpl *This = impl_from_ITextPara(iface); 3746 FIXME("(%p)->(%p)\n", This, value); 3747 3748 if (!para_get_reole(This)) 3749 return CO_E_RELEASED; 3750 3751 return E_NOTIMPL; 3752 } 3753 3754 static HRESULT WINAPI TextPara_SetListLevelIndex(ITextPara *iface, LONG value) 3755 { 3756 ITextParaImpl *This = impl_from_ITextPara(iface); 3757 FIXME("(%p)->(%d)\n", This, value); 3758 3759 if (!para_get_reole(This)) 3760 return CO_E_RELEASED; 3761 3762 return E_NOTIMPL; 3763 } 3764 3765 static HRESULT WINAPI TextPara_GetListStart(ITextPara *iface, LONG *value) 3766 { 3767 ITextParaImpl *This = impl_from_ITextPara(iface); 3768 FIXME("(%p)->(%p)\n", This, value); 3769 3770 if (!para_get_reole(This)) 3771 return CO_E_RELEASED; 3772 3773 return E_NOTIMPL; 3774 } 3775 3776 static HRESULT WINAPI TextPara_SetListStart(ITextPara *iface, LONG value) 3777 { 3778 ITextParaImpl *This = impl_from_ITextPara(iface); 3779 FIXME("(%p)->(%d)\n", This, value); 3780 3781 if (!para_get_reole(This)) 3782 return CO_E_RELEASED; 3783 3784 return E_NOTIMPL; 3785 } 3786 3787 static HRESULT WINAPI TextPara_GetListTab(ITextPara *iface, FLOAT *value) 3788 { 3789 ITextParaImpl *This = impl_from_ITextPara(iface); 3790 FIXME("(%p)->(%p)\n", This, value); 3791 3792 if (!para_get_reole(This)) 3793 return CO_E_RELEASED; 3794 3795 return E_NOTIMPL; 3796 } 3797 3798 static HRESULT WINAPI TextPara_SetListTab(ITextPara *iface, FLOAT value) 3799 { 3800 ITextParaImpl *This = impl_from_ITextPara(iface); 3801 FIXME("(%p)->(%.2f)\n", This, value); 3802 3803 if (!para_get_reole(This)) 3804 return CO_E_RELEASED; 3805 3806 return E_NOTIMPL; 3807 } 3808 3809 static HRESULT WINAPI TextPara_GetListType(ITextPara *iface, LONG *value) 3810 { 3811 ITextParaImpl *This = impl_from_ITextPara(iface); 3812 FIXME("(%p)->(%p)\n", This, value); 3813 3814 if (!para_get_reole(This)) 3815 return CO_E_RELEASED; 3816 3817 return E_NOTIMPL; 3818 } 3819 3820 static HRESULT WINAPI TextPara_SetListType(ITextPara *iface, LONG value) 3821 { 3822 ITextParaImpl *This = impl_from_ITextPara(iface); 3823 FIXME("(%p)->(%d)\n", This, value); 3824 3825 if (!para_get_reole(This)) 3826 return CO_E_RELEASED; 3827 3828 return E_NOTIMPL; 3829 } 3830 3831 static HRESULT WINAPI TextPara_GetNoLineNumber(ITextPara *iface, LONG *value) 3832 { 3833 ITextParaImpl *This = impl_from_ITextPara(iface); 3834 FIXME("(%p)->(%p)\n", This, value); 3835 3836 if (!para_get_reole(This)) 3837 return CO_E_RELEASED; 3838 3839 return E_NOTIMPL; 3840 } 3841 3842 static HRESULT WINAPI TextPara_SetNoLineNumber(ITextPara *iface, LONG value) 3843 { 3844 ITextParaImpl *This = impl_from_ITextPara(iface); 3845 FIXME("(%p)->(%d)\n", This, value); 3846 3847 if (!para_get_reole(This)) 3848 return CO_E_RELEASED; 3849 3850 return E_NOTIMPL; 3851 } 3852 3853 static HRESULT WINAPI TextPara_GetPageBreakBefore(ITextPara *iface, LONG *value) 3854 { 3855 ITextParaImpl *This = impl_from_ITextPara(iface); 3856 FIXME("(%p)->(%p)\n", This, value); 3857 3858 if (!para_get_reole(This)) 3859 return CO_E_RELEASED; 3860 3861 return E_NOTIMPL; 3862 } 3863 3864 static HRESULT WINAPI TextPara_SetPageBreakBefore(ITextPara *iface, LONG value) 3865 { 3866 ITextParaImpl *This = impl_from_ITextPara(iface); 3867 FIXME("(%p)->(%d)\n", This, value); 3868 3869 if (!para_get_reole(This)) 3870 return CO_E_RELEASED; 3871 3872 return E_NOTIMPL; 3873 } 3874 3875 static HRESULT WINAPI TextPara_GetRightIndent(ITextPara *iface, FLOAT *value) 3876 { 3877 ITextParaImpl *This = impl_from_ITextPara(iface); 3878 FIXME("(%p)->(%p)\n", This, value); 3879 3880 if (!para_get_reole(This)) 3881 return CO_E_RELEASED; 3882 3883 return E_NOTIMPL; 3884 } 3885 3886 static HRESULT WINAPI TextPara_SetRightIndent(ITextPara *iface, FLOAT value) 3887 { 3888 ITextParaImpl *This = impl_from_ITextPara(iface); 3889 FIXME("(%p)->(%.2f)\n", This, value); 3890 3891 if (!para_get_reole(This)) 3892 return CO_E_RELEASED; 3893 3894 return E_NOTIMPL; 3895 } 3896 3897 static HRESULT WINAPI TextPara_SetIndents(ITextPara *iface, FLOAT StartIndent, FLOAT LeftIndent, FLOAT RightIndent) 3898 { 3899 ITextParaImpl *This = impl_from_ITextPara(iface); 3900 FIXME("(%p)->(%.2f %.2f %.2f)\n", This, StartIndent, LeftIndent, RightIndent); 3901 3902 if (!para_get_reole(This)) 3903 return CO_E_RELEASED; 3904 3905 return E_NOTIMPL; 3906 } 3907 3908 static HRESULT WINAPI TextPara_SetLineSpacing(ITextPara *iface, LONG LineSpacingRule, FLOAT LineSpacing) 3909 { 3910 ITextParaImpl *This = impl_from_ITextPara(iface); 3911 FIXME("(%p)->(%d %.2f)\n", This, LineSpacingRule, LineSpacing); 3912 3913 if (!para_get_reole(This)) 3914 return CO_E_RELEASED; 3915 3916 return E_NOTIMPL; 3917 } 3918 3919 static HRESULT WINAPI TextPara_GetSpaceAfter(ITextPara *iface, FLOAT *value) 3920 { 3921 ITextParaImpl *This = impl_from_ITextPara(iface); 3922 FIXME("(%p)->(%p)\n", This, value); 3923 3924 if (!para_get_reole(This)) 3925 return CO_E_RELEASED; 3926 3927 return E_NOTIMPL; 3928 } 3929 3930 static HRESULT WINAPI TextPara_SetSpaceAfter(ITextPara *iface, FLOAT value) 3931 { 3932 ITextParaImpl *This = impl_from_ITextPara(iface); 3933 FIXME("(%p)->(%.2f)\n", This, value); 3934 3935 if (!para_get_reole(This)) 3936 return CO_E_RELEASED; 3937 3938 return E_NOTIMPL; 3939 } 3940 3941 static HRESULT WINAPI TextPara_GetSpaceBefore(ITextPara *iface, FLOAT *value) 3942 { 3943 ITextParaImpl *This = impl_from_ITextPara(iface); 3944 FIXME("(%p)->(%p)\n", This, value); 3945 3946 if (!para_get_reole(This)) 3947 return CO_E_RELEASED; 3948 3949 return E_NOTIMPL; 3950 } 3951 3952 static HRESULT WINAPI TextPara_SetSpaceBefore(ITextPara *iface, FLOAT value) 3953 { 3954 ITextParaImpl *This = impl_from_ITextPara(iface); 3955 FIXME("(%p)->(%.2f)\n", This, value); 3956 3957 if (!para_get_reole(This)) 3958 return CO_E_RELEASED; 3959 3960 return E_NOTIMPL; 3961 } 3962 3963 static HRESULT WINAPI TextPara_GetWidowControl(ITextPara *iface, LONG *value) 3964 { 3965 ITextParaImpl *This = impl_from_ITextPara(iface); 3966 FIXME("(%p)->(%p)\n", This, value); 3967 3968 if (!para_get_reole(This)) 3969 return CO_E_RELEASED; 3970 3971 return E_NOTIMPL; 3972 } 3973 3974 static HRESULT WINAPI TextPara_SetWidowControl(ITextPara *iface, LONG value) 3975 { 3976 ITextParaImpl *This = impl_from_ITextPara(iface); 3977 FIXME("(%p)->(%d)\n", This, value); 3978 3979 if (!para_get_reole(This)) 3980 return CO_E_RELEASED; 3981 3982 return E_NOTIMPL; 3983 } 3984 3985 static HRESULT WINAPI TextPara_GetTabCount(ITextPara *iface, LONG *value) 3986 { 3987 ITextParaImpl *This = impl_from_ITextPara(iface); 3988 FIXME("(%p)->(%p)\n", This, value); 3989 3990 if (!para_get_reole(This)) 3991 return CO_E_RELEASED; 3992 3993 return E_NOTIMPL; 3994 } 3995 3996 static HRESULT WINAPI TextPara_AddTab(ITextPara *iface, FLOAT tbPos, LONG tbAlign, LONG tbLeader) 3997 { 3998 ITextParaImpl *This = impl_from_ITextPara(iface); 3999 FIXME("(%p)->(%.2f %d %d)\n", This, tbPos, tbAlign, tbLeader); 4000 4001 if (!para_get_reole(This)) 4002 return CO_E_RELEASED; 4003 4004 return E_NOTIMPL; 4005 } 4006 4007 static HRESULT WINAPI TextPara_ClearAllTabs(ITextPara *iface) 4008 { 4009 ITextParaImpl *This = impl_from_ITextPara(iface); 4010 FIXME("(%p)\n", This); 4011 4012 if (!para_get_reole(This)) 4013 return CO_E_RELEASED; 4014 4015 return E_NOTIMPL; 4016 } 4017 4018 static HRESULT WINAPI TextPara_DeleteTab(ITextPara *iface, FLOAT pos) 4019 { 4020 ITextParaImpl *This = impl_from_ITextPara(iface); 4021 FIXME("(%p)->(%.2f)\n", This, pos); 4022 4023 if (!para_get_reole(This)) 4024 return CO_E_RELEASED; 4025 4026 return E_NOTIMPL; 4027 } 4028 4029 static HRESULT WINAPI TextPara_GetTab(ITextPara *iface, LONG iTab, FLOAT *ptbPos, LONG *ptbAlign, LONG *ptbLeader) 4030 { 4031 ITextParaImpl *This = impl_from_ITextPara(iface); 4032 FIXME("(%p)->(%d %p %p %p)\n", This, iTab, ptbPos, ptbAlign, ptbLeader); 4033 4034 if (!para_get_reole(This)) 4035 return CO_E_RELEASED; 4036 4037 return E_NOTIMPL; 4038 } 4039 4040 static ITextParaVtbl textparavtbl = { 4041 TextPara_QueryInterface, 4042 TextPara_AddRef, 4043 TextPara_Release, 4044 TextPara_GetTypeInfoCount, 4045 TextPara_GetTypeInfo, 4046 TextPara_GetIDsOfNames, 4047 TextPara_Invoke, 4048 TextPara_GetDuplicate, 4049 TextPara_SetDuplicate, 4050 TextPara_CanChange, 4051 TextPara_IsEqual, 4052 TextPara_Reset, 4053 TextPara_GetStyle, 4054 TextPara_SetStyle, 4055 TextPara_GetAlignment, 4056 TextPara_SetAlignment, 4057 TextPara_GetHyphenation, 4058 TextPara_SetHyphenation, 4059 TextPara_GetFirstLineIndent, 4060 TextPara_GetKeepTogether, 4061 TextPara_SetKeepTogether, 4062 TextPara_GetKeepWithNext, 4063 TextPara_SetKeepWithNext, 4064 TextPara_GetLeftIndent, 4065 TextPara_GetLineSpacing, 4066 TextPara_GetLineSpacingRule, 4067 TextPara_GetListAlignment, 4068 TextPara_SetListAlignment, 4069 TextPara_GetListLevelIndex, 4070 TextPara_SetListLevelIndex, 4071 TextPara_GetListStart, 4072 TextPara_SetListStart, 4073 TextPara_GetListTab, 4074 TextPara_SetListTab, 4075 TextPara_GetListType, 4076 TextPara_SetListType, 4077 TextPara_GetNoLineNumber, 4078 TextPara_SetNoLineNumber, 4079 TextPara_GetPageBreakBefore, 4080 TextPara_SetPageBreakBefore, 4081 TextPara_GetRightIndent, 4082 TextPara_SetRightIndent, 4083 TextPara_SetIndents, 4084 TextPara_SetLineSpacing, 4085 TextPara_GetSpaceAfter, 4086 TextPara_SetSpaceAfter, 4087 TextPara_GetSpaceBefore, 4088 TextPara_SetSpaceBefore, 4089 TextPara_GetWidowControl, 4090 TextPara_SetWidowControl, 4091 TextPara_GetTabCount, 4092 TextPara_AddTab, 4093 TextPara_ClearAllTabs, 4094 TextPara_DeleteTab, 4095 TextPara_GetTab 4096 }; 4097 4098 static HRESULT create_textpara(ITextRange *range, ITextPara **ret) 4099 { 4100 ITextParaImpl *para; 4101 4102 *ret = NULL; 4103 para = heap_alloc(sizeof(*para)); 4104 if (!para) 4105 return E_OUTOFMEMORY; 4106 4107 para->ITextPara_iface.lpVtbl = &textparavtbl; 4108 para->ref = 1; 4109 para->range = range; 4110 ITextRange_AddRef(range); 4111 4112 *ret = ¶->ITextPara_iface; 4113 return S_OK; 4114 } 4115 4116 /* ITextDocument */ 4117 static HRESULT WINAPI 4118 ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid, 4119 void** ppvObject) 4120 { 4121 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4122 return IRichEditOle_QueryInterface(&This->IRichEditOle_iface, riid, ppvObject); 4123 } 4124 4125 static ULONG WINAPI 4126 ITextDocument_fnAddRef(ITextDocument* me) 4127 { 4128 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4129 return IRichEditOle_AddRef(&This->IRichEditOle_iface); 4130 } 4131 4132 static ULONG WINAPI 4133 ITextDocument_fnRelease(ITextDocument* me) 4134 { 4135 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4136 return IRichEditOle_Release(&This->IRichEditOle_iface); 4137 } 4138 4139 static HRESULT WINAPI 4140 ITextDocument_fnGetTypeInfoCount(ITextDocument* me, 4141 UINT* pctinfo) 4142 { 4143 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4144 TRACE("(%p)->(%p)\n", This, pctinfo); 4145 *pctinfo = 1; 4146 return S_OK; 4147 } 4148 4149 static HRESULT WINAPI 4150 ITextDocument_fnGetTypeInfo(ITextDocument* me, UINT iTInfo, LCID lcid, 4151 ITypeInfo** ppTInfo) 4152 { 4153 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4154 HRESULT hr; 4155 4156 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 4157 4158 hr = get_typeinfo(ITextDocument_tid, ppTInfo); 4159 if (SUCCEEDED(hr)) 4160 ITypeInfo_AddRef(*ppTInfo); 4161 return hr; 4162 } 4163 4164 static HRESULT WINAPI 4165 ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid, 4166 LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) 4167 { 4168 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4169 ITypeInfo *ti; 4170 HRESULT hr; 4171 4172 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), 4173 rgszNames, cNames, lcid, rgDispId); 4174 4175 hr = get_typeinfo(ITextDocument_tid, &ti); 4176 if (SUCCEEDED(hr)) 4177 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 4178 return hr; 4179 } 4180 4181 static HRESULT WINAPI 4182 ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember, 4183 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, 4184 VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) 4185 { 4186 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4187 ITypeInfo *ti; 4188 HRESULT hr; 4189 4190 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, 4191 debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, 4192 pExcepInfo, puArgErr); 4193 4194 hr = get_typeinfo(ITextDocument_tid, &ti); 4195 if (SUCCEEDED(hr)) 4196 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 4197 return hr; 4198 } 4199 4200 static HRESULT WINAPI 4201 ITextDocument_fnGetName(ITextDocument* me, BSTR* pName) 4202 { 4203 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4204 FIXME("stub %p\n",This); 4205 return E_NOTIMPL; 4206 } 4207 4208 static HRESULT WINAPI 4209 ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **selection) 4210 { 4211 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4212 4213 TRACE("(%p)->(%p)\n", me, selection); 4214 4215 if (!selection) 4216 return E_INVALIDARG; 4217 4218 if (!This->txtSel) { 4219 This->txtSel = CreateTextSelection(This); 4220 if (!This->txtSel) { 4221 *selection = NULL; 4222 return E_OUTOFMEMORY; 4223 } 4224 } 4225 4226 *selection = &This->txtSel->ITextSelection_iface; 4227 ITextSelection_AddRef(*selection); 4228 return S_OK; 4229 } 4230 4231 static HRESULT WINAPI 4232 ITextDocument_fnGetStoryCount(ITextDocument* me, LONG* pCount) 4233 { 4234 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4235 FIXME("stub %p\n",This); 4236 return E_NOTIMPL; 4237 } 4238 4239 static HRESULT WINAPI 4240 ITextDocument_fnGetStoryRanges(ITextDocument* me, 4241 ITextStoryRanges** ppStories) 4242 { 4243 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4244 FIXME("stub %p\n",This); 4245 return E_NOTIMPL; 4246 } 4247 4248 static HRESULT WINAPI 4249 ITextDocument_fnGetSaved(ITextDocument* me, LONG* pValue) 4250 { 4251 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4252 FIXME("stub %p\n",This); 4253 return E_NOTIMPL; 4254 } 4255 4256 static HRESULT WINAPI 4257 ITextDocument_fnSetSaved(ITextDocument* me, LONG Value) 4258 { 4259 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4260 FIXME("stub %p\n",This); 4261 return E_NOTIMPL; 4262 } 4263 4264 static HRESULT WINAPI 4265 ITextDocument_fnGetDefaultTabStop(ITextDocument* me, float* pValue) 4266 { 4267 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4268 FIXME("stub %p\n",This); 4269 return E_NOTIMPL; 4270 } 4271 4272 static HRESULT WINAPI 4273 ITextDocument_fnSetDefaultTabStop(ITextDocument* me, float Value) 4274 { 4275 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4276 FIXME("stub %p\n",This); 4277 return E_NOTIMPL; 4278 } 4279 4280 static HRESULT WINAPI 4281 ITextDocument_fnNew(ITextDocument* me) 4282 { 4283 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4284 FIXME("stub %p\n",This); 4285 return E_NOTIMPL; 4286 } 4287 4288 static HRESULT WINAPI 4289 ITextDocument_fnOpen(ITextDocument* me, VARIANT* pVar, LONG Flags, 4290 LONG CodePage) 4291 { 4292 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4293 FIXME("stub %p\n",This); 4294 return E_NOTIMPL; 4295 } 4296 4297 static HRESULT WINAPI 4298 ITextDocument_fnSave(ITextDocument* me, VARIANT* pVar, LONG Flags, 4299 LONG CodePage) 4300 { 4301 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4302 FIXME("stub %p\n",This); 4303 return E_NOTIMPL; 4304 } 4305 4306 static HRESULT WINAPI 4307 ITextDocument_fnFreeze(ITextDocument* me, LONG* pCount) 4308 { 4309 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4310 FIXME("stub %p\n",This); 4311 return E_NOTIMPL; 4312 } 4313 4314 static HRESULT WINAPI 4315 ITextDocument_fnUnfreeze(ITextDocument* me, LONG* pCount) 4316 { 4317 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4318 FIXME("stub %p\n",This); 4319 return E_NOTIMPL; 4320 } 4321 4322 static HRESULT WINAPI 4323 ITextDocument_fnBeginEditCollection(ITextDocument* me) 4324 { 4325 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4326 FIXME("stub %p\n",This); 4327 return E_NOTIMPL; 4328 } 4329 4330 static HRESULT WINAPI 4331 ITextDocument_fnEndEditCollection(ITextDocument* me) 4332 { 4333 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4334 FIXME("stub %p\n",This); 4335 return E_NOTIMPL; 4336 } 4337 4338 static HRESULT WINAPI 4339 ITextDocument_fnUndo(ITextDocument* me, LONG Count, LONG* prop) 4340 { 4341 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4342 FIXME("stub %p\n",This); 4343 return E_NOTIMPL; 4344 } 4345 4346 static HRESULT WINAPI 4347 ITextDocument_fnRedo(ITextDocument* me, LONG Count, LONG* prop) 4348 { 4349 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4350 FIXME("stub %p\n",This); 4351 return E_NOTIMPL; 4352 } 4353 4354 static HRESULT CreateITextRange(IRichEditOleImpl *reOle, LONG start, LONG end, ITextRange** ppRange) 4355 { 4356 ITextRangeImpl *txtRge = heap_alloc(sizeof(ITextRangeImpl)); 4357 4358 if (!txtRge) 4359 return E_OUTOFMEMORY; 4360 txtRge->ITextRange_iface.lpVtbl = &trvt; 4361 txtRge->ref = 1; 4362 txtRge->child.reole = reOle; 4363 txtRge->start = start; 4364 txtRge->end = end; 4365 list_add_head(&reOle->rangelist, &txtRge->child.entry); 4366 *ppRange = &txtRge->ITextRange_iface; 4367 return S_OK; 4368 } 4369 4370 static HRESULT WINAPI 4371 ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2, 4372 ITextRange** ppRange) 4373 { 4374 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4375 4376 TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2); 4377 if (!ppRange) 4378 return E_INVALIDARG; 4379 4380 cp2range(This->editor, &cp1, &cp2); 4381 return CreateITextRange(This, cp1, cp2, ppRange); 4382 } 4383 4384 static HRESULT WINAPI 4385 ITextDocument_fnRangeFromPoint(ITextDocument* me, LONG x, LONG y, 4386 ITextRange** ppRange) 4387 { 4388 IRichEditOleImpl *This = impl_from_ITextDocument(me); 4389 FIXME("stub %p\n",This); 4390 return E_NOTIMPL; 4391 } 4392 4393 static const ITextDocumentVtbl tdvt = { 4394 ITextDocument_fnQueryInterface, 4395 ITextDocument_fnAddRef, 4396 ITextDocument_fnRelease, 4397 ITextDocument_fnGetTypeInfoCount, 4398 ITextDocument_fnGetTypeInfo, 4399 ITextDocument_fnGetIDsOfNames, 4400 ITextDocument_fnInvoke, 4401 ITextDocument_fnGetName, 4402 ITextDocument_fnGetSelection, 4403 ITextDocument_fnGetStoryCount, 4404 ITextDocument_fnGetStoryRanges, 4405 ITextDocument_fnGetSaved, 4406 ITextDocument_fnSetSaved, 4407 ITextDocument_fnGetDefaultTabStop, 4408 ITextDocument_fnSetDefaultTabStop, 4409 ITextDocument_fnNew, 4410 ITextDocument_fnOpen, 4411 ITextDocument_fnSave, 4412 ITextDocument_fnFreeze, 4413 ITextDocument_fnUnfreeze, 4414 ITextDocument_fnBeginEditCollection, 4415 ITextDocument_fnEndEditCollection, 4416 ITextDocument_fnUndo, 4417 ITextDocument_fnRedo, 4418 ITextDocument_fnRange, 4419 ITextDocument_fnRangeFromPoint 4420 }; 4421 4422 /* ITextSelection */ 4423 static HRESULT WINAPI ITextSelection_fnQueryInterface( 4424 ITextSelection *me, 4425 REFIID riid, 4426 void **ppvObj) 4427 { 4428 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4429 4430 *ppvObj = NULL; 4431 if (IsEqualGUID(riid, &IID_IUnknown) 4432 || IsEqualGUID(riid, &IID_IDispatch) 4433 || IsEqualGUID(riid, &IID_ITextRange) 4434 || IsEqualGUID(riid, &IID_ITextSelection)) 4435 { 4436 *ppvObj = me; 4437 ITextSelection_AddRef(me); 4438 return S_OK; 4439 } 4440 else if (IsEqualGUID(riid, &IID_Igetrichole)) 4441 { 4442 *ppvObj = This->reOle; 4443 return S_OK; 4444 } 4445 4446 return E_NOINTERFACE; 4447 } 4448 4449 static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *me) 4450 { 4451 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4452 return InterlockedIncrement(&This->ref); 4453 } 4454 4455 static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *me) 4456 { 4457 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4458 ULONG ref = InterlockedDecrement(&This->ref); 4459 if (ref == 0) 4460 heap_free(This); 4461 return ref; 4462 } 4463 4464 static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *me, UINT *pctinfo) 4465 { 4466 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4467 TRACE("(%p)->(%p)\n", This, pctinfo); 4468 *pctinfo = 1; 4469 return S_OK; 4470 } 4471 4472 static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *me, UINT iTInfo, LCID lcid, 4473 ITypeInfo **ppTInfo) 4474 { 4475 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4476 HRESULT hr; 4477 4478 TRACE("(%p)->(%u,%d,%p)\n", This, iTInfo, lcid, ppTInfo); 4479 4480 hr = get_typeinfo(ITextSelection_tid, ppTInfo); 4481 if (SUCCEEDED(hr)) 4482 ITypeInfo_AddRef(*ppTInfo); 4483 return hr; 4484 } 4485 4486 static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID riid, 4487 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 4488 { 4489 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4490 ITypeInfo *ti; 4491 HRESULT hr; 4492 4493 TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, 4494 rgDispId); 4495 4496 hr = get_typeinfo(ITextSelection_tid, &ti); 4497 if (SUCCEEDED(hr)) 4498 hr = ITypeInfo_GetIDsOfNames(ti, rgszNames, cNames, rgDispId); 4499 return hr; 4500 } 4501 4502 static HRESULT WINAPI ITextSelection_fnInvoke( 4503 ITextSelection *me, 4504 DISPID dispIdMember, 4505 REFIID riid, 4506 LCID lcid, 4507 WORD wFlags, 4508 DISPPARAMS *pDispParams, 4509 VARIANT *pVarResult, 4510 EXCEPINFO *pExcepInfo, 4511 UINT *puArgErr) 4512 { 4513 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4514 ITypeInfo *ti; 4515 HRESULT hr; 4516 4517 TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, 4518 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 4519 4520 hr = get_typeinfo(ITextSelection_tid, &ti); 4521 if (SUCCEEDED(hr)) 4522 hr = ITypeInfo_Invoke(ti, me, dispIdMember, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 4523 return hr; 4524 } 4525 4526 /*** ITextRange methods ***/ 4527 static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *me, BSTR *pbstr) 4528 { 4529 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4530 ME_Cursor *start = NULL, *end = NULL; 4531 int nChars, endOfs; 4532 BOOL bEOP; 4533 4534 TRACE("(%p)->(%p)\n", This, pbstr); 4535 4536 if (!This->reOle) 4537 return CO_E_RELEASED; 4538 4539 if (!pbstr) 4540 return E_INVALIDARG; 4541 4542 ME_GetSelection(This->reOle->editor, &start, &end); 4543 endOfs = ME_GetCursorOfs(end); 4544 nChars = endOfs - ME_GetCursorOfs(start); 4545 if (!nChars) 4546 { 4547 *pbstr = NULL; 4548 return S_OK; 4549 } 4550 4551 *pbstr = SysAllocStringLen(NULL, nChars); 4552 if (!*pbstr) 4553 return E_OUTOFMEMORY; 4554 4555 bEOP = (end->pRun->next->type == diTextEnd && endOfs > ME_GetTextLength(This->reOle->editor)); 4556 ME_GetTextW(This->reOle->editor, *pbstr, nChars, start, nChars, FALSE, bEOP); 4557 TRACE("%s\n", wine_dbgstr_w(*pbstr)); 4558 4559 return S_OK; 4560 } 4561 4562 static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *me, BSTR str) 4563 { 4564 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4565 ME_TextEditor *editor; 4566 int len, to, from; 4567 4568 TRACE("(%p)->(%s)\n", This, debugstr_w(str)); 4569 4570 if (!This->reOle) 4571 return CO_E_RELEASED; 4572 4573 editor = This->reOle->editor; 4574 len = strlenW(str); 4575 ME_GetSelectionOfs(editor, &from, &to); 4576 ME_ReplaceSel(editor, FALSE, str, len); 4577 4578 if (len < to - from) 4579 textranges_update_ranges(This->reOle, from, len, RANGE_UPDATE_DELETE); 4580 4581 return S_OK; 4582 } 4583 4584 static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *me, LONG *pch) 4585 { 4586 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4587 ME_Cursor *start = NULL, *end = NULL; 4588 4589 TRACE("(%p)->(%p)\n", This, pch); 4590 4591 if (!This->reOle) 4592 return CO_E_RELEASED; 4593 4594 if (!pch) 4595 return E_INVALIDARG; 4596 4597 ME_GetSelection(This->reOle->editor, &start, &end); 4598 return range_GetChar(This->reOle->editor, start, pch); 4599 } 4600 4601 static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *me, LONG ch) 4602 { 4603 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4604 4605 FIXME("(%p)->(%x): stub\n", This, ch); 4606 4607 if (!This->reOle) 4608 return CO_E_RELEASED; 4609 4610 return E_NOTIMPL; 4611 } 4612 4613 static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *me, ITextRange **range) 4614 { 4615 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4616 LONG start, end; 4617 4618 TRACE("(%p)->(%p)\n", This, range); 4619 4620 if (!This->reOle) 4621 return CO_E_RELEASED; 4622 4623 if (!range) 4624 return E_INVALIDARG; 4625 4626 ITextSelection_GetStart(me, &start); 4627 ITextSelection_GetEnd(me, &end); 4628 return CreateITextRange(This->reOle, start, end, range); 4629 } 4630 4631 static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *me, ITextRange **range) 4632 { 4633 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4634 4635 FIXME("(%p)->(%p): stub\n", This, range); 4636 4637 if (!This->reOle) 4638 return CO_E_RELEASED; 4639 4640 return E_NOTIMPL; 4641 } 4642 4643 static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *me, ITextRange *range) 4644 { 4645 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4646 4647 FIXME("(%p)->(%p): stub\n", This, range); 4648 4649 if (!This->reOle) 4650 return CO_E_RELEASED; 4651 4652 FIXME("not implemented\n"); 4653 return E_NOTIMPL; 4654 } 4655 4656 static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *me, LONG *pcpFirst) 4657 { 4658 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4659 LONG lim; 4660 4661 TRACE("(%p)->(%p)\n", This, pcpFirst); 4662 4663 if (!This->reOle) 4664 return CO_E_RELEASED; 4665 4666 if (!pcpFirst) 4667 return E_INVALIDARG; 4668 ME_GetSelectionOfs(This->reOle->editor, pcpFirst, &lim); 4669 return S_OK; 4670 } 4671 4672 static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *me, LONG value) 4673 { 4674 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4675 LONG start, end; 4676 HRESULT hr; 4677 4678 TRACE("(%p)->(%d)\n", This, value); 4679 4680 if (!This->reOle) 4681 return CO_E_RELEASED; 4682 4683 ME_GetSelectionOfs(This->reOle->editor, &start, &end); 4684 hr = textrange_setstart(This->reOle, value, &start, &end); 4685 if (hr == S_OK) 4686 ME_SetSelection(This->reOle->editor, start, end); 4687 4688 return hr; 4689 } 4690 4691 static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *me, LONG *pcpLim) 4692 { 4693 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4694 LONG first; 4695 4696 TRACE("(%p)->(%p)\n", This, pcpLim); 4697 4698 if (!This->reOle) 4699 return CO_E_RELEASED; 4700 4701 if (!pcpLim) 4702 return E_INVALIDARG; 4703 ME_GetSelectionOfs(This->reOle->editor, &first, pcpLim); 4704 return S_OK; 4705 } 4706 4707 static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *me, LONG value) 4708 { 4709 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4710 LONG start, end; 4711 HRESULT hr; 4712 4713 TRACE("(%p)->(%d)\n", This, value); 4714 4715 if (!This->reOle) 4716 return CO_E_RELEASED; 4717 4718 ME_GetSelectionOfs(This->reOle->editor, &start, &end); 4719 hr = textrange_setend(This->reOle, value, &start, &end); 4720 if (hr == S_OK) 4721 ME_SetSelection(This->reOle->editor, start, end); 4722 4723 return hr; 4724 } 4725 4726 static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *me, ITextFont **font) 4727 { 4728 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4729 ITextRange *range = NULL; 4730 HRESULT hr; 4731 4732 TRACE("(%p)->(%p)\n", This, font); 4733 4734 if (!This->reOle) 4735 return CO_E_RELEASED; 4736 4737 if (!font) 4738 return E_INVALIDARG; 4739 4740 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); 4741 hr = create_textfont(range, NULL, font); 4742 ITextRange_Release(range); 4743 return hr; 4744 } 4745 4746 static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *me, ITextFont *font) 4747 { 4748 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4749 ITextRange *range = NULL; 4750 4751 TRACE("(%p)->(%p)\n", This, font); 4752 4753 if (!font) 4754 return E_INVALIDARG; 4755 4756 if (!This->reOle) 4757 return CO_E_RELEASED; 4758 4759 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); 4760 textrange_set_font(range, font); 4761 ITextRange_Release(range); 4762 return S_OK; 4763 } 4764 4765 static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *me, ITextPara **para) 4766 { 4767 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4768 ITextRange *range = NULL; 4769 HRESULT hr; 4770 4771 TRACE("(%p)->(%p)\n", This, para); 4772 4773 if (!This->reOle) 4774 return CO_E_RELEASED; 4775 4776 if (!para) 4777 return E_INVALIDARG; 4778 4779 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); 4780 hr = create_textpara(range, para); 4781 ITextRange_Release(range); 4782 return hr; 4783 } 4784 4785 static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *me, ITextPara *para) 4786 { 4787 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4788 4789 FIXME("(%p)->(%p): stub\n", This, para); 4790 4791 if (!This->reOle) 4792 return CO_E_RELEASED; 4793 4794 FIXME("not implemented\n"); 4795 return E_NOTIMPL; 4796 } 4797 4798 static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *me, LONG *length) 4799 { 4800 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4801 4802 TRACE("(%p)->(%p)\n", This, length); 4803 4804 if (!This->reOle) 4805 return CO_E_RELEASED; 4806 4807 return textrange_get_storylength(This->reOle->editor, length); 4808 } 4809 4810 static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *me, LONG *value) 4811 { 4812 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4813 4814 TRACE("(%p)->(%p)\n", This, value); 4815 4816 if (!This->reOle) 4817 return CO_E_RELEASED; 4818 4819 if (!value) 4820 return E_INVALIDARG; 4821 4822 *value = tomUnknownStory; 4823 return S_OK; 4824 } 4825 4826 static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *me, LONG bStart) 4827 { 4828 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4829 LONG start, end; 4830 HRESULT hres; 4831 4832 TRACE("(%p)->(%d)\n", This, bStart); 4833 4834 if (!This->reOle) 4835 return CO_E_RELEASED; 4836 4837 ME_GetSelectionOfs(This->reOle->editor, &start, &end); 4838 hres = range_Collapse(bStart, &start, &end); 4839 if (SUCCEEDED(hres)) 4840 ME_SetSelection(This->reOle->editor, start, end); 4841 return hres; 4842 } 4843 4844 static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *me, LONG unit, LONG *delta) 4845 { 4846 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4847 ITextRange *range = NULL; 4848 HRESULT hr; 4849 4850 TRACE("(%p)->(%d %p)\n", This, unit, delta); 4851 4852 if (!This->reOle) 4853 return CO_E_RELEASED; 4854 4855 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); 4856 hr = textrange_expand(range, unit, delta); 4857 ITextRange_Release(range); 4858 return hr; 4859 } 4860 4861 static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *me, LONG unit, LONG *index) 4862 { 4863 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4864 4865 FIXME("(%p)->(%d %p): stub\n", This, unit, index); 4866 4867 if (!This->reOle) 4868 return CO_E_RELEASED; 4869 4870 return E_NOTIMPL; 4871 } 4872 4873 static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *me, LONG unit, LONG index, 4874 LONG extend) 4875 { 4876 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4877 4878 FIXME("(%p)->(%d %d %d): stub\n", This, unit, index, extend); 4879 4880 if (!This->reOle) 4881 return CO_E_RELEASED; 4882 4883 return E_NOTIMPL; 4884 } 4885 4886 static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *me, LONG anchor, LONG active) 4887 { 4888 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4889 4890 FIXME("(%p)->(%d %d): stub\n", This, anchor, active); 4891 4892 if (!This->reOle) 4893 return CO_E_RELEASED; 4894 4895 return E_NOTIMPL; 4896 } 4897 4898 static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *me, ITextRange *range, LONG *ret) 4899 { 4900 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4901 ITextSelection *selection = NULL; 4902 LONG start, end; 4903 4904 TRACE("(%p)->(%p %p)\n", This, range, ret); 4905 4906 if (ret) 4907 *ret = tomFalse; 4908 4909 if (!This->reOle) 4910 return CO_E_RELEASED; 4911 4912 if (!range) 4913 return S_FALSE; 4914 4915 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection); 4916 if (!selection) 4917 return S_FALSE; 4918 ITextSelection_Release(selection); 4919 4920 ITextSelection_GetStart(me, &start); 4921 ITextSelection_GetEnd(me, &end); 4922 return textrange_inrange(start, end, range, ret); 4923 } 4924 4925 static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *me, ITextRange *range, LONG *ret) 4926 { 4927 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4928 4929 FIXME("(%p)->(%p %p): stub\n", This, range, ret); 4930 4931 if (!This->reOle) 4932 return CO_E_RELEASED; 4933 4934 return E_NOTIMPL; 4935 } 4936 4937 static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *me, ITextRange *range, LONG *ret) 4938 { 4939 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4940 ITextSelection *selection = NULL; 4941 LONG start, end; 4942 4943 TRACE("(%p)->(%p %p)\n", This, range, ret); 4944 4945 if (ret) 4946 *ret = tomFalse; 4947 4948 if (!This->reOle) 4949 return CO_E_RELEASED; 4950 4951 if (!range) 4952 return S_FALSE; 4953 4954 ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&selection); 4955 if (!selection) 4956 return S_FALSE; 4957 ITextSelection_Release(selection); 4958 4959 ITextSelection_GetStart(me, &start); 4960 ITextSelection_GetEnd(me, &end); 4961 return textrange_isequal(start, end, range, ret); 4962 } 4963 4964 static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *me) 4965 { 4966 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4967 4968 TRACE("(%p)\n", This); 4969 4970 if (!This->reOle) 4971 return CO_E_RELEASED; 4972 4973 /* nothing to do */ 4974 return S_OK; 4975 } 4976 4977 static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *me, LONG unit, LONG extend, 4978 LONG *delta) 4979 { 4980 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4981 4982 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 4983 4984 if (!This->reOle) 4985 return CO_E_RELEASED; 4986 4987 return E_NOTIMPL; 4988 } 4989 4990 static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *me, LONG unit, LONG extend, 4991 LONG *delta) 4992 { 4993 ITextSelectionImpl *This = impl_from_ITextSelection(me); 4994 4995 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 4996 4997 if (!This->reOle) 4998 return CO_E_RELEASED; 4999 5000 return E_NOTIMPL; 5001 } 5002 5003 static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *me, LONG unit, LONG count, LONG *delta) 5004 { 5005 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5006 5007 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 5008 5009 if (!This->reOle) 5010 return CO_E_RELEASED; 5011 5012 return E_NOTIMPL; 5013 } 5014 5015 static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *me, LONG unit, LONG count, 5016 LONG *delta) 5017 { 5018 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5019 5020 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 5021 5022 if (!This->reOle) 5023 return CO_E_RELEASED; 5024 5025 return E_NOTIMPL; 5026 } 5027 5028 static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *me, LONG unit, LONG count, 5029 LONG *delta) 5030 { 5031 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5032 ITextRange *range = NULL; 5033 HRESULT hr; 5034 5035 TRACE("(%p)->(%d %d %p)\n", This, unit, count, delta); 5036 5037 if (!This->reOle) 5038 return CO_E_RELEASED; 5039 5040 ITextSelection_QueryInterface(me, &IID_ITextRange, (void**)&range); 5041 hr = textrange_moveend(range, unit, count, delta); 5042 ITextRange_Release(range); 5043 return hr; 5044 } 5045 5046 static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *me, VARIANT *charset, LONG count, 5047 LONG *delta) 5048 { 5049 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5050 5051 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5052 5053 if (!This->reOle) 5054 return CO_E_RELEASED; 5055 5056 return E_NOTIMPL; 5057 } 5058 5059 static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *me, VARIANT *charset, LONG count, 5060 LONG *delta) 5061 { 5062 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5063 5064 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5065 5066 if (!This->reOle) 5067 return CO_E_RELEASED; 5068 5069 return E_NOTIMPL; 5070 } 5071 5072 static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *me, VARIANT *charset, LONG count, 5073 LONG *delta) 5074 { 5075 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5076 5077 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5078 5079 if (!This->reOle) 5080 return CO_E_RELEASED; 5081 5082 return E_NOTIMPL; 5083 } 5084 5085 static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *me, VARIANT *charset, LONG count, 5086 LONG *delta) 5087 { 5088 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5089 5090 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5091 5092 if (!This->reOle) 5093 return CO_E_RELEASED; 5094 5095 return E_NOTIMPL; 5096 } 5097 5098 static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *me, VARIANT *charset, LONG count, 5099 LONG *delta) 5100 { 5101 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5102 5103 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5104 5105 if (!This->reOle) 5106 return CO_E_RELEASED; 5107 5108 return E_NOTIMPL; 5109 } 5110 5111 static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *me, VARIANT *charset, LONG count, 5112 LONG *delta) 5113 { 5114 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5115 5116 FIXME("(%p)->(%s %d %p): stub\n", This, debugstr_variant(charset), count, delta); 5117 5118 if (!This->reOle) 5119 return CO_E_RELEASED; 5120 5121 return E_NOTIMPL; 5122 } 5123 5124 static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *me, BSTR text, LONG count, LONG flags, 5125 LONG *length) 5126 { 5127 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5128 5129 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 5130 5131 if (!This->reOle) 5132 return CO_E_RELEASED; 5133 5134 FIXME("not implemented\n"); 5135 return E_NOTIMPL; 5136 } 5137 5138 static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *me, BSTR text, LONG count, 5139 LONG flags, LONG *length) 5140 { 5141 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5142 5143 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 5144 5145 if (!This->reOle) 5146 return CO_E_RELEASED; 5147 5148 return E_NOTIMPL; 5149 } 5150 5151 static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *me, BSTR text, LONG count, 5152 LONG flags, LONG *length) 5153 { 5154 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5155 5156 FIXME("(%p)->(%s %d %x %p): stub\n", This, debugstr_w(text), count, flags, length); 5157 5158 if (!This->reOle) 5159 return CO_E_RELEASED; 5160 5161 return E_NOTIMPL; 5162 } 5163 5164 static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *me, LONG unit, LONG count, 5165 LONG *delta) 5166 { 5167 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5168 5169 FIXME("(%p)->(%d %d %p): stub\n", This, unit, count, delta); 5170 5171 if (!This->reOle) 5172 return CO_E_RELEASED; 5173 5174 return E_NOTIMPL; 5175 } 5176 5177 static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *me, VARIANT *v) 5178 { 5179 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5180 5181 FIXME("(%p)->(%p): stub\n", This, v); 5182 5183 if (!This->reOle) 5184 return CO_E_RELEASED; 5185 5186 return E_NOTIMPL; 5187 } 5188 5189 static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *me, VARIANT *v) 5190 { 5191 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5192 5193 FIXME("(%p)->(%p): stub\n", This, v); 5194 5195 if (!This->reOle) 5196 return CO_E_RELEASED; 5197 5198 return E_NOTIMPL; 5199 } 5200 5201 static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *me, VARIANT *v, LONG format) 5202 { 5203 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5204 5205 FIXME("(%p)->(%s %x): stub\n", This, debugstr_variant(v), format); 5206 5207 if (!This->reOle) 5208 return CO_E_RELEASED; 5209 5210 return E_NOTIMPL; 5211 } 5212 5213 static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *me, VARIANT *v, LONG format, 5214 LONG *ret) 5215 { 5216 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5217 5218 FIXME("(%p)->(%s %x %p): stub\n", This, debugstr_variant(v), format, ret); 5219 5220 if (!This->reOle) 5221 return CO_E_RELEASED; 5222 5223 return E_NOTIMPL; 5224 } 5225 5226 static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *me, LONG *ret) 5227 { 5228 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5229 5230 FIXME("(%p)->(%p): stub\n", This, ret); 5231 5232 if (!This->reOle) 5233 return CO_E_RELEASED; 5234 5235 return E_NOTIMPL; 5236 } 5237 5238 static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *me, LONG type) 5239 { 5240 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5241 5242 FIXME("(%p)->(%d): stub\n", This, type); 5243 5244 if (!This->reOle) 5245 return CO_E_RELEASED; 5246 5247 return E_NOTIMPL; 5248 } 5249 5250 static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *me, LONG type, LONG *cx, LONG *cy) 5251 { 5252 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5253 5254 FIXME("(%p)->(%d %p %p): stub\n", This, type, cx, cy); 5255 5256 if (!This->reOle) 5257 return CO_E_RELEASED; 5258 5259 return E_NOTIMPL; 5260 } 5261 5262 static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *me, LONG x, LONG y, LONG type, 5263 LONG extend) 5264 { 5265 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5266 5267 FIXME("(%p)->(%d %d %d %d): stub\n", This, x, y, type, extend); 5268 5269 if (!This->reOle) 5270 return CO_E_RELEASED; 5271 5272 return E_NOTIMPL; 5273 } 5274 5275 static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *me, LONG value) 5276 { 5277 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5278 5279 FIXME("(%p)->(%d): stub\n", This, value); 5280 5281 if (!This->reOle) 5282 return CO_E_RELEASED; 5283 5284 return E_NOTIMPL; 5285 } 5286 5287 static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *me, IUnknown **ppv) 5288 { 5289 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5290 5291 FIXME("(%p)->(%p): stub\n", This, ppv); 5292 5293 if (!This->reOle) 5294 return CO_E_RELEASED; 5295 5296 return E_NOTIMPL; 5297 } 5298 5299 /*** ITextSelection methods ***/ 5300 static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *me, LONG *flags) 5301 { 5302 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5303 5304 FIXME("(%p)->(%p): stub\n", This, flags); 5305 5306 if (!This->reOle) 5307 return CO_E_RELEASED; 5308 5309 return E_NOTIMPL; 5310 } 5311 5312 static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *me, LONG flags) 5313 { 5314 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5315 5316 FIXME("(%p)->(%x): stub\n", This, flags); 5317 5318 if (!This->reOle) 5319 return CO_E_RELEASED; 5320 5321 return E_NOTIMPL; 5322 } 5323 5324 static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *me, LONG *type) 5325 { 5326 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5327 5328 FIXME("(%p)->(%p): stub\n", This, type); 5329 5330 if (!This->reOle) 5331 return CO_E_RELEASED; 5332 5333 return E_NOTIMPL; 5334 } 5335 5336 static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *me, LONG unit, LONG count, 5337 LONG extend, LONG *delta) 5338 { 5339 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5340 5341 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5342 5343 if (!This->reOle) 5344 return CO_E_RELEASED; 5345 5346 return E_NOTIMPL; 5347 } 5348 5349 static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *me, LONG unit, LONG count, 5350 LONG extend, LONG *delta) 5351 { 5352 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5353 5354 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5355 5356 if (!This->reOle) 5357 return CO_E_RELEASED; 5358 5359 return E_NOTIMPL; 5360 } 5361 5362 static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *me, LONG unit, LONG count, 5363 LONG extend, LONG *delta) 5364 { 5365 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5366 5367 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5368 5369 if (!This->reOle) 5370 return CO_E_RELEASED; 5371 5372 return E_NOTIMPL; 5373 } 5374 5375 static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *me, LONG unit, LONG count, 5376 LONG extend, LONG *delta) 5377 { 5378 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5379 5380 FIXME("(%p)->(%d %d %d %p): stub\n", This, unit, count, extend, delta); 5381 5382 if (!This->reOle) 5383 return CO_E_RELEASED; 5384 5385 return E_NOTIMPL; 5386 } 5387 5388 static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *me, LONG unit, LONG extend, 5389 LONG *delta) 5390 { 5391 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5392 5393 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 5394 5395 if (!This->reOle) 5396 return CO_E_RELEASED; 5397 5398 return E_NOTIMPL; 5399 } 5400 5401 static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *me, LONG unit, LONG extend, 5402 LONG *delta) 5403 { 5404 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5405 5406 FIXME("(%p)->(%d %d %p): stub\n", This, unit, extend, delta); 5407 5408 if (!This->reOle) 5409 return CO_E_RELEASED; 5410 5411 return E_NOTIMPL; 5412 } 5413 5414 static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *me, BSTR text) 5415 { 5416 ITextSelectionImpl *This = impl_from_ITextSelection(me); 5417 5418 FIXME("(%p)->(%s): stub\n", This, debugstr_w(text)); 5419 5420 if (!This->reOle) 5421 return CO_E_RELEASED; 5422 5423 return E_NOTIMPL; 5424 } 5425 5426 static const ITextSelectionVtbl tsvt = { 5427 ITextSelection_fnQueryInterface, 5428 ITextSelection_fnAddRef, 5429 ITextSelection_fnRelease, 5430 ITextSelection_fnGetTypeInfoCount, 5431 ITextSelection_fnGetTypeInfo, 5432 ITextSelection_fnGetIDsOfNames, 5433 ITextSelection_fnInvoke, 5434 ITextSelection_fnGetText, 5435 ITextSelection_fnSetText, 5436 ITextSelection_fnGetChar, 5437 ITextSelection_fnSetChar, 5438 ITextSelection_fnGetDuplicate, 5439 ITextSelection_fnGetFormattedText, 5440 ITextSelection_fnSetFormattedText, 5441 ITextSelection_fnGetStart, 5442 ITextSelection_fnSetStart, 5443 ITextSelection_fnGetEnd, 5444 ITextSelection_fnSetEnd, 5445 ITextSelection_fnGetFont, 5446 ITextSelection_fnSetFont, 5447 ITextSelection_fnGetPara, 5448 ITextSelection_fnSetPara, 5449 ITextSelection_fnGetStoryLength, 5450 ITextSelection_fnGetStoryType, 5451 ITextSelection_fnCollapse, 5452 ITextSelection_fnExpand, 5453 ITextSelection_fnGetIndex, 5454 ITextSelection_fnSetIndex, 5455 ITextSelection_fnSetRange, 5456 ITextSelection_fnInRange, 5457 ITextSelection_fnInStory, 5458 ITextSelection_fnIsEqual, 5459 ITextSelection_fnSelect, 5460 ITextSelection_fnStartOf, 5461 ITextSelection_fnEndOf, 5462 ITextSelection_fnMove, 5463 ITextSelection_fnMoveStart, 5464 ITextSelection_fnMoveEnd, 5465 ITextSelection_fnMoveWhile, 5466 ITextSelection_fnMoveStartWhile, 5467 ITextSelection_fnMoveEndWhile, 5468 ITextSelection_fnMoveUntil, 5469 ITextSelection_fnMoveStartUntil, 5470 ITextSelection_fnMoveEndUntil, 5471 ITextSelection_fnFindText, 5472 ITextSelection_fnFindTextStart, 5473 ITextSelection_fnFindTextEnd, 5474 ITextSelection_fnDelete, 5475 ITextSelection_fnCut, 5476 ITextSelection_fnCopy, 5477 ITextSelection_fnPaste, 5478 ITextSelection_fnCanPaste, 5479 ITextSelection_fnCanEdit, 5480 ITextSelection_fnChangeCase, 5481 ITextSelection_fnGetPoint, 5482 ITextSelection_fnSetPoint, 5483 ITextSelection_fnScrollIntoView, 5484 ITextSelection_fnGetEmbeddedObject, 5485 ITextSelection_fnGetFlags, 5486 ITextSelection_fnSetFlags, 5487 ITextSelection_fnGetType, 5488 ITextSelection_fnMoveLeft, 5489 ITextSelection_fnMoveRight, 5490 ITextSelection_fnMoveUp, 5491 ITextSelection_fnMoveDown, 5492 ITextSelection_fnHomeKey, 5493 ITextSelection_fnEndKey, 5494 ITextSelection_fnTypeText 5495 }; 5496 5497 static ITextSelectionImpl * 5498 CreateTextSelection(IRichEditOleImpl *reOle) 5499 { 5500 ITextSelectionImpl *txtSel = heap_alloc(sizeof *txtSel); 5501 if (!txtSel) 5502 return NULL; 5503 5504 txtSel->ITextSelection_iface.lpVtbl = &tsvt; 5505 txtSel->ref = 1; 5506 txtSel->reOle = reOle; 5507 return txtSel; 5508 } 5509 5510 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) 5511 { 5512 IRichEditOleImpl *reo; 5513 5514 reo = heap_alloc(sizeof(IRichEditOleImpl)); 5515 if (!reo) 5516 return 0; 5517 5518 reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl; 5519 reo->IRichEditOle_iface.lpVtbl = &revt; 5520 reo->ITextDocument_iface.lpVtbl = &tdvt; 5521 reo->ref = 1; 5522 reo->editor = editor; 5523 reo->txtSel = NULL; 5524 5525 TRACE("Created %p\n",reo); 5526 list_init(&reo->rangelist); 5527 list_init(&reo->clientsites); 5528 if (outer_unk) 5529 reo->outer_unk = outer_unk; 5530 else 5531 reo->outer_unk = &reo->IUnknown_inner; 5532 *ppvObj = &reo->IRichEditOle_iface; 5533 5534 return 1; 5535 } 5536 5537 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz) 5538 { 5539 /* sizel is in .01 millimeters, sz in pixels */ 5540 sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540); 5541 sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540); 5542 } 5543 5544 /****************************************************************************** 5545 * ME_GetOLEObjectSize 5546 * 5547 * Sets run extent for OLE objects. 5548 */ 5549 void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) 5550 { 5551 IDataObject* ido; 5552 FORMATETC fmt; 5553 STGMEDIUM stgm; 5554 DIBSECTION dibsect; 5555 ENHMETAHEADER emh; 5556 5557 assert(run->nFlags & MERF_GRAPHICS); 5558 assert(run->reobj); 5559 5560 if (run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0) 5561 { 5562 convert_sizel(c, &run->reobj->obj.sizel, pSize); 5563 if (c->editor->nZoomNumerator != 0) 5564 { 5565 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5566 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5567 } 5568 return; 5569 } 5570 5571 if (!run->reobj->obj.poleobj) 5572 { 5573 pSize->cx = pSize->cy = 0; 5574 return; 5575 } 5576 5577 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK) 5578 { 5579 FIXME("Query Interface IID_IDataObject failed!\n"); 5580 pSize->cx = pSize->cy = 0; 5581 return; 5582 } 5583 fmt.cfFormat = CF_BITMAP; 5584 fmt.ptd = NULL; 5585 fmt.dwAspect = DVASPECT_CONTENT; 5586 fmt.lindex = -1; 5587 fmt.tymed = TYMED_GDI; 5588 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5589 { 5590 fmt.cfFormat = CF_ENHMETAFILE; 5591 fmt.tymed = TYMED_ENHMF; 5592 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5593 { 5594 FIXME("unsupported format\n"); 5595 pSize->cx = pSize->cy = 0; 5596 IDataObject_Release(ido); 5597 return; 5598 } 5599 } 5600 IDataObject_Release(ido); 5601 5602 switch (stgm.tymed) 5603 { 5604 case TYMED_GDI: 5605 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); 5606 pSize->cx = dibsect.dsBm.bmWidth; 5607 pSize->cy = dibsect.dsBm.bmHeight; 5608 break; 5609 case TYMED_ENHMF: 5610 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); 5611 pSize->cx = emh.rclBounds.right - emh.rclBounds.left; 5612 pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top; 5613 break; 5614 default: 5615 FIXME("Unsupported tymed %d\n", stgm.tymed); 5616 break; 5617 } 5618 ReleaseStgMedium(&stgm); 5619 if (c->editor->nZoomNumerator != 0) 5620 { 5621 pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5622 pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5623 } 5624 } 5625 5626 void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run, BOOL selected) 5627 { 5628 IDataObject* ido; 5629 FORMATETC fmt; 5630 STGMEDIUM stgm; 5631 DIBSECTION dibsect; 5632 ENHMETAHEADER emh; 5633 HDC hMemDC; 5634 SIZE sz; 5635 BOOL has_size; 5636 HBITMAP old_bm; 5637 RECT rc; 5638 5639 assert(run->nFlags & MERF_GRAPHICS); 5640 assert(run->reobj); 5641 if (IOleObject_QueryInterface(run->reobj->obj.poleobj, &IID_IDataObject, (void**)&ido) != S_OK) 5642 { 5643 FIXME("Couldn't get interface\n"); 5644 return; 5645 } 5646 has_size = run->reobj->obj.sizel.cx != 0 || run->reobj->obj.sizel.cy != 0; 5647 fmt.cfFormat = CF_BITMAP; 5648 fmt.ptd = NULL; 5649 fmt.dwAspect = DVASPECT_CONTENT; 5650 fmt.lindex = -1; 5651 fmt.tymed = TYMED_GDI; 5652 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5653 { 5654 fmt.cfFormat = CF_ENHMETAFILE; 5655 fmt.tymed = TYMED_ENHMF; 5656 if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) 5657 { 5658 FIXME("Couldn't get storage medium\n"); 5659 IDataObject_Release(ido); 5660 return; 5661 } 5662 } 5663 IDataObject_Release(ido); 5664 5665 switch (stgm.tymed) 5666 { 5667 case TYMED_GDI: 5668 GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect); 5669 hMemDC = CreateCompatibleDC(c->hDC); 5670 old_bm = SelectObject(hMemDC, stgm.u.hBitmap); 5671 if (has_size) 5672 { 5673 convert_sizel(c, &run->reobj->obj.sizel, &sz); 5674 } else { 5675 sz.cx = dibsect.dsBm.bmWidth; 5676 sz.cy = dibsect.dsBm.bmHeight; 5677 } 5678 if (c->editor->nZoomNumerator != 0) 5679 { 5680 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5681 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5682 } 5683 StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, 5684 hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY); 5685 5686 SelectObject(hMemDC, old_bm); 5687 DeleteDC(hMemDC); 5688 break; 5689 case TYMED_ENHMF: 5690 GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh); 5691 if (has_size) 5692 { 5693 convert_sizel(c, &run->reobj->obj.sizel, &sz); 5694 } else { 5695 sz.cx = emh.rclBounds.right - emh.rclBounds.left; 5696 sz.cy = emh.rclBounds.bottom - emh.rclBounds.top; 5697 } 5698 if (c->editor->nZoomNumerator != 0) 5699 { 5700 sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5701 sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator); 5702 } 5703 5704 rc.left = x; 5705 rc.top = y - sz.cy; 5706 rc.right = x + sz.cx; 5707 rc.bottom = y; 5708 PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc); 5709 break; 5710 default: 5711 FIXME("Unsupported tymed %d\n", stgm.tymed); 5712 selected = FALSE; 5713 break; 5714 } 5715 ReleaseStgMedium(&stgm); 5716 5717 if (selected && !c->editor->bHideSelection) 5718 PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT); 5719 } 5720 5721 void ME_DeleteReObject(struct re_object *reobj) 5722 { 5723 if (reobj->obj.poleobj) IOleObject_Release(reobj->obj.poleobj); 5724 if (reobj->obj.pstg) IStorage_Release(reobj->obj.pstg); 5725 if (reobj->obj.polesite) IOleClientSite_Release(reobj->obj.polesite); 5726 heap_free(reobj); 5727 } 5728 5729 void ME_CopyReObject(REOBJECT *dst, const REOBJECT *src, DWORD flags) 5730 { 5731 *dst = *src; 5732 dst->poleobj = NULL; 5733 dst->pstg = NULL; 5734 dst->polesite = NULL; 5735 5736 if ((flags & REO_GETOBJ_POLEOBJ) && src->poleobj) 5737 { 5738 dst->poleobj = src->poleobj; 5739 IOleObject_AddRef(dst->poleobj); 5740 } 5741 if ((flags & REO_GETOBJ_PSTG) && src->pstg) 5742 { 5743 dst->pstg = src->pstg; 5744 IStorage_AddRef(dst->pstg); 5745 } 5746 if ((flags & REO_GETOBJ_POLESITE) && src->polesite) 5747 { 5748 dst->polesite = src->polesite; 5749 IOleClientSite_AddRef(dst->polesite); 5750 } 5751 } 5752 5753 void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) 5754 { 5755 IRichEditOleImpl *This = impl_from_IRichEditOle(iface); 5756 *ppvObj = &This->ITextDocument_iface; 5757 } 5758