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
);
37 IUnknown IUnknown_inner
;
38 ITextServices ITextServices_iface
;
42 ME_TextEditor
*editor
;
43 char spare
[256]; /* for bug #12179 */
46 static inline struct text_services
*impl_from_IUnknown( IUnknown
*iface
)
48 return CONTAINING_RECORD( iface
, struct text_services
, IUnknown_inner
);
51 static HRESULT WINAPI
ITextServicesImpl_QueryInterface( IUnknown
*iface
, REFIID iid
, void **obj
)
53 struct text_services
*services
= impl_from_IUnknown( iface
);
55 TRACE( "(%p)->(%s, %p)\n", iface
, debugstr_guid( iid
), obj
);
57 if (IsEqualIID( iid
, &IID_IUnknown
)) *obj
= &services
->IUnknown_inner
;
58 else if (IsEqualIID( iid
, &IID_ITextServices
)) *obj
= &services
->ITextServices_iface
;
59 else if (IsEqualIID( iid
, &IID_IRichEditOle
) || IsEqualIID( iid
, &IID_ITextDocument
) ||
60 IsEqualIID( iid
, &IID_ITextDocument2Old
))
62 if (!services
->editor
->reOle
&& !CreateIRichEditOle( services
->outer_unk
, services
->editor
, (void **)&services
->editor
->reOle
))
64 return IUnknown_QueryInterface( services
->editor
->reOle
, iid
, obj
);
69 FIXME( "Unknown interface: %s\n", debugstr_guid( iid
) );
73 IUnknown_AddRef( (IUnknown
*)*obj
);
77 static ULONG WINAPI
ITextServicesImpl_AddRef(IUnknown
*iface
)
79 struct text_services
*services
= impl_from_IUnknown( iface
);
80 LONG ref
= InterlockedIncrement( &services
->ref
);
82 TRACE( "(%p) ref = %d\n", services
, ref
);
87 static ULONG WINAPI
ITextServicesImpl_Release(IUnknown
*iface
)
89 struct text_services
*services
= impl_from_IUnknown( iface
);
90 LONG ref
= InterlockedDecrement( &services
->ref
);
92 TRACE( "(%p) ref = %d\n", services
, ref
);
96 ME_DestroyEditor( services
->editor
);
97 CoTaskMemFree( services
);
102 static const IUnknownVtbl textservices_inner_vtbl
=
104 ITextServicesImpl_QueryInterface
,
105 ITextServicesImpl_AddRef
,
106 ITextServicesImpl_Release
109 static inline struct text_services
*impl_from_ITextServices( ITextServices
*iface
)
111 return CONTAINING_RECORD( iface
, struct text_services
, ITextServices_iface
);
114 static HRESULT WINAPI
fnTextSrv_QueryInterface( ITextServices
*iface
, REFIID iid
, void **obj
)
116 struct text_services
*services
= impl_from_ITextServices( iface
);
117 return IUnknown_QueryInterface( services
->outer_unk
, iid
, obj
);
120 static ULONG WINAPI
fnTextSrv_AddRef(ITextServices
*iface
)
122 struct text_services
*services
= impl_from_ITextServices( iface
);
123 return IUnknown_AddRef( services
->outer_unk
);
126 static ULONG WINAPI
fnTextSrv_Release(ITextServices
*iface
)
128 struct text_services
*services
= impl_from_ITextServices( iface
);
129 return IUnknown_Release( services
->outer_unk
);
132 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSendMessage
,20)
133 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxSendMessage(ITextServices
*iface
, UINT msg
, WPARAM wparam
,
134 LPARAM lparam
, LRESULT
*plresult
)
136 struct text_services
*services
= impl_from_ITextServices( iface
);
140 lresult
= ME_HandleMessage( services
->editor
, msg
, wparam
, lparam
, TRUE
, &hresult
);
141 if (plresult
) *plresult
= lresult
;
145 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxDraw
,52)
146 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxDraw(ITextServices
*iface
, DWORD dwDrawAspect
, LONG lindex
,
147 void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hdcDraw
, HDC hdcTargetDev
,
148 LPCRECTL lprcBounds
, LPCRECTL lprcWBounds
, LPRECT lprcUpdate
,
149 BOOL (CALLBACK
* pfnContinue
)(DWORD
), DWORD dwContinue
,
152 struct text_services
*services
= impl_from_ITextServices( iface
);
154 FIXME( "%p: STUB\n", services
);
158 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetHScroll
,24)
159 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetHScroll( ITextServices
*iface
, LONG
*min_pos
, LONG
*max_pos
, LONG
*pos
,
160 LONG
*page
, BOOL
*enabled
)
162 struct text_services
*services
= impl_from_ITextServices( iface
);
164 if (min_pos
) *min_pos
= services
->editor
->horz_si
.nMin
;
165 if (max_pos
) *max_pos
= services
->editor
->horz_si
.nMax
;
166 if (pos
) *pos
= services
->editor
->horz_si
.nPos
;
167 if (page
) *page
= services
->editor
->horz_si
.nPage
;
168 if (enabled
) *enabled
= (services
->editor
->styleFlags
& WS_HSCROLL
) != 0;
172 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetVScroll
,24)
173 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetVScroll( ITextServices
*iface
, LONG
*min_pos
, LONG
*max_pos
, LONG
*pos
,
174 LONG
*page
, BOOL
*enabled
)
176 struct text_services
*services
= impl_from_ITextServices( iface
);
178 if (min_pos
) *min_pos
= services
->editor
->vert_si
.nMin
;
179 if (max_pos
) *max_pos
= services
->editor
->vert_si
.nMax
;
180 if (pos
) *pos
= services
->editor
->vert_si
.nPos
;
181 if (page
) *page
= services
->editor
->vert_si
.nPage
;
182 if (enabled
) *enabled
= (services
->editor
->styleFlags
& WS_VSCROLL
) != 0;
186 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxSetCursor
,40)
187 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_OnTxSetCursor(ITextServices
*iface
, DWORD dwDrawAspect
, LONG lindex
,
188 void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hdcDraw
,
189 HDC hicTargetDev
, LPCRECT lprcClient
, INT x
, INT y
)
191 struct text_services
*services
= impl_from_ITextServices( iface
);
193 FIXME( "%p: STUB\n", services
);
197 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxQueryHitPoint
,44)
198 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxQueryHitPoint(ITextServices
*iface
, DWORD dwDrawAspect
, LONG lindex
,
199 void *pvAspect
, DVTARGETDEVICE
*ptd
, HDC hdcDraw
,
200 HDC hicTargetDev
, LPCRECT lprcClient
, INT x
, INT y
,
203 struct text_services
*services
= impl_from_ITextServices( iface
);
205 FIXME( "%p: STUB\n", services
);
209 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceActivate
,8)
210 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_OnTxInplaceActivate(ITextServices
*iface
, LPCRECT prcClient
)
212 struct text_services
*services
= impl_from_ITextServices( iface
);
214 FIXME( "%p: STUB\n", services
);
218 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceDeactivate
,4)
219 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_OnTxInplaceDeactivate(ITextServices
*iface
)
221 struct text_services
*services
= impl_from_ITextServices( iface
);
223 FIXME( "%p: STUB\n", services
);
227 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate
,4)
228 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_OnTxUIActivate(ITextServices
*iface
)
230 struct text_services
*services
= impl_from_ITextServices( iface
);
232 FIXME( "%p: STUB\n", services
);
236 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate
,4)
237 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_OnTxUIDeactivate(ITextServices
*iface
)
239 struct text_services
*services
= impl_from_ITextServices( iface
);
241 FIXME( "%p: STUB\n", services
);
245 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText
,8)
246 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetText( ITextServices
*iface
, BSTR
*text
)
248 struct text_services
*services
= impl_from_ITextServices( iface
);
251 length
= ME_GetTextLength( services
->editor
);
256 bstr
= SysAllocStringByteLen( NULL
, length
* sizeof(WCHAR
) );
257 if (bstr
== NULL
) return E_OUTOFMEMORY
;
259 cursor_from_char_ofs( services
->editor
, 0, &start
);
260 ME_GetTextW( services
->editor
, bstr
, length
, &start
, INT_MAX
, FALSE
, FALSE
);
268 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText
,8)
269 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxSetText( ITextServices
*iface
, const WCHAR
*text
)
271 struct text_services
*services
= impl_from_ITextServices( iface
);
274 ME_SetCursorToStart( services
->editor
, &cursor
);
275 ME_InternalDeleteText( services
->editor
, &cursor
, ME_GetTextLength( services
->editor
), FALSE
);
276 if (text
) ME_InsertTextFromCursor( services
->editor
, 0, text
, -1, services
->editor
->pBuffer
->pDefaultStyle
);
277 set_selection_cursors( services
->editor
, 0, 0);
278 services
->editor
->nModifyStep
= 0;
280 ME_EmptyUndoStack( services
->editor
);
281 ME_UpdateRepaint( services
->editor
, FALSE
);
286 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurTargetX
,8)
287 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetCurTargetX(ITextServices
*iface
, LONG
*x
)
289 struct text_services
*services
= impl_from_ITextServices( iface
);
291 FIXME( "%p: STUB\n", services
);
295 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos
,8)
296 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetBaseLinePos(ITextServices
*iface
, LONG
*x
)
298 struct text_services
*services
= impl_from_ITextServices( iface
);
300 FIXME( "%p: STUB\n", services
);
304 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize
,36)
305 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetNaturalSize(ITextServices
*iface
, DWORD dwAspect
, HDC hdcDraw
,
306 HDC hicTargetDev
, DVTARGETDEVICE
*ptd
, DWORD dwMode
,
307 const SIZEL
*psizelExtent
, LONG
*pwidth
, LONG
*pheight
)
309 struct text_services
*services
= impl_from_ITextServices( iface
);
311 FIXME( "%p: STUB\n", services
);
315 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget
,8)
316 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetDropTarget(ITextServices
*iface
, IDropTarget
**ppDropTarget
)
318 struct text_services
*services
= impl_from_ITextServices( iface
);
320 FIXME( "%p: STUB\n", services
);
324 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange
,12)
325 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_OnTxPropertyBitsChange(ITextServices
*iface
, DWORD dwMask
, DWORD dwBits
)
327 struct text_services
*services
= impl_from_ITextServices( iface
);
329 FIXME( "%p: STUB\n", services
);
333 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize
,12)
334 DECLSPEC_HIDDEN HRESULT __thiscall
fnTextSrv_TxGetCachedSize(ITextServices
*iface
, DWORD
*pdwWidth
, DWORD
*pdwHeight
)
336 struct text_services
*services
= impl_from_ITextServices( iface
);
338 FIXME( "%p: STUB\n", services
);
343 static const ITextServicesVtbl textservices_vtbl
=
345 fnTextSrv_QueryInterface
,
348 THISCALL(fnTextSrv_TxSendMessage
),
349 THISCALL(fnTextSrv_TxDraw
),
350 THISCALL(fnTextSrv_TxGetHScroll
),
351 THISCALL(fnTextSrv_TxGetVScroll
),
352 THISCALL(fnTextSrv_OnTxSetCursor
),
353 THISCALL(fnTextSrv_TxQueryHitPoint
),
354 THISCALL(fnTextSrv_OnTxInplaceActivate
),
355 THISCALL(fnTextSrv_OnTxInplaceDeactivate
),
356 THISCALL(fnTextSrv_OnTxUIActivate
),
357 THISCALL(fnTextSrv_OnTxUIDeactivate
),
358 THISCALL(fnTextSrv_TxGetText
),
359 THISCALL(fnTextSrv_TxSetText
),
360 THISCALL(fnTextSrv_TxGetCurTargetX
),
361 THISCALL(fnTextSrv_TxGetBaseLinePos
),
362 THISCALL(fnTextSrv_TxGetNaturalSize
),
363 THISCALL(fnTextSrv_TxGetDropTarget
),
364 THISCALL(fnTextSrv_OnTxPropertyBitsChange
),
365 THISCALL(fnTextSrv_TxGetCachedSize
)
368 HRESULT
create_text_services( IUnknown
*outer
, ITextHost
*text_host
, IUnknown
**unk
, BOOL emulate_10
,
369 ME_TextEditor
**editor
)
371 struct text_services
*services
;
373 TRACE( "%p %p --> %p\n", outer
, text_host
, unk
);
374 if (text_host
== NULL
) return E_POINTER
;
376 services
= CoTaskMemAlloc( sizeof(*services
) );
377 if (services
== NULL
) return E_OUTOFMEMORY
;
379 services
->host
= text_host
; /* Don't take a ref of the host - this would lead to a mutual dependency */
380 services
->IUnknown_inner
.lpVtbl
= &textservices_inner_vtbl
;
381 services
->ITextServices_iface
.lpVtbl
= &textservices_vtbl
;
382 services
->editor
= ME_MakeEditor( text_host
, emulate_10
);
383 if (editor
) *editor
= services
->editor
; /* To be removed */
385 if (outer
) services
->outer_unk
= outer
;
386 else services
->outer_unk
= &services
->IUnknown_inner
;
388 *unk
= &services
->IUnknown_inner
;
392 /******************************************************************
393 * CreateTextServices (RICHED20.4)
395 HRESULT WINAPI
CreateTextServices( IUnknown
*outer
, ITextHost
*text_host
, IUnknown
**unk
)
397 return create_text_services( outer
, text_host
, unk
, FALSE
, NULL
);