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