Added LOAD_WITH_ALTERED_SEARCH_PATH support to LoadLibraryEx.
[wine/dcerpc.git] / windows / winproc.c
blobd7cf9122fc7aa1e649d930ed1ae6218afa7b5ba8
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include <string.h>
10 #include "config.h"
11 #include "windef.h"
12 #include "winbase.h"
13 #include "wingdi.h"
14 #include "wine/winbase16.h"
15 #include "wine/winuser16.h"
16 #include "stackframe.h"
17 #include "builtin16.h"
18 #include "controls.h"
19 #include "heap.h"
20 #include "struct32.h"
21 #include "win.h"
22 #include "winproc.h"
23 #include "debugtools.h"
24 #include "spy.h"
25 #include "task.h"
26 #include "thread.h"
28 DECLARE_DEBUG_CHANNEL(msg);
29 DECLARE_DEBUG_CHANNEL(relay);
30 DECLARE_DEBUG_CHANNEL(win);
32 /* Window procedure 16-to-32-bit thunk,
33 * see BuildSpec16File() in tools/build.c */
35 #include "pshpack1.h"
36 typedef struct
38 WORD pushw_bp; /* pushw %bp */
39 BYTE pushl_func; /* pushl $proc */
40 WNDPROC proc;
41 WORD pushw_ax; /* pushw %ax */
42 BYTE pushl_relay; /* pushl $relay */
43 void (*relay)(); /* WINPROC_Thunk16To32A/W() */
44 BYTE lcall; /* lcall cs:glue */
45 void (*glue)(); /* __wine_call_from_16_long */
46 WORD cs; /* __FLATCS */
47 WORD lret; /* lret $10 */
48 WORD nArgs;
49 } WINPROC_THUNK_FROM16;
50 #include "poppack.h"
52 /* Window procedure 32-to-16-bit thunk,
53 * see BuildSpec32File() in tools/build.c */
55 typedef struct
57 BYTE popl_eax; /* popl %eax (return address) */
58 BYTE pushl_func; /* pushl $proc */
59 WNDPROC16 proc WINE_PACKED;
60 BYTE pushl_eax; /* pushl %eax */
61 BYTE jmp; /* jmp relay (relative jump)*/
62 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
63 } WINPROC_THUNK_FROM32;
65 /* Simple jmp to call 32-bit procedure directly */
66 typedef struct
68 BYTE jmp; /* jmp proc (relative jump) */
69 WNDPROC proc WINE_PACKED;
70 } WINPROC_JUMP;
72 typedef union
74 WINPROC_THUNK_FROM16 t_from16;
75 WINPROC_THUNK_FROM32 t_from32;
76 } WINPROC_THUNK;
78 typedef struct tagWINDOWPROC
80 WINPROC_THUNK thunk; /* Thunk */
81 WINPROC_JUMP jmp; /* Jump */
82 struct tagWINDOWPROC *next; /* Next window proc */
83 UINT magic; /* Magic number */
84 WINDOWPROCTYPE type; /* Function type */
85 WINDOWPROCUSER user; /* Function user */
86 } WINDOWPROC;
88 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
90 #define WINPROC_THUNKPROC(pproc) \
91 (((pproc)->type == WIN_PROC_16) ? \
92 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
93 (WNDPROC16)((pproc)->thunk.t_from16.proc))
95 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
96 UINT msg, WPARAM wParam,
97 LPARAM lParam );
98 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
99 UINT msg, WPARAM wParam,
100 LPARAM lParam );
101 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args );
102 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args );
104 static HANDLE WinProcHeap;
107 /**********************************************************************
108 * WINPROC_Init
110 BOOL WINPROC_Init(void)
112 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
113 if (!WinProcHeap)
115 WARN_(relay)("Unable to create winproc heap\n" );
116 return FALSE;
118 return TRUE;
122 #ifdef __i386__
123 /* Some window procedures modify register they shouldn't, or are not
124 * properly declared stdcall; so we need a small assembly wrapper to
125 * call them. */
126 extern LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
127 WPARAM wParam, LPARAM lParam );
128 __ASM_GLOBAL_FUNC( WINPROC_wrapper,
129 "pushl %ebp\n\t"
130 "movl %esp,%ebp\n\t"
131 "pushl %edi\n\t"
132 "pushl %esi\n\t"
133 "pushl %ebx\n\t"
134 "pushl 24(%ebp)\n\t"
135 "pushl 20(%ebp)\n\t"
136 "pushl 16(%ebp)\n\t"
137 "pushl 12(%ebp)\n\t"
138 "movl 8(%ebp),%eax\n\t"
139 "call *%eax\n\t"
140 "leal -12(%ebp),%esp\n\t"
141 "popl %ebx\n\t"
142 "popl %esi\n\t"
143 "popl %edi\n\t"
144 "leave\n\t"
145 "ret" );
146 #else
147 static inline LRESULT WINPROC_wrapper( WNDPROC proc, HWND hwnd, UINT msg,
148 WPARAM wParam, LPARAM lParam )
150 return proc( hwnd, msg, wParam, lParam );
152 #endif /* __i386__ */
154 /**********************************************************************
155 * WINPROC_CallWndProc32
157 * Call a 32-bit WndProc.
159 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
160 WPARAM wParam, LPARAM lParam )
162 LRESULT retvalue;
163 int iWndsLocks;
165 if (TRACE_ON(relay))
166 DPRINTF( "%08lx:Call window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
167 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
168 /* To avoid any deadlocks, all the locks on the windows structures
169 must be suspended before the control is passed to the application */
170 iWndsLocks = WIN_SuspendWndsLock();
171 retvalue = WINPROC_wrapper( proc, hwnd, msg, wParam, lParam );
172 WIN_RestoreWndsLock(iWndsLocks);
174 if (TRACE_ON(relay))
175 DPRINTF( "%08lx:Ret window proc %p (hwnd=%08x,msg=%s,wp=%08x,lp=%08lx) retval=%08lx\n",
176 GetCurrentThreadId(), proc, hwnd, SPY_GetMsgName(msg), wParam, lParam, retvalue );
177 return retvalue;
180 /***********************************************************************
181 * WINPROC_CallWndProc16
183 * Call a 16-bit window procedure
185 static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
186 UINT16 msg, WPARAM16 wParam,
187 LPARAM lParam )
189 CONTEXT86 context;
190 LRESULT ret;
191 WORD *args;
192 WND *wndPtr = WIN_FindWndPtr( hwnd );
193 DWORD offset = 0;
194 TEB *teb = NtCurrentTeb();
195 int iWndsLocks;
197 /* Window procedures want ax = hInstance, ds = es = ss */
199 memset(&context, '\0', sizeof(context));
200 context.SegDs = context.SegEs = SELECTOROF(teb->cur_stack);
201 context.Eax = wndPtr ? wndPtr->hInstance : context.SegDs;
202 context.SegCs = SELECTOROF(proc);
203 context.Eip = OFFSETOF(proc);
204 context.Ebp = OFFSETOF(teb->cur_stack)
205 + (WORD)&((STACK16FRAME*)0)->bp;
207 WIN_ReleaseWndPtr(wndPtr);
209 if (lParam)
211 /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
212 work if structures passed in lParam are placed in the stack/data
213 segment. Programmers easily make the mistake of converting lParam
214 to a near rather than a far pointer, since Windows apparently
215 allows this. We copy the structures to the 16 bit stack; this is
216 ugly but makes these programs work. */
217 switch (msg)
219 case WM_CREATE:
220 case WM_NCCREATE:
221 offset = sizeof(CREATESTRUCT16); break;
222 case WM_DRAWITEM:
223 offset = sizeof(DRAWITEMSTRUCT16); break;
224 case WM_COMPAREITEM:
225 offset = sizeof(COMPAREITEMSTRUCT16); break;
227 if (offset)
229 void *s = MapSL(lParam);
230 lParam = stack16_push( offset );
231 memcpy( MapSL(lParam), s, offset );
235 iWndsLocks = WIN_SuspendWndsLock();
237 args = (WORD *)THREAD_STACK16(teb) - 5;
238 args[0] = LOWORD(lParam);
239 args[1] = HIWORD(lParam);
240 args[2] = wParam;
241 args[3] = msg;
242 args[4] = hwnd;
244 wine_call_to_16_regs_short( &context, 5 * sizeof(WORD) );
245 ret = MAKELONG( LOWORD(context.Eax), LOWORD(context.Edx) );
246 if (offset) stack16_pop( offset );
248 WIN_RestoreWndsLock(iWndsLocks);
250 return ret;
254 /**********************************************************************
255 * WINPROC_GetPtr
257 * Return a pointer to the win proc.
259 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
261 BYTE *ptr;
262 WINDOWPROC *proc;
264 /* ptr cannot be < 64K */
265 if (!HIWORD(handle)) return NULL;
267 /* Check for a linear pointer */
269 ptr = (BYTE *)handle;
270 /* First check if it is the jmp address */
271 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->jmp);
272 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
273 return proc;
274 /* Now it must be the thunk address */
275 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
276 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
277 return proc;
279 /* Check for a segmented pointer */
281 if (!IsBadReadPtr16( (SEGPTR)handle, sizeof(proc->thunk) ))
283 ptr = MapSL( (SEGPTR)handle );
284 /* It must be the thunk address */
285 proc = (WINDOWPROC *)(ptr - (int)&((WINDOWPROC *)0)->thunk);
286 if (HeapValidate( WinProcHeap, 0, proc ) && (proc->magic == WINPROC_MAGIC))
287 return proc;
290 return NULL;
294 /**********************************************************************
295 * WINPROC_AllocWinProc
297 * Allocate a new window procedure.
299 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
300 WINDOWPROCUSER user )
302 WINDOWPROC *proc, *oldproc;
304 /* Allocate a window procedure */
306 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
308 /* Check if the function is already a win proc */
310 if ((oldproc = WINPROC_GetPtr( func )))
312 *proc = *oldproc;
314 else
316 switch(type)
318 case WIN_PROC_16:
319 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
320 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
321 proc->thunk.t_from32.proc = func;
322 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
323 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
324 proc->thunk.t_from32.relay = /* relative jump */
325 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
326 (DWORD)(&proc->thunk.t_from32.relay + 1));
327 break;
328 case WIN_PROC_32A:
329 case WIN_PROC_32W:
330 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
331 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
332 proc->thunk.t_from16.proc = (WNDPROC)func;
333 proc->thunk.t_from16.pushw_ax = 0x5066; /* pushw %ax */
334 proc->thunk.t_from16.pushl_relay = 0x68; /* pushl $relay */
335 proc->thunk.t_from16.relay = (type == WIN_PROC_32A) ?
336 (void(*)())WINPROC_Thunk16To32A :
337 (void(*)())WINPROC_Thunk16To32W;
338 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:glue */
339 proc->thunk.t_from16.glue = (void*)__wine_call_from_16_long;
340 proc->thunk.t_from16.cs = __get_cs();
341 proc->thunk.t_from16.lret = 0xca66;
342 proc->thunk.t_from16.nArgs = 10;
343 proc->jmp.jmp = 0xe9;
344 /* Fixup relative jump */
345 proc->jmp.proc = (WNDPROC)((DWORD)func -
346 (DWORD)(&proc->jmp.proc + 1));
347 break;
348 default:
349 /* Should not happen */
350 break;
352 proc->magic = WINPROC_MAGIC;
353 proc->type = type;
354 proc->user = user;
356 proc->next = NULL;
357 TRACE_(win)("(%08x,%d): returning %08x\n",
358 (UINT)func, type, (UINT)proc );
359 return proc;
363 /**********************************************************************
364 * WINPROC_GetProc
366 * Get a window procedure pointer that can be passed to the Windows program.
368 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
370 if (!proc) return NULL;
371 if (type == WIN_PROC_16) /* We want a 16:16 address */
373 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
374 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
375 else
376 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
377 &((WINDOWPROC *)proc)->thunk );
379 else /* We want a 32-bit address */
381 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
382 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
383 else if (type != ((WINDOWPROC *)proc)->type)
384 /* Have to return the jmp address if types don't match */
385 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
386 else
387 /* Some Win16 programs want to get back the proc they set */
388 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
393 /**********************************************************************
394 * WINPROC_SetProc
396 * Set the window procedure for a window or class. There are
397 * three tree classes of winproc callbacks:
399 * 1) class -> wp - not subclassed
400 * class -> wp -> wp -> wp -> wp - SetClassLong()
401 * / /
402 * 2) window -' / - not subclassed
403 * window -> wp -> wp ' - SetWindowLong()
405 * 3) timer -> wp - SetTimer()
407 * Initially, winproc of the window points to the current winproc
408 * thunk of its class. Subclassing prepends a new thunk to the
409 * window winproc chain at the head of the list. Thus, window thunk
410 * list includes class thunks and the latter are preserved when the
411 * window is destroyed.
414 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
415 WINDOWPROCTYPE type, WINDOWPROCUSER user )
417 BOOL bRecycle = FALSE;
418 WINDOWPROC *proc, **ppPrev;
420 /* Check if function is already in the list */
422 ppPrev = (WINDOWPROC **)pFirst;
423 proc = WINPROC_GetPtr( func );
424 while (*ppPrev)
426 if (proc)
428 if (*ppPrev == proc)
430 if ((*ppPrev)->user != user)
432 /* terminal thunk is being restored */
434 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
435 *(WINDOWPROC **)pFirst = *ppPrev;
436 return TRUE;
438 bRecycle = TRUE;
439 break;
442 else
444 if (((*ppPrev)->type == type) &&
445 (func == WINPROC_THUNKPROC(*ppPrev)))
447 bRecycle = TRUE;
448 break;
452 /* WPF_CLASS thunk terminates window thunk list */
453 if ((*ppPrev)->user != user) break;
454 ppPrev = &(*ppPrev)->next;
457 if (bRecycle)
459 /* Extract this thunk from the list */
460 proc = *ppPrev;
461 *ppPrev = proc->next;
463 else /* Allocate a new one */
465 if (proc) /* Was already a win proc */
467 type = proc->type;
468 func = WINPROC_THUNKPROC(proc);
470 proc = WINPROC_AllocWinProc( func, type, user );
471 if (!proc) return FALSE;
474 /* Add the win proc at the head of the list */
476 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
477 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
478 proc->next = *(WINDOWPROC **)pFirst;
479 *(WINDOWPROC **)pFirst = proc;
480 return TRUE;
484 /**********************************************************************
485 * WINPROC_FreeProc
487 * Free a list of win procs.
489 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
491 while (proc)
493 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
494 if (((WINDOWPROC *)proc)->user != user) break;
495 TRACE_(win)("freeing %08x\n", (UINT)proc);
496 HeapFree( WinProcHeap, 0, proc );
497 proc = next;
502 /**********************************************************************
503 * WINPROC_GetProcType
505 * Return the window procedure type.
507 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
509 if (!proc ||
510 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
511 return WIN_PROC_INVALID;
512 return ((WINDOWPROC *)proc)->type;
514 /**********************************************************************
515 * WINPROC_TestCBForStr
517 * Return TRUE if the lparam is a string
519 static BOOL WINPROC_TestCBForStr ( HWND hwnd )
521 BOOL retvalue;
522 WND * wnd = WIN_FindWndPtr(hwnd);
523 retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
524 (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
525 WIN_ReleaseWndPtr(wnd);
526 return retvalue;
528 /**********************************************************************
529 * WINPROC_TestLBForStr
531 * Return TRUE if the lparam is a string
533 static BOOL WINPROC_TestLBForStr ( HWND hwnd )
535 BOOL retvalue;
536 WND * wnd = WIN_FindWndPtr(hwnd);
537 retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
538 (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
539 WIN_ReleaseWndPtr(wnd);
540 return retvalue;
543 /**********************************************************************
544 * WINPROC_MapMsg32ATo32W
546 * Map a message from Ansi to Unicode.
547 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
549 * FIXME:
550 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
551 * the first four bytes are the handle of the icon
552 * when the WM_SETTEXT message has been used to set the icon
554 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
556 switch(msg)
558 case WM_GETTEXT:
559 case WM_ASKCBFORMATNAME:
561 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
562 *pwparam * sizeof(WCHAR) + sizeof(LPARAM) );
563 if (!ptr) return -1;
564 *ptr++ = *plparam; /* Store previous lParam */
565 *plparam = (LPARAM)ptr;
567 return 1;
568 /* lparam is string (0-terminated) */
569 case WM_SETTEXT:
570 case WM_WININICHANGE:
571 case WM_DEVMODECHANGE:
572 case CB_DIR:
573 case CB_FINDSTRING:
574 case CB_FINDSTRINGEXACT:
575 case CB_SELECTSTRING:
576 case LB_DIR:
577 case LB_ADDFILE:
578 case LB_FINDSTRING:
579 case LB_FINDSTRINGEXACT:
580 case LB_SELECTSTRING:
581 case EM_REPLACESEL:
582 if(!*plparam) return 0;
583 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
584 return (*plparam ? 1 : -1);
585 case WM_GETTEXTLENGTH:
586 case CB_GETLBTEXTLEN:
587 case LB_GETTEXTLEN:
588 return 1; /* need to map result */
589 case WM_NCCREATE:
590 case WM_CREATE:
592 struct s
593 { CREATESTRUCTW cs; /* new structure */
594 LPCWSTR lpszName; /* allocated Name */
595 LPCWSTR lpszClass; /* allocated Class */
598 struct s *xs = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct s));
599 if (!xs) return -1;
600 xs->cs = *(CREATESTRUCTW *)*plparam;
601 if (HIWORD(xs->cs.lpszName))
602 xs->lpszName = xs->cs.lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
603 (LPCSTR)xs->cs.lpszName );
604 if (HIWORD(xs->cs.lpszClass))
605 xs->lpszClass = xs->cs.lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
606 (LPCSTR)xs->cs.lpszClass );
607 *plparam = (LPARAM)xs;
609 return 1;
610 case WM_MDICREATE:
612 MDICREATESTRUCTW *cs =
613 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
614 if (!cs) return -1;
615 *cs = *(MDICREATESTRUCTW *)*plparam;
616 if (HIWORD(cs->szClass))
617 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
618 (LPCSTR)cs->szClass );
619 if (HIWORD(cs->szTitle))
620 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
621 (LPCSTR)cs->szTitle );
622 *plparam = (LPARAM)cs;
624 return 1;
626 /* Listbox */
627 case LB_ADDSTRING:
628 case LB_INSERTSTRING:
629 if(!*plparam) return 0;
630 if ( WINPROC_TestLBForStr( hwnd ))
631 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
632 return (*plparam ? 1 : -1);
634 case LB_GETTEXT: /* fixme: fixed sized buffer */
635 { if ( WINPROC_TestLBForStr( hwnd ))
636 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
637 if (!ptr) return -1;
638 *ptr++ = *plparam; /* Store previous lParam */
639 *plparam = (LPARAM)ptr;
642 return 1;
644 /* Combobox */
645 case CB_ADDSTRING:
646 case CB_INSERTSTRING:
647 if(!*plparam) return 0;
648 if ( WINPROC_TestCBForStr( hwnd ))
649 *plparam = (LPARAM)HEAP_strdupAtoW( GetProcessHeap(), 0, (LPCSTR)*plparam );
650 return (*plparam ? 1 : -1);
652 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
653 { if ( WINPROC_TestCBForStr( hwnd ))
654 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
655 if (!ptr) return -1;
656 *ptr++ = *plparam; /* Store previous lParam */
657 *plparam = (LPARAM)ptr;
660 return 1;
662 /* Multiline edit */
663 case EM_GETLINE:
664 { WORD len = (WORD)*plparam;
665 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
666 if (!ptr) return -1;
667 *ptr++ = *plparam; /* Store previous lParam */
668 *((WORD *) ptr) = len; /* Store the length */
669 *plparam = (LPARAM)ptr;
671 return 1;
673 case WM_CHARTOITEM:
674 case WM_MENUCHAR:
675 case WM_CHAR:
676 case WM_DEADCHAR:
677 case WM_SYSCHAR:
678 case WM_SYSDEADCHAR:
679 case EM_SETPASSWORDCHAR:
681 char ch = LOWORD(*pwparam);
682 WCHAR wch;
683 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1);
684 *pwparam = MAKEWPARAM( wch, HIWORD(*pwparam) );
686 return 0;
688 case WM_PAINTCLIPBOARD:
689 case WM_SIZECLIPBOARD:
690 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
691 return -1;
692 default: /* No translation needed */
693 return 0;
698 /**********************************************************************
699 * WINPROC_UnmapMsg32ATo32W
701 * Unmap a message that was mapped from Ansi to Unicode.
703 LRESULT WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
704 LRESULT result )
706 switch(msg)
708 case WM_GETTEXT:
709 case WM_ASKCBFORMATNAME:
711 LPARAM *ptr = (LPARAM *)lParam - 1;
712 if (wParam > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
713 (LPSTR)*ptr, wParam, NULL, NULL ))
714 ((LPSTR)*ptr)[wParam-1] = 0;
715 HeapFree( GetProcessHeap(), 0, ptr );
717 break;
718 case WM_GETTEXTLENGTH:
719 case CB_GETLBTEXTLEN:
720 case LB_GETTEXTLEN:
721 /* there may be one DBCS char for each Unicode char */
722 return result * 2;
723 case WM_NCCREATE:
724 case WM_CREATE:
726 struct s
727 { CREATESTRUCTW cs; /* new structure */
728 LPWSTR lpszName; /* allocated Name */
729 LPWSTR lpszClass; /* allocated Class */
731 struct s *xs = (struct s *)lParam;
732 if (xs->lpszName) HeapFree( GetProcessHeap(), 0, xs->lpszName );
733 if (xs->lpszClass) HeapFree( GetProcessHeap(), 0, xs->lpszClass );
734 HeapFree( GetProcessHeap(), 0, xs );
736 break;
738 case WM_MDICREATE:
740 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
741 if (HIWORD(cs->szTitle))
742 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
743 if (HIWORD(cs->szClass))
744 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
745 HeapFree( GetProcessHeap(), 0, cs );
747 break;
749 case WM_SETTEXT:
750 case WM_WININICHANGE:
751 case WM_DEVMODECHANGE:
752 case CB_DIR:
753 case CB_FINDSTRING:
754 case CB_FINDSTRINGEXACT:
755 case CB_SELECTSTRING:
756 case LB_DIR:
757 case LB_ADDFILE:
758 case LB_FINDSTRING:
759 case LB_FINDSTRINGEXACT:
760 case LB_SELECTSTRING:
761 case EM_REPLACESEL:
762 HeapFree( GetProcessHeap(), 0, (void *)lParam );
763 break;
765 /* Listbox */
766 case LB_ADDSTRING:
767 case LB_INSERTSTRING:
768 if ( WINPROC_TestLBForStr( hwnd ))
769 HeapFree( GetProcessHeap(), 0, (void *)lParam );
770 break;
772 case LB_GETTEXT:
773 { if ( WINPROC_TestLBForStr( hwnd ))
774 { LPARAM *ptr = (LPARAM *)lParam - 1;
775 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
776 HeapFree( GetProcessHeap(), 0, ptr );
779 break;
781 /* Combobox */
782 case CB_ADDSTRING:
783 case CB_INSERTSTRING:
784 if ( WINPROC_TestCBForStr( hwnd ))
785 HeapFree( GetProcessHeap(), 0, (void *)lParam );
786 break;
788 case CB_GETLBTEXT:
789 { if ( WINPROC_TestCBForStr( hwnd ))
790 { LPARAM *ptr = (LPARAM *)lParam - 1;
791 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, (LPSTR)*ptr, 0x7fffffff, NULL, NULL );
792 HeapFree( GetProcessHeap(), 0, ptr );
795 break;
797 /* Multiline edit */
798 case EM_GETLINE:
799 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
800 WORD len = *(WORD *) lParam;
801 if (len > 0 && !WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1,
802 (LPSTR)*ptr, len, NULL, NULL ))
803 ((LPSTR)*ptr)[len-1] = 0;
804 HeapFree( GetProcessHeap(), 0, ptr );
806 break;
808 return result;
812 /**********************************************************************
813 * WINPROC_MapMsg32WTo32A
815 * Map a message from Unicode to Ansi.
816 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
818 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM *pwparam, LPARAM *plparam )
820 switch(msg)
822 case WM_GETTEXT:
823 case WM_ASKCBFORMATNAME:
825 LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0,
826 *pwparam + sizeof(LPARAM) );
827 if (!ptr) return -1;
828 *ptr++ = *plparam; /* Store previous lParam */
829 *plparam = (LPARAM)ptr;
831 return 1;
833 case WM_SETTEXT:
834 case WM_WININICHANGE:
835 case WM_DEVMODECHANGE:
836 case CB_DIR:
837 case CB_FINDSTRING:
838 case CB_FINDSTRINGEXACT:
839 case CB_SELECTSTRING:
840 case LB_DIR:
841 case LB_ADDFILE:
842 case LB_FINDSTRING:
843 case LB_FINDSTRINGEXACT:
844 case LB_SELECTSTRING:
845 case EM_REPLACESEL:
846 if(!*plparam) return 0;
847 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
848 return (*plparam ? 1 : -1);
850 case WM_NCCREATE:
851 case WM_CREATE:
853 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
854 sizeof(*cs) );
855 if (!cs) return -1;
856 *cs = *(CREATESTRUCTA *)*plparam;
857 if (HIWORD(cs->lpszName))
858 cs->lpszName = HEAP_strdupWtoA( GetProcessHeap(), 0,
859 (LPCWSTR)cs->lpszName );
860 if (HIWORD(cs->lpszClass))
861 cs->lpszClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
862 (LPCWSTR)cs->lpszClass);
863 *plparam = (LPARAM)cs;
865 return 1;
866 case WM_MDICREATE:
868 MDICREATESTRUCTA *cs =
869 (MDICREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) );
870 if (!cs) return -1;
871 *cs = *(MDICREATESTRUCTA *)*plparam;
872 if (HIWORD(cs->szTitle))
873 cs->szTitle = HEAP_strdupWtoA( GetProcessHeap(), 0,
874 (LPCWSTR)cs->szTitle );
875 if (HIWORD(cs->szClass))
876 cs->szClass = HEAP_strdupWtoA( GetProcessHeap(), 0,
877 (LPCWSTR)cs->szClass );
878 *plparam = (LPARAM)cs;
880 return 1;
882 /* Listbox */
883 case LB_ADDSTRING:
884 case LB_INSERTSTRING:
885 if(!*plparam) return 0;
886 if ( WINPROC_TestLBForStr( hwnd ))
887 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
888 return (*plparam ? 1 : -1);
890 case LB_GETTEXT: /* fixme: fixed sized buffer */
891 { if ( WINPROC_TestLBForStr( hwnd ))
892 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
893 if (!ptr) return -1;
894 *ptr++ = *plparam; /* Store previous lParam */
895 *plparam = (LPARAM)ptr;
898 return 1;
900 /* Combobox */
901 case CB_ADDSTRING:
902 case CB_INSERTSTRING:
903 if(!*plparam) return 0;
904 if ( WINPROC_TestCBForStr( hwnd ))
905 *plparam = (LPARAM)HEAP_strdupWtoA( GetProcessHeap(), 0, (LPCWSTR)*plparam );
906 return (*plparam ? 1 : -1);
908 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
909 { if ( WINPROC_TestCBForStr( hwnd ))
910 { LPARAM *ptr = (LPARAM *)HeapAlloc( GetProcessHeap(), 0, 256 + sizeof(LPARAM) );
911 if (!ptr) return -1;
912 *ptr++ = *plparam; /* Store previous lParam */
913 *plparam = (LPARAM)ptr;
916 return 1;
918 /* Multiline edit */
919 case EM_GETLINE:
920 { WORD len = (WORD)*plparam;
921 LPARAM *ptr = (LPARAM *) HeapAlloc( GetProcessHeap(), 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
922 if (!ptr) return -1;
923 *ptr++ = *plparam; /* Store previous lParam */
924 *((WORD *) ptr) = len; /* Store the length */
925 *plparam = (LPARAM)ptr;
927 return 1;
929 case WM_CHARTOITEM:
930 case WM_MENUCHAR:
931 case WM_CHAR:
932 case WM_DEADCHAR:
933 case WM_SYSCHAR:
934 case WM_SYSDEADCHAR:
935 case EM_SETPASSWORDCHAR:
937 WCHAR wch = LOWORD(*pwparam);
938 char ch;
939 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL );
940 *pwparam = MAKEWPARAM( ch, HIWORD(*pwparam) );
942 return 0;
944 case WM_PAINTCLIPBOARD:
945 case WM_SIZECLIPBOARD:
946 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
947 return -1;
948 default: /* No translation needed */
949 return 0;
954 /**********************************************************************
955 * WINPROC_UnmapMsg32WTo32A
957 * Unmap a message that was mapped from Unicode to Ansi.
959 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
961 switch(msg)
963 case WM_GETTEXT:
964 case WM_ASKCBFORMATNAME:
966 LPARAM *ptr = (LPARAM *)lParam - 1;
967 if (wParam)
969 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, wParam ))
970 ((LPWSTR)*ptr)[wParam-1] = 0;
972 HeapFree( GetProcessHeap(), 0, ptr );
974 break;
976 case WM_SETTEXT:
977 case WM_WININICHANGE:
978 case WM_DEVMODECHANGE:
979 case CB_DIR:
980 case CB_FINDSTRING:
981 case CB_FINDSTRINGEXACT:
982 case CB_SELECTSTRING:
983 case LB_DIR:
984 case LB_ADDFILE:
985 case LB_FINDSTRING:
986 case LB_FINDSTRINGEXACT:
987 case LB_SELECTSTRING:
988 case EM_REPLACESEL:
989 HeapFree( GetProcessHeap(), 0, (void *)lParam );
990 break;
992 case WM_NCCREATE:
993 case WM_CREATE:
995 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
996 if (HIWORD(cs->lpszName))
997 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
998 if (HIWORD(cs->lpszClass))
999 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
1000 HeapFree( GetProcessHeap(), 0, cs );
1002 break;
1004 case WM_MDICREATE:
1006 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1007 if (HIWORD(cs->szTitle))
1008 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
1009 if (HIWORD(cs->szClass))
1010 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
1011 HeapFree( GetProcessHeap(), 0, cs );
1013 break;
1015 /* Listbox */
1016 case LB_ADDSTRING:
1017 case LB_INSERTSTRING:
1018 if ( WINPROC_TestLBForStr( hwnd ))
1019 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1020 break;
1022 case LB_GETTEXT:
1023 if ( WINPROC_TestLBForStr( hwnd ))
1025 LPARAM *ptr = (LPARAM *)lParam - 1;
1026 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1027 HeapFree( GetProcessHeap(), 0, ptr );
1029 break;
1031 /* Combobox */
1032 case CB_ADDSTRING:
1033 case CB_INSERTSTRING:
1034 if ( WINPROC_TestCBForStr( hwnd ))
1035 HeapFree( GetProcessHeap(), 0, (void *)lParam );
1036 break;
1038 case CB_GETLBTEXT:
1039 if ( WINPROC_TestCBForStr( hwnd ))
1041 LPARAM *ptr = (LPARAM *)lParam - 1;
1042 MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, 0x7fffffff );
1043 HeapFree( GetProcessHeap(), 0, ptr );
1045 break;
1047 /* Multiline edit */
1048 case EM_GETLINE:
1049 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
1050 WORD len = *(WORD *)ptr;
1051 if (len)
1053 if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)lParam, -1, (LPWSTR)*ptr, len ))
1054 ((LPWSTR)*ptr)[len-1] = 0;
1056 HeapFree( GetProcessHeap(), 0, ptr );
1058 break;
1063 /**********************************************************************
1064 * WINPROC_MapMsg16To32A
1066 * Map a message from 16- to 32-bit Ansi.
1067 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1069 INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1070 WPARAM *pwparam32, LPARAM *plparam )
1072 *pmsg32 = (UINT)msg16;
1073 *pwparam32 = (WPARAM)wParam16;
1074 switch(msg16)
1076 case WM_ACTIVATE:
1077 case WM_CHARTOITEM:
1078 case WM_COMMAND:
1079 case WM_VKEYTOITEM:
1080 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1081 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1082 return 0;
1083 case WM_HSCROLL:
1084 case WM_VSCROLL:
1085 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1086 *plparam = (LPARAM)(HWND)HIWORD(*plparam);
1087 return 0;
1088 case WM_CTLCOLOR:
1089 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
1090 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
1091 *pwparam32 = (WPARAM)(HDC)wParam16;
1092 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1093 return 0;
1094 case WM_COMPAREITEM:
1096 COMPAREITEMSTRUCT16* cis16 = MapSL(*plparam);
1097 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
1098 HeapAlloc(GetProcessHeap(), 0, sizeof(*cis));
1099 if (!cis) return -1;
1100 cis->CtlType = cis16->CtlType;
1101 cis->CtlID = cis16->CtlID;
1102 cis->hwndItem = cis16->hwndItem;
1103 cis->itemID1 = cis16->itemID1;
1104 cis->itemData1 = cis16->itemData1;
1105 cis->itemID2 = cis16->itemID2;
1106 cis->itemData2 = cis16->itemData2;
1107 cis->dwLocaleId = 0; /* FIXME */
1108 *plparam = (LPARAM)cis;
1110 return 1;
1111 case WM_DELETEITEM:
1113 DELETEITEMSTRUCT16* dis16 = MapSL(*plparam);
1114 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
1115 HeapAlloc(GetProcessHeap(), 0, sizeof(*dis));
1116 if (!dis) return -1;
1117 dis->CtlType = dis16->CtlType;
1118 dis->CtlID = dis16->CtlID;
1119 dis->hwndItem = dis16->hwndItem;
1120 dis->itemData = dis16->itemData;
1121 *plparam = (LPARAM)dis;
1123 return 1;
1124 case WM_MEASUREITEM:
1126 MEASUREITEMSTRUCT16* mis16 = MapSL(*plparam);
1127 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
1128 HeapAlloc(GetProcessHeap(), 0,
1129 sizeof(*mis) + sizeof(LPARAM));
1130 if (!mis) return -1;
1131 mis->CtlType = mis16->CtlType;
1132 mis->CtlID = mis16->CtlID;
1133 mis->itemID = mis16->itemID;
1134 mis->itemWidth = mis16->itemWidth;
1135 mis->itemHeight = mis16->itemHeight;
1136 mis->itemData = mis16->itemData;
1137 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1138 *plparam = (LPARAM)mis;
1140 return 1;
1141 case WM_DRAWITEM:
1143 DRAWITEMSTRUCT16* dis16 = MapSL(*plparam);
1144 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(GetProcessHeap(), 0,
1145 sizeof(*dis));
1146 if (!dis) return -1;
1147 dis->CtlType = dis16->CtlType;
1148 dis->CtlID = dis16->CtlID;
1149 dis->itemID = dis16->itemID;
1150 dis->itemAction = dis16->itemAction;
1151 dis->itemState = dis16->itemState;
1152 dis->hwndItem = dis16->hwndItem;
1153 dis->hDC = dis16->hDC;
1154 dis->itemData = dis16->itemData;
1155 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
1156 *plparam = (LPARAM)dis;
1158 return 1;
1159 case WM_GETMINMAXINFO:
1161 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( GetProcessHeap(), 0,
1162 sizeof(*mmi) + sizeof(LPARAM));
1163 if (!mmi) return -1;
1164 STRUCT32_MINMAXINFO16to32( MapSL(*plparam), mmi );
1165 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1166 *plparam = (LPARAM)mmi;
1168 return 1;
1169 case WM_GETTEXT:
1170 case WM_SETTEXT:
1171 case WM_WININICHANGE:
1172 case WM_DEVMODECHANGE:
1173 case WM_ASKCBFORMATNAME:
1174 *plparam = (LPARAM)MapSL(*plparam);
1175 return 0;
1176 case WM_MDICREATE:
1178 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1179 MDICREATESTRUCTA *cs = HeapAlloc( GetProcessHeap(), 0, sizeof(*cs) + sizeof(LPARAM) );
1180 if (!cs) return -1;
1181 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1182 cs->szTitle = MapSL(cs16->szTitle);
1183 cs->szClass = MapSL(cs16->szClass);
1184 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1185 *plparam = (LPARAM)cs;
1187 return 1;
1188 case WM_MDIGETACTIVE:
1189 *plparam = (LPARAM)HeapAlloc( GetProcessHeap(), 0, sizeof(BOOL) );
1190 *(BOOL*)(*plparam) = 0;
1191 return 1;
1192 case WM_MDISETMENU:
1193 if(wParam16==TRUE)
1194 *pmsg32=WM_MDIREFRESHMENU;
1195 *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
1196 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1197 return 0;
1198 case WM_MENUCHAR:
1199 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1200 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1201 return 0;
1202 case WM_MENUSELECT:
1203 if((LOWORD(*plparam) & MF_POPUP) && (LOWORD(*plparam) != 0xFFFF))
1205 HMENU hmenu=(HMENU)HIWORD(*plparam);
1206 UINT Pos=MENU_FindSubMenu( &hmenu, wParam16);
1207 if(Pos==0xFFFF) Pos=0; /* NO_SELECTED_ITEM */
1208 *pwparam32 = MAKEWPARAM( Pos, LOWORD(*plparam) );
1210 else *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1211 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1212 return 0;
1213 case WM_MDIACTIVATE:
1214 if( *plparam )
1216 *pwparam32 = (WPARAM)(HWND)HIWORD(*plparam);
1217 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1219 else /* message sent to MDI client */
1220 *pwparam32 = wParam16;
1221 return 0;
1222 case WM_NCCALCSIZE:
1224 NCCALCSIZE_PARAMS16 *nc16;
1225 NCCALCSIZE_PARAMS *nc;
1227 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( GetProcessHeap(), 0,
1228 sizeof(*nc) + sizeof(LPARAM) );
1229 if (!nc) return -1;
1230 nc16 = MapSL(*plparam);
1231 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1232 if (wParam16)
1234 nc->lppos = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1235 sizeof(*nc->lppos) );
1236 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1237 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1238 if (nc->lppos) STRUCT32_WINDOWPOS16to32( MapSL(nc16->lppos), nc->lppos );
1240 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1241 *plparam = (LPARAM)nc;
1243 return 1;
1244 case WM_NCCREATE:
1245 case WM_CREATE:
1247 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1248 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( GetProcessHeap(), 0,
1249 sizeof(*cs) + sizeof(LPARAM) );
1250 if (!cs) return -1;
1251 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1252 cs->lpszName = MapSL(cs16->lpszName);
1253 cs->lpszClass = MapSL(cs16->lpszClass);
1254 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1255 *plparam = (LPARAM)cs;
1257 return 1;
1258 case WM_PARENTNOTIFY:
1259 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1261 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1262 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1264 return 0;
1265 case WM_WINDOWPOSCHANGING:
1266 case WM_WINDOWPOSCHANGED:
1268 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( GetProcessHeap(), 0,
1269 sizeof(*wp) + sizeof(LPARAM) );
1270 if (!wp) return -1;
1271 STRUCT32_WINDOWPOS16to32( MapSL(*plparam), wp );
1272 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1273 *plparam = (LPARAM)wp;
1275 return 1;
1276 case WM_GETDLGCODE:
1277 if (*plparam)
1279 LPMSG16 msg16 = MapSL(*plparam);
1280 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1282 if (!msg32) return -1;
1283 msg32->hwnd = msg16->hwnd;
1284 msg32->lParam = msg16->lParam;
1285 msg32->time = msg16->time;
1286 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1287 /* this is right, right? */
1288 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
1289 &msg32->message,&msg32->wParam,
1290 &msg32->lParam)<0) {
1291 HeapFree( GetProcessHeap(), 0, msg32 );
1292 return -1;
1294 *plparam = (LPARAM)msg32;
1295 return 1;
1297 else return 0;
1298 case WM_NOTIFY:
1299 *plparam = (LPARAM)MapSL(*plparam);
1300 return 0;
1301 case WM_ACTIVATEAPP:
1302 if (*plparam)
1303 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1304 a 32bit window. Might be superflous with 32bit interprocess
1305 message queues.
1307 HTASK16 htask = (HTASK16) *plparam;
1308 DWORD idThread = (DWORD)TASK_GetPtr(htask)->teb->tid;
1309 *plparam = (LPARAM) idThread;
1311 return 0;
1312 case WM_NEXTMENU:
1314 MDINEXTMENU *next = HeapAlloc( GetProcessHeap(), 0, sizeof(*next) );
1315 if (!next) return -1;
1316 next->hmenuIn = *plparam;
1317 next->hmenuNext = 0;
1318 next->hwndNext = 0;
1319 *plparam = (LPARAM)next;
1320 return 1;
1322 case WM_PAINTCLIPBOARD:
1323 case WM_SIZECLIPBOARD:
1324 FIXME_(msg)("message %04x needs translation\n",msg16 );
1325 return -1;
1327 default: /* No translation needed */
1328 return 0;
1333 /**********************************************************************
1334 * WINPROC_UnmapMsg16To32A
1336 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1338 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1339 LRESULT result )
1341 switch(msg)
1343 case WM_COMPAREITEM:
1344 case WM_DELETEITEM:
1345 case WM_DRAWITEM:
1346 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1347 break;
1348 case WM_MEASUREITEM:
1350 MEASUREITEMSTRUCT16 *mis16;
1351 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1352 lParam = *(LPARAM *)(mis + 1);
1353 mis16 = MapSL(lParam);
1354 mis16->itemWidth = (UINT16)mis->itemWidth;
1355 mis16->itemHeight = (UINT16)mis->itemHeight;
1356 HeapFree( GetProcessHeap(), 0, mis );
1358 break;
1359 case WM_GETMINMAXINFO:
1361 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1362 lParam = *(LPARAM *)(mmi + 1);
1363 STRUCT32_MINMAXINFO32to16( mmi, MapSL(lParam));
1364 HeapFree( GetProcessHeap(), 0, mmi );
1366 break;
1367 case WM_MDICREATE:
1369 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1370 lParam = *(LPARAM *)(cs + 1);
1371 STRUCT32_MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1372 HeapFree( GetProcessHeap(), 0, cs );
1374 break;
1375 case WM_MDIGETACTIVE:
1376 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1377 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1378 break;
1379 case WM_NCCALCSIZE:
1381 NCCALCSIZE_PARAMS16 *nc16;
1382 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1383 lParam = *(LPARAM *)(nc + 1);
1384 nc16 = MapSL(lParam);
1385 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1386 if (wParam)
1388 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1389 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1390 if (nc->lppos)
1392 STRUCT32_WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1393 HeapFree( GetProcessHeap(), 0, nc->lppos );
1396 HeapFree( GetProcessHeap(), 0, nc );
1398 break;
1399 case WM_NCCREATE:
1400 case WM_CREATE:
1402 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1403 lParam = *(LPARAM *)(cs + 1);
1404 STRUCT32_CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1405 HeapFree( GetProcessHeap(), 0, cs );
1407 break;
1408 case WM_WINDOWPOSCHANGING:
1409 case WM_WINDOWPOSCHANGED:
1411 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1412 lParam = *(LPARAM *)(wp + 1);
1413 STRUCT32_WINDOWPOS32to16(wp, MapSL(lParam));
1414 HeapFree( GetProcessHeap(), 0, wp );
1416 break;
1417 case WM_GETDLGCODE:
1418 if (lParam)
1420 LPMSG msg32 = (LPMSG)lParam;
1422 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1423 result);
1424 HeapFree( GetProcessHeap(), 0, msg32 );
1426 break;
1427 case WM_NEXTMENU:
1429 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
1430 result = MAKELONG( next->hmenuNext, next->hwndNext );
1431 HeapFree( GetProcessHeap(), 0, next );
1433 break;
1435 return result;
1439 /**********************************************************************
1440 * WINPROC_MapMsg16To32W
1442 * Map a message from 16- to 32-bit Unicode.
1443 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1445 INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1446 WPARAM *pwparam32, LPARAM *plparam )
1448 char ch;
1449 WCHAR wch;
1451 *pmsg32=(UINT)msg16;
1452 *pwparam32 = (WPARAM)wParam16;
1453 switch(msg16)
1455 case WM_GETTEXT:
1456 case WM_SETTEXT:
1457 case WM_WININICHANGE:
1458 case WM_DEVMODECHANGE:
1459 case WM_ASKCBFORMATNAME:
1460 *plparam = (LPARAM)MapSL(*plparam);
1461 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1462 case WM_GETTEXTLENGTH:
1463 case CB_GETLBTEXTLEN:
1464 case LB_GETTEXTLEN:
1465 return 1; /* need to map result */
1466 case WM_NCCREATE:
1467 case WM_CREATE:
1469 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1470 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1471 sizeof(*cs) + sizeof(LPARAM) );
1472 if (!cs) return -1;
1473 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1474 cs->lpszName = MapSL(cs16->lpszName);
1475 cs->lpszClass = MapSL(cs16->lpszClass);
1476 if (HIWORD(cs->lpszName))
1477 cs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
1478 (LPCSTR)cs->lpszName );
1479 if (HIWORD(cs->lpszClass))
1480 cs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
1481 (LPCSTR)cs->lpszClass );
1482 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1483 *plparam = (LPARAM)cs;
1485 return 1;
1486 case WM_MDICREATE:
1488 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1489 MDICREATESTRUCTW *cs =
1490 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1491 sizeof(*cs) + sizeof(LPARAM) );
1492 if (!cs) return -1;
1493 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1494 cs->szTitle = MapSL(cs16->szTitle);
1495 cs->szClass = MapSL(cs16->szClass);
1496 if (HIWORD(cs->szTitle))
1497 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
1498 (LPCSTR)cs->szTitle );
1499 if (HIWORD(cs->szClass))
1500 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
1501 (LPCSTR)cs->szClass );
1502 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1503 *plparam = (LPARAM)cs;
1505 return 1;
1506 case WM_GETDLGCODE:
1507 if (*plparam)
1509 LPMSG16 msg16 = MapSL(*plparam);
1510 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1512 if (!msg32) return -1;
1513 msg32->hwnd = msg16->hwnd;
1514 msg32->lParam = msg16->lParam;
1515 msg32->time = msg16->time;
1516 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1517 /* this is right, right? */
1518 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1519 &msg32->message,&msg32->wParam,
1520 &msg32->lParam)<0) {
1521 HeapFree( GetProcessHeap(), 0, msg32 );
1522 return -1;
1524 *plparam = (LPARAM)msg32;
1525 return 1;
1527 else return 0;
1529 case WM_CHARTOITEM:
1530 ch = wParam16;
1531 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1532 *pwparam32 = MAKEWPARAM( wch, HIWORD(*plparam) );
1533 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1534 return 0;
1535 case WM_MENUCHAR:
1536 ch = wParam16;
1537 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1538 *pwparam32 = MAKEWPARAM( wch, LOWORD(*plparam) );
1539 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1540 return 0;
1541 case WM_CHAR:
1542 case WM_DEADCHAR:
1543 case WM_SYSCHAR:
1544 case WM_SYSDEADCHAR:
1545 ch = wParam16;
1546 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1547 *pwparam32 = wch;
1548 return 0;
1550 default: /* No Unicode translation needed */
1551 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1552 pwparam32, plparam );
1557 /**********************************************************************
1558 * WINPROC_UnmapMsg16To32W
1560 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1562 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1563 LRESULT result )
1565 switch(msg)
1567 case WM_GETTEXT:
1568 case WM_SETTEXT:
1569 case WM_GETTEXTLENGTH:
1570 case CB_GETLBTEXTLEN:
1571 case LB_GETTEXTLEN:
1572 case WM_ASKCBFORMATNAME:
1573 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
1574 case WM_NCCREATE:
1575 case WM_CREATE:
1577 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1578 lParam = *(LPARAM *)(cs + 1);
1579 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1580 if (HIWORD(cs->lpszName))
1581 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
1582 if (HIWORD(cs->lpszClass))
1583 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
1584 HeapFree( GetProcessHeap(), 0, cs );
1586 break;
1587 case WM_MDICREATE:
1589 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1590 lParam = *(LPARAM *)(cs + 1);
1591 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1592 if (HIWORD(cs->szTitle))
1593 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
1594 if (HIWORD(cs->szClass))
1595 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
1596 HeapFree( GetProcessHeap(), 0, cs );
1598 break;
1599 case WM_GETDLGCODE:
1600 if (lParam)
1602 LPMSG msg32 = (LPMSG)lParam;
1604 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1605 result);
1606 HeapFree( GetProcessHeap(), 0, msg32 );
1608 break;
1609 default:
1610 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1612 return result;
1616 /**********************************************************************
1617 * WINPROC_MapMsg32ATo16
1619 * Map a message from 32-bit Ansi to 16-bit.
1620 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1622 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1623 UINT16 *pmsg16, WPARAM16 *pwparam16,
1624 LPARAM *plparam )
1626 *pmsg16 = (UINT16)msg32;
1627 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1628 switch(msg32)
1630 case BM_GETCHECK:
1631 case BM_SETCHECK:
1632 case BM_GETSTATE:
1633 case BM_SETSTATE:
1634 case BM_SETSTYLE:
1635 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1636 return 0;
1638 case EM_GETSEL:
1639 case EM_GETRECT:
1640 case EM_SETRECT:
1641 case EM_SETRECTNP:
1642 case EM_SCROLL:
1643 case EM_LINESCROLL:
1644 case EM_SCROLLCARET:
1645 case EM_GETMODIFY:
1646 case EM_SETMODIFY:
1647 case EM_GETLINECOUNT:
1648 case EM_LINEINDEX:
1649 case EM_SETHANDLE:
1650 case EM_GETHANDLE:
1651 case EM_GETTHUMB:
1652 case EM_LINELENGTH:
1653 case EM_REPLACESEL:
1654 case EM_GETLINE:
1655 case EM_LIMITTEXT:
1656 case EM_CANUNDO:
1657 case EM_UNDO:
1658 case EM_FMTLINES:
1659 case EM_LINEFROMCHAR:
1660 case EM_SETTABSTOPS:
1661 case EM_SETPASSWORDCHAR:
1662 case EM_EMPTYUNDOBUFFER:
1663 case EM_GETFIRSTVISIBLELINE:
1664 case EM_SETREADONLY:
1665 case EM_SETWORDBREAKPROC:
1666 case EM_GETWORDBREAKPROC:
1667 case EM_GETPASSWORDCHAR:
1668 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1669 return 0;
1671 case LB_CARETOFF:
1672 case LB_CARETON:
1673 case LB_DELETESTRING:
1674 case LB_GETANCHORINDEX:
1675 case LB_GETCARETINDEX:
1676 case LB_GETCOUNT:
1677 case LB_GETCURSEL:
1678 case LB_GETHORIZONTALEXTENT:
1679 case LB_GETITEMDATA:
1680 case LB_GETITEMHEIGHT:
1681 case LB_GETSEL:
1682 case LB_GETSELCOUNT:
1683 case LB_GETTEXTLEN:
1684 case LB_GETTOPINDEX:
1685 case LB_RESETCONTENT:
1686 case LB_SELITEMRANGE:
1687 case LB_SELITEMRANGEEX:
1688 case LB_SETANCHORINDEX:
1689 case LB_SETCARETINDEX:
1690 case LB_SETCOLUMNWIDTH:
1691 case LB_SETCURSEL:
1692 case LB_SETHORIZONTALEXTENT:
1693 case LB_SETITEMDATA:
1694 case LB_SETITEMHEIGHT:
1695 case LB_SETSEL:
1696 case LB_SETTOPINDEX:
1697 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1698 return 0;
1699 case CB_DELETESTRING:
1700 case CB_GETCOUNT:
1701 case CB_GETLBTEXTLEN:
1702 case CB_LIMITTEXT:
1703 case CB_RESETCONTENT:
1704 case CB_SETEDITSEL:
1705 case CB_GETCURSEL:
1706 case CB_SETCURSEL:
1707 case CB_SHOWDROPDOWN:
1708 case CB_SETITEMDATA:
1709 case CB_SETITEMHEIGHT:
1710 case CB_GETITEMHEIGHT:
1711 case CB_SETEXTENDEDUI:
1712 case CB_GETEXTENDEDUI:
1713 case CB_GETDROPPEDSTATE:
1714 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1715 return 0;
1716 case CB_GETEDITSEL:
1717 *pmsg16 = CB_GETEDITSEL16;
1718 return 1;
1720 case LB_ADDSTRING:
1721 case LB_FINDSTRING:
1722 case LB_FINDSTRINGEXACT:
1723 case LB_INSERTSTRING:
1724 case LB_SELECTSTRING:
1725 case LB_DIR:
1726 case LB_ADDFILE:
1728 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1729 if (!str) return -1;
1730 *plparam = (LPARAM)SEGPTR_GET(str);
1732 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1733 return 1;
1735 case CB_ADDSTRING:
1736 case CB_FINDSTRING:
1737 case CB_FINDSTRINGEXACT:
1738 case CB_INSERTSTRING:
1739 case CB_SELECTSTRING:
1740 case CB_DIR:
1742 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1743 if (!str) return -1;
1744 *plparam = (LPARAM)SEGPTR_GET(str);
1746 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1747 return 1;
1749 case LB_GETITEMRECT:
1751 RECT16 *rect;
1752 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1753 if (!rect) return -1;
1754 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1755 *plparam = (LPARAM)SEGPTR_GET(rect);
1757 *pmsg16 = LB_GETITEMRECT16;
1758 return 1;
1759 case LB_GETSELITEMS:
1761 LPINT16 items;
1762 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1763 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1764 + sizeof(LPARAM)))) return -1;
1765 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1766 *plparam = (LPARAM)SEGPTR_GET(items);
1768 *pmsg16 = LB_GETSELITEMS16;
1769 return 1;
1770 case LB_SETTABSTOPS:
1771 if (wParam32)
1773 INT i;
1774 LPINT16 stops;
1775 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1776 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1777 + sizeof(LPARAM)))) return -1;
1778 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1779 *plparam = (LPARAM)SEGPTR_GET(stops);
1780 return 1;
1782 *pmsg16 = LB_SETTABSTOPS16;
1783 return 0;
1785 case CB_GETDROPPEDCONTROLRECT:
1787 RECT16 *rect;
1788 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1789 if (!rect) return -1;
1790 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1791 *plparam = (LPARAM)SEGPTR_GET(rect);
1793 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1794 return 1;
1796 case LB_GETTEXT:
1797 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1798 *pmsg16 = LB_GETTEXT16;
1799 return 1;
1801 case CB_GETLBTEXT:
1802 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1803 *pmsg16 = CB_GETLBTEXT16;
1804 return 1;
1806 case EM_SETSEL:
1807 *pwparam16 = 0;
1808 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1809 *pmsg16 = EM_SETSEL16;
1810 return 0;
1812 case WM_ACTIVATE:
1813 case WM_CHARTOITEM:
1814 case WM_COMMAND:
1815 case WM_VKEYTOITEM:
1816 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1817 return 0;
1818 case WM_HSCROLL:
1819 case WM_VSCROLL:
1820 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1821 return 0;
1822 case WM_CTLCOLORMSGBOX:
1823 case WM_CTLCOLOREDIT:
1824 case WM_CTLCOLORLISTBOX:
1825 case WM_CTLCOLORBTN:
1826 case WM_CTLCOLORDLG:
1827 case WM_CTLCOLORSCROLLBAR:
1828 case WM_CTLCOLORSTATIC:
1829 *pmsg16 = WM_CTLCOLOR;
1830 *plparam = MAKELPARAM( (HWND16)*plparam,
1831 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1832 return 0;
1833 case WM_COMPAREITEM:
1835 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1836 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1837 if (!cis) return -1;
1838 cis->CtlType = (UINT16)cis32->CtlType;
1839 cis->CtlID = (UINT16)cis32->CtlID;
1840 cis->hwndItem = (HWND16)cis32->hwndItem;
1841 cis->itemID1 = (UINT16)cis32->itemID1;
1842 cis->itemData1 = cis32->itemData1;
1843 cis->itemID2 = (UINT16)cis32->itemID2;
1844 cis->itemData2 = cis32->itemData2;
1845 *plparam = (LPARAM)SEGPTR_GET(cis);
1847 return 1;
1848 case WM_DELETEITEM:
1850 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1851 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1852 if (!dis) return -1;
1853 dis->CtlType = (UINT16)dis32->CtlType;
1854 dis->CtlID = (UINT16)dis32->CtlID;
1855 dis->itemID = (UINT16)dis32->itemID;
1856 dis->hwndItem = (HWND16)dis32->hwndItem;
1857 dis->itemData = dis32->itemData;
1858 *plparam = (LPARAM)SEGPTR_GET(dis);
1860 return 1;
1861 case WM_DRAWITEM:
1863 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1864 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1865 if (!dis) return -1;
1866 dis->CtlType = (UINT16)dis32->CtlType;
1867 dis->CtlID = (UINT16)dis32->CtlID;
1868 dis->itemID = (UINT16)dis32->itemID;
1869 dis->itemAction = (UINT16)dis32->itemAction;
1870 dis->itemState = (UINT16)dis32->itemState;
1871 dis->hwndItem = (HWND16)dis32->hwndItem;
1872 dis->hDC = (HDC16)dis32->hDC;
1873 dis->itemData = dis32->itemData;
1874 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1875 *plparam = (LPARAM)SEGPTR_GET(dis);
1877 return 1;
1878 case WM_MEASUREITEM:
1880 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1881 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1882 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1883 if (!mis) return -1;
1884 mis->CtlType = (UINT16)mis32->CtlType;
1885 mis->CtlID = (UINT16)mis32->CtlID;
1886 mis->itemID = (UINT16)mis32->itemID;
1887 mis->itemWidth = (UINT16)mis32->itemWidth;
1888 mis->itemHeight = (UINT16)mis32->itemHeight;
1889 mis->itemData = mis32->itemData;
1890 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1891 *plparam = (LPARAM)SEGPTR_GET(mis);
1893 return 1;
1894 case WM_GETMINMAXINFO:
1896 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1897 sizeof(LPARAM) );
1898 if (!mmi) return -1;
1899 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1900 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1901 *plparam = (LPARAM)SEGPTR_GET(mmi);
1903 return 1;
1904 case WM_GETTEXT:
1905 case WM_ASKCBFORMATNAME:
1907 LPSTR str;
1908 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
1909 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1910 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1911 *plparam = (LPARAM)SEGPTR_GET(str);
1913 return 1;
1914 case WM_MDICREATE:
1916 MDICREATESTRUCT16 *cs;
1917 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1918 LPSTR name, cls;
1920 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1921 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1922 name = SEGPTR_STRDUP( cs32->szTitle );
1923 cls = SEGPTR_STRDUP( cs32->szClass );
1924 cs->szTitle = SEGPTR_GET(name);
1925 cs->szClass = SEGPTR_GET(cls);
1926 *plparam = (LPARAM)SEGPTR_GET(cs);
1928 return 1;
1929 case WM_MDIGETACTIVE:
1930 return 1;
1931 case WM_MDISETMENU:
1932 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1933 (HMENU16)LOWORD(*plparam) );
1934 *pwparam16 = (*plparam == 0);
1935 return 0;
1936 case WM_MENUSELECT:
1937 if(HIWORD(wParam32) & MF_POPUP)
1939 UINT16 hmenu;
1940 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
1942 if((hmenu = GetSubMenu((HMENU16)*plparam, *pwparam16)))
1943 *pwparam16=hmenu;
1946 /* fall through */
1947 case WM_MENUCHAR:
1948 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1949 return 0;
1950 case WM_MDIACTIVATE:
1951 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
1953 *pwparam16 = ((HWND)*plparam == hwnd);
1954 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1955 (HWND16)LOWORD(wParam32) );
1957 else
1959 *pwparam16 = (HWND)wParam32;
1960 *plparam = 0;
1962 return 0;
1963 case WM_NCCALCSIZE:
1965 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1966 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1967 if (!nc) return -1;
1969 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1970 if (wParam32)
1972 WINDOWPOS16 *wp;
1973 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1974 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1975 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1977 SEGPTR_FREE(nc);
1978 return -1;
1980 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1981 nc->lppos = SEGPTR_GET(wp);
1983 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1984 *plparam = (LPARAM)SEGPTR_GET(nc);
1986 return 1;
1987 case WM_NCCREATE:
1988 case WM_CREATE:
1990 CREATESTRUCT16 *cs;
1991 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1992 LPSTR name, cls;
1994 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1995 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1996 name = SEGPTR_STRDUP( cs32->lpszName );
1997 cls = SEGPTR_STRDUP( cs32->lpszClass );
1998 cs->lpszName = SEGPTR_GET(name);
1999 cs->lpszClass = SEGPTR_GET(cls);
2000 *plparam = (LPARAM)SEGPTR_GET(cs);
2002 return 1;
2003 case WM_PARENTNOTIFY:
2004 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
2005 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
2006 /* else nothing to do */
2007 return 0;
2008 case WM_NOTIFY:
2009 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
2010 return 1;
2011 case WM_SETTEXT:
2012 case WM_WININICHANGE:
2013 case WM_DEVMODECHANGE:
2015 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
2016 if (!str) return -1;
2017 *plparam = (LPARAM)SEGPTR_GET(str);
2019 return 1;
2020 case WM_WINDOWPOSCHANGING:
2021 case WM_WINDOWPOSCHANGED:
2023 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
2024 sizeof(LPARAM) );
2025 if (!wp) return -1;
2026 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
2027 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
2028 *plparam = (LPARAM)SEGPTR_GET(wp);
2030 return 1;
2031 case WM_GETDLGCODE:
2032 if (*plparam) {
2033 LPMSG msg32 = (LPMSG) *plparam;
2034 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
2036 if (!msg16) return -1;
2037 msg16->hwnd = msg32->hwnd;
2038 msg16->lParam = msg32->lParam;
2039 msg16->time = msg32->time;
2040 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
2041 /* this is right, right? */
2042 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
2043 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
2044 SEGPTR_FREE( msg16 );
2045 return -1;
2047 *plparam = (LPARAM)SEGPTR_GET(msg16);
2048 return 1;
2050 return 0;
2052 case WM_ACTIVATEAPP:
2053 if (*plparam) *plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
2054 return 0;
2055 case WM_NEXTMENU:
2057 MDINEXTMENU *next = (MDINEXTMENU *)*plparam;
2058 *plparam = next->hmenuIn;
2059 return 1;
2061 case WM_PAINTCLIPBOARD:
2062 case WM_SIZECLIPBOARD:
2063 FIXME_(msg)("message %04x needs translation\n", msg32 );
2064 return -1;
2065 /* following messages should not be sent to 16-bit apps */
2066 case WM_SIZING:
2067 case WM_MOVING:
2068 case WM_CAPTURECHANGED:
2069 case WM_STYLECHANGING:
2070 case WM_STYLECHANGED:
2071 return -1;
2072 default: /* No translation needed */
2073 return 0;
2078 /**********************************************************************
2079 * WINPROC_UnmapMsg32ATo16
2081 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2083 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2084 MSGPARAM16* p16 )
2086 switch(msg)
2088 case LB_ADDFILE:
2089 case LB_ADDSTRING:
2090 case LB_DIR:
2091 case LB_FINDSTRING:
2092 case LB_FINDSTRINGEXACT:
2093 case LB_INSERTSTRING:
2094 case LB_SELECTSTRING:
2095 case LB_SETTABSTOPS:
2096 case CB_ADDSTRING:
2097 case CB_FINDSTRING:
2098 case CB_FINDSTRINGEXACT:
2099 case CB_INSERTSTRING:
2100 case CB_SELECTSTRING:
2101 case CB_DIR:
2102 case WM_COMPAREITEM:
2103 case WM_DELETEITEM:
2104 case WM_DRAWITEM:
2105 case WM_SETTEXT:
2106 case WM_WININICHANGE:
2107 case WM_DEVMODECHANGE:
2108 SEGPTR_FREE( MapSL(p16->lParam) );
2109 break;
2111 case CB_GETDROPPEDCONTROLRECT:
2112 case LB_GETITEMRECT:
2114 RECT16 *rect = MapSL(p16->lParam);
2115 p16->lParam = *(LPARAM *)(rect + 1);
2116 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
2117 SEGPTR_FREE( rect );
2119 break;
2120 case LB_GETSELITEMS:
2122 INT i;
2123 LPINT16 items = MapSL(lParam);
2124 p16->lParam = *((LPARAM *)items - 1);
2125 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
2126 SEGPTR_FREE( (LPARAM *)items - 1 );
2128 break;
2130 case CB_GETEDITSEL:
2131 if( wParam )
2132 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
2133 if( lParam )
2134 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
2135 break;
2137 case LB_GETTEXT:
2138 case CB_GETLBTEXT:
2139 UnMapLS( (SEGPTR)(p16->lParam) );
2140 break;
2142 case WM_MEASUREITEM:
2144 MEASUREITEMSTRUCT16 *mis = MapSL(p16->lParam);
2145 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2146 mis32->itemWidth = mis->itemWidth;
2147 mis32->itemHeight = mis->itemHeight;
2148 SEGPTR_FREE(mis);
2150 break;
2151 case WM_GETMINMAXINFO:
2153 MINMAXINFO16 *mmi = MapSL(p16->lParam);
2154 p16->lParam = *(LPARAM *)(mmi + 1);
2155 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2156 SEGPTR_FREE(mmi);
2158 break;
2159 case WM_GETTEXT:
2160 case WM_ASKCBFORMATNAME:
2162 LPSTR str = MapSL(p16->lParam);
2163 p16->lParam = *((LPARAM *)str - 1);
2164 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2165 SEGPTR_FREE( (LPARAM *)str - 1 );
2167 break;
2168 case WM_MDICREATE:
2170 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2171 SEGPTR_FREE( MapSL(cs->szTitle) );
2172 SEGPTR_FREE( MapSL(cs->szClass) );
2173 SEGPTR_FREE( cs );
2175 break;
2176 case WM_MDIGETACTIVE:
2177 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2178 p16->lResult = (HWND)LOWORD(p16->lResult);
2179 break;
2180 case WM_NCCALCSIZE:
2182 NCCALCSIZE_PARAMS *nc32;
2183 NCCALCSIZE_PARAMS16 *nc = MapSL(p16->lParam);
2184 p16->lParam = *(LPARAM *)(nc + 1);
2185 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2186 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
2187 if (p16->wParam)
2189 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
2190 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
2191 STRUCT32_WINDOWPOS16to32( MapSL(nc->lppos), nc32->lppos );
2192 SEGPTR_FREE( MapSL(nc->lppos) );
2194 SEGPTR_FREE(nc);
2196 break;
2197 case WM_NCCREATE:
2198 case WM_CREATE:
2200 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2201 SEGPTR_FREE( MapSL(cs->lpszName) );
2202 SEGPTR_FREE( MapSL(cs->lpszClass) );
2203 SEGPTR_FREE( cs );
2205 break;
2206 case WM_WINDOWPOSCHANGING:
2207 case WM_WINDOWPOSCHANGED:
2209 WINDOWPOS16 *wp = MapSL(p16->lParam);
2210 p16->lParam = *(LPARAM *)(wp + 1);
2211 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2212 SEGPTR_FREE(wp);
2214 break;
2215 case WM_NOTIFY:
2216 UnMapLS(p16->lParam);
2217 break;
2218 case WM_GETDLGCODE:
2219 if (p16->lParam)
2221 LPMSG16 msg16 = MapSL(p16->lParam);
2222 MSGPARAM16 msgp16;
2223 msgp16.wParam=msg16->wParam;
2224 msgp16.lParam=msg16->lParam;
2225 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2226 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2227 &msgp16 );
2228 SEGPTR_FREE(msg16);
2230 break;
2231 case WM_NEXTMENU:
2233 MDINEXTMENU *next = (MDINEXTMENU *)lParam;
2234 next->hmenuNext = LOWORD(p16->lResult);
2235 next->hwndNext = HIWORD(p16->lResult);
2236 p16->lResult = 0;
2238 break;
2243 /**********************************************************************
2244 * WINPROC_MapMsg32WTo16
2246 * Map a message from 32-bit Unicode to 16-bit.
2247 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2249 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2250 UINT16 *pmsg16, WPARAM16 *pwparam16,
2251 LPARAM *plparam )
2253 char ch;
2254 WCHAR wch;
2256 *pmsg16 = LOWORD(msg32);
2257 *pwparam16 = LOWORD(wParam32);
2258 switch(msg32)
2260 case LB_ADDSTRING:
2261 case LB_FINDSTRING:
2262 case LB_FINDSTRINGEXACT:
2263 case LB_INSERTSTRING:
2264 case LB_SELECTSTRING:
2265 case LB_DIR:
2266 case LB_ADDFILE:
2268 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2269 if (!str) return -1;
2270 *plparam = (LPARAM)SEGPTR_GET(str);
2272 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2273 return 1;
2275 case CB_ADDSTRING:
2276 case CB_FINDSTRING:
2277 case CB_FINDSTRINGEXACT:
2278 case CB_INSERTSTRING:
2279 case CB_SELECTSTRING:
2280 case CB_DIR:
2282 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2283 if (!str) return -1;
2284 *plparam = (LPARAM)SEGPTR_GET(str);
2286 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2287 return 1;
2289 case WM_NCCREATE:
2290 case WM_CREATE:
2292 CREATESTRUCT16 *cs;
2293 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2294 LPSTR name, cls;
2296 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2297 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2298 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
2299 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
2300 cs->lpszName = SEGPTR_GET(name);
2301 cs->lpszClass = SEGPTR_GET(cls);
2302 *plparam = (LPARAM)SEGPTR_GET(cs);
2304 return 1;
2305 case WM_MDICREATE:
2307 MDICREATESTRUCT16 *cs;
2308 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2309 LPSTR name, cls;
2311 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2312 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2313 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2314 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2315 cs->szTitle = SEGPTR_GET(name);
2316 cs->szClass = SEGPTR_GET(cls);
2317 *plparam = (LPARAM)SEGPTR_GET(cs);
2319 return 1;
2320 case WM_SETTEXT:
2322 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2323 if (!str) return -1;
2324 *plparam = (LPARAM)SEGPTR_GET(str);
2326 return 1;
2327 case LB_GETTEXT:
2328 case CB_GETLBTEXT:
2329 if ( WINPROC_TestLBForStr( hwnd ))
2331 LPSTR str = (LPSTR) SEGPTR_ALLOC( 256 ); /* fixme: fixed sized buffer */
2332 if (!str) return -1;
2333 *pmsg16 = (msg32 == LB_GETTEXT)? LB_GETTEXT16 : CB_GETLBTEXT16;
2334 *plparam = (LPARAM)SEGPTR_GET(str);
2336 return 1;
2338 case WM_CHARTOITEM:
2339 wch = LOWORD(wParam32);
2340 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2341 *pwparam16 = ch;
2342 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2343 return 0;
2344 case WM_MENUCHAR:
2345 wch = LOWORD(wParam32);
2346 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2347 *pwparam16 = ch;
2348 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2349 return 0;
2350 case WM_CHAR:
2351 case WM_DEADCHAR:
2352 case WM_SYSCHAR:
2353 case WM_SYSDEADCHAR:
2354 wch = wParam32;
2355 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2356 *pwparam16 = ch;
2357 return 0;
2359 default: /* No Unicode translation needed (?) */
2360 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2361 pwparam16, plparam );
2366 /**********************************************************************
2367 * WINPROC_UnmapMsg32WTo16
2369 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2371 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2372 MSGPARAM16* p16 )
2374 switch(msg)
2376 case WM_GETTEXT:
2377 case WM_ASKCBFORMATNAME:
2379 LPSTR str = MapSL(p16->lParam);
2380 p16->lParam = *((LPARAM *)str - 1);
2381 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)p16->lParam, 0x7fffffff );
2382 SEGPTR_FREE( (LPARAM *)str - 1 );
2384 break;
2385 case LB_GETTEXT:
2386 case CB_GETLBTEXT:
2387 if ( WINPROC_TestLBForStr( hwnd ))
2389 LPSTR str = MapSL(p16->lParam);
2390 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff );
2391 SEGPTR_FREE( (LPARAM *) str );
2393 break;
2394 default:
2395 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2396 break;
2401 /**********************************************************************
2402 * WINPROC_CallProc32ATo32W
2404 * Call a window procedure, translating args from Ansi to Unicode.
2406 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2407 UINT msg, WPARAM wParam,
2408 LPARAM lParam )
2410 LRESULT result;
2411 int unmap;
2413 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2414 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2415 SPY_GetMsgName(msg), wParam, lParam );
2416 return 0;
2418 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2419 if (unmap) result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
2420 return result;
2424 /**********************************************************************
2425 * WINPROC_CallProc32WTo32A
2427 * Call a window procedure, translating args from Unicode to Ansi.
2429 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2430 UINT msg, WPARAM wParam,
2431 LPARAM lParam )
2433 LRESULT result;
2434 int unmap;
2436 if ((unmap = WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam )) == -1) {
2437 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2438 SPY_GetMsgName(msg), wParam, lParam );
2439 return 0;
2441 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2442 if( unmap ) WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2443 return result;
2447 /**********************************************************************
2448 * WINPROC_CallProc16To32A
2450 * Call a 32-bit window procedure, translating the 16-bit args.
2452 static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd,
2453 UINT16 msg, WPARAM16 wParam,
2454 LPARAM lParam )
2456 LRESULT result;
2457 UINT msg32;
2458 WPARAM wParam32;
2460 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2461 return 0;
2462 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2463 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2466 /**********************************************************************
2467 * WINPROC_Thunk16To32A
2469 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args )
2471 HWND16 hwnd = *(HWND16 *)( args+8 );
2472 UINT16 msg = *(HWND16 *)( args+6 );
2473 WPARAM16 wParam = *(HWND16 *)( args+4 );
2474 LPARAM lParam = *(LPARAM *)( args+0 );
2476 return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
2480 /**********************************************************************
2481 * WINPROC_CallProc16To32W
2483 * Call a 32-bit window procedure, translating the 16-bit args.
2485 static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd,
2486 UINT16 msg, WPARAM16 wParam,
2487 LPARAM lParam )
2489 LRESULT result;
2490 UINT msg32;
2491 WPARAM wParam32;
2493 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2494 return 0;
2496 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2498 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2501 /**********************************************************************
2502 * WINPROC_Thunk16To32W
2504 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args )
2506 HWND16 hwnd = *(HWND16 *)( args+8 );
2507 UINT16 msg = *(HWND16 *)( args+6 );
2508 WPARAM16 wParam = *(HWND16 *)( args+4 );
2509 LPARAM lParam = *(LPARAM *)( args+0 );
2511 return WINPROC_CallProc16To32W( func, hwnd, msg, wParam, lParam );
2514 /**********************************************************************
2515 * WINPROC_CallProc32ATo16
2517 * Call a 16-bit window procedure, translating the 32-bit args.
2519 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2520 UINT msg, WPARAM wParam,
2521 LPARAM lParam )
2523 UINT16 msg16;
2524 MSGPARAM16 mp16;
2526 mp16.lParam = lParam;
2527 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2528 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2529 return 0;
2530 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2531 mp16.wParam, mp16.lParam );
2532 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2533 return mp16.lResult;
2537 /**********************************************************************
2538 * WINPROC_CallProc32WTo16
2540 * Call a 16-bit window procedure, translating the 32-bit args.
2542 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2543 UINT msg, WPARAM wParam,
2544 LPARAM lParam )
2546 UINT16 msg16;
2547 MSGPARAM16 mp16;
2549 mp16.lParam = lParam;
2550 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2551 &mp16.lParam ) == -1)
2552 return 0;
2553 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2554 mp16.wParam, mp16.lParam );
2555 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2556 return mp16.lResult;
2560 /**********************************************************************
2561 * CallWindowProc (USER.122)
2562 * CallWindowProc16 (USER32.@)
2564 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2565 WPARAM16 wParam, LPARAM lParam )
2567 WINDOWPROC *proc = WINPROC_GetPtr( func );
2569 if (!proc)
2570 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2572 #if testing
2573 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2574 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2575 #endif
2577 switch(proc->type)
2579 case WIN_PROC_16:
2580 if (!proc->thunk.t_from32.proc) return 0;
2581 return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
2582 hwnd, msg, wParam, lParam );
2583 case WIN_PROC_32A:
2584 if (!proc->thunk.t_from16.proc) return 0;
2585 return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc,
2586 hwnd, msg, wParam, lParam );
2587 case WIN_PROC_32W:
2588 if (!proc->thunk.t_from16.proc) return 0;
2589 return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc,
2590 hwnd, msg, wParam, lParam );
2591 default:
2592 WARN_(relay)("Invalid proc %p\n", proc );
2593 return 0;
2598 /**********************************************************************
2599 * CallWindowProcA (USER32.@)
2601 * The CallWindowProc() function invokes the windows procedure _func_,
2602 * with _hwnd_ as the target window, the message specified by _msg_, and
2603 * the message parameters _wParam_ and _lParam_.
2605 * Some kinds of argument conversion may be done, I'm not sure what.
2607 * CallWindowProc() may be used for windows subclassing. Use
2608 * SetWindowLong() to set a new windows procedure for windows of the
2609 * subclass, and handle subclassed messages in the new windows
2610 * procedure. The new windows procedure may then use CallWindowProc()
2611 * with _func_ set to the parent class's windows procedure to dispatch
2612 * the message to the superclass.
2614 * RETURNS
2616 * The return value is message dependent.
2618 * CONFORMANCE
2620 * ECMA-234, Win32
2622 LRESULT WINAPI CallWindowProcA(
2623 WNDPROC func, /* [in] window procedure */
2624 HWND hwnd, /* [in] target window */
2625 UINT msg, /* [in] message */
2626 WPARAM wParam, /* [in] message dependent parameter */
2627 LPARAM lParam /* [in] message dependent parameter */
2629 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2631 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2633 #if testing
2634 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2635 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2636 #endif
2638 switch(proc->type)
2640 case WIN_PROC_16:
2641 if (!proc->thunk.t_from32.proc) return 0;
2642 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2643 hwnd, msg, wParam, lParam );
2644 case WIN_PROC_32A:
2645 if (!proc->thunk.t_from16.proc) return 0;
2646 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2647 hwnd, msg, wParam, lParam );
2648 case WIN_PROC_32W:
2649 if (!proc->thunk.t_from16.proc) return 0;
2650 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2651 hwnd, msg, wParam, lParam );
2652 default:
2653 WARN_(relay)("Invalid proc %p\n", proc );
2654 return 0;
2659 /**********************************************************************
2660 * CallWindowProcW (USER32.@)
2662 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2663 WPARAM wParam, LPARAM lParam )
2665 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2667 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2669 #if testing
2670 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2671 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2672 #endif
2674 switch(proc->type)
2676 case WIN_PROC_16:
2677 if (!proc->thunk.t_from32.proc) return 0;
2678 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2679 hwnd, msg, wParam, lParam );
2680 case WIN_PROC_32A:
2681 if (!proc->thunk.t_from16.proc) return 0;
2682 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2683 hwnd, msg, wParam, lParam );
2684 case WIN_PROC_32W:
2685 if (!proc->thunk.t_from16.proc) return 0;
2686 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2687 hwnd, msg, wParam, lParam );
2688 default:
2689 WARN_(relay)("Invalid proc %p\n", proc );
2690 return 0;