2 * Unit test suite for windowless rich edit controls
4 * Copyright 2008 Maarten Lankhorst
5 * Copyright 2008 Austin Lund
6 * Copyright 2008 Dylan Smith
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #include <wine/test.h>
35 static HMODULE hmoduleRichEdit
;
37 /* Define C Macros for ITextServices calls. */
39 /* Use a special table for x86 machines to convert the thiscall
40 * calling convention. This isn't needed on other platforms. */
42 static ITextServicesVtbl itextServicesStdcallVtbl
;
43 #define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl)
45 #define TXTSERV_VTABLE(This) (This)->lpVtbl
48 #define ITextServices_TxSendMessage(This,a,b,c,d) TXTSERV_VTABLE(This)->TxSendMessage(This,a,b,c,d)
49 #define ITextServices_TxDraw(This,a,b,c,d,e,f,g,h,i,j,k,l) TXTSERV_VTABLE(This)->TxDraw(This,a,b,c,d,e,f,g,h,i,j,k,l)
50 #define ITextServices_TxGetHScroll(This,a,b,c,d,e) TXTSERV_VTABLE(This)->TxGetHScroll(This,a,b,c,d,e)
51 #define ITextServices_TxGetVScroll(This,a,b,c,d,e) TXTSERV_VTABLE(This)->TxGetVScroll(This,a,b,c,d,e)
52 #define ITextServices_OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) TXTSERV_VTABLE(This)->OnTxSetCursor(This,a,b,c,d,e,f,g,h,i)
53 #define ITextServices_TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) TXTSERV_VTABLE(This)->TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j)
54 #define ITextServices_OnTxInplaceActivate(This,a) TXTSERV_VTABLE(This)->OnTxInplaceActivate(This,a)
55 #define ITextServices_OnTxInplaceDeactivate(This) TXTSERV_VTABLE(This)->OnTxInplaceDeactivate(This)
56 #define ITextServices_OnTxUIActivate(This) TXTSERV_VTABLE(This)->OnTxUIActivate(This)
57 #define ITextServices_OnTxUIDeactivate(This) TXTSERV_VTABLE(This)->OnTxUIDeactivate(This)
58 #define ITextServices_TxGetText(This,a) TXTSERV_VTABLE(This)->TxGetText(This,a)
59 #define ITextServices_TxSetText(This,a) TXTSERV_VTABLE(This)->TxSetText(This,a)
60 #define ITextServices_TxGetCurrentTargetX(This,a) TXTSERV_VTABLE(This)->TxGetCurrentTargetX(This,a)
61 #define ITextServices_TxGetBaseLinePos(This,a) TXTSERV_VTABLE(This)->TxGetBaseLinePos(This,a)
62 #define ITextServices_TxGetNaturalSize(This,a,b,c,d,e,f,g,h) TXTSERV_VTABLE(This)->TxGetNaturalSize(This,a,b,c,d,e,f,g,h)
63 #define ITextServices_TxGetDropTarget(This,a) TXTSERV_VTABLE(This)->TxGetDropTarget(This,a)
64 #define ITextServices_OnTxPropertyBitsChange(This,a,b) TXTSERV_VTABLE(This)->OnTxPropertyBitsChange(This,a,b)
65 #define ITextServices_TxGetCachedSize(This,a,b) TXTSERV_VTABLE(This)->TxGetCachedSize(This,a,b)
67 /* Set the WINETEST_DEBUG environment variable to be greater than 1 for verbose
68 * function call traces of ITextHost. */
69 #define TRACECALL if(winetest_debug > 1) trace
71 /************************************************************************/
72 /* ITextHost implementation for conformance testing. */
74 typedef struct ITextHostTestImpl
76 ITextHostVtbl
*lpVtbl
;
80 static HRESULT WINAPI
ITextHostImpl_QueryInterface(ITextHost
*iface
,
84 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
86 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_ITextHost
)) {
88 ITextHost_AddRef((ITextHost
*)*ppvObject
);
95 static ULONG WINAPI
ITextHostImpl_AddRef(ITextHost
*iface
)
97 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
98 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
102 static ULONG WINAPI
ITextHostImpl_Release(ITextHost
*iface
)
104 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
105 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
116 static HDC WINAPI
ITextHostImpl_TxGetDC(ITextHost
*iface
)
118 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
119 TRACECALL("Call to TxGetDC(%p)\n", This
);
123 static INT WINAPI
ITextHostImpl_TxReleaseDC(ITextHost
*iface
,
126 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
127 TRACECALL("Call to TxReleaseDC(%p)\n", This
);
131 static BOOL WINAPI
ITextHostImpl_TxShowScrollBar(ITextHost
*iface
,
135 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
136 TRACECALL("Call to TxShowScrollBar(%p, fnBar=%d, fShow=%d)\n",
141 static BOOL WINAPI
ITextHostImpl_TxEnableScrollBar(ITextHost
*iface
,
145 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
146 TRACECALL("Call to TxEnableScrollBar(%p, fuSBFlags=%d, fuArrowflags=%d)\n",
147 This
, fuSBFlags
, fuArrowflags
);
151 static BOOL WINAPI
ITextHostImpl_TxSetScrollRange(ITextHost
*iface
,
157 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
158 TRACECALL("Call to TxSetScrollRange(%p, fnBar=%d, nMinPos=%d, nMaxPos=%d, fRedraw=%d)\n",
159 This
, fnBar
, nMinPos
, nMaxPos
, fRedraw
);
163 static BOOL WINAPI
ITextHostImpl_TxSetScrollPos(ITextHost
*iface
,
168 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
169 TRACECALL("Call to TxSetScrollPos(%p, fnBar=%d, nPos=%d, fRedraw=%d)\n",
170 This
, fnBar
, nPos
, fRedraw
);
174 static void WINAPI
ITextHostImpl_TxInvalidateRect(ITextHost
*iface
,
178 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
179 TRACECALL("Call to TxInvalidateRect(%p, prc=%p, fMode=%d)\n",
183 static void WINAPI
ITextHostImpl_TxViewChange(ITextHost
*iface
, BOOL fUpdate
)
185 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
186 TRACECALL("Call to TxViewChange(%p, fUpdate=%d)\n",
190 static BOOL WINAPI
ITextHostImpl_TxCreateCaret(ITextHost
*iface
,
192 INT xWidth
, INT yHeight
)
194 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
195 TRACECALL("Call to TxCreateCaret(%p, nbmp=%p, xWidth=%d, yHeight=%d)\n",
196 This
, hbmp
, xWidth
, yHeight
);
200 static BOOL WINAPI
ITextHostImpl_TxShowCaret(ITextHost
*iface
, BOOL fShow
)
202 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
203 TRACECALL("Call to TxShowCaret(%p, fShow=%d)\n",
208 static BOOL WINAPI
ITextHostImpl_TxSetCaretPos(ITextHost
*iface
,
211 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
212 TRACECALL("Call to TxSetCaretPos(%p, x=%d, y=%d)\n", This
, x
, y
);
216 static BOOL WINAPI
ITextHostImpl_TxSetTimer(ITextHost
*iface
,
217 UINT idTimer
, UINT uTimeout
)
219 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
220 TRACECALL("Call to TxSetTimer(%p, idTimer=%u, uTimeout=%u)\n",
221 This
, idTimer
, uTimeout
);
225 static void WINAPI
ITextHostImpl_TxKillTimer(ITextHost
*iface
, UINT idTimer
)
227 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
228 TRACECALL("Call to TxKillTimer(%p, idTimer=%u)\n", This
, idTimer
);
231 static void WINAPI
ITextHostImpl_TxScrollWindowEx(ITextHost
*iface
,
239 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
240 TRACECALL("Call to TxScrollWindowEx(%p, %d, %d, %p, %p, %p, %p, %d)\n",
241 This
, dx
, dy
, lprcScroll
, lprcClip
, hRgnUpdate
, lprcUpdate
, fuScroll
);
244 static void WINAPI
ITextHostImpl_TxSetCapture(ITextHost
*iface
, BOOL fCapture
)
246 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
247 TRACECALL("Call to TxSetCapture(%p, fCapture=%d)\n", This
, fCapture
);
250 static void WINAPI
ITextHostImpl_TxSetFocus(ITextHost
*iface
)
252 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
253 TRACECALL("Call to TxSetFocus(%p)\n", This
);
256 static void WINAPI
ITextHostImpl_TxSetCursor(ITextHost
*iface
,
260 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
261 TRACECALL("Call to TxSetCursor(%p, hcur=%p, fText=%d)\n",
265 static BOOL WINAPI
ITextHostImpl_TxScreenToClient(ITextHost
*iface
,
268 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
269 TRACECALL("Call to TxScreenToClient(%p, lppt=%p)\n", This
, lppt
);
273 static BOOL WINAPI
ITextHostImpl_TxClientToScreen(ITextHost
*iface
,
276 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
277 TRACECALL("Call to TxClientToScreen(%p, lppt=%p)\n", This
, lppt
);
281 static HRESULT WINAPI
ITextHostImpl_TxActivate(ITextHost
*iface
,
284 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
285 TRACECALL("Call to TxActivate(%p, plOldState=%p)\n", This
, plOldState
);
289 static HRESULT WINAPI
ITextHostImpl_TxDeactivate(ITextHost
*iface
,
292 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
293 TRACECALL("Call to TxDeactivate(%p, lNewState=%d)\n", This
, lNewState
);
297 static HRESULT WINAPI
ITextHostImpl_TxGetClientRect(ITextHost
*iface
,
300 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
301 TRACECALL("Call to TxGetClientRect(%p, prc=%p)\n", This
, prc
);
305 static HRESULT WINAPI
ITextHostImpl_TxGetViewInset(ITextHost
*iface
,
308 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
309 TRACECALL("Call to TxGetViewInset(%p, prc=%p)\n", This
, prc
);
313 static HRESULT WINAPI
ITextHostImpl_TxGetCharFormat(ITextHost
*iface
,
314 const CHARFORMATW
**ppCF
)
316 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
317 TRACECALL("Call to TxGetCharFormat(%p, ppCF=%p)\n", This
, ppCF
);
321 static HRESULT WINAPI
ITextHostImpl_TxGetParaFormat(ITextHost
*iface
,
322 const PARAFORMAT
**ppPF
)
324 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
325 TRACECALL("Call to TxGetParaFormat(%p, ppPF=%p)\n", This
, ppPF
);
329 static COLORREF WINAPI
ITextHostImpl_TxGetSysColor(ITextHost
*iface
,
332 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
333 TRACECALL("Call to TxGetSysColor(%p, nIndex=%d)\n", This
, nIndex
);
337 static HRESULT WINAPI
ITextHostImpl_TxGetBackStyle(ITextHost
*iface
,
338 TXTBACKSTYLE
*pStyle
)
340 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
341 TRACECALL("Call to TxGetBackStyle(%p, pStyle=%p)\n", This
, pStyle
);
345 static HRESULT WINAPI
ITextHostImpl_TxGetMaxLength(ITextHost
*iface
,
348 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
349 TRACECALL("Call to TxGetMaxLength(%p, pLength=%p)\n", This
, pLength
);
353 static HRESULT WINAPI
ITextHostImpl_TxGetScrollBars(ITextHost
*iface
,
356 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
357 TRACECALL("Call to TxGetScrollBars(%p, pdwScrollBar=%p)\n",
362 static HRESULT WINAPI
ITextHostImpl_TxGetPasswordChar(ITextHost
*iface
,
365 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
366 TRACECALL("Call to TxGetPasswordChar(%p, pch=%p)\n", This
, pch
);
370 static HRESULT WINAPI
ITextHostImpl_TxGetAcceleratorPos(ITextHost
*iface
,
373 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
374 TRACECALL("Call to TxGetAcceleratorPos(%p, pch=%p)\n", This
, pch
);
378 static HRESULT WINAPI
ITextHostImpl_TxGetExtent(ITextHost
*iface
,
381 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
382 TRACECALL("Call to TxGetExtent(%p, lpExtent=%p)\n", This
, lpExtent
);
386 static HRESULT WINAPI
ITextHostImpl_OnTxCharFormatChange(ITextHost
*iface
,
387 const CHARFORMATW
*pcf
)
389 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
390 TRACECALL("Call to OnTxCharFormatChange(%p, pcf=%p)\n", This
, pcf
);
394 static HRESULT WINAPI
ITextHostImpl_OnTxParaFormatChange(ITextHost
*iface
,
395 const PARAFORMAT
*ppf
)
397 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
398 TRACECALL("Call to OnTxParaFormatChange(%p, ppf=%p)\n", This
, ppf
);
402 /* This must return S_OK for the native ITextServices object to
404 static HRESULT WINAPI
ITextHostImpl_TxGetPropertyBits(ITextHost
*iface
,
408 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
409 TRACECALL("Call to TxGetPropertyBits(%p, dwMask=0x%08x, pdwBits=%p)\n",
410 This
, dwMask
, pdwBits
);
415 static HRESULT WINAPI
ITextHostImpl_TxNotify(ITextHost
*iface
, DWORD iNotify
,
418 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
419 TRACECALL("Call to TxNotify(%p, iNotify=%d, pv=%p)\n", This
, iNotify
, pv
);
423 static HIMC WINAPI
ITextHostImpl_TxImmGetContext(ITextHost
*iface
)
425 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
426 TRACECALL("Call to TxImmGetContext(%p)\n", This
);
430 static void WINAPI
ITextHostImpl_TxImmReleaseContext(ITextHost
*iface
, HIMC himc
)
432 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
433 TRACECALL("Call to TxImmReleaseContext(%p, himc=%p)\n", This
, himc
);
436 static HRESULT WINAPI
ITextHostImpl_TxGetSelectionBarWidth(ITextHost
*iface
,
439 ITextHostTestImpl
*This
= (ITextHostTestImpl
*)iface
;
440 TRACECALL("Call to TxGetSelectionBarWidth(%p, lSelBarWidth=%p)\n",
445 static ITextHostVtbl itextHostVtbl
= {
446 ITextHostImpl_QueryInterface
,
447 ITextHostImpl_AddRef
,
448 ITextHostImpl_Release
,
449 ITextHostImpl_TxGetDC
,
450 ITextHostImpl_TxReleaseDC
,
451 ITextHostImpl_TxShowScrollBar
,
452 ITextHostImpl_TxEnableScrollBar
,
453 ITextHostImpl_TxSetScrollRange
,
454 ITextHostImpl_TxSetScrollPos
,
455 ITextHostImpl_TxInvalidateRect
,
456 ITextHostImpl_TxViewChange
,
457 ITextHostImpl_TxCreateCaret
,
458 ITextHostImpl_TxShowCaret
,
459 ITextHostImpl_TxSetCaretPos
,
460 ITextHostImpl_TxSetTimer
,
461 ITextHostImpl_TxKillTimer
,
462 ITextHostImpl_TxScrollWindowEx
,
463 ITextHostImpl_TxSetCapture
,
464 ITextHostImpl_TxSetFocus
,
465 ITextHostImpl_TxSetCursor
,
466 ITextHostImpl_TxScreenToClient
,
467 ITextHostImpl_TxClientToScreen
,
468 ITextHostImpl_TxActivate
,
469 ITextHostImpl_TxDeactivate
,
470 ITextHostImpl_TxGetClientRect
,
471 ITextHostImpl_TxGetViewInset
,
472 ITextHostImpl_TxGetCharFormat
,
473 ITextHostImpl_TxGetParaFormat
,
474 ITextHostImpl_TxGetSysColor
,
475 ITextHostImpl_TxGetBackStyle
,
476 ITextHostImpl_TxGetMaxLength
,
477 ITextHostImpl_TxGetScrollBars
,
478 ITextHostImpl_TxGetPasswordChar
,
479 ITextHostImpl_TxGetAcceleratorPos
,
480 ITextHostImpl_TxGetExtent
,
481 ITextHostImpl_OnTxCharFormatChange
,
482 ITextHostImpl_OnTxParaFormatChange
,
483 ITextHostImpl_TxGetPropertyBits
,
484 ITextHostImpl_TxNotify
,
485 ITextHostImpl_TxImmGetContext
,
486 ITextHostImpl_TxImmReleaseContext
,
487 ITextHostImpl_TxGetSelectionBarWidth
490 static ITextServices
*txtserv
= NULL
;
491 static ITextHostTestImpl
*dummyTextHost
;
492 static void *wrapperCodeMem
= NULL
;
494 #include "pshpack1.h"
496 /* Code structure for x86 byte code */
499 BYTE pop_eax
; /* popl %eax */
500 BYTE push_ecx
; /* pushl %ecx */
501 BYTE push_eax
; /* pushl %eax */
502 BYTE jmp_func
; /* jmp $func */
504 } THISCALL_TO_STDCALL_THUNK
;
508 BYTE pop_eax
; /* popl %eax */
509 BYTE pop_ecx
; /* popl %ecx */
510 BYTE push_eax
; /* pushl %eax */
511 BYTE mov_vtable_eax
[2]; /* movl (%ecx), %eax */
512 BYTE jmp_eax
[2]; /* jmp *$vtablefunc_offset(%eax) */
513 int vtablefunc_offset
;
514 } STDCALL_TO_THISCALL_THUNK
;
518 static void setup_thiscall_wrappers(void)
523 THISCALL_TO_STDCALL_THUNK
*thunk
;
524 STDCALL_TO_THISCALL_THUNK
*thunk2
;
526 wrapperCodeMem
= VirtualAlloc(NULL
,
527 (sizeof(ITextHostVtbl
)/sizeof(void*) - 3)
528 * sizeof(THISCALL_TO_STDCALL_THUNK
)
529 +(sizeof(ITextServicesVtbl
)/sizeof(void*) - 3)
530 * sizeof(STDCALL_TO_THISCALL_THUNK
),
531 MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
532 thunk
= wrapperCodeMem
;
534 /* Wrap all ITextHostImpl methods with code to perform a thiscall to
535 * stdcall conversion. The thiscall calling convention places the This
536 * pointer in ecx on the x86 platform, and the stdcall calling convention
537 * pushes the This pointer on the stack as the first argument.
539 * The byte code does the conversion then jumps to the real function.
541 * Each wrapper needs to be modified so that the function to jump to is
542 * modified in the byte code. */
544 /* Skip QueryInterface, AddRef, and Release native actually
545 * defined them with the stdcall calling convention. */
546 pVtable
= (void**)&itextHostVtbl
+ 3;
547 pVtableEnd
= (void**)(&itextHostVtbl
+ 1);
548 while (pVtable
!= pVtableEnd
) {
549 /* write byte code to executable memory */
550 thunk
->pop_eax
= 0x58; /* popl %eax */
551 thunk
->push_ecx
= 0x51; /* pushl %ecx */
552 thunk
->push_eax
= 0x50; /* pushl %eax */
553 thunk
->jmp_func
= 0xe9; /* jmp $func */
554 /* The address needs to be relative to the end of the jump instructions. */
555 thunk
->func
= (char*)*pVtable
- (char*)(&thunk
->func
+ 1);
561 /* Setup an ITextServices standard call vtable that will call the
562 * native thiscall vtable when the methods are called. */
564 /* QueryInterface, AddRef, and Release should be called directly on the
565 * real vtable since they use the stdcall calling convention. */
566 thunk2
= (STDCALL_TO_THISCALL_THUNK
*)thunk
;
567 pVtable
= (void**)&itextServicesStdcallVtbl
+ 3;
568 pVtableEnd
= (void**)(&itextServicesStdcallVtbl
+ 1);
569 while (pVtable
!= pVtableEnd
) {
570 /* write byte code to executable memory */
571 thunk2
->pop_eax
= 0x58; /* popl %eax */
572 thunk2
->pop_ecx
= 0x59; /* popl %ecx */
573 thunk2
->push_eax
= 0x50; /* pushl %eax */
574 thunk2
->mov_vtable_eax
[0] = 0x8b; /* movl (%ecx), %eax */
575 thunk2
->mov_vtable_eax
[1] = 0x01;
576 thunk2
->jmp_eax
[0] = 0xff; /* jmp *$vtablefunc_offset(%eax) */
577 thunk2
->jmp_eax
[1] = 0xa0;
578 thunk2
->vtablefunc_offset
= (char*)pVtable
- (char*)&itextServicesStdcallVtbl
;
583 #endif /* __i386__ */
586 /*************************************************************************/
587 /* Conformance test functions. */
589 /* Initialize the test texthost structure */
590 static BOOL
init_texthost(void)
594 PCreateTextServices pCreateTextServices
;
596 dummyTextHost
= CoTaskMemAlloc(sizeof(*dummyTextHost
));
597 if (dummyTextHost
== NULL
) {
598 skip("Insufficient memory to create ITextHost interface\n");
601 dummyTextHost
->lpVtbl
= &itextHostVtbl
;
602 dummyTextHost
->refCount
= 1;
604 /* MSDN states that an IUnknown object is returned by
605 CreateTextServices which is then queried to obtain a
606 ITextServices object. */
607 pCreateTextServices
= (void*)GetProcAddress(hmoduleRichEdit
, "CreateTextServices");
608 result
= (*pCreateTextServices
)(NULL
,(ITextHost
*)dummyTextHost
, &init
);
609 ok(result
== S_OK
, "Did not return OK when created. Returned %x\n", result
);
610 if (result
!= S_OK
) {
611 CoTaskMemFree(dummyTextHost
);
612 skip("CreateTextServices failed.\n");
616 result
= IUnknown_QueryInterface(init
, &IID_ITextServices
,
618 ok((result
== S_OK
) && (txtserv
!= NULL
), "Querying interface failed\n");
619 IUnknown_Release(init
);
620 if (!((result
== S_OK
) && (txtserv
!= NULL
))) {
621 CoTaskMemFree(dummyTextHost
);
622 skip("Could not retrieve ITextServices interface\n");
629 static void test_TxGetText(void)
634 if (!init_texthost())
637 hres
= ITextServices_TxGetText(txtserv
, &rettext
);
638 todo_wine
ok(hres
== S_OK
, "ITextServices_TxGetText failed\n");
640 IUnknown_Release(txtserv
);
641 CoTaskMemFree(dummyTextHost
);
646 setup_thiscall_wrappers();
648 /* Must explicitly LoadLibrary(). The test has no references to functions in
649 * RICHED20.DLL, so the linker doesn't actually link to it. */
650 hmoduleRichEdit
= LoadLibrary("RICHED20.DLL");
651 ok(hmoduleRichEdit
!= NULL
, "error: %d\n", (int) GetLastError());
655 IUnknown_Release(txtserv
);
656 CoTaskMemFree(dummyTextHost
);
660 if (wrapperCodeMem
) VirtualFree(wrapperCodeMem
, 0, MEM_RELEASE
);