diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c index 4ee6246..7286706 100644 --- a/dlls/riched20/tests/txtsrv.c +++ b/dlls/riched20/tests/txtsrv.c @@ -73,6 +73,270 @@ static HMODULE hmoduleRichEdit; } #endif /* __GNUC__ */ +/* The ITextServices methods are defined as having the thiscall calling + * convention (the default calling convention for c++ methods). This is + * not compatible with the stdcall calling convention because the "This" + * pointer is stored in the ecx register on x86 machines. + * + * The following code manipulates the stack after a call to change + * the calling convention, then jumps right to the actual method. + */ +#ifdef __i386__ +#define STDCALL_TO_THISCALL \ + "movl 0x8(%esp), %ecx\n\t" \ + "popl %eax\n\t" \ + "movl %eax, 0x4(%esp)\n\t" \ + "popl %eax\n\t" \ + "jmp *%eax" + +#define THISCALL_NEEDED +#endif + +/* ITextServices functions used are now wrapped with this construct. */ + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxSendMessage(LPVOID function, + ITextServices *iface, + UINT msg, + WPARAM wparam, + LPARAM lparam, + LRESULT* plresult); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxSendMessage, STDCALL_TO_THISCALL); +#define ITextServices_TxSendMessage(This,a,b,c,d) fnTextSrv_TxSendMessage((This)->lpVtbl->TxSendMessage,This,a,b,c,d) +#else +#define ITextServices_TxSendMessage(This,a,b,c,d) (This)->lpVtbl->TxSendMessage(This,a,b,c,d) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxDraw(LPVOID function, + ITextServices *iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcDraw, + HDC hdcTargetDev, + LPCRECTL lprcBounds, + LPCRECTL lprcWBounds, + LPRECT lprcUpdate, + BOOL (CALLBACK * pfnContinue)(DWORD), + DWORD dwContinue, + LONG lViewId); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxDraw, STDCALL_TO_THISCALL) +#define ITextServices_TxDraw(This,a,b,c,d,e,f,g,h,i,j,k,l) fnTextSrv_TxDraw((This)->lpVtbl->TxDraw,This,a,b,c,d,e,f,g,h,i,j,k,l) +#else +#define ITextServices_TxDraw(This,a,b,c,d,e,f,g,h,i,j,k,l) (This)->lpVtbl->TxDraw(This,a,b,c,d,e,f,g,h,i,j,k,l) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxGetHScroll(LPVOID function, + ITextServices *iface, + LONG* plMin, + LONG* plMax, + LONG* plPos, + LONG* plPage, + BOOL* pfEnabled); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetHScroll, STDCALL_TO_THISCALL) +#define ITextServices_TxGetHScroll(This,a,b,c,d,e) fnTextSrv_TxGetHScroll((This)->lpVtbl->TxGetHScroll,This,a,b,c,d,e) +#else +#define ITextServices_TxGetHScroll(This,a,b,c,d,e) (This)->lpVtbl->TxGetHScroll(This,a,b,c,d,e) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxGetVScroll(LPVOID function, + ITextServices *iface, + LONG* plMin, + LONG* plMax, + LONG* plPos, + LONG* plPage, + BOOL* pfEnabled); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetVScroll, STDCALL_TO_THISCALL) +#define ITextServices_TxGetVScroll(This,a,b,c,d,e) fnTextSrv_TxGetVScroll((This)->lpVtbl->TxGetVScroll,This,a,b,c,d,e) +#else +#define ITextServices_TxGetVScroll(This,a,b,c,d,e) (This)->lpVtbl->TxGetVScroll(This,a,b,c,d,e) +#endif + +#ifdef THISCALL_NEEDED +HRESULT WINAPI fnTextSrv_OnTxSetCursor(LPVOID function, + ITextServices *iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcDraw, + HDC hicTargetDev, + LPCRECT lprcClient, + INT x, INT y); + +__ASM_GLOBAL_FUNC(fnTextSrv_OnTxSetCursor, STDCALL_TO_THISCALL) +#define ITextServices_OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) fnTextSrv_OnTxSetCursor((This)->lpVtbl->OnTxSetCursor,This,a,b,c,d,e,f,g,h,i) +#else +#define ITextServices_OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) (This)->lpVtbl->OnTxSetCursor(This,a,b,c,d,e,f,g,h,i) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxQueryHitPoint(LPVOID function, + ITextServices *iface, + DWORD dwDrawAspect, + LONG lindex, + void* pvAspect, + DVTARGETDEVICE* ptd, + HDC hdcDraw, + HDC hicTargetDev, + LPCRECT lprcClient, + INT x, INT y, + DWORD* pHitResult); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxQueryHitPoint, STDCALL_TO_THISCALL) +#define ITextServices_TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) fnTextSrv_TxQueryHitPoint((This)->lpVtbl->TxQueryHitPoint,This,a,b,c,d,e,f,g,h,i,j) +#else +#define ITextServices_TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) (This)->lpVtbl->TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_OnTxInplaceActivate(LPVOID function, + ITextServices *iface, + LPCRECT prcClient); + +__ASM_GLOBAL_FUNC(fnTextSrv_OnTxInplaceActivate, STDCALL_TO_THISCALL) +#define ITextServices_OnTxInplaceActivate(This,a) fnTextSrv_OnTxInplaceActivate((This)->lpVtbl->OnTxInplaceActivate,This,a) +#else +#define ITextServices_OnTxInplaceActivate(This,a) (This)->lpVtbl->OnTxInplaceActivate(This,a) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_OnTxInplaceDeactivate(LPVOID function, + ITextServices *iface); + +__ASM_GLOBAL_FUNC(fnTextSrv_OnTxInplaceDeactivate, STDCALL_TO_THISCALL) +#define ITextServices_OnTxInplaceDeactivate(This) fnTextSrv_OnTxInplaceDeactivate((This)->lpVtbl->OnTxInplaceDeactivate,This) +#else +#define ITextServices_OnTxInplaceDeactivate(This) (This)->lpVtbl->OnTxInplaceDeactivate(This) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_OnTxUIActivate(LPVOID function, + ITextServices *iface); + +__ASM_GLOBAL_FUNC(fnTextSrv_OnTxUIActivate, STDCALL_TO_THISCALL) +#define ITextServices_OnTxUIActivate(This) fnTextSrv_OnTxUIActivate((This)->lpVtbl->OnTxUIActivate,This) +#else +#define ITextServices_OnTxUIActivate(This) (This)->lpVtbl->OnTxUIActivate(This) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_OnTxUIDeactivate(LPVOID function, + ITextServices *iface); + +__ASM_GLOBAL_FUNC(fnTextSrv_OnTxUIDeactivate, STDCALL_TO_THISCALL) +#define ITextServices_OnTxUIDeactivate(This) fnTextSrv_OnTxUIDeactivate((This)->lpVtbl->OnTxUIDeactivate,This) +#else +#define ITextServices_OnTxUIDeactivate(This) (This)->lpVtbl->OnTxUIDeactivate(This) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxGetText(LPVOID function, + ITextServices *iface, + BSTR* pbstrText); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetText, STDCALL_TO_THISCALL); +#define ITextServices_TxGetText(This,a) fnTextSrv_TxGetText((This)->lpVtbl->TxGetText,This,a) +#else +#define ITextServices_TxGetText(This,a) (This)->lpVtbl->TxGetText(This,a) +#endif + +#ifdef THISCALL_NEEDED +extern HRESULT WINAPI fnTextSrv_TxSetText(LPVOID function, + ITextServices *iface, + LPCTSTR pszText); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxSetText, STDCALL_TO_THISCALL); +#define ITextServices_TxSetText(This,a) fnTextSrv_TxSetText((This)->lpVtbl->TxSetText,This,a) +#else +#define ITextServices_TxSetText(This,a) (This)->lpVtbl->TxSetText(This,a) +#endif + +#ifdef THISCALL_NEEDED +HRESULT WINAPI fnTextSrv_TxGetCurrentTargetX(LPVOID function, + ITextServices *iface, + LONG* x); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetCurrentTargetX, STDCALL_TO_THISCALL); +#define ITextServices_TxGetCurrentTargetX(This,a) fnTextSrv_TxGetCurrentTargetX((This)->lpVtbl->TxGetCurrentTargetX,This,a) +#else +#define ITextServices_TxGetCurrentTargetX(This,a) (This)->lpVtbl->TxGetCurrentTargetX(This,a) +#endif + +#ifdef THISCALL_NEEDED +HRESULT WINAPI fnTextSrv_TxGetBaseLinePos(LPVOID function, + ITextServices *iface, + LONG* x); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetBaseLinePos, STDCALL_TO_THISCALL); +#define ITextServices_TxGetBaseLinePos(This,a) fnTextSrv_TxGetBaseLinePos((This)->lpVtbl->TxGetBaseLinePos,This,a) +#else +#define ITextServices_TxGetBaseLinePos(This,a) (This)->lpVtbl->TxGetBaseLinePos(This,a) +#endif + +#ifdef THISCALL_NEEDED +HRESULT WINAPI fnTextSrv_TxGetNaturalSize(LPVOID function, + ITextServices *iface, + DWORD dwAspect, + HDC hdcDraw, + HDC hicTargetDev, + DVTARGETDEVICE* ptd, + DWORD dwMode, + const SIZEL* psizelExtent, + LONG* pwidth, + LONG* pheight); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetNaturalSize, STDCALL_TO_THISCALL); +#define ITextServices_TxGetNaturalSize(This,a,b,c,d,e,f,g,h) fnTextSrv_TxGetNaturalSize((This)->lpVtbl->TxGetNaturalSize,This,a,b,c,d,e,f,g,h) +#else +#define ITextServices_TxGetNaturalSize(This,a,b,c,d,e,f,g,h) (This)->lpVtbl->TxGetNaturalSize(This,a,b,c,d,e,f,g,h) +#endif + +#ifdef THISCALL_NEEDED +HRESULT WINAPI fnTextSrv_TxGetDropTarget(LPVOID function, + ITextServices *iface, + IDropTarget** ppDropTarget); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetDropTarget, STDCALL_TO_THISCALL); +#define ITextServices_TxGetDropTarget(This,a) fnTextSrv_TxGetDropTarget((This)->lpVtbl->TxGetDropTarget,This,a) +#else +#define ITextServices_TxGetDropTarget(This,a) (This)->lpVtbl->TxGetDropTarget(This,a) +#endif + +#ifdef THISCALL_NEEDED +HRESULT WINAPI fnTextSrv_OnTxPropertyBitsChange(LPVOID function, + ITextServices *iface, + DWORD dwMask, + DWORD dwBits); + +__ASM_GLOBAL_FUNC(fnTextSrv_OnTxPropertyBitsChange, STDCALL_TO_THISCALL); +#define ITextServices_OnTxPropertyBitsChange(This,a,b) fnTextSrv_OnTxPropertyBitsChange((This)->lpVtbl->OnTxPropertyBitsChange,This,a,b) +#else +#define ITextServices_OnTxPropertyBitsChange(This,a,b) (This)->lpVtbl->OnTxPropertyBitsChange(This,a,b) +#endif + +#ifdef THISCALL_NEEDED +HRESULT WINAPI fnTextSrv_TxGetCachedSize(LPVOID function, + ITextServices *iface, + DWORD* pdwWidth, + DWORD* pdwHeight); + +__ASM_GLOBAL_FUNC(fnTextSrv_TxGetCachedSize, STDCALL_TO_THISCALL); +#define ITextServices_TxGetCachedSize(This,a,b) fnTextSrv_TxGetCachedSize((This)->lpVtbl->TxGetCachedSize,This,a,b) +#else +#define ITextServices_TxGetCachedSize(This,a,b) (This)->lpVtbl->TxGetCachedSize(This,a,b) +#endif + + + /* 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 @@ -650,6 +914,21 @@ BOOL init_texthost() return TRUE; } +static void test_TxGetText() +{ + HRESULT hres; + BSTR rettext; + + if (!init_texthost()) + return; + + hres = ITextServices_TxGetText(txtserv, &rettext); + todo_wine ok(hres == S_OK, "ITextServices_TxGetText failed\n"); + + IUnknown_Release(txtserv); + CoTaskMemFree(dummyTextHost); +} + START_TEST( txtsrv ) { /* Must explicitly LoadLibrary(). The test has no references to functions in @@ -662,4 +941,6 @@ START_TEST( txtsrv ) IUnknown_Release(txtserv); CoTaskMemFree(dummyTextHost); + + test_TxGetText(); } diff --git a/include/textserv.h b/include/textserv.h index 9b3cbf9..1c262ac 100644 --- a/include/textserv.h +++ b/include/textserv.h @@ -147,25 +147,6 @@ DECLARE_INTERFACE_(ITextServices,IUnknown) #define ITextServices_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) #define ITextServices_AddRef(p) (p)->lpVtbl->AddRef(p) #define ITextServices_Release(p) (p)->lpVtbl->Release(p) -/*** ITextServices methods ***/ -#define ITextServices_TxSendMessage(p,a,b,c,d) (p)->lpVtbl->TxSendMessage(p,a,b,c,d) -#define ITextServices_TxDraw(p,a,b,c,d,e,f,g,h,i,j,k,l) (p)->lpVtbl->TxDraw(p,a,b,c,d,e,f,g,h,i,j,k,l) -#define ITextServices_TxGetHScroll(p,a,b,c,d,e) (p)->lpVtbl->TxGetHScroll(p,a,b,c,d,e) -#define ITextServices_TxGetVScroll(p,a,b,c,d,e) (p)->lpVtbl->TxGetVScroll(p,a,b,c,d,e) -#define ITextServices_OnTxSetCursor(p,a,b,c,d,e,f,g,h,i) (p)->lpVtbl->OnTxSetCursor(p,a,b,c,d,e,f,g,h,i) -#define ITextServices_TxQueryHitPoint(p,a,b,c,d,e,f,g,h,i,j) (p)->lpVtbl->TxQueryHitPoint(p,a,b,c,d,e,f,g,h,i,j) -#define ITextServices_OnTxInplaceActivate(p,a) (p)->lpVtbl->OnTxInplaceActivate(p,a) -#define ITextServices_OnTxInplaceDeactivate(p) (p)->lpVtbl->OnTxInplaceDeactivate(p) -#define ITextServices_OnTxUIActivate(p) (p)->lpVtbl->OnTxUIActivate(p) -#define ITextServices_OnTxUIDeactivate(p) (p)->lpVtbl->OnTxUIDeactivate(p) -#define ITextServices_TxGetText(p,a) (p)->lpVtbl->TxGetText(p,a) -#define ITextServices_TxSetText(p,a) (p)->lpVtbl->TxSetText(p,a) -#define ITextServices_TxGetCurrentTargetX(p,a) (p)->lpVtbl->TxGetCurrentTargetX(p,a) -#define ITextServices_TxGetBaseLinePos(p,a) (p)->lpVtbl->TxGetBaseLinePos(p,a) -#define ITextServices_TxGetNaturalSize(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->TxGetNaturalSize(p,a,b,c,d,e,f,g,h) -#define ITextServices_TxGetDropTarget(p,a) (p)->lpVtbl->TxGetDropTarget(p,a) -#define ITextServices_OnTxPropertyBitsChange(p,a,b) (p)->lpVtbl->OnTxPropertyBitsChange(p,a,b) -#define ITextServices_TxGetCachedSize(p,a,b) (p)->lpVtbl->TxGetCachedSize(p,a,b) #endif #undef INTERFACE