xref: /reactos/dll/win32/riched20/txthost.c (revision 8a978a17)
1 /*
2  * RichEdit - ITextHost implementation for windowed richedit controls
3  *
4  * Copyright 2009 by Dylan Smith
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #define COBJMACROS
22 
23 #include "editor.h"
24 #include "ole2.h"
25 #include "richole.h"
26 #include "imm.h"
27 #include "textserv.h"
28 #include "wine/asm.h"
29 #include "wine/debug.h"
30 #include "editstr.h"
31 
32 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
33 
34 typedef struct ITextHostImpl {
35     ITextHost ITextHost_iface;
36     LONG ref;
37     HWND hWnd;
38     BOOL bEmulateVersion10;
39     PARAFORMAT2 para_fmt;
40 } ITextHostImpl;
41 
42 static const ITextHostVtbl textHostVtbl;
43 
44 ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10)
45 {
46     ITextHostImpl *texthost;
47 
48     texthost = CoTaskMemAlloc(sizeof(*texthost));
49     if (!texthost) return NULL;
50 
51     texthost->ITextHost_iface.lpVtbl = &textHostVtbl;
52     texthost->ref = 1;
53     texthost->hWnd = hwnd;
54     texthost->bEmulateVersion10 = bEmulateVersion10;
55     memset( &texthost->para_fmt, 0, sizeof(texthost->para_fmt) );
56     texthost->para_fmt.cbSize = sizeof(texthost->para_fmt);
57     texthost->para_fmt.dwMask = PFM_ALIGNMENT;
58     texthost->para_fmt.wAlignment = PFA_LEFT;
59     if (cs->style & ES_RIGHT)
60         texthost->para_fmt.wAlignment = PFA_RIGHT;
61     if (cs->style & ES_CENTER)
62         texthost->para_fmt.wAlignment = PFA_CENTER;
63 
64     return &texthost->ITextHost_iface;
65 }
66 
67 static inline ITextHostImpl *impl_from_ITextHost(ITextHost *iface)
68 {
69     return CONTAINING_RECORD(iface, ITextHostImpl, ITextHost_iface);
70 }
71 
72 static HRESULT WINAPI ITextHostImpl_QueryInterface(ITextHost *iface, REFIID riid, void **ppvObject)
73 {
74     ITextHostImpl *This = impl_from_ITextHost(iface);
75 
76     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ITextHost)) {
77         *ppvObject = &This->ITextHost_iface;
78         ITextHost_AddRef((ITextHost *)*ppvObject);
79         return S_OK;
80     }
81 
82     FIXME("Unknown interface: %s\n", debugstr_guid(riid));
83     return E_NOINTERFACE;
84 }
85 
86 static ULONG WINAPI ITextHostImpl_AddRef(ITextHost *iface)
87 {
88     ITextHostImpl *This = impl_from_ITextHost(iface);
89     ULONG ref = InterlockedIncrement(&This->ref);
90     return ref;
91 }
92 
93 static ULONG WINAPI ITextHostImpl_Release(ITextHost *iface)
94 {
95     ITextHostImpl *This = impl_from_ITextHost(iface);
96     ULONG ref = InterlockedDecrement(&This->ref);
97 
98     if (!ref)
99     {
100         SetWindowLongPtrW(This->hWnd, 0, 0);
101         CoTaskMemFree(This);
102     }
103     return ref;
104 }
105 
106 DECLSPEC_HIDDEN HDC WINAPI ITextHostImpl_TxGetDC(ITextHost *iface)
107 {
108     ITextHostImpl *This = impl_from_ITextHost(iface);
109     return GetDC(This->hWnd);
110 }
111 
112 DECLSPEC_HIDDEN INT WINAPI ITextHostImpl_TxReleaseDC(ITextHost *iface, HDC hdc)
113 {
114     ITextHostImpl *This = impl_from_ITextHost(iface);
115     return ReleaseDC(This->hWnd, hdc);
116 }
117 
118 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxShowScrollBar(ITextHost *iface, INT fnBar, BOOL fShow)
119 {
120     ITextHostImpl *This = impl_from_ITextHost(iface);
121     return ShowScrollBar(This->hWnd, fnBar, fShow);
122 }
123 
124 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxEnableScrollBar(ITextHost *iface, INT fuSBFlags, INT fuArrowflags)
125 {
126     ITextHostImpl *This = impl_from_ITextHost(iface);
127     return EnableScrollBar(This->hWnd, fuSBFlags, fuArrowflags);
128 }
129 
130 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxSetScrollRange(ITextHost *iface, INT fnBar, LONG nMinPos, INT nMaxPos,
131                                            BOOL fRedraw)
132 {
133     ITextHostImpl *This = impl_from_ITextHost(iface);
134     return SetScrollRange(This->hWnd, fnBar, nMinPos, nMaxPos, fRedraw);
135 }
136 
137 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxSetScrollPos(ITextHost *iface, INT fnBar, INT nPos, BOOL fRedraw)
138 {
139     ITextHostImpl *This = impl_from_ITextHost(iface);
140     return SetScrollPos(This->hWnd, fnBar, nPos, fRedraw) != 0;
141 }
142 
143 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxInvalidateRect(ITextHost *iface, LPCRECT prc, BOOL fMode)
144 {
145     ITextHostImpl *This = impl_from_ITextHost(iface);
146     InvalidateRect(This->hWnd, prc, fMode);
147 }
148 
149 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxViewChange(ITextHost *iface, BOOL fUpdate)
150 {
151     ITextHostImpl *This = impl_from_ITextHost(iface);
152     if (fUpdate)
153         UpdateWindow(This->hWnd);
154 }
155 
156 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxCreateCaret(ITextHost *iface, HBITMAP hbmp, INT xWidth, INT yHeight)
157 {
158     ITextHostImpl *This = impl_from_ITextHost(iface);
159     return CreateCaret(This->hWnd, hbmp, xWidth, yHeight);
160 }
161 
162 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxShowCaret(ITextHost *iface, BOOL fShow)
163 {
164     ITextHostImpl *This = impl_from_ITextHost(iface);
165     if (fShow)
166         return ShowCaret(This->hWnd);
167     else
168         return HideCaret(This->hWnd);
169 }
170 
171 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxSetCaretPos(ITextHost *iface,
172                                         INT x, INT y)
173 {
174     return SetCaretPos(x, y);
175 }
176 
177 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxSetTimer(ITextHost *iface, UINT idTimer, UINT uTimeout)
178 {
179     ITextHostImpl *This = impl_from_ITextHost(iface);
180     return SetTimer(This->hWnd, idTimer, uTimeout, NULL) != 0;
181 }
182 
183 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxKillTimer(ITextHost *iface, UINT idTimer)
184 {
185     ITextHostImpl *This = impl_from_ITextHost(iface);
186     KillTimer(This->hWnd, idTimer);
187 }
188 
189 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxScrollWindowEx(ITextHost *iface, INT dx, INT dy, LPCRECT lprcScroll,
190                                            LPCRECT lprcClip, HRGN hRgnUpdate, LPRECT lprcUpdate,
191                                            UINT fuScroll)
192 {
193     ITextHostImpl *This = impl_from_ITextHost(iface);
194     ScrollWindowEx(This->hWnd, dx, dy, lprcScroll, lprcClip,
195                    hRgnUpdate, lprcUpdate, fuScroll);
196 }
197 
198 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxSetCapture(ITextHost *iface, BOOL fCapture)
199 {
200     ITextHostImpl *This = impl_from_ITextHost(iface);
201     if (fCapture)
202         SetCapture(This->hWnd);
203     else
204         ReleaseCapture();
205 }
206 
207 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxSetFocus(ITextHost *iface)
208 {
209     ITextHostImpl *This = impl_from_ITextHost(iface);
210     SetFocus(This->hWnd);
211 }
212 
213 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxSetCursor(ITextHost *iface,
214                                       HCURSOR hcur,
215                                       BOOL fText)
216 {
217     SetCursor(hcur);
218 }
219 
220 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxScreenToClient(ITextHost *iface, LPPOINT lppt)
221 {
222     ITextHostImpl *This = impl_from_ITextHost(iface);
223     return ScreenToClient(This->hWnd, lppt);
224 }
225 
226 DECLSPEC_HIDDEN BOOL WINAPI ITextHostImpl_TxClientToScreen(ITextHost *iface, LPPOINT lppt)
227 {
228     ITextHostImpl *This = impl_from_ITextHost(iface);
229     return ClientToScreen(This->hWnd, lppt);
230 }
231 
232 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxActivate(ITextHost *iface, LONG *plOldState)
233 {
234     ITextHostImpl *This = impl_from_ITextHost(iface);
235     *plOldState = HandleToLong(SetActiveWindow(This->hWnd));
236     return (*plOldState ? S_OK : E_FAIL);
237 }
238 
239 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxDeactivate(ITextHost *iface,
240                                           LONG lNewState)
241 {
242     HWND ret = SetActiveWindow(LongToHandle(lNewState));
243     return (ret ? S_OK : E_FAIL);
244 }
245 
246 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetClientRect(ITextHost *iface, LPRECT prc)
247 {
248     ITextHostImpl *This = impl_from_ITextHost(iface);
249     int ret = GetClientRect(This->hWnd, prc);
250     return (ret ? S_OK : E_FAIL);
251 }
252 
253 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetViewInset(ITextHost *iface,
254                                             LPRECT prc)
255 {
256     prc->top = 0;
257     prc->left = 0;
258     prc->bottom = 0;
259     prc->right = 0;
260     return S_OK;
261 }
262 
263 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetCharFormat(ITextHost *iface,
264                                              const CHARFORMATW **ppCF)
265 {
266     return E_NOTIMPL;
267 }
268 
269 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetParaFormat(ITextHost *iface,
270                                                              const PARAFORMAT **fmt)
271 {
272     ITextHostImpl *This = impl_from_ITextHost(iface);
273     *fmt = (const PARAFORMAT *)&This->para_fmt;
274     return S_OK;
275 }
276 
277 DECLSPEC_HIDDEN COLORREF WINAPI ITextHostImpl_TxGetSysColor(ITextHost *iface,
278                                             int nIndex)
279 {
280     return GetSysColor(nIndex);
281 }
282 
283 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetBackStyle(ITextHost *iface,
284                                             TXTBACKSTYLE *pStyle)
285 {
286     *pStyle = TXTBACK_OPAQUE;
287     return S_OK;
288 }
289 
290 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetMaxLength(ITextHost *iface,
291                                             DWORD *pLength)
292 {
293     *pLength = INFINITE;
294     return S_OK;
295 }
296 
297 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetScrollBars(ITextHost *iface, DWORD *pdwScrollBar)
298 {
299     ITextHostImpl *This = impl_from_ITextHost(iface);
300     ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0);
301     const DWORD mask = WS_VSCROLL|
302                        WS_HSCROLL|
303                        ES_AUTOVSCROLL|
304                        ES_AUTOHSCROLL|
305                        ES_DISABLENOSCROLL;
306     if (editor)
307     {
308         *pdwScrollBar = editor->styleFlags & mask;
309     } else {
310         DWORD style = GetWindowLongW(This->hWnd, GWL_STYLE);
311         if (style & WS_VSCROLL)
312             style |= ES_AUTOVSCROLL;
313         if (!This->bEmulateVersion10 && (style & WS_HSCROLL))
314             style |= ES_AUTOHSCROLL;
315         *pdwScrollBar = style & mask;
316     }
317     return S_OK;
318 }
319 
320 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetPasswordChar(ITextHost *iface,
321                                                WCHAR *pch)
322 {
323     *pch = '*';
324     return S_OK;
325 }
326 
327 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetAcceleratorPos(ITextHost *iface,
328                                                  LONG *pch)
329 {
330     *pch = -1;
331     return S_OK;
332 }
333 
334 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetExtent(ITextHost *iface,
335                                          LPSIZEL lpExtent)
336 {
337     return E_NOTIMPL;
338 }
339 
340 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_OnTxCharFormatChange(ITextHost *iface,
341                                                   const CHARFORMATW *pcf)
342 {
343     return S_OK;
344 }
345 
346 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_OnTxParaFormatChange(ITextHost *iface,
347                                                   const PARAFORMAT *ppf)
348 {
349     return S_OK;
350 }
351 
352 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetPropertyBits(ITextHost *iface, DWORD dwMask, DWORD *pdwBits)
353 {
354     ITextHostImpl *This = impl_from_ITextHost(iface);
355     ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(This->hWnd, 0);
356     DWORD style;
357     DWORD dwBits = 0;
358 
359     if (editor)
360     {
361         style = editor->styleFlags;
362         if (editor->mode & TM_RICHTEXT)
363             dwBits |= TXTBIT_RICHTEXT;
364         if (editor->bWordWrap)
365             dwBits |= TXTBIT_WORDWRAP;
366         if (style & ECO_AUTOWORDSELECTION)
367             dwBits |= TXTBIT_AUTOWORDSEL;
368     } else {
369         DWORD dwScrollBar;
370 
371         style = GetWindowLongW(This->hWnd, GWL_STYLE);
372         ITextHostImpl_TxGetScrollBars(iface, &dwScrollBar);
373 
374         dwBits |= TXTBIT_RICHTEXT|TXTBIT_AUTOWORDSEL;
375         if (!(dwScrollBar & ES_AUTOHSCROLL))
376             dwBits |= TXTBIT_WORDWRAP;
377     }
378 
379     /* Bits that correspond to window styles. */
380     if (style & ES_MULTILINE)
381         dwBits |= TXTBIT_MULTILINE;
382     if (style & ES_READONLY)
383         dwBits |= TXTBIT_READONLY;
384     if (style & ES_PASSWORD)
385         dwBits |= TXTBIT_USEPASSWORD;
386     if (!(style & ES_NOHIDESEL))
387         dwBits |= TXTBIT_HIDESELECTION;
388     if (style & ES_SAVESEL)
389         dwBits |= TXTBIT_SAVESELECTION;
390     if (style & ES_VERTICAL)
391         dwBits |= TXTBIT_VERTICAL;
392     if (style & ES_NOOLEDRAGDROP)
393         dwBits |= TXTBIT_DISABLEDRAG;
394 
395     dwBits |= TXTBIT_ALLOWBEEP;
396 
397     /* The following bits are always FALSE because they are probably only
398      * needed for ITextServices_OnTxPropertyBitsChange:
399      *   TXTBIT_VIEWINSETCHANGE
400      *   TXTBIT_BACKSTYLECHANGE
401      *   TXTBIT_MAXLENGTHCHANGE
402      *   TXTBIT_CHARFORMATCHANGE
403      *   TXTBIT_PARAFORMATCHANGE
404      *   TXTBIT_SHOWACCELERATOR
405      *   TXTBIT_EXTENTCHANGE
406      *   TXTBIT_SELBARCHANGE
407      *   TXTBIT_SCROLLBARCHANGE
408      *   TXTBIT_CLIENTRECTCHANGE
409      *
410      * Documented by MSDN as not supported:
411      *   TXTBIT_USECURRENTBKG
412      */
413 
414     *pdwBits = dwBits & dwMask;
415     return S_OK;
416 }
417 
418 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, void *pv)
419 {
420     ITextHostImpl *This = impl_from_ITextHost(iface);
421     ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0);
422     HWND hwnd = This->hWnd;
423     UINT id;
424 
425     if (!editor || !editor->hwndParent) return S_OK;
426 
427     id = GetWindowLongW(hwnd, GWLP_ID);
428 
429     switch (iNotify)
430     {
431         case EN_DROPFILES:
432         case EN_LINK:
433         case EN_OLEOPFAILED:
434         case EN_PROTECTED:
435         case EN_REQUESTRESIZE:
436         case EN_SAVECLIPBOARD:
437         case EN_SELCHANGE:
438         case EN_STOPNOUNDO:
439         {
440             /* FIXME: Verify this assumption that pv starts with NMHDR. */
441             NMHDR *info = pv;
442             if (!info)
443                 return E_FAIL;
444 
445             info->hwndFrom = hwnd;
446             info->idFrom = id;
447             info->code = iNotify;
448             SendMessageW(editor->hwndParent, WM_NOTIFY, id, (LPARAM)info);
449             break;
450         }
451 
452         case EN_UPDATE:
453             /* Only sent when the window is visible. */
454             if (!IsWindowVisible(hwnd))
455                 break;
456             /* Fall through */
457         case EN_CHANGE:
458         case EN_ERRSPACE:
459         case EN_HSCROLL:
460         case EN_KILLFOCUS:
461         case EN_MAXTEXT:
462         case EN_SETFOCUS:
463         case EN_VSCROLL:
464             SendMessageW(editor->hwndParent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd);
465             break;
466 
467         case EN_MSGFILTER:
468             FIXME("EN_MSGFILTER is documented as not being sent to TxNotify\n");
469             /* fall through */
470         default:
471             return E_FAIL;
472     }
473     return S_OK;
474 }
475 
476 DECLSPEC_HIDDEN HIMC WINAPI ITextHostImpl_TxImmGetContext(ITextHost *iface)
477 {
478     ITextHostImpl *This = impl_from_ITextHost(iface);
479     return ImmGetContext(This->hWnd);
480 }
481 
482 DECLSPEC_HIDDEN void WINAPI ITextHostImpl_TxImmReleaseContext(ITextHost *iface, HIMC himc)
483 {
484     ITextHostImpl *This = impl_from_ITextHost(iface);
485     ImmReleaseContext(This->hWnd, himc);
486 }
487 
488 DECLSPEC_HIDDEN HRESULT WINAPI ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface, LONG *lSelBarWidth)
489 {
490     ITextHostImpl *This = impl_from_ITextHost(iface);
491     ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(This->hWnd, 0);
492 
493     DWORD style = editor ? editor->styleFlags
494                          : GetWindowLongW(This->hWnd, GWL_STYLE);
495     *lSelBarWidth = (style & ES_SELECTIONBAR) ? 225 : 0; /* in HIMETRIC */
496     return S_OK;
497 }
498 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC,4)
499 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC,8)
500 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar,12)
501 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar,12)
502 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange,20)
503 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos,16)
504 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect,12)
505 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange,8)
506 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret,16)
507 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret,8)
508 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos,12)
509 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer,12)
510 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer,8)
511 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx,32)
512 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture,8)
513 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus,4)
514 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor,12)
515 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient,8)
516 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen,8)
517 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate,8)
518 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate,8)
519 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8)
520 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8)
521 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat,8)
522 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat,8)
523 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor,8)
524 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle,8)
525 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength,8)
526 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8)
527 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar,8)
528 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos,8)
529 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent,8)
530 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange,8)
531 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange,8)
532 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits,12)
533 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify,12)
534 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext,4)
535 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext,8)
536 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth,8)
537 
538 #if defined(__i386__) && !defined(__MINGW32__)  /* thiscall functions are i386-specific */
539 
540 #define STDCALL(func) (void *) __stdcall_ ## func
541 #ifdef _MSC_VER
542 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
543     __declspec(naked) HRESULT __stdcall_##func(void) \
544     { \
545         __asm pop eax \
546         __asm pop ecx \
547         __asm push eax \
548         __asm mov eax, [ecx] \
549         __asm jmp dword ptr [eax + 4*num] \
550     }
551 #else /* _MSC_VER */
552 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
553    extern HRESULT __stdcall_ ## func(void); \
554    __ASM_GLOBAL_FUNC(__stdcall_ ## func, \
555                    "popl %eax\n\t" \
556                    "popl %ecx\n\t" \
557                    "pushl %eax\n\t" \
558                    "movl (%ecx), %eax\n\t" \
559                    "jmp *(4*(" #num "))(%eax)" )
560 #endif /* _MSC_VER */
561 
562 DEFINE_STDCALL_WRAPPER(3,ITextHostImpl_TxGetDC,4)
563 DEFINE_STDCALL_WRAPPER(4,ITextHostImpl_TxReleaseDC,8)
564 DEFINE_STDCALL_WRAPPER(5,ITextHostImpl_TxShowScrollBar,12)
565 DEFINE_STDCALL_WRAPPER(6,ITextHostImpl_TxEnableScrollBar,12)
566 DEFINE_STDCALL_WRAPPER(7,ITextHostImpl_TxSetScrollRange,20)
567 DEFINE_STDCALL_WRAPPER(8,ITextHostImpl_TxSetScrollPos,16)
568 DEFINE_STDCALL_WRAPPER(9,ITextHostImpl_TxInvalidateRect,12)
569 DEFINE_STDCALL_WRAPPER(10,ITextHostImpl_TxViewChange,8)
570 DEFINE_STDCALL_WRAPPER(11,ITextHostImpl_TxCreateCaret,16)
571 DEFINE_STDCALL_WRAPPER(12,ITextHostImpl_TxShowCaret,8)
572 DEFINE_STDCALL_WRAPPER(13,ITextHostImpl_TxSetCaretPos,12)
573 DEFINE_STDCALL_WRAPPER(14,ITextHostImpl_TxSetTimer,12)
574 DEFINE_STDCALL_WRAPPER(15,ITextHostImpl_TxKillTimer,8)
575 DEFINE_STDCALL_WRAPPER(16,ITextHostImpl_TxScrollWindowEx,32)
576 DEFINE_STDCALL_WRAPPER(17,ITextHostImpl_TxSetCapture,8)
577 DEFINE_STDCALL_WRAPPER(18,ITextHostImpl_TxSetFocus,4)
578 DEFINE_STDCALL_WRAPPER(19,ITextHostImpl_TxSetCursor,12)
579 DEFINE_STDCALL_WRAPPER(20,ITextHostImpl_TxScreenToClient,8)
580 DEFINE_STDCALL_WRAPPER(21,ITextHostImpl_TxClientToScreen,8)
581 DEFINE_STDCALL_WRAPPER(22,ITextHostImpl_TxActivate,8)
582 DEFINE_STDCALL_WRAPPER(23,ITextHostImpl_TxDeactivate,8)
583 DEFINE_STDCALL_WRAPPER(24,ITextHostImpl_TxGetClientRect,8)
584 DEFINE_STDCALL_WRAPPER(25,ITextHostImpl_TxGetViewInset,8)
585 DEFINE_STDCALL_WRAPPER(26,ITextHostImpl_TxGetCharFormat,8)
586 DEFINE_STDCALL_WRAPPER(27,ITextHostImpl_TxGetParaFormat,8)
587 DEFINE_STDCALL_WRAPPER(28,ITextHostImpl_TxGetSysColor,8)
588 DEFINE_STDCALL_WRAPPER(29,ITextHostImpl_TxGetBackStyle,8)
589 DEFINE_STDCALL_WRAPPER(30,ITextHostImpl_TxGetMaxLength,8)
590 DEFINE_STDCALL_WRAPPER(31,ITextHostImpl_TxGetScrollBars,8)
591 DEFINE_STDCALL_WRAPPER(32,ITextHostImpl_TxGetPasswordChar,8)
592 DEFINE_STDCALL_WRAPPER(33,ITextHostImpl_TxGetAcceleratorPos,8)
593 DEFINE_STDCALL_WRAPPER(34,ITextHostImpl_TxGetExtent,8)
594 DEFINE_STDCALL_WRAPPER(35,ITextHostImpl_OnTxCharFormatChange,8)
595 DEFINE_STDCALL_WRAPPER(36,ITextHostImpl_OnTxParaFormatChange,8)
596 DEFINE_STDCALL_WRAPPER(37,ITextHostImpl_TxGetPropertyBits,12)
597 DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify,12)
598 DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext,4)
599 DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext,8)
600 DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth,8)
601 
602 const ITextHostVtbl itextHostStdcallVtbl = {
603     NULL,
604     NULL,
605     NULL,
606     STDCALL(ITextHostImpl_TxGetDC),
607     STDCALL(ITextHostImpl_TxReleaseDC),
608     STDCALL(ITextHostImpl_TxShowScrollBar),
609     STDCALL(ITextHostImpl_TxEnableScrollBar),
610     STDCALL(ITextHostImpl_TxSetScrollRange),
611     STDCALL(ITextHostImpl_TxSetScrollPos),
612     STDCALL(ITextHostImpl_TxInvalidateRect),
613     STDCALL(ITextHostImpl_TxViewChange),
614     STDCALL(ITextHostImpl_TxCreateCaret),
615     STDCALL(ITextHostImpl_TxShowCaret),
616     STDCALL(ITextHostImpl_TxSetCaretPos),
617     STDCALL(ITextHostImpl_TxSetTimer),
618     STDCALL(ITextHostImpl_TxKillTimer),
619     STDCALL(ITextHostImpl_TxScrollWindowEx),
620     STDCALL(ITextHostImpl_TxSetCapture),
621     STDCALL(ITextHostImpl_TxSetFocus),
622     STDCALL(ITextHostImpl_TxSetCursor),
623     STDCALL(ITextHostImpl_TxScreenToClient),
624     STDCALL(ITextHostImpl_TxClientToScreen),
625     STDCALL(ITextHostImpl_TxActivate),
626     STDCALL(ITextHostImpl_TxDeactivate),
627     STDCALL(ITextHostImpl_TxGetClientRect),
628     STDCALL(ITextHostImpl_TxGetViewInset),
629     STDCALL(ITextHostImpl_TxGetCharFormat),
630     STDCALL(ITextHostImpl_TxGetParaFormat),
631     STDCALL(ITextHostImpl_TxGetSysColor),
632     STDCALL(ITextHostImpl_TxGetBackStyle),
633     STDCALL(ITextHostImpl_TxGetMaxLength),
634     STDCALL(ITextHostImpl_TxGetScrollBars),
635     STDCALL(ITextHostImpl_TxGetPasswordChar),
636     STDCALL(ITextHostImpl_TxGetAcceleratorPos),
637     STDCALL(ITextHostImpl_TxGetExtent),
638     STDCALL(ITextHostImpl_OnTxCharFormatChange),
639     STDCALL(ITextHostImpl_OnTxParaFormatChange),
640     STDCALL(ITextHostImpl_TxGetPropertyBits),
641     STDCALL(ITextHostImpl_TxNotify),
642     STDCALL(ITextHostImpl_TxImmGetContext),
643     STDCALL(ITextHostImpl_TxImmReleaseContext),
644     STDCALL(ITextHostImpl_TxGetSelectionBarWidth),
645 };
646 
647 #endif /* __i386__ */
648 
649 static const ITextHostVtbl textHostVtbl = {
650     ITextHostImpl_QueryInterface,
651     ITextHostImpl_AddRef,
652     ITextHostImpl_Release,
653     THISCALL(ITextHostImpl_TxGetDC),
654     THISCALL(ITextHostImpl_TxReleaseDC),
655     THISCALL(ITextHostImpl_TxShowScrollBar),
656     THISCALL(ITextHostImpl_TxEnableScrollBar),
657     THISCALL(ITextHostImpl_TxSetScrollRange),
658     THISCALL(ITextHostImpl_TxSetScrollPos),
659     THISCALL(ITextHostImpl_TxInvalidateRect),
660     THISCALL(ITextHostImpl_TxViewChange),
661     THISCALL(ITextHostImpl_TxCreateCaret),
662     THISCALL(ITextHostImpl_TxShowCaret),
663     THISCALL(ITextHostImpl_TxSetCaretPos),
664     THISCALL(ITextHostImpl_TxSetTimer),
665     THISCALL(ITextHostImpl_TxKillTimer),
666     THISCALL(ITextHostImpl_TxScrollWindowEx),
667     THISCALL(ITextHostImpl_TxSetCapture),
668     THISCALL(ITextHostImpl_TxSetFocus),
669     THISCALL(ITextHostImpl_TxSetCursor),
670     THISCALL(ITextHostImpl_TxScreenToClient),
671     THISCALL(ITextHostImpl_TxClientToScreen),
672     THISCALL(ITextHostImpl_TxActivate),
673     THISCALL(ITextHostImpl_TxDeactivate),
674     THISCALL(ITextHostImpl_TxGetClientRect),
675     THISCALL(ITextHostImpl_TxGetViewInset),
676     THISCALL(ITextHostImpl_TxGetCharFormat),
677     THISCALL(ITextHostImpl_TxGetParaFormat),
678     THISCALL(ITextHostImpl_TxGetSysColor),
679     THISCALL(ITextHostImpl_TxGetBackStyle),
680     THISCALL(ITextHostImpl_TxGetMaxLength),
681     THISCALL(ITextHostImpl_TxGetScrollBars),
682     THISCALL(ITextHostImpl_TxGetPasswordChar),
683     THISCALL(ITextHostImpl_TxGetAcceleratorPos),
684     THISCALL(ITextHostImpl_TxGetExtent),
685     THISCALL(ITextHostImpl_OnTxCharFormatChange),
686     THISCALL(ITextHostImpl_OnTxParaFormatChange),
687     THISCALL(ITextHostImpl_TxGetPropertyBits),
688     THISCALL(ITextHostImpl_TxNotify),
689     THISCALL(ITextHostImpl_TxImmGetContext),
690     THISCALL(ITextHostImpl_TxImmReleaseContext),
691     THISCALL(ITextHostImpl_TxGetSelectionBarWidth),
692 };
693