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