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
28 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(richedit
);
36 ITextHost2 ITextHost_iface
;
38 ITextServices
*text_srv
;
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 unsigned int defer_release
: 1;
49 DWORD props
, scrollbars
, event_mask
;
50 RECT client_rect
, set_rect
;
53 unsigned int notify_level
;
56 static const ITextHost2Vtbl textHostVtbl
;
58 static BOOL listbox_registered
;
59 static BOOL combobox_registered
;
61 static void host_init_props( struct host
*host
)
65 style
= GetWindowLongW( host
->window
, GWL_STYLE
);
67 /* text services assumes the scrollbars are originally not shown, so hide them.
68 However with ES_DISABLENOSCROLL it'll immediately show them, so don't bother */
69 if (!(style
& ES_DISABLENOSCROLL
)) ShowScrollBar( host
->window
, SB_BOTH
, FALSE
);
71 host
->scrollbars
= style
& (WS_VSCROLL
| WS_HSCROLL
| ES_AUTOVSCROLL
|
72 ES_AUTOHSCROLL
| ES_DISABLENOSCROLL
);
73 if (style
& WS_VSCROLL
) host
->scrollbars
|= ES_AUTOVSCROLL
;
74 if ((style
& WS_HSCROLL
) && !host
->emulate_10
) host
->scrollbars
|= ES_AUTOHSCROLL
;
76 host
->props
= TXTBIT_RICHTEXT
| TXTBIT_ALLOWBEEP
;
77 if (style
& ES_MULTILINE
) host
->props
|= TXTBIT_MULTILINE
;
78 if (style
& ES_READONLY
) host
->props
|= TXTBIT_READONLY
;
79 if (style
& ES_PASSWORD
) host
->props
|= TXTBIT_USEPASSWORD
;
80 if (!(style
& ES_NOHIDESEL
)) host
->props
|= TXTBIT_HIDESELECTION
;
81 if (style
& ES_SAVESEL
) host
->props
|= TXTBIT_SAVESELECTION
;
82 if (style
& ES_VERTICAL
) host
->props
|= TXTBIT_VERTICAL
;
83 if (style
& ES_NOOLEDRAGDROP
) host
->props
|= TXTBIT_DISABLEDRAG
;
85 if (!(host
->scrollbars
& ES_AUTOHSCROLL
)) host
->props
|= TXTBIT_WORDWRAP
;
87 host
->sel_bar
= !!(style
& ES_SELECTIONBAR
);
88 host
->want_return
= !!(style
& ES_WANTRETURN
);
90 style
= GetWindowLongW( host
->window
, GWL_EXSTYLE
);
91 host
->client_edge
= !!(style
& WS_EX_CLIENTEDGE
);
94 struct host
*host_create( HWND hwnd
, CREATESTRUCTW
*cs
, BOOL emulate_10
)
96 struct host
*texthost
;
98 texthost
= heap_alloc(sizeof(*texthost
));
99 if (!texthost
) return NULL
;
101 texthost
->ITextHost_iface
.lpVtbl
= &textHostVtbl
;
103 texthost
->text_srv
= NULL
;
104 texthost
->window
= hwnd
;
105 texthost
->parent
= cs
->hwndParent
;
106 texthost
->emulate_10
= emulate_10
;
107 texthost
->dialog_mode
= 0;
108 memset( &texthost
->para_fmt
, 0, sizeof(texthost
->para_fmt
) );
109 texthost
->para_fmt
.cbSize
= sizeof(texthost
->para_fmt
);
110 texthost
->para_fmt
.dwMask
= PFM_ALIGNMENT
;
111 texthost
->para_fmt
.wAlignment
= PFA_LEFT
;
112 if (cs
->style
& ES_RIGHT
)
113 texthost
->para_fmt
.wAlignment
= PFA_RIGHT
;
114 if (cs
->style
& ES_CENTER
)
115 texthost
->para_fmt
.wAlignment
= PFA_CENTER
;
116 host_init_props( texthost
);
117 texthost
->event_mask
= 0;
118 texthost
->use_set_rect
= 0;
119 SetRectEmpty( &texthost
->set_rect
);
120 GetClientRect( hwnd
, &texthost
->client_rect
);
121 texthost
->use_back_colour
= 0;
122 texthost
->password_char
= (texthost
->props
& TXTBIT_USEPASSWORD
) ? '*' : 0;
123 texthost
->defer_release
= 0;
124 texthost
->notify_level
= 0;
129 static inline struct host
*impl_from_ITextHost( ITextHost2
*iface
)
131 return CONTAINING_RECORD( iface
, struct host
, ITextHost_iface
);
134 static HRESULT WINAPI
ITextHostImpl_QueryInterface( ITextHost2
*iface
, REFIID iid
, void **obj
)
136 struct host
*host
= impl_from_ITextHost( iface
);
138 if (IsEqualIID( iid
, &IID_IUnknown
) || IsEqualIID( iid
, &IID_ITextHost
) || IsEqualIID( iid
, &IID_ITextHost2
))
140 *obj
= &host
->ITextHost_iface
;
141 ITextHost_AddRef( (ITextHost
*)*obj
);
145 FIXME( "Unknown interface: %s\n", debugstr_guid( iid
) );
146 return E_NOINTERFACE
;
149 static ULONG WINAPI
ITextHostImpl_AddRef( ITextHost2
*iface
)
151 struct host
*host
= impl_from_ITextHost( iface
);
152 ULONG ref
= InterlockedIncrement( &host
->ref
);
156 static ULONG WINAPI
ITextHostImpl_Release( ITextHost2
*iface
)
158 struct host
*host
= impl_from_ITextHost( iface
);
159 ULONG ref
= InterlockedDecrement( &host
->ref
);
163 SetWindowLongPtrW( host
->window
, 0, 0 );
164 ITextServices_Release( host
->text_srv
);
170 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC
,4)
171 DECLSPEC_HIDDEN HDC __thiscall
ITextHostImpl_TxGetDC( ITextHost2
*iface
)
173 struct host
*host
= impl_from_ITextHost( iface
);
174 return GetDC( host
->window
);
177 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC
,8)
178 DECLSPEC_HIDDEN INT __thiscall
ITextHostImpl_TxReleaseDC( ITextHost2
*iface
, HDC hdc
)
180 struct host
*host
= impl_from_ITextHost( iface
);
181 return ReleaseDC( host
->window
, hdc
);
184 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar
,12)
185 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxShowScrollBar( ITextHost2
*iface
, INT bar
, BOOL show
)
187 struct host
*host
= impl_from_ITextHost( iface
);
188 return ShowScrollBar( host
->window
, bar
, show
);
191 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar
,12)
192 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxEnableScrollBar( ITextHost2
*iface
, INT bar
, INT arrows
)
194 struct host
*host
= impl_from_ITextHost( iface
);
195 return EnableScrollBar( host
->window
, bar
, arrows
);
198 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange
,20)
199 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxSetScrollRange( ITextHost2
*iface
, INT bar
, LONG min_pos
, INT max_pos
, BOOL redraw
)
201 struct host
*host
= impl_from_ITextHost( iface
);
202 SCROLLINFO info
= { .cbSize
= sizeof(info
), .fMask
= SIF_PAGE
| SIF_RANGE
};
204 if (bar
!= SB_HORZ
&& bar
!= SB_VERT
)
206 FIXME( "Unexpected bar %d\n", bar
);
210 if (host
->scrollbars
& ES_DISABLENOSCROLL
) info
.fMask
|= SIF_DISABLENOSCROLL
;
212 if (host
->text_srv
) /* This can be called during text services creation */
214 if (bar
== SB_HORZ
) ITextServices_TxGetHScroll( host
->text_srv
, NULL
, NULL
, NULL
, (LONG
*)&info
.nPage
, NULL
);
215 else ITextServices_TxGetVScroll( host
->text_srv
, NULL
, NULL
, NULL
, (LONG
*)&info
.nPage
, NULL
);
220 return SetScrollInfo( host
->window
, bar
, &info
, redraw
);
223 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos
,16)
224 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxSetScrollPos( ITextHost2
*iface
, INT bar
, INT pos
, BOOL redraw
)
226 struct host
*host
= impl_from_ITextHost( iface
);
227 DWORD style
= GetWindowLongW( host
->window
, GWL_STYLE
);
228 DWORD mask
= (bar
== SB_HORZ
) ? WS_HSCROLL
: WS_VSCROLL
;
229 BOOL show
= TRUE
, shown
= style
& mask
;
231 if (bar
!= SB_HORZ
&& bar
!= SB_VERT
)
233 FIXME( "Unexpected bar %d\n", bar
);
237 /* If the application has adjusted the scrollbar's visibility it is reset */
238 if (!(host
->scrollbars
& ES_DISABLENOSCROLL
))
240 if (bar
== SB_HORZ
) ITextServices_TxGetHScroll( host
->text_srv
, NULL
, NULL
, NULL
, NULL
, &show
);
241 else ITextServices_TxGetVScroll( host
->text_srv
, NULL
, NULL
, NULL
, NULL
, &show
);
244 if (!show
^ !shown
) ShowScrollBar( host
->window
, bar
, show
);
245 return SetScrollPos( host
->window
, bar
, pos
, redraw
) != 0;
248 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect
,12)
249 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxInvalidateRect( ITextHost2
*iface
, const RECT
*rect
, BOOL mode
)
251 struct host
*host
= impl_from_ITextHost( iface
);
252 InvalidateRect( host
->window
, rect
, mode
);
255 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange
,8)
256 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxViewChange( ITextHost2
*iface
, BOOL update
)
258 struct host
*host
= impl_from_ITextHost( iface
);
259 if (update
) UpdateWindow( host
->window
);
262 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret
,16)
263 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxCreateCaret( ITextHost2
*iface
, HBITMAP bitmap
, INT width
, INT height
)
265 struct host
*host
= impl_from_ITextHost( iface
);
266 return CreateCaret( host
->window
, bitmap
, width
, height
);
269 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret
,8)
270 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxShowCaret( ITextHost2
*iface
, BOOL show
)
272 struct host
*host
= impl_from_ITextHost( iface
);
273 if (show
) return ShowCaret( host
->window
);
274 else return HideCaret( host
->window
);
277 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos
,12)
278 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxSetCaretPos( ITextHost2
*iface
, INT x
, INT y
)
280 return SetCaretPos(x
, y
);
283 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer
,12)
284 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxSetTimer( ITextHost2
*iface
, UINT id
, UINT timeout
)
286 struct host
*host
= impl_from_ITextHost( iface
);
287 return SetTimer( host
->window
, id
, timeout
, NULL
) != 0;
290 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer
,8)
291 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxKillTimer( ITextHost2
*iface
, UINT id
)
293 struct host
*host
= impl_from_ITextHost( iface
);
294 KillTimer( host
->window
, id
);
297 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx
,32)
298 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxScrollWindowEx( ITextHost2
*iface
, INT dx
, INT dy
, const RECT
*scroll
,
299 const RECT
*clip
, HRGN update_rgn
, RECT
*update_rect
,
302 struct host
*host
= impl_from_ITextHost( iface
);
303 ScrollWindowEx( host
->window
, dx
, dy
, scroll
, clip
, update_rgn
, update_rect
, flags
);
306 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture
,8)
307 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxSetCapture( ITextHost2
*iface
, BOOL capture
)
309 struct host
*host
= impl_from_ITextHost( iface
);
310 if (capture
) SetCapture( host
->window
);
311 else ReleaseCapture();
314 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus
,4)
315 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxSetFocus( ITextHost2
*iface
)
317 struct host
*host
= impl_from_ITextHost( iface
);
318 SetFocus( host
->window
);
321 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor
,12)
322 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxSetCursor( ITextHost2
*iface
, HCURSOR cursor
, BOOL text
)
327 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient
,8)
328 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxScreenToClient( ITextHost2
*iface
, POINT
*pt
)
330 struct host
*host
= impl_from_ITextHost( iface
);
331 return ScreenToClient( host
->window
, pt
);
334 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen
,8)
335 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxClientToScreen( ITextHost2
*iface
, POINT
*pt
)
337 struct host
*host
= impl_from_ITextHost( iface
);
338 return ClientToScreen( host
->window
, pt
);
341 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate
,8)
342 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxActivate( ITextHost2
*iface
, LONG
*old_state
)
344 struct host
*host
= impl_from_ITextHost( iface
);
345 *old_state
= HandleToLong( SetActiveWindow( host
->window
) );
346 return *old_state
? S_OK
: E_FAIL
;
349 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate
,8)
350 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxDeactivate( ITextHost2
*iface
, LONG new_state
)
352 HWND ret
= SetActiveWindow( LongToHandle( new_state
) );
353 return ret
? S_OK
: E_FAIL
;
356 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect
,8)
357 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetClientRect( ITextHost2
*iface
, RECT
*rect
)
359 struct host
*host
= impl_from_ITextHost( iface
);
361 if (!host
->use_set_rect
)
363 *rect
= host
->client_rect
;
364 if (host
->client_edge
) rect
->top
+= 1;
365 InflateRect( rect
, -1, 0 );
367 else *rect
= host
->set_rect
;
372 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset
,8)
373 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetViewInset( ITextHost2
*iface
, RECT
*rect
)
375 SetRectEmpty( rect
);
379 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat
,8)
380 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetCharFormat( ITextHost2
*iface
, const CHARFORMATW
**ppCF
)
385 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat
,8)
386 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetParaFormat( ITextHost2
*iface
, const PARAFORMAT
**fmt
)
388 struct host
*host
= impl_from_ITextHost( iface
);
389 *fmt
= (const PARAFORMAT
*)&host
->para_fmt
;
393 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor
,8)
394 DECLSPEC_HIDDEN COLORREF __thiscall
ITextHostImpl_TxGetSysColor( ITextHost2
*iface
, int index
)
396 struct host
*host
= impl_from_ITextHost( iface
);
398 if (index
== COLOR_WINDOW
&& host
->use_back_colour
) return host
->back_colour
;
399 return GetSysColor( index
);
402 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle
,8)
403 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetBackStyle( ITextHost2
*iface
, TXTBACKSTYLE
*style
)
405 *style
= TXTBACK_OPAQUE
;
409 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength
,8)
410 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetMaxLength( ITextHost2
*iface
, DWORD
*length
)
416 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars
,8)
417 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetScrollBars( ITextHost2
*iface
, DWORD
*scrollbars
)
419 struct host
*host
= impl_from_ITextHost( iface
);
421 *scrollbars
= host
->scrollbars
;
425 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar
,8)
426 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetPasswordChar( ITextHost2
*iface
, WCHAR
*c
)
428 struct host
*host
= impl_from_ITextHost( iface
);
430 *c
= host
->password_char
;
431 return *c
? S_OK
: S_FALSE
;
434 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos
,8)
435 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetAcceleratorPos( ITextHost2
*iface
, LONG
*pos
)
441 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent
,8)
442 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetExtent( ITextHost2
*iface
, SIZEL
*extent
)
447 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange
,8)
448 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_OnTxCharFormatChange( ITextHost2
*iface
, const CHARFORMATW
*pcf
)
453 DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange
,8)
454 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_OnTxParaFormatChange( ITextHost2
*iface
, const PARAFORMAT
*ppf
)
459 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits
,12)
460 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetPropertyBits( ITextHost2
*iface
, DWORD mask
, DWORD
*bits
)
462 struct host
*host
= impl_from_ITextHost( iface
);
464 *bits
= host
->props
& mask
;
468 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify
,12)
469 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxNotify( ITextHost2
*iface
, DWORD iNotify
, void *pv
)
471 struct host
*host
= impl_from_ITextHost( iface
);
474 if (!host
->parent
) return S_OK
;
476 id
= GetWindowLongW( host
->window
, GWLP_ID
);
484 case EN_REQUESTRESIZE
:
485 case EN_SAVECLIPBOARD
:
489 /* FIXME: Verify this assumption that pv starts with NMHDR. */
494 info
->hwndFrom
= host
->window
;
496 info
->code
= iNotify
;
497 SendMessageW( host
->parent
, WM_NOTIFY
, id
, (LPARAM
)info
);
502 /* Only sent when the window is visible. */
503 if (!IsWindowVisible( host
->window
))
513 SendMessageW( host
->parent
, WM_COMMAND
, MAKEWPARAM( id
, iNotify
), (LPARAM
)host
->window
);
517 FIXME("EN_MSGFILTER is documented as not being sent to TxNotify\n");
525 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext
,4)
526 DECLSPEC_HIDDEN HIMC __thiscall
ITextHostImpl_TxImmGetContext( ITextHost2
*iface
)
528 struct host
*host
= impl_from_ITextHost( iface
);
529 return ImmGetContext( host
->window
);
532 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext
,8)
533 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxImmReleaseContext( ITextHost2
*iface
, HIMC context
)
535 struct host
*host
= impl_from_ITextHost( iface
);
536 ImmReleaseContext( host
->window
, context
);
539 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth
,8)
540 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetSelectionBarWidth( ITextHost2
*iface
, LONG
*width
)
542 struct host
*host
= impl_from_ITextHost( iface
);
544 *width
= host
->sel_bar
? 225 : 0; /* in HIMETRIC */
548 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxIsDoubleClickPending
,4)
549 DECLSPEC_HIDDEN BOOL __thiscall
ITextHostImpl_TxIsDoubleClickPending( ITextHost2
*iface
)
554 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetWindow
,8)
555 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetWindow( ITextHost2
*iface
, HWND
*hwnd
)
557 struct host
*host
= impl_from_ITextHost( iface
);
558 *hwnd
= host
->window
;
562 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetForegroundWindow
,4)
563 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxSetForegroundWindow( ITextHost2
*iface
)
568 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPalette
,4)
569 DECLSPEC_HIDDEN HPALETTE __thiscall
ITextHostImpl_TxGetPalette( ITextHost2
*iface
)
574 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetEastAsianFlags
,8)
575 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetEastAsianFlags( ITextHost2
*iface
, LONG
*flags
)
580 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor2
,12)
581 DECLSPEC_HIDDEN HCURSOR __thiscall
ITextHostImpl_TxSetCursor2( ITextHost2
*iface
, HCURSOR cursor
, BOOL text
)
586 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxFreeTextServicesNotification
,4)
587 DECLSPEC_HIDDEN
void __thiscall
ITextHostImpl_TxFreeTextServicesNotification( ITextHost2
*iface
)
592 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetEditStyle
,12)
593 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetEditStyle( ITextHost2
*iface
, DWORD item
, DWORD
*data
)
598 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetWindowStyles
,12)
599 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetWindowStyles( ITextHost2
*iface
, DWORD
*style
, DWORD
*ex_style
)
604 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowDropCaret
,16)
605 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxShowDropCaret( ITextHost2
*iface
, BOOL show
, HDC hdc
, const RECT
*rect
)
610 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDestroyCaret
,4)
611 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxDestroyCaret( ITextHost2
*iface
)
616 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetHorzExtent
,8)
617 DECLSPEC_HIDDEN HRESULT __thiscall
ITextHostImpl_TxGetHorzExtent( ITextHost2
*iface
, LONG
*horz_extent
)
623 #ifdef __ASM_USE_THISCALL_WRAPPER
625 #define STDCALL(func) (void *) __stdcall_ ## func
627 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
628 __declspec(naked) HRESULT __stdcall_##func(void) \
633 __asm mov eax, [ecx] \
634 __asm jmp dword ptr [eax + 4*num] \
637 #define DEFINE_STDCALL_WRAPPER(num,func,args) \
638 extern HRESULT __stdcall_ ## func(void); \
639 __ASM_GLOBAL_FUNC(__stdcall_ ## func, \
643 "movl (%ecx), %eax\n\t" \
644 "jmp *(4*(" #num "))(%eax)" )
645 #endif /* _MSC_VER */
647 DEFINE_STDCALL_WRAPPER(3,ITextHostImpl_TxGetDC
,4)
648 DEFINE_STDCALL_WRAPPER(4,ITextHostImpl_TxReleaseDC
,8)
649 DEFINE_STDCALL_WRAPPER(5,ITextHostImpl_TxShowScrollBar
,12)
650 DEFINE_STDCALL_WRAPPER(6,ITextHostImpl_TxEnableScrollBar
,12)
651 DEFINE_STDCALL_WRAPPER(7,ITextHostImpl_TxSetScrollRange
,20)
652 DEFINE_STDCALL_WRAPPER(8,ITextHostImpl_TxSetScrollPos
,16)
653 DEFINE_STDCALL_WRAPPER(9,ITextHostImpl_TxInvalidateRect
,12)
654 DEFINE_STDCALL_WRAPPER(10,ITextHostImpl_TxViewChange
,8)
655 DEFINE_STDCALL_WRAPPER(11,ITextHostImpl_TxCreateCaret
,16)
656 DEFINE_STDCALL_WRAPPER(12,ITextHostImpl_TxShowCaret
,8)
657 DEFINE_STDCALL_WRAPPER(13,ITextHostImpl_TxSetCaretPos
,12)
658 DEFINE_STDCALL_WRAPPER(14,ITextHostImpl_TxSetTimer
,12)
659 DEFINE_STDCALL_WRAPPER(15,ITextHostImpl_TxKillTimer
,8)
660 DEFINE_STDCALL_WRAPPER(16,ITextHostImpl_TxScrollWindowEx
,32)
661 DEFINE_STDCALL_WRAPPER(17,ITextHostImpl_TxSetCapture
,8)
662 DEFINE_STDCALL_WRAPPER(18,ITextHostImpl_TxSetFocus
,4)
663 DEFINE_STDCALL_WRAPPER(19,ITextHostImpl_TxSetCursor
,12)
664 DEFINE_STDCALL_WRAPPER(20,ITextHostImpl_TxScreenToClient
,8)
665 DEFINE_STDCALL_WRAPPER(21,ITextHostImpl_TxClientToScreen
,8)
666 DEFINE_STDCALL_WRAPPER(22,ITextHostImpl_TxActivate
,8)
667 DEFINE_STDCALL_WRAPPER(23,ITextHostImpl_TxDeactivate
,8)
668 DEFINE_STDCALL_WRAPPER(24,ITextHostImpl_TxGetClientRect
,8)
669 DEFINE_STDCALL_WRAPPER(25,ITextHostImpl_TxGetViewInset
,8)
670 DEFINE_STDCALL_WRAPPER(26,ITextHostImpl_TxGetCharFormat
,8)
671 DEFINE_STDCALL_WRAPPER(27,ITextHostImpl_TxGetParaFormat
,8)
672 DEFINE_STDCALL_WRAPPER(28,ITextHostImpl_TxGetSysColor
,8)
673 DEFINE_STDCALL_WRAPPER(29,ITextHostImpl_TxGetBackStyle
,8)
674 DEFINE_STDCALL_WRAPPER(30,ITextHostImpl_TxGetMaxLength
,8)
675 DEFINE_STDCALL_WRAPPER(31,ITextHostImpl_TxGetScrollBars
,8)
676 DEFINE_STDCALL_WRAPPER(32,ITextHostImpl_TxGetPasswordChar
,8)
677 DEFINE_STDCALL_WRAPPER(33,ITextHostImpl_TxGetAcceleratorPos
,8)
678 DEFINE_STDCALL_WRAPPER(34,ITextHostImpl_TxGetExtent
,8)
679 DEFINE_STDCALL_WRAPPER(35,ITextHostImpl_OnTxCharFormatChange
,8)
680 DEFINE_STDCALL_WRAPPER(36,ITextHostImpl_OnTxParaFormatChange
,8)
681 DEFINE_STDCALL_WRAPPER(37,ITextHostImpl_TxGetPropertyBits
,12)
682 DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify
,12)
683 DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext
,4)
684 DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext
,8)
685 DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth
,8)
687 DEFINE_STDCALL_WRAPPER(42,ITextHostImpl_TxIsDoubleClickPending
,4)
688 DEFINE_STDCALL_WRAPPER(43,ITextHostImpl_TxGetWindow
,8)
689 DEFINE_STDCALL_WRAPPER(44,ITextHostImpl_TxSetForegroundWindow
,4)
690 DEFINE_STDCALL_WRAPPER(45,ITextHostImpl_TxGetPalette
,4)
691 DEFINE_STDCALL_WRAPPER(46,ITextHostImpl_TxGetEastAsianFlags
,8)
692 DEFINE_STDCALL_WRAPPER(47,ITextHostImpl_TxSetCursor2
,12)
693 DEFINE_STDCALL_WRAPPER(48,ITextHostImpl_TxFreeTextServicesNotification
,4)
694 DEFINE_STDCALL_WRAPPER(49,ITextHostImpl_TxGetEditStyle
,12)
695 DEFINE_STDCALL_WRAPPER(50,ITextHostImpl_TxGetWindowStyles
,12)
696 DEFINE_STDCALL_WRAPPER(51,ITextHostImpl_TxShowDropCaret
,16)
697 DEFINE_STDCALL_WRAPPER(52,ITextHostImpl_TxDestroyCaret
,4)
698 DEFINE_STDCALL_WRAPPER(53,ITextHostImpl_TxGetHorzExtent
,8)
700 const ITextHost2Vtbl text_host2_stdcall_vtbl
=
705 STDCALL(ITextHostImpl_TxGetDC
),
706 STDCALL(ITextHostImpl_TxReleaseDC
),
707 STDCALL(ITextHostImpl_TxShowScrollBar
),
708 STDCALL(ITextHostImpl_TxEnableScrollBar
),
709 STDCALL(ITextHostImpl_TxSetScrollRange
),
710 STDCALL(ITextHostImpl_TxSetScrollPos
),
711 STDCALL(ITextHostImpl_TxInvalidateRect
),
712 STDCALL(ITextHostImpl_TxViewChange
),
713 STDCALL(ITextHostImpl_TxCreateCaret
),
714 STDCALL(ITextHostImpl_TxShowCaret
),
715 STDCALL(ITextHostImpl_TxSetCaretPos
),
716 STDCALL(ITextHostImpl_TxSetTimer
),
717 STDCALL(ITextHostImpl_TxKillTimer
),
718 STDCALL(ITextHostImpl_TxScrollWindowEx
),
719 STDCALL(ITextHostImpl_TxSetCapture
),
720 STDCALL(ITextHostImpl_TxSetFocus
),
721 STDCALL(ITextHostImpl_TxSetCursor
),
722 STDCALL(ITextHostImpl_TxScreenToClient
),
723 STDCALL(ITextHostImpl_TxClientToScreen
),
724 STDCALL(ITextHostImpl_TxActivate
),
725 STDCALL(ITextHostImpl_TxDeactivate
),
726 STDCALL(ITextHostImpl_TxGetClientRect
),
727 STDCALL(ITextHostImpl_TxGetViewInset
),
728 STDCALL(ITextHostImpl_TxGetCharFormat
),
729 STDCALL(ITextHostImpl_TxGetParaFormat
),
730 STDCALL(ITextHostImpl_TxGetSysColor
),
731 STDCALL(ITextHostImpl_TxGetBackStyle
),
732 STDCALL(ITextHostImpl_TxGetMaxLength
),
733 STDCALL(ITextHostImpl_TxGetScrollBars
),
734 STDCALL(ITextHostImpl_TxGetPasswordChar
),
735 STDCALL(ITextHostImpl_TxGetAcceleratorPos
),
736 STDCALL(ITextHostImpl_TxGetExtent
),
737 STDCALL(ITextHostImpl_OnTxCharFormatChange
),
738 STDCALL(ITextHostImpl_OnTxParaFormatChange
),
739 STDCALL(ITextHostImpl_TxGetPropertyBits
),
740 STDCALL(ITextHostImpl_TxNotify
),
741 STDCALL(ITextHostImpl_TxImmGetContext
),
742 STDCALL(ITextHostImpl_TxImmReleaseContext
),
743 STDCALL(ITextHostImpl_TxGetSelectionBarWidth
),
745 STDCALL(ITextHostImpl_TxIsDoubleClickPending
),
746 STDCALL(ITextHostImpl_TxGetWindow
),
747 STDCALL(ITextHostImpl_TxSetForegroundWindow
),
748 STDCALL(ITextHostImpl_TxGetPalette
),
749 STDCALL(ITextHostImpl_TxGetEastAsianFlags
),
750 STDCALL(ITextHostImpl_TxSetCursor2
),
751 STDCALL(ITextHostImpl_TxFreeTextServicesNotification
),
752 STDCALL(ITextHostImpl_TxGetEditStyle
),
753 STDCALL(ITextHostImpl_TxGetWindowStyles
),
754 STDCALL(ITextHostImpl_TxShowDropCaret
),
755 STDCALL(ITextHostImpl_TxDestroyCaret
),
756 STDCALL(ITextHostImpl_TxGetHorzExtent
)
759 #endif /* __ASM_USE_THISCALL_WRAPPER */
761 static const ITextHost2Vtbl textHostVtbl
=
763 ITextHostImpl_QueryInterface
,
764 ITextHostImpl_AddRef
,
765 ITextHostImpl_Release
,
766 THISCALL(ITextHostImpl_TxGetDC
),
767 THISCALL(ITextHostImpl_TxReleaseDC
),
768 THISCALL(ITextHostImpl_TxShowScrollBar
),
769 THISCALL(ITextHostImpl_TxEnableScrollBar
),
770 THISCALL(ITextHostImpl_TxSetScrollRange
),
771 THISCALL(ITextHostImpl_TxSetScrollPos
),
772 THISCALL(ITextHostImpl_TxInvalidateRect
),
773 THISCALL(ITextHostImpl_TxViewChange
),
774 THISCALL(ITextHostImpl_TxCreateCaret
),
775 THISCALL(ITextHostImpl_TxShowCaret
),
776 THISCALL(ITextHostImpl_TxSetCaretPos
),
777 THISCALL(ITextHostImpl_TxSetTimer
),
778 THISCALL(ITextHostImpl_TxKillTimer
),
779 THISCALL(ITextHostImpl_TxScrollWindowEx
),
780 THISCALL(ITextHostImpl_TxSetCapture
),
781 THISCALL(ITextHostImpl_TxSetFocus
),
782 THISCALL(ITextHostImpl_TxSetCursor
),
783 THISCALL(ITextHostImpl_TxScreenToClient
),
784 THISCALL(ITextHostImpl_TxClientToScreen
),
785 THISCALL(ITextHostImpl_TxActivate
),
786 THISCALL(ITextHostImpl_TxDeactivate
),
787 THISCALL(ITextHostImpl_TxGetClientRect
),
788 THISCALL(ITextHostImpl_TxGetViewInset
),
789 THISCALL(ITextHostImpl_TxGetCharFormat
),
790 THISCALL(ITextHostImpl_TxGetParaFormat
),
791 THISCALL(ITextHostImpl_TxGetSysColor
),
792 THISCALL(ITextHostImpl_TxGetBackStyle
),
793 THISCALL(ITextHostImpl_TxGetMaxLength
),
794 THISCALL(ITextHostImpl_TxGetScrollBars
),
795 THISCALL(ITextHostImpl_TxGetPasswordChar
),
796 THISCALL(ITextHostImpl_TxGetAcceleratorPos
),
797 THISCALL(ITextHostImpl_TxGetExtent
),
798 THISCALL(ITextHostImpl_OnTxCharFormatChange
),
799 THISCALL(ITextHostImpl_OnTxParaFormatChange
),
800 THISCALL(ITextHostImpl_TxGetPropertyBits
),
801 THISCALL(ITextHostImpl_TxNotify
),
802 THISCALL(ITextHostImpl_TxImmGetContext
),
803 THISCALL(ITextHostImpl_TxImmReleaseContext
),
804 THISCALL(ITextHostImpl_TxGetSelectionBarWidth
),
806 THISCALL(ITextHostImpl_TxIsDoubleClickPending
),
807 THISCALL(ITextHostImpl_TxGetWindow
),
808 THISCALL(ITextHostImpl_TxSetForegroundWindow
),
809 THISCALL(ITextHostImpl_TxGetPalette
),
810 THISCALL(ITextHostImpl_TxGetEastAsianFlags
),
811 THISCALL(ITextHostImpl_TxSetCursor2
),
812 THISCALL(ITextHostImpl_TxFreeTextServicesNotification
),
813 THISCALL(ITextHostImpl_TxGetEditStyle
),
814 THISCALL(ITextHostImpl_TxGetWindowStyles
),
815 THISCALL(ITextHostImpl_TxShowDropCaret
),
816 THISCALL(ITextHostImpl_TxDestroyCaret
),
817 THISCALL(ITextHostImpl_TxGetHorzExtent
)
820 static const char * const edit_messages
[] =
822 "EM_GETSEL", "EM_SETSEL", "EM_GETRECT", "EM_SETRECT",
823 "EM_SETRECTNP", "EM_SCROLL", "EM_LINESCROLL", "EM_SCROLLCARET",
824 "EM_GETMODIFY", "EM_SETMODIFY", "EM_GETLINECOUNT", "EM_LINEINDEX",
825 "EM_SETHANDLE", "EM_GETHANDLE", "EM_GETTHUMB", "EM_UNKNOWN_BF",
826 "EM_UNKNOWN_C0", "EM_LINELENGTH", "EM_REPLACESEL", "EM_UNKNOWN_C3",
827 "EM_GETLINE", "EM_LIMITTEXT", "EM_CANUNDO", "EM_UNDO",
828 "EM_FMTLINES", "EM_LINEFROMCHAR", "EM_UNKNOWN_CA", "EM_SETTABSTOPS",
829 "EM_SETPASSWORDCHAR", "EM_EMPTYUNDOBUFFER", "EM_GETFIRSTVISIBLELINE", "EM_SETREADONLY",
830 "EM_SETWORDBREAKPROC", "EM_GETWORDBREAKPROC", "EM_GETPASSWORDCHAR", "EM_SETMARGINS",
831 "EM_GETMARGINS", "EM_GETLIMITTEXT", "EM_POSFROMCHAR", "EM_CHARFROMPOS",
832 "EM_SETIMESTATUS", "EM_GETIMESTATUS"
835 static const char * const richedit_messages
[] =
837 "EM_CANPASTE", "EM_DISPLAYBAND", "EM_EXGETSEL", "EM_EXLIMITTEXT",
838 "EM_EXLINEFROMCHAR", "EM_EXSETSEL", "EM_FINDTEXT", "EM_FORMATRANGE",
839 "EM_GETCHARFORMAT", "EM_GETEVENTMASK", "EM_GETOLEINTERFACE", "EM_GETPARAFORMAT",
840 "EM_GETSELTEXT", "EM_HIDESELECTION", "EM_PASTESPECIAL", "EM_REQUESTRESIZE",
841 "EM_SELECTIONTYPE", "EM_SETBKGNDCOLOR", "EM_SETCHARFORMAT", "EM_SETEVENTMASK",
842 "EM_SETOLECALLBACK", "EM_SETPARAFORMAT", "EM_SETTARGETDEVICE", "EM_STREAMIN",
843 "EM_STREAMOUT", "EM_GETTEXTRANGE", "EM_FINDWORDBREAK", "EM_SETOPTIONS",
844 "EM_GETOPTIONS", "EM_FINDTEXTEX", "EM_GETWORDBREAKPROCEX", "EM_SETWORDBREAKPROCEX",
845 "EM_SETUNDOLIMIT", "EM_UNKNOWN_USER_83", "EM_REDO", "EM_CANREDO",
846 "EM_GETUNDONAME", "EM_GETREDONAME", "EM_STOPGROUPTYPING", "EM_SETTEXTMODE",
847 "EM_GETTEXTMODE", "EM_AUTOURLDETECT", "EM_GETAUTOURLDETECT", "EM_SETPALETTE",
848 "EM_GETTEXTEX", "EM_GETTEXTLENGTHEX", "EM_SHOWSCROLLBAR", "EM_SETTEXTEX",
849 "EM_UNKNOWN_USER_98", "EM_UNKNOWN_USER_99", "EM_SETPUNCTUATION", "EM_GETPUNCTUATION",
850 "EM_SETWORDWRAPMODE", "EM_GETWORDWRAPMODE", "EM_SETIMECOLOR", "EM_GETIMECOLOR",
851 "EM_SETIMEOPTIONS", "EM_GETIMEOPTIONS", "EM_CONVPOSITION", "EM_UNKNOWN_USER_109",
852 "EM_UNKNOWN_USER_110", "EM_UNKNOWN_USER_111", "EM_UNKNOWN_USER_112", "EM_UNKNOWN_USER_113",
853 "EM_UNKNOWN_USER_114", "EM_UNKNOWN_USER_115", "EM_UNKNOWN_USER_116", "EM_UNKNOWN_USER_117",
854 "EM_UNKNOWN_USER_118", "EM_UNKNOWN_USER_119", "EM_SETLANGOPTIONS", "EM_GETLANGOPTIONS",
855 "EM_GETIMECOMPMODE", "EM_FINDTEXTW", "EM_FINDTEXTEXW", "EM_RECONVERSION",
856 "EM_SETIMEMODEBIAS", "EM_GETIMEMODEBIAS"
859 static const char *get_msg_name( UINT msg
)
861 if (msg
>= EM_GETSEL
&& msg
<= EM_CHARFROMPOS
)
862 return edit_messages
[msg
- EM_GETSEL
];
863 if (msg
>= EM_CANPASTE
&& msg
<= EM_GETIMEMODEBIAS
)
864 return richedit_messages
[msg
- EM_CANPASTE
];
868 static BOOL
create_windowed_editor( HWND hwnd
, CREATESTRUCTW
*create
, BOOL emulate_10
)
870 struct host
*host
= host_create( hwnd
, create
, emulate_10
);
874 if (!host
) return FALSE
;
876 hr
= create_text_services( NULL
, (ITextHost
*)&host
->ITextHost_iface
, &unk
, emulate_10
);
879 ITextHost2_Release( &host
->ITextHost_iface
);
882 IUnknown_QueryInterface( unk
, &IID_ITextServices
, (void **)&host
->text_srv
);
883 IUnknown_Release( unk
);
885 SetWindowLongPtrW( hwnd
, 0, (LONG_PTR
)host
);
890 static HRESULT
get_lineA( ITextServices
*text_srv
, WPARAM wparam
, LPARAM lparam
, LRESULT
*res
)
892 LRESULT len
= USHRT_MAX
;
898 sizeA
= *(WORD
*)lparam
;
900 if (!sizeA
) return S_OK
;
901 buf
= heap_alloc( len
* sizeof(WCHAR
) );
902 if (!buf
) return E_OUTOFMEMORY
;
904 hr
= ITextServices_TxSendMessage( text_srv
, EM_GETLINE
, wparam
, (LPARAM
)buf
, &len
);
905 if (hr
== S_OK
&& len
)
907 len
= WideCharToMultiByte( CP_ACP
, 0, buf
, len
, (char *)lparam
, sizeA
, NULL
, NULL
);
908 if (!len
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
) len
= sizeA
;
909 if (len
< sizeA
) ((char *)lparam
)[len
] = '\0';
916 static HRESULT
get_text_rangeA( struct host
*host
, TEXTRANGEA
*rangeA
, LRESULT
*res
)
924 if (rangeA
->chrg
.cpMin
< 0) return S_OK
;
925 ITextServices_TxSendMessage( host
->text_srv
, WM_GETTEXTLENGTH
, 0, 0, &len
);
926 range
.chrg
= rangeA
->chrg
;
927 if ((range
.chrg
.cpMin
== 0 && range
.chrg
.cpMax
== -1) || range
.chrg
.cpMax
> len
)
928 range
.chrg
.cpMax
= len
;
929 if (range
.chrg
.cpMin
>= range
.chrg
.cpMax
) return S_OK
;
930 count
= range
.chrg
.cpMax
- range
.chrg
.cpMin
+ 1;
931 range
.lpstrText
= heap_alloc( count
* sizeof(WCHAR
) );
932 if (!range
.lpstrText
) return E_OUTOFMEMORY
;
933 hr
= ITextServices_TxSendMessage( host
->text_srv
, EM_GETTEXTRANGE
, 0, (LPARAM
)&range
, &len
);
934 if (hr
== S_OK
&& len
)
936 if (!host
->emulate_10
) count
= INT_MAX
;
937 len
= WideCharToMultiByte( CP_ACP
, 0, range
.lpstrText
, -1, rangeA
->lpstrText
, count
, NULL
, NULL
);
938 if (!host
->emulate_10
) *res
= len
- 1;
942 rangeA
->lpstrText
[*res
] = '\0';
945 heap_free( range
.lpstrText
);
949 static HRESULT
set_options( struct host
*host
, DWORD op
, DWORD value
, LRESULT
*res
)
951 DWORD style
, old_options
, new_options
, change
, props_mask
= 0;
952 DWORD mask
= ECO_AUTOWORDSELECTION
| ECO_AUTOVSCROLL
| ECO_AUTOHSCROLL
| ECO_NOHIDESEL
| ECO_READONLY
|
953 ECO_WANTRETURN
| ECO_SAVESEL
| ECO_SELECTIONBAR
| ECO_VERTICAL
;
955 new_options
= old_options
= SendMessageW( host
->window
, EM_GETOPTIONS
, 0, 0 );
963 new_options
|= value
;
966 new_options
&= value
;
969 new_options
^= value
;
973 change
= (new_options
^ old_options
);
975 if (change
& ECO_AUTOWORDSELECTION
)
977 host
->props
^= TXTBIT_AUTOWORDSEL
;
978 props_mask
|= TXTBIT_AUTOWORDSEL
;
980 if (change
& ECO_AUTOVSCROLL
)
982 host
->scrollbars
^= WS_VSCROLL
;
983 props_mask
|= TXTBIT_SCROLLBARCHANGE
;
985 if (change
& ECO_AUTOHSCROLL
)
987 host
->scrollbars
^= WS_HSCROLL
;
988 props_mask
|= TXTBIT_SCROLLBARCHANGE
;
990 if (change
& ECO_NOHIDESEL
)
992 host
->props
^= TXTBIT_HIDESELECTION
;
993 props_mask
|= TXTBIT_HIDESELECTION
;
995 if (change
& ECO_READONLY
)
997 host
->props
^= TXTBIT_READONLY
;
998 props_mask
|= TXTBIT_READONLY
;
1000 if (change
& ECO_SAVESEL
)
1002 host
->props
^= TXTBIT_SAVESELECTION
;
1003 props_mask
|= TXTBIT_SAVESELECTION
;
1005 if (change
& ECO_SELECTIONBAR
)
1008 props_mask
|= TXTBIT_SELBARCHANGE
;
1009 if (host
->use_set_rect
)
1011 int width
= SELECTIONBAR_WIDTH
;
1012 host
->set_rect
.left
+= host
->sel_bar
? width
: -width
;
1013 props_mask
|= TXTBIT_CLIENTRECTCHANGE
;
1016 if (change
& ECO_VERTICAL
)
1018 host
->props
^= TXTBIT_VERTICAL
;
1019 props_mask
|= TXTBIT_VERTICAL
;
1021 if (change
& ECO_WANTRETURN
) host
->want_return
^= 1;
1024 ITextServices_OnTxPropertyBitsChange( host
->text_srv
, props_mask
, host
->props
& props_mask
);
1028 mask
&= ~ECO_AUTOWORDSELECTION
; /* doesn't correspond to a window style */
1029 style
= GetWindowLongW( host
->window
, GWL_STYLE
);
1030 style
= (style
& ~mask
) | (*res
& mask
);
1031 SetWindowLongW( host
->window
, GWL_STYLE
, style
);
1035 /* handle dialog mode VK_RETURN. Returns TRUE if message has been processed */
1036 static BOOL
handle_dialog_enter( struct host
*host
)
1038 BOOL ctrl_is_down
= GetKeyState( VK_CONTROL
) & 0x8000;
1040 if (ctrl_is_down
) return TRUE
;
1042 if (host
->want_return
) return FALSE
;
1046 DWORD id
= SendMessageW( host
->parent
, DM_GETDEFID
, 0, 0 );
1047 if (HIWORD( id
) == DC_HASDEFID
)
1049 HWND ctrl
= GetDlgItem( host
->parent
, LOWORD( id
));
1052 SendMessageW( host
->parent
, WM_NEXTDLGCTL
, (WPARAM
)ctrl
, TRUE
);
1053 PostMessageW( ctrl
, WM_KEYDOWN
, VK_RETURN
, 0 );
1060 static LRESULT
send_msg_filter( struct host
*host
, UINT msg
, WPARAM
*wparam
, LPARAM
*lparam
)
1065 if (!host
->parent
) return 0;
1066 msgf
.nmhdr
.hwndFrom
= host
->window
;
1067 msgf
.nmhdr
.idFrom
= GetWindowLongW( host
->window
, GWLP_ID
);
1068 msgf
.nmhdr
.code
= EN_MSGFILTER
;
1070 msgf
.wParam
= *wparam
;
1071 msgf
.lParam
= *lparam
;
1072 if ((res
= SendMessageW( host
->parent
, WM_NOTIFY
, msgf
.nmhdr
.idFrom
, (LPARAM
)&msgf
)))
1074 *wparam
= msgf
.wParam
;
1075 *lparam
= msgf
.lParam
;
1080 static LRESULT
RichEditWndProc_common( HWND hwnd
, UINT msg
, WPARAM wparam
,
1081 LPARAM lparam
, BOOL unicode
)
1087 TRACE( "enter hwnd %p msg %04x (%s) %Ix %Ix, unicode %d\n",
1088 hwnd
, msg
, get_msg_name(msg
), wparam
, lparam
, unicode
);
1090 host
= (struct host
*)GetWindowLongPtrW( hwnd
, 0 );
1093 if (msg
== WM_NCCREATE
)
1095 CREATESTRUCTW
*pcs
= (CREATESTRUCTW
*)lparam
;
1097 TRACE( "WM_NCCREATE: hwnd %p style 0x%08lx\n", hwnd
, pcs
->style
);
1098 return create_windowed_editor( hwnd
, pcs
, FALSE
);
1100 else return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
1103 if ((((host
->event_mask
& ENM_KEYEVENTS
) && msg
>= WM_KEYFIRST
&& msg
<= WM_KEYLAST
) ||
1104 ((host
->event_mask
& ENM_MOUSEEVENTS
) && msg
>= WM_MOUSEFIRST
&& msg
<= WM_MOUSELAST
) ||
1105 ((host
->event_mask
& ENM_SCROLLEVENTS
) && msg
>= WM_HSCROLL
&& msg
<= WM_VSCROLL
)))
1107 host
->notify_level
++;
1108 res
= send_msg_filter( host
, msg
, &wparam
, &lparam
);
1109 if (!--host
->notify_level
&& host
->defer_release
)
1111 TRACE( "exit (filtered deferred release) hwnd %p msg %04x (%s) %Ix %Ix -> 0\n",
1112 hwnd
, msg
, get_msg_name(msg
), wparam
, lparam
);
1113 ITextHost2_Release( &host
->ITextHost_iface
);
1119 TRACE( "exit (filtered %Iu) hwnd %p msg %04x (%s) %Ix %Ix -> 0\n",
1120 res
, hwnd
, msg
, get_msg_name(msg
), wparam
, lparam
);
1131 if (!unicode
) MultiByteToWideChar( CP_ACP
, 0, (char *)&wparam
, 1, &wc
, 1 );
1132 if (wparam
== '\r' && host
->dialog_mode
&& host
->emulate_10
&& handle_dialog_enter( host
)) break;
1133 hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wc
, lparam
, &res
);
1139 CREATESTRUCTW
*createW
= (CREATESTRUCTW
*)lparam
;
1140 CREATESTRUCTA
*createA
= (CREATESTRUCTA
*)lparam
;
1142 WCHAR
*textW
= NULL
;
1143 LONG codepage
= unicode
? CP_UNICODE
: CP_ACP
;
1146 ITextServices_OnTxInPlaceActivate( host
->text_srv
, NULL
);
1150 text
= unicode
? (void *)createW
->lpszName
: (void *)createA
->lpszName
;
1151 textW
= ME_ToUnicode( codepage
, text
, &len
);
1153 ITextServices_TxSetText( host
->text_srv
, textW
);
1154 if (lparam
) ME_EndToUnicode( codepage
, textW
);
1158 if (!host
->notify_level
) ITextHost2_Release( &host
->ITextHost_iface
);
1159 else host
->defer_release
= 1;
1164 HDC hdc
= (HDC
)wparam
;
1168 if (GetUpdateRect( hwnd
, &rc
, TRUE
))
1170 brush
= CreateSolidBrush( ITextHost_TxGetSysColor( &host
->ITextHost_iface
, COLOR_WINDOW
) );
1171 FillRect( hdc
, &rc
, brush
);
1172 DeleteObject( brush
);
1178 FINDTEXTW
*params
= (FINDTEXTW
*)lparam
;
1179 FINDTEXTW new_params
;
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_FINDTEXTW
, wparam
, (LPARAM
)params
, &res
);
1189 if (!unicode
) ME_EndToUnicode( CP_ACP
, (WCHAR
*)new_params
.lpstrText
);
1194 FINDTEXTEXA
*paramsA
= (FINDTEXTEXA
*)lparam
;
1195 FINDTEXTEXW
*params
= (FINDTEXTEXW
*)lparam
;
1196 FINDTEXTEXW new_params
;
1201 new_params
.chrg
= params
->chrg
;
1202 new_params
.lpstrText
= ME_ToUnicode( CP_ACP
, (char *)params
->lpstrText
, &len
);
1203 params
= &new_params
;
1205 hr
= ITextServices_TxSendMessage( host
->text_srv
, EM_FINDTEXTEXW
, wparam
, (LPARAM
)params
, &res
);
1208 ME_EndToUnicode( CP_ACP
, (WCHAR
*)new_params
.lpstrText
);
1209 paramsA
->chrgText
= params
->chrgText
;
1214 if (lparam
) host
->dialog_mode
= TRUE
;
1216 res
= DLGC_WANTCHARS
| DLGC_WANTTAB
| DLGC_WANTARROWS
;
1217 if (host
->props
& TXTBIT_MULTILINE
) res
|= DLGC_WANTMESSAGE
;
1218 if (!(host
->props
& TXTBIT_SAVESELECTION
)) res
|= DLGC_HASSETSEL
;
1222 if (unicode
) hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, lparam
, &res
);
1223 else hr
= get_lineA( host
->text_srv
, wparam
, lparam
, &res
);
1226 case EM_GETPASSWORDCHAR
:
1227 ITextHost_TxGetPasswordChar( &host
->ITextHost_iface
, (WCHAR
*)&res
);
1231 hr
= ITextHost_TxGetClientRect( &host
->ITextHost_iface
, (RECT
*)lparam
);
1238 if (unicode
) hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, lparam
, &res
);
1241 ITextServices_TxSendMessage( host
->text_srv
, EM_EXGETSEL
, 0, (LPARAM
)&range
.chrg
, &res
);
1242 range
.lpstrText
= (char *)lparam
;
1243 range
.lpstrText
[0] = '\0';
1244 hr
= get_text_rangeA( host
, &range
, &res
);
1249 if (host
->props
& TXTBIT_READONLY
) res
|= ECO_READONLY
;
1250 if (!(host
->props
& TXTBIT_HIDESELECTION
)) res
|= ECO_NOHIDESEL
;
1251 if (host
->props
& TXTBIT_SAVESELECTION
) res
|= ECO_SAVESEL
;
1252 if (host
->props
& TXTBIT_AUTOWORDSEL
) res
|= ECO_AUTOWORDSELECTION
;
1253 if (host
->props
& TXTBIT_VERTICAL
) res
|= ECO_VERTICAL
;
1254 if (host
->scrollbars
& ES_AUTOHSCROLL
) res
|= ECO_AUTOHSCROLL
;
1255 if (host
->scrollbars
& ES_AUTOVSCROLL
) res
|= ECO_AUTOVSCROLL
;
1256 if (host
->want_return
) res
|= ECO_WANTRETURN
;
1257 if (host
->sel_bar
) res
|= ECO_SELECTIONBAR
;
1264 params
.cb
= wparam
* (unicode
? sizeof(WCHAR
) : sizeof(CHAR
));
1265 params
.flags
= GT_USECRLF
;
1266 params
.codepage
= unicode
? CP_UNICODE
: CP_ACP
;
1267 params
.lpDefaultChar
= NULL
;
1268 params
.lpUsedDefChar
= NULL
;
1269 hr
= ITextServices_TxSendMessage( host
->text_srv
, EM_GETTEXTEX
, (WPARAM
)¶ms
, lparam
, &res
);
1272 case WM_GETTEXTLENGTH
:
1274 GETTEXTLENGTHEX params
;
1276 params
.flags
= GTL_CLOSE
| (host
->emulate_10
? 0 : GTL_USECRLF
) | GTL_NUMCHARS
;
1277 params
.codepage
= unicode
? CP_UNICODE
: CP_ACP
;
1278 hr
= ITextServices_TxSendMessage( host
->text_srv
, EM_GETTEXTLENGTHEX
, (WPARAM
)¶ms
, 0, &res
);
1281 case EM_GETTEXTRANGE
:
1282 if (unicode
) hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, lparam
, &res
);
1283 else hr
= get_text_rangeA( host
, (TEXTRANGEA
*)lparam
, &res
);
1287 switch (LOWORD( wparam
))
1290 if (host
->dialog_mode
&& host
->parent
)
1291 PostMessageW( host
->parent
, WM_CLOSE
, 0, 0 );
1294 if (host
->dialog_mode
&& host
->parent
)
1295 SendMessageW( host
->parent
, WM_NEXTDLGCTL
, GetKeyState( VK_SHIFT
) & 0x8000, 0 );
1298 if (host
->dialog_mode
&& !host
->emulate_10
&& handle_dialog_enter( host
)) break;
1301 hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, lparam
, &res
);
1306 case WM_PRINTCLIENT
:
1309 RECT rc
, client
, update
;
1311 HBRUSH brush
= CreateSolidBrush( ITextHost_TxGetSysColor( &host
->ITextHost_iface
, COLOR_WINDOW
) );
1313 ITextHost_TxGetClientRect( &host
->ITextHost_iface
, &client
);
1315 if (msg
== WM_PAINT
)
1317 hdc
= BeginPaint( hwnd
, &ps
);
1318 update
= ps
.rcPaint
;
1326 brush
= SelectObject( hdc
, brush
);
1328 /* Erase area outside of the formatting rectangle */
1329 if (update
.top
< client
.top
)
1332 rc
.bottom
= client
.top
;
1333 PatBlt( hdc
, rc
.left
, rc
.top
, rc
.right
- rc
.left
, rc
.bottom
- rc
.top
, PATCOPY
);
1334 update
.top
= client
.top
;
1336 if (update
.bottom
> client
.bottom
)
1339 rc
.top
= client
.bottom
;
1340 PatBlt( hdc
, rc
.left
, rc
.top
, rc
.right
- rc
.left
, rc
.bottom
- rc
.top
, PATCOPY
);
1341 update
.bottom
= client
.bottom
;
1343 if (update
.left
< client
.left
)
1346 rc
.right
= client
.left
;
1347 PatBlt( hdc
, rc
.left
, rc
.top
, rc
.right
- rc
.left
, rc
.bottom
- rc
.top
, PATCOPY
);
1348 update
.left
= client
.left
;
1350 if (update
.right
> client
.right
)
1353 rc
.left
= client
.right
;
1354 PatBlt( hdc
, rc
.left
, rc
.top
, rc
.right
- rc
.left
, rc
.bottom
- rc
.top
, PATCOPY
);
1355 update
.right
= client
.right
;
1358 ITextServices_TxDraw( host
->text_srv
, DVASPECT_CONTENT
, 0, NULL
, NULL
, hdc
, NULL
, NULL
, NULL
,
1359 &update
, NULL
, 0, TXTVIEW_ACTIVE
);
1360 DeleteObject( SelectObject( hdc
, brush
) );
1361 if (msg
== WM_PAINT
) EndPaint( hwnd
, &ps
);
1367 LONG codepage
= unicode
? CP_UNICODE
: CP_ACP
;
1368 WCHAR
*text
= ME_ToUnicode( codepage
, (void *)lparam
, &len
);
1370 hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, (LPARAM
)text
, &res
);
1371 ME_EndToUnicode( codepage
, text
);
1375 case EM_SETBKGNDCOLOR
:
1376 res
= ITextHost_TxGetSysColor( &host
->ITextHost_iface
, COLOR_WINDOW
);
1377 host
->use_back_colour
= !wparam
;
1378 if (host
->use_back_colour
) host
->back_colour
= lparam
;
1379 InvalidateRect( hwnd
, NULL
, TRUE
);
1387 if (hwnd
!= (HWND
)wparam
) break;
1388 GetCursorPos( &pos
);
1389 ScreenToClient( hwnd
, &pos
);
1390 ITextHost_TxGetClientRect( &host
->ITextHost_iface
, &rect
);
1391 if (PtInRect( &rect
, pos
))
1392 ITextServices_OnTxSetCursor( host
->text_srv
, DVASPECT_CONTENT
, 0, NULL
, NULL
, NULL
, NULL
, NULL
, pos
.x
, pos
.y
);
1393 else ITextHost_TxSetCursor( &host
->ITextHost_iface
, LoadCursorW( NULL
, MAKEINTRESOURCEW( IDC_ARROW
) ), FALSE
);
1396 case EM_SETEVENTMASK
:
1397 host
->event_mask
= lparam
;
1398 hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, lparam
, &res
);
1402 hr
= set_options( host
, wparam
, lparam
, &res
);
1405 case EM_SETPASSWORDCHAR
:
1406 if (wparam
== host
->password_char
) break;
1407 host
->password_char
= wparam
;
1408 if (wparam
) host
->props
|= TXTBIT_USEPASSWORD
;
1409 else host
->props
&= ~TXTBIT_USEPASSWORD
;
1410 ITextServices_OnTxPropertyBitsChange( host
->text_srv
, TXTBIT_USEPASSWORD
, host
->props
& TXTBIT_USEPASSWORD
);
1413 case EM_SETREADONLY
:
1415 DWORD op
= wparam
? ECOOP_OR
: ECOOP_AND
;
1416 DWORD mask
= wparam
? ECO_READONLY
: ~ECO_READONLY
;
1418 SendMessageW( hwnd
, EM_SETOPTIONS
, op
, mask
);
1424 RECT
*rc
= (RECT
*)lparam
;
1426 if (!rc
) host
->use_set_rect
= 0;
1429 if (wparam
>= 2) break;
1430 host
->set_rect
= *rc
;
1431 if (host
->client_edge
)
1433 InflateRect( &host
->set_rect
, 1, 0 );
1434 host
->set_rect
.top
-= 1;
1436 if (!wparam
) IntersectRect( &host
->set_rect
, &host
->set_rect
, &host
->client_rect
);
1437 host
->use_set_rect
= 1;
1439 ITextServices_OnTxPropertyBitsChange( host
->text_srv
, TXTBIT_CLIENTRECTCHANGE
, 0 );
1444 char *textA
= (char *)lparam
;
1445 WCHAR
*text
= (WCHAR
*)lparam
;
1448 if (!unicode
&& textA
&& strncmp( textA
, "{\\rtf", 5 ) && strncmp( textA
, "{\\urtf", 6 ))
1449 text
= ME_ToUnicode( CP_ACP
, textA
, &len
);
1450 hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, (LPARAM
)text
, &res
);
1451 if (text
!= (WCHAR
*)lparam
) ME_EndToUnicode( CP_ACP
, text
);
1454 case EM_SHOWSCROLLBAR
:
1456 DWORD mask
= 0, new;
1458 if (wparam
== SB_HORZ
) mask
= WS_HSCROLL
;
1459 else if (wparam
== SB_VERT
) mask
= WS_VSCROLL
;
1460 else if (wparam
== SB_BOTH
) mask
= WS_HSCROLL
| WS_VSCROLL
;
1464 new = lparam
? mask
: 0;
1465 if ((host
->scrollbars
& mask
) != new)
1467 host
->scrollbars
&= ~mask
;
1468 host
->scrollbars
|= new;
1469 ITextServices_OnTxPropertyBitsChange( host
->text_srv
, TXTBIT_SCROLLBARCHANGE
, 0 );
1476 case WM_WINDOWPOSCHANGED
:
1479 WINDOWPOS
*winpos
= (WINDOWPOS
*)lparam
;
1481 hr
= S_FALSE
; /* call defwndproc */
1482 if (winpos
->flags
& SWP_NOCLIENTSIZE
) break;
1483 GetClientRect( hwnd
, &client
);
1484 if (host
->use_set_rect
)
1486 host
->set_rect
.right
+= client
.right
- host
->client_rect
.right
;
1487 host
->set_rect
.bottom
+= client
.bottom
- host
->client_rect
.bottom
;
1489 host
->client_rect
= client
;
1490 ITextServices_OnTxPropertyBitsChange( host
->text_srv
, TXTBIT_CLIENTRECTCHANGE
, 0 );
1494 hr
= ITextServices_TxSendMessage( host
->text_srv
, msg
, wparam
, lparam
, &res
);
1498 res
= DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
1500 TRACE( "exit hwnd %p msg %04x (%s) %Ix %Ix, unicode %d -> %Iu\n",
1501 hwnd
, msg
, get_msg_name(msg
), wparam
, lparam
, unicode
, res
);
1506 static LRESULT WINAPI
RichEditWndProcW( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1508 BOOL unicode
= TRUE
;
1510 /* Under Win9x RichEdit20W returns ANSI strings, see the tests. */
1511 if (msg
== WM_GETTEXT
&& (GetVersion() & 0x80000000))
1514 return RichEditWndProc_common( hwnd
, msg
, wparam
, lparam
, unicode
);
1517 static LRESULT WINAPI
RichEditWndProcA( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1519 return RichEditWndProc_common( hwnd
, msg
, wparam
, lparam
, FALSE
);
1522 /******************************************************************
1523 * RichEditANSIWndProc (RICHED20.10)
1525 LRESULT WINAPI
RichEditANSIWndProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1527 return RichEditWndProcA( hwnd
, msg
, wparam
, lparam
);
1530 /******************************************************************
1531 * RichEdit10ANSIWndProc (RICHED20.9)
1533 LRESULT WINAPI
RichEdit10ANSIWndProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1535 if (msg
== WM_NCCREATE
&& !GetWindowLongPtrW( hwnd
, 0 ))
1537 CREATESTRUCTW
*pcs
= (CREATESTRUCTW
*)lparam
;
1539 TRACE( "WM_NCCREATE: hwnd %p style 0x%08lx\n", hwnd
, pcs
->style
);
1540 return create_windowed_editor( hwnd
, pcs
, TRUE
);
1542 return RichEditANSIWndProc( hwnd
, msg
, wparam
, lparam
);
1545 static LRESULT WINAPI
REComboWndProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1547 /* FIXME: Not implemented */
1548 TRACE( "hwnd %p msg %04x (%s) %08Ix %08Ix\n",
1549 hwnd
, msg
, get_msg_name( msg
), wparam
, lparam
);
1550 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
1553 static LRESULT WINAPI
REListWndProc( HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
1555 /* FIXME: Not implemented */
1556 TRACE( "hwnd %p msg %04x (%s) %08Ix %08Ix\n",
1557 hwnd
, msg
, get_msg_name( msg
), wparam
, lparam
);
1558 return DefWindowProcW( hwnd
, msg
, wparam
, lparam
);
1561 /******************************************************************
1562 * REExtendedRegisterClass (RICHED20.8)
1564 * FIXME undocumented
1565 * Need to check for errors and implement controls and callbacks
1567 LRESULT WINAPI
REExtendedRegisterClass( void )
1572 FIXME( "semi stub\n" );
1575 wc
.hInstance
= NULL
;
1578 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
+ 1);
1579 wc
.lpszMenuName
= NULL
;
1581 if (!listbox_registered
)
1583 wc
.style
= CS_PARENTDC
| CS_DBLCLKS
| CS_GLOBALCLASS
;
1584 wc
.lpfnWndProc
= REListWndProc
;
1585 wc
.lpszClassName
= L
"REListBox20W";
1586 if (RegisterClassW( &wc
)) listbox_registered
= TRUE
;
1589 if (!combobox_registered
)
1591 wc
.style
= CS_PARENTDC
| CS_DBLCLKS
| CS_GLOBALCLASS
| CS_VREDRAW
| CS_HREDRAW
;
1592 wc
.lpfnWndProc
= REComboWndProc
;
1593 wc
.lpszClassName
= L
"REComboBox20W";
1594 if (RegisterClassW( &wc
)) combobox_registered
= TRUE
;
1598 if (listbox_registered
) result
+= 1;
1599 if (combobox_registered
) result
+= 2;
1604 static BOOL
register_classes( HINSTANCE instance
)
1609 wcW
.style
= CS_DBLCLKS
| CS_HREDRAW
| CS_VREDRAW
| CS_GLOBALCLASS
;
1610 wcW
.lpfnWndProc
= RichEditWndProcW
;
1612 wcW
.cbWndExtra
= sizeof(struct host
*);
1613 wcW
.hInstance
= NULL
; /* hInstance would register DLL-local class */
1615 wcW
.hCursor
= LoadCursorW( NULL
, (LPWSTR
)IDC_IBEAM
);
1616 wcW
.hbrBackground
= GetStockObject( NULL_BRUSH
);
1617 wcW
.lpszMenuName
= NULL
;
1619 if (!(GetVersion() & 0x80000000))
1621 wcW
.lpszClassName
= RICHEDIT_CLASS20W
;
1622 if (!RegisterClassW( &wcW
)) return FALSE
;
1623 wcW
.lpszClassName
= MSFTEDIT_CLASS
;
1624 if (!RegisterClassW( &wcW
)) return FALSE
;
1628 /* WNDCLASSA/W have the same layout */
1629 wcW
.lpszClassName
= (LPCWSTR
)"RichEdit20W";
1630 if (!RegisterClassA( (WNDCLASSA
*)&wcW
)) return FALSE
;
1631 wcW
.lpszClassName
= (LPCWSTR
)"RichEdit50W";
1632 if (!RegisterClassA( (WNDCLASSA
*)&wcW
)) return FALSE
;
1635 wcA
.style
= CS_DBLCLKS
| CS_HREDRAW
| CS_VREDRAW
| CS_GLOBALCLASS
;
1636 wcA
.lpfnWndProc
= RichEditWndProcA
;
1638 wcA
.cbWndExtra
= sizeof(struct host
*);
1639 wcA
.hInstance
= NULL
; /* hInstance would register DLL-local class */
1641 wcA
.hCursor
= LoadCursorW( NULL
, (LPWSTR
)IDC_IBEAM
);
1642 wcA
.hbrBackground
= GetStockObject(NULL_BRUSH
);
1643 wcA
.lpszMenuName
= NULL
;
1644 wcA
.lpszClassName
= RICHEDIT_CLASS20A
;
1645 if (!RegisterClassA( &wcA
)) return FALSE
;
1646 wcA
.lpszClassName
= "RichEdit50A";
1647 if (!RegisterClassA( &wcA
)) return FALSE
;
1652 BOOL WINAPI
DllMain( HINSTANCE instance
, DWORD reason
, void *reserved
)
1656 case DLL_PROCESS_ATTACH
:
1657 dll_instance
= instance
;
1658 DisableThreadLibraryCalls( instance
);
1659 if (!register_classes( instance
)) return FALSE
;
1663 case DLL_PROCESS_DETACH
:
1664 if (reserved
) break;
1665 UnregisterClassW( RICHEDIT_CLASS20W
, 0 );
1666 UnregisterClassW( MSFTEDIT_CLASS
, 0 );
1667 UnregisterClassA( RICHEDIT_CLASS20A
, 0 );
1668 UnregisterClassA( "RichEdit50A", 0 );
1669 if (listbox_registered
) UnregisterClassW( L
"REListBox20W", 0 );
1670 if (combobox_registered
) UnregisterClassW( L
"REComboBox20W", 0 );