Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
e4ef9c5c
Commit
e4ef9c5c
authored
Nov 12, 2008
by
Dylan Smith
Committed by
Alexandre Julliard
Nov 13, 2008
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
richedit: Initial testing of ITextServices methods.
parent
6cd908d4
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
89 additions
and
21 deletions
+89
-21
txtsrv.c
dlls/riched20/tests/txtsrv.c
+89
-2
textserv.h
include/textserv.h
+0
-19
No files found.
dlls/riched20/tests/txtsrv.c
View file @
e4ef9c5c
...
@@ -34,6 +34,35 @@
...
@@ -34,6 +34,35 @@
static
HMODULE
hmoduleRichEdit
;
static
HMODULE
hmoduleRichEdit
;
/* Define C Macros for ITextServices calls. */
/* Use a special table for x86 machines to convert the thiscall
* calling convention. This isn't needed on other platforms. */
#ifdef __i386__
#define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl)
#else
/* __i386__ */
#define TXTSERV_VTABLE(This) (This)->lpVtbl
#endif
/* __i386__ */
#define ITextServices_TxSendMessage(This,a,b,c,d) TXTSERV_VTABLE(This)->TxSendMessage(This,a,b,c,d)
#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)
#define ITextServices_TxGetHScroll(This,a,b,c,d,e) TXTSERV_VTABLE(This)->TxGetHScroll(This,a,b,c,d,e)
#define ITextServices_TxGetVScroll(This,a,b,c,d,e) TXTSERV_VTABLE(This)->TxGetVScroll(This,a,b,c,d,e)
#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)
#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)
#define ITextServices_OnTxInplaceActivate(This,a) TXTSERV_VTABLE(This)->OnTxInplaceActivate(This,a)
#define ITextServices_OnTxInplaceDeactivate(This) TXTSERV_VTABLE(This)->OnTxInplaceDeactivate(This)
#define ITextServices_OnTxUIActivate(This) TXTSERV_VTABLE(This)->OnTxUIActivate(This)
#define ITextServices_OnTxUIDeactivate(This) TXTSERV_VTABLE(This)->OnTxUIDeactivate(This)
#define ITextServices_TxGetText(This,a) TXTSERV_VTABLE(This)->TxGetText(This,a)
#define ITextServices_TxSetText(This,a) TXTSERV_VTABLE(This)->TxSetText(This,a)
#define ITextServices_TxGetCurrentTargetX(This,a) TXTSERV_VTABLE(This)->TxGetCurrentTargetX(This,a)
#define ITextServices_TxGetBaseLinePos(This,a) TXTSERV_VTABLE(This)->TxGetBaseLinePos(This,a)
#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)
#define ITextServices_TxGetDropTarget(This,a) TXTSERV_VTABLE(This)->TxGetDropTarget(This,a)
#define ITextServices_OnTxPropertyBitsChange(This,a,b) TXTSERV_VTABLE(This)->OnTxPropertyBitsChange(This,a,b)
#define ITextServices_TxGetCachedSize(This,a,b) TXTSERV_VTABLE(This)->TxGetCachedSize(This,a,b)
/* Set the WINETEST_DEBUG environment variable to be greater than 1 for verbose
/* Set the WINETEST_DEBUG environment variable to be greater than 1 for verbose
* function call traces of ITextHost. */
* function call traces of ITextHost. */
#define TRACECALL if(winetest_debug > 1) trace
#define TRACECALL if(winetest_debug > 1) trace
...
@@ -412,6 +441,8 @@ static HRESULT WINAPI ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface,
...
@@ -412,6 +441,8 @@ static HRESULT WINAPI ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface,
return
E_NOTIMPL
;
return
E_NOTIMPL
;
}
}
static
ITextServicesVtbl
itextServicesStdcallVtbl
;
static
ITextHostVtbl
itextHostVtbl
=
{
static
ITextHostVtbl
itextHostVtbl
=
{
ITextHostImpl_QueryInterface
,
ITextHostImpl_QueryInterface
,
ITextHostImpl_AddRef
,
ITextHostImpl_AddRef
,
...
@@ -461,6 +492,8 @@ static ITextServices *txtserv = NULL;
...
@@ -461,6 +492,8 @@ static ITextServices *txtserv = NULL;
static
ITextHostTestImpl
*
dummyTextHost
;
static
ITextHostTestImpl
*
dummyTextHost
;
static
void
*
wrapperCodeMem
=
NULL
;
static
void
*
wrapperCodeMem
=
NULL
;
#include "pshpack1.h"
/* Code structure for x86 byte code */
/* Code structure for x86 byte code */
typedef
struct
typedef
struct
{
{
...
@@ -471,6 +504,17 @@ typedef struct
...
@@ -471,6 +504,17 @@ typedef struct
DWORD
func
;
DWORD
func
;
}
THISCALL_TO_STDCALL_THUNK
;
}
THISCALL_TO_STDCALL_THUNK
;
typedef
struct
{
BYTE
pop_eax
;
/* popl %eax */
BYTE
pop_ecx
;
/* popl %ecx */
BYTE
push_eax
;
/* pushl %eax */
BYTE
mov_vtable_eax
[
2
];
/* movl (%ecx), %eax */
BYTE
jmp_eax
[
2
];
/* jmp *$vtablefunc_offset(%eax) */
int
vtablefunc_offset
;
}
STDCALL_TO_THISCALL_THUNK
;
#include "poppack.h"
static
void
setup_thiscall_wrappers
(
void
)
static
void
setup_thiscall_wrappers
(
void
)
{
{
...
@@ -478,10 +522,13 @@ static void setup_thiscall_wrappers(void)
...
@@ -478,10 +522,13 @@ static void setup_thiscall_wrappers(void)
void
**
pVtable
;
void
**
pVtable
;
void
**
pVtableEnd
;
void
**
pVtableEnd
;
THISCALL_TO_STDCALL_THUNK
*
thunk
;
THISCALL_TO_STDCALL_THUNK
*
thunk
;
STDCALL_TO_THISCALL_THUNK
*
thunk2
;
wrapperCodeMem
=
VirtualAlloc
(
NULL
,
wrapperCodeMem
=
VirtualAlloc
(
NULL
,
(
sizeof
(
ITextHostVtbl
)
/
sizeof
(
void
*
)
-
3
)
(
sizeof
(
ITextHostVtbl
)
/
sizeof
(
void
*
)
-
3
)
*
sizeof
(
THISCALL_TO_STDCALL_THUNK
),
*
sizeof
(
THISCALL_TO_STDCALL_THUNK
)
+
(
sizeof
(
ITextServicesVtbl
)
/
sizeof
(
void
*
)
-
3
)
*
sizeof
(
STDCALL_TO_THISCALL_THUNK
),
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
);
MEM_COMMIT
,
PAGE_EXECUTE_READWRITE
);
thunk
=
wrapperCodeMem
;
thunk
=
wrapperCodeMem
;
...
@@ -498,7 +545,7 @@ static void setup_thiscall_wrappers(void)
...
@@ -498,7 +545,7 @@ static void setup_thiscall_wrappers(void)
/* Skip QueryInterface, AddRef, and Release native actually
/* Skip QueryInterface, AddRef, and Release native actually
* defined them with the stdcall calling convention. */
* defined them with the stdcall calling convention. */
pVtable
=
(
void
**
)
&
itextHostVtbl
+
3
;
pVtable
=
(
void
**
)
&
itextHostVtbl
+
3
;
pVtableEnd
=
(
void
**
)(
(
char
*
)
&
itextHostVtbl
+
sizeof
(
ITextHostVtbl
)
);
pVtableEnd
=
(
void
**
)(
&
itextHostVtbl
+
1
);
while
(
pVtable
!=
pVtableEnd
)
{
while
(
pVtable
!=
pVtableEnd
)
{
/* write byte code to executable memory */
/* write byte code to executable memory */
thunk
->
pop_eax
=
0x58
;
/* popl %eax */
thunk
->
pop_eax
=
0x58
;
/* popl %eax */
...
@@ -511,6 +558,29 @@ static void setup_thiscall_wrappers(void)
...
@@ -511,6 +558,29 @@ static void setup_thiscall_wrappers(void)
pVtable
++
;
pVtable
++
;
thunk
++
;
thunk
++
;
}
}
/* Setup an ITextServices standard call vtable that will call the
* native thiscall vtable when the methods are called. */
/* QueryInterface, AddRef, and Release should be called directly on the
* real vtable since they use the stdcall calling convention. */
thunk2
=
(
STDCALL_TO_THISCALL_THUNK
*
)
thunk
;
pVtable
=
(
void
**
)
&
itextServicesStdcallVtbl
+
3
;
pVtableEnd
=
(
void
**
)(
&
itextServicesStdcallVtbl
+
1
);
while
(
pVtable
!=
pVtableEnd
)
{
/* write byte code to executable memory */
thunk2
->
pop_eax
=
0x58
;
/* popl %eax */
thunk2
->
pop_ecx
=
0x59
;
/* popl %ecx */
thunk2
->
push_eax
=
0x50
;
/* pushl %eax */
thunk2
->
mov_vtable_eax
[
0
]
=
0x8b
;
/* movl (%ecx), %eax */
thunk2
->
mov_vtable_eax
[
1
]
=
0x01
;
thunk2
->
jmp_eax
[
0
]
=
0xff
;
/* jmp *$vtablefunc_offset(%eax) */
thunk2
->
jmp_eax
[
1
]
=
0xa0
;
thunk2
->
vtablefunc_offset
=
(
char
*
)
pVtable
-
(
char
*
)
&
itextServicesStdcallVtbl
;
*
pVtable
=
thunk2
;
pVtable
++
;
thunk2
++
;
}
#endif
/* __i386__ */
#endif
/* __i386__ */
}
}
...
@@ -557,6 +627,21 @@ static BOOL init_texthost(void)
...
@@ -557,6 +627,21 @@ static BOOL init_texthost(void)
return
TRUE
;
return
TRUE
;
}
}
static
void
test_TxGetText
(
void
)
{
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
)
START_TEST
(
txtsrv
)
{
{
setup_thiscall_wrappers
();
setup_thiscall_wrappers
();
...
@@ -570,6 +655,8 @@ START_TEST( txtsrv )
...
@@ -570,6 +655,8 @@ START_TEST( txtsrv )
{
{
IUnknown_Release
(
txtserv
);
IUnknown_Release
(
txtserv
);
CoTaskMemFree
(
dummyTextHost
);
CoTaskMemFree
(
dummyTextHost
);
test_TxGetText
();
}
}
if
(
wrapperCodeMem
)
VirtualFree
(
wrapperCodeMem
,
0
,
MEM_RELEASE
);
if
(
wrapperCodeMem
)
VirtualFree
(
wrapperCodeMem
,
0
,
MEM_RELEASE
);
}
}
include/textserv.h
View file @
e4ef9c5c
...
@@ -147,25 +147,6 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
...
@@ -147,25 +147,6 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
#define ITextServices_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define ITextServices_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
#define ITextServices_AddRef(p) (p)->lpVtbl->AddRef(p)
#define ITextServices_AddRef(p) (p)->lpVtbl->AddRef(p)
#define ITextServices_Release(p) (p)->lpVtbl->Release(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
#endif
#undef INTERFACE
#undef INTERFACE
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment