xref: /reactos/dll/win32/riched20/txthost.c (revision 9d33a205)
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 __thiscall ITextHostImpl_TxGetDC(ITextHost *iface)
107 {
108     ITextHostImpl *This = impl_from_ITextHost(iface);
109     return GetDC(This->hWnd);
110 }
111 
112 DECLSPEC_HIDDEN INT __thiscall 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 __thiscall 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 __thiscall 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 __thiscall 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 __thiscall 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 __thiscall 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 __thiscall 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 __thiscall 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 __thiscall 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 __thiscall ITextHostImpl_TxSetCaretPos(ITextHost *iface,
172                                                             INT x, INT y)
173 {
174     return SetCaretPos(x, y);
175 }
176 
177 DECLSPEC_HIDDEN BOOL __thiscall 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 __thiscall 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 __thiscall 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 __thiscall 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 __thiscall ITextHostImpl_TxSetFocus(ITextHost *iface)
208 {
209     ITextHostImpl *This = impl_from_ITextHost(iface);
210     SetFocus(This->hWnd);
211 }
212 
213 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCursor(ITextHost *iface, HCURSOR hcur, BOOL fText)
214 {
215     SetCursor(hcur);
216 }
217 
218 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxScreenToClient(ITextHost *iface, LPPOINT lppt)
219 {
220     ITextHostImpl *This = impl_from_ITextHost(iface);
221     return ScreenToClient(This->hWnd, lppt);
222 }
223 
224 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxClientToScreen(ITextHost *iface, LPPOINT lppt)
225 {
226     ITextHostImpl *This = impl_from_ITextHost(iface);
227     return ClientToScreen(This->hWnd, lppt);
228 }
229 
230 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxActivate(ITextHost *iface, LONG *plOldState)
231 {
232     ITextHostImpl *This = impl_from_ITextHost(iface);
233     *plOldState = HandleToLong(SetActiveWindow(This->hWnd));
234     return (*plOldState ? S_OK : E_FAIL);
235 }
236 
237 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDeactivate(ITextHost *iface, LONG lNewState)
238 {
239     HWND ret = SetActiveWindow(LongToHandle(lNewState));
240     return (ret ? S_OK : E_FAIL);
241 }
242 
243 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetClientRect(ITextHost *iface, LPRECT prc)
244 {
245     ITextHostImpl *This = impl_from_ITextHost(iface);
246     int ret = GetClientRect(This->hWnd, prc);
247     return (ret ? S_OK : E_FAIL);
248 }
249 
250 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetViewInset(ITextHost *iface, LPRECT prc)
251 {
252     prc->top = 0;
253     prc->left = 0;
254     prc->bottom = 0;
255     prc->right = 0;
256     return S_OK;
257 }
258 
259 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetCharFormat(ITextHost *iface, const CHARFORMATW **ppCF)
260 {
261     return E_NOTIMPL;
262 }
263 
264 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetParaFormat(ITextHost *iface, const PARAFORMAT **fmt)
265 {
266     ITextHostImpl *This = impl_from_ITextHost(iface);
267     *fmt = (const PARAFORMAT *)&This->para_fmt;
268     return S_OK;
269 }
270 
271 DECLSPEC_HIDDEN COLORREF __thiscall ITextHostImpl_TxGetSysColor(ITextHost *iface, int nIndex)
272 {
273     return GetSysColor(nIndex);
274 }
275 
276 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetBackStyle(ITextHost *iface, TXTBACKSTYLE *pStyle)
277 {
278     *pStyle = TXTBACK_OPAQUE;
279     return S_OK;
280 }
281 
282 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength(ITextHost *iface, DWORD *pLength)
283 {
284     *pLength = INFINITE;
285     return S_OK;
286 }
287 
288 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars(ITextHost *iface, DWORD *pdwScrollBar)
289 {
290     ITextHostImpl *This = impl_from_ITextHost(iface);
291     ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0);
292     const DWORD mask = WS_VSCROLL|
293                        WS_HSCROLL|
294                        ES_AUTOVSCROLL|
295                        ES_AUTOHSCROLL|
296                        ES_DISABLENOSCROLL;
297     if (editor)
298     {
299         *pdwScrollBar = editor->styleFlags & mask;
300     } else {
301         DWORD style = GetWindowLongW(This->hWnd, GWL_STYLE);
302         if (style & WS_VSCROLL)
303             style |= ES_AUTOVSCROLL;
304         if (!This->bEmulateVersion10 && (style & WS_HSCROLL))
305             style |= ES_AUTOHSCROLL;
306         *pdwScrollBar = style & mask;
307     }
308     return S_OK;
309 }
310 
311 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPasswordChar(ITextHost *iface, WCHAR *pch)
312 {
313     *pch = '*';
314     return S_OK;
315 }
316 
317 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetAcceleratorPos(ITextHost *iface, LONG *pch)
318 {
319     *pch = -1;
320     return S_OK;
321 }
322 
323 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetExtent(ITextHost *iface, LPSIZEL lpExtent)
324 {
325     return E_NOTIMPL;
326 }
327 
328 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxCharFormatChange(ITextHost *iface, const CHARFORMATW *pcf)
329 {
330     return S_OK;
331 }
332 
333 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxParaFormatChange(ITextHost *iface, const PARAFORMAT *ppf)
334 {
335     return S_OK;
336 }
337 
338 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPropertyBits(ITextHost *iface, DWORD dwMask, DWORD *pdwBits)
339 {
340     ITextHostImpl *This = impl_from_ITextHost(iface);
341     ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(This->hWnd, 0);
342     DWORD style;
343     DWORD dwBits = 0;
344 
345     if (editor)
346     {
347         style = editor->styleFlags;
348         if (editor->mode & TM_RICHTEXT)
349             dwBits |= TXTBIT_RICHTEXT;
350         if (editor->bWordWrap)
351             dwBits |= TXTBIT_WORDWRAP;
352         if (style & ECO_AUTOWORDSELECTION)
353             dwBits |= TXTBIT_AUTOWORDSEL;
354     } else {
355         DWORD dwScrollBar;
356 
357         style = GetWindowLongW(This->hWnd, GWL_STYLE);
358         ITextHostImpl_TxGetScrollBars(iface, &dwScrollBar);
359 
360         dwBits |= TXTBIT_RICHTEXT|TXTBIT_AUTOWORDSEL;
361         if (!(dwScrollBar & ES_AUTOHSCROLL))
362             dwBits |= TXTBIT_WORDWRAP;
363     }
364 
365     /* Bits that correspond to window styles. */
366     if (style & ES_MULTILINE)
367         dwBits |= TXTBIT_MULTILINE;
368     if (style & ES_READONLY)
369         dwBits |= TXTBIT_READONLY;
370     if (style & ES_PASSWORD)
371         dwBits |= TXTBIT_USEPASSWORD;
372     if (!(style & ES_NOHIDESEL))
373         dwBits |= TXTBIT_HIDESELECTION;
374     if (style & ES_SAVESEL)
375         dwBits |= TXTBIT_SAVESELECTION;
376     if (style & ES_VERTICAL)
377         dwBits |= TXTBIT_VERTICAL;
378     if (style & ES_NOOLEDRAGDROP)
379         dwBits |= TXTBIT_DISABLEDRAG;
380 
381     dwBits |= TXTBIT_ALLOWBEEP;
382 
383     /* The following bits are always FALSE because they are probably only
384      * needed for ITextServices_OnTxPropertyBitsChange:
385      *   TXTBIT_VIEWINSETCHANGE
386      *   TXTBIT_BACKSTYLECHANGE
387      *   TXTBIT_MAXLENGTHCHANGE
388      *   TXTBIT_CHARFORMATCHANGE
389      *   TXTBIT_PARAFORMATCHANGE
390      *   TXTBIT_SHOWACCELERATOR
391      *   TXTBIT_EXTENTCHANGE
392      *   TXTBIT_SELBARCHANGE
393      *   TXTBIT_SCROLLBARCHANGE
394      *   TXTBIT_CLIENTRECTCHANGE
395      *
396      * Documented by MSDN as not supported:
397      *   TXTBIT_USECURRENTBKG
398      */
399 
400     *pdwBits = dwBits & dwMask;
401     return S_OK;
402 }
403 
404 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, void *pv)
405 {
406     ITextHostImpl *This = impl_from_ITextHost(iface);
407     ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0);
408     HWND hwnd = This->hWnd;
409     UINT id;
410 
411     if (!editor || !editor->hwndParent) return S_OK;
412 
413     id = GetWindowLongW(hwnd, GWLP_ID);
414 
415     switch (iNotify)
416     {
417         case EN_DROPFILES:
418         case EN_LINK:
419         case EN_OLEOPFAILED:
420         case EN_PROTECTED:
421         case EN_REQUESTRESIZE:
422         case EN_SAVECLIPBOARD:
423         case EN_SELCHANGE:
424         case EN_STOPNOUNDO:
425         {
426             /* FIXME: Verify this assumption that pv starts with NMHDR. */
427             NMHDR *info = pv;
428             if (!info)
429                 return E_FAIL;
430 
431             info->hwndFrom = hwnd;
432             info->idFrom = id;
433             info->code = iNotify;
434             SendMessageW(editor->hwndParent, WM_NOTIFY, id, (LPARAM)info);
435             break;
436         }
437 
438         case EN_UPDATE:
439             /* Only sent when the window is visible. */
440             if (!IsWindowVisible(hwnd))
441                 break;
442             /* Fall through */
443         case EN_CHANGE:
444         case EN_ERRSPACE:
445         case EN_HSCROLL:
446         case EN_KILLFOCUS:
447         case EN_MAXTEXT:
448         case EN_SETFOCUS:
449         case EN_VSCROLL:
450             SendMessageW(editor->hwndParent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd);
451             break;
452 
453         case EN_MSGFILTER:
454             FIXME("EN_MSGFILTER is documented as not being sent to TxNotify\n");
455             /* fall through */
456         default:
457             return E_FAIL;
458     }
459     return S_OK;
460 }
461 
462 DECLSPEC_HIDDEN HIMC __thiscall ITextHostImpl_TxImmGetContext(ITextHost *iface)
463 {
464     ITextHostImpl *This = impl_from_ITextHost(iface);
465     return ImmGetContext(This->hWnd);
466 }
467 
468 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxImmReleaseContext(ITextHost *iface, HIMC himc)
469 {
470     ITextHostImpl *This = impl_from_ITextHost(iface);
471     ImmReleaseContext(This->hWnd, himc);
472 }
473 
474 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface, LONG *lSelBarWidth)
475 {
476     ITextHostImpl *This = impl_from_ITextHost(iface);
477     ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongPtrW(This->hWnd, 0);
478 
479     DWORD style = editor ? editor->styleFlags
480                          : GetWindowLongW(This->hWnd, GWL_STYLE);
481     *lSelBarWidth = (style & ES_SELECTIONBAR) ? 225 : 0; /* in HIMETRIC */
482     return S_OK;
483 }
484 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC,4)
485 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC,8)
486 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar,12)
487 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar,12)
488 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange,20)
489 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos,16)
490 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect,12)
491 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange,8)
492 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret,16)
493 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret,8)
494 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos,12)
495 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer,12)
496 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer,8)
497 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx,32)
498 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture,8)
499 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus,4)
500 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor,12)
501 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient,8)
502 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen,8)
503 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate,8)
504 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate,8)
505 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8)
506 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8)
507 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat,8)
508 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat,8)
509 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor,8)
510 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle,8)
511 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength,8)
512 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8)
513 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar,8)
514 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos,8)
515 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent,8)
516 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange,8)
517 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange,8)
518 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits,12)
519 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify,12)
520 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext,4)
521 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext,8)
522 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth,8)
523 
524 #if defined(__i386__) && !defined(__MINGW32__)  /* thiscall functions are i386-specific */
525 
526 #define STDCALL(func) (void *) __stdcall_ ## func
527 #ifdef _MSC_VER
528 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
529     __declspec(naked) HRESULT __stdcall_##func(void) \
530     { \
531         __asm pop eax \
532         __asm pop ecx \
533         __asm push eax \
534         __asm mov eax, [ecx] \
535         __asm jmp dword ptr [eax + 4*num] \
536     }
537 #else /* _MSC_VER */
538 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
539    extern HRESULT __stdcall_ ## func(void); \
540    __ASM_GLOBAL_FUNC(__stdcall_ ## func, \
541                    "popl %eax\n\t" \
542                    "popl %ecx\n\t" \
543                    "pushl %eax\n\t" \
544                    "movl (%ecx), %eax\n\t" \
545                    "jmp *(4*(" #num "))(%eax)" )
546 #endif /* _MSC_VER */
547 
548 DEFINE_STDCALL_WRAPPER(3,ITextHostImpl_TxGetDC,4)
549 DEFINE_STDCALL_WRAPPER(4,ITextHostImpl_TxReleaseDC,8)
550 DEFINE_STDCALL_WRAPPER(5,ITextHostImpl_TxShowScrollBar,12)
551 DEFINE_STDCALL_WRAPPER(6,ITextHostImpl_TxEnableScrollBar,12)
552 DEFINE_STDCALL_WRAPPER(7,ITextHostImpl_TxSetScrollRange,20)
553 DEFINE_STDCALL_WRAPPER(8,ITextHostImpl_TxSetScrollPos,16)
554 DEFINE_STDCALL_WRAPPER(9,ITextHostImpl_TxInvalidateRect,12)
555 DEFINE_STDCALL_WRAPPER(10,ITextHostImpl_TxViewChange,8)
556 DEFINE_STDCALL_WRAPPER(11,ITextHostImpl_TxCreateCaret,16)
557 DEFINE_STDCALL_WRAPPER(12,ITextHostImpl_TxShowCaret,8)
558 DEFINE_STDCALL_WRAPPER(13,ITextHostImpl_TxSetCaretPos,12)
559 DEFINE_STDCALL_WRAPPER(14,ITextHostImpl_TxSetTimer,12)
560 DEFINE_STDCALL_WRAPPER(15,ITextHostImpl_TxKillTimer,8)
561 DEFINE_STDCALL_WRAPPER(16,ITextHostImpl_TxScrollWindowEx,32)
562 DEFINE_STDCALL_WRAPPER(17,ITextHostImpl_TxSetCapture,8)
563 DEFINE_STDCALL_WRAPPER(18,ITextHostImpl_TxSetFocus,4)
564 DEFINE_STDCALL_WRAPPER(19,ITextHostImpl_TxSetCursor,12)
565 DEFINE_STDCALL_WRAPPER(20,ITextHostImpl_TxScreenToClient,8)
566 DEFINE_STDCALL_WRAPPER(21,ITextHostImpl_TxClientToScreen,8)
567 DEFINE_STDCALL_WRAPPER(22,ITextHostImpl_TxActivate,8)
568 DEFINE_STDCALL_WRAPPER(23,ITextHostImpl_TxDeactivate,8)
569 DEFINE_STDCALL_WRAPPER(24,ITextHostImpl_TxGetClientRect,8)
570 DEFINE_STDCALL_WRAPPER(25,ITextHostImpl_TxGetViewInset,8)
571 DEFINE_STDCALL_WRAPPER(26,ITextHostImpl_TxGetCharFormat,8)
572 DEFINE_STDCALL_WRAPPER(27,ITextHostImpl_TxGetParaFormat,8)
573 DEFINE_STDCALL_WRAPPER(28,ITextHostImpl_TxGetSysColor,8)
574 DEFINE_STDCALL_WRAPPER(29,ITextHostImpl_TxGetBackStyle,8)
575 DEFINE_STDCALL_WRAPPER(30,ITextHostImpl_TxGetMaxLength,8)
576 DEFINE_STDCALL_WRAPPER(31,ITextHostImpl_TxGetScrollBars,8)
577 DEFINE_STDCALL_WRAPPER(32,ITextHostImpl_TxGetPasswordChar,8)
578 DEFINE_STDCALL_WRAPPER(33,ITextHostImpl_TxGetAcceleratorPos,8)
579 DEFINE_STDCALL_WRAPPER(34,ITextHostImpl_TxGetExtent,8)
580 DEFINE_STDCALL_WRAPPER(35,ITextHostImpl_OnTxCharFormatChange,8)
581 DEFINE_STDCALL_WRAPPER(36,ITextHostImpl_OnTxParaFormatChange,8)
582 DEFINE_STDCALL_WRAPPER(37,ITextHostImpl_TxGetPropertyBits,12)
583 DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify,12)
584 DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext,4)
585 DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext,8)
586 DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth,8)
587 
588 const ITextHostVtbl itextHostStdcallVtbl = {
589     NULL,
590     NULL,
591     NULL,
592     STDCALL(ITextHostImpl_TxGetDC),
593     STDCALL(ITextHostImpl_TxReleaseDC),
594     STDCALL(ITextHostImpl_TxShowScrollBar),
595     STDCALL(ITextHostImpl_TxEnableScrollBar),
596     STDCALL(ITextHostImpl_TxSetScrollRange),
597     STDCALL(ITextHostImpl_TxSetScrollPos),
598     STDCALL(ITextHostImpl_TxInvalidateRect),
599     STDCALL(ITextHostImpl_TxViewChange),
600     STDCALL(ITextHostImpl_TxCreateCaret),
601     STDCALL(ITextHostImpl_TxShowCaret),
602     STDCALL(ITextHostImpl_TxSetCaretPos),
603     STDCALL(ITextHostImpl_TxSetTimer),
604     STDCALL(ITextHostImpl_TxKillTimer),
605     STDCALL(ITextHostImpl_TxScrollWindowEx),
606     STDCALL(ITextHostImpl_TxSetCapture),
607     STDCALL(ITextHostImpl_TxSetFocus),
608     STDCALL(ITextHostImpl_TxSetCursor),
609     STDCALL(ITextHostImpl_TxScreenToClient),
610     STDCALL(ITextHostImpl_TxClientToScreen),
611     STDCALL(ITextHostImpl_TxActivate),
612     STDCALL(ITextHostImpl_TxDeactivate),
613     STDCALL(ITextHostImpl_TxGetClientRect),
614     STDCALL(ITextHostImpl_TxGetViewInset),
615     STDCALL(ITextHostImpl_TxGetCharFormat),
616     STDCALL(ITextHostImpl_TxGetParaFormat),
617     STDCALL(ITextHostImpl_TxGetSysColor),
618     STDCALL(ITextHostImpl_TxGetBackStyle),
619     STDCALL(ITextHostImpl_TxGetMaxLength),
620     STDCALL(ITextHostImpl_TxGetScrollBars),
621     STDCALL(ITextHostImpl_TxGetPasswordChar),
622     STDCALL(ITextHostImpl_TxGetAcceleratorPos),
623     STDCALL(ITextHostImpl_TxGetExtent),
624     STDCALL(ITextHostImpl_OnTxCharFormatChange),
625     STDCALL(ITextHostImpl_OnTxParaFormatChange),
626     STDCALL(ITextHostImpl_TxGetPropertyBits),
627     STDCALL(ITextHostImpl_TxNotify),
628     STDCALL(ITextHostImpl_TxImmGetContext),
629     STDCALL(ITextHostImpl_TxImmReleaseContext),
630     STDCALL(ITextHostImpl_TxGetSelectionBarWidth),
631 };
632 
633 #endif /* __i386__ */
634 
635 static const ITextHostVtbl textHostVtbl = {
636     ITextHostImpl_QueryInterface,
637     ITextHostImpl_AddRef,
638     ITextHostImpl_Release,
639     THISCALL(ITextHostImpl_TxGetDC),
640     THISCALL(ITextHostImpl_TxReleaseDC),
641     THISCALL(ITextHostImpl_TxShowScrollBar),
642     THISCALL(ITextHostImpl_TxEnableScrollBar),
643     THISCALL(ITextHostImpl_TxSetScrollRange),
644     THISCALL(ITextHostImpl_TxSetScrollPos),
645     THISCALL(ITextHostImpl_TxInvalidateRect),
646     THISCALL(ITextHostImpl_TxViewChange),
647     THISCALL(ITextHostImpl_TxCreateCaret),
648     THISCALL(ITextHostImpl_TxShowCaret),
649     THISCALL(ITextHostImpl_TxSetCaretPos),
650     THISCALL(ITextHostImpl_TxSetTimer),
651     THISCALL(ITextHostImpl_TxKillTimer),
652     THISCALL(ITextHostImpl_TxScrollWindowEx),
653     THISCALL(ITextHostImpl_TxSetCapture),
654     THISCALL(ITextHostImpl_TxSetFocus),
655     THISCALL(ITextHostImpl_TxSetCursor),
656     THISCALL(ITextHostImpl_TxScreenToClient),
657     THISCALL(ITextHostImpl_TxClientToScreen),
658     THISCALL(ITextHostImpl_TxActivate),
659     THISCALL(ITextHostImpl_TxDeactivate),
660     THISCALL(ITextHostImpl_TxGetClientRect),
661     THISCALL(ITextHostImpl_TxGetViewInset),
662     THISCALL(ITextHostImpl_TxGetCharFormat),
663     THISCALL(ITextHostImpl_TxGetParaFormat),
664     THISCALL(ITextHostImpl_TxGetSysColor),
665     THISCALL(ITextHostImpl_TxGetBackStyle),
666     THISCALL(ITextHostImpl_TxGetMaxLength),
667     THISCALL(ITextHostImpl_TxGetScrollBars),
668     THISCALL(ITextHostImpl_TxGetPasswordChar),
669     THISCALL(ITextHostImpl_TxGetAcceleratorPos),
670     THISCALL(ITextHostImpl_TxGetExtent),
671     THISCALL(ITextHostImpl_OnTxCharFormatChange),
672     THISCALL(ITextHostImpl_OnTxParaFormatChange),
673     THISCALL(ITextHostImpl_TxGetPropertyBits),
674     THISCALL(ITextHostImpl_TxNotify),
675     THISCALL(ITextHostImpl_TxImmGetContext),
676     THISCALL(ITextHostImpl_TxImmReleaseContext),
677     THISCALL(ITextHostImpl_TxGetSelectionBarWidth),
678 };
679