2009-01-20 07:41:25 +01:00
|
|
|
/*
|
|
|
|
* RichEdit - ITextHost implementation for windowed richedit controls
|
|
|
|
*
|
|
|
|
* Copyright 2009 by Dylan Smith
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define COBJMACROS
|
|
|
|
|
|
|
|
#include "editor.h"
|
|
|
|
#include "ole2.h"
|
|
|
|
#include "richole.h"
|
|
|
|
#include "imm.h"
|
|
|
|
#include "textserv.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
#include "editstr.h"
|
2021-03-03 12:29:37 +01:00
|
|
|
#include "rtf.h"
|
|
|
|
#include "res.h"
|
2009-01-20 07:41:25 +01:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
|
|
|
|
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host
|
|
|
|
{
|
2011-04-10 21:42:53 +02:00
|
|
|
ITextHost ITextHost_iface;
|
2009-01-20 07:41:25 +01:00
|
|
|
LONG ref;
|
2021-03-03 12:29:41 +01:00
|
|
|
ITextServices *text_srv;
|
|
|
|
ME_TextEditor *editor; /* to be removed */
|
2021-03-16 09:22:49 +01:00
|
|
|
HWND window, parent;
|
2021-03-03 12:29:38 +01:00
|
|
|
BOOL emulate_10;
|
2017-08-21 13:31:45 +02:00
|
|
|
PARAFORMAT2 para_fmt;
|
2021-03-16 09:22:49 +01:00
|
|
|
DWORD props, scrollbars, event_mask;
|
2021-03-03 12:29:38 +01:00
|
|
|
};
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2009-09-07 14:13:52 +02:00
|
|
|
static const ITextHostVtbl textHostVtbl;
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2021-03-03 12:29:37 +01:00
|
|
|
static BOOL listbox_registered;
|
|
|
|
static BOOL combobox_registered;
|
|
|
|
|
2021-03-15 11:03:21 +01:00
|
|
|
static void host_init_props( struct host *host )
|
|
|
|
{
|
2021-03-16 09:22:46 +01:00
|
|
|
DWORD style;
|
2021-03-15 11:03:21 +01:00
|
|
|
|
|
|
|
style = GetWindowLongW( host->window, GWL_STYLE );
|
|
|
|
|
2021-03-16 09:22:46 +01:00
|
|
|
host->scrollbars = style & (WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL |
|
|
|
|
ES_AUTOHSCROLL | ES_DISABLENOSCROLL);
|
|
|
|
if (style & WS_VSCROLL) host->scrollbars |= ES_AUTOVSCROLL;
|
|
|
|
if ((style & WS_HSCROLL) && !host->emulate_10) host->scrollbars |= ES_AUTOHSCROLL;
|
|
|
|
|
2021-03-16 09:22:47 +01:00
|
|
|
host->props = TXTBIT_RICHTEXT | TXTBIT_ALLOWBEEP;
|
2021-03-15 11:03:21 +01:00
|
|
|
if (style & ES_MULTILINE) host->props |= TXTBIT_MULTILINE;
|
|
|
|
if (style & ES_READONLY) host->props |= TXTBIT_READONLY;
|
|
|
|
if (style & ES_PASSWORD) host->props |= TXTBIT_USEPASSWORD;
|
|
|
|
if (!(style & ES_NOHIDESEL)) host->props |= TXTBIT_HIDESELECTION;
|
|
|
|
if (style & ES_SAVESEL) host->props |= TXTBIT_SAVESELECTION;
|
|
|
|
if (style & ES_VERTICAL) host->props |= TXTBIT_VERTICAL;
|
|
|
|
if (style & ES_NOOLEDRAGDROP) host->props |= TXTBIT_DISABLEDRAG;
|
|
|
|
|
2021-03-16 09:22:46 +01:00
|
|
|
if (!(host->scrollbars & ES_AUTOHSCROLL)) host->props |= TXTBIT_WORDWRAP;
|
2021-03-15 11:03:21 +01:00
|
|
|
}
|
|
|
|
|
2021-03-03 12:29:41 +01:00
|
|
|
struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *texthost;
|
2017-08-21 13:31:44 +02:00
|
|
|
|
2009-01-20 07:41:25 +01:00
|
|
|
texthost = CoTaskMemAlloc(sizeof(*texthost));
|
2017-08-21 13:31:44 +02:00
|
|
|
if (!texthost) return NULL;
|
|
|
|
|
|
|
|
texthost->ITextHost_iface.lpVtbl = &textHostVtbl;
|
|
|
|
texthost->ref = 1;
|
2021-03-03 12:29:38 +01:00
|
|
|
texthost->window = hwnd;
|
2021-03-16 09:22:49 +01:00
|
|
|
texthost->parent = cs->hwndParent;
|
2021-03-03 12:29:38 +01:00
|
|
|
texthost->emulate_10 = emulate_10;
|
2017-08-21 13:31:45 +02:00
|
|
|
memset( &texthost->para_fmt, 0, sizeof(texthost->para_fmt) );
|
|
|
|
texthost->para_fmt.cbSize = sizeof(texthost->para_fmt);
|
|
|
|
texthost->para_fmt.dwMask = PFM_ALIGNMENT;
|
|
|
|
texthost->para_fmt.wAlignment = PFA_LEFT;
|
|
|
|
if (cs->style & ES_RIGHT)
|
|
|
|
texthost->para_fmt.wAlignment = PFA_RIGHT;
|
|
|
|
if (cs->style & ES_CENTER)
|
|
|
|
texthost->para_fmt.wAlignment = PFA_CENTER;
|
2021-03-08 14:45:49 +01:00
|
|
|
texthost->editor = NULL;
|
2021-03-15 11:03:21 +01:00
|
|
|
host_init_props( texthost );
|
2021-03-16 09:22:49 +01:00
|
|
|
texthost->event_mask = 0;
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2021-03-03 12:29:41 +01:00
|
|
|
return texthost;
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2021-03-03 12:29:38 +01:00
|
|
|
static inline struct host *impl_from_ITextHost( ITextHost *iface )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
return CONTAINING_RECORD( iface, struct host, ITextHost_iface );
|
2011-04-10 21:42:53 +02:00
|
|
|
}
|
|
|
|
|
2021-03-03 12:29:38 +01:00
|
|
|
static HRESULT WINAPI ITextHostImpl_QueryInterface( ITextHost *iface, REFIID riid, void **obj )
|
2011-04-10 21:42:53 +02:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2021-03-03 12:29:38 +01:00
|
|
|
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_ITextHost))
|
|
|
|
{
|
|
|
|
*obj = &host->ITextHost_iface;
|
|
|
|
ITextHost_AddRef( (ITextHost *)*obj );
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
FIXME("Unknown interface: %s\n", debugstr_guid(riid));
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI ITextHostImpl_AddRef(ITextHost *iface)
|
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
ULONG ref = InterlockedIncrement( &host->ref );
|
2009-01-20 07:41:25 +01:00
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG WINAPI ITextHostImpl_Release(ITextHost *iface)
|
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
ULONG ref = InterlockedDecrement( &host->ref );
|
2009-01-20 07:41:25 +01:00
|
|
|
|
|
|
|
if (!ref)
|
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
SetWindowLongPtrW( host->window, 0, 0 );
|
2021-03-03 12:29:41 +01:00
|
|
|
ITextServices_Release( host->text_srv );
|
2021-03-03 12:29:38 +01:00
|
|
|
CoTaskMemFree( host );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC,4)
|
|
|
|
DECLSPEC_HIDDEN HDC __thiscall ITextHostImpl_TxGetDC(ITextHost *iface)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return GetDC( host->window );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC,8)
|
|
|
|
DECLSPEC_HIDDEN INT __thiscall ITextHostImpl_TxReleaseDC(ITextHost *iface, HDC hdc)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return ReleaseDC( host->window, hdc );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar,12)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowScrollBar( ITextHost *iface, INT bar, BOOL show )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return ShowScrollBar( host->window, bar, show );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar,12)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxEnableScrollBar( ITextHost *iface, INT bar, INT arrows )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return EnableScrollBar( host->window, bar, arrows );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange,20)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollRange( ITextHost *iface, INT bar, LONG min_pos, INT max_pos, BOOL redraw )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return SetScrollRange( host->window, bar, min_pos, max_pos, redraw );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos,16)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetScrollPos( ITextHost *iface, INT bar, INT pos, BOOL redraw )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return SetScrollPos( host->window, bar, pos, redraw ) != 0;
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect,12)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxInvalidateRect( ITextHost *iface, const RECT *rect, BOOL mode )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
InvalidateRect( host->window, rect, mode );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxViewChange( ITextHost *iface, BOOL update )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
if (update) UpdateWindow( host->window );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret,16)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxCreateCaret( ITextHost *iface, HBITMAP bitmap, INT width, INT height )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return CreateCaret( host->window, bitmap, width, height );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxShowCaret( ITextHost *iface, BOOL show )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
if (show) return ShowCaret( host->window );
|
|
|
|
else return HideCaret( host->window );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos,12)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetCaretPos( ITextHost *iface, INT x, INT y )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
|
|
|
return SetCaretPos(x, y);
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer,12)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxSetTimer( ITextHost *iface, UINT id, UINT timeout )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return SetTimer( host->window, id, timeout, NULL ) != 0;
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxKillTimer( ITextHost *iface, UINT id )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
KillTimer( host->window, id );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx,32)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxScrollWindowEx( ITextHost *iface, INT dx, INT dy, const RECT *scroll,
|
|
|
|
const RECT *clip, HRGN update_rgn, RECT *update_rect,
|
|
|
|
UINT flags )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
ScrollWindowEx( host->window, dx, dy, scroll, clip, update_rgn, update_rect, flags );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCapture( ITextHost *iface, BOOL capture )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
if (capture) SetCapture( host->window );
|
|
|
|
else ReleaseCapture();
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus,4)
|
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetFocus(ITextHost *iface)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
SetFocus( host->window );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor,12)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxSetCursor( ITextHost *iface, HCURSOR cursor, BOOL text )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
SetCursor( cursor );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxScreenToClient( ITextHost *iface, POINT *pt )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return ScreenToClient( host->window, pt );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN BOOL __thiscall ITextHostImpl_TxClientToScreen( ITextHost *iface, POINT *pt )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return ClientToScreen( host->window, pt );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxActivate( ITextHost *iface, LONG *old_state )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
*old_state = HandleToLong( SetActiveWindow( host->window ) );
|
|
|
|
return *old_state ? S_OK : E_FAIL;
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxDeactivate( ITextHost *iface, LONG new_state )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
HWND ret = SetActiveWindow( LongToHandle( new_state ) );
|
|
|
|
return ret ? S_OK : E_FAIL;
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetClientRect( ITextHost *iface, RECT *rect )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
int ret = GetClientRect( host->window, rect );
|
|
|
|
return ret ? S_OK : E_FAIL;
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetViewInset( ITextHost *iface, RECT *rect )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
SetRectEmpty( rect );
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat,8)
|
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetCharFormat(ITextHost *iface, const CHARFORMATW **ppCF)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetParaFormat( ITextHost *iface, const PARAFORMAT **fmt )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
*fmt = (const PARAFORMAT *)&host->para_fmt;
|
2017-08-21 13:31:45 +02:00
|
|
|
return S_OK;
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN COLORREF __thiscall ITextHostImpl_TxGetSysColor( ITextHost *iface, int index )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
return GetSysColor( index );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetBackStyle( ITextHost *iface, TXTBACKSTYLE *style )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
*style = TXTBACK_OPAQUE;
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength( ITextHost *iface, DWORD *length )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
*length = INFINITE;
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8)
|
2021-03-16 09:22:46 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost *iface, DWORD *scrollbars )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
2021-03-16 09:22:46 +01:00
|
|
|
|
|
|
|
*scrollbars = host->scrollbars;
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPasswordChar( ITextHost *iface, WCHAR *c )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
*c = '*';
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetAcceleratorPos( ITextHost *iface, LONG *pos )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
*pos = -1;
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetExtent( ITextHost *iface, SIZEL *extent )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange,8)
|
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxCharFormatChange(ITextHost *iface, const CHARFORMATW *pcf)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange,8)
|
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_OnTxParaFormatChange(ITextHost *iface, const PARAFORMAT *ppf)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits,12)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetPropertyBits( ITextHost *iface, DWORD mask, DWORD *bits )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2021-03-15 11:03:21 +01:00
|
|
|
*bits = host->props & mask;
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify,12)
|
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, void *pv)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
HWND hwnd = host->window;
|
2009-09-30 16:46:37 +02:00
|
|
|
UINT id;
|
|
|
|
|
2021-03-08 14:45:49 +01:00
|
|
|
if (!host->editor || !host->editor->hwndParent) return S_OK;
|
2009-09-30 16:46:37 +02:00
|
|
|
|
|
|
|
id = GetWindowLongW(hwnd, GWLP_ID);
|
2009-01-20 07:41:25 +01:00
|
|
|
|
|
|
|
switch (iNotify)
|
|
|
|
{
|
|
|
|
case EN_DROPFILES:
|
|
|
|
case EN_LINK:
|
|
|
|
case EN_OLEOPFAILED:
|
|
|
|
case EN_PROTECTED:
|
|
|
|
case EN_REQUESTRESIZE:
|
|
|
|
case EN_SAVECLIPBOARD:
|
|
|
|
case EN_SELCHANGE:
|
|
|
|
case EN_STOPNOUNDO:
|
|
|
|
{
|
|
|
|
/* FIXME: Verify this assumption that pv starts with NMHDR. */
|
2009-01-30 10:40:02 +01:00
|
|
|
NMHDR *info = pv;
|
2009-01-20 07:41:25 +01:00
|
|
|
if (!info)
|
|
|
|
return E_FAIL;
|
|
|
|
|
|
|
|
info->hwndFrom = hwnd;
|
|
|
|
info->idFrom = id;
|
|
|
|
info->code = iNotify;
|
2021-03-08 14:45:49 +01:00
|
|
|
SendMessageW( host->editor->hwndParent, WM_NOTIFY, id, (LPARAM)info );
|
2009-01-20 07:41:25 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case EN_UPDATE:
|
|
|
|
/* Only sent when the window is visible. */
|
2009-09-30 16:46:37 +02:00
|
|
|
if (!IsWindowVisible(hwnd))
|
2009-01-20 07:41:25 +01:00
|
|
|
break;
|
|
|
|
/* Fall through */
|
|
|
|
case EN_CHANGE:
|
|
|
|
case EN_ERRSPACE:
|
|
|
|
case EN_HSCROLL:
|
|
|
|
case EN_KILLFOCUS:
|
|
|
|
case EN_MAXTEXT:
|
|
|
|
case EN_SETFOCUS:
|
|
|
|
case EN_VSCROLL:
|
2021-03-08 14:45:49 +01:00
|
|
|
SendMessageW( host->editor->hwndParent, WM_COMMAND, MAKEWPARAM( id, iNotify ), (LPARAM)hwnd );
|
2009-01-20 07:41:25 +01:00
|
|
|
break;
|
|
|
|
|
2009-03-05 23:06:47 +01:00
|
|
|
case EN_MSGFILTER:
|
|
|
|
FIXME("EN_MSGFILTER is documented as not being sent to TxNotify\n");
|
|
|
|
/* fall through */
|
2009-01-20 07:41:25 +01:00
|
|
|
default:
|
|
|
|
return E_FAIL;
|
|
|
|
}
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext,4)
|
|
|
|
DECLSPEC_HIDDEN HIMC __thiscall ITextHostImpl_TxImmGetContext(ITextHost *iface)
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
return ImmGetContext( host->window );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN void __thiscall ITextHostImpl_TxImmReleaseContext( ITextHost *iface, HIMC context )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
|
|
|
ImmReleaseContext( host->window, context );
|
2009-01-20 07:41:25 +01:00
|
|
|
}
|
|
|
|
|
2019-05-15 20:07:53 +02:00
|
|
|
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth,8)
|
2021-03-03 12:29:38 +01:00
|
|
|
DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetSelectionBarWidth( ITextHost *iface, LONG *width )
|
2009-01-20 07:41:25 +01:00
|
|
|
{
|
2021-03-03 12:29:38 +01:00
|
|
|
struct host *host = impl_from_ITextHost( iface );
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2021-03-08 14:45:49 +01:00
|
|
|
DWORD style = host->editor ? host->editor->styleFlags : GetWindowLongW( host->window, GWL_STYLE );
|
2021-03-03 12:29:38 +01:00
|
|
|
*width = (style & ES_SELECTIONBAR) ? 225 : 0; /* in HIMETRIC */
|
2009-01-20 07:41:25 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-04-27 02:31:39 +02:00
|
|
|
#ifdef __ASM_USE_THISCALL_WRAPPER
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2018-09-26 19:10:30 +02:00
|
|
|
#define STDCALL(func) (void *) __stdcall_ ## func
|
2019-03-15 09:37:01 +01:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define DEFINE_STDCALL_WRAPPER(num,func,args) \
|
|
|
|
__declspec(naked) HRESULT __stdcall_##func(void) \
|
|
|
|
{ \
|
|
|
|
__asm pop eax \
|
|
|
|
__asm pop ecx \
|
|
|
|
__asm push eax \
|
|
|
|
__asm mov eax, [ecx] \
|
|
|
|
__asm jmp dword ptr [eax + 4*num] \
|
|
|
|
}
|
|
|
|
#else /* _MSC_VER */
|
2009-06-14 15:34:20 +02:00
|
|
|
#define DEFINE_STDCALL_WRAPPER(num,func,args) \
|
2018-09-26 19:10:30 +02:00
|
|
|
extern HRESULT __stdcall_ ## func(void); \
|
|
|
|
__ASM_GLOBAL_FUNC(__stdcall_ ## func, \
|
2009-01-20 07:41:25 +01:00
|
|
|
"popl %eax\n\t" \
|
|
|
|
"popl %ecx\n\t" \
|
|
|
|
"pushl %eax\n\t" \
|
|
|
|
"movl (%ecx), %eax\n\t" \
|
|
|
|
"jmp *(4*(" #num "))(%eax)" )
|
2019-03-15 09:37:01 +01:00
|
|
|
#endif /* _MSC_VER */
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2009-06-14 15:34:20 +02:00
|
|
|
DEFINE_STDCALL_WRAPPER(3,ITextHostImpl_TxGetDC,4)
|
|
|
|
DEFINE_STDCALL_WRAPPER(4,ITextHostImpl_TxReleaseDC,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(5,ITextHostImpl_TxShowScrollBar,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(6,ITextHostImpl_TxEnableScrollBar,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(7,ITextHostImpl_TxSetScrollRange,20)
|
|
|
|
DEFINE_STDCALL_WRAPPER(8,ITextHostImpl_TxSetScrollPos,16)
|
|
|
|
DEFINE_STDCALL_WRAPPER(9,ITextHostImpl_TxInvalidateRect,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(10,ITextHostImpl_TxViewChange,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(11,ITextHostImpl_TxCreateCaret,16)
|
|
|
|
DEFINE_STDCALL_WRAPPER(12,ITextHostImpl_TxShowCaret,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(13,ITextHostImpl_TxSetCaretPos,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(14,ITextHostImpl_TxSetTimer,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(15,ITextHostImpl_TxKillTimer,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(16,ITextHostImpl_TxScrollWindowEx,32)
|
|
|
|
DEFINE_STDCALL_WRAPPER(17,ITextHostImpl_TxSetCapture,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(18,ITextHostImpl_TxSetFocus,4)
|
|
|
|
DEFINE_STDCALL_WRAPPER(19,ITextHostImpl_TxSetCursor,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(20,ITextHostImpl_TxScreenToClient,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(21,ITextHostImpl_TxClientToScreen,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(22,ITextHostImpl_TxActivate,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(23,ITextHostImpl_TxDeactivate,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(24,ITextHostImpl_TxGetClientRect,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(25,ITextHostImpl_TxGetViewInset,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(26,ITextHostImpl_TxGetCharFormat,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(27,ITextHostImpl_TxGetParaFormat,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(28,ITextHostImpl_TxGetSysColor,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(29,ITextHostImpl_TxGetBackStyle,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(30,ITextHostImpl_TxGetMaxLength,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(31,ITextHostImpl_TxGetScrollBars,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(32,ITextHostImpl_TxGetPasswordChar,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(33,ITextHostImpl_TxGetAcceleratorPos,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(34,ITextHostImpl_TxGetExtent,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(35,ITextHostImpl_OnTxCharFormatChange,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(36,ITextHostImpl_OnTxParaFormatChange,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(37,ITextHostImpl_TxGetPropertyBits,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify,12)
|
|
|
|
DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext,4)
|
|
|
|
DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext,8)
|
|
|
|
DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth,8)
|
2009-01-20 07:41:25 +01:00
|
|
|
|
2021-03-11 09:50:59 +01:00
|
|
|
const ITextHostVtbl text_host_stdcall_vtbl =
|
|
|
|
{
|
2009-01-20 07:41:25 +01:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2018-09-26 19:10:30 +02:00
|
|
|
STDCALL(ITextHostImpl_TxGetDC),
|
|
|
|
STDCALL(ITextHostImpl_TxReleaseDC),
|
|
|
|
STDCALL(ITextHostImpl_TxShowScrollBar),
|
|
|
|
STDCALL(ITextHostImpl_TxEnableScrollBar),
|
|
|
|
STDCALL(ITextHostImpl_TxSetScrollRange),
|
|
|
|
STDCALL(ITextHostImpl_TxSetScrollPos),
|
|
|
|
STDCALL(ITextHostImpl_TxInvalidateRect),
|
|
|
|
STDCALL(ITextHostImpl_TxViewChange),
|
|
|
|
STDCALL(ITextHostImpl_TxCreateCaret),
|
|
|
|
STDCALL(ITextHostImpl_TxShowCaret),
|
|
|
|
STDCALL(ITextHostImpl_TxSetCaretPos),
|
|
|
|
STDCALL(ITextHostImpl_TxSetTimer),
|
|
|
|
STDCALL(ITextHostImpl_TxKillTimer),
|
|
|
|
STDCALL(ITextHostImpl_TxScrollWindowEx),
|
|
|
|
STDCALL(ITextHostImpl_TxSetCapture),
|
|
|
|
STDCALL(ITextHostImpl_TxSetFocus),
|
|
|
|
STDCALL(ITextHostImpl_TxSetCursor),
|
|
|
|
STDCALL(ITextHostImpl_TxScreenToClient),
|
|
|
|
STDCALL(ITextHostImpl_TxClientToScreen),
|
|
|
|
STDCALL(ITextHostImpl_TxActivate),
|
|
|
|
STDCALL(ITextHostImpl_TxDeactivate),
|
|
|
|
STDCALL(ITextHostImpl_TxGetClientRect),
|
|
|
|
STDCALL(ITextHostImpl_TxGetViewInset),
|
|
|
|
STDCALL(ITextHostImpl_TxGetCharFormat),
|
|
|
|
STDCALL(ITextHostImpl_TxGetParaFormat),
|
|
|
|
STDCALL(ITextHostImpl_TxGetSysColor),
|
|
|
|
STDCALL(ITextHostImpl_TxGetBackStyle),
|
|
|
|
STDCALL(ITextHostImpl_TxGetMaxLength),
|
|
|
|
STDCALL(ITextHostImpl_TxGetScrollBars),
|
|
|
|
STDCALL(ITextHostImpl_TxGetPasswordChar),
|
|
|
|
STDCALL(ITextHostImpl_TxGetAcceleratorPos),
|
|
|
|
STDCALL(ITextHostImpl_TxGetExtent),
|
|
|
|
STDCALL(ITextHostImpl_OnTxCharFormatChange),
|
|
|
|
STDCALL(ITextHostImpl_OnTxParaFormatChange),
|
|
|
|
STDCALL(ITextHostImpl_TxGetPropertyBits),
|
|
|
|
STDCALL(ITextHostImpl_TxNotify),
|
|
|
|
STDCALL(ITextHostImpl_TxImmGetContext),
|
|
|
|
STDCALL(ITextHostImpl_TxImmReleaseContext),
|
|
|
|
STDCALL(ITextHostImpl_TxGetSelectionBarWidth),
|
2009-01-20 07:41:25 +01:00
|
|
|
};
|
|
|
|
|
2021-03-11 09:50:59 +01:00
|
|
|
#endif /* __ASM_USE_THISCALL_WRAPPER */
|
2009-08-26 21:23:52 +02:00
|
|
|
|
2021-03-11 09:50:59 +01:00
|
|
|
static const ITextHostVtbl textHostVtbl =
|
|
|
|
{
|
2009-08-26 21:23:52 +02:00
|
|
|
ITextHostImpl_QueryInterface,
|
|
|
|
ITextHostImpl_AddRef,
|
|
|
|
ITextHostImpl_Release,
|
|
|
|
THISCALL(ITextHostImpl_TxGetDC),
|
|
|
|
THISCALL(ITextHostImpl_TxReleaseDC),
|
|
|
|
THISCALL(ITextHostImpl_TxShowScrollBar),
|
|
|
|
THISCALL(ITextHostImpl_TxEnableScrollBar),
|
|
|
|
THISCALL(ITextHostImpl_TxSetScrollRange),
|
|
|
|
THISCALL(ITextHostImpl_TxSetScrollPos),
|
|
|
|
THISCALL(ITextHostImpl_TxInvalidateRect),
|
|
|
|
THISCALL(ITextHostImpl_TxViewChange),
|
|
|
|
THISCALL(ITextHostImpl_TxCreateCaret),
|
|
|
|
THISCALL(ITextHostImpl_TxShowCaret),
|
|
|
|
THISCALL(ITextHostImpl_TxSetCaretPos),
|
|
|
|
THISCALL(ITextHostImpl_TxSetTimer),
|
|
|
|
THISCALL(ITextHostImpl_TxKillTimer),
|
|
|
|
THISCALL(ITextHostImpl_TxScrollWindowEx),
|
|
|
|
THISCALL(ITextHostImpl_TxSetCapture),
|
|
|
|
THISCALL(ITextHostImpl_TxSetFocus),
|
|
|
|
THISCALL(ITextHostImpl_TxSetCursor),
|
|
|
|
THISCALL(ITextHostImpl_TxScreenToClient),
|
|
|
|
THISCALL(ITextHostImpl_TxClientToScreen),
|
|
|
|
THISCALL(ITextHostImpl_TxActivate),
|
|
|
|
THISCALL(ITextHostImpl_TxDeactivate),
|
|
|
|
THISCALL(ITextHostImpl_TxGetClientRect),
|
|
|
|
THISCALL(ITextHostImpl_TxGetViewInset),
|
|
|
|
THISCALL(ITextHostImpl_TxGetCharFormat),
|
|
|
|
THISCALL(ITextHostImpl_TxGetParaFormat),
|
|
|
|
THISCALL(ITextHostImpl_TxGetSysColor),
|
|
|
|
THISCALL(ITextHostImpl_TxGetBackStyle),
|
|
|
|
THISCALL(ITextHostImpl_TxGetMaxLength),
|
|
|
|
THISCALL(ITextHostImpl_TxGetScrollBars),
|
|
|
|
THISCALL(ITextHostImpl_TxGetPasswordChar),
|
|
|
|
THISCALL(ITextHostImpl_TxGetAcceleratorPos),
|
|
|
|
THISCALL(ITextHostImpl_TxGetExtent),
|
|
|
|
THISCALL(ITextHostImpl_OnTxCharFormatChange),
|
|
|
|
THISCALL(ITextHostImpl_OnTxParaFormatChange),
|
|
|
|
THISCALL(ITextHostImpl_TxGetPropertyBits),
|
|
|
|
THISCALL(ITextHostImpl_TxNotify),
|
|
|
|
THISCALL(ITextHostImpl_TxImmGetContext),
|
|
|
|
THISCALL(ITextHostImpl_TxImmReleaseContext),
|
|
|
|
THISCALL(ITextHostImpl_TxGetSelectionBarWidth),
|
|
|
|
};
|
2021-03-03 12:29:37 +01:00
|
|
|
|
|
|
|
static const char * const edit_messages[] =
|
|
|
|
{
|
|
|
|
"EM_GETSEL", "EM_SETSEL", "EM_GETRECT", "EM_SETRECT",
|
|
|
|
"EM_SETRECTNP", "EM_SCROLL", "EM_LINESCROLL", "EM_SCROLLCARET",
|
|
|
|
"EM_GETMODIFY", "EM_SETMODIFY", "EM_GETLINECOUNT", "EM_LINEINDEX",
|
|
|
|
"EM_SETHANDLE", "EM_GETHANDLE", "EM_GETTHUMB", "EM_UNKNOWN_BF",
|
|
|
|
"EM_UNKNOWN_C0", "EM_LINELENGTH", "EM_REPLACESEL", "EM_UNKNOWN_C3",
|
|
|
|
"EM_GETLINE", "EM_LIMITTEXT", "EM_CANUNDO", "EM_UNDO",
|
|
|
|
"EM_FMTLINES", "EM_LINEFROMCHAR", "EM_UNKNOWN_CA", "EM_SETTABSTOPS",
|
|
|
|
"EM_SETPASSWORDCHAR", "EM_EMPTYUNDOBUFFER", "EM_GETFIRSTVISIBLELINE", "EM_SETREADONLY",
|
|
|
|
"EM_SETWORDBREAKPROC", "EM_GETWORDBREAKPROC", "EM_GETPASSWORDCHAR", "EM_SETMARGINS",
|
|
|
|
"EM_GETMARGINS", "EM_GETLIMITTEXT", "EM_POSFROMCHAR", "EM_CHARFROMPOS",
|
|
|
|
"EM_SETIMESTATUS", "EM_GETIMESTATUS"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char * const richedit_messages[] =
|
|
|
|
{
|
|
|
|
"EM_CANPASTE", "EM_DISPLAYBAND", "EM_EXGETSEL", "EM_EXLIMITTEXT",
|
|
|
|
"EM_EXLINEFROMCHAR", "EM_EXSETSEL", "EM_FINDTEXT", "EM_FORMATRANGE",
|
|
|
|
"EM_GETCHARFORMAT", "EM_GETEVENTMASK", "EM_GETOLEINTERFACE", "EM_GETPARAFORMAT",
|
|
|
|
"EM_GETSELTEXT", "EM_HIDESELECTION", "EM_PASTESPECIAL", "EM_REQUESTRESIZE",
|
|
|
|
"EM_SELECTIONTYPE", "EM_SETBKGNDCOLOR", "EM_SETCHARFORMAT", "EM_SETEVENTMASK",
|
|
|
|
"EM_SETOLECALLBACK", "EM_SETPARAFORMAT", "EM_SETTARGETDEVICE", "EM_STREAMIN",
|
|
|
|
"EM_STREAMOUT", "EM_GETTEXTRANGE", "EM_FINDWORDBREAK", "EM_SETOPTIONS",
|
|
|
|
"EM_GETOPTIONS", "EM_FINDTEXTEX", "EM_GETWORDBREAKPROCEX", "EM_SETWORDBREAKPROCEX",
|
|
|
|
"EM_SETUNDOLIMIT", "EM_UNKNOWN_USER_83", "EM_REDO", "EM_CANREDO",
|
|
|
|
"EM_GETUNDONAME", "EM_GETREDONAME", "EM_STOPGROUPTYPING", "EM_SETTEXTMODE",
|
|
|
|
"EM_GETTEXTMODE", "EM_AUTOURLDETECT", "EM_GETAUTOURLDETECT", "EM_SETPALETTE",
|
|
|
|
"EM_GETTEXTEX", "EM_GETTEXTLENGTHEX", "EM_SHOWSCROLLBAR", "EM_SETTEXTEX",
|
|
|
|
"EM_UNKNOWN_USER_98", "EM_UNKNOWN_USER_99", "EM_SETPUNCTUATION", "EM_GETPUNCTUATION",
|
|
|
|
"EM_SETWORDWRAPMODE", "EM_GETWORDWRAPMODE", "EM_SETIMECOLOR", "EM_GETIMECOLOR",
|
|
|
|
"EM_SETIMEOPTIONS", "EM_GETIMEOPTIONS", "EM_CONVPOSITION", "EM_UNKNOWN_USER_109",
|
|
|
|
"EM_UNKNOWN_USER_110", "EM_UNKNOWN_USER_111", "EM_UNKNOWN_USER_112", "EM_UNKNOWN_USER_113",
|
|
|
|
"EM_UNKNOWN_USER_114", "EM_UNKNOWN_USER_115", "EM_UNKNOWN_USER_116", "EM_UNKNOWN_USER_117",
|
|
|
|
"EM_UNKNOWN_USER_118", "EM_UNKNOWN_USER_119", "EM_SETLANGOPTIONS", "EM_GETLANGOPTIONS",
|
|
|
|
"EM_GETIMECOMPMODE", "EM_FINDTEXTW", "EM_FINDTEXTEXW", "EM_RECONVERSION",
|
|
|
|
"EM_SETIMEMODEBIAS", "EM_GETIMEMODEBIAS"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *get_msg_name( UINT msg )
|
|
|
|
{
|
|
|
|
if (msg >= EM_GETSEL && msg <= EM_CHARFROMPOS)
|
|
|
|
return edit_messages[msg - EM_GETSEL];
|
|
|
|
if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS)
|
|
|
|
return richedit_messages[msg - EM_CANPASTE];
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL create_windowed_editor( HWND hwnd, CREATESTRUCTW *create, BOOL emulate_10 )
|
|
|
|
{
|
2021-03-03 12:29:41 +01:00
|
|
|
struct host *host = host_create( hwnd, create, emulate_10 );
|
|
|
|
IUnknown *unk;
|
|
|
|
HRESULT hr;
|
2021-03-03 12:29:37 +01:00
|
|
|
|
|
|
|
if (!host) return FALSE;
|
|
|
|
|
2021-03-03 12:29:41 +01:00
|
|
|
hr = create_text_services( NULL, &host->ITextHost_iface, &unk, emulate_10, &host->editor );
|
|
|
|
if (FAILED( hr ))
|
2021-03-03 12:29:37 +01:00
|
|
|
{
|
2021-03-03 12:29:41 +01:00
|
|
|
ITextHost_Release( &host->ITextHost_iface );
|
2021-03-03 12:29:37 +01:00
|
|
|
return FALSE;
|
|
|
|
}
|
2021-03-03 12:29:41 +01:00
|
|
|
IUnknown_QueryInterface( unk, &IID_ITextServices, (void **)&host->text_srv );
|
|
|
|
IUnknown_Release( unk );
|
2021-03-03 12:29:37 +01:00
|
|
|
|
2021-03-03 12:29:41 +01:00
|
|
|
host->editor->exStyleFlags = GetWindowLongW( hwnd, GWL_EXSTYLE );
|
|
|
|
host->editor->styleFlags |= GetWindowLongW( hwnd, GWL_STYLE ) & ES_WANTRETURN;
|
|
|
|
host->editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */
|
|
|
|
host->editor->hwndParent = create->hwndParent;
|
2021-03-03 12:29:37 +01:00
|
|
|
|
2021-03-08 14:45:49 +01:00
|
|
|
SetWindowLongPtrW( hwnd, 0, (LONG_PTR)host );
|
2021-03-03 12:29:37 +01:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-03-15 11:03:17 +01:00
|
|
|
static HRESULT get_lineA( ITextServices *text_srv, WPARAM wparam, LPARAM lparam, LRESULT *res )
|
|
|
|
{
|
|
|
|
LRESULT len = USHRT_MAX;
|
|
|
|
WORD sizeA;
|
|
|
|
HRESULT hr;
|
|
|
|
WCHAR *buf;
|
|
|
|
|
|
|
|
*res = 0;
|
|
|
|
sizeA = *(WORD *)lparam;
|
|
|
|
*(WORD *)lparam = 0;
|
|
|
|
if (!sizeA) return S_OK;
|
|
|
|
buf = heap_alloc( len * sizeof(WCHAR) );
|
|
|
|
if (!buf) return E_OUTOFMEMORY;
|
|
|
|
*(WORD *)buf = len;
|
|
|
|
hr = ITextServices_TxSendMessage( text_srv, EM_GETLINE, wparam, (LPARAM)buf, &len );
|
|
|
|
if (hr == S_OK && len)
|
|
|
|
{
|
|
|
|
len = WideCharToMultiByte( CP_ACP, 0, buf, len, (char *)lparam, sizeA, NULL, NULL );
|
|
|
|
if (!len && GetLastError() == ERROR_INSUFFICIENT_BUFFER) len = sizeA;
|
|
|
|
if (len < sizeA) ((char *)lparam)[len] = '\0';
|
|
|
|
*res = len;
|
|
|
|
}
|
|
|
|
heap_free( buf );
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2021-03-12 10:01:36 +01:00
|
|
|
static HRESULT get_text_rangeA( struct host *host, TEXTRANGEA *rangeA, LRESULT *res )
|
|
|
|
{
|
|
|
|
TEXTRANGEW range;
|
|
|
|
HRESULT hr;
|
|
|
|
unsigned int count;
|
|
|
|
LRESULT len;
|
|
|
|
|
|
|
|
*res = 0;
|
|
|
|
if (rangeA->chrg.cpMin < 0) return S_OK;
|
|
|
|
ITextServices_TxSendMessage( host->text_srv, WM_GETTEXTLENGTH, 0, 0, &len );
|
|
|
|
range.chrg = rangeA->chrg;
|
|
|
|
if ((range.chrg.cpMin == 0 && range.chrg.cpMax == -1) || range.chrg.cpMax > len)
|
|
|
|
range.chrg.cpMax = len;
|
|
|
|
if (range.chrg.cpMin >= range.chrg.cpMax) return S_OK;
|
|
|
|
count = range.chrg.cpMax - range.chrg.cpMin + 1;
|
|
|
|
range.lpstrText = heap_alloc( count * sizeof(WCHAR) );
|
|
|
|
if (!range.lpstrText) return E_OUTOFMEMORY;
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTRANGE, 0, (LPARAM)&range, &len );
|
|
|
|
if (hr == S_OK && len)
|
|
|
|
{
|
|
|
|
if (!host->emulate_10) count = INT_MAX;
|
|
|
|
len = WideCharToMultiByte( CP_ACP, 0, range.lpstrText, -1, rangeA->lpstrText, count, NULL, NULL );
|
|
|
|
if (!host->emulate_10) *res = len - 1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*res = count - 1;
|
|
|
|
rangeA->lpstrText[*res] = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
heap_free( range.lpstrText );
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2021-03-16 09:22:45 +01:00
|
|
|
static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *res )
|
|
|
|
{
|
|
|
|
DWORD style, old_options, new_options, change, props_mask = 0;
|
2021-03-16 09:22:47 +01:00
|
|
|
DWORD mask = ECO_AUTOWORDSELECTION | ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY |
|
|
|
|
ECO_WANTRETURN | ECO_SAVESEL | ECO_SELECTIONBAR | ECO_VERTICAL;
|
|
|
|
const DWORD host_mask = ECO_AUTOWORDSELECTION | ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY |
|
|
|
|
ECO_SAVESEL | ECO_VERTICAL;
|
|
|
|
|
2021-03-16 09:22:45 +01:00
|
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
|
|
new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 );
|
|
|
|
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
case ECOOP_SET:
|
|
|
|
new_options = value;
|
|
|
|
break;
|
|
|
|
case ECOOP_OR:
|
|
|
|
new_options |= value;
|
|
|
|
break;
|
|
|
|
case ECOOP_AND:
|
|
|
|
new_options &= value;
|
|
|
|
break;
|
|
|
|
case ECOOP_XOR:
|
|
|
|
new_options ^= value;
|
|
|
|
}
|
|
|
|
new_options &= mask;
|
|
|
|
|
|
|
|
change = (new_options ^ old_options);
|
|
|
|
|
2021-03-16 09:22:47 +01:00
|
|
|
if (change & ECO_AUTOWORDSELECTION)
|
|
|
|
{
|
|
|
|
host->props ^= TXTBIT_AUTOWORDSEL;
|
|
|
|
props_mask |= TXTBIT_AUTOWORDSEL;
|
|
|
|
}
|
2021-03-16 09:22:46 +01:00
|
|
|
if (change & ECO_AUTOVSCROLL)
|
|
|
|
{
|
|
|
|
host->scrollbars ^= WS_VSCROLL;
|
|
|
|
props_mask |= TXTBIT_SCROLLBARCHANGE;
|
|
|
|
}
|
|
|
|
if (change & ECO_AUTOHSCROLL)
|
|
|
|
{
|
|
|
|
host->scrollbars ^= WS_HSCROLL;
|
|
|
|
props_mask |= TXTBIT_SCROLLBARCHANGE;
|
|
|
|
}
|
2021-03-16 09:22:47 +01:00
|
|
|
if (change & ECO_NOHIDESEL)
|
|
|
|
{
|
|
|
|
host->props ^= TXTBIT_HIDESELECTION;
|
|
|
|
props_mask |= TXTBIT_HIDESELECTION;
|
|
|
|
}
|
2021-03-16 09:22:45 +01:00
|
|
|
if (change & ECO_READONLY)
|
|
|
|
{
|
|
|
|
host->props ^= TXTBIT_READONLY;
|
|
|
|
props_mask |= TXTBIT_READONLY;
|
|
|
|
}
|
2021-03-16 09:22:47 +01:00
|
|
|
if (change & ECO_SAVESEL)
|
|
|
|
{
|
|
|
|
host->props ^= TXTBIT_SAVESELECTION;
|
|
|
|
props_mask |= TXTBIT_SAVESELECTION;
|
|
|
|
}
|
|
|
|
if (change & ECO_VERTICAL)
|
|
|
|
{
|
|
|
|
host->props ^= TXTBIT_VERTICAL;
|
|
|
|
props_mask |= TXTBIT_VERTICAL;
|
|
|
|
}
|
2021-03-16 09:22:45 +01:00
|
|
|
|
|
|
|
if (props_mask)
|
|
|
|
ITextServices_OnTxPropertyBitsChange( host->text_srv, props_mask, host->props & props_mask );
|
|
|
|
|
|
|
|
/* Handle the rest in the editor for now */
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, EM_SETOPTIONS, op, value, res );
|
|
|
|
*res = (*res & ~host_mask) | (new_options & host_mask);
|
|
|
|
|
2021-03-16 09:22:47 +01:00
|
|
|
mask &= ~ECO_AUTOWORDSELECTION; /* doesn't correspond to a window style */
|
2021-03-16 09:22:45 +01:00
|
|
|
style = GetWindowLongW( host->window, GWL_STYLE );
|
|
|
|
style = (style & ~mask) | (*res & mask);
|
|
|
|
SetWindowLongW( host->window, GWL_STYLE, style );
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2021-03-16 09:22:49 +01:00
|
|
|
static LRESULT send_msg_filter( struct host *host, UINT msg, WPARAM *wparam, LPARAM *lparam )
|
|
|
|
{
|
|
|
|
MSGFILTER msgf;
|
|
|
|
LRESULT res;
|
|
|
|
|
|
|
|
if (!host->parent) return 0;
|
|
|
|
msgf.nmhdr.hwndFrom = host->window;
|
|
|
|
msgf.nmhdr.idFrom = GetWindowLongW( host->window, GWLP_ID );
|
|
|
|
msgf.nmhdr.code = EN_MSGFILTER;
|
|
|
|
msgf.msg = msg;
|
|
|
|
msgf.wParam = *wparam;
|
|
|
|
msgf.lParam = *lparam;
|
|
|
|
if ((res = SendMessageW( host->parent, WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf )))
|
|
|
|
return res;
|
|
|
|
*wparam = msgf.wParam;
|
|
|
|
*lparam = msgf.lParam;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-03-03 12:29:37 +01:00
|
|
|
static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
|
|
|
|
LPARAM lparam, BOOL unicode )
|
|
|
|
{
|
2021-03-08 14:45:49 +01:00
|
|
|
struct host *host;
|
2021-03-03 12:29:37 +01:00
|
|
|
ME_TextEditor *editor;
|
2021-03-16 09:22:45 +01:00
|
|
|
HRESULT hr = S_OK;
|
2021-03-03 12:29:37 +01:00
|
|
|
LRESULT res = 0;
|
|
|
|
|
|
|
|
TRACE( "enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
|
|
|
|
hwnd, msg, get_msg_name(msg), wparam, lparam, unicode );
|
|
|
|
|
2021-03-08 14:45:49 +01:00
|
|
|
host = (struct host *)GetWindowLongPtrW( hwnd, 0 );
|
|
|
|
if (!host)
|
2021-03-03 12:29:37 +01:00
|
|
|
{
|
|
|
|
if (msg == WM_NCCREATE)
|
|
|
|
{
|
|
|
|
CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam;
|
|
|
|
|
|
|
|
TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style );
|
|
|
|
return create_windowed_editor( hwnd, pcs, FALSE );
|
|
|
|
}
|
|
|
|
else return DefWindowProcW( hwnd, msg, wparam, lparam );
|
|
|
|
}
|
|
|
|
|
2021-03-16 09:22:49 +01:00
|
|
|
if ((((host->event_mask & ENM_KEYEVENTS) && msg >= WM_KEYFIRST && msg <= WM_KEYLAST) ||
|
|
|
|
((host->event_mask & ENM_MOUSEEVENTS) && msg >= WM_MOUSEFIRST && msg <= WM_MOUSELAST)) &&
|
|
|
|
send_msg_filter( host, msg, &wparam, &lparam ))
|
|
|
|
{
|
|
|
|
TRACE( "exit (filtered) hwnd %p msg %04x (%s) %lx %lx -> %lu\n",
|
|
|
|
hwnd, msg, get_msg_name(msg), wparam, lparam, res );
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2021-03-08 14:45:49 +01:00
|
|
|
editor = host->editor;
|
2021-03-03 12:29:37 +01:00
|
|
|
switch (msg)
|
|
|
|
{
|
2021-03-11 09:51:02 +01:00
|
|
|
case WM_CHAR:
|
|
|
|
{
|
|
|
|
WCHAR wc = wparam;
|
|
|
|
|
|
|
|
if (!unicode) MultiByteToWideChar( CP_ACP, 0, (char *)&wparam, 1, &wc, 1 );
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, msg, wc, lparam, &res );
|
|
|
|
break;
|
|
|
|
}
|
2021-03-11 09:51:00 +01:00
|
|
|
case WM_DESTROY:
|
|
|
|
ITextHost_Release( &host->ITextHost_iface );
|
|
|
|
return 0;
|
|
|
|
|
2021-03-03 12:29:37 +01:00
|
|
|
case WM_ERASEBKGND:
|
|
|
|
{
|
|
|
|
HDC hdc = (HDC)wparam;
|
|
|
|
RECT rc;
|
|
|
|
|
|
|
|
if (GetUpdateRect( editor->hWnd, &rc, TRUE ))
|
|
|
|
FillRect( hdc, &rc, editor->hbrBackground );
|
|
|
|
return 1;
|
|
|
|
}
|
2021-03-12 10:01:37 +01:00
|
|
|
case EM_FINDTEXT:
|
|
|
|
{
|
|
|
|
FINDTEXTW *params = (FINDTEXTW *)lparam;
|
|
|
|
FINDTEXTW new_params;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (!unicode)
|
|
|
|
{
|
|
|
|
new_params.chrg = params->chrg;
|
|
|
|
new_params.lpstrText = ME_ToUnicode( CP_ACP, (char *)params->lpstrText, &len );
|
|
|
|
params = &new_params;
|
|
|
|
}
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, EM_FINDTEXTW, wparam, (LPARAM)params, &res );
|
|
|
|
if (!unicode) ME_EndToUnicode( CP_ACP, (WCHAR *)new_params.lpstrText );
|
|
|
|
break;
|
|
|
|
}
|
2021-03-12 10:01:38 +01:00
|
|
|
case EM_FINDTEXTEX:
|
|
|
|
{
|
|
|
|
FINDTEXTEXA *paramsA = (FINDTEXTEXA *)lparam;
|
|
|
|
FINDTEXTEXW *params = (FINDTEXTEXW *)lparam;
|
|
|
|
FINDTEXTEXW new_params;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (!unicode)
|
|
|
|
{
|
|
|
|
new_params.chrg = params->chrg;
|
|
|
|
new_params.lpstrText = ME_ToUnicode( CP_ACP, (char *)params->lpstrText, &len );
|
|
|
|
params = &new_params;
|
|
|
|
}
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, EM_FINDTEXTEXW, wparam, (LPARAM)params, &res );
|
|
|
|
if (!unicode)
|
|
|
|
{
|
|
|
|
ME_EndToUnicode( CP_ACP, (WCHAR *)new_params.lpstrText );
|
|
|
|
paramsA->chrgText = params->chrgText;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-03-15 11:03:17 +01:00
|
|
|
case EM_GETLINE:
|
|
|
|
if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
|
|
|
|
else hr = get_lineA( host->text_srv, wparam, lparam, &res );
|
|
|
|
break;
|
|
|
|
|
2021-03-15 11:03:18 +01:00
|
|
|
case EM_GETSELTEXT:
|
|
|
|
{
|
|
|
|
TEXTRANGEA range;
|
|
|
|
|
|
|
|
if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ITextServices_TxSendMessage( host->text_srv, EM_EXGETSEL, 0, (LPARAM)&range.chrg, &res );
|
|
|
|
range.lpstrText = (char *)lparam;
|
|
|
|
range.lpstrText[0] = '\0';
|
|
|
|
hr = get_text_rangeA( host, &range, &res );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2021-03-16 09:22:45 +01:00
|
|
|
case EM_GETOPTIONS:
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, EM_GETOPTIONS, 0, 0, &res );
|
|
|
|
if (host->props & TXTBIT_READONLY) res |= ECO_READONLY;
|
2021-03-16 09:22:47 +01:00
|
|
|
if (!(host->props & TXTBIT_HIDESELECTION)) res |= ECO_NOHIDESEL;
|
|
|
|
if (host->props & TXTBIT_SAVESELECTION) res |= ECO_SAVESEL;
|
|
|
|
if (host->props & TXTBIT_AUTOWORDSEL) res |= ECO_AUTOWORDSELECTION;
|
|
|
|
if (host->props & TXTBIT_VERTICAL) res |= ECO_VERTICAL;
|
2021-03-16 09:22:46 +01:00
|
|
|
if (host->scrollbars & ES_AUTOHSCROLL) res |= ECO_AUTOHSCROLL;
|
|
|
|
if (host->scrollbars & ES_AUTOVSCROLL) res |= ECO_AUTOVSCROLL;
|
2021-03-16 09:22:45 +01:00
|
|
|
break;
|
|
|
|
|
2021-03-12 10:01:35 +01:00
|
|
|
case WM_GETTEXT:
|
|
|
|
{
|
|
|
|
GETTEXTEX params;
|
|
|
|
|
|
|
|
params.cb = wparam * (unicode ? sizeof(WCHAR) : sizeof(CHAR));
|
|
|
|
params.flags = GT_USECRLF;
|
|
|
|
params.codepage = unicode ? CP_UNICODE : CP_ACP;
|
|
|
|
params.lpDefaultChar = NULL;
|
|
|
|
params.lpUsedDefChar = NULL;
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTEX, (WPARAM)¶ms, lparam, &res );
|
|
|
|
break;
|
|
|
|
}
|
2021-03-12 10:01:34 +01:00
|
|
|
case WM_GETTEXTLENGTH:
|
|
|
|
{
|
|
|
|
GETTEXTLENGTHEX params;
|
|
|
|
|
|
|
|
params.flags = GTL_CLOSE | (host->emulate_10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS;
|
|
|
|
params.codepage = unicode ? CP_UNICODE : CP_ACP;
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, EM_GETTEXTLENGTHEX, (WPARAM)¶ms, 0, &res );
|
|
|
|
break;
|
|
|
|
}
|
2021-03-12 10:01:36 +01:00
|
|
|
case EM_GETTEXTRANGE:
|
|
|
|
if (unicode) hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
|
|
|
|
else hr = get_text_rangeA( host, (TEXTRANGEA *)lparam, &res );
|
|
|
|
break;
|
|
|
|
|
2021-03-03 12:29:37 +01:00
|
|
|
case WM_PAINT:
|
|
|
|
{
|
|
|
|
HDC hdc;
|
|
|
|
RECT rc;
|
|
|
|
PAINTSTRUCT ps;
|
|
|
|
HBRUSH old_brush;
|
|
|
|
|
|
|
|
update_caret( editor );
|
|
|
|
hdc = BeginPaint( editor->hWnd, &ps );
|
|
|
|
if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE))
|
|
|
|
ME_SendOldNotify( editor, EN_UPDATE );
|
|
|
|
old_brush = SelectObject( hdc, editor->hbrBackground );
|
|
|
|
|
|
|
|
/* Erase area outside of the formatting rectangle */
|
|
|
|
if (ps.rcPaint.top < editor->rcFormat.top)
|
|
|
|
{
|
|
|
|
rc = ps.rcPaint;
|
|
|
|
rc.bottom = editor->rcFormat.top;
|
|
|
|
PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
|
|
|
|
ps.rcPaint.top = editor->rcFormat.top;
|
|
|
|
}
|
|
|
|
if (ps.rcPaint.bottom > editor->rcFormat.bottom)
|
|
|
|
{
|
|
|
|
rc = ps.rcPaint;
|
|
|
|
rc.top = editor->rcFormat.bottom;
|
|
|
|
PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
|
|
|
|
ps.rcPaint.bottom = editor->rcFormat.bottom;
|
|
|
|
}
|
|
|
|
if (ps.rcPaint.left < editor->rcFormat.left)
|
|
|
|
{
|
|
|
|
rc = ps.rcPaint;
|
|
|
|
rc.right = editor->rcFormat.left;
|
|
|
|
PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
|
|
|
|
ps.rcPaint.left = editor->rcFormat.left;
|
|
|
|
}
|
|
|
|
if (ps.rcPaint.right > editor->rcFormat.right)
|
|
|
|
{
|
|
|
|
rc = ps.rcPaint;
|
|
|
|
rc.left = editor->rcFormat.right;
|
|
|
|
PatBlt( hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY );
|
|
|
|
ps.rcPaint.right = editor->rcFormat.right;
|
|
|
|
}
|
|
|
|
|
|
|
|
ME_PaintContent( editor, hdc, &ps.rcPaint );
|
|
|
|
SelectObject( hdc, old_brush );
|
|
|
|
EndPaint( editor->hWnd, &ps );
|
|
|
|
return 0;
|
|
|
|
}
|
2021-03-11 09:51:03 +01:00
|
|
|
case EM_REPLACESEL:
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
LONG codepage = unicode ? CP_UNICODE : CP_ACP;
|
|
|
|
WCHAR *text = ME_ToUnicode( codepage, (void *)lparam, &len );
|
|
|
|
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, (LPARAM)text, &res );
|
|
|
|
ME_EndToUnicode( codepage, text );
|
|
|
|
res = len;
|
|
|
|
break;
|
|
|
|
}
|
2021-03-16 09:22:49 +01:00
|
|
|
case EM_SETEVENTMASK:
|
|
|
|
host->event_mask = lparam;
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, lparam, &res );
|
|
|
|
break;
|
|
|
|
|
2021-03-03 12:29:37 +01:00
|
|
|
case EM_SETOPTIONS:
|
2021-03-16 09:22:45 +01:00
|
|
|
hr = set_options( host, wparam, lparam, &res );
|
|
|
|
break;
|
|
|
|
|
2021-03-03 12:29:37 +01:00
|
|
|
case EM_SETREADONLY:
|
|
|
|
{
|
2021-03-15 11:03:20 +01:00
|
|
|
DWORD op = wparam ? ECOOP_OR : ECOOP_AND;
|
|
|
|
DWORD mask = wparam ? ECO_READONLY : ~ECO_READONLY;
|
2021-03-03 12:29:37 +01:00
|
|
|
|
2021-03-15 11:03:20 +01:00
|
|
|
SendMessageW( hwnd, EM_SETOPTIONS, op, mask );
|
|
|
|
return 1;
|
2021-03-03 12:29:37 +01:00
|
|
|
}
|
2021-03-11 09:51:01 +01:00
|
|
|
case WM_SETTEXT:
|
|
|
|
{
|
|
|
|
char *textA = (char *)lparam;
|
|
|
|
WCHAR *text = (WCHAR *)lparam;
|
|
|
|
int len;
|
|
|
|
|
|
|
|
if (!unicode && textA && strncmp( textA, "{\\rtf", 5 ) && strncmp( textA, "{\\urtf", 6 ))
|
|
|
|
text = ME_ToUnicode( CP_ACP, textA, &len );
|
|
|
|
hr = ITextServices_TxSendMessage( host->text_srv, msg, wparam, (LPARAM)text, &res );
|
|
|
|
if (text != (WCHAR *)lparam) ME_EndToUnicode( CP_ACP, text );
|
|
|
|
break;
|
|
|
|
}
|
2021-03-16 09:22:46 +01:00
|
|
|
case EM_SHOWSCROLLBAR:
|
|
|
|
{
|
|
|
|
DWORD mask = 0, new;
|
|
|
|
|
|
|
|
if (wparam == SB_HORZ) mask = WS_HSCROLL;
|
|
|
|
else if (wparam == SB_VERT) mask = WS_VSCROLL;
|
|
|
|
else if (wparam == SB_BOTH) mask = WS_HSCROLL | WS_VSCROLL;
|
|
|
|
|
|
|
|
if (mask)
|
|
|
|
{
|
|
|
|
new = lparam ? mask : 0;
|
|
|
|
if ((host->scrollbars & mask) != new)
|
|
|
|
{
|
|
|
|
host->scrollbars &= ~mask;
|
|
|
|
host->scrollbars |= new;
|
|
|
|
ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_SCROLLBARCHANGE, 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
res = 0;
|
|
|
|
break;
|
|
|
|
}
|
2021-03-03 12:29:37 +01:00
|
|
|
default:
|
|
|
|
res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hr == S_FALSE)
|
|
|
|
res = DefWindowProcW( hwnd, msg, wparam, lparam );
|
|
|
|
|
|
|
|
TRACE( "exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n",
|
|
|
|
hwnd, msg, get_msg_name(msg), wparam, lparam, unicode, res );
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT WINAPI RichEditWndProcW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|
|
|
{
|
|
|
|
BOOL unicode = TRUE;
|
|
|
|
|
|
|
|
/* Under Win9x RichEdit20W returns ANSI strings, see the tests. */
|
|
|
|
if (msg == WM_GETTEXT && (GetVersion() & 0x80000000))
|
|
|
|
unicode = FALSE;
|
|
|
|
|
|
|
|
return RichEditWndProc_common( hwnd, msg, wparam, lparam, unicode );
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT WINAPI RichEditWndProcA( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|
|
|
{
|
|
|
|
return RichEditWndProc_common( hwnd, msg, wparam, lparam, FALSE );
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
|
|
* RichEditANSIWndProc (RICHED20.10)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI RichEditANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|
|
|
{
|
|
|
|
return RichEditWndProcA( hwnd, msg, wparam, lparam );
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
|
|
* RichEdit10ANSIWndProc (RICHED20.9)
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI RichEdit10ANSIWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|
|
|
{
|
|
|
|
if (msg == WM_NCCREATE && !GetWindowLongPtrW( hwnd, 0 ))
|
|
|
|
{
|
|
|
|
CREATESTRUCTW *pcs = (CREATESTRUCTW *)lparam;
|
|
|
|
|
|
|
|
TRACE( "WM_NCCREATE: hwnd %p style 0x%08x\n", hwnd, pcs->style );
|
|
|
|
return create_windowed_editor( hwnd, pcs, TRUE );
|
|
|
|
}
|
|
|
|
return RichEditANSIWndProc( hwnd, msg, wparam, lparam );
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT WINAPI REComboWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|
|
|
{
|
|
|
|
/* FIXME: Not implemented */
|
|
|
|
TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n",
|
|
|
|
hwnd, msg, get_msg_name( msg ), wparam, lparam );
|
|
|
|
return DefWindowProcW( hwnd, msg, wparam, lparam );
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT WINAPI REListWndProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
|
|
|
|
{
|
|
|
|
/* FIXME: Not implemented */
|
|
|
|
TRACE( "hwnd %p msg %04x (%s) %08lx %08lx\n",
|
|
|
|
hwnd, msg, get_msg_name( msg ), wparam, lparam );
|
|
|
|
return DefWindowProcW( hwnd, msg, wparam, lparam );
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************
|
|
|
|
* REExtendedRegisterClass (RICHED20.8)
|
|
|
|
*
|
|
|
|
* FIXME undocumented
|
|
|
|
* Need to check for errors and implement controls and callbacks
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI REExtendedRegisterClass( void )
|
|
|
|
{
|
|
|
|
WNDCLASSW wc;
|
|
|
|
UINT result;
|
|
|
|
|
|
|
|
FIXME( "semi stub\n" );
|
|
|
|
wc.cbClsExtra = 0;
|
|
|
|
wc.cbWndExtra = 4;
|
|
|
|
wc.hInstance = NULL;
|
|
|
|
wc.hIcon = NULL;
|
|
|
|
wc.hCursor = NULL;
|
|
|
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
|
|
wc.lpszMenuName = NULL;
|
|
|
|
|
|
|
|
if (!listbox_registered)
|
|
|
|
{
|
|
|
|
wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS;
|
|
|
|
wc.lpfnWndProc = REListWndProc;
|
|
|
|
wc.lpszClassName = L"REListBox20W";
|
|
|
|
if (RegisterClassW( &wc )) listbox_registered = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!combobox_registered)
|
|
|
|
{
|
|
|
|
wc.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
|
|
|
|
wc.lpfnWndProc = REComboWndProc;
|
|
|
|
wc.lpszClassName = L"REComboBox20W";
|
|
|
|
if (RegisterClassW( &wc )) combobox_registered = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = 0;
|
|
|
|
if (listbox_registered) result += 1;
|
|
|
|
if (combobox_registered) result += 2;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL register_classes( HINSTANCE instance )
|
|
|
|
{
|
|
|
|
WNDCLASSW wcW;
|
|
|
|
WNDCLASSA wcA;
|
|
|
|
|
|
|
|
wcW.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
|
|
|
|
wcW.lpfnWndProc = RichEditWndProcW;
|
|
|
|
wcW.cbClsExtra = 0;
|
|
|
|
wcW.cbWndExtra = sizeof(ME_TextEditor *);
|
|
|
|
wcW.hInstance = NULL; /* hInstance would register DLL-local class */
|
|
|
|
wcW.hIcon = NULL;
|
|
|
|
wcW.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM );
|
|
|
|
wcW.hbrBackground = GetStockObject( NULL_BRUSH );
|
|
|
|
wcW.lpszMenuName = NULL;
|
|
|
|
|
|
|
|
if (!(GetVersion() & 0x80000000))
|
|
|
|
{
|
|
|
|
wcW.lpszClassName = RICHEDIT_CLASS20W;
|
|
|
|
if (!RegisterClassW( &wcW )) return FALSE;
|
|
|
|
wcW.lpszClassName = MSFTEDIT_CLASS;
|
|
|
|
if (!RegisterClassW( &wcW )) return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* WNDCLASSA/W have the same layout */
|
|
|
|
wcW.lpszClassName = (LPCWSTR)"RichEdit20W";
|
|
|
|
if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE;
|
|
|
|
wcW.lpszClassName = (LPCWSTR)"RichEdit50W";
|
|
|
|
if (!RegisterClassA( (WNDCLASSA *)&wcW )) return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
|
|
|
|
wcA.lpfnWndProc = RichEditWndProcA;
|
|
|
|
wcA.cbClsExtra = 0;
|
|
|
|
wcA.cbWndExtra = sizeof(ME_TextEditor *);
|
|
|
|
wcA.hInstance = NULL; /* hInstance would register DLL-local class */
|
|
|
|
wcA.hIcon = NULL;
|
|
|
|
wcA.hCursor = LoadCursorW( NULL, (LPWSTR)IDC_IBEAM );
|
|
|
|
wcA.hbrBackground = GetStockObject(NULL_BRUSH);
|
|
|
|
wcA.lpszMenuName = NULL;
|
|
|
|
wcA.lpszClassName = RICHEDIT_CLASS20A;
|
|
|
|
if (!RegisterClassA( &wcA )) return FALSE;
|
|
|
|
wcA.lpszClassName = "RichEdit50A";
|
|
|
|
if (!RegisterClassA( &wcA )) return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI DllMain( HINSTANCE instance, DWORD reason, void *reserved )
|
|
|
|
{
|
|
|
|
switch (reason)
|
|
|
|
{
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
DisableThreadLibraryCalls( instance );
|
|
|
|
me_heap = HeapCreate( 0, 0x10000, 0 );
|
|
|
|
if (!register_classes( instance )) return FALSE;
|
|
|
|
cursor_reverse = LoadCursorW( instance, MAKEINTRESOURCEW( OCR_REVERSE ) );
|
|
|
|
LookupInit();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
if (reserved) break;
|
|
|
|
UnregisterClassW( RICHEDIT_CLASS20W, 0 );
|
|
|
|
UnregisterClassW( MSFTEDIT_CLASS, 0 );
|
|
|
|
UnregisterClassA( RICHEDIT_CLASS20A, 0 );
|
|
|
|
UnregisterClassA( "RichEdit50A", 0 );
|
|
|
|
if (listbox_registered) UnregisterClassW( L"REListBox20W", 0 );
|
|
|
|
if (combobox_registered) UnregisterClassW( L"REComboBox20W", 0 );
|
|
|
|
LookupCleanup();
|
|
|
|
HeapDestroy( me_heap );
|
|
|
|
release_typelib();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|