From a9f13beffbbb06b7ba5bdae0b068d8741f27eb98 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Sat, 25 Oct 2008 20:37:42 -0400 Subject: richedit: Created initial tests for windowless richedit controls. To: wine-patches Reply-To: wine-devel@winehq.org MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------1.5.4.3" This is a multi-part message in MIME format. --------------1.5.4.3 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit The initial tests added simply call CreatTextServices, and query for the ITextServices interface, then cleans up. Since CreateTextServices needs an implementation of ITextHost to be given, this patch needed a stub implementation. This required wrappers for converting thiscall to stdcall, which is why the macros borrowed from port.h and config.h. All of this is why the patch got quicky bloated. The code borrowed from config.h for the __ASM_FUNC and __ASM_NAME macros was only tested with gcc and mingw, so I am not sure if it works with other platforms. Since config.h is autogenerated from configure, I was not able to borrow proper conditional macros, and both config.h and port.h aren't supposed to be included in tests according to errors in wine/test.h --- dlls/riched20/tests/Makefile.in | 3 +- dlls/riched20/tests/txtsrv.c | 664 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 666 insertions(+), 1 deletions(-) create mode 100644 dlls/riched20/tests/txtsrv.c --------------1.5.4.3 Content-Type: text/x-patch; name="a9f13beffbbb06b7ba5bdae0b068d8741f27eb98.diff" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="a9f13beffbbb06b7ba5bdae0b068d8741f27eb98.diff" diff --git a/dlls/riched20/tests/Makefile.in b/dlls/riched20/tests/Makefile.in index 0993609..9690e5e 100644 --- a/dlls/riched20/tests/Makefile.in +++ b/dlls/riched20/tests/Makefile.in @@ -7,7 +7,8 @@ IMPORTS = ole32 user32 gdi32 kernel32 CTESTS = \ editor.c \ - richole.c + richole.c \ + txtsrv.c @MAKE_TEST_RULES@ diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c new file mode 100644 index 0000000..5be953a --- /dev/null +++ b/dlls/riched20/tests/txtsrv.c @@ -0,0 +1,664 @@ +/* + * Unit test suite for windowless rich edit controls + * + * Copyright 2008 Maarten Lankhorst + * Copyright 2008 Austin Lund + * Copyright 2008 Dylan Smith + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static HMODULE hmoduleRichEdit; + +/* This is defined in config.h that can't be included in the tests. */ +#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__CYGWIN__) + +/* Define to a macro to generate an assembly function directive */ +# define __ASM_FUNC(name) ".type " __ASM_NAME(name) ",@function" +/* Define to a macro to generate an assembly name from a C symbol */ +# define __ASM_NAME(name) name + +#else /* defined(__GNUC__) && !defined(__MINGW32__) && !defined(__APPLE__) */ + +/* Define to a macro to generate an assembly function directive */ +# define __ASM_FUNC(name) ".def " __ASM_NAME(name) "; .scl 2; .type 32; .endef" +/* Define to a macro to generate an assembly name from a C symbol */ +# define __ASM_NAME(name) "_" name + +#endif /* __GNUC__ */ + +/* Macros to define assembler functions somewhat portably */ +/* This is defined in wine/port.h but can't be included in the tests. */ +#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__APPLE__) +# define __ASM_GLOBAL_FUNC(name,code) \ + __asm__( ".text\n\t" \ + ".align 4\n\t" \ + ".globl " __ASM_NAME(#name) "\n\t" \ + __ASM_FUNC(#name) "\n" \ + __ASM_NAME(#name) ":\n\t" \ + code \ + "\n\t.previous" ); +#else /* defined(__GNUC__) && !defined(__MINGW32__) && !defined(__APPLE__) */ +# define __ASM_GLOBAL_FUNC(name,code) \ + void __asm_dummy_##name(void) { \ + asm( ".align 4\n\t" \ + ".globl " __ASM_NAME(#name) "\n\t" \ + __ASM_FUNC(#name) "\n" \ + __ASM_NAME(#name) ":\n\t" \ + code ); \ + } +#endif /* __GNUC__ */ + +/* Set the WINETEST_DEBUG environment variable to be greater than 1 for verbose + * function call traces of ITextHost. */ +#define TRACECALL if(winetest_debug > 1) trace + +/************************************************************************/ +/* ITextHost implementation for conformance testing. */ + +typedef struct ITextHostTestImpl { + ITextHostVtbl *lpVtbl; + LONG refCount; +} ITextHostTestImpl; + +static ITextHostVtbl itestvtbl; + +static HRESULT WINAPI ITextHostImpl_QueryInterface(ITextHost *iface, + REFIID riid, + LPVOID *ppvObject) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ITextHost)) { + *ppvObject = (LPVOID)This; + ITextHost_AddRef((ITextHost *)(*ppvObject)); + return S_OK; + } + else + return E_NOINTERFACE; +} + +static ULONG WINAPI ITextHostImpl_AddRef(ITextHost *iface) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + ULONG refCount = InterlockedIncrement(&This->refCount); + return refCount; +} + +static ULONG WINAPI ITextHostImpl_Release(ITextHost *iface) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + ULONG refCount = InterlockedDecrement(&This->refCount); + + if (!refCount) + { + CoTaskMemFree(This); + return 0; + } + else + return refCount; +} + +HDC WINAPI ITextHostImpl_TxGetDC(ITextHost *iface) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetDC(%p)\n", This); + return NULL; +} + +INT WINAPI ITextHostImpl_TxReleaseDC(ITextHost *iface, + HDC hdc) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxReleaseDC(%p)\n", This); + return 0; +} + +BOOL WINAPI ITextHostImpl_TxShowScrollBar(ITextHost *iface, + INT fnBar, + BOOL fShow) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxShowScrollBar(%p, fnBar=%d, fShow=%d)\n", + This, fnBar, fShow); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxEnableScrollBar(ITextHost *iface, + INT fuSBFlags, + INT fuArrowflags) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxEnableScrollBar(%p, fuSBFlags=%d, fuArrowflags=%d)\n", + This, fuSBFlags, fuArrowflags); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetScrollRange(ITextHost *iface, + INT fnBar, + LONG nMinPos, + INT nMaxPos, + BOOL fRedraw) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxSetScrollRange(%p, fnBar=%d, nMinPos=%d, nMaxPos=%d, fRedraw=%d)\n", + This, fnBar, nMinPos, nMaxPos, fRedraw); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetScrollPos(ITextHost *iface, + INT fnBar, + INT nPos, + BOOL fRedraw) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxSetScrollPos(%p, fnBar=%d, nPos=%d, fRedraw=%d)\n", + This, fnBar, nPos, fRedraw); + return E_NOTIMPL; +} + +void WINAPI ITextHostImpl_TxInvalidateRect(ITextHost *iface, + LPCRECT prc, + BOOL fMode) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxInvalidateRect(%p, prc=%p, fMode=%d)\n", + This, prc, fMode); +} + +void WINAPI ITextHostImpl_TxViewChange(ITextHost *iface, BOOL fUpdate) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxViewChange(%p, fUpdate=%d)\n", + This, fUpdate); +} + +BOOL WINAPI ITextHostImpl_TxCreateCaret(ITextHost *iface, + HBITMAP hbmp, + INT xWidth, INT yHeight) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxCreateCaret(%p, nbmp=%p, xWidth=%d, yHeight=%d)\n", + This, hbmp, xWidth, yHeight); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxShowCaret(ITextHost *iface, BOOL fShow) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxShowCaret(%p, fShow=%d)\n", + This, fShow); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetCaretPos(ITextHost *iface, + INT x, INT y) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxSetCaretPos(%p, x=%d, y=%d)\n", This, x, y); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxSetTimer(ITextHost *iface, + UINT idTimer, UINT uTimeout) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxSetTimer(%p, idTimer=%u, uTimeout=%u)\n", + This, idTimer, uTimeout); + return E_NOTIMPL; +} + +void WINAPI ITextHostImpl_TxKillTimer(ITextHost *iface, UINT idTimer) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxKillTimer(%p, idTimer=%u)\n", This, idTimer); +} + +void WINAPI ITextHostImpl_TxScrollWindowEx(ITextHost *iface, + INT dx, INT dy, + LPCRECT lprcScroll, + LPCRECT lprcClip, + HRGN hRgnUpdate, + LPRECT lprcUpdate, + UINT fuScroll) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxScrollWindowEx(%p, %d, %d, %p, %p, %p, %p, %d)\n", + This, dx, dy, lprcScroll, lprcClip, hRgnUpdate, lprcUpdate, fuScroll); +} + +void WINAPI ITextHostImpl_TxSetCapture(ITextHost *iface, BOOL fCapture) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxSetCapture(%p, fCapture=%d)\n", This, fCapture); +} + +void WINAPI ITextHostImpl_TxSetFocus(ITextHost *iface) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxSetFocus(%p)\n", This); +} + +void WINAPI ITextHostImpl_TxSetCursor(ITextHost *iface, + HCURSOR hcur, + BOOL fText) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxSetCursor(%p, hcur=%p, fText=%d)\n", + This, hcur, fText); +} + +BOOL WINAPI ITextHostImpl_TxScreenToClient(ITextHost *iface, + LPPOINT lppt) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxScreenToClient(%p, lppt=%p)\n", This, lppt); + return E_NOTIMPL; +} + +BOOL WINAPI ITextHostImpl_TxClientToScreen(ITextHost *iface, + LPPOINT lppt) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxClientToScreen(%p, lppt=%p)\n", This, lppt); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxActivate(ITextHost *iface, + LONG *plOldState) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxActivate(%p, plOldState=%p)\n", This, plOldState); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxDeactivate(ITextHost *iface, + LONG lNewState) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxDeactivate(%p, lNewState=%d)\n", This, lNewState); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetClientRect(ITextHost *iface, + LPRECT prc) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetClientRect(%p, prc=%p)\n", This, prc); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetViewInset(ITextHost *iface, + LPRECT prc) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetViewInset(%p, prc=%p)\n", This, prc); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetCharFormat(ITextHost *iface, + const CHARFORMATW **ppCF) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetCharFormat(%p, ppCF=%p)\n", This, ppCF); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetParaFormat(ITextHost *iface, + const PARAFORMAT **ppPF) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetParaFormat(%p, ppPF=%p)\n", This, ppPF); + return E_NOTIMPL; +} + +COLORREF WINAPI ITextHostImpl_TxGetSysColor(ITextHost *iface, + int nIndex) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetSysColor(%p, nIndex=%d)\n", This, nIndex); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetBackStyle(ITextHost *iface, + TXTBACKSTYLE *pStyle) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetBackStyle(%p, pStyle=%p)\n", This, pStyle); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetMaxLength(ITextHost *iface, + DWORD *pLength) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetMaxLength(%p, pLength=%p)\n", This, pLength); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetScrollbars(ITextHost *iface, + DWORD *pdwScrollBar) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetScrollbars(%p, pdwScrollBar=%p)\n", + This, pdwScrollBar); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetPasswordChar(ITextHost *iface, + WCHAR *pch) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetPasswordChar(%p, pch=%p)\n", This, pch); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetAcceleratorPos(ITextHost *iface, + LONG *pch) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetAcceleratorPos(%p, pch=%p)\n", This, pch); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_TxGetExtent(ITextHost *iface, + LPSIZEL lpExtent) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetExtent(%p, lpExtent=%p)\n", This, lpExtent); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_OnTxCharFormatChange(ITextHost *iface, + const CHARFORMATW *pcf) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to OnTxCharFormatChange(%p, pcf=%p)\n", This, pcf); + return E_NOTIMPL; +} + +HRESULT WINAPI ITextHostImpl_OnTxParaFormatChange(ITextHost *iface, + const PARAFORMAT *ppf) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to OnTxParaFormatChange(%p, ppf=%p)\n", This, ppf); + return E_NOTIMPL; +} + +/* This must return S_OK for the native ITextServices object to + initialize. */ +HRESULT WINAPI ITextHostImpl_TxGetPropertyBits(ITextHost *iface, + DWORD dwMask, + DWORD *pdwBits) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetPropertyBits(%p, dwMask=0x%08x, pdwBits=%p)\n", + This, dwMask, pdwBits); + *pdwBits = 0; + return S_OK; +} + +HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, + void *pv) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxNotify(%p, iNotify=%d, pv=%p)\n", This, iNotify, pv); + return E_NOTIMPL; +} + +HIMC WINAPI ITextHostImpl_TxImmGetContext(ITextHost *iface) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxImmGetContext(%p)\n", This); + return 0; +} + +void WINAPI ITextHostImpl_TxImmReleaseContext(ITextHost *iface, HIMC himc) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxImmReleaseContext(%p, himc=%p)\n", This, himc); +} + +HRESULT WINAPI ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface, + LONG *lSelBarWidth) +{ + ITextHostTestImpl *This = (ITextHostTestImpl *)iface; + TRACECALL("Call to TxGetSelectionBarWidth(%p, lSelBarWidth=%p)\n", + This, lSelBarWidth); + return E_NOTIMPL; +} + +/* Each function must now be converted into a thiscall style function. + * These wrappers do this. */ + +#ifdef __i386__ /* thiscall functions are i386-specific */ +#define THISCALL(func) __thiscall_ ## func +#else /* __i386__ */ +#define THISCALL(func) func +#endif /* __i386__ */ + +HDC WINAPI THISCALL(ITextHostImpl_TxGetDC)(ITextHost *iface); +INT WINAPI THISCALL(ITextHostImpl_TxReleaseDC)(ITextHost *iface, HDC hdc); +BOOL WINAPI THISCALL(ITextHostImpl_TxShowScrollBar)(ITextHost *iface,INT fnBar,BOOL fShow); +BOOL WINAPI THISCALL(ITextHostImpl_TxEnableScrollBar)(ITextHost *iface,INT fuSBFlags,INT fuArrowflags); +BOOL WINAPI THISCALL(ITextHostImpl_TxSetScrollRange)(ITextHost *iface,INT fnBar,LONG nMinPos,INT nMaxPos,BOOL fRedraw); +BOOL WINAPI THISCALL(ITextHostImpl_TxSetScrollPos)(ITextHost *iface,INT fnBar,INT nPos,BOOL fRedraw); +void WINAPI THISCALL(ITextHostImpl_TxInvalidateRect)(ITextHost *iface,LPCRECT prc,BOOL fMode); +void WINAPI THISCALL(ITextHostImpl_TxViewChange)(ITextHost *iface, BOOL fUpdate); +BOOL WINAPI THISCALL(ITextHostImpl_TxCreateCaret)(ITextHost *iface,HBITMAP hbmp,INT xWidth, INT yHeight); +BOOL WINAPI THISCALL(ITextHostImpl_TxShowCaret)(ITextHost *iface, BOOL fShow); +BOOL WINAPI THISCALL(ITextHostImpl_TxSetCaretPos)(ITextHost *iface,INT x, INT y); +BOOL WINAPI THISCALL(ITextHostImpl_TxSetTimer)(ITextHost *iface,UINT idTimer, UINT uTimeout); +void WINAPI THISCALL(ITextHostImpl_TxKillTimer)(ITextHost *iface, UINT idTimer); +void WINAPI THISCALL(ITextHostImpl_TxScrollWindowEx)(ITextHost *iface,INT dx, INT dy,LPCRECT lprcScroll,LPCRECT lprcClip,HRGN hRgnUpdate,LPRECT lprcUpdate,UINT fuScroll); +void WINAPI THISCALL(ITextHostImpl_TxSetCapture)(ITextHost *iface, BOOL fCapture); +void WINAPI THISCALL(ITextHostImpl_TxSetFocus)(ITextHost *iface); +void WINAPI THISCALL(ITextHostImpl_TxSetCursor)(ITextHost *iface,HCURSOR hcur,BOOL fText); +BOOL WINAPI THISCALL(ITextHostImpl_TxScreenToClient)(ITextHost *iface,LPPOINT lppt); +BOOL WINAPI THISCALL(ITextHostImpl_TxClientToScreen)(ITextHost *iface,LPPOINT lppt); +HRESULT WINAPI THISCALL(ITextHostImpl_TxActivate)(ITextHost *iface,LONG *plOldState); +HRESULT WINAPI THISCALL(ITextHostImpl_TxDeactivate)(ITextHost *iface,LONG lNewState); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetClientRect)(ITextHost *iface,LPRECT prc); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetViewInset)(ITextHost *iface,LPRECT prc); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetCharFormat)(ITextHost *iface,const CHARFORMATW **ppCF); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetParaFormat)(ITextHost *iface,const PARAFORMAT **ppPF); +COLORREF WINAPI THISCALL(ITextHostImpl_TxGetSysColor)(ITextHost *iface,int nIndex); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetBackStyle)(ITextHost *iface,TXTBACKSTYLE *pStyle); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetMaxLength)(ITextHost *iface,DWORD *plength); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetScrollbars)(ITextHost *iface,DWORD *pdwScrollBar); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetPasswordChar)(ITextHost *iface,WCHAR *pch); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetAcceleratorPos)(ITextHost *iface,LONG *pch); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetExtent)(ITextHost *iface,LPSIZEL lpExtent); +HRESULT WINAPI THISCALL(ITextHostImpl_OnTxCharFormatChange)(ITextHost *iface,const CHARFORMATW *pcf); +HRESULT WINAPI THISCALL(ITextHostImpl_OnTxParaFormatChange)(ITextHost *iface,const PARAFORMAT *ppf); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetPropertyBits)(ITextHost *iface,DWORD dwMask,DWORD *pdwBits); +HRESULT WINAPI THISCALL(ITextHostImpl_TxNotify)(ITextHost *iface, DWORD iNotify,void *pv); +HIMC WINAPI THISCALL(ITextHostImpl_TxImmGetContext)(ITextHost *iface); +void WINAPI THISCALL(ITextHostImpl_TxImmReleaseContext)(ITextHost *iface, HIMC himc); +HRESULT WINAPI THISCALL(ITextHostImpl_TxGetSelectionBarWidth)(ITextHost *iface,LONG *lSelBarWidth); + +/* In order to call thiscall functions using stdcall, the values + * passed via the registers are pushed onto the stack. The return + * pointer needs to be bypassed to maintain the intergrity of the + * stack. + */ + +#ifdef __i386__ +#define DEFINE_THISCALL_WRAPPER(func) \ + __ASM_GLOBAL_FUNC(__thiscall_ ## func, \ + "popl %eax\n\t" \ + "pushl %ecx\n\t" \ + "pushl %eax\n\t" \ + "jmp " __ASM_NAME(#func) ) +#else /* __i386__ */ +#define DEFINE_THISCALL_WRAPPER(func) /* nothing */ +#endif /* __i386__ */ + +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollbars) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext) +DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth) + +static ITextHostVtbl itestvtbl = { + ITextHostImpl_QueryInterface, + ITextHostImpl_AddRef, + ITextHostImpl_Release, + THISCALL(ITextHostImpl_TxGetDC), + THISCALL(ITextHostImpl_TxReleaseDC), + THISCALL(ITextHostImpl_TxShowScrollBar), + THISCALL(ITextHostImpl_TxEnableScrollBar), + THISCALL(ITextHostImpl_TxSetScrollRange), + THISCALL(ITextHostImpl_TxSetScrollPos), + THISCALL(ITextHostImpl_TxInvalidateRect), + THISCALL(ITextHostImpl_TxViewChange), + THISCALL(ITextHostImpl_TxCreateCaret), + THISCALL(ITextHostImpl_TxShowCaret), + THISCALL(ITextHostImpl_TxSetCaretPos), + THISCALL(ITextHostImpl_TxSetTimer), + THISCALL(ITextHostImpl_TxKillTimer), + THISCALL(ITextHostImpl_TxScrollWindowEx), + THISCALL(ITextHostImpl_TxSetCapture), + THISCALL(ITextHostImpl_TxSetFocus), + THISCALL(ITextHostImpl_TxSetCursor), + THISCALL(ITextHostImpl_TxScreenToClient), + THISCALL(ITextHostImpl_TxClientToScreen), + THISCALL(ITextHostImpl_TxActivate), + THISCALL(ITextHostImpl_TxDeactivate), + THISCALL(ITextHostImpl_TxGetClientRect), + THISCALL(ITextHostImpl_TxGetViewInset), + THISCALL(ITextHostImpl_TxGetCharFormat), + THISCALL(ITextHostImpl_TxGetParaFormat), + THISCALL(ITextHostImpl_TxGetSysColor), + THISCALL(ITextHostImpl_TxGetBackStyle), + THISCALL(ITextHostImpl_TxGetMaxLength), + THISCALL(ITextHostImpl_TxGetScrollbars), + THISCALL(ITextHostImpl_TxGetPasswordChar), + THISCALL(ITextHostImpl_TxGetAcceleratorPos), + THISCALL(ITextHostImpl_TxGetExtent), + THISCALL(ITextHostImpl_OnTxCharFormatChange), + THISCALL(ITextHostImpl_OnTxParaFormatChange), + THISCALL(ITextHostImpl_TxGetPropertyBits), + THISCALL(ITextHostImpl_TxNotify), + THISCALL(ITextHostImpl_TxImmGetContext), + THISCALL(ITextHostImpl_TxImmReleaseContext), + THISCALL(ITextHostImpl_TxGetSelectionBarWidth) +}; + +ITextServices *txtserv = NULL; +ITextHostTestImpl *dummyTextHost; + +/*************************************************************************/ +/* Conformance test functions. */ + +/* Initialize the test texthost structure */ +BOOL init_texthost() +{ + IUnknown *init; + HRESULT result; + PCreateTextServices pCreateTextServices; + + dummyTextHost = CoTaskMemAlloc(sizeof(*dummyTextHost)); + if (dummyTextHost == NULL) { + skip("Insufficient memory to create ITextHost interface\n"); + return FALSE; + } + dummyTextHost->lpVtbl = &itestvtbl; + dummyTextHost->refCount = 1; + + /* MSDN states that an IUnknown object is returned by + CreateTextServices which is then queried to obtain a + ITextServices object. */ + pCreateTextServices = (void*)GetProcAddress(hmoduleRichEdit, "CreateTextServices"); + result = (*pCreateTextServices)(NULL,(ITextHost*)dummyTextHost, &init); + ok(result == S_OK, "Did not return OK when created. Returned %x\n", result); + if (result != S_OK) { + CoTaskMemFree(dummyTextHost); + skip("CreateTextServices failed.\n"); + return FALSE; + } + + result = IUnknown_QueryInterface(init, &IID_ITextServices, + (void **)&txtserv); + ok((result == S_OK) && (txtserv != NULL), "Querying interface failed\n"); + IUnknown_Release(init); + if (!((result == S_OK) && (txtserv != NULL))) { + CoTaskMemFree(dummyTextHost); + skip("Could not retrieve ITextServices interface\n"); + return FALSE; + } + + return TRUE; +} + +START_TEST( txtsrv ) +{ + /* Must explicitly LoadLibrary(). The test has no references to functions in + * RICHED20.DLL, so the linker doesn't actually link to it. */ + hmoduleRichEdit = LoadLibrary("RICHED20.DLL"); + ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError()); + + if (!init_texthost()) + return; + + IUnknown_Release(txtserv); + CoTaskMemFree(dummyTextHost); +} --------------1.5.4.3--