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
30 #include "wine/debug.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
;
55 FIXME( "Unknown interface: %s\n", debugstr_guid( iid
) );
59 IUnknown_AddRef( (IUnknown
*)*obj
);
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
);
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
);
82 richole_release_children( services
);
83 ME_DestroyEditor( services
->editor
);
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
);
127 res
= editor_handle_message( services
->editor
, msg
, wparam
, lparam
, &hr
);
128 if (result
) *result
= res
;
132 static HRESULT
update_client_rect( struct text_services
*services
, const RECT
*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
;
145 rect
.left
+= services
->editor
->selofs
;
147 if (EqualRect( &rect
, &services
->editor
->rcFormat
)) return S_FALSE
;
148 services
->editor
->rcFormat
= rect
;
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
,
159 struct text_services
*services
= impl_from_ITextServices( iface
);
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
;
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
);
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
;
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
;
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
);
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
,
248 struct text_services
*services
= impl_from_ITextServices( iface
);
250 FIXME( "%p: STUB\n", services
);
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
);
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
);
267 services
->editor
->in_place_active
= old_active
;
270 ME_RewrapRepaint( services
->editor
);
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
;
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
);
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
);
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
);
308 length
= ME_GetTextLength( services
->editor
);
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
);
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
);
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;
337 ME_EmptyUndoStack( services
->editor
);
338 ME_UpdateRepaint( services
->editor
, FALSE
);
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
);
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
);
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
);
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
;
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
);
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
);
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
);
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
);
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
)
445 hr
= ITextHost_TxGetSelectionBarWidth( services
->editor
->texthost
, &width
);
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
;
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;
469 if (repaint
) ME_RewrapRepaint( services
->editor
);
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
);
483 #ifdef __ASM_USE_THISCALL_WRAPPER
485 #define STDCALL(func) (void *) __stdcall_ ## func
487 #define DEFINE_STDCALL_WRAPPER(num,func) \
488 __declspec(naked) HRESULT __stdcall_##func(void) \
493 __asm mov eax, [ecx] \
494 __asm jmp dword ptr [eax + 4*num] \
497 #define DEFINE_STDCALL_WRAPPER(num,func) \
498 extern HRESULT __stdcall_ ## func(void); \
499 __ASM_GLOBAL_FUNC(__stdcall_ ## func, \
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
=
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
,
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
;
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
;
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
);