user32: Turn the edit winproc into a Wow handler.

This commit is contained in:
Alexandre Julliard 2009-12-15 13:19:03 +01:00
parent 9f12c730e1
commit 57e5c8f67a
4 changed files with 372 additions and 397 deletions

View File

@ -63,6 +63,7 @@ struct wow_handlers16
{
LRESULT (*button_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*combo_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*edit_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*listbox_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
};
@ -70,6 +71,7 @@ struct wow_handlers32
{
LRESULT (*button_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*combo_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*edit_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
LRESULT (*listbox_proc)(HWND,UINT,WPARAM,LPARAM,BOOL);
};
@ -77,6 +79,7 @@ extern struct wow_handlers16 wow_handlers DECLSPEC_HIDDEN;
extern LRESULT ButtonWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT ComboWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT EditWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern LRESULT ListBoxWndProc_common(HWND,UINT,WPARAM,LPARAM,BOOL) DECLSPEC_HIDDEN;
extern void register_wow_handlers(void) DECLSPEC_HIDDEN;

View File

@ -249,90 +249,6 @@ static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc)
}
/**********************************************************************
* Support for word break proc thunks
*/
#define MAX_THUNKS 32
#include <pshpack1.h>
static struct word_break_thunk
{
BYTE popl_eax; /* popl %eax (return address) */
BYTE pushl_proc16; /* pushl proc16 */
EDITWORDBREAKPROC16 proc16;
BYTE pushl_eax; /* pushl %eax */
BYTE jmp; /* ljmp call_word_break_proc16 */
DWORD callback;
} *word_break_thunks;
#include <poppack.h>
/**********************************************************************
* call_word_break_proc16
*/
static INT16 CALLBACK call_word_break_proc16( SEGPTR proc16, LPSTR text, INT index, INT count, INT action )
{
SEGPTR segptr;
WORD args[5];
DWORD result;
segptr = MapLS( text );
args[4] = SELECTOROF(segptr);
args[3] = OFFSETOF(segptr);
args[2] = index;
args[1] = count;
args[0] = action;
WOWCallback16Ex( proc16, WCB16_PASCAL, sizeof(args), args, &result );
UnMapLS( segptr );
return LOWORD(result);
}
/******************************************************************
* add_word_break_thunk
*/
static struct word_break_thunk *add_word_break_thunk( EDITWORDBREAKPROC16 proc16 )
{
struct word_break_thunk *thunk;
if (!word_break_thunks)
{
word_break_thunks = VirtualAlloc( NULL, MAX_THUNKS * sizeof(*thunk),
MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if (!word_break_thunks) return NULL;
for (thunk = word_break_thunks; thunk < &word_break_thunks[MAX_THUNKS]; thunk++)
{
thunk->popl_eax = 0x58; /* popl %eax */
thunk->pushl_proc16 = 0x68; /* pushl proc16 */
thunk->pushl_eax = 0x50; /* pushl %eax */
thunk->jmp = 0xe9; /* jmp call_word_break_proc16 */
thunk->callback = (char *)call_word_break_proc16 - (char *)(&thunk->callback + 1);
}
}
for (thunk = word_break_thunks; thunk < &word_break_thunks[MAX_THUNKS]; thunk++)
if (thunk->proc16 == proc16) return thunk;
for (thunk = word_break_thunks; thunk < &word_break_thunks[MAX_THUNKS]; thunk++)
{
if (thunk->proc16) continue;
thunk->proc16 = proc16;
return thunk;
}
FIXME("Out of word break thunks\n");
return NULL;
}
/******************************************************************
* get_word_break_thunk
*/
static EDITWORDBREAKPROC16 get_word_break_thunk( EDITWORDBREAKPROCA proc )
{
struct word_break_thunk *thunk = (struct word_break_thunk *)proc;
if (word_break_thunks && thunk >= word_break_thunks && thunk < &word_break_thunks[MAX_THUNKS])
return thunk->proc16;
return NULL;
}
/*********************************************************************
*
* EDIT_WordBreakProc
@ -1174,66 +1090,6 @@ static inline void text_buffer_changed(EDITSTATE *es)
es->text_length = (UINT)-1;
}
#define GWW_HANDLE16 sizeof(EDITSTATE*)
/*********************************************************************
* EDIT_LockBuffer16
*/
static void EDIT_LockBuffer16(EDITSTATE *es)
{
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HLOCAL16 hloc16 = GetWindowWord( es->hwndSelf, GWW_HANDLE16 );
HANDLE16 oldDS;
HLOCAL hloc32;
UINT size;
if (!hloc16) return;
if (!(hloc32 = es->hloc32A)) return;
oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
size = LocalSize16(hloc16);
if (LocalReAlloc( hloc32, size, LMEM_MOVEABLE ))
{
char *text = MapSL( LocalLock16( hloc16 ));
char *dest = LocalLock( hloc32 );
memcpy( dest, text, size );
LocalUnlock( hloc32 );
LocalUnlock16( hloc16 );
}
stack16->ds = oldDS;
}
/*********************************************************************
* EDIT_UnlockBuffer16
*
*/
static void EDIT_UnlockBuffer16(EDITSTATE *es)
{
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HLOCAL16 hloc16 = GetWindowWord( es->hwndSelf, GWW_HANDLE16 );
HANDLE16 oldDS;
HLOCAL hloc32;
UINT size;
if (!hloc16) return;
if (!(hloc32 = es->hloc32A)) return;
size = LocalSize( hloc32 );
oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
if (LocalReAlloc16( hloc16, size, LMEM_MOVEABLE ))
{
char *text = LocalLock( hloc32 );
char *dest = MapSL( LocalLock16( hloc16 ));
memcpy( dest, text, size );
LocalUnlock( hloc32 );
LocalUnlock16( hloc16 );
}
stack16->ds = oldDS;
}
/*********************************************************************
*
* EDIT_LockBuffer
@ -1256,8 +1112,6 @@ static void EDIT_LockBuffer(EDITSTATE *es)
if(!es->hloc32W) return;
EDIT_LockBuffer16(es);
if(es->hloc32A)
{
CHAR *textA = LocalLock(es->hloc32A);
@ -1345,7 +1199,6 @@ static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force)
LocalUnlock(es->hloc32W);
es->text = NULL;
EDIT_UnlockBuffer16(es);
}
else {
ERR("no buffer ... please report\n");
@ -2452,73 +2305,6 @@ static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es)
}
/*********************************************************************
*
* EM_GETHANDLE16
*
* Hopefully this won't fire back at us.
* We always start with a buffer in 32 bit linear memory.
* However, with this message a 16 bit application requests
* a handle of 16 bit local heap memory, where it expects to find
* the text.
* It's a pitty that from this moment on we have to use this
* local heap, because applications may rely on the handle
* in the future.
*
* In this function we'll try to switch to local heap.
*/
static HLOCAL16 EDIT_EM_GetHandle16( HWND hwnd )
{
CHAR *textA;
UINT alloc_size;
HLOCAL hloc;
STACK16FRAME* stack16;
HANDLE16 oldDS;
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
if (hloc16) return hloc16;
if (!(hloc = (HLOCAL)SendMessageA( hwnd, EM_GETHANDLE, 0, 0 ))) return 0;
alloc_size = LocalSize( hloc );
stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
if (!LocalHeapSize16()) {
if (!LocalInit16(stack16->ds, 0, GlobalSize16(stack16->ds))) {
ERR("could not initialize local heap\n");
goto done;
}
TRACE("local heap initialized\n");
}
TRACE("Allocating 16-bit ANSI alias buffer\n");
if (!(hloc16 = LocalAlloc16(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size))) {
ERR("could not allocate new 16 bit buffer\n");
goto done;
}
if (!(textA = MapSL(LocalLock16( hloc16)))) {
ERR("could not lock new 16 bit buffer\n");
LocalFree16(hloc16);
hloc16 = 0;
goto done;
}
memcpy( textA, LocalLock( hloc ), alloc_size );
LocalUnlock( hloc );
LocalUnlock16( hloc16 );
SetWindowWord( hwnd, GWW_HANDLE16, hloc16 );
TRACE("Returning %04X, LocalSize() = %d\n", hloc16, alloc_size);
done:
stack16->ds = oldDS;
return hloc16;
}
/*********************************************************************
*
* EM_GETLINE
@ -2865,46 +2651,6 @@ static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc)
}
/*********************************************************************
*
* EM_SETHANDLE16
*
* FIXME: ES_LOWERCASE, ES_UPPERCASE, ES_OEMCONVERT, ES_NUMBER ???
*
*/
static void EDIT_EM_SetHandle16( HWND hwnd, HLOCAL16 hloc16 )
{
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HINSTANCE16 hInstance = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
HANDLE16 oldDS = stack16->ds;
HLOCAL hloc32;
INT count;
CHAR *text;
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & ES_MULTILINE)) return;
if (!hloc16) {
WARN("called with NULL handle\n");
return;
}
stack16->ds = hInstance;
count = LocalSize16(hloc16);
text = MapSL(LocalLock16(hloc16));
if ((hloc32 = LocalAlloc(LMEM_MOVEABLE, count)))
{
memcpy( LocalLock(hloc32), text, count );
LocalUnlock(hloc32);
LocalUnlock16(hloc16);
SetWindowWord( hwnd, GWW_HANDLE16, hloc16 );
}
stack16->ds = oldDS;
if (hloc32) SendMessageA( hwnd, EM_SETHANDLE, (WPARAM)hloc32, 0 );
else ERR("Could not allocate new buffer\n");
}
/*********************************************************************
*
* EM_SETLIMITTEXT
@ -4651,7 +4397,6 @@ static LRESULT EDIT_WM_Create(EDITSTATE *es, LPCWSTR name)
static LRESULT EDIT_WM_NCDestroy(EDITSTATE *es)
{
LINEDEF *pc, *pp;
HLOCAL16 hloc16 = GetWindowWord( es->hwndSelf, GWW_HANDLE16 );
if (es->hloc32W) {
LocalFree(es->hloc32W);
@ -4659,17 +4404,6 @@ static LRESULT EDIT_WM_NCDestroy(EDITSTATE *es)
if (es->hloc32A) {
LocalFree(es->hloc32A);
}
if (hloc16) {
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HANDLE16 oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( es->hwndSelf, GWLP_HINSTANCE );
while (LocalUnlock16(hloc16)) ;
LocalFree16(hloc16);
stack16->ds = oldDS;
SetWindowWord( es->hwndSelf, GWW_HANDLE16, 0 );
}
pc = es->first_line_def;
while (pc)
{
@ -4701,8 +4435,7 @@ static inline LRESULT DefWindowProcT(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
* The messages are in the order of the actual integer values
* (which can be found in include/windows.h)
*/
static LRESULT EditWndProc_common( HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam, BOOL unicode )
LRESULT EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode )
{
EDITSTATE *es = (EDITSTATE *)GetWindowLongPtrW( hwnd, 0 );
LRESULT result = 0;
@ -5242,140 +4975,13 @@ static LRESULT EditWndProc_common( HWND hwnd, UINT msg,
}
/*********************************************************************
* EditWndProc_wrapper16
*/
static LRESULT EditWndProc_wrapper16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode )
{
static const UINT msg16_offset = EM_GETSEL16 - EM_GETSEL;
LRESULT result;
switch (msg)
{
case EM_SCROLL16:
case EM_SCROLLCARET16:
case EM_GETMODIFY16:
case EM_SETMODIFY16:
case EM_GETLINECOUNT16:
case EM_GETTHUMB16:
case EM_LINELENGTH16:
case EM_LIMITTEXT16:
case EM_CANUNDO16:
case EM_UNDO16:
case EM_FMTLINES16:
case EM_LINEFROMCHAR16:
case EM_SETPASSWORDCHAR16:
case EM_EMPTYUNDOBUFFER16:
case EM_SETREADONLY16:
case EM_GETPASSWORDCHAR16:
/* these messages missing from specs */
case WM_USER+15:
case WM_USER+16:
case WM_USER+19:
case WM_USER+26:
msg -= msg16_offset;
break;
case EM_GETSEL16:
wParam = 0;
lParam = 0;
msg -= msg16_offset;
break;
case EM_REPLACESEL16:
case EM_GETLINE16:
lParam = (LPARAM)MapSL(lParam);
msg -= msg16_offset;
break;
case EM_LINESCROLL16:
wParam = (INT)(SHORT)HIWORD(lParam);
lParam = (INT)(SHORT)LOWORD(lParam);
msg -= msg16_offset;
break;
case EM_LINEINDEX16:
if ((INT16)wParam == -1) wParam = (WPARAM)-1;
msg -= msg16_offset;
break;
case EM_SETSEL16:
if ((short)LOWORD(lParam) == -1)
{
wParam = -1;
lParam = 0;
}
else
{
wParam = LOWORD(lParam);
lParam = HIWORD(lParam);
}
msg -= msg16_offset;
break;
case EM_GETRECT16:
if (lParam)
{
RECT rect;
RECT16 *r16 = MapSL(lParam);
EditWndProc_common( hwnd, msg - msg16_offset, wParam, (LPARAM)&rect, FALSE );
r16->left = rect.left;
r16->top = rect.top;
r16->right = rect.right;
r16->bottom = rect.bottom;
}
return 0;
case EM_SETRECT16:
case EM_SETRECTNP16:
if (lParam)
{
RECT rect;
RECT16 *r16 = MapSL(lParam);
rect.left = r16->left;
rect.top = r16->top;
rect.right = r16->right;
rect.bottom = r16->bottom;
EditWndProc_common( hwnd, msg - msg16_offset, wParam, (LPARAM)&rect, FALSE );
}
return 0;
case EM_SETHANDLE16:
EDIT_EM_SetHandle16( hwnd, (HLOCAL16)wParam );
break;
case EM_GETHANDLE16:
result = EDIT_EM_GetHandle16( hwnd );
break;
case EM_SETTABSTOPS16:
{
INT16 *tabs16 = MapSL(lParam);
INT i, count = wParam, *tabs = NULL;
if (count > 0)
{
if (!(tabs = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*tabs) ))) return 0;
for (i = 0; i < count; i++) tabs[i] = tabs16[i];
}
result = EditWndProc_common( hwnd, msg - msg16_offset, count, (LPARAM)tabs, FALSE );
HeapFree( GetProcessHeap(), 0, tabs );
return result;
}
case EM_GETFIRSTVISIBLELINE16:
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & ES_MULTILINE)) return 0;
msg -= msg16_offset;
break;
case EM_SETWORDBREAKPROC16:
{
struct word_break_thunk *thunk = add_word_break_thunk( (EDITWORDBREAKPROC16)lParam );
return EditWndProc_common( hwnd, EM_SETWORDBREAKPROC, wParam, (LPARAM)thunk, FALSE );
}
case EM_GETWORDBREAKPROC16:
result = EditWndProc_common( hwnd, EM_GETWORDBREAKPROC, wParam, lParam, FALSE );
return (LRESULT)get_word_break_thunk( (EDITWORDBREAKPROCA)result );
default:
return EditWndProc_common( hwnd, msg, wParam, lParam, unicode );
}
return EditWndProc_common( hwnd, msg, wParam, lParam, FALSE );
}
/*********************************************************************
*
* EditWndProc (USER32.@)
*/
LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return EditWndProc_wrapper16(hWnd, uMsg, wParam, lParam, FALSE);
return wow_handlers.edit_proc(hWnd, uMsg, wParam, lParam, FALSE);
}
/*********************************************************************
@ -5384,7 +4990,7 @@ LRESULT WINAPI EditWndProcA(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
*/
static LRESULT WINAPI EditWndProcW(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
return EditWndProc_wrapper16(hWnd, uMsg, wParam, lParam, TRUE);
return wow_handlers.edit_proc(hWnd, uMsg, wParam, lParam, TRUE);
}
/*********************************************************************

View File

@ -88,6 +88,91 @@ static LRESULT defdlg_proc_callback( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
}
/**********************************************************************
* Support for Edit word break proc thunks
*/
#define MAX_THUNKS 32
#include <pshpack1.h>
static struct word_break_thunk
{
BYTE popl_eax; /* popl %eax (return address) */
BYTE pushl_proc16; /* pushl proc16 */
EDITWORDBREAKPROC16 proc16;
BYTE pushl_eax; /* pushl %eax */
BYTE jmp; /* ljmp call_word_break_proc16 */
DWORD callback;
} *word_break_thunks;
#include <poppack.h>
/**********************************************************************
* call_word_break_proc16
*/
static INT16 CALLBACK call_word_break_proc16( SEGPTR proc16, LPSTR text, INT index, INT count, INT action )
{
SEGPTR segptr;
WORD args[5];
DWORD result;
segptr = MapLS( text );
args[4] = SELECTOROF(segptr);
args[3] = OFFSETOF(segptr);
args[2] = index;
args[1] = count;
args[0] = action;
WOWCallback16Ex( proc16, WCB16_PASCAL, sizeof(args), args, &result );
UnMapLS( segptr );
return LOWORD(result);
}
/******************************************************************
* add_word_break_thunk
*/
static struct word_break_thunk *add_word_break_thunk( EDITWORDBREAKPROC16 proc16 )
{
struct word_break_thunk *thunk;
if (!word_break_thunks)
{
word_break_thunks = VirtualAlloc( NULL, MAX_THUNKS * sizeof(*thunk),
MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if (!word_break_thunks) return NULL;
for (thunk = word_break_thunks; thunk < &word_break_thunks[MAX_THUNKS]; thunk++)
{
thunk->popl_eax = 0x58; /* popl %eax */
thunk->pushl_proc16 = 0x68; /* pushl proc16 */
thunk->pushl_eax = 0x50; /* pushl %eax */
thunk->jmp = 0xe9; /* jmp call_word_break_proc16 */
thunk->callback = (char *)call_word_break_proc16 - (char *)(&thunk->callback + 1);
}
}
for (thunk = word_break_thunks; thunk < &word_break_thunks[MAX_THUNKS]; thunk++)
if (thunk->proc16 == proc16) return thunk;
for (thunk = word_break_thunks; thunk < &word_break_thunks[MAX_THUNKS]; thunk++)
{
if (thunk->proc16) continue;
thunk->proc16 = proc16;
return thunk;
}
FIXME("Out of word break thunks\n");
return NULL;
}
/******************************************************************
* get_word_break_thunk
*/
static EDITWORDBREAKPROC16 get_word_break_thunk( EDITWORDBREAKPROCA proc )
{
struct word_break_thunk *thunk = (struct word_break_thunk *)proc;
if (word_break_thunks && thunk >= word_break_thunks && thunk < &word_break_thunks[MAX_THUNKS])
return thunk->proc16;
return NULL;
}
/***********************************************************************
* SendMessage (USER.111)
*/
@ -684,6 +769,284 @@ static LRESULT combo_proc16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
}
#define GWW_HANDLE16 sizeof(void*)
static void edit_lock_buffer( HWND hwnd )
{
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
HANDLE16 oldDS;
HLOCAL hloc32;
UINT size;
if (!hloc16) return;
if (!(hloc32 = (HLOCAL)wow_handlers32.edit_proc( hwnd, EM_GETHANDLE, 0, 0, FALSE ))) return;
oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
size = LocalSize16(hloc16);
if (LocalReAlloc( hloc32, size, LMEM_MOVEABLE ))
{
char *text = MapSL( LocalLock16( hloc16 ));
char *dest = LocalLock( hloc32 );
memcpy( dest, text, size );
LocalUnlock( hloc32 );
LocalUnlock16( hloc16 );
}
stack16->ds = oldDS;
}
static void edit_unlock_buffer( HWND hwnd )
{
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
HANDLE16 oldDS;
HLOCAL hloc32;
UINT size;
if (!hloc16) return;
if (!(hloc32 = (HLOCAL)wow_handlers32.edit_proc( hwnd, EM_GETHANDLE, 0, 0, FALSE ))) return;
size = LocalSize( hloc32 );
oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
if (LocalReAlloc16( hloc16, size, LMEM_MOVEABLE ))
{
char *text = LocalLock( hloc32 );
char *dest = MapSL( LocalLock16( hloc16 ));
memcpy( dest, text, size );
LocalUnlock( hloc32 );
LocalUnlock16( hloc16 );
}
stack16->ds = oldDS;
}
static HLOCAL16 edit_get_handle( HWND hwnd )
{
CHAR *textA;
UINT alloc_size;
HLOCAL hloc;
STACK16FRAME* stack16;
HANDLE16 oldDS;
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
if (hloc16) return hloc16;
if (!(hloc = (HLOCAL)wow_handlers32.edit_proc( hwnd, EM_GETHANDLE, 0, 0, FALSE ))) return 0;
alloc_size = LocalSize( hloc );
stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
if (!LocalHeapSize16())
{
if (!LocalInit16(stack16->ds, 0, GlobalSize16(stack16->ds)))
{
ERR("could not initialize local heap\n");
goto done;
}
}
if (!(hloc16 = LocalAlloc16(LMEM_MOVEABLE | LMEM_ZEROINIT, alloc_size)))
{
ERR("could not allocate new 16 bit buffer\n");
goto done;
}
if (!(textA = MapSL(LocalLock16( hloc16))))
{
ERR("could not lock new 16 bit buffer\n");
LocalFree16(hloc16);
hloc16 = 0;
goto done;
}
memcpy( textA, LocalLock( hloc ), alloc_size );
LocalUnlock( hloc );
LocalUnlock16( hloc16 );
SetWindowWord( hwnd, GWW_HANDLE16, hloc16 );
done:
stack16->ds = oldDS;
return hloc16;
}
static void edit_set_handle( HWND hwnd, HLOCAL16 hloc16 )
{
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HINSTANCE16 hInstance = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
HANDLE16 oldDS = stack16->ds;
HLOCAL hloc32;
INT count;
CHAR *text;
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & ES_MULTILINE)) return;
if (!hloc16) return;
stack16->ds = hInstance;
count = LocalSize16(hloc16);
text = MapSL(LocalLock16(hloc16));
if ((hloc32 = LocalAlloc(LMEM_MOVEABLE, count)))
{
memcpy( LocalLock(hloc32), text, count );
LocalUnlock(hloc32);
LocalUnlock16(hloc16);
SetWindowWord( hwnd, GWW_HANDLE16, hloc16 );
}
stack16->ds = oldDS;
if (hloc32) wow_handlers32.edit_proc( hwnd, EM_SETHANDLE, (WPARAM)hloc32, 0, FALSE );
}
static void edit_destroy_handle( HWND hwnd )
{
HLOCAL16 hloc16 = GetWindowWord( hwnd, GWW_HANDLE16 );
if (hloc16)
{
STACK16FRAME* stack16 = MapSL(PtrToUlong(NtCurrentTeb()->WOW32Reserved));
HANDLE16 oldDS = stack16->ds;
stack16->ds = GetWindowLongPtrW( hwnd, GWLP_HINSTANCE );
while (LocalUnlock16(hloc16)) ;
LocalFree16(hloc16);
stack16->ds = oldDS;
SetWindowWord( hwnd, GWW_HANDLE16, 0 );
}
}
/*********************************************************************
* edit_proc16
*/
static LRESULT edit_proc16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode )
{
static const UINT msg16_offset = EM_GETSEL16 - EM_GETSEL;
LRESULT result = 0;
edit_lock_buffer( hwnd );
switch (msg)
{
case EM_SCROLL16:
case EM_SCROLLCARET16:
case EM_GETMODIFY16:
case EM_SETMODIFY16:
case EM_GETLINECOUNT16:
case EM_GETTHUMB16:
case EM_LINELENGTH16:
case EM_LIMITTEXT16:
case EM_CANUNDO16:
case EM_UNDO16:
case EM_FMTLINES16:
case EM_LINEFROMCHAR16:
case EM_SETPASSWORDCHAR16:
case EM_EMPTYUNDOBUFFER16:
case EM_SETREADONLY16:
case EM_GETPASSWORDCHAR16:
/* these messages missing from specs */
case WM_USER+15:
case WM_USER+16:
case WM_USER+19:
case WM_USER+26:
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, wParam, lParam, FALSE );
break;
case EM_GETSEL16:
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, 0, 0, FALSE );
break;
case EM_REPLACESEL16:
case EM_GETLINE16:
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, wParam, (LPARAM)MapSL(lParam), FALSE );
break;
case EM_LINESCROLL16:
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, (INT)(SHORT)HIWORD(lParam),
(INT)(SHORT)LOWORD(lParam), FALSE );
break;
case EM_LINEINDEX16:
if ((INT16)wParam == -1) wParam = (WPARAM)-1;
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, wParam, lParam, FALSE );
break;
case EM_SETSEL16:
if ((short)LOWORD(lParam) == -1)
{
wParam = -1;
lParam = 0;
}
else
{
wParam = LOWORD(lParam);
lParam = HIWORD(lParam);
}
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, wParam, lParam, FALSE );
break;
case EM_GETRECT16:
if (lParam)
{
RECT rect;
RECT16 *r16 = MapSL(lParam);
wow_handlers32.edit_proc( hwnd, msg - msg16_offset, wParam, (LPARAM)&rect, FALSE );
r16->left = rect.left;
r16->top = rect.top;
r16->right = rect.right;
r16->bottom = rect.bottom;
}
break;
case EM_SETRECT16:
case EM_SETRECTNP16:
if (lParam)
{
RECT rect;
RECT16 *r16 = MapSL(lParam);
rect.left = r16->left;
rect.top = r16->top;
rect.right = r16->right;
rect.bottom = r16->bottom;
wow_handlers32.edit_proc( hwnd, msg - msg16_offset, wParam, (LPARAM)&rect, FALSE );
}
break;
case EM_SETHANDLE16:
edit_set_handle( hwnd, (HLOCAL16)wParam );
break;
case EM_GETHANDLE16:
result = edit_get_handle( hwnd );
break;
case EM_SETTABSTOPS16:
{
INT16 *tabs16 = MapSL(lParam);
INT i, count = wParam, *tabs = NULL;
if (count > 0)
{
if (!(tabs = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*tabs) ))) return 0;
for (i = 0; i < count; i++) tabs[i] = tabs16[i];
}
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, count, (LPARAM)tabs, FALSE );
HeapFree( GetProcessHeap(), 0, tabs );
break;
}
case EM_GETFIRSTVISIBLELINE16:
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & ES_MULTILINE)) break;
result = wow_handlers32.edit_proc( hwnd, msg - msg16_offset, wParam, lParam, FALSE );
break;
case EM_SETWORDBREAKPROC16:
{
struct word_break_thunk *thunk = add_word_break_thunk( (EDITWORDBREAKPROC16)lParam );
result = wow_handlers32.edit_proc( hwnd, EM_SETWORDBREAKPROC, wParam, (LPARAM)thunk, FALSE );
break;
}
case EM_GETWORDBREAKPROC16:
result = wow_handlers32.edit_proc( hwnd, EM_GETWORDBREAKPROC, wParam, lParam, FALSE );
result = (LRESULT)get_word_break_thunk( (EDITWORDBREAKPROCA)result );
break;
case WM_NCDESTROY:
edit_destroy_handle( hwnd );
return wow_handlers32.edit_proc( hwnd, msg, wParam, lParam, unicode ); /* no unlock on destroy */
default:
result = wow_handlers32.edit_proc( hwnd, msg, wParam, lParam, unicode );
break;
}
edit_unlock_buffer( hwnd );
return result;
}
/***********************************************************************
* listbox_proc16
*/
@ -802,6 +1165,7 @@ void register_wow_handlers(void)
{
button_proc16,
combo_proc16,
edit_proc16,
listbox_proc16,
};

View File

@ -2390,6 +2390,7 @@ void WINAPI UserRegisterWowHandlers( const struct wow_handlers16 *new, struct wo
{
orig->button_proc = ButtonWndProc_common;
orig->combo_proc = ComboWndProc_common;
orig->edit_proc = EditWndProc_common;
orig->listbox_proc = ListBoxWndProc_common;
wow_handlers = *new;
@ -2399,5 +2400,6 @@ struct wow_handlers16 wow_handlers =
{
ButtonWndProc_common,
ComboWndProc_common,
EditWndProc_common,
ListBoxWndProc_common,
};