Fixed error message and return value in case of bogus 'open all' mci
[wine.git] / windows / winproc.c
bloba06e241ff6f77ddf92d7514c0f3f8cf886ff58f4
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_PAINTCLIPBOARD:
1313 case WM_SIZECLIPBOARD:
1314 case WM_NEXTMENU:
1315 FIXME_(msg)("message %04x needs translation\n",msg16 );
1316 return -1;
1318 default: /* No translation needed */
1319 return 0;
1324 /**********************************************************************
1325 * WINPROC_UnmapMsg16To32A
1327 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1329 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1330 LRESULT result )
1332 switch(msg)
1334 case WM_COMPAREITEM:
1335 case WM_DELETEITEM:
1336 case WM_DRAWITEM:
1337 HeapFree( GetProcessHeap(), 0, (LPVOID)lParam );
1338 break;
1339 case WM_MEASUREITEM:
1341 MEASUREITEMSTRUCT16 *mis16;
1342 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1343 lParam = *(LPARAM *)(mis + 1);
1344 mis16 = MapSL(lParam);
1345 mis16->itemWidth = (UINT16)mis->itemWidth;
1346 mis16->itemHeight = (UINT16)mis->itemHeight;
1347 HeapFree( GetProcessHeap(), 0, mis );
1349 break;
1350 case WM_GETMINMAXINFO:
1352 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1353 lParam = *(LPARAM *)(mmi + 1);
1354 STRUCT32_MINMAXINFO32to16( mmi, MapSL(lParam));
1355 HeapFree( GetProcessHeap(), 0, mmi );
1357 break;
1358 case WM_MDICREATE:
1360 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1361 lParam = *(LPARAM *)(cs + 1);
1362 STRUCT32_MDICREATESTRUCT32Ato16( cs, MapSL(lParam) );
1363 HeapFree( GetProcessHeap(), 0, cs );
1365 break;
1366 case WM_MDIGETACTIVE:
1367 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1368 HeapFree( GetProcessHeap(), 0, (BOOL *)lParam );
1369 break;
1370 case WM_NCCALCSIZE:
1372 NCCALCSIZE_PARAMS16 *nc16;
1373 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1374 lParam = *(LPARAM *)(nc + 1);
1375 nc16 = MapSL(lParam);
1376 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1377 if (wParam)
1379 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1380 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1381 if (nc->lppos)
1383 STRUCT32_WINDOWPOS32to16( nc->lppos, MapSL(nc16->lppos));
1384 HeapFree( GetProcessHeap(), 0, nc->lppos );
1387 HeapFree( GetProcessHeap(), 0, nc );
1389 break;
1390 case WM_NCCREATE:
1391 case WM_CREATE:
1393 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1394 lParam = *(LPARAM *)(cs + 1);
1395 STRUCT32_CREATESTRUCT32Ato16( cs, MapSL(lParam) );
1396 HeapFree( GetProcessHeap(), 0, cs );
1398 break;
1399 case WM_WINDOWPOSCHANGING:
1400 case WM_WINDOWPOSCHANGED:
1402 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1403 lParam = *(LPARAM *)(wp + 1);
1404 STRUCT32_WINDOWPOS32to16(wp, MapSL(lParam));
1405 HeapFree( GetProcessHeap(), 0, wp );
1407 break;
1408 case WM_GETDLGCODE:
1409 if (lParam)
1411 LPMSG msg32 = (LPMSG)lParam;
1413 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1414 result);
1415 HeapFree( GetProcessHeap(), 0, msg32 );
1417 break;
1419 return result;
1423 /**********************************************************************
1424 * WINPROC_MapMsg16To32W
1426 * Map a message from 16- to 32-bit Unicode.
1427 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1429 INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1430 WPARAM *pwparam32, LPARAM *plparam )
1432 char ch;
1433 WCHAR wch;
1435 *pmsg32=(UINT)msg16;
1436 *pwparam32 = (WPARAM)wParam16;
1437 switch(msg16)
1439 case WM_GETTEXT:
1440 case WM_SETTEXT:
1441 case WM_WININICHANGE:
1442 case WM_DEVMODECHANGE:
1443 case WM_ASKCBFORMATNAME:
1444 *plparam = (LPARAM)MapSL(*plparam);
1445 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, pwparam32, plparam );
1446 case WM_GETTEXTLENGTH:
1447 case CB_GETLBTEXTLEN:
1448 case LB_GETTEXTLEN:
1449 return 1; /* need to map result */
1450 case WM_NCCREATE:
1451 case WM_CREATE:
1453 CREATESTRUCT16 *cs16 = MapSL(*plparam);
1454 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1455 sizeof(*cs) + sizeof(LPARAM) );
1456 if (!cs) return -1;
1457 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1458 cs->lpszName = MapSL(cs16->lpszName);
1459 cs->lpszClass = MapSL(cs16->lpszClass);
1460 if (HIWORD(cs->lpszName))
1461 cs->lpszName = HEAP_strdupAtoW( GetProcessHeap(), 0,
1462 (LPCSTR)cs->lpszName );
1463 if (HIWORD(cs->lpszClass))
1464 cs->lpszClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
1465 (LPCSTR)cs->lpszClass );
1466 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1467 *plparam = (LPARAM)cs;
1469 return 1;
1470 case WM_MDICREATE:
1472 MDICREATESTRUCT16 *cs16 = MapSL(*plparam);
1473 MDICREATESTRUCTW *cs =
1474 (MDICREATESTRUCTW *)HeapAlloc( GetProcessHeap(), 0,
1475 sizeof(*cs) + sizeof(LPARAM) );
1476 if (!cs) return -1;
1477 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1478 cs->szTitle = MapSL(cs16->szTitle);
1479 cs->szClass = MapSL(cs16->szClass);
1480 if (HIWORD(cs->szTitle))
1481 cs->szTitle = HEAP_strdupAtoW( GetProcessHeap(), 0,
1482 (LPCSTR)cs->szTitle );
1483 if (HIWORD(cs->szClass))
1484 cs->szClass = HEAP_strdupAtoW( GetProcessHeap(), 0,
1485 (LPCSTR)cs->szClass );
1486 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1487 *plparam = (LPARAM)cs;
1489 return 1;
1490 case WM_GETDLGCODE:
1491 if (*plparam)
1493 LPMSG16 msg16 = MapSL(*plparam);
1494 LPMSG msg32 = (LPMSG)HeapAlloc( GetProcessHeap(), 0, sizeof(MSG) );
1496 if (!msg32) return -1;
1497 msg32->hwnd = msg16->hwnd;
1498 msg32->lParam = msg16->lParam;
1499 msg32->time = msg16->time;
1500 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1501 /* this is right, right? */
1502 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1503 &msg32->message,&msg32->wParam,
1504 &msg32->lParam)<0) {
1505 HeapFree( GetProcessHeap(), 0, msg32 );
1506 return -1;
1508 *plparam = (LPARAM)msg32;
1509 return 1;
1511 else return 0;
1513 case WM_CHARTOITEM:
1514 ch = wParam16;
1515 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1516 *pwparam32 = MAKEWPARAM( wch, HIWORD(*plparam) );
1517 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1518 return 0;
1519 case WM_MENUCHAR:
1520 ch = wParam16;
1521 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1522 *pwparam32 = MAKEWPARAM( wch, LOWORD(*plparam) );
1523 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1524 return 0;
1525 case WM_CHAR:
1526 case WM_DEADCHAR:
1527 case WM_SYSCHAR:
1528 case WM_SYSDEADCHAR:
1529 ch = wParam16;
1530 MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1);
1531 *pwparam32 = wch;
1532 return 0;
1534 default: /* No Unicode translation needed */
1535 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1536 pwparam32, plparam );
1541 /**********************************************************************
1542 * WINPROC_UnmapMsg16To32W
1544 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1546 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1547 LRESULT result )
1549 switch(msg)
1551 case WM_GETTEXT:
1552 case WM_SETTEXT:
1553 case WM_GETTEXTLENGTH:
1554 case CB_GETLBTEXTLEN:
1555 case LB_GETTEXTLEN:
1556 case WM_ASKCBFORMATNAME:
1557 return WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
1558 case WM_NCCREATE:
1559 case WM_CREATE:
1561 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1562 lParam = *(LPARAM *)(cs + 1);
1563 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs, MapSL(lParam) );
1564 if (HIWORD(cs->lpszName))
1565 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszName );
1566 if (HIWORD(cs->lpszClass))
1567 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->lpszClass );
1568 HeapFree( GetProcessHeap(), 0, cs );
1570 break;
1571 case WM_MDICREATE:
1573 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1574 lParam = *(LPARAM *)(cs + 1);
1575 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs, MapSL(lParam) );
1576 if (HIWORD(cs->szTitle))
1577 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szTitle );
1578 if (HIWORD(cs->szClass))
1579 HeapFree( GetProcessHeap(), 0, (LPVOID)cs->szClass );
1580 HeapFree( GetProcessHeap(), 0, cs );
1582 break;
1583 case WM_GETDLGCODE:
1584 if (lParam)
1586 LPMSG msg32 = (LPMSG)lParam;
1588 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1589 result);
1590 HeapFree( GetProcessHeap(), 0, msg32 );
1592 break;
1593 default:
1594 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1596 return result;
1600 /**********************************************************************
1601 * WINPROC_MapMsg32ATo16
1603 * Map a message from 32-bit Ansi to 16-bit.
1604 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1606 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1607 UINT16 *pmsg16, WPARAM16 *pwparam16,
1608 LPARAM *plparam )
1610 *pmsg16 = (UINT16)msg32;
1611 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1612 switch(msg32)
1614 case BM_GETCHECK:
1615 case BM_SETCHECK:
1616 case BM_GETSTATE:
1617 case BM_SETSTATE:
1618 case BM_SETSTYLE:
1619 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1620 return 0;
1622 case EM_GETSEL:
1623 case EM_GETRECT:
1624 case EM_SETRECT:
1625 case EM_SETRECTNP:
1626 case EM_SCROLL:
1627 case EM_LINESCROLL:
1628 case EM_SCROLLCARET:
1629 case EM_GETMODIFY:
1630 case EM_SETMODIFY:
1631 case EM_GETLINECOUNT:
1632 case EM_LINEINDEX:
1633 case EM_SETHANDLE:
1634 case EM_GETHANDLE:
1635 case EM_GETTHUMB:
1636 case EM_LINELENGTH:
1637 case EM_REPLACESEL:
1638 case EM_GETLINE:
1639 case EM_LIMITTEXT:
1640 case EM_CANUNDO:
1641 case EM_UNDO:
1642 case EM_FMTLINES:
1643 case EM_LINEFROMCHAR:
1644 case EM_SETTABSTOPS:
1645 case EM_SETPASSWORDCHAR:
1646 case EM_EMPTYUNDOBUFFER:
1647 case EM_GETFIRSTVISIBLELINE:
1648 case EM_SETREADONLY:
1649 case EM_SETWORDBREAKPROC:
1650 case EM_GETWORDBREAKPROC:
1651 case EM_GETPASSWORDCHAR:
1652 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1653 return 0;
1655 case LB_CARETOFF:
1656 case LB_CARETON:
1657 case LB_DELETESTRING:
1658 case LB_GETANCHORINDEX:
1659 case LB_GETCARETINDEX:
1660 case LB_GETCOUNT:
1661 case LB_GETCURSEL:
1662 case LB_GETHORIZONTALEXTENT:
1663 case LB_GETITEMDATA:
1664 case LB_GETITEMHEIGHT:
1665 case LB_GETSEL:
1666 case LB_GETSELCOUNT:
1667 case LB_GETTEXTLEN:
1668 case LB_GETTOPINDEX:
1669 case LB_RESETCONTENT:
1670 case LB_SELITEMRANGE:
1671 case LB_SELITEMRANGEEX:
1672 case LB_SETANCHORINDEX:
1673 case LB_SETCARETINDEX:
1674 case LB_SETCOLUMNWIDTH:
1675 case LB_SETCURSEL:
1676 case LB_SETHORIZONTALEXTENT:
1677 case LB_SETITEMDATA:
1678 case LB_SETITEMHEIGHT:
1679 case LB_SETSEL:
1680 case LB_SETTOPINDEX:
1681 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1682 return 0;
1683 case CB_DELETESTRING:
1684 case CB_GETCOUNT:
1685 case CB_GETLBTEXTLEN:
1686 case CB_LIMITTEXT:
1687 case CB_RESETCONTENT:
1688 case CB_SETEDITSEL:
1689 case CB_GETCURSEL:
1690 case CB_SETCURSEL:
1691 case CB_SHOWDROPDOWN:
1692 case CB_SETITEMDATA:
1693 case CB_SETITEMHEIGHT:
1694 case CB_GETITEMHEIGHT:
1695 case CB_SETEXTENDEDUI:
1696 case CB_GETEXTENDEDUI:
1697 case CB_GETDROPPEDSTATE:
1698 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1699 return 0;
1700 case CB_GETEDITSEL:
1701 *pmsg16 = CB_GETEDITSEL16;
1702 return 1;
1704 case LB_ADDSTRING:
1705 case LB_FINDSTRING:
1706 case LB_FINDSTRINGEXACT:
1707 case LB_INSERTSTRING:
1708 case LB_SELECTSTRING:
1709 case LB_DIR:
1710 case LB_ADDFILE:
1712 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1713 if (!str) return -1;
1714 *plparam = (LPARAM)SEGPTR_GET(str);
1716 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1717 return 1;
1719 case CB_ADDSTRING:
1720 case CB_FINDSTRING:
1721 case CB_FINDSTRINGEXACT:
1722 case CB_INSERTSTRING:
1723 case CB_SELECTSTRING:
1724 case CB_DIR:
1726 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1727 if (!str) return -1;
1728 *plparam = (LPARAM)SEGPTR_GET(str);
1730 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1731 return 1;
1733 case LB_GETITEMRECT:
1735 RECT16 *rect;
1736 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1737 if (!rect) return -1;
1738 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1739 *plparam = (LPARAM)SEGPTR_GET(rect);
1741 *pmsg16 = LB_GETITEMRECT16;
1742 return 1;
1743 case LB_GETSELITEMS:
1745 LPINT16 items;
1746 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1747 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1748 + sizeof(LPARAM)))) return -1;
1749 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1750 *plparam = (LPARAM)SEGPTR_GET(items);
1752 *pmsg16 = LB_GETSELITEMS16;
1753 return 1;
1754 case LB_SETTABSTOPS:
1755 if (wParam32)
1757 INT i;
1758 LPINT16 stops;
1759 *pwparam16 = (WPARAM16)min( wParam32, 0x7f80 ); /* Must be < 64K */
1760 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1761 + sizeof(LPARAM)))) return -1;
1762 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1763 *plparam = (LPARAM)SEGPTR_GET(stops);
1764 return 1;
1766 *pmsg16 = LB_SETTABSTOPS16;
1767 return 0;
1769 case CB_GETDROPPEDCONTROLRECT:
1771 RECT16 *rect;
1772 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1773 if (!rect) return -1;
1774 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1775 *plparam = (LPARAM)SEGPTR_GET(rect);
1777 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1778 return 1;
1780 case LB_GETTEXT:
1781 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1782 *pmsg16 = LB_GETTEXT16;
1783 return 1;
1785 case CB_GETLBTEXT:
1786 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1787 *pmsg16 = CB_GETLBTEXT16;
1788 return 1;
1790 case EM_SETSEL:
1791 *pwparam16 = 0;
1792 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1793 *pmsg16 = EM_SETSEL16;
1794 return 0;
1796 case WM_ACTIVATE:
1797 case WM_CHARTOITEM:
1798 case WM_COMMAND:
1799 case WM_VKEYTOITEM:
1800 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1801 return 0;
1802 case WM_HSCROLL:
1803 case WM_VSCROLL:
1804 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1805 return 0;
1806 case WM_CTLCOLORMSGBOX:
1807 case WM_CTLCOLOREDIT:
1808 case WM_CTLCOLORLISTBOX:
1809 case WM_CTLCOLORBTN:
1810 case WM_CTLCOLORDLG:
1811 case WM_CTLCOLORSCROLLBAR:
1812 case WM_CTLCOLORSTATIC:
1813 *pmsg16 = WM_CTLCOLOR;
1814 *plparam = MAKELPARAM( (HWND16)*plparam,
1815 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1816 return 0;
1817 case WM_COMPAREITEM:
1819 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1820 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1821 if (!cis) return -1;
1822 cis->CtlType = (UINT16)cis32->CtlType;
1823 cis->CtlID = (UINT16)cis32->CtlID;
1824 cis->hwndItem = (HWND16)cis32->hwndItem;
1825 cis->itemID1 = (UINT16)cis32->itemID1;
1826 cis->itemData1 = cis32->itemData1;
1827 cis->itemID2 = (UINT16)cis32->itemID2;
1828 cis->itemData2 = cis32->itemData2;
1829 *plparam = (LPARAM)SEGPTR_GET(cis);
1831 return 1;
1832 case WM_DELETEITEM:
1834 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1835 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1836 if (!dis) return -1;
1837 dis->CtlType = (UINT16)dis32->CtlType;
1838 dis->CtlID = (UINT16)dis32->CtlID;
1839 dis->itemID = (UINT16)dis32->itemID;
1840 dis->hwndItem = (HWND16)dis32->hwndItem;
1841 dis->itemData = dis32->itemData;
1842 *plparam = (LPARAM)SEGPTR_GET(dis);
1844 return 1;
1845 case WM_DRAWITEM:
1847 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1848 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1849 if (!dis) return -1;
1850 dis->CtlType = (UINT16)dis32->CtlType;
1851 dis->CtlID = (UINT16)dis32->CtlID;
1852 dis->itemID = (UINT16)dis32->itemID;
1853 dis->itemAction = (UINT16)dis32->itemAction;
1854 dis->itemState = (UINT16)dis32->itemState;
1855 dis->hwndItem = (HWND16)dis32->hwndItem;
1856 dis->hDC = (HDC16)dis32->hDC;
1857 dis->itemData = dis32->itemData;
1858 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1859 *plparam = (LPARAM)SEGPTR_GET(dis);
1861 return 1;
1862 case WM_MEASUREITEM:
1864 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1865 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1866 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1867 if (!mis) return -1;
1868 mis->CtlType = (UINT16)mis32->CtlType;
1869 mis->CtlID = (UINT16)mis32->CtlID;
1870 mis->itemID = (UINT16)mis32->itemID;
1871 mis->itemWidth = (UINT16)mis32->itemWidth;
1872 mis->itemHeight = (UINT16)mis32->itemHeight;
1873 mis->itemData = mis32->itemData;
1874 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1875 *plparam = (LPARAM)SEGPTR_GET(mis);
1877 return 1;
1878 case WM_GETMINMAXINFO:
1880 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1881 sizeof(LPARAM) );
1882 if (!mmi) return -1;
1883 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1884 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1885 *plparam = (LPARAM)SEGPTR_GET(mmi);
1887 return 1;
1888 case WM_GETTEXT:
1889 case WM_ASKCBFORMATNAME:
1891 LPSTR str;
1892 *pwparam16 = (WPARAM16)min( wParam32, 0xff80 ); /* Must be < 64K */
1893 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1894 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1895 *plparam = (LPARAM)SEGPTR_GET(str);
1897 return 1;
1898 case WM_MDICREATE:
1900 MDICREATESTRUCT16 *cs;
1901 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1902 LPSTR name, cls;
1904 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1905 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1906 name = SEGPTR_STRDUP( cs32->szTitle );
1907 cls = SEGPTR_STRDUP( cs32->szClass );
1908 cs->szTitle = SEGPTR_GET(name);
1909 cs->szClass = SEGPTR_GET(cls);
1910 *plparam = (LPARAM)SEGPTR_GET(cs);
1912 return 1;
1913 case WM_MDIGETACTIVE:
1914 return 1;
1915 case WM_MDISETMENU:
1916 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1917 (HMENU16)LOWORD(*plparam) );
1918 *pwparam16 = (*plparam == 0);
1919 return 0;
1920 case WM_MENUSELECT:
1921 if(HIWORD(wParam32) & MF_POPUP)
1923 UINT16 hmenu;
1924 if (((UINT)HIWORD(wParam32) != 0xFFFF) || (*plparam))
1926 if((hmenu = GetSubMenu((HMENU16)*plparam, *pwparam16)))
1927 *pwparam16=hmenu;
1930 /* fall through */
1931 case WM_MENUCHAR:
1932 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1933 return 0;
1934 case WM_MDIACTIVATE:
1935 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_MDICHILD)
1937 *pwparam16 = ((HWND)*plparam == hwnd);
1938 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1939 (HWND16)LOWORD(wParam32) );
1941 else
1943 *pwparam16 = (HWND)wParam32;
1944 *plparam = 0;
1946 return 0;
1947 case WM_NCCALCSIZE:
1949 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1950 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1951 if (!nc) return -1;
1953 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1954 if (wParam32)
1956 WINDOWPOS16 *wp;
1957 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1958 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1959 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1961 SEGPTR_FREE(nc);
1962 return -1;
1964 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1965 nc->lppos = SEGPTR_GET(wp);
1967 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1968 *plparam = (LPARAM)SEGPTR_GET(nc);
1970 return 1;
1971 case WM_NCCREATE:
1972 case WM_CREATE:
1974 CREATESTRUCT16 *cs;
1975 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1976 LPSTR name, cls;
1978 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1979 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1980 name = SEGPTR_STRDUP( cs32->lpszName );
1981 cls = SEGPTR_STRDUP( cs32->lpszClass );
1982 cs->lpszName = SEGPTR_GET(name);
1983 cs->lpszClass = SEGPTR_GET(cls);
1984 *plparam = (LPARAM)SEGPTR_GET(cs);
1986 return 1;
1987 case WM_PARENTNOTIFY:
1988 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1989 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1990 /* else nothing to do */
1991 return 0;
1992 case WM_NOTIFY:
1993 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1994 return 1;
1995 case WM_SETTEXT:
1996 case WM_WININICHANGE:
1997 case WM_DEVMODECHANGE:
1999 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
2000 if (!str) return -1;
2001 *plparam = (LPARAM)SEGPTR_GET(str);
2003 return 1;
2004 case WM_WINDOWPOSCHANGING:
2005 case WM_WINDOWPOSCHANGED:
2007 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
2008 sizeof(LPARAM) );
2009 if (!wp) return -1;
2010 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
2011 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
2012 *plparam = (LPARAM)SEGPTR_GET(wp);
2014 return 1;
2015 case WM_GETDLGCODE:
2016 if (*plparam) {
2017 LPMSG msg32 = (LPMSG) *plparam;
2018 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
2020 if (!msg16) return -1;
2021 msg16->hwnd = msg32->hwnd;
2022 msg16->lParam = msg32->lParam;
2023 msg16->time = msg32->time;
2024 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
2025 /* this is right, right? */
2026 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
2027 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
2028 SEGPTR_FREE( msg16 );
2029 return -1;
2031 *plparam = (LPARAM)SEGPTR_GET(msg16);
2032 return 1;
2034 return 0;
2036 case WM_ACTIVATEAPP:
2037 if (*plparam) *plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
2038 return 0;
2039 case WM_PAINTCLIPBOARD:
2040 case WM_SIZECLIPBOARD:
2041 case WM_NEXTMENU:
2042 FIXME_(msg)("message %04x needs translation\n", msg32 );
2043 return -1;
2044 /* following messages should not be sent to 16-bit apps */
2045 case WM_SIZING:
2046 case WM_MOVING:
2047 case WM_CAPTURECHANGED:
2048 case WM_STYLECHANGING:
2049 case WM_STYLECHANGED:
2050 return -1;
2051 default: /* No translation needed */
2052 return 0;
2057 /**********************************************************************
2058 * WINPROC_UnmapMsg32ATo16
2060 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
2062 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2063 MSGPARAM16* p16 )
2065 switch(msg)
2067 case LB_ADDFILE:
2068 case LB_ADDSTRING:
2069 case LB_DIR:
2070 case LB_FINDSTRING:
2071 case LB_FINDSTRINGEXACT:
2072 case LB_INSERTSTRING:
2073 case LB_SELECTSTRING:
2074 case LB_SETTABSTOPS:
2075 case CB_ADDSTRING:
2076 case CB_FINDSTRING:
2077 case CB_FINDSTRINGEXACT:
2078 case CB_INSERTSTRING:
2079 case CB_SELECTSTRING:
2080 case CB_DIR:
2081 case WM_COMPAREITEM:
2082 case WM_DELETEITEM:
2083 case WM_DRAWITEM:
2084 case WM_SETTEXT:
2085 case WM_WININICHANGE:
2086 case WM_DEVMODECHANGE:
2087 SEGPTR_FREE( MapSL(p16->lParam) );
2088 break;
2090 case CB_GETDROPPEDCONTROLRECT:
2091 case LB_GETITEMRECT:
2093 RECT16 *rect = MapSL(p16->lParam);
2094 p16->lParam = *(LPARAM *)(rect + 1);
2095 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
2096 SEGPTR_FREE( rect );
2098 break;
2099 case LB_GETSELITEMS:
2101 INT i;
2102 LPINT16 items = MapSL(lParam);
2103 p16->lParam = *((LPARAM *)items - 1);
2104 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
2105 SEGPTR_FREE( (LPARAM *)items - 1 );
2107 break;
2109 case CB_GETEDITSEL:
2110 if( wParam )
2111 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
2112 if( lParam )
2113 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
2114 break;
2116 case LB_GETTEXT:
2117 case CB_GETLBTEXT:
2118 UnMapLS( (SEGPTR)(p16->lParam) );
2119 break;
2121 case WM_MEASUREITEM:
2123 MEASUREITEMSTRUCT16 *mis = MapSL(p16->lParam);
2124 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
2125 mis32->itemWidth = mis->itemWidth;
2126 mis32->itemHeight = mis->itemHeight;
2127 SEGPTR_FREE(mis);
2129 break;
2130 case WM_GETMINMAXINFO:
2132 MINMAXINFO16 *mmi = MapSL(p16->lParam);
2133 p16->lParam = *(LPARAM *)(mmi + 1);
2134 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
2135 SEGPTR_FREE(mmi);
2137 break;
2138 case WM_GETTEXT:
2139 case WM_ASKCBFORMATNAME:
2141 LPSTR str = MapSL(p16->lParam);
2142 p16->lParam = *((LPARAM *)str - 1);
2143 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
2144 SEGPTR_FREE( (LPARAM *)str - 1 );
2146 break;
2147 case WM_MDICREATE:
2149 MDICREATESTRUCT16 *cs = MapSL(p16->lParam);
2150 SEGPTR_FREE( MapSL(cs->szTitle) );
2151 SEGPTR_FREE( MapSL(cs->szClass) );
2152 SEGPTR_FREE( cs );
2154 break;
2155 case WM_MDIGETACTIVE:
2156 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
2157 p16->lResult = (HWND)LOWORD(p16->lResult);
2158 break;
2159 case WM_NCCALCSIZE:
2161 NCCALCSIZE_PARAMS *nc32;
2162 NCCALCSIZE_PARAMS16 *nc = MapSL(p16->lParam);
2163 p16->lParam = *(LPARAM *)(nc + 1);
2164 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
2165 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
2166 if (p16->wParam)
2168 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
2169 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
2170 STRUCT32_WINDOWPOS16to32( MapSL(nc->lppos), nc32->lppos );
2171 SEGPTR_FREE( MapSL(nc->lppos) );
2173 SEGPTR_FREE(nc);
2175 break;
2176 case WM_NCCREATE:
2177 case WM_CREATE:
2179 CREATESTRUCT16 *cs = MapSL(p16->lParam);
2180 SEGPTR_FREE( MapSL(cs->lpszName) );
2181 SEGPTR_FREE( MapSL(cs->lpszClass) );
2182 SEGPTR_FREE( cs );
2184 break;
2185 case WM_WINDOWPOSCHANGING:
2186 case WM_WINDOWPOSCHANGED:
2188 WINDOWPOS16 *wp = MapSL(p16->lParam);
2189 p16->lParam = *(LPARAM *)(wp + 1);
2190 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
2191 SEGPTR_FREE(wp);
2193 break;
2194 case WM_NOTIFY:
2195 UnMapLS(p16->lParam);
2196 break;
2197 case WM_GETDLGCODE:
2198 if (p16->lParam)
2200 LPMSG16 msg16 = MapSL(p16->lParam);
2201 MSGPARAM16 msgp16;
2202 msgp16.wParam=msg16->wParam;
2203 msgp16.lParam=msg16->lParam;
2204 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
2205 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2206 &msgp16 );
2207 SEGPTR_FREE(msg16);
2209 break;
2214 /**********************************************************************
2215 * WINPROC_MapMsg32WTo16
2217 * Map a message from 32-bit Unicode to 16-bit.
2218 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
2220 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
2221 UINT16 *pmsg16, WPARAM16 *pwparam16,
2222 LPARAM *plparam )
2224 char ch;
2225 WCHAR wch;
2227 *pmsg16 = LOWORD(msg32);
2228 *pwparam16 = LOWORD(wParam32);
2229 switch(msg32)
2231 case LB_ADDSTRING:
2232 case LB_FINDSTRING:
2233 case LB_FINDSTRINGEXACT:
2234 case LB_INSERTSTRING:
2235 case LB_SELECTSTRING:
2236 case LB_DIR:
2237 case LB_ADDFILE:
2239 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2240 if (!str) return -1;
2241 *plparam = (LPARAM)SEGPTR_GET(str);
2243 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2244 return 1;
2246 case CB_ADDSTRING:
2247 case CB_FINDSTRING:
2248 case CB_FINDSTRINGEXACT:
2249 case CB_INSERTSTRING:
2250 case CB_SELECTSTRING:
2251 case CB_DIR:
2253 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2254 if (!str) return -1;
2255 *plparam = (LPARAM)SEGPTR_GET(str);
2257 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2258 return 1;
2260 case WM_NCCREATE:
2261 case WM_CREATE:
2263 CREATESTRUCT16 *cs;
2264 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2265 LPSTR name, cls;
2267 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2268 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2269 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
2270 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
2271 cs->lpszName = SEGPTR_GET(name);
2272 cs->lpszClass = SEGPTR_GET(cls);
2273 *plparam = (LPARAM)SEGPTR_GET(cs);
2275 return 1;
2276 case WM_MDICREATE:
2278 MDICREATESTRUCT16 *cs;
2279 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2280 LPSTR name, cls;
2282 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2283 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2284 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2285 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2286 cs->szTitle = SEGPTR_GET(name);
2287 cs->szClass = SEGPTR_GET(cls);
2288 *plparam = (LPARAM)SEGPTR_GET(cs);
2290 return 1;
2291 case WM_SETTEXT:
2293 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2294 if (!str) return -1;
2295 *plparam = (LPARAM)SEGPTR_GET(str);
2297 return 1;
2298 case LB_GETTEXT:
2299 case CB_GETLBTEXT:
2300 if ( WINPROC_TestLBForStr( hwnd ))
2302 LPSTR str = (LPSTR) SEGPTR_ALLOC( 256 ); /* fixme: fixed sized buffer */
2303 if (!str) return -1;
2304 *pmsg16 = (msg32 == LB_GETTEXT)? LB_GETTEXT16 : CB_GETLBTEXT16;
2305 *plparam = (LPARAM)SEGPTR_GET(str);
2307 return 1;
2309 case WM_CHARTOITEM:
2310 wch = LOWORD(wParam32);
2311 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2312 *pwparam16 = ch;
2313 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
2314 return 0;
2315 case WM_MENUCHAR:
2316 wch = LOWORD(wParam32);
2317 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2318 *pwparam16 = ch;
2319 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
2320 return 0;
2321 case WM_CHAR:
2322 case WM_DEADCHAR:
2323 case WM_SYSCHAR:
2324 case WM_SYSDEADCHAR:
2325 wch = wParam32;
2326 WideCharToMultiByte( CP_ACP, 0, &wch, 1, &ch, 1, NULL, NULL);
2327 *pwparam16 = ch;
2328 return 0;
2330 default: /* No Unicode translation needed (?) */
2331 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2332 pwparam16, plparam );
2337 /**********************************************************************
2338 * WINPROC_UnmapMsg32WTo16
2340 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2342 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2343 MSGPARAM16* p16 )
2345 switch(msg)
2347 case WM_GETTEXT:
2348 case WM_ASKCBFORMATNAME:
2350 LPSTR str = MapSL(p16->lParam);
2351 p16->lParam = *((LPARAM *)str - 1);
2352 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)p16->lParam, 0x7fffffff );
2353 SEGPTR_FREE( (LPARAM *)str - 1 );
2355 break;
2356 case LB_GETTEXT:
2357 case CB_GETLBTEXT:
2358 if ( WINPROC_TestLBForStr( hwnd ))
2360 LPSTR str = MapSL(p16->lParam);
2361 MultiByteToWideChar( CP_ACP, 0, str, -1, (LPWSTR)lParam, 0x7fffffff );
2362 SEGPTR_FREE( (LPARAM *) str );
2364 break;
2365 default:
2366 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2367 break;
2372 /**********************************************************************
2373 * WINPROC_CallProc32ATo32W
2375 * Call a window procedure, translating args from Ansi to Unicode.
2377 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2378 UINT msg, WPARAM wParam,
2379 LPARAM lParam )
2381 LRESULT result;
2382 int unmap;
2384 if( (unmap = WINPROC_MapMsg32ATo32W( hwnd, msg, &wParam, &lParam )) == -1) {
2385 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2386 SPY_GetMsgName(msg), wParam, lParam );
2387 return 0;
2389 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2390 if (unmap) result = WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam, result );
2391 return result;
2395 /**********************************************************************
2396 * WINPROC_CallProc32WTo32A
2398 * Call a window procedure, translating args from Unicode to Ansi.
2400 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2401 UINT msg, WPARAM wParam,
2402 LPARAM lParam )
2404 LRESULT result;
2405 int unmap;
2407 if ((unmap = WINPROC_MapMsg32WTo32A( hwnd, msg, &wParam, &lParam )) == -1) {
2408 ERR_(msg)("Message translation failed. (msg=%s,wp=%08x,lp=%08lx)\n",
2409 SPY_GetMsgName(msg), wParam, lParam );
2410 return 0;
2412 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2413 if( unmap ) WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2414 return result;
2418 /**********************************************************************
2419 * WINPROC_CallProc16To32A
2421 * Call a 32-bit window procedure, translating the 16-bit args.
2423 static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd,
2424 UINT16 msg, WPARAM16 wParam,
2425 LPARAM lParam )
2427 LRESULT result;
2428 UINT msg32;
2429 WPARAM wParam32;
2431 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2432 return 0;
2433 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2434 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2437 /**********************************************************************
2438 * WINPROC_Thunk16To32A
2440 static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args )
2442 HWND16 hwnd = *(HWND16 *)( args+8 );
2443 UINT16 msg = *(HWND16 *)( args+6 );
2444 WPARAM16 wParam = *(HWND16 *)( args+4 );
2445 LPARAM lParam = *(LPARAM *)( args+0 );
2447 return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
2451 /**********************************************************************
2452 * WINPROC_CallProc16To32W
2454 * Call a 32-bit window procedure, translating the 16-bit args.
2456 static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd,
2457 UINT16 msg, WPARAM16 wParam,
2458 LPARAM lParam )
2460 LRESULT result;
2461 UINT msg32;
2462 WPARAM wParam32;
2464 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2465 return 0;
2467 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2469 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2472 /**********************************************************************
2473 * WINPROC_Thunk16To32W
2475 static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args )
2477 HWND16 hwnd = *(HWND16 *)( args+8 );
2478 UINT16 msg = *(HWND16 *)( args+6 );
2479 WPARAM16 wParam = *(HWND16 *)( args+4 );
2480 LPARAM lParam = *(LPARAM *)( args+0 );
2482 return WINPROC_CallProc16To32W( func, hwnd, msg, wParam, lParam );
2485 /**********************************************************************
2486 * WINPROC_CallProc32ATo16
2488 * Call a 16-bit window procedure, translating the 32-bit args.
2490 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2491 UINT msg, WPARAM wParam,
2492 LPARAM lParam )
2494 UINT16 msg16;
2495 MSGPARAM16 mp16;
2497 mp16.lParam = lParam;
2498 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2499 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2500 return 0;
2501 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2502 mp16.wParam, mp16.lParam );
2503 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2504 return mp16.lResult;
2508 /**********************************************************************
2509 * WINPROC_CallProc32WTo16
2511 * Call a 16-bit window procedure, translating the 32-bit args.
2513 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2514 UINT msg, WPARAM wParam,
2515 LPARAM lParam )
2517 UINT16 msg16;
2518 MSGPARAM16 mp16;
2520 mp16.lParam = lParam;
2521 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2522 &mp16.lParam ) == -1)
2523 return 0;
2524 mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
2525 mp16.wParam, mp16.lParam );
2526 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2527 return mp16.lResult;
2531 /**********************************************************************
2532 * CallWindowProc (USER.122)
2533 * CallWindowProc16 (USER32.@)
2535 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2536 WPARAM16 wParam, LPARAM lParam )
2538 WINDOWPROC *proc = WINPROC_GetPtr( func );
2540 if (!proc)
2541 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2543 #if testing
2544 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2545 return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
2546 #endif
2548 switch(proc->type)
2550 case WIN_PROC_16:
2551 if (!proc->thunk.t_from32.proc) return 0;
2552 return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
2553 hwnd, msg, wParam, lParam );
2554 case WIN_PROC_32A:
2555 if (!proc->thunk.t_from16.proc) return 0;
2556 return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc,
2557 hwnd, msg, wParam, lParam );
2558 case WIN_PROC_32W:
2559 if (!proc->thunk.t_from16.proc) return 0;
2560 return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc,
2561 hwnd, msg, wParam, lParam );
2562 default:
2563 WARN_(relay)("Invalid proc %p\n", proc );
2564 return 0;
2569 /**********************************************************************
2570 * CallWindowProcA (USER32.@)
2572 * The CallWindowProc() function invokes the windows procedure _func_,
2573 * with _hwnd_ as the target window, the message specified by _msg_, and
2574 * the message parameters _wParam_ and _lParam_.
2576 * Some kinds of argument conversion may be done, I'm not sure what.
2578 * CallWindowProc() may be used for windows subclassing. Use
2579 * SetWindowLong() to set a new windows procedure for windows of the
2580 * subclass, and handle subclassed messages in the new windows
2581 * procedure. The new windows procedure may then use CallWindowProc()
2582 * with _func_ set to the parent class's windows procedure to dispatch
2583 * the message to the superclass.
2585 * RETURNS
2587 * The return value is message dependent.
2589 * CONFORMANCE
2591 * ECMA-234, Win32
2593 LRESULT WINAPI CallWindowProcA(
2594 WNDPROC func, /* [in] window procedure */
2595 HWND hwnd, /* [in] target window */
2596 UINT msg, /* [in] message */
2597 WPARAM wParam, /* [in] message dependent parameter */
2598 LPARAM lParam /* [in] message dependent parameter */
2600 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2602 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2604 #if testing
2605 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2606 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2607 #endif
2609 switch(proc->type)
2611 case WIN_PROC_16:
2612 if (!proc->thunk.t_from32.proc) return 0;
2613 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2614 hwnd, msg, wParam, lParam );
2615 case WIN_PROC_32A:
2616 if (!proc->thunk.t_from16.proc) return 0;
2617 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2618 hwnd, msg, wParam, lParam );
2619 case WIN_PROC_32W:
2620 if (!proc->thunk.t_from16.proc) return 0;
2621 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2622 hwnd, msg, wParam, lParam );
2623 default:
2624 WARN_(relay)("Invalid proc %p\n", proc );
2625 return 0;
2630 /**********************************************************************
2631 * CallWindowProcW (USER32.@)
2633 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2634 WPARAM wParam, LPARAM lParam )
2636 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2638 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2640 #if testing
2641 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2642 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2643 #endif
2645 switch(proc->type)
2647 case WIN_PROC_16:
2648 if (!proc->thunk.t_from32.proc) return 0;
2649 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2650 hwnd, msg, wParam, lParam );
2651 case WIN_PROC_32A:
2652 if (!proc->thunk.t_from16.proc) return 0;
2653 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2654 hwnd, msg, wParam, lParam );
2655 case WIN_PROC_32W:
2656 if (!proc->thunk.t_from16.proc) return 0;
2657 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2658 hwnd, msg, wParam, lParam );
2659 default:
2660 WARN_(relay)("Invalid proc %p\n", proc );
2661 return 0;