comctl32/tests: Use CRT allocation functions.
[wine.git] / dlls / riched20 / txtsrv.c
blob5c63b3daf9af525b34d30dc0953e69b6b741d249
1 /*
2 * RichEdit - functions and interfaces around CreateTextServices
4 * Copyright 2005, 2006, Maarten Lankhorst
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "editor.h"
24 #include "ole2.h"
25 #include "oleauto.h"
26 #include "richole.h"
27 #include "tom.h"
28 #include "imm.h"
29 #include "textserv.h"
30 #include "wine/debug.h"
31 #include "editstr.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
35 static inline struct text_services *impl_from_IUnknown( IUnknown *iface )
37 return CONTAINING_RECORD( iface, struct text_services, IUnknown_inner );
40 static HRESULT WINAPI ITextServicesImpl_QueryInterface( IUnknown *iface, REFIID iid, void **obj )
42 struct text_services *services = impl_from_IUnknown( iface );
44 TRACE( "(%p)->(%s, %p)\n", iface, debugstr_guid( iid ), obj );
46 if (IsEqualIID( iid, &IID_IUnknown )) *obj = &services->IUnknown_inner;
47 else if (IsEqualIID( iid, &IID_ITextServices )) *obj = &services->ITextServices_iface;
48 else if (IsEqualIID( iid, &IID_IRichEditOle )) *obj= &services->IRichEditOle_iface;
49 else if (IsEqualIID( iid, &IID_IDispatch ) ||
50 IsEqualIID( iid, &IID_ITextDocument ) ||
51 IsEqualIID( iid, &IID_ITextDocument2Old )) *obj = &services->ITextDocument2Old_iface;
52 else
54 *obj = NULL;
55 FIXME( "Unknown interface: %s\n", debugstr_guid( iid ) );
56 return E_NOINTERFACE;
59 IUnknown_AddRef( (IUnknown *)*obj );
60 return S_OK;
63 static ULONG WINAPI ITextServicesImpl_AddRef(IUnknown *iface)
65 struct text_services *services = impl_from_IUnknown( iface );
66 LONG ref = InterlockedIncrement( &services->ref );
68 TRACE( "(%p) ref = %ld\n", services, ref );
70 return ref;
73 static ULONG WINAPI ITextServicesImpl_Release(IUnknown *iface)
75 struct text_services *services = impl_from_IUnknown( iface );
76 LONG ref = InterlockedDecrement( &services->ref );
78 TRACE( "(%p) ref = %ld\n", services, ref );
80 if (!ref)
82 richole_release_children( services );
83 ME_DestroyEditor( services->editor );
84 free( services );
86 return ref;
89 static const IUnknownVtbl textservices_inner_vtbl =
91 ITextServicesImpl_QueryInterface,
92 ITextServicesImpl_AddRef,
93 ITextServicesImpl_Release
96 static inline struct text_services *impl_from_ITextServices( ITextServices *iface )
98 return CONTAINING_RECORD( iface, struct text_services, ITextServices_iface );
101 static HRESULT WINAPI fnTextSrv_QueryInterface( ITextServices *iface, REFIID iid, void **obj )
103 struct text_services *services = impl_from_ITextServices( iface );
104 return IUnknown_QueryInterface( services->outer_unk, iid, obj );
107 static ULONG WINAPI fnTextSrv_AddRef(ITextServices *iface)
109 struct text_services *services = impl_from_ITextServices( iface );
110 return IUnknown_AddRef( services->outer_unk );
113 static ULONG WINAPI fnTextSrv_Release(ITextServices *iface)
115 struct text_services *services = impl_from_ITextServices( iface );
116 return IUnknown_Release( services->outer_unk );
119 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSendMessage,20)
120 HRESULT __thiscall fnTextSrv_TxSendMessage( ITextServices *iface, UINT msg, WPARAM wparam,
121 LPARAM lparam, LRESULT *result )
123 struct text_services *services = impl_from_ITextServices( iface );
124 HRESULT hr;
125 LRESULT res;
127 res = editor_handle_message( services->editor, msg, wparam, lparam, &hr );
128 if (result) *result = res;
129 return hr;
132 static HRESULT update_client_rect( struct text_services *services, const RECT *client )
134 RECT rect;
135 HRESULT hr;
137 if (!client)
139 if (!services->editor->in_place_active) return E_INVALIDARG;
140 hr = ITextHost_TxGetClientRect( services->editor->texthost, &rect );
141 if (FAILED( hr )) return hr;
143 else rect = *client;
145 rect.left += services->editor->selofs;
147 if (EqualRect( &rect, &services->editor->rcFormat )) return S_FALSE;
148 services->editor->rcFormat = rect;
149 return S_OK;
152 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxDraw,52)
153 HRESULT __thiscall fnTextSrv_TxDraw( ITextServices *iface, DWORD aspect, LONG index, void *aspect_info,
154 DVTARGETDEVICE *td, HDC draw, HDC target,
155 const RECTL *bounds, const RECTL *mf_bounds, RECT *update,
156 BOOL (CALLBACK *continue_fn)(DWORD), DWORD continue_param,
157 LONG view_id )
159 struct text_services *services = impl_from_ITextServices( iface );
160 HRESULT hr;
161 HDC dc = draw;
162 BOOL rewrap = FALSE;
164 TRACE( "%p: aspect %ld, %ld, %p, %p, draw %p, target %p, bounds %s, mf_bounds %s, update %s, %p, %ld, view %ld\n",
165 services, aspect, index, aspect_info, td, draw, target, wine_dbgstr_rect( (RECT *)bounds ),
166 wine_dbgstr_rect( (RECT *)mf_bounds ), wine_dbgstr_rect( update ), continue_fn, continue_param, view_id );
168 if (aspect != DVASPECT_CONTENT || aspect_info || td || target || mf_bounds || continue_fn )
169 FIXME( "Many arguments are ignored\n" );
171 if (view_id == TXTVIEW_ACTIVE && services->editor->freeze_count) return E_UNEXPECTED;
173 hr = update_client_rect( services, (RECT *)bounds );
174 if (FAILED( hr )) return hr;
175 if (hr == S_OK) rewrap = TRUE;
177 if (!dc && services->editor->in_place_active)
178 dc = ITextHost_TxGetDC( services->editor->texthost );
179 if (!dc) return E_FAIL;
181 if (rewrap)
183 editor_mark_rewrap_all( services->editor );
184 wrap_marked_paras_dc( services->editor, dc, FALSE );
187 if (!services->editor->bEmulateVersion10 || services->editor->nEventMask & ENM_UPDATE)
188 ITextHost_TxNotify( services->editor->texthost, EN_UPDATE, NULL );
190 editor_draw( services->editor, dc, update );
192 if (!draw) ITextHost_TxReleaseDC( services->editor->texthost, dc );
193 return S_OK;
196 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetHScroll,24)
197 HRESULT __thiscall fnTextSrv_TxGetHScroll( ITextServices *iface, LONG *min_pos, LONG *max_pos, LONG *pos,
198 LONG *page, BOOL *enabled )
200 struct text_services *services = impl_from_ITextServices( iface );
202 if (min_pos) *min_pos = services->editor->horz_si.nMin;
203 if (max_pos) *max_pos = services->editor->horz_si.nMax;
204 if (pos) *pos = services->editor->horz_si.nPos;
205 if (page) *page = services->editor->horz_si.nPage;
206 if (enabled) *enabled = services->editor->horz_sb_enabled;
207 return S_OK;
210 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetVScroll,24)
211 HRESULT __thiscall fnTextSrv_TxGetVScroll( ITextServices *iface, LONG *min_pos, LONG *max_pos, LONG *pos,
212 LONG *page, BOOL *enabled )
214 struct text_services *services = impl_from_ITextServices( iface );
216 if (min_pos) *min_pos = services->editor->vert_si.nMin;
217 if (max_pos) *max_pos = services->editor->vert_si.nMax;
218 if (pos) *pos = services->editor->vert_si.nPos;
219 if (page) *page = services->editor->vert_si.nPage;
220 if (enabled) *enabled = services->editor->vert_sb_enabled;
221 return S_OK;
224 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxSetCursor,40)
225 HRESULT __thiscall fnTextSrv_OnTxSetCursor( ITextServices *iface, DWORD aspect, LONG index,
226 void *aspect_info, DVTARGETDEVICE *td, HDC draw,
227 HDC target, const RECT *client, INT x, INT y )
229 struct text_services *services = impl_from_ITextServices( iface );
231 TRACE( "%p: %ld, %ld, %p, %p, draw %p target %p client %s pos (%d, %d)\n", services, aspect, index, aspect_info, td, draw,
232 target, wine_dbgstr_rect( client ), x, y );
234 if (aspect != DVASPECT_CONTENT || index || aspect_info || td || draw || target || client)
235 FIXME( "Ignoring most params\n" );
237 link_notify( services->editor, WM_SETCURSOR, 0, MAKELPARAM( x, y ) );
238 editor_set_cursor( services->editor, x, y );
239 return S_OK;
242 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxQueryHitPoint,44)
243 HRESULT __thiscall fnTextSrv_TxQueryHitPoint(ITextServices *iface, DWORD dwDrawAspect, LONG lindex,
244 void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcDraw,
245 HDC hicTargetDev, LPCRECT lprcClient, INT x, INT y,
246 DWORD *pHitResult)
248 struct text_services *services = impl_from_ITextServices( iface );
250 FIXME( "%p: STUB\n", services );
251 return E_NOTIMPL;
254 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInPlaceActivate,8)
255 HRESULT __thiscall fnTextSrv_OnTxInPlaceActivate( ITextServices *iface, const RECT *client )
257 struct text_services *services = impl_from_ITextServices( iface );
258 HRESULT hr;
259 BOOL old_active = services->editor->in_place_active;
261 TRACE( "%p: %s\n", services, wine_dbgstr_rect( client ) );
263 services->editor->in_place_active = TRUE;
264 hr = update_client_rect( services, client );
265 if (FAILED( hr ))
267 services->editor->in_place_active = old_active;
268 return hr;
270 ME_RewrapRepaint( services->editor );
271 return S_OK;
274 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInPlaceDeactivate,4)
275 HRESULT __thiscall fnTextSrv_OnTxInPlaceDeactivate(ITextServices *iface)
277 struct text_services *services = impl_from_ITextServices( iface );
279 TRACE( "%p\n", services );
280 services->editor->in_place_active = FALSE;
281 return S_OK;
284 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate,4)
285 HRESULT __thiscall fnTextSrv_OnTxUIActivate(ITextServices *iface)
287 struct text_services *services = impl_from_ITextServices( iface );
289 FIXME( "%p: STUB\n", services );
290 return E_NOTIMPL;
293 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate,4)
294 HRESULT __thiscall fnTextSrv_OnTxUIDeactivate(ITextServices *iface)
296 struct text_services *services = impl_from_ITextServices( iface );
298 FIXME( "%p: STUB\n", services );
299 return E_NOTIMPL;
302 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText,8)
303 HRESULT __thiscall fnTextSrv_TxGetText( ITextServices *iface, BSTR *text )
305 struct text_services *services = impl_from_ITextServices( iface );
306 int length;
308 length = ME_GetTextLength( services->editor );
309 if (length)
311 ME_Cursor start;
312 BSTR bstr;
313 bstr = SysAllocStringByteLen( NULL, length * sizeof(WCHAR) );
314 if (bstr == NULL) return E_OUTOFMEMORY;
316 cursor_from_char_ofs( services->editor, 0, &start );
317 ME_GetTextW( services->editor, bstr, length, &start, INT_MAX, FALSE, FALSE );
318 *text = bstr;
320 else *text = NULL;
322 return S_OK;
325 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText,8)
326 HRESULT __thiscall fnTextSrv_TxSetText( ITextServices *iface, const WCHAR *text )
328 struct text_services *services = impl_from_ITextServices( iface );
329 ME_Cursor cursor;
331 ME_SetCursorToStart( services->editor, &cursor );
332 ME_InternalDeleteText( services->editor, &cursor, ME_GetTextLength( services->editor ), FALSE );
333 if (text) ME_InsertTextFromCursor( services->editor, 0, text, -1, services->editor->pBuffer->pDefaultStyle );
334 set_selection_cursors( services->editor, 0, 0);
335 services->editor->nModifyStep = 0;
336 OleFlushClipboard();
337 ME_EmptyUndoStack( services->editor );
338 ME_UpdateRepaint( services->editor, FALSE );
340 return S_OK;
343 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurTargetX,8)
344 HRESULT __thiscall fnTextSrv_TxGetCurTargetX(ITextServices *iface, LONG *x)
346 struct text_services *services = impl_from_ITextServices( iface );
348 FIXME( "%p: STUB\n", services );
349 return E_NOTIMPL;
352 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos,8)
353 HRESULT __thiscall fnTextSrv_TxGetBaseLinePos(ITextServices *iface, LONG *x)
355 struct text_services *services = impl_from_ITextServices( iface );
357 FIXME( "%p: STUB\n", services );
358 return E_NOTIMPL;
361 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize,36)
362 HRESULT __thiscall fnTextSrv_TxGetNaturalSize( ITextServices *iface, DWORD aspect, HDC draw,
363 HDC target, DVTARGETDEVICE *td, DWORD mode,
364 const SIZEL *extent, LONG *width, LONG *height )
366 struct text_services *services = impl_from_ITextServices( iface );
367 RECT rect;
368 HDC dc = draw;
369 BOOL rewrap = FALSE;
370 HRESULT hr;
372 TRACE( "%p: aspect %ld, draw %p, target %p, td %p, mode %08lx, extent %s, *width %ld, *height %ld\n", services,
373 aspect, draw, target, td, mode, wine_dbgstr_point( (POINT *)extent ), *width, *height );
375 if (aspect != DVASPECT_CONTENT || target || td || mode != TXTNS_FITTOCONTENT )
376 FIXME( "Many arguments are ignored\n" );
378 SetRect( &rect, 0, 0, *width, *height );
380 hr = update_client_rect( services, &rect );
381 if (FAILED( hr )) return hr;
382 if (hr == S_OK) rewrap = TRUE;
384 if (!dc && services->editor->in_place_active)
385 dc = ITextHost_TxGetDC( services->editor->texthost );
386 if (!dc) return E_FAIL;
388 if (rewrap)
390 editor_mark_rewrap_all( services->editor );
391 wrap_marked_paras_dc( services->editor, dc, FALSE );
394 *width = services->editor->nTotalWidth;
395 *height = services->editor->nTotalLength;
397 if (!draw) ITextHost_TxReleaseDC( services->editor->texthost, dc );
398 return S_OK;
401 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget,8)
402 HRESULT __thiscall fnTextSrv_TxGetDropTarget(ITextServices *iface, IDropTarget **ppDropTarget)
404 struct text_services *services = impl_from_ITextServices( iface );
406 FIXME( "%p: STUB\n", services );
407 return E_NOTIMPL;
410 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12)
411 HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServices *iface, DWORD mask, DWORD bits )
413 struct text_services *services = impl_from_ITextServices( iface );
414 DWORD scrollbars;
415 HRESULT hr;
416 BOOL repaint = FALSE;
418 TRACE( "%p, mask %08lx, bits %08lx\n", services, mask, bits );
420 services->editor->props = (services->editor->props & ~mask) | (bits & mask);
421 if (mask & (TXTBIT_WORDWRAP | TXTBIT_MULTILINE))
422 services->editor->bWordWrap = (services->editor->props & TXTBIT_WORDWRAP) && (services->editor->props & TXTBIT_MULTILINE);
424 if (mask & TXTBIT_SCROLLBARCHANGE)
426 hr = ITextHost_TxGetScrollBars( services->editor->texthost, &scrollbars );
427 if (SUCCEEDED( hr ))
429 if ((services->editor->scrollbars ^ scrollbars) & WS_HSCROLL)
430 ITextHost_TxShowScrollBar( services->editor->texthost, SB_HORZ, (scrollbars & WS_HSCROLL) &&
431 services->editor->nTotalWidth > services->editor->sizeWindow.cx );
432 if ((services->editor->scrollbars ^ scrollbars) & WS_VSCROLL)
433 ITextHost_TxShowScrollBar( services->editor->texthost, SB_VERT, (scrollbars & WS_VSCROLL) &&
434 services->editor->nTotalLength > services->editor->sizeWindow.cy );
435 services->editor->scrollbars = scrollbars;
439 if ((mask & TXTBIT_HIDESELECTION) && !services->editor->bHaveFocus) ME_InvalidateSelection( services->editor );
441 if (mask & TXTBIT_SELBARCHANGE)
443 LONG width;
445 hr = ITextHost_TxGetSelectionBarWidth( services->editor->texthost, &width );
446 if (hr == S_OK)
448 ITextHost_TxInvalidateRect( services->editor->texthost, &services->editor->rcFormat, TRUE );
449 services->editor->rcFormat.left -= services->editor->selofs;
450 services->editor->selofs = width ? SELECTIONBAR_WIDTH : 0; /* FIXME: convert from HIMETRIC */
451 services->editor->rcFormat.left += services->editor->selofs;
452 repaint = TRUE;
456 if (mask & TXTBIT_CLIENTRECTCHANGE)
458 hr = update_client_rect( services, NULL );
459 if (SUCCEEDED( hr )) repaint = TRUE;
462 if (mask & TXTBIT_USEPASSWORD)
464 if (bits & TXTBIT_USEPASSWORD) ITextHost_TxGetPasswordChar( services->editor->texthost, &services->editor->password_char );
465 else services->editor->password_char = 0;
466 repaint = TRUE;
469 if (repaint) ME_RewrapRepaint( services->editor );
471 return S_OK;
474 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize,12)
475 HRESULT __thiscall fnTextSrv_TxGetCachedSize(ITextServices *iface, DWORD *pdwWidth, DWORD *pdwHeight)
477 struct text_services *services = impl_from_ITextServices( iface );
479 FIXME( "%p: STUB\n", services );
480 return E_NOTIMPL;
483 #ifdef __ASM_USE_THISCALL_WRAPPER
485 #define STDCALL(func) (void *) __stdcall_ ## func
486 #ifdef _MSC_VER
487 #define DEFINE_STDCALL_WRAPPER(num,func) \
488 __declspec(naked) HRESULT __stdcall_##func(void) \
490 __asm pop eax \
491 __asm pop ecx \
492 __asm push eax \
493 __asm mov eax, [ecx] \
494 __asm jmp dword ptr [eax + 4*num] \
496 #else /* _MSC_VER */
497 #define DEFINE_STDCALL_WRAPPER(num,func) \
498 extern HRESULT __stdcall_ ## func(void); \
499 __ASM_GLOBAL_FUNC(__stdcall_ ## func, \
500 "popl %eax\n\t" \
501 "popl %ecx\n\t" \
502 "pushl %eax\n\t" \
503 "movl (%ecx), %eax\n\t" \
504 "jmp *(4*(" #num "))(%eax)" )
505 #endif /* _MSC_VER */
507 DEFINE_STDCALL_WRAPPER(3, ITextServices_TxSendMessage)
508 DEFINE_STDCALL_WRAPPER(4, ITextServices_TxDraw)
509 DEFINE_STDCALL_WRAPPER(5, ITextServices_TxGetHScroll)
510 DEFINE_STDCALL_WRAPPER(6, ITextServices_TxGetVScroll)
511 DEFINE_STDCALL_WRAPPER(7, ITextServices_OnTxSetCursor)
512 DEFINE_STDCALL_WRAPPER(8, ITextServices_TxQueryHitPoint)
513 DEFINE_STDCALL_WRAPPER(9, ITextServices_OnTxInPlaceActivate)
514 DEFINE_STDCALL_WRAPPER(10, ITextServices_OnTxInPlaceDeactivate)
515 DEFINE_STDCALL_WRAPPER(11, ITextServices_OnTxUIActivate)
516 DEFINE_STDCALL_WRAPPER(12, ITextServices_OnTxUIDeactivate)
517 DEFINE_STDCALL_WRAPPER(13, ITextServices_TxGetText)
518 DEFINE_STDCALL_WRAPPER(14, ITextServices_TxSetText)
519 DEFINE_STDCALL_WRAPPER(15, ITextServices_TxGetCurTargetX)
520 DEFINE_STDCALL_WRAPPER(16, ITextServices_TxGetBaseLinePos)
521 DEFINE_STDCALL_WRAPPER(17, ITextServices_TxGetNaturalSize)
522 DEFINE_STDCALL_WRAPPER(18, ITextServices_TxGetDropTarget)
523 DEFINE_STDCALL_WRAPPER(19, ITextServices_OnTxPropertyBitsChange)
524 DEFINE_STDCALL_WRAPPER(20, ITextServices_TxGetCachedSize)
526 const ITextServicesVtbl text_services_stdcall_vtbl =
528 NULL,
529 NULL,
530 NULL,
531 STDCALL(ITextServices_TxSendMessage),
532 STDCALL(ITextServices_TxDraw),
533 STDCALL(ITextServices_TxGetHScroll),
534 STDCALL(ITextServices_TxGetVScroll),
535 STDCALL(ITextServices_OnTxSetCursor),
536 STDCALL(ITextServices_TxQueryHitPoint),
537 STDCALL(ITextServices_OnTxInPlaceActivate),
538 STDCALL(ITextServices_OnTxInPlaceDeactivate),
539 STDCALL(ITextServices_OnTxUIActivate),
540 STDCALL(ITextServices_OnTxUIDeactivate),
541 STDCALL(ITextServices_TxGetText),
542 STDCALL(ITextServices_TxSetText),
543 STDCALL(ITextServices_TxGetCurTargetX),
544 STDCALL(ITextServices_TxGetBaseLinePos),
545 STDCALL(ITextServices_TxGetNaturalSize),
546 STDCALL(ITextServices_TxGetDropTarget),
547 STDCALL(ITextServices_OnTxPropertyBitsChange),
548 STDCALL(ITextServices_TxGetCachedSize),
551 #endif /* __ASM_USE_THISCALL_WRAPPER */
553 static const ITextServicesVtbl textservices_vtbl =
555 fnTextSrv_QueryInterface,
556 fnTextSrv_AddRef,
557 fnTextSrv_Release,
558 THISCALL(fnTextSrv_TxSendMessage),
559 THISCALL(fnTextSrv_TxDraw),
560 THISCALL(fnTextSrv_TxGetHScroll),
561 THISCALL(fnTextSrv_TxGetVScroll),
562 THISCALL(fnTextSrv_OnTxSetCursor),
563 THISCALL(fnTextSrv_TxQueryHitPoint),
564 THISCALL(fnTextSrv_OnTxInPlaceActivate),
565 THISCALL(fnTextSrv_OnTxInPlaceDeactivate),
566 THISCALL(fnTextSrv_OnTxUIActivate),
567 THISCALL(fnTextSrv_OnTxUIDeactivate),
568 THISCALL(fnTextSrv_TxGetText),
569 THISCALL(fnTextSrv_TxSetText),
570 THISCALL(fnTextSrv_TxGetCurTargetX),
571 THISCALL(fnTextSrv_TxGetBaseLinePos),
572 THISCALL(fnTextSrv_TxGetNaturalSize),
573 THISCALL(fnTextSrv_TxGetDropTarget),
574 THISCALL(fnTextSrv_OnTxPropertyBitsChange),
575 THISCALL(fnTextSrv_TxGetCachedSize)
578 HRESULT create_text_services( IUnknown *outer, ITextHost *text_host, IUnknown **unk, BOOL emulate_10 )
580 struct text_services *services;
582 TRACE( "%p %p --> %p\n", outer, text_host, unk );
583 if (text_host == NULL) return E_POINTER;
585 services = malloc( sizeof(*services) );
586 if (services == NULL) return E_OUTOFMEMORY;
587 services->ref = 1;
588 services->IUnknown_inner.lpVtbl = &textservices_inner_vtbl;
589 services->ITextServices_iface.lpVtbl = &textservices_vtbl;
590 services->IRichEditOle_iface.lpVtbl = &re_ole_vtbl;
591 services->ITextDocument2Old_iface.lpVtbl = &text_doc2old_vtbl;
592 services->editor = ME_MakeEditor( text_host, emulate_10 );
593 services->editor->richole = &services->IRichEditOle_iface;
595 if (outer) services->outer_unk = outer;
596 else services->outer_unk = &services->IUnknown_inner;
598 services->text_selection = NULL;
599 list_init( &services->rangelist );
600 list_init( &services->clientsites );
602 *unk = &services->IUnknown_inner;
603 return S_OK;
606 /******************************************************************
607 * CreateTextServices (RICHED20.4)
609 HRESULT WINAPI CreateTextServices( IUnknown *outer, ITextHost *text_host, IUnknown **unk )
611 return create_text_services( outer, text_host, unk, FALSE );