d3d10/effect: Add a helper to read raw variable values.
[wine.git] / dlls / riched20 / txthost.c
blobaf4d37d9fd2671ce2fc2d57a916c4731cdf6b2c3
1 /*
2 * RichEdit - ITextHost implementation for windowed richedit controls
4 * Copyright 2009 by Dylan Smith
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.
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.
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
21 #define COBJMACROS
23 #include "editor.h"
24 #include "ole2.h"
25 #include "richole.h"
26 #include "imm.h"
27 #include "textserv.h"
28 #include "wine/debug.h"
29 #include "editstr.h"
30 #include "rtf.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
34 struct host
36 ITextHost2 ITextHost_iface;
37 LONG ref;
38 ITextServices *text_srv;
39 HWND window, parent;
40 unsigned int emulate_10 : 1;
41 unsigned int dialog_mode : 1;
42 unsigned int want_return : 1;
43 unsigned int sel_bar : 1;
44 unsigned int client_edge : 1;
45 unsigned int use_set_rect : 1;
46 unsigned int use_back_colour : 1;
47 PARAFORMAT2 para_fmt;
48 DWORD props, scrollbars, event_mask;
49 RECT client_rect, set_rect;
50 COLORREF back_colour;
51 WCHAR password_char;
54 static const ITextHost2Vtbl textHostVtbl;
56 static BOOL listbox_registered;
57 static BOOL combobox_registered;
59 static void host_init_props( struct host *host )
61 DWORD style;
63 style = GetWindowLongW( host->window, GWL_STYLE );
65 /* text services assumes the scrollbars are originally not shown, so hide them.
66 However with ES_DISABLENOSCROLL it'll immediately show them, so don't bother */
67 if (!(style & ES_DISABLENOSCROLL)) ShowScrollBar( host->window, SB_BOTH, FALSE );
69 host->scrollbars = style & (WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL |
70 ES_AUTOHSCROLL | ES_DISABLENOSCROLL);
71 if (style & WS_VSCROLL) host->scrollbars |= ES_AUTOVSCROLL;
72 if ((style & WS_HSCROLL) && !host->emulate_10) host->scrollbars |= ES_AUTOHSCROLL;
74 host->props = TXTBIT_RICHTEXT | TXTBIT_ALLOWBEEP;
75 if (style & ES_MULTILINE) host->props |= TXTBIT_MULTILINE;
76 if (style & ES_READONLY) host->props |= TXTBIT_READONLY;
77 if (style & ES_PASSWORD) host->props |= TXTBIT_USEPASSWORD;
78 if (!(style & ES_NOHIDESEL)) host->props |= TXTBIT_HIDESELECTION;
79 if (style & ES_SAVESEL) host->props |= TXTBIT_SAVESELECTION;
80 if (style & ES_VERTICAL) host->props |= TXTBIT_VERTICAL;
81 if (style & ES_NOOLEDRAGDROP) host->props |= TXTBIT_DISABLEDRAG;
83 if (!(host->scrollbars & ES_AUTOHSCROLL)) host->props |= TXTBIT_WORDWRAP;
85 host->sel_bar = !!(style & ES_SELECTIONBAR);
86 host->want_return = !!(style & ES_WANTRETURN);
88 style = GetWindowLongW( host->window, GWL_EXSTYLE );
89 host->client_edge = !!(style & WS_EX_CLIENTEDGE);
92 struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 )
94 struct host *texthost;
96 texthost = heap_alloc(sizeof(*texthost));
97 if (!texthost) return NULL;
99 texthost->ITextHost_iface.lpVtbl = &textHostVtbl;
100 texthost->ref = 1;
101 texthost->text_srv = NULL;
102 texthost->window = hwnd;
103 texthost->parent = cs->hwndParent;
104 texthost->emulate_10 = emulate_10;
105 texthost->dialog_mode = 0;
106 memset( &texthost->para_fmt, 0, sizeof(texthost->para_fmt) );
107 texthost->para_fmt.cbSize = sizeof(texthost->para_fmt);
108 texthost->para_fmt.dwMask = PFM_ALIGNMENT;
109 texthost->para_fmt.wAlignment = PFA_LEFT;
110 if (cs->style & ES_RIGHT)
111 texthost->para_fmt.wAlignment = PFA_RIGHT;
112 if (cs->style & ES_CENTER)
113 texthost->para_fmt.wAlignment = PFA_CENTER;
114 host_init_props( texthost );
115 texthost->event_mask = 0;
116 texthost->use_set_rect = 0;
117 SetRectEmpty( &texthost->set_rect );
118 GetClientRect( hwnd, &texthost->client_rect );
119 texthost->use_back_colour = 0;
120 texthost->password_char = (texthost->props & TXTBIT_USEPASSWORD) ? '*' : 0;
122 return texthost;
125 static inline struct host *impl_from_ITextHost( ITextHost2 *iface )
127 return CONTAINING_RECORD( iface, struct host, ITextHost_iface );
130 static HRESULT WINAPI ITextHostImpl_QueryInterface( ITextHost2 *iface, REFIID iid, void **obj )
132 struct host *host = impl_from_ITextHost( iface );
134 if (IsEqualIID( iid, &IID_IUnknown ) || IsEqualIID( iid, &IID_ITextHost ) || IsEqualIID( iid, &IID_ITextHost2 ))
136 *obj = &host->ITextHost_iface;
137 ITextHost_AddRef( (ITextHost *)*obj );
138 return S_OK;
141 FIXME( "Unknown interface: %s\n", debugstr_guid( iid ) );
142 return E_NOINTERFACE;
145 static ULONG WINAPI ITextHostImpl_AddRef( ITextHost2 *iface )
147 struct host *host = impl_from_ITextHost( iface );
148 ULONG ref = InterlockedIncrement( &host->ref );
149 return ref;
152 static ULONG WINAPI ITextHostImpl_Release( ITextHost2 *iface )
154 struct host *host = impl_from_ITextHost( iface );
155 ULONG ref = InterlockedDecrement( &host->ref );
157 if (!ref)
159 SetWindowLongPtrW( host->window, 0, 0 );
160 ITextServices_Release( host->text_srv );
161 heap_free( host );
163 return ref;
166 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC,4)
167 DECLSPEC_HIDDEN HDC __thiscall ITextHostImpl_TxGetDC( ITextHost2 *iface )
169 struct host *host = impl_from_ITextHost( iface );
170 return GetDC( host->window );
173 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC,8)
174 DECLSPEC_HIDDEN INT __thiscall ITextHostImpl_TxReleaseDC( ITextHost2 *iface, HDC hdc )
176 struct host *host = impl_from_ITextHost( iface );
177 return ReleaseDC( host->window, hdc );
180 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar,12)
181 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowScrollBar( ITextHost2 *iface, INT bar, BOOL show )
183 struct host *host = impl_from_ITextHost( iface );
184 return ShowScrollBar( host->window, bar, show );
187 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar,12)
188 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxEnableScrollBar( ITextHost2 *iface, INT bar, INT arrows )
190 struct host *host = impl_from_ITextHost( iface );
191 return EnableScrollBar( host->window, bar, arrows );
194 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange,20)
195 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollRange( ITextHost2 *iface, INT bar, LONG min_pos, INT max_pos, BOOL redraw )
197 struct host *host = impl_from_ITextHost( iface );
198 SCROLLINFO info = { .cbSize = sizeof(info), .fMask = SIF_PAGE | SIF_RANGE };
200 if (bar != SB_HORZ && bar != SB_VERT)
202 FIXME( "Unexpected bar %d\n", bar );
203 return FALSE;
206 if (host->scrollbars & ES_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL;
208 if (host->text_srv) /* This can be called during text services creation */
210 if (bar == SB_HORZ) ITextServices_TxGetHScroll( host->text_srv, NULL, NULL, NULL, (LONG *)&info.nPage, NULL );
211 else ITextServices_TxGetVScroll( host->text_srv, NULL, NULL, NULL, (LONG *)&info.nPage, NULL );
214 info.nMin = min_pos;
215 info.nMax = max_pos;
216 return SetScrollInfo( host->window, bar, &info, redraw );
219 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos,16)
220 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollPos( ITextHost2 *iface, INT bar, INT pos, BOOL redraw )
222 struct host *host = impl_from_ITextHost( iface );
223 DWORD style = GetWindowLongW( host->window, GWL_STYLE );
224 DWORD mask = (bar == SB_HORZ) ? WS_HSCROLL : WS_VSCROLL;
225 BOOL show = TRUE, shown = style & mask;
227 if (bar != SB_HORZ && bar != SB_VERT)
229 FIXME( "Unexpected bar %d\n", bar );
230 return FALSE;
233 /* If the application has adjusted the scrollbar's visibility it is reset */
234 if (!(host->scrollbars & ES_DISABLENOSCROLL))
236 if (bar == SB_HORZ) ITextServices_TxGetHScroll( host->text_srv, NULL, NULL, NULL, NULL, &show );
237 else ITextServices_TxGetVScroll( host->text_srv, NULL, NULL, NULL, NULL, &show );
240 if (!show ^ !shown) ShowScrollBar( host->window, bar, show );
241 return SetScrollPos( host->window, bar, pos, redraw ) != 0;
244 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect,12)
245 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxInvalidateRect( ITextHost2 *iface, const RECT *rect, BOOL mode )
247 struct host *host = impl_from_ITextHost( iface );
248 InvalidateRect( host->window, rect, mode );
251 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange,8)
252 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxViewChange( ITextHost2 *iface, BOOL update )
254 struct host *host = impl_from_ITextHost( iface );
255 if (update) UpdateWindow( host->window );
258 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret,16)
259 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxCreateCaret( ITextHost2 *iface, HBITMAP bitmap, INT width, INT height )
261 struct host *host = impl_from_ITextHost( iface );
262 return CreateCaret( host->window, bitmap, width, height );
265 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret,8)
266 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowCaret( ITextHost2 *iface, BOOL show )
268 struct host *host = impl_from_ITextHost( iface );
269 if (show) return ShowCaret( host->window );
270 else return HideCaret( host->window );
273 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos,12)
274 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetCaretPos( ITextHost2 *iface, INT x, INT y )
276 return SetCaretPos(x, y);
279 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer,12)
280 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetTimer( ITextHost2 *iface, UINT id, UINT timeout )
282 struct host *host = impl_from_ITextHost( iface );
283 return SetTimer( host->window, id, timeout, NULL ) != 0;
286 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer,8)
287 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxKillTimer( ITextHost2 *iface, UINT id )
289 struct host *host = impl_from_ITextHost( iface );
290 KillTimer( host->window, id );
293 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx,32)
294 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxScrollWindowEx( ITextHost2 *iface, INT dx, INT dy, const RECT *scroll,
295 const RECT *clip, HRGN update_rgn, RECT *update_rect,
296 UINT flags )
298 struct host *host = impl_from_ITextHost( iface );
299 ScrollWindowEx( host->window, dx, dy, scroll, clip, update_rgn, update_rect, flags );
302 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture,8)
303 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCapture( ITextHost2 *iface, BOOL capture )
305 struct host *host = impl_from_ITextHost( iface );
306 if (capture) SetCapture( host->window );
307 else ReleaseCapture();
310 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus,4)
311 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetFocus( ITextHost2 *iface )
313 struct host *host = impl_from_ITextHost( iface );
314 SetFocus( host->window );
317 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor,12)
318 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCursor( ITextHost2 *iface, HCURSOR cursor, BOOL text )
320 SetCursor( cursor );
323 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient,8)
324 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxScreenToClient( ITextHost2 *iface, POINT *pt )
326 struct host *host = impl_from_ITextHost( iface );
327 return ScreenToClient( host->window, pt );
330 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen,8)
331 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxClientToScreen( ITextHost2 *iface, POINT *pt )
333 struct host *host = impl_from_ITextHost( iface );
334 return ClientToScreen( host->window, pt );
337 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate,8)
338 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxActivate( ITextHost2 *iface, LONG *old_state )
340 struct host *host = impl_from_ITextHost( iface );
341 *old_state = HandleToLong( SetActiveWindow( host->window ) );
342 return *old_state ? S_OK : E_FAIL;
345 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate,8)
346 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDeactivate( ITextHost2 *iface, LONG new_state )
348 HWND ret = SetActiveWindow( LongToHandle( new_state ) );
349 return ret ? S_OK : E_FAIL;
352 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8)
353 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetClientRect( ITextHost2 *iface, RECT *rect )
355 struct host *host = impl_from_ITextHost( iface );
357 if (!host->use_set_rect)
359 *rect = host->client_rect;
360 if (host->client_edge) rect->top += 1;
361 InflateRect( rect, -1, 0 );
363 else *rect = host->set_rect;
365 return S_OK;
368 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8)
369 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetViewInset( ITextHost2 *iface, RECT *rect )
371 SetRectEmpty( rect );
372 return S_OK;
375 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat,8)
376 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetCharFormat( ITextHost2 *iface, const CHARFORMATW **ppCF )
378 return E_NOTIMPL;
381 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat,8)
382 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetParaFormat( ITextHost2 *iface, const PARAFORMAT **fmt )
384 struct host *host = impl_from_ITextHost( iface );
385 *fmt = (const PARAFORMAT *)&host->para_fmt;
386 return S_OK;
389 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor,8)
390 DECLSPEC_HIDDEN COLORREF __thiscall ITextHostImpl_TxGetSysColor( ITextHost2 *iface, int index )
392 struct host *host = impl_from_ITextHost( iface );
394 if (index == COLOR_WINDOW && host->use_back_colour) return host->back_colour;
395 return GetSysColor( index );
398 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle,8)
399 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetBackStyle( ITextHost2 *iface, TXTBACKSTYLE *style )
401 *style = TXTBACK_OPAQUE;
402 return S_OK;
405 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength,8)
406 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength( ITextHost2 *iface, DWORD *length )
408 *length = INFINITE;
409 return S_OK;
412 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8)
413 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost2 *iface, DWORD *scrollbars )
415 struct host *host = impl_from_ITextHost( iface );
417 *scrollbars = host->scrollbars;
418 return S_OK;
421 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar,8)
422 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPasswordChar( ITextHost2 *iface, WCHAR *c )
424 struct host *host = impl_from_ITextHost( iface );
426 *c = host->password_char;
427 return *c ? S_OK : S_FALSE;
430 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos,8)
431 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetAcceleratorPos( ITextHost2 *iface, LONG *pos )
433 *pos = -1;
434 return S_OK;
437 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent,8)
438 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetExtent( ITextHost2 *iface, SIZEL *extent )
440 return E_NOTIMPL;
443 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange,8)
444 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxCharFormatChange( ITextHost2 *iface, const CHARFORMATW *pcf )
446 return S_OK;
449 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange,8)
450 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxParaFormatChange( ITextHost2 *iface, const PARAFORMAT *ppf )
452 return S_OK;
455 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits,12)
456 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPropertyBits( ITextHost2 *iface, DWORD mask, DWORD *bits )
458 struct host *host = impl_from_ITextHost( iface );
460 *bits = host->props & mask;
461 return S_OK;
464 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify,12)
465 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify( ITextHost2 *iface, DWORD iNotify, void *pv )
467 struct host *host = impl_from_ITextHost( iface );
468 UINT id;
470 if (!host->parent) return S_OK;
472 id = GetWindowLongW( host->window, GWLP_ID );
474 switch (iNotify)
476 case EN_DROPFILES:
477 case EN_LINK:
478 case EN_OLEOPFAILED:
479 case EN_PROTECTED:
480 case EN_REQUESTRESIZE:
481 case EN_SAVECLIPBOARD:
482 case EN_SELCHANGE:
483 case EN_STOPNOUNDO:
485 /* FIXME: Verify this assumption that pv starts with NMHDR. */
486 NMHDR *info = pv;
487 if (!info)
488 return E_FAIL;
490 info->hwndFrom = host->window;
491 info->idFrom = id;
492 info->code = iNotify;
493 SendMessageW( host->parent, WM_NOTIFY, id, (LPARAM)info );
494 break;
497 case EN_UPDATE:
498 /* Only sent when the window is visible. */
499 if (!IsWindowVisible( host->window ))
500 break;
501 /* Fall through */
502 case EN_CHANGE:
503 case EN_ERRSPACE:
504 case EN_HSCROLL:
505 case EN_KILLFOCUS:
506 case EN_MAXTEXT:
507 case EN_SETFOCUS:
508 case EN_VSCROLL:
509 SendMessageW( host->parent, WM_COMMAND, MAKEWPARAM( id, iNotify ), (LPARAM)host->window );
510 break;
512 case EN_MSGFILTER:
513 FIXME("EN_MSGFILTER is documented as not being sent to TxNotify\n");
514 /* fall through */
515 default:
516 return E_FAIL;
518 return S_OK;
521 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext,4)
522 DECLSPEC_HIDDEN HIMC __thiscall ITextHostImpl_TxImmGetContext( ITextHost2 *iface )
524 struct host *host = impl_from_ITextHost( iface );
525 return ImmGetContext( host->window );
528 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext,8)
529 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxImmReleaseContext( ITextHost2 *iface, HIMC context )
531 struct host *host = impl_from_ITextHost( iface );
532 ImmReleaseContext( host->window, context );
535 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth,8)
536 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetSelectionBarWidth( ITextHost2 *iface, LONG *width )
538 struct host *host = impl_from_ITextHost( iface );
540 *width = host->sel_bar ? 225 : 0; /* in HIMETRIC */
541 return S_OK;
544 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxIsDoubleClickPending,4)
545 DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxIsDoubleClickPending( ITextHost2 *iface )
547 return FALSE;
550 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetWindow,8)
551 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetWindow( ITextHost2 *iface, HWND *hwnd )
553 struct host *host = impl_from_ITextHost( iface );
554 *hwnd = host->window;
555 return S_OK;
558 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetForegroundWindow,4)
559 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxSetForegroundWindow( ITextHost2 *iface )
561 return E_NOTIMPL;
564 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPalette,4)
565 DECLSPEC_HIDDEN HPALETTE __thiscall ITextHostImpl_TxGetPalette( ITextHost2 *iface )
567 return NULL;
570 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetEastAsianFlags,8)
571 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetEastAsianFlags( ITextHost2 *iface, LONG *flags )
573 return E_NOTIMPL;
576 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor2,12)
577 DECLSPEC_HIDDEN HCURSOR __thiscall ITextHostImpl_TxSetCursor2( ITextHost2 *iface, HCURSOR cursor, BOOL text )
579 return NULL;
582 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxFreeTextServicesNotification,4)
583 DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxFreeTextServicesNotification( ITextHost2 *iface )
585 return;
588 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetEditStyle,12)
589 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetEditStyle( ITextHost2 *iface, DWORD item, DWORD *data )
591 return E_NOTIMPL;
594 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetWindowStyles,12)
595 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetWindowStyles( ITextHost2 *iface, DWORD *style, DWORD *ex_style )
597 return E_NOTIMPL;
600 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowDropCaret,16)
601 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxShowDropCaret( ITextHost2 *iface, BOOL show, HDC hdc, const RECT *rect )
603 return E_NOTIMPL;
606 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDestroyCaret,4)
607 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDestroyCaret( ITextHost2 *iface )
609 return E_NOTIMPL;
612 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetHorzExtent,8)
613 DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetHorzExtent( ITextHost2 *iface, LONG *horz_extent )
615 return E_NOTIMPL;
619 #ifdef __ASM_USE_THISCALL_WRAPPER
621 #define STDCALL(func) (void *) __stdcall_ ## func
622 #ifdef _MSC_VER
623 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
624 __declspec(naked) HRESULT __stdcall_##func(void) \
626 __asm pop eax \
627 __asm pop ecx \
628 __asm push eax \
629 __asm mov eax, [ecx] \
630 __asm jmp dword ptr [eax + 4*num] \
632 #else /* _MSC_VER */
633 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
634 extern HRESULT __stdcall_ ## func(void); \
635 __ASM_GLOBAL_FUNC(__stdcall_ ## func, \
636 "popl %eax\n\t" \
637 "popl %ecx\n\t" \
638 "pushl %eax\n\t" \
639 "movl (%ecx), %eax\n\t" \
640 "jmp *(4*(" #num "))(%eax)" )
641 #endif /* _MSC_VER */
643 DEFINE_STDCALL_WRAPPER(3,ITextHostImpl_TxGetDC,4)
644 DEFINE_STDCALL_WRAPPER(4,ITextHostImpl_TxReleaseDC,8)
645 DEFINE_STDCALL_WRAPPER(5,ITextHostImpl_TxShowScrollBar,12)
646 DEFINE_STDCALL_WRAPPER(6,ITextHostImpl_TxEnableScrollBar,12)
647 DEFINE_STDCALL_WRAPPER(7,ITextHostImpl_TxSetScrollRange,20)
648 DEFINE_STDCALL_WRAPPER(8,ITextHostImpl_TxSetScrollPos,16)
649 DEFINE_STDCALL_WRAPPER(9,ITextHostImpl_TxInvalidateRect,12)
650 DEFINE_STDCALL_WRAPPER(10,ITextHostImpl_TxViewChange,8)
651 DEFINE_STDCALL_WRAPPER(11,ITextHostImpl_TxCreateCaret,16)
652 DEFINE_STDCALL_WRAPPER(12,ITextHostImpl_TxShowCaret,8)
653 DEFINE_STDCALL_WRAPPER(13,ITextHostImpl_TxSetCaretPos,12)
654 DEFINE_STDCALL_WRAPPER(14,ITextHostImpl_TxSetTimer,12)
655 DEFINE_STDCALL_WRAPPER(15,ITextHostImpl_TxKillTimer,8)
656 DEFINE_STDCALL_WRAPPER(16,ITextHostImpl_TxScrollWindowEx,32)
657 DEFINE_STDCALL_WRAPPER(17,ITextHostImpl_TxSetCapture,8)
658 DEFINE_STDCALL_WRAPPER(18,ITextHostImpl_TxSetFocus,4)
659 DEFINE_STDCALL_WRAPPER(19,ITextHostImpl_TxSetCursor,12)
660 DEFINE_STDCALL_WRAPPER(20,ITextHostImpl_TxScreenToClient,8)
661 DEFINE_STDCALL_WRAPPER(21,ITextHostImpl_TxClientToScreen,8)
662 DEFINE_STDCALL_WRAPPER(22,ITextHostImpl_TxActivate,8)
663 DEFINE_STDCALL_WRAPPER(23,ITextHostImpl_TxDeactivate,8)
664 DEFINE_STDCALL_WRAPPER(24,ITextHostImpl_TxGetClientRect,8)
665 DEFINE_STDCALL_WRAPPER(25,ITextHostImpl_TxGetViewInset,8)
666 DEFINE_STDCALL_WRAPPER(26,ITextHostImpl_TxGetCharFormat,8)
667 DEFINE_STDCALL_WRAPPER(27,ITextHostImpl_TxGetParaFormat,8)
668 DEFINE_STDCALL_WRAPPER(28,ITextHostImpl_TxGetSysColor,8)
669 DEFINE_STDCALL_WRAPPER(29,ITextHostImpl_TxGetBackStyle,8)
670 DEFINE_STDCALL_WRAPPER(30,ITextHostImpl_TxGetMaxLength,8)
671 DEFINE_STDCALL_WRAPPER(31,ITextHostImpl_TxGetScrollBars,8)
672 DEFINE_STDCALL_WRAPPER(32,ITextHostImpl_TxGetPasswordChar,8)
673 DEFINE_STDCALL_WRAPPER(33,ITextHostImpl_TxGetAcceleratorPos,8)
674 DEFINE_STDCALL_WRAPPER(34,ITextHostImpl_TxGetExtent,8)
675 DEFINE_STDCALL_WRAPPER(35,ITextHostImpl_OnTxCharFormatChange,8)
676 DEFINE_STDCALL_WRAPPER(36,ITextHostImpl_OnTxParaFormatChange,8)
677 DEFINE_STDCALL_WRAPPER(37,ITextHostImpl_TxGetPropertyBits,12)
678 DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify,12)
679 DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext,4)
680 DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext,8)
681 DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth,8)
682 /* ITextHost2 */
683 DEFINE_STDCALL_WRAPPER(42,ITextHostImpl_TxIsDoubleClickPending,4)
684 DEFINE_STDCALL_WRAPPER(43,ITextHostImpl_TxGetWindow,8)
685 DEFINE_STDCALL_WRAPPER(44,ITextHostImpl_TxSetForegroundWindow,4)
686 DEFINE_STDCALL_WRAPPER(45,ITextHostImpl_TxGetPalette,4)
687 DEFINE_STDCALL_WRAPPER(46,ITextHostImpl_TxGetEastAsianFlags,8)
688 DEFINE_STDCALL_WRAPPER(47,ITextHostImpl_TxSetCursor2,12)
689 DEFINE_STDCALL_WRAPPER(48,ITextHostImpl_TxFreeTextServicesNotification,4)
690 DEFINE_STDCALL_WRAPPER(49,ITextHostImpl_TxGetEditStyle,12)
691 DEFINE_STDCALL_WRAPPER(50,ITextHostImpl_TxGetWindowStyles,12)
692 DEFINE_STDCALL_WRAPPER(51,ITextHostImpl_TxShowDropCaret,16)
693 DEFINE_STDCALL_WRAPPER(52,ITextHostImpl_TxDestroyCaret,4)
694 DEFINE_STDCALL_WRAPPER(53,ITextHostImpl_TxGetHorzExtent,8)
696 const ITextHost2Vtbl text_host2_stdcall_vtbl =
698 NULL,
699 NULL,
700 NULL,
701 STDCALL(ITextHostImpl_TxGetDC),
702 STDCALL(ITextHostImpl_TxReleaseDC),
703 STDCALL(ITextHostImpl_TxShowScrollBar),
704 STDCALL(ITextHostImpl_TxEnableScrollBar),
705 STDCALL(ITextHostImpl_TxSetScrollRange),
706 STDCALL(ITextHostImpl_TxSetScrollPos),
707 STDCALL(ITextHostImpl_TxInvalidateRect),
708 STDCALL(ITextHostImpl_TxViewChange),
709 STDCALL(ITextHostImpl_TxCreateCaret),
710 STDCALL(ITextHostImpl_TxShowCaret),
711 STDCALL(ITextHostImpl_TxSetCaretPos),
712 STDCALL(ITextHostImpl_TxSetTimer),
713 STDCALL(ITextHostImpl_TxKillTimer),
714 STDCALL(ITextHostImpl_TxScrollWindowEx),
715 STDCALL(ITextHostImpl_TxSetCapture),
716 STDCALL(ITextHostImpl_TxSetFocus),
717 STDCALL(ITextHostImpl_TxSetCursor),
718 STDCALL(ITextHostImpl_TxScreenToClient),
719 STDCALL(ITextHostImpl_TxClientToScreen),
720 STDCALL(ITextHostImpl_TxActivate),
721 STDCALL(ITextHostImpl_TxDeactivate),
722 STDCALL(ITextHostImpl_TxGetClientRect),
723 STDCALL(ITextHostImpl_TxGetViewInset),
724 STDCALL(ITextHostImpl_TxGetCharFormat),
725 STDCALL(ITextHostImpl_TxGetParaFormat),
726 STDCALL(ITextHostImpl_TxGetSysColor),
727 STDCALL(ITextHostImpl_TxGetBackStyle),
728 STDCALL(ITextHostImpl_TxGetMaxLength),
729 STDCALL(ITextHostImpl_TxGetScrollBars),
730 STDCALL(ITextHostImpl_TxGetPasswordChar),
731 STDCALL(ITextHostImpl_TxGetAcceleratorPos),
732 STDCALL(ITextHostImpl_TxGetExtent),
733 STDCALL(ITextHostImpl_OnTxCharFormatChange),
734 STDCALL(ITextHostImpl_OnTxParaFormatChange),
735 STDCALL(ITextHostImpl_TxGetPropertyBits),
736 STDCALL(ITextHostImpl_TxNotify),
737 STDCALL(ITextHostImpl_TxImmGetContext),
738 STDCALL(ITextHostImpl_TxImmReleaseContext),
739 STDCALL(ITextHostImpl_TxGetSelectionBarWidth),
740 /* ITextHost2 */
741 STDCALL(ITextHostImpl_TxIsDoubleClickPending),
742 STDCALL(ITextHostImpl_TxGetWindow),
743 STDCALL(ITextHostImpl_TxSetForegroundWindow),
744 STDCALL(ITextHostImpl_TxGetPalette),
745 STDCALL(ITextHostImpl_TxGetEastAsianFlags),
746 STDCALL(ITextHostImpl_TxSetCursor2),
747 STDCALL(ITextHostImpl_TxFreeTextServicesNotification),
748 STDCALL(ITextHostImpl_TxGetEditStyle),
749 STDCALL(ITextHostImpl_TxGetWindowStyles),
750 STDCALL(ITextHostImpl_TxShowDropCaret),
751 STDCALL(ITextHostImpl_TxDestroyCaret),
752 STDCALL(ITextHostImpl_TxGetHorzExtent)
755 #endif /* __ASM_USE_THISCALL_WRAPPER */
757 static const ITextHost2Vtbl textHostVtbl =
759 ITextHostImpl_QueryInterface,
760 ITextHostImpl_AddRef,
761 ITextHostImpl_Release,
762 THISCALL(ITextHostImpl_TxGetDC),
763 THISCALL(ITextHostImpl_TxReleaseDC),
764 THISCALL(ITextHostImpl_TxShowScrollBar),
765 THISCALL(ITextHostImpl_TxEnableScrollBar),
766 THISCALL(ITextHostImpl_TxSetScrollRange),
767 THISCALL(ITextHostImpl_TxSetScrollPos),
768 THISCALL(ITextHostImpl_TxInvalidateRect),
769 THISCALL(ITextHostImpl_TxViewChange),
770 THISCALL(ITextHostImpl_TxCreateCaret),
771 THISCALL(ITextHostImpl_TxShowCaret),
772 THISCALL(ITextHostImpl_TxSetCaretPos),
773 THISCALL(ITextHostImpl_TxSetTimer),
774 THISCALL(ITextHostImpl_TxKillTimer),
775 THISCALL(ITextHostImpl_TxScrollWindowEx),
776 THISCALL(ITextHostImpl_TxSetCapture),
777 THISCALL(ITextHostImpl_TxSetFocus),
778 THISCALL(ITextHostImpl_TxSetCursor),
779 THISCALL(ITextHostImpl_TxScreenToClient),
780 THISCALL(ITextHostImpl_TxClientToScreen),
781 THISCALL(ITextHostImpl_TxActivate),
782 THISCALL(ITextHostImpl_TxDeactivate),
783 THISCALL(ITextHostImpl_TxGetClientRect),
784 THISCALL(ITextHostImpl_TxGetViewInset),
785 THISCALL(ITextHostImpl_TxGetCharFormat),
786 THISCALL(ITextHostImpl_TxGetParaFormat),
787 THISCALL(ITextHostImpl_TxGetSysColor),
788 THISCALL(ITextHostImpl_TxGetBackStyle),
789 THISCALL(ITextHostImpl_TxGetMaxLength),
790 THISCALL(ITextHostImpl_TxGetScrollBars),
791 THISCALL(ITextHostImpl_TxGetPasswordChar),
792 THISCALL(ITextHostImpl_TxGetAcceleratorPos),
793 THISCALL(ITextHostImpl_TxGetExtent),
794 THISCALL(ITextHostImpl_OnTxCharFormatChange),
795 THISCALL(ITextHostImpl_OnTxParaFormatChange),
796 THISCALL(ITextHostImpl_TxGetPropertyBits),
797 THISCALL(ITextHostImpl_TxNotify),
798 THISCALL(ITextHostImpl_TxImmGetContext),
799 THISCALL(ITextHostImpl_TxImmReleaseContext),
800 THISCALL(ITextHostImpl_TxGetSelectionBarWidth),
801 /* ITextHost2 */
802 THISCALL(ITextHostImpl_TxIsDoubleClickPending),
803 THISCALL(ITextHostImpl_TxGetWindow),
804 THISCALL(ITextHostImpl_TxSetForegroundWindow),
805 THISCALL(ITextHostImpl_TxGetPalette),
806 THISCALL(ITextHostImpl_TxGetEastAsianFlags),
807 THISCALL(ITextHostImpl_TxSetCursor2),
808 THISCALL(ITextHostImpl_TxFreeTextServicesNotification),
809 THISCALL(ITextHostImpl_TxGetEditStyle),
810 THISCALL(ITextHostImpl_TxGetWindowStyles),
811 THISCALL(ITextHostImpl_TxShowDropCaret),
812 THISCALL(ITextHostImpl_TxDestroyCaret),
813 THISCALL(ITextHostImpl_TxGetHorzExtent)
816 static const char * const edit_messages[] =
818 "EM_GETSEL", "EM_SETSEL", "EM_GETRECT", "EM_SETRECT",
819 "EM_SETRECTNP", "EM_SCROLL", "EM_LINESCROLL", "EM_SCROLLCARET",
820 "EM_GETMODIFY", "EM_SETMODIFY", "EM_GETLINECOUNT", "EM_LINEINDEX",
821 "EM_SETHANDLE", "EM_GETHANDLE", "EM_GETTHUMB", "EM_UNKNOWN_BF",
822 "EM_UNKNOWN_C0", "EM_LINELENGTH", "EM_REPLACESEL", "EM_UNKNOWN_C3",
823 "EM_GETLINE", "EM_LIMITTEXT", "EM_CANUNDO", "EM_UNDO",
824 "EM_FMTLINES", "EM_LINEFROMCHAR", "EM_UNKNOWN_CA", "EM_SETTABSTOPS",
825 "EM_SETPASSWORDCHAR", "EM_EMPTYUNDOBUFFER", "EM_GETFIRSTVISIBLELINE", "EM_SETREADONLY",
826 "EM_SETWORDBREAKPROC", "EM_GETWORDBREAKPROC", "EM_GETPASSWORDCHAR", "EM_SETMARGINS",
827 "EM_GETMARGINS", "EM_GETLIMITTEXT", "EM_POSFROMCHAR", "EM_CHARFROMPOS",
828 "EM_SETIMESTATUS", "EM_GETIMESTATUS"
831 static const char * const richedit_messages[] =
833 "EM_CANPASTE", "EM_DISPLAYBAND", "EM_EXGETSEL", "EM_EXLIMITTEXT",
834 "EM_EXLINEFROMCHAR", "EM_EXSETSEL", "EM_FINDTEXT", "EM_FORMATRANGE",
835 "EM_GETCHARFORMAT", "EM_GETEVENTMASK", "EM_GETOLEINTERFACE", "EM_GETPARAFORMAT",
836 "EM_GETSELTEXT", "EM_HIDESELECTION", "EM_PASTESPECIAL", "EM_REQUESTRESIZE",
837 "EM_SELECTIONTYPE", "EM_SETBKGNDCOLOR", "EM_SETCHARFORMAT", "EM_SETEVENTMASK",
838 "EM_SETOLECALLBACK", "EM_SETPARAFORMAT", "EM_SETTARGETDEVICE", "EM_STREAMIN",
839 "EM_STREAMOUT", "EM_GETTEXTRANGE", "EM_FINDWORDBREAK", "EM_SETOPTIONS",
840 "EM_GETOPTIONS", "EM_FINDTEXTEX", "EM_GETWORDBREAKPROCEX", "EM_SETWORDBREAKPROCEX",
841 "EM_SETUNDOLIMIT", "EM_UNKNOWN_USER_83", "EM_REDO", "EM_CANREDO",
842 "EM_GETUNDONAME", "EM_GETREDONAME", "EM_STOPGROUPTYPING", "EM_SETTEXTMODE",
843 "EM_GETTEXTMODE", "EM_AUTOURLDETECT", "EM_GETAUTOURLDETECT", "EM_SETPALETTE",
844 "EM_GETTEXTEX", "EM_GETTEXTLENGTHEX", "EM_SHOWSCROLLBAR", "EM_SETTEXTEX",
845 "EM_UNKNOWN_USER_98", "EM_UNKNOWN_USER_99", "EM_SETPUNCTUATION", "EM_GETPUNCTUATION",
846 "EM_SETWORDWRAPMODE", "EM_GETWORDWRAPMODE", "EM_SETIMECOLOR", "EM_GETIMECOLOR",
847 "EM_SETIMEOPTIONS", "EM_GETIMEOPTIONS", "EM_CONVPOSITION", "EM_UNKNOWN_USER_109",
848 "EM_UNKNOWN_USER_110", "EM_UNKNOWN_USER_111", "EM_UNKNOWN_USER_112", "EM_UNKNOWN_USER_113",
849 "EM_UNKNOWN_USER_114", "EM_UNKNOWN_USER_115", "EM_UNKNOWN_USER_116", "EM_UNKNOWN_USER_117",
850 "EM_UNKNOWN_USER_118", "EM_UNKNOWN_USER_119", "EM_SETLANGOPTIONS", "EM_GETLANGOPTIONS",
851 "EM_GETIMECOMPMODE", "EM_FINDTEXTW", "EM_FINDTEXTEXW", "EM_RECONVERSION",
852 "EM_SETIMEMODEBIAS", "EM_GETIMEMODEBIAS"
855 static const char *get_msg_name( UINT msg )
857 if (msg >= EM_GETSEL && msg <= EM_CHARFROMPOS)
858 return edit_messages[msg - EM_GETSEL];
859 if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS)
860 return richedit_messages[msg - EM_CANPASTE];
861 return "";
864 static BOOL create_windowed_editor( HWND hwnd, CREATESTRUCTW *create, BOOL emulate_10 )
866 struct host *host = host_create( hwnd, create, emulate_10 );
867 IUnknown *unk;
868 HRESULT hr;
870 if (!host) return FALSE;
872 hr = create_text_services( NULL, (ITextHost *)&host->ITextHost_iface, &unk, emulate_10 );
873 if (FAILED( hr ))
875 ITextHost2_Release( &host->ITextHost_iface );
876 return FALSE;
878 IUnknown_QueryInterface( unk, &IID_ITextServices, (void **)&host->text_srv );
879 IUnknown_Release( unk );
881 SetWindowLongPtrW( hwnd, 0, (LONG_PTR)host );
883 return TRUE;
886 static HRESULT get_lineA( ITextServices *text_srv, WPARAM wparam, LPARAM lparam, LRESULT *res )
888 LRESULT len = USHRT_MAX;
889 WORD sizeA;
890 HRESULT hr;
891 WCHAR *buf;
893 *res = 0;
894 sizeA = *(WORD *)lparam;
895 *(WORD *)lparam = 0;
896 if (!sizeA) return S_OK;
897 buf = heap_alloc( len * sizeof(WCHAR) );
898 if (!buf) return E_OUTOFMEMORY;
899 *(WORD *)buf = len;
900 hr = ITextServices_TxSendMessage( text_srv, EM_GETLINE, wparam, (LPARAM)buf, &len );
901 if (hr == S_OK && len)
903 len = WideCharToMultiByte( CP_ACP, 0, buf, len, (char *)lparam, sizeA, NULL, NULL );
904 if (!len && GetLastError() == ERROR_INSUFFICIENT_BUFFER) len = sizeA;
905 if (len < sizeA) ((char *)lparam)[len] = '\0';
906 *res = len;
908 heap_free( buf );
909 return hr;
912 static HRESULT get_text_rangeA( struct host *host, TEXTRANGEA *rangeA, LRESULT *res )
914 TEXTRANGEW range;
915 HRESULT hr;
916 unsigned int count;
917 LRESULT len;
919 *res = 0;
920 if (rangeA->chrg.cpMin < 0) return S_OK;
921 ITextServices_TxSendMessage( host->text_srv, WM_GETTEXTLENGTH, 0, 0, &len );
922 range.chrg = rangeA->chrg;
923 if ((range.chrg.cpMin == 0 && range.chrg.cpMax == -1) || range.chrg.cpMax > len)
924 range.chrg.cpMax = len;
925 if (range.chrg.cpMin >= range.chrg.cpMax) return S_OK;
926 count = range.chrg.cpMax - range.chrg.cpMin + 1;
927 range.lpstrText = heap_alloc( count * sizeof(WCHAR) );
928 if (!range.lpstrText) return E_OUTOFMEMORY;
929 hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTRANGE, 0, (LPARAM)&range, &len );
930 if (hr == S_OK && len)
932 if (!host->emulate_10) count = INT_MAX;
933 len = WideCharToMultiByte( CP_ACP, 0, range.lpstrText, -1, rangeA->lpstrText, count, NULL, NULL );
934 if (!host->emulate_10) *res = len - 1;
935 else
937 *res = count - 1;
938 rangeA->lpstrText[*res] = '\0';
941 heap_free( range.lpstrText );
942 return hr;
945 static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *res )
947 DWORD style, old_options, new_options, change, props_mask = 0;
948 DWORD mask = ECO_AUTOWORDSELECTION | ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY |
949 ECO_WANTRETURN | ECO_SAVESEL | ECO_SELECTIONBAR | ECO_VERTICAL;
951 new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 );
953 switch (op)
955 case ECOOP_SET:
956 new_options = value;
957 break;
958 case ECOOP_OR:
959 new_options |= value;
960 break;
961 case ECOOP_AND:
962 new_options &= value;
963 break;
964 case ECOOP_XOR:
965 new_options ^= value;
967 new_options &= mask;
969 change = (new_options ^ old_options);
971 if (change & ECO_AUTOWORDSELECTION)
973 host->props ^= TXTBIT_AUTOWORDSEL;
974 props_mask |= TXTBIT_AUTOWORDSEL;
976 if (change & ECO_AUTOVSCROLL)
978 host->scrollbars ^= WS_VSCROLL;
979 props_mask |= TXTBIT_SCROLLBARCHANGE;
981 if (change & ECO_AUTOHSCROLL)
983 host->scrollbars ^= WS_HSCROLL;
984 props_mask |= TXTBIT_SCROLLBARCHANGE;
986 if (change & ECO_NOHIDESEL)
988 host->props ^= TXTBIT_HIDESELECTION;
989 props_mask |= TXTBIT_HIDESELECTION;
991 if (change & ECO_READONLY)
993 host->props ^= TXTBIT_READONLY;
994 props_mask |= TXTBIT_READONLY;
996 if (change & ECO_SAVESEL)
998 host->props ^= TXTBIT_SAVESELECTION;
999 props_mask |= TXTBIT_SAVESELECTION;
1001 if (change & ECO_SELECTIONBAR)
1003 host->sel_bar ^= 1;
1004 props_mask |= TXTBIT_SELBARCHANGE;
1005 if (host->use_set_rect)
1007 int width = SELECTIONBAR_WIDTH;
1008 host->set_rect.left += host->sel_bar ? width : -width;
1009 props_mask |= TXTBIT_CLIENTRECTCHANGE;
1012 if (change & ECO_VERTICAL)
1014 host->props ^= TXTBIT_VERTICAL;
1015 props_mask |= TXTBIT_VERTICAL;
1017 if (change & ECO_WANTRETURN) host->want_return ^= 1;
1019 if (props_mask)
1020 ITextServices_OnTxPropertyBitsChange( host->text_srv, props_mask, host->props & props_mask );
1022 *res = new_options;
1024 mask &= ~ECO_AUTOWORDSELECTION; /* doesn't correspond to a window style */
1025 style = GetWindowLongW( host->window, GWL_STYLE );
1026 style = (style & ~mask) | (*res & mask);
1027 SetWindowLongW( host->window, GWL_STYLE, style );
1028 return S_OK;
1031 /* handle dialog mode VK_RETURN. Returns TRUE if message has been processed */
1032 static BOOL handle_dialog_enter( struct host *host )
1034 BOOL ctrl_is_down = GetKeyState( VK_CONTROL ) & 0x8000;
1036 if (ctrl_is_down) return TRUE;
1038 if (host->want_return) return FALSE;
1040 if (host->parent)
1042 DWORD id = SendMessageW( host->parent, DM_GETDEFID, 0, 0 );
1043 if (HIWORD( id ) == DC_HASDEFID)
1045 HWND ctrl = GetDlgItem( host->parent, LOWORD( id ));
1046 if (ctrl)
1048 SendMessageW( host->parent, WM_NEXTDLGCTL, (WPARAM)ctrl, TRUE );
1049 PostMessageW( ctrl, WM_KEYDOWN, VK_RETURN, 0 );
1053 return TRUE;
1056 static LRESULT send_msg_filter( struct host *host, UINT msg, WPARAM *wparam, LPARAM *lparam )
1058 MSGFILTER msgf;
1059 LRESULT res;
1061 if (!host->parent) return 0;
1062 msgf.nmhdr.hwndFrom = host->window;
1063 msgf.nmhdr.idFrom = GetWindowLongW( host->window, GWLP_ID );
1064 msgf.nmhdr.code = EN_MSGFILTER;
1065 msgf.msg = msg;
1066 msgf.wParam = *wparam;
1067 msgf.lParam = *lparam;
1068 if ((res = SendMessageW( host->parent, WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf )))
1069 return res;
1070 *wparam = msgf.wParam;
1071 *lparam = msgf.lParam;
1073 return 0;
1076 static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
1077 LPARAM lparam, BOOL unicode )
1079 struct host *host;
1080 HRESULT hr = S_OK;
1081 LRESULT res = 0;
1083 TRACE( "enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
1084 hwnd, msg, get_msg_name(msg), wparam, lparam, unicode );
1086 host = (struct host *)GetWindowLongPtrW( hwnd, 0 );
1087 if (!host)
1089 if (msg == WM_NCCREATE)
1091 CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam;
1093 TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style );
1094 return create_windowed_editor( hwnd, pcs, FALSE );
1096 else return DefWindowProcW( hwnd, msg, wparam, lparam );
1099 if ((((host->event_mask & ENM_KEYEVENTS) && msg >= WM_KEYFIRST && msg <= WM_KEYLAST) ||
1100 ((host->event_mask & ENM_MOUSEEVENTS) && msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST) ||
1101 ((host->event_mask & ENM_SCROLLEVENTS) && msg >= WM_HSCROLL && msg <= WM_VSCROLL)) &&
1102 send_msg_filter( host, msg, &wparam, &lparam ))
1104 TRACE( "exit (filtered) hwnd %p msg %04x (%s) %lx %lx -> %lu\n",
1105 hwnd, msg, get_msg_name(msg), wparam, lparam, res );
1106 return res;
1109 switch (msg)
1111 case WM_CHAR:
1113 WCHAR wc = wparam;
1115 if (!unicode) MultiByteToWideChar( CP_ACP, 0, (char *)&wparam, 1, &wc, 1 );
1116 if (wparam == '\r' && host->dialog_mode && host->emulate_10 && handle_dialog_enter( host )) break;
1117 hr = ITextServices_TxSendMessage( host->text_srv, msg, wc, lparam, &res );
1118 break;
1121 case WM_CREATE:
1123 CREATESTRUCTW *createW = (CREATESTRUCTW *)lparam;
1124 CREATESTRUCTA *createA = (CREATESTRUCTA *)lparam;
1125 void *text;
1126 WCHAR *textW = NULL;
1127 LONG codepage = unicode ? CP_UNICODE : CP_ACP;
1128 int len;
1130 ITextServices_OnTxInPlaceActivate( host->text_srv, NULL );
1132 if (lparam)
1134 text = unicode ? (void *)createW->lpszName : (void *)createA->lpszName;
1135 textW = ME_ToUnicode( codepage, text, &len );
1137 ITextServices_TxSetText( host->text_srv, textW );
1138 if (lparam) ME_EndToUnicode( codepage, textW );
1139 break;
1141 case WM_DESTROY:
1142 ITextHost2_Release( &host->ITextHost_iface );
1143 return 0;
1145 case WM_ERASEBKGND:
1147 HDC hdc = (HDC)wparam;
1148 RECT rc;
1149 HBRUSH brush;
1151 if (GetUpdateRect( hwnd, &rc, TRUE ))
1153 brush = CreateSolidBrush( ITextHost_TxGetSysColor( &host->ITextHost_iface, COLOR_WINDOW ) );
1154 FillRect( hdc, &rc, brush );
1155 DeleteObject( brush );
1157 return 1;
1159 case EM_FINDTEXT:
1161 FINDTEXTW *params = (FINDTEXTW *)lparam;
1162 FINDTEXTW new_params;
1163 int len;
1165 if (!unicode)
1167 new_params.chrg = params->chrg;
1168 new_params.lpstrText = ME_ToUnicode( CP_ACP, (char *)params->lpstrText, &len );
1169 params = &new_params;
1171 hr = ITextServices_TxSendMessage( host->text_srv, EM_FINDTEXTW, wparam, (LPARAM)params, &res );
1172 if (!unicode) ME_EndToUnicode( CP_ACP, (WCHAR *)new_params.lpstrText );
1173 break;
1175 case EM_FINDTEXTEX:
1177 FINDTEXTEXA *paramsA = (FINDTEXTEXA *)lparam;
1178 FINDTEXTEXW *params = (FINDTEXTEXW *)lparam;
1179 FINDTEXTEXW new_params;
1180 int len;
1182 if (!unicode)
1184 new_params.chrg = params->chrg;
1185 new_params.lpstrText = ME_ToUnicode( CP_ACP, (char *)params->lpstrText, &len );
1186 params = &new_params;
1188 hr = ITextServices_TxSendMessage( host->text_srv, EM_FINDTEXTEXW, wparam, (LPARAM)params, &res );
1189 if (!unicode)
1191 ME_EndToUnicode( CP_ACP, (WCHAR *)new_params.lpstrText );
1192 paramsA->chrgText = params->chrgText;
1194 break;
1196 case WM_GETDLGCODE:
1197 if (lparam) host->dialog_mode = TRUE;
1199 res = DLGC_WANTCHARS | DLGC_WANTTAB | DLGC_WANTARROWS;
1200 if (host->props & TXTBIT_MULTILINE) res |= DLGC_WANTMESSAGE;
1201 if (!(host->props & TXTBIT_SAVESELECTION)) res |= DLGC_HASSETSEL;
1202 break;
1204 case EM_GETLINE:
1205 if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
1206 else hr = get_lineA( host->text_srv, wparam, lparam, &res );
1207 break;
1209 case EM_GETPASSWORDCHAR:
1210 ITextHost_TxGetPasswordChar( &host->ITextHost_iface, (WCHAR *)&res );
1211 break;
1213 case EM_GETRECT:
1214 hr = ITextHost_TxGetClientRect( &host->ITextHost_iface, (RECT *)lparam );
1215 break;
1217 case EM_GETSELTEXT:
1219 TEXTRANGEA range;
1221 if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
1222 else
1224 ITextServices_TxSendMessage( host->text_srv, EM_EXGETSEL, 0, (LPARAM)&range.chrg, &res );
1225 range.lpstrText = (char *)lparam;
1226 range.lpstrText[0] = '\0';
1227 hr = get_text_rangeA( host, &range, &res );
1229 break;
1231 case EM_GETOPTIONS:
1232 if (host->props & TXTBIT_READONLY) res |= ECO_READONLY;
1233 if (!(host->props & TXTBIT_HIDESELECTION)) res |= ECO_NOHIDESEL;
1234 if (host->props & TXTBIT_SAVESELECTION) res |= ECO_SAVESEL;
1235 if (host->props & TXTBIT_AUTOWORDSEL) res |= ECO_AUTOWORDSELECTION;
1236 if (host->props & TXTBIT_VERTICAL) res |= ECO_VERTICAL;
1237 if (host->scrollbars & ES_AUTOHSCROLL) res |= ECO_AUTOHSCROLL;
1238 if (host->scrollbars & ES_AUTOVSCROLL) res |= ECO_AUTOVSCROLL;
1239 if (host->want_return) res |= ECO_WANTRETURN;
1240 if (host->sel_bar) res |= ECO_SELECTIONBAR;
1241 break;
1243 case WM_GETTEXT:
1245 GETTEXTEX params;
1247 params.cb = wparam * (unicode ? sizeof(WCHAR) : sizeof(CHAR));
1248 params.flags = GT_USECRLF;
1249 params.codepage = unicode ? CP_UNICODE : CP_ACP;
1250 params.lpDefaultChar = NULL;
1251 params.lpUsedDefChar = NULL;
1252 hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTEX, (WPARAM)&params, lparam, &res );
1253 break;
1255 case WM_GETTEXTLENGTH:
1257 GETTEXTLENGTHEX params;
1259 params.flags = GTL_CLOSE | (host->emulate_10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS;
1260 params.codepage = unicode ? CP_UNICODE : CP_ACP;
1261 hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTLENGTHEX, (WPARAM)&params, 0, &res );
1262 break;
1264 case EM_GETTEXTRANGE:
1265 if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
1266 else hr = get_text_rangeA( host, (TEXTRANGEA *)lparam, &res );
1267 break;
1269 case WM_KEYDOWN:
1270 switch (LOWORD( wparam ))
1272 case VK_ESCAPE:
1273 if (host->dialog_mode && host->parent)
1274 PostMessageW( host->parent, WM_CLOSE, 0, 0 );
1275 break;
1276 case VK_TAB:
1277 if (host->dialog_mode && host->parent)
1278 SendMessageW( host->parent, WM_NEXTDLGCTL, GetKeyState( VK_SHIFT ) & 0x8000, 0 );
1279 break;
1280 case VK_RETURN:
1281 if (host->dialog_mode && !host->emulate_10 && handle_dialog_enter( host )) break;
1282 /* fall through */
1283 default:
1284 hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
1286 break;
1288 case WM_PAINT:
1289 case WM_PRINTCLIENT:
1291 HDC hdc;
1292 RECT rc, client, update;
1293 PAINTSTRUCT ps;
1294 HBRUSH brush = CreateSolidBrush( ITextHost_TxGetSysColor( &host->ITextHost_iface, COLOR_WINDOW ) );
1296 ITextHost_TxGetClientRect( &host->ITextHost_iface, &client );
1298 if (msg == WM_PAINT)
1300 hdc = BeginPaint( hwnd, &ps );
1301 update = ps.rcPaint;
1303 else
1305 hdc = (HDC)wparam;
1306 update = client;
1309 brush = SelectObject( hdc, brush );
1311 /* Erase area outside of the formatting rectangle */
1312 if (update.top < client.top)
1314 rc = update;
1315 rc.bottom = client.top;
1316 PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
1317 update.top = client.top;
1319 if (update.bottom > client.bottom)
1321 rc = update;
1322 rc.top = client.bottom;
1323 PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
1324 update.bottom = client.bottom;
1326 if (update.left < client.left)
1328 rc = update;
1329 rc.right = client.left;
1330 PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
1331 update.left = client.left;
1333 if (update.right > client.right)
1335 rc = update;
1336 rc.left = client.right;
1337 PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
1338 update.right = client.right;
1341 ITextServices_TxDraw( host->text_srv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, NULL, NULL,
1342 &update, NULL, 0, TXTVIEW_ACTIVE );
1343 DeleteObject( SelectObject( hdc, brush ) );
1344 if (msg == WM_PAINT) EndPaint( hwnd, &ps );
1345 return 0;
1347 case EM_REPLACESEL:
1349 int len;
1350 LONG codepage = unicode ? CP_UNICODE : CP_ACP;
1351 WCHAR *text = ME_ToUnicode( codepage, (void *)lparam, &len );
1353 hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, (LPARAM)text, &res );
1354 ME_EndToUnicode( codepage, text );
1355 res = len;
1356 break;
1358 case EM_SETBKGNDCOLOR:
1359 res = ITextHost_TxGetSysColor( &host->ITextHost_iface, COLOR_WINDOW );
1360 host->use_back_colour = !wparam;
1361 if (host->use_back_colour) host->back_colour = lparam;
1362 InvalidateRect( hwnd, NULL, TRUE );
1363 break;
1365 case WM_SETCURSOR:
1367 POINT pos;
1368 RECT rect;
1370 if (hwnd != (HWND)wparam) break;
1371 GetCursorPos( &pos );
1372 ScreenToClient( hwnd, &pos );
1373 ITextHost_TxGetClientRect( &host->ITextHost_iface, &rect );
1374 if (PtInRect( &rect, pos ))
1375 ITextServices_OnTxSetCursor( host->text_srv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL, NULL, pos.x, pos.y );
1376 else ITextHost_TxSetCursor( &host->ITextHost_iface, LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_ARROW ) ), FALSE );
1377 break;
1379 case EM_SETEVENTMASK:
1380 host->event_mask = lparam;
1381 hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
1382 break;
1384 case EM_SETOPTIONS:
1385 hr = set_options( host, wparam, lparam, &res );
1386 break;
1388 case EM_SETPASSWORDCHAR:
1389 if (wparam == host->password_char) break;
1390 host->password_char = wparam;
1391 if (wparam) host->props |= TXTBIT_USEPASSWORD;
1392 else host->props &= ~TXTBIT_USEPASSWORD;
1393 ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_USEPASSWORD, host->props & TXTBIT_USEPASSWORD );
1394 break;
1396 case EM_SETREADONLY:
1398 DWORD op = wparam ? ECOOP_OR : ECOOP_AND;
1399 DWORD mask = wparam ? ECO_READONLY : ~ECO_READONLY;
1401 SendMessageW( hwnd, EM_SETOPTIONS, op, mask );
1402 return 1;
1404 case EM_SETRECT:
1405 case EM_SETRECTNP:
1407 RECT *rc = (RECT *)lparam;
1409 if (!rc) host->use_set_rect = 0;
1410 else
1412 if (wparam >= 2) break;
1413 host->set_rect = *rc;
1414 if (host->client_edge)
1416 InflateRect( &host->set_rect, 1, 0 );
1417 host->set_rect.top -= 1;
1419 if (!wparam) IntersectRect( &host->set_rect, &host->set_rect, &host->client_rect );
1420 host->use_set_rect = 1;
1422 ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_CLIENTRECTCHANGE, 0 );
1423 break;
1425 case WM_SETTEXT:
1427 char *textA = (char *)lparam;
1428 WCHAR *text = (WCHAR *)lparam;
1429 int len;
1431 if (!unicode && textA && strncmp( textA, "{\\rtf", 5 ) && strncmp( textA, "{\\urtf", 6 ))
1432 text = ME_ToUnicode( CP_ACP, textA, &len );
1433 hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, (LPARAM)text, &res );
1434 if (text != (WCHAR *)lparam) ME_EndToUnicode( CP_ACP, text );
1435 break;
1437 case EM_SHOWSCROLLBAR:
1439 DWORD mask = 0, new;
1441 if (wparam == SB_HORZ) mask = WS_HSCROLL;
1442 else if (wparam == SB_VERT) mask = WS_VSCROLL;
1443 else if (wparam == SB_BOTH) mask = WS_HSCROLL | WS_VSCROLL;
1445 if (mask)
1447 new = lparam ? mask : 0;
1448 if ((host->scrollbars & mask) != new)
1450 host->scrollbars &= ~mask;
1451 host->scrollbars |= new;
1452 ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_SCROLLBARCHANGE, 0 );
1456 res = 0;
1457 break;
1459 case WM_WINDOWPOSCHANGED:
1461 RECT client;
1462 WINDOWPOS *winpos = (WINDOWPOS *)lparam;
1464 hr = S_FALSE; /* call defwndproc */
1465 if (winpos->flags & SWP_NOCLIENTSIZE) break;
1466 GetClientRect( hwnd, &client );
1467 if (host->use_set_rect)
1469 host->set_rect.right += client.right - host->client_rect.right;
1470 host->set_rect.bottom += client.bottom - host->client_rect.bottom;
1472 host->client_rect = client;
1473 ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_CLIENTRECTCHANGE, 0 );
1474 break;
1476 default:
1477 hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
1480 if (hr == S_FALSE)
1481 res = DefWindowProcW( hwnd, msg, wparam, lparam );
1483 TRACE( "exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n",
1484 hwnd, msg, get_msg_name(msg), wparam, lparam, unicode, res );
1486 return res;
1489 static LRESULT WINAPI RichEditWndProcW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
1491 BOOL unicode = TRUE;
1493 /* Under Win9x RichEdit20W returns ANSI strings, see the tests. */
1494 if (msg == WM_GETTEXT && (GetVersion() & 0x80000000))
1495 unicode = FALSE;
1497 return RichEditWndProc_common( hwnd, msg, wparam, lparam, unicode );
1500 static LRESULT WINAPI RichEditWndProcA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
1502 return RichEditWndProc_common( hwnd, msg, wparam, lparam, FALSE );
1505 /******************************************************************
1506 * RichEditANSIWndProc (RICHED20.10)
1508 LRESULT WINAPI RichEditANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
1510 return RichEditWndProcA( hwnd, msg, wparam, lparam );
1513 /******************************************************************
1514 * RichEdit10ANSIWndProc (RICHED20.9)
1516 LRESULT WINAPI RichEdit10ANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
1518 if (msg == WM_NCCREATE && !GetWindowLongPtrW( hwnd, 0 ))
1520 CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam;
1522 TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style );
1523 return create_windowed_editor( hwnd, pcs, TRUE );
1525 return RichEditANSIWndProc( hwnd, msg, wparam, lparam );
1528 static LRESULT WINAPI REComboWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
1530 /* FIXME: Not implemented */
1531 TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n",
1532 hwnd, msg, get_msg_name( msg ), wparam, lparam );
1533 return DefWindowProcW( hwnd, msg, wparam, lparam );
1536 static LRESULT WINAPI REListWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
1538 /* FIXME: Not implemented */
1539 TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n",
1540 hwnd, msg, get_msg_name( msg ), wparam, lparam );
1541 return DefWindowProcW( hwnd, msg, wparam, lparam );
1544 /******************************************************************
1545 * REExtendedRegisterClass (RICHED20.8)
1547 * FIXME undocumented
1548 * Need to check for errors and implement controls and callbacks
1550 LRESULT WINAPI REExtendedRegisterClass( void )
1552 WNDCLASSW wc;
1553 UINT result;
1555 FIXME( "semi stub\n" );
1556 wc.cbClsExtra = 0;
1557 wc.cbWndExtra = 4;
1558 wc.hInstance = NULL;
1559 wc.hIcon = NULL;
1560 wc.hCursor = NULL;
1561 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1562 wc.lpszMenuName = NULL;
1564 if (!listbox_registered)
1566 wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS;
1567 wc.lpfnWndProc = REListWndProc;
1568 wc.lpszClassName = L"REListBox20W";
1569 if (RegisterClassW( &wc )) listbox_registered = TRUE;
1572 if (!combobox_registered)
1574 wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
1575 wc.lpfnWndProc = REComboWndProc;
1576 wc.lpszClassName = L"REComboBox20W";
1577 if (RegisterClassW( &wc )) combobox_registered = TRUE;
1580 result = 0;
1581 if (listbox_registered) result += 1;
1582 if (combobox_registered) result += 2;
1584 return result;
1587 static BOOL register_classes( HINSTANCE instance )
1589 WNDCLASSW wcW;
1590 WNDCLASSA wcA;
1592 wcW.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
1593 wcW.lpfnWndProc = RichEditWndProcW;
1594 wcW.cbClsExtra = 0;
1595 wcW.cbWndExtra = sizeof(struct host *);
1596 wcW.hInstance = NULL; /* hInstance would register DLL-local class */
1597 wcW.hIcon = NULL;
1598 wcW.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM );
1599 wcW.hbrBackground = GetStockObject( NULL_BRUSH );
1600 wcW.lpszMenuName = NULL;
1602 if (!(GetVersion() & 0x80000000))
1604 wcW.lpszClassName = RICHEDIT_CLASS20W;
1605 if (!RegisterClassW( &wcW )) return FALSE;
1606 wcW.lpszClassName = MSFTEDIT_CLASS;
1607 if (!RegisterClassW( &wcW )) return FALSE;
1609 else
1611 /* WNDCLASSA/W have the same layout */
1612 wcW.lpszClassName = (LPCWSTR)"RichEdit20W";
1613 if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE;
1614 wcW.lpszClassName = (LPCWSTR)"RichEdit50W";
1615 if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE;
1618 wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
1619 wcA.lpfnWndProc = RichEditWndProcA;
1620 wcA.cbClsExtra = 0;
1621 wcA.cbWndExtra = sizeof(struct host *);
1622 wcA.hInstance = NULL; /* hInstance would register DLL-local class */
1623 wcA.hIcon = NULL;
1624 wcA.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM );
1625 wcA.hbrBackground = GetStockObject(NULL_BRUSH);
1626 wcA.lpszMenuName = NULL;
1627 wcA.lpszClassName = RICHEDIT_CLASS20A;
1628 if (!RegisterClassA( &wcA )) return FALSE;
1629 wcA.lpszClassName = "RichEdit50A";
1630 if (!RegisterClassA( &wcA )) return FALSE;
1632 return TRUE;
1635 BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
1637 switch (reason)
1639 case DLL_PROCESS_ATTACH:
1640 dll_instance = instance;
1641 DisableThreadLibraryCalls( instance );
1642 if (!register_classes( instance )) return FALSE;
1643 LookupInit();
1644 break;
1646 case DLL_PROCESS_DETACH:
1647 if (reserved) break;
1648 UnregisterClassW( RICHEDIT_CLASS20W, 0 );
1649 UnregisterClassW( MSFTEDIT_CLASS, 0 );
1650 UnregisterClassA( RICHEDIT_CLASS20A, 0 );
1651 UnregisterClassA( "RichEdit50A", 0 );
1652 if (listbox_registered) UnregisterClassW( L"REListBox20W", 0 );
1653 if (combobox_registered) UnregisterClassW( L"REComboBox20W", 0 );
1654 LookupCleanup();
1655 release_typelib();
1656 break;
1658 return TRUE;