Converted to the new debugging interface (done with the help of the
[wine/multimedia.git] / windows / winproc.c
blob4e4c351c346573be688dab95ea42794483550adb
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include "wine/winbase16.h"
9 #include "winuser.h"
10 #include "callback.h"
11 #include "heap.h"
12 #include "selectors.h"
13 #include "struct32.h"
14 #include "win.h"
15 #include "winproc.h"
16 #include "debugtools.h"
17 #include "spy.h"
18 #include "commctrl.h"
19 #include "task.h"
20 #include "thread.h"
22 DECLARE_DEBUG_CHANNEL(msg)
23 DECLARE_DEBUG_CHANNEL(relay)
24 DECLARE_DEBUG_CHANNEL(win)
26 /* Window procedure 16-to-32-bit thunk,
27 * see BuildSpec16Files() in tools/build.c */
29 typedef struct
31 BYTE popl_eax; /* popl %eax (return address) */
32 BYTE pushl_func; /* pushl $proc */
33 WNDPROC proc WINE_PACKED;
34 BYTE pushl_eax; /* pushl %eax */
35 WORD pushw_bp WINE_PACKED; /* pushw %bp */
36 BYTE pushl_thunk; /* pushl $thunkfrom16 */
37 void (*thunk32)() WINE_PACKED;
38 BYTE lcall; /* lcall cs:relay */
39 void (*relay)() WINE_PACKED; /* WINPROC_CallProc16To32A/W() */
40 WORD cs WINE_PACKED;
41 } WINPROC_THUNK_FROM16;
43 /* Window procedure 32-to-16-bit thunk,
44 * see BuildSpec32Files() in tools/build.c */
46 typedef struct
48 BYTE popl_eax; /* popl %eax (return address) */
49 BYTE pushl_func; /* pushl $proc */
50 WNDPROC16 proc WINE_PACKED;
51 BYTE pushl_eax; /* pushl %eax */
52 BYTE jmp; /* jmp relay (relative jump)*/
53 void (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
54 } WINPROC_THUNK_FROM32;
56 /* Simple jmp to call 32-bit procedure directly */
57 typedef struct
59 BYTE jmp; /* jmp proc (relative jump) */
60 WNDPROC proc WINE_PACKED;
61 } WINPROC_JUMP;
63 typedef union
65 WINPROC_THUNK_FROM16 t_from16;
66 WINPROC_THUNK_FROM32 t_from32;
67 } WINPROC_THUNK;
69 typedef struct tagWINDOWPROC
71 WINPROC_THUNK thunk; /* Thunk */
72 WINPROC_JUMP jmp; /* Jump */
73 struct tagWINDOWPROC *next; /* Next window proc */
74 UINT magic; /* Magic number */
75 WINDOWPROCTYPE type; /* Function type */
76 WINDOWPROCUSER user; /* Function user */
77 } WINDOWPROC;
79 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
81 #define WINPROC_THUNKPROC(pproc) \
82 (((pproc)->type == WIN_PROC_16) ? \
83 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
84 (WNDPROC16)((pproc)->thunk.t_from16.proc))
86 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
87 UINT msg, WPARAM wParam,
88 LPARAM lParam );
89 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
90 UINT msg, WPARAM wParam,
91 LPARAM lParam );
92 static LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
93 WPARAM16 wParam, LPARAM lParam,
94 WNDPROC func );
95 static LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
96 WPARAM16 wParam, LPARAM lParam,
97 WNDPROC func );
99 static HANDLE WinProcHeap;
102 /**********************************************************************
103 * WINPROC_Init
105 BOOL WINPROC_Init(void)
107 WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
108 if (!WinProcHeap)
110 WARN_(relay)("Unable to create winproc heap\n" );
111 return FALSE;
113 return TRUE;
117 /**********************************************************************
118 * WINPROC_CallWndProc32
120 * Call a 32-bit WndProc.
122 static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
123 WPARAM wParam, LPARAM lParam )
125 LRESULT retvalue;
126 int iWndsLocks;
128 TRACE_(relay)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
129 proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
130 /* To avoid any deadlocks, all the locks on the windows structures
131 must be suspended before the control is passed to the application */
132 iWndsLocks = WIN_SuspendWndsLock();
133 retvalue = proc( hwnd, msg, wParam, lParam );
134 WIN_RestoreWndsLock(iWndsLocks);
135 return retvalue;
139 /**********************************************************************
140 * WINPROC_GetPtr
142 * Return a pointer to the win proc.
144 static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
146 BYTE *ptr;
147 WINDOWPROC *proc;
149 /* Check for a linear pointer */
151 if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
153 ptr = (BYTE *)handle;
154 /* First check if it is the jmp address */
155 if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
156 (int)&((WINDOWPROC *)0)->thunk;
157 /* Now it must be the thunk address */
158 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
159 /* Now we have a pointer to the WINDOWPROC struct */
160 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
161 return (WINDOWPROC *)ptr;
164 /* Check for a segmented pointer */
166 if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
168 ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
169 if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
170 /* It must be the thunk address */
171 if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
172 /* Now we have a pointer to the WINDOWPROC struct */
173 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
174 return (WINDOWPROC *)ptr;
177 return NULL;
181 /**********************************************************************
182 * WINPROC_AllocWinProc
184 * Allocate a new window procedure.
186 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
187 WINDOWPROCUSER user )
189 WINDOWPROC *proc, *oldproc;
191 /* Allocate a window procedure */
193 if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
195 /* Check if the function is already a win proc */
197 if ((oldproc = WINPROC_GetPtr( func )))
199 *proc = *oldproc;
201 else
203 switch(type)
205 case WIN_PROC_16:
206 proc->thunk.t_from32.popl_eax = 0x58; /* popl %eax */
207 proc->thunk.t_from32.pushl_func = 0x68; /* pushl $proc */
208 proc->thunk.t_from32.proc = func;
209 proc->thunk.t_from32.pushl_eax = 0x50; /* pushl %eax */
210 proc->thunk.t_from32.jmp = 0xe9; /* jmp relay*/
211 proc->thunk.t_from32.relay = /* relative jump */
212 (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
213 (DWORD)(&proc->thunk.t_from32.relay + 1));
214 break;
215 case WIN_PROC_32A:
216 case WIN_PROC_32W:
217 proc->thunk.t_from16.popl_eax = 0x58; /* popl %eax */
218 proc->thunk.t_from16.pushl_func = 0x68; /* pushl $proc */
219 proc->thunk.t_from16.proc = (FARPROC)func;
220 proc->thunk.t_from16.pushl_eax = 0x50; /* pushl %eax */
221 proc->thunk.t_from16.pushw_bp = 0x5566; /* pushw %bp */
222 proc->thunk.t_from16.pushl_thunk = 0x68; /* pushl $thunkfrom16 */
223 proc->thunk.t_from16.thunk32 = (type == WIN_PROC_32A) ?
224 (void(*)())WINPROC_CallProc16To32A :
225 (void(*)())WINPROC_CallProc16To32W;
226 proc->thunk.t_from16.lcall = 0x9a; /* lcall cs:relay */
227 proc->thunk.t_from16.relay = (void*)Callbacks->CallFrom16WndProc;
228 GET_CS(proc->thunk.t_from16.cs);
229 proc->jmp.jmp = 0xe9;
230 /* Fixup relative jump */
231 proc->jmp.proc = (WNDPROC)((DWORD)func -
232 (DWORD)(&proc->jmp.proc + 1));
233 break;
234 default:
235 /* Should not happen */
236 break;
238 proc->magic = WINPROC_MAGIC;
239 proc->type = type;
240 proc->user = user;
242 proc->next = NULL;
243 TRACE_(win)("(%08x,%d): returning %08x\n",
244 (UINT)func, type, (UINT)proc );
245 return proc;
249 /**********************************************************************
250 * WINPROC_GetProc
252 * Get a window procedure pointer that can be passed to the Windows program.
254 WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
256 if (!proc) return NULL;
257 if (type == WIN_PROC_16) /* We want a 16:16 address */
259 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
260 return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
261 else
262 return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
263 &((WINDOWPROC *)proc)->thunk );
265 else /* We want a 32-bit address */
267 if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
268 return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
269 else if (type != ((WINDOWPROC *)proc)->type)
270 /* Have to return the jmp address if types don't match */
271 return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
272 else
273 /* Some Win16 programs want to get back the proc they set */
274 return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
279 /**********************************************************************
280 * WINPROC_SetProc
282 * Set the window procedure for a window or class. There are
283 * three tree classes of winproc callbacks:
285 * 1) class -> wp - not subclassed
286 * class -> wp -> wp -> wp -> wp - SetClassLong()
287 * / /
288 * 2) window -' / - not subclassed
289 * window -> wp -> wp ' - SetWindowLong()
291 * 3) timer -> wp - SetTimer()
293 * Initially, winproc of the window points to the current winproc
294 * thunk of its class. Subclassing prepends a new thunk to the
295 * window winproc chain at the head of the list. Thus, window thunk
296 * list includes class thunks and the latter are preserved when the
297 * window is destroyed.
300 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
301 WINDOWPROCTYPE type, WINDOWPROCUSER user )
303 BOOL bRecycle = FALSE;
304 WINDOWPROC *proc, **ppPrev;
306 /* Check if function is already in the list */
308 ppPrev = (WINDOWPROC **)pFirst;
309 proc = WINPROC_GetPtr( func );
310 while (*ppPrev)
312 if (proc)
314 if (*ppPrev == proc)
316 if ((*ppPrev)->user != user)
318 /* terminal thunk is being restored */
320 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
321 *(WINDOWPROC **)pFirst = *ppPrev;
322 return TRUE;
324 bRecycle = TRUE;
325 break;
328 else
330 if (((*ppPrev)->type == type) &&
331 (func == WINPROC_THUNKPROC(*ppPrev)))
333 bRecycle = TRUE;
334 break;
338 /* WPF_CLASS thunk terminates window thunk list */
339 if ((*ppPrev)->user != user) break;
340 ppPrev = &(*ppPrev)->next;
343 if (bRecycle)
345 /* Extract this thunk from the list */
346 proc = *ppPrev;
347 *ppPrev = proc->next;
349 else /* Allocate a new one */
351 if (proc) /* Was already a win proc */
353 type = proc->type;
354 func = WINPROC_THUNKPROC(proc);
356 proc = WINPROC_AllocWinProc( func, type, user );
357 if (!proc) return FALSE;
360 /* Add the win proc at the head of the list */
362 TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
363 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
364 proc->next = *(WINDOWPROC **)pFirst;
365 *(WINDOWPROC **)pFirst = proc;
366 return TRUE;
370 /**********************************************************************
371 * WINPROC_FreeProc
373 * Free a list of win procs.
375 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
377 while (proc)
379 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
380 if (((WINDOWPROC *)proc)->user != user) break;
381 TRACE_(win)("freeing %08x\n", (UINT)proc);
382 HeapFree( WinProcHeap, 0, proc );
383 proc = next;
388 /**********************************************************************
389 * WINPROC_GetProcType
391 * Return the window procedure type.
393 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
395 if (!proc ||
396 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
397 return WIN_PROC_INVALID;
398 return ((WINDOWPROC *)proc)->type;
400 /**********************************************************************
401 * WINPROC_TestCBForStr
403 * Return TRUE if the lparam is a string
405 BOOL WINPROC_TestCBForStr ( HWND hwnd )
407 BOOL retvalue;
408 WND * wnd = WIN_FindWndPtr(hwnd);
409 retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
410 (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
411 WIN_ReleaseWndPtr(wnd);
412 return retvalue;
414 /**********************************************************************
415 * WINPROC_TestLBForStr
417 * Return TRUE if the lparam is a string
419 BOOL WINPROC_TestLBForStr ( HWND hwnd )
421 BOOL retvalue;
422 WND * wnd = WIN_FindWndPtr(hwnd);
423 retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
424 (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
425 WIN_ReleaseWndPtr(wnd);
426 return retvalue;
429 /**********************************************************************
430 * WINPROC_MapMsg32ATo32W
432 * Map a message from Ansi to Unicode.
433 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
435 * FIXME:
436 * WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
438 * FIXME:
439 * WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
440 * the first four bytes are the handle of the icon
441 * when the WM_SETTEXT message has been used to set the icon
443 INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
445 switch(msg)
447 case WM_GETTEXT:
449 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
450 wParam * sizeof(WCHAR) + sizeof(LPARAM) );
451 if (!ptr) return -1;
452 *ptr++ = *plparam; /* Store previous lParam */
453 *plparam = (LPARAM)ptr;
455 return 1;
456 /* lparam is string (0-terminated) */
457 case WM_SETTEXT:
458 case WM_WININICHANGE:
459 case CB_DIR:
460 case CB_FINDSTRING:
461 case CB_FINDSTRINGEXACT:
462 case CB_SELECTSTRING:
463 case LB_DIR:
464 case LB_ADDFILE:
465 case LB_FINDSTRING:
466 case LB_SELECTSTRING:
467 case EM_REPLACESEL:
468 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
469 return (*plparam ? 1 : -1);
471 case WM_NCCREATE:
472 case WM_CREATE:
474 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
475 sizeof(*cs) );
476 if (!cs) return -1;
477 *cs = *(CREATESTRUCTW *)*plparam;
478 if (HIWORD(cs->lpszName))
479 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
480 (LPCSTR)cs->lpszName );
481 if (HIWORD(cs->lpszClass))
482 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
483 (LPCSTR)cs->lpszClass );
484 *plparam = (LPARAM)cs;
486 return 1;
487 case WM_MDICREATE:
489 MDICREATESTRUCTW *cs =
490 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
491 if (!cs) return -1;
492 *cs = *(MDICREATESTRUCTW *)*plparam;
493 if (HIWORD(cs->szClass))
494 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
495 (LPCSTR)cs->szClass );
496 if (HIWORD(cs->szTitle))
497 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
498 (LPCSTR)cs->szTitle );
499 *plparam = (LPARAM)cs;
501 return 1;
503 /* Listbox */
504 case LB_ADDSTRING:
505 case LB_INSERTSTRING:
506 if ( WINPROC_TestLBForStr( hwnd ))
507 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
508 return (*plparam ? 1 : -1);
510 case LB_GETTEXT: /* fixme: fixed sized buffer */
511 { if ( WINPROC_TestLBForStr( hwnd ))
512 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
513 if (!ptr) return -1;
514 *ptr++ = *plparam; /* Store previous lParam */
515 *plparam = (LPARAM)ptr;
518 return 1;
520 /* Combobox */
521 case CB_ADDSTRING:
522 case CB_INSERTSTRING:
523 if ( WINPROC_TestCBForStr( hwnd ))
524 *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
525 return (*plparam ? 1 : -1);
527 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
528 { if ( WINPROC_TestCBForStr( hwnd ))
529 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
530 if (!ptr) return -1;
531 *ptr++ = *plparam; /* Store previous lParam */
532 *plparam = (LPARAM)ptr;
535 return 1;
537 /* Multiline edit */
538 case EM_GETLINE:
539 { WORD len = (WORD)*plparam;
540 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
541 if (!ptr) return -1;
542 *ptr++ = *plparam; /* Store previous lParam */
543 *((WORD *) ptr) = len; /* Store the length */
544 *plparam = (LPARAM)ptr;
546 return 1;
548 case WM_ASKCBFORMATNAME:
549 case WM_DEVMODECHANGE:
550 case WM_PAINTCLIPBOARD:
551 case WM_SIZECLIPBOARD:
552 case EM_SETPASSWORDCHAR:
553 FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
554 return -1;
555 default: /* No translation needed */
556 return 0;
561 /**********************************************************************
562 * WINPROC_UnmapMsg32ATo32W
564 * Unmap a message that was mapped from Ansi to Unicode.
566 void WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
568 switch(msg)
570 case WM_GETTEXT:
572 LPARAM *ptr = (LPARAM *)lParam - 1;
573 lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
574 HeapFree( SystemHeap, 0, ptr );
576 break;
578 case WM_NCCREATE:
579 case WM_CREATE:
581 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
582 if (HIWORD(cs->lpszName))
583 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
584 if (HIWORD(cs->lpszClass))
585 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
586 HeapFree( SystemHeap, 0, cs );
588 break;
590 case WM_MDICREATE:
592 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
593 if (HIWORD(cs->szTitle))
594 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
595 if (HIWORD(cs->szClass))
596 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
597 HeapFree( SystemHeap, 0, cs );
599 break;
601 case WM_SETTEXT:
602 case WM_WININICHANGE:
603 case CB_DIR:
604 case CB_FINDSTRING:
605 case CB_FINDSTRINGEXACT:
606 case CB_SELECTSTRING:
607 case LB_DIR:
608 case LB_ADDFILE:
609 case LB_FINDSTRING:
610 case LB_SELECTSTRING:
611 case EM_REPLACESEL:
612 HeapFree( SystemHeap, 0, (void *)lParam );
613 break;
615 /* Listbox */
616 case LB_ADDSTRING:
617 case LB_INSERTSTRING:
618 if ( WINPROC_TestLBForStr( hwnd ))
619 HeapFree( SystemHeap, 0, (void *)lParam );
620 break;
622 case LB_GETTEXT:
623 { if ( WINPROC_TestLBForStr( hwnd ))
624 { LPARAM *ptr = (LPARAM *)lParam - 1;
625 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
626 HeapFree( SystemHeap, 0, ptr );
629 break;
631 /* Combobox */
632 case CB_ADDSTRING:
633 case CB_INSERTSTRING:
634 if ( WINPROC_TestCBForStr( hwnd ))
635 HeapFree( SystemHeap, 0, (void *)lParam );
636 break;
638 case CB_GETLBTEXT:
639 { if ( WINPROC_TestCBForStr( hwnd ))
640 { LPARAM *ptr = (LPARAM *)lParam - 1;
641 lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
642 HeapFree( SystemHeap, 0, ptr );
645 break;
647 /* Multiline edit */
648 case EM_GETLINE:
649 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lParam */
650 WORD len = *(WORD *) lParam;
651 lstrcpynWtoA( (LPSTR)*ptr , (LPWSTR)lParam, len );
652 HeapFree( SystemHeap, 0, ptr );
654 break;
659 /**********************************************************************
660 * WINPROC_MapMsg32WTo32A
662 * Map a message from Unicode to Ansi.
663 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
665 INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
666 { switch(msg)
668 case WM_GETTEXT:
670 LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
671 wParam + sizeof(LPARAM) );
672 if (!ptr) return -1;
673 *ptr++ = *plparam; /* Store previous lParam */
674 *plparam = (LPARAM)ptr;
676 return 1;
678 case WM_SETTEXT:
679 case WM_WININICHANGE:
680 case CB_DIR:
681 case CB_FINDSTRING:
682 case CB_FINDSTRINGEXACT:
683 case CB_SELECTSTRING:
684 case LB_DIR:
685 case LB_ADDFILE:
686 case LB_FINDSTRING:
687 case LB_SELECTSTRING:
688 case EM_REPLACESEL:
689 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
690 return (*plparam ? 1 : -1);
692 case WM_NCCREATE:
693 case WM_CREATE:
695 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
696 sizeof(*cs) );
697 if (!cs) return -1;
698 *cs = *(CREATESTRUCTA *)*plparam;
699 if (HIWORD(cs->lpszName))
700 cs->lpszName = HEAP_strdupWtoA( SystemHeap, 0,
701 (LPCWSTR)cs->lpszName );
702 if (HIWORD(cs->lpszClass))
703 cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
704 (LPCWSTR)cs->lpszClass);
705 *plparam = (LPARAM)cs;
707 return 1;
708 case WM_MDICREATE:
710 MDICREATESTRUCTA *cs =
711 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
712 if (!cs) return -1;
713 *cs = *(MDICREATESTRUCTA *)*plparam;
714 if (HIWORD(cs->szTitle))
715 cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
716 (LPCWSTR)cs->szTitle );
717 if (HIWORD(cs->szClass))
718 cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
719 (LPCWSTR)cs->szClass );
720 *plparam = (LPARAM)cs;
722 return 1;
724 /* Listbox */
725 case LB_ADDSTRING:
726 case LB_INSERTSTRING:
727 if ( WINPROC_TestLBForStr( hwnd ))
728 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
729 return (*plparam ? 1 : -1);
731 case LB_GETTEXT: /* fixme: fixed sized buffer */
732 { if ( WINPROC_TestLBForStr( hwnd ))
733 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
734 if (!ptr) return -1;
735 *ptr++ = *plparam; /* Store previous lParam */
736 *plparam = (LPARAM)ptr;
739 return 1;
741 /* Combobox */
742 case CB_ADDSTRING:
743 case CB_INSERTSTRING:
744 if ( WINPROC_TestCBForStr( hwnd ))
745 *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
746 return (*plparam ? 1 : -1);
748 case CB_GETLBTEXT: /* fixme: fixed sized buffer */
749 { if ( WINPROC_TestCBForStr( hwnd ))
750 { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
751 if (!ptr) return -1;
752 *ptr++ = *plparam; /* Store previous lParam */
753 *plparam = (LPARAM)ptr;
756 return 1;
758 /* Multiline edit */
759 case EM_GETLINE:
760 { WORD len = (WORD)*plparam;
761 LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
762 if (!ptr) return -1;
763 *ptr++ = *plparam; /* Store previous lParam */
764 *((WORD *) ptr) = len; /* Store the length */
765 *plparam = (LPARAM)ptr;
767 return 1;
769 case WM_ASKCBFORMATNAME:
770 case WM_DEVMODECHANGE:
771 case WM_PAINTCLIPBOARD:
772 case WM_SIZECLIPBOARD:
773 case EM_SETPASSWORDCHAR:
774 FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
775 return -1;
776 default: /* No translation needed */
777 return 0;
782 /**********************************************************************
783 * WINPROC_UnmapMsg32WTo32A
785 * Unmap a message that was mapped from Unicode to Ansi.
787 void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
789 switch(msg)
791 case WM_GETTEXT:
793 LPARAM *ptr = (LPARAM *)lParam - 1;
794 lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
795 HeapFree( SystemHeap, 0, ptr );
797 break;
799 case WM_SETTEXT:
800 case WM_WININICHANGE:
801 case CB_DIR:
802 case CB_FINDSTRING:
803 case CB_FINDSTRINGEXACT:
804 case CB_SELECTSTRING:
805 case LB_DIR:
806 case LB_ADDFILE:
807 case LB_FINDSTRING:
808 case LB_SELECTSTRING:
809 case EM_REPLACESEL:
810 HeapFree( SystemHeap, 0, (void *)lParam );
811 break;
813 case WM_NCCREATE:
814 case WM_CREATE:
816 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
817 if (HIWORD(cs->lpszName))
818 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
819 if (HIWORD(cs->lpszClass))
820 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
821 HeapFree( SystemHeap, 0, cs );
823 break;
825 case WM_MDICREATE:
827 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
828 if (HIWORD(cs->szTitle))
829 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
830 if (HIWORD(cs->szClass))
831 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
832 HeapFree( SystemHeap, 0, cs );
834 break;
836 /* Listbox */
837 case LB_ADDSTRING:
838 case LB_INSERTSTRING:
839 if ( WINPROC_TestLBForStr( hwnd ))
840 HeapFree( SystemHeap, 0, (void *)lParam );
841 break;
843 case LB_GETTEXT:
844 { if ( WINPROC_TestLBForStr( hwnd ))
845 { LPARAM *ptr = (LPARAM *)lParam - 1;
846 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
847 HeapFree( SystemHeap, 0, ptr );
850 break;
852 /* Combobox */
853 case CB_ADDSTRING:
854 case CB_INSERTSTRING:
855 if ( WINPROC_TestCBForStr( hwnd ))
856 HeapFree( SystemHeap, 0, (void *)lParam );
857 break;
859 case CB_GETLBTEXT:
860 { if ( WINPROC_TestCBForStr( hwnd ))
861 { LPARAM *ptr = (LPARAM *)lParam - 1;
862 lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
863 HeapFree( SystemHeap, 0, ptr );
866 break;
868 /* Multiline edit */
869 case EM_GETLINE:
870 { LPARAM * ptr = (LPARAM *)lParam - 1; /* get the old lparam */
871 WORD len = *(WORD *)ptr;
872 lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len );
873 HeapFree( SystemHeap, 0, ptr );
875 break;
880 /**********************************************************************
881 * WINPROC_MapMsg16To32A
883 * Map a message from 16- to 32-bit Ansi.
884 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
886 INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
887 WPARAM *pwparam32, LPARAM *plparam )
889 *pmsg32 = (UINT)msg16;
890 *pwparam32 = (WPARAM)wParam16;
891 switch(msg16)
893 case WM_ACTIVATE:
894 case WM_CHARTOITEM:
895 case WM_COMMAND:
896 case WM_VKEYTOITEM:
897 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
898 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
899 return 0;
900 case WM_HSCROLL:
901 case WM_VSCROLL:
902 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
903 *plparam = (LPARAM)(HWND)HIWORD(*plparam);
904 return 0;
905 case WM_CTLCOLOR:
906 if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
907 *pmsg32 = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
908 *pwparam32 = (WPARAM)(HDC)wParam16;
909 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
910 return 0;
911 case WM_COMPAREITEM:
913 COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
914 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
915 HeapAlloc(SystemHeap, 0, sizeof(*cis));
916 if (!cis) return -1;
917 cis->CtlType = cis16->CtlType;
918 cis->CtlID = cis16->CtlID;
919 cis->hwndItem = cis16->hwndItem;
920 cis->itemID1 = cis16->itemID1;
921 cis->itemData1 = cis16->itemData1;
922 cis->itemID2 = cis16->itemID2;
923 cis->itemData2 = cis16->itemData2;
924 cis->dwLocaleId = 0; /* FIXME */
925 *plparam = (LPARAM)cis;
927 return 1;
928 case WM_DELETEITEM:
930 DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
931 DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
932 HeapAlloc(SystemHeap, 0, sizeof(*dis));
933 if (!dis) return -1;
934 dis->CtlType = dis16->CtlType;
935 dis->CtlID = dis16->CtlID;
936 dis->hwndItem = dis16->hwndItem;
937 dis->itemData = dis16->itemData;
938 *plparam = (LPARAM)dis;
940 return 1;
941 case WM_MEASUREITEM:
943 MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
944 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
945 HeapAlloc(SystemHeap, 0,
946 sizeof(*mis) + sizeof(LPARAM));
947 if (!mis) return -1;
948 mis->CtlType = mis16->CtlType;
949 mis->CtlID = mis16->CtlID;
950 mis->itemID = mis16->itemID;
951 mis->itemWidth = mis16->itemWidth;
952 mis->itemHeight = mis16->itemHeight;
953 mis->itemData = mis16->itemData;
954 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
955 *plparam = (LPARAM)mis;
957 return 1;
958 case WM_DRAWITEM:
960 DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
961 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(SystemHeap, 0,
962 sizeof(*dis));
963 if (!dis) return -1;
964 dis->CtlType = dis16->CtlType;
965 dis->CtlID = dis16->CtlID;
966 dis->itemID = dis16->itemID;
967 dis->itemAction = dis16->itemAction;
968 dis->itemState = dis16->itemState;
969 dis->hwndItem = dis16->hwndItem;
970 dis->hDC = dis16->hDC;
971 dis->itemData = dis16->itemData;
972 CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
973 *plparam = (LPARAM)dis;
975 return 1;
976 case WM_GETMINMAXINFO:
978 MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( SystemHeap, 0,
979 sizeof(*mmi) + sizeof(LPARAM));
980 if (!mmi) return -1;
981 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
982 mmi );
983 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
984 *plparam = (LPARAM)mmi;
986 return 1;
987 case WM_GETTEXT:
988 case WM_SETTEXT:
989 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
990 return 0;
991 case WM_MDICREATE:
993 MDICREATESTRUCT16 *cs16 =
994 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
995 MDICREATESTRUCTA *cs =
996 (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
997 sizeof(*cs) + sizeof(LPARAM) );
998 if (!cs) return -1;
999 STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
1000 cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1001 cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
1002 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1003 *plparam = (LPARAM)cs;
1005 return 1;
1006 case WM_MDIGETACTIVE:
1007 *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL) );
1008 *(BOOL*)(*plparam) = 0;
1009 return 1;
1010 case WM_MDISETMENU:
1011 if(wParam16==TRUE)
1012 *pmsg32=WM_MDIREFRESHMENU;
1013 *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
1014 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1015 return 0;
1016 case WM_MENUCHAR:
1017 case WM_MENUSELECT:
1018 *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1019 *plparam = (LPARAM)(HMENU)HIWORD(*plparam);
1020 return 0;
1021 case WM_MDIACTIVATE:
1022 if( *plparam )
1024 *pwparam32 = (WPARAM)(HWND)HIWORD(*plparam);
1025 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1027 else /* message sent to MDI client */
1028 *pwparam32 = wParam16;
1029 return 0;
1030 case WM_NCCALCSIZE:
1032 NCCALCSIZE_PARAMS16 *nc16;
1033 NCCALCSIZE_PARAMS *nc;
1035 nc = (NCCALCSIZE_PARAMS *)HeapAlloc( SystemHeap, 0,
1036 sizeof(*nc) + sizeof(LPARAM) );
1037 if (!nc) return -1;
1038 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
1039 CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
1040 if (wParam16)
1042 nc->lppos = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1043 sizeof(*nc->lppos) );
1044 CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
1045 CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
1046 if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
1048 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1049 *plparam = (LPARAM)nc;
1051 return 1;
1052 case WM_NCCREATE:
1053 case WM_CREATE:
1055 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1056 CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
1057 sizeof(*cs) + sizeof(LPARAM) );
1058 if (!cs) return -1;
1059 STRUCT32_CREATESTRUCT16to32A( cs16, cs );
1060 cs->lpszName = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1061 cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1062 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1063 *plparam = (LPARAM)cs;
1065 return 1;
1066 case WM_PARENTNOTIFY:
1067 if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
1069 *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1070 *plparam = (LPARAM)(HWND)LOWORD(*plparam);
1072 return 0;
1073 case WM_WINDOWPOSCHANGING:
1074 case WM_WINDOWPOSCHANGED:
1076 WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
1077 sizeof(*wp) + sizeof(LPARAM) );
1078 if (!wp) return -1;
1079 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
1080 wp );
1081 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1082 *plparam = (LPARAM)wp;
1084 return 1;
1085 case WM_GETDLGCODE:
1086 if (*plparam)
1088 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1089 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1091 if (!msg32) return -1;
1092 msg32->hwnd = msg16->hwnd;
1093 msg32->lParam = msg16->lParam;
1094 msg32->time = msg16->time;
1095 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1096 /* this is right, right? */
1097 if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
1098 &msg32->message,&msg32->wParam,
1099 &msg32->lParam)<0) {
1100 HeapFree( SystemHeap, 0, msg32 );
1101 return -1;
1103 *plparam = (LPARAM)msg32;
1104 return 1;
1106 else return 0;
1107 case WM_NOTIFY:
1108 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1109 return 1;
1110 case WM_ACTIVATEAPP:
1111 if (*plparam)
1112 { /* We need this when SetActiveWindow sends a Sendmessage16() to
1113 a 32bit window. Might be superflous with 32bit interprocess
1114 message queues.
1116 HTASK16 htask = (HTASK16) *plparam;
1117 DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->thdb->server_tid;
1118 *plparam = (LPARAM) idThread;
1120 return 1;
1121 case WM_ASKCBFORMATNAME:
1122 case WM_DEVMODECHANGE:
1123 case WM_PAINTCLIPBOARD:
1124 case WM_SIZECLIPBOARD:
1125 case WM_WININICHANGE:
1126 FIXME_(msg)("message %04x needs translation\n",msg16 );
1127 return -1;
1129 default: /* No translation needed */
1130 return 0;
1135 /**********************************************************************
1136 * WINPROC_UnmapMsg16To32A
1138 * Unmap a message that was mapped from 16- to 32-bit Ansi.
1140 LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1141 LRESULT result )
1143 switch(msg)
1145 case WM_COMPAREITEM:
1146 case WM_DELETEITEM:
1147 case WM_DRAWITEM:
1148 HeapFree( SystemHeap, 0, (LPVOID)lParam );
1149 break;
1150 case WM_MEASUREITEM:
1152 MEASUREITEMSTRUCT16 *mis16;
1153 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
1154 lParam = *(LPARAM *)(mis + 1);
1155 mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
1156 mis16->itemWidth = (UINT16)mis->itemWidth;
1157 mis16->itemHeight = (UINT16)mis->itemHeight;
1158 HeapFree( SystemHeap, 0, mis );
1160 break;
1161 case WM_GETMINMAXINFO:
1163 MINMAXINFO *mmi = (MINMAXINFO *)lParam;
1164 lParam = *(LPARAM *)(mmi + 1);
1165 STRUCT32_MINMAXINFO32to16( mmi,
1166 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
1167 HeapFree( SystemHeap, 0, mmi );
1169 break;
1170 case WM_MDICREATE:
1172 MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
1173 lParam = *(LPARAM *)(cs + 1);
1174 STRUCT32_MDICREATESTRUCT32Ato16( cs,
1175 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1176 HeapFree( SystemHeap, 0, cs );
1178 break;
1179 case WM_MDIGETACTIVE:
1180 result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
1181 HeapFree( SystemHeap, 0, (BOOL *)lParam );
1182 break;
1183 case WM_NCCALCSIZE:
1185 NCCALCSIZE_PARAMS16 *nc16;
1186 NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
1187 lParam = *(LPARAM *)(nc + 1);
1188 nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
1189 CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
1190 if (wParam)
1192 CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
1193 CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
1194 if (nc->lppos)
1196 STRUCT32_WINDOWPOS32to16( nc->lppos,
1197 (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
1198 HeapFree( SystemHeap, 0, nc->lppos );
1201 HeapFree( SystemHeap, 0, nc );
1203 break;
1204 case WM_NCCREATE:
1205 case WM_CREATE:
1207 CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
1208 lParam = *(LPARAM *)(cs + 1);
1209 STRUCT32_CREATESTRUCT32Ato16( cs,
1210 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1211 HeapFree( SystemHeap, 0, cs );
1213 break;
1214 case WM_WINDOWPOSCHANGING:
1215 case WM_WINDOWPOSCHANGED:
1217 WINDOWPOS *wp = (WINDOWPOS *)lParam;
1218 lParam = *(LPARAM *)(wp + 1);
1219 STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
1220 HeapFree( SystemHeap, 0, wp );
1222 break;
1223 case WM_GETDLGCODE:
1224 if (lParam)
1226 LPMSG msg32 = (LPMSG)lParam;
1228 WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1229 result);
1230 HeapFree( SystemHeap, 0, msg32 );
1232 break;
1234 return result;
1238 /**********************************************************************
1239 * WINPROC_MapMsg16To32W
1241 * Map a message from 16- to 32-bit Unicode.
1242 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1244 INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
1245 WPARAM *pwparam32, LPARAM *plparam )
1247 switch(msg16)
1249 case WM_GETTEXT:
1250 case WM_SETTEXT:
1251 *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1252 return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, *pwparam32, plparam );
1253 case WM_NCCREATE:
1254 case WM_CREATE:
1256 CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1257 CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1258 sizeof(*cs) + sizeof(LPARAM) );
1259 if (!cs) return -1;
1260 STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
1261 cs->lpszName = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
1262 cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
1263 if (HIWORD(cs->lpszName))
1264 cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
1265 (LPCSTR)cs->lpszName );
1266 if (HIWORD(cs->lpszClass))
1267 cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
1268 (LPCSTR)cs->lpszClass );
1269 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1270 *plparam = (LPARAM)cs;
1272 return 1;
1273 case WM_MDICREATE:
1275 MDICREATESTRUCT16 *cs16 =
1276 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1277 MDICREATESTRUCTW *cs =
1278 (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
1279 sizeof(*cs) + sizeof(LPARAM) );
1280 if (!cs) return -1;
1281 STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
1282 cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
1283 cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
1284 if (HIWORD(cs->szTitle))
1285 cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
1286 (LPCSTR)cs->szTitle );
1287 if (HIWORD(cs->szClass))
1288 cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
1289 (LPCSTR)cs->szClass );
1290 *(LPARAM *)(cs + 1) = *plparam; /* Store the previous lParam */
1291 *plparam = (LPARAM)cs;
1293 return 1;
1294 case WM_GETDLGCODE:
1295 if (*plparam)
1297 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1298 LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
1300 if (!msg32) return -1;
1301 msg32->hwnd = msg16->hwnd;
1302 msg32->lParam = msg16->lParam;
1303 msg32->time = msg16->time;
1304 CONV_POINT16TO32(&msg16->pt,&msg32->pt);
1305 /* this is right, right? */
1306 if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
1307 &msg32->message,&msg32->wParam,
1308 &msg32->lParam)<0) {
1309 HeapFree( SystemHeap, 0, msg32 );
1310 return -1;
1312 *plparam = (LPARAM)msg32;
1313 return 1;
1315 else return 0;
1316 default: /* No Unicode translation needed */
1317 return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
1318 pwparam32, plparam );
1323 /**********************************************************************
1324 * WINPROC_UnmapMsg16To32W
1326 * Unmap a message that was mapped from 16- to 32-bit Unicode.
1328 LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1329 LRESULT result )
1331 switch(msg)
1333 case WM_GETTEXT:
1334 case WM_SETTEXT:
1335 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
1336 break;
1337 case WM_NCCREATE:
1338 case WM_CREATE:
1340 CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
1341 lParam = *(LPARAM *)(cs + 1);
1342 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs,
1343 (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1344 if (HIWORD(cs->lpszName))
1345 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
1346 if (HIWORD(cs->lpszClass))
1347 HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
1348 HeapFree( SystemHeap, 0, cs );
1350 break;
1351 case WM_MDICREATE:
1353 MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
1354 lParam = *(LPARAM *)(cs + 1);
1355 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs,
1356 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
1357 if (HIWORD(cs->szTitle))
1358 HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
1359 if (HIWORD(cs->szClass))
1360 HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
1361 HeapFree( SystemHeap, 0, cs );
1363 break;
1364 case WM_GETDLGCODE:
1365 if (lParam)
1367 LPMSG msg32 = (LPMSG)lParam;
1369 WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
1370 result);
1371 HeapFree( SystemHeap, 0, msg32 );
1373 break;
1374 default:
1375 return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
1377 return result;
1381 /**********************************************************************
1382 * WINPROC_MapMsg32ATo16
1384 * Map a message from 32-bit Ansi to 16-bit.
1385 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1387 INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1388 UINT16 *pmsg16, WPARAM16 *pwparam16,
1389 LPARAM *plparam )
1391 *pmsg16 = (UINT16)msg32;
1392 *pwparam16 = (WPARAM16)LOWORD(wParam32);
1393 switch(msg32)
1395 case BM_GETCHECK:
1396 case BM_SETCHECK:
1397 case BM_GETSTATE:
1398 case BM_SETSTATE:
1399 case BM_SETSTYLE:
1400 *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
1401 return 0;
1403 case EM_GETSEL:
1404 case EM_GETRECT:
1405 case EM_SETRECT:
1406 case EM_SETRECTNP:
1407 case EM_SCROLL:
1408 case EM_LINESCROLL:
1409 case EM_SCROLLCARET:
1410 case EM_GETMODIFY:
1411 case EM_SETMODIFY:
1412 case EM_GETLINECOUNT:
1413 case EM_LINEINDEX:
1414 case EM_SETHANDLE:
1415 case EM_GETHANDLE:
1416 case EM_GETTHUMB:
1417 case EM_LINELENGTH:
1418 case EM_REPLACESEL:
1419 case EM_GETLINE:
1420 case EM_LIMITTEXT:
1421 case EM_CANUNDO:
1422 case EM_UNDO:
1423 case EM_FMTLINES:
1424 case EM_LINEFROMCHAR:
1425 case EM_SETTABSTOPS:
1426 case EM_SETPASSWORDCHAR:
1427 case EM_EMPTYUNDOBUFFER:
1428 case EM_GETFIRSTVISIBLELINE:
1429 case EM_SETREADONLY:
1430 case EM_SETWORDBREAKPROC:
1431 case EM_GETWORDBREAKPROC:
1432 case EM_GETPASSWORDCHAR:
1433 *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
1434 return 0;
1436 case LB_CARETOFF:
1437 case LB_CARETON:
1438 case LB_DELETESTRING:
1439 case LB_GETANCHORINDEX:
1440 case LB_GETCARETINDEX:
1441 case LB_GETCOUNT:
1442 case LB_GETCURSEL:
1443 case LB_GETHORIZONTALEXTENT:
1444 case LB_GETITEMDATA:
1445 case LB_GETITEMHEIGHT:
1446 case LB_GETSEL:
1447 case LB_GETSELCOUNT:
1448 case LB_GETTEXTLEN:
1449 case LB_GETTOPINDEX:
1450 case LB_RESETCONTENT:
1451 case LB_SELITEMRANGE:
1452 case LB_SELITEMRANGEEX:
1453 case LB_SETANCHORINDEX:
1454 case LB_SETCARETINDEX:
1455 case LB_SETCOLUMNWIDTH:
1456 case LB_SETCURSEL:
1457 case LB_SETHORIZONTALEXTENT:
1458 case LB_SETITEMDATA:
1459 case LB_SETITEMHEIGHT:
1460 case LB_SETSEL:
1461 case LB_SETTOPINDEX:
1462 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1463 return 0;
1464 case CB_DELETESTRING:
1465 case CB_GETCOUNT:
1466 case CB_GETLBTEXTLEN:
1467 case CB_LIMITTEXT:
1468 case CB_RESETCONTENT:
1469 case CB_SETEDITSEL:
1470 case CB_GETCURSEL:
1471 case CB_SETCURSEL:
1472 case CB_SHOWDROPDOWN:
1473 case CB_SETITEMDATA:
1474 case CB_SETITEMHEIGHT:
1475 case CB_GETITEMHEIGHT:
1476 case CB_SETEXTENDEDUI:
1477 case CB_GETEXTENDEDUI:
1478 case CB_GETDROPPEDSTATE:
1479 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1480 return 0;
1481 case CB_GETEDITSEL:
1482 *pmsg16 = CB_GETEDITSEL16;
1483 return 1;
1485 case LB_ADDSTRING:
1486 case LB_FINDSTRING:
1487 case LB_FINDSTRINGEXACT:
1488 case LB_INSERTSTRING:
1489 case LB_SELECTSTRING:
1490 case LB_DIR:
1491 case LB_ADDFILE:
1493 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1494 if (!str) return -1;
1495 *plparam = (LPARAM)SEGPTR_GET(str);
1497 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
1498 return 1;
1500 case CB_ADDSTRING:
1501 case CB_FINDSTRING:
1502 case CB_FINDSTRINGEXACT:
1503 case CB_INSERTSTRING:
1504 case CB_SELECTSTRING:
1505 case CB_DIR:
1507 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1508 if (!str) return -1;
1509 *plparam = (LPARAM)SEGPTR_GET(str);
1511 *pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
1512 return 1;
1514 case LB_GETITEMRECT:
1516 RECT16 *rect;
1517 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1518 if (!rect) return -1;
1519 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1520 *plparam = (LPARAM)SEGPTR_GET(rect);
1522 *pmsg16 = LB_GETITEMRECT16;
1523 return 1;
1524 case LB_GETSELITEMS:
1526 LPINT16 items;
1527 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1528 if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1529 + sizeof(LPARAM)))) return -1;
1530 *((LPARAM *)items)++ = *plparam; /* Store the previous lParam */
1531 *plparam = (LPARAM)SEGPTR_GET(items);
1533 *pmsg16 = LB_GETSELITEMS16;
1534 return 1;
1535 case LB_SETTABSTOPS:
1536 if (wParam32)
1538 INT i;
1539 LPINT16 stops;
1540 *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
1541 if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
1542 + sizeof(LPARAM)))) return -1;
1543 for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
1544 *plparam = (LPARAM)SEGPTR_GET(stops);
1545 return 1;
1547 *pmsg16 = LB_SETTABSTOPS16;
1548 return 0;
1550 case CB_GETDROPPEDCONTROLRECT:
1552 RECT16 *rect;
1553 rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
1554 if (!rect) return -1;
1555 *(LPARAM *)(rect + 1) = *plparam; /* Store the previous lParam */
1556 *plparam = (LPARAM)SEGPTR_GET(rect);
1558 *pmsg16 = CB_GETDROPPEDCONTROLRECT16;
1559 return 1;
1561 case LB_GETTEXT:
1562 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1563 *pmsg16 = LB_GETTEXT16;
1564 return 1;
1566 case CB_GETLBTEXT:
1567 *plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
1568 *pmsg16 = CB_GETLBTEXT16;
1569 return 1;
1571 case EM_SETSEL:
1572 *pwparam16 = 0;
1573 *plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
1574 *pmsg16 = EM_SETSEL16;
1575 return 0;
1577 case WM_ACTIVATE:
1578 case WM_CHARTOITEM:
1579 case WM_COMMAND:
1580 case WM_VKEYTOITEM:
1581 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
1582 return 0;
1583 case WM_HSCROLL:
1584 case WM_VSCROLL:
1585 *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
1586 return 0;
1587 case WM_CTLCOLORMSGBOX:
1588 case WM_CTLCOLOREDIT:
1589 case WM_CTLCOLORLISTBOX:
1590 case WM_CTLCOLORBTN:
1591 case WM_CTLCOLORDLG:
1592 case WM_CTLCOLORSCROLLBAR:
1593 case WM_CTLCOLORSTATIC:
1594 *pmsg16 = WM_CTLCOLOR;
1595 *plparam = MAKELPARAM( (HWND16)*plparam,
1596 (WORD)msg32 - WM_CTLCOLORMSGBOX );
1597 return 0;
1598 case WM_COMPAREITEM:
1600 COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
1601 COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
1602 if (!cis) return -1;
1603 cis->CtlType = (UINT16)cis32->CtlType;
1604 cis->CtlID = (UINT16)cis32->CtlID;
1605 cis->hwndItem = (HWND16)cis32->hwndItem;
1606 cis->itemID1 = (UINT16)cis32->itemID1;
1607 cis->itemData1 = cis32->itemData1;
1608 cis->itemID2 = (UINT16)cis32->itemID2;
1609 cis->itemData2 = cis32->itemData2;
1610 *plparam = (LPARAM)SEGPTR_GET(cis);
1612 return 1;
1613 case WM_DELETEITEM:
1615 DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
1616 DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
1617 if (!dis) return -1;
1618 dis->CtlType = (UINT16)dis32->CtlType;
1619 dis->CtlID = (UINT16)dis32->CtlID;
1620 dis->itemID = (UINT16)dis32->itemID;
1621 dis->hwndItem = (HWND16)dis32->hwndItem;
1622 dis->itemData = dis32->itemData;
1623 *plparam = (LPARAM)SEGPTR_GET(dis);
1625 return 1;
1626 case WM_DRAWITEM:
1628 DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
1629 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
1630 if (!dis) return -1;
1631 dis->CtlType = (UINT16)dis32->CtlType;
1632 dis->CtlID = (UINT16)dis32->CtlID;
1633 dis->itemID = (UINT16)dis32->itemID;
1634 dis->itemAction = (UINT16)dis32->itemAction;
1635 dis->itemState = (UINT16)dis32->itemState;
1636 dis->hwndItem = (HWND16)dis32->hwndItem;
1637 dis->hDC = (HDC16)dis32->hDC;
1638 dis->itemData = dis32->itemData;
1639 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
1640 *plparam = (LPARAM)SEGPTR_GET(dis);
1642 return 1;
1643 case WM_MEASUREITEM:
1645 MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
1646 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
1647 SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
1648 if (!mis) return -1;
1649 mis->CtlType = (UINT16)mis32->CtlType;
1650 mis->CtlID = (UINT16)mis32->CtlID;
1651 mis->itemID = (UINT16)mis32->itemID;
1652 mis->itemWidth = (UINT16)mis32->itemWidth;
1653 mis->itemHeight = (UINT16)mis32->itemHeight;
1654 mis->itemData = mis32->itemData;
1655 *(LPARAM *)(mis + 1) = *plparam; /* Store the previous lParam */
1656 *plparam = (LPARAM)SEGPTR_GET(mis);
1658 return 1;
1659 case WM_GETMINMAXINFO:
1661 MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
1662 sizeof(LPARAM) );
1663 if (!mmi) return -1;
1664 STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
1665 *(LPARAM *)(mmi + 1) = *plparam; /* Store the previous lParam */
1666 *plparam = (LPARAM)SEGPTR_GET(mmi);
1668 return 1;
1669 case WM_GETTEXT:
1671 LPSTR str;
1672 *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
1673 if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
1674 *((LPARAM *)str)++ = *plparam; /* Store the previous lParam */
1675 *plparam = (LPARAM)SEGPTR_GET(str);
1677 return 1;
1678 case WM_MDICREATE:
1680 MDICREATESTRUCT16 *cs;
1681 MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
1682 LPSTR name, cls;
1684 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
1685 STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
1686 name = SEGPTR_STRDUP( cs32->szTitle );
1687 cls = SEGPTR_STRDUP( cs32->szClass );
1688 cs->szTitle = SEGPTR_GET(name);
1689 cs->szClass = SEGPTR_GET(cls);
1690 *plparam = (LPARAM)SEGPTR_GET(cs);
1692 return 1;
1693 case WM_MDIGETACTIVE:
1694 return 1;
1695 case WM_MDISETMENU:
1696 *plparam = MAKELPARAM( (HMENU16)LOWORD(wParam32),
1697 (HMENU16)LOWORD(*plparam) );
1698 *pwparam16 = (*plparam == 0);
1699 return 0;
1700 case WM_MENUCHAR:
1701 case WM_MENUSELECT:
1702 *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
1703 return 0;
1704 case WM_MDIACTIVATE:
1706 WND *tempWnd = WIN_FindWndPtr(hwnd);
1707 if( WIDGETS_IsControl(tempWnd, BIC32_MDICLIENT) )
1709 *pwparam16 = (HWND)wParam32;
1710 *plparam = 0;
1712 else
1714 *pwparam16 = ((HWND)*plparam == hwnd);
1715 *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
1716 (HWND16)LOWORD(wParam32) );
1718 WIN_ReleaseWndPtr(tempWnd);
1720 return 0;
1721 case WM_NCCALCSIZE:
1723 NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
1724 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
1725 if (!nc) return -1;
1727 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
1728 if (wParam32)
1730 WINDOWPOS16 *wp;
1731 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
1732 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
1733 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
1735 SEGPTR_FREE(nc);
1736 return -1;
1738 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
1739 nc->lppos = SEGPTR_GET(wp);
1741 *(LPARAM *)(nc + 1) = *plparam; /* Store the previous lParam */
1742 *plparam = (LPARAM)SEGPTR_GET(nc);
1744 return 1;
1745 case WM_NCCREATE:
1746 case WM_CREATE:
1748 CREATESTRUCT16 *cs;
1749 CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
1750 LPSTR name, cls;
1752 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
1753 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
1754 name = SEGPTR_STRDUP( cs32->lpszName );
1755 cls = SEGPTR_STRDUP( cs32->lpszClass );
1756 cs->lpszName = SEGPTR_GET(name);
1757 cs->lpszClass = SEGPTR_GET(cls);
1758 *plparam = (LPARAM)SEGPTR_GET(cs);
1760 return 1;
1761 case WM_PARENTNOTIFY:
1762 if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
1763 *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
1764 /* else nothing to do */
1765 return 0;
1766 case WM_NOTIFY:
1767 *plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
1768 return 1;
1769 case WM_SETTEXT:
1771 LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
1772 if (!str) return -1;
1773 *plparam = (LPARAM)SEGPTR_GET(str);
1775 return 1;
1776 case WM_WINDOWPOSCHANGING:
1777 case WM_WINDOWPOSCHANGED:
1779 WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
1780 sizeof(LPARAM) );
1781 if (!wp) return -1;
1782 STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
1783 *(LPARAM *)(wp + 1) = *plparam; /* Store the previous lParam */
1784 *plparam = (LPARAM)SEGPTR_GET(wp);
1786 return 1;
1787 case WM_GETDLGCODE:
1788 if (*plparam) {
1789 LPMSG msg32 = (LPMSG) *plparam;
1790 LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );
1792 if (!msg16) return -1;
1793 msg16->hwnd = msg32->hwnd;
1794 msg16->lParam = msg32->lParam;
1795 msg16->time = msg32->time;
1796 CONV_POINT32TO16(&msg32->pt,&msg16->pt);
1797 /* this is right, right? */
1798 if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
1799 &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
1800 SEGPTR_FREE( msg16 );
1801 return -1;
1803 *plparam = (LPARAM)SEGPTR_GET(msg16);
1804 return 1;
1806 return 0;
1808 case WM_ACTIVATEAPP:
1809 if (*plparam) {
1810 *plparam = (LPARAM)THREAD_IdToTHDB((DWORD) *plparam)->teb.htask16;
1812 return 1;
1813 case WM_ASKCBFORMATNAME:
1814 case WM_DEVMODECHANGE:
1815 case WM_PAINTCLIPBOARD:
1816 case WM_SIZECLIPBOARD:
1817 case WM_WININICHANGE:
1818 FIXME_(msg)("message %04x needs translation\n", msg32 );
1819 return -1;
1820 default: /* No translation needed */
1821 return 0;
1826 /**********************************************************************
1827 * WINPROC_UnmapMsg32ATo16
1829 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1831 void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
1832 MSGPARAM16* p16 )
1834 switch(msg)
1836 case LB_ADDFILE:
1837 case LB_ADDSTRING:
1838 case LB_DIR:
1839 case LB_FINDSTRING:
1840 case LB_FINDSTRINGEXACT:
1841 case LB_INSERTSTRING:
1842 case LB_SELECTSTRING:
1843 case LB_SETTABSTOPS:
1844 case CB_ADDSTRING:
1845 case CB_FINDSTRING:
1846 case CB_FINDSTRINGEXACT:
1847 case CB_INSERTSTRING:
1848 case CB_SELECTSTRING:
1849 case CB_DIR:
1850 case WM_COMPAREITEM:
1851 case WM_DELETEITEM:
1852 case WM_DRAWITEM:
1853 case WM_SETTEXT:
1854 SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
1855 break;
1857 case CB_GETDROPPEDCONTROLRECT:
1858 case LB_GETITEMRECT:
1860 RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
1861 p16->lParam = *(LPARAM *)(rect + 1);
1862 CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
1863 SEGPTR_FREE( rect );
1865 break;
1866 case LB_GETSELITEMS:
1868 INT i;
1869 LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
1870 p16->lParam = *((LPARAM *)items - 1);
1871 for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
1872 SEGPTR_FREE( (LPARAM *)items - 1 );
1874 break;
1876 case CB_GETEDITSEL:
1877 if( wParam )
1878 *((LPUINT)(wParam)) = LOWORD(p16->lResult);
1879 if( lParam )
1880 *((LPUINT)(lParam)) = HIWORD(p16->lResult); /* FIXME: substract 1? */
1881 break;
1883 case LB_GETTEXT:
1884 case CB_GETLBTEXT:
1885 UnMapLS( (SEGPTR)(p16->lParam) );
1886 break;
1888 case WM_MEASUREITEM:
1890 MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1891 MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
1892 mis32->itemWidth = mis->itemWidth;
1893 mis32->itemHeight = mis->itemHeight;
1894 SEGPTR_FREE(mis);
1896 break;
1897 case WM_GETMINMAXINFO:
1899 MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
1900 p16->lParam = *(LPARAM *)(mmi + 1);
1901 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
1902 SEGPTR_FREE(mmi);
1904 break;
1905 case WM_GETTEXT:
1907 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
1908 p16->lParam = *((LPARAM *)str - 1);
1909 lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
1910 SEGPTR_FREE( (LPARAM *)str - 1 );
1912 break;
1913 case WM_MDICREATE:
1915 MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
1916 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
1917 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
1918 SEGPTR_FREE( cs );
1920 break;
1921 case WM_MDIGETACTIVE:
1922 if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
1923 p16->lResult = (HWND)LOWORD(p16->lResult);
1924 break;
1925 case WM_NCCALCSIZE:
1927 NCCALCSIZE_PARAMS *nc32;
1928 NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
1929 p16->lParam = *(LPARAM *)(nc + 1);
1930 nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
1931 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
1932 if (p16->wParam)
1934 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
1935 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
1936 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
1937 nc32->lppos );
1938 SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
1940 SEGPTR_FREE(nc);
1942 break;
1943 case WM_NCCREATE:
1944 case WM_CREATE:
1946 CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1947 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
1948 SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
1949 SEGPTR_FREE( cs );
1951 break;
1952 case WM_WINDOWPOSCHANGING:
1953 case WM_WINDOWPOSCHANGED:
1955 WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
1956 p16->lParam = *(LPARAM *)(wp + 1);
1957 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
1958 SEGPTR_FREE(wp);
1960 break;
1961 case WM_NOTIFY:
1962 UnMapLS(p16->lParam);
1963 break;
1964 case WM_GETDLGCODE:
1965 if (p16->lParam)
1967 LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(p16->lParam);
1968 MSGPARAM16 msgp16;
1969 msgp16.wParam=msg16->wParam;
1970 msgp16.lParam=msg16->lParam;
1971 WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
1972 ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
1973 &msgp16 );
1974 SEGPTR_FREE(msg16);
1976 break;
1981 /**********************************************************************
1982 * WINPROC_MapMsg32WTo16
1984 * Map a message from 32-bit Unicode to 16-bit.
1985 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1987 INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
1988 UINT16 *pmsg16, WPARAM16 *pwparam16,
1989 LPARAM *plparam )
1991 switch(msg32)
1993 case LB_ADDSTRING:
1994 case LB_FINDSTRING:
1995 case LB_FINDSTRINGEXACT:
1996 case LB_INSERTSTRING:
1997 case LB_SELECTSTRING:
1998 case LB_DIR:
1999 case LB_ADDFILE:
2001 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2002 if (!str) return -1;
2003 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2004 *plparam = (LPARAM)SEGPTR_GET(str);
2006 *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
2007 return 1;
2009 case CB_ADDSTRING:
2010 case CB_FINDSTRING:
2011 case CB_FINDSTRINGEXACT:
2012 case CB_INSERTSTRING:
2013 case CB_SELECTSTRING:
2014 case CB_DIR:
2016 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2017 if (!str) return -1;
2018 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2019 *plparam = (LPARAM)SEGPTR_GET(str);
2021 *pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
2022 return 1;
2024 case WM_NCCREATE:
2025 case WM_CREATE:
2027 CREATESTRUCT16 *cs;
2028 CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
2029 LPSTR name, cls;
2031 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2032 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
2033 name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
2034 cls = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
2035 cs->lpszName = SEGPTR_GET(name);
2036 cs->lpszClass = SEGPTR_GET(cls);
2037 *pmsg16 = (UINT16)msg32;
2038 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2039 *plparam = (LPARAM)SEGPTR_GET(cs);
2041 return 1;
2042 case WM_MDICREATE:
2044 MDICREATESTRUCT16 *cs;
2045 MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
2046 LPSTR name, cls;
2048 if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2049 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
2050 name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
2051 cls = SEGPTR_STRDUP_WtoA( cs32->szClass );
2052 cs->szTitle = SEGPTR_GET(name);
2053 cs->szClass = SEGPTR_GET(cls);
2054 *pmsg16 = (UINT16)msg32;
2055 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2056 *plparam = (LPARAM)SEGPTR_GET(cs);
2058 return 1;
2059 case WM_SETTEXT:
2061 LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
2062 if (!str) return -1;
2063 *pmsg16 = (UINT16)msg32;
2064 *pwparam16 = (WPARAM16)LOWORD(wParam32);
2065 *plparam = (LPARAM)SEGPTR_GET(str);
2067 return 1;
2068 default: /* No Unicode translation needed */
2069 return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
2070 pwparam16, plparam );
2075 /**********************************************************************
2076 * WINPROC_UnmapMsg32WTo16
2078 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
2080 void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
2081 MSGPARAM16* p16 )
2083 switch(msg)
2085 case WM_GETTEXT:
2087 LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
2088 p16->lParam = *((LPARAM *)str - 1);
2089 lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
2090 SEGPTR_FREE( (LPARAM *)str - 1 );
2092 break;
2093 default:
2094 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
2095 break;
2100 /**********************************************************************
2101 * WINPROC_CallProc32ATo32W
2103 * Call a window procedure, translating args from Ansi to Unicode.
2105 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
2106 UINT msg, WPARAM wParam,
2107 LPARAM lParam )
2109 LRESULT result;
2111 if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
2112 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2113 WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
2114 return result;
2118 /**********************************************************************
2119 * WINPROC_CallProc32WTo32A
2121 * Call a window procedure, translating args from Unicode to Ansi.
2123 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
2124 UINT msg, WPARAM wParam,
2125 LPARAM lParam )
2127 LRESULT result;
2129 if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
2130 result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2131 WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
2132 return result;
2136 /**********************************************************************
2137 * WINPROC_CallProc16To32A
2139 * Call a 32-bit window procedure, translating the 16-bit args.
2141 LRESULT WINPROC_CallProc16To32A( HWND16 hwnd, UINT16 msg,
2142 WPARAM16 wParam, LPARAM lParam,
2143 WNDPROC func )
2145 LRESULT result;
2146 UINT msg32;
2147 WPARAM wParam32;
2149 if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2150 return 0;
2151 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2152 return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
2156 /**********************************************************************
2157 * WINPROC_CallProc16To32W
2159 * Call a 32-bit window procedure, translating the 16-bit args.
2161 LRESULT WINPROC_CallProc16To32W( HWND16 hwnd, UINT16 msg,
2162 WPARAM16 wParam, LPARAM lParam,
2163 WNDPROC func )
2165 LRESULT result;
2166 UINT msg32;
2167 WPARAM wParam32;
2169 if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
2170 return 0;
2172 result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2174 return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
2178 /**********************************************************************
2179 * WINPROC_CallProc32ATo16
2181 * Call a 16-bit window procedure, translating the 32-bit args.
2183 static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
2184 UINT msg, WPARAM wParam,
2185 LPARAM lParam )
2187 UINT16 msg16;
2188 MSGPARAM16 mp16;
2190 mp16.lParam = lParam;
2191 if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam,
2192 &msg16, &mp16.wParam, &mp16.lParam ) == -1)
2193 return 0;
2194 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
2195 mp16.wParam, mp16.lParam );
2196 WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
2197 return mp16.lResult;
2201 /**********************************************************************
2202 * WINPROC_CallProc32WTo16
2204 * Call a 16-bit window procedure, translating the 32-bit args.
2206 static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
2207 UINT msg, WPARAM wParam,
2208 LPARAM lParam )
2210 UINT16 msg16;
2211 MSGPARAM16 mp16;
2213 mp16.lParam = lParam;
2214 if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
2215 &mp16.lParam ) == -1)
2216 return 0;
2217 mp16.lResult = Callbacks->CallWndProc( func, hwnd, msg16,
2218 mp16.wParam, mp16.lParam );
2219 WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
2220 return mp16.lResult;
2224 /**********************************************************************
2225 * CallWindowProc16 (USER.122)
2227 LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
2228 WPARAM16 wParam, LPARAM lParam )
2230 WINDOWPROC *proc = WINPROC_GetPtr( func );
2232 if (!proc)
2233 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
2235 #if testing
2236 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2237 return Callbacks->CallWndProc( func, hwnd, msg, wParam, lParam );
2238 #endif
2240 switch(proc->type)
2242 case WIN_PROC_16:
2243 if (!proc->thunk.t_from32.proc) return 0;
2244 return Callbacks->CallWndProc( proc->thunk.t_from32.proc,
2245 hwnd, msg, wParam, lParam );
2246 case WIN_PROC_32A:
2247 if (!proc->thunk.t_from16.proc) return 0;
2248 return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,
2249 proc->thunk.t_from16.proc );
2250 case WIN_PROC_32W:
2251 if (!proc->thunk.t_from16.proc) return 0;
2252 return WINPROC_CallProc16To32W( hwnd, msg, wParam, lParam,
2253 proc->thunk.t_from16.proc );
2254 default:
2255 WARN_(relay)("Invalid proc %p\n", proc );
2256 return 0;
2261 /**********************************************************************
2262 * CallWindowProc32A (USER32.18)
2264 * The CallWindowProc() function invokes the windows procedure _func_,
2265 * with _hwnd_ as the target window, the message specified by _msg_, and
2266 * the message parameters _wParam_ and _lParam_.
2268 * Some kinds of argument conversion may be done, I'm not sure what.
2270 * CallWindowProc() may be used for windows subclassing. Use
2271 * SetWindowLong() to set a new windows procedure for windows of the
2272 * subclass, and handle subclassed messages in the new windows
2273 * procedure. The new windows procedure may then use CallWindowProc()
2274 * with _func_ set to the parent class's windows procedure to dispatch
2275 * the message to the superclass.
2277 * RETURNS
2279 * The return value is message dependent.
2281 * CONFORMANCE
2283 * ECMA-234, Win32
2285 LRESULT WINAPI CallWindowProcA(
2286 WNDPROC func, /* window procedure */
2287 HWND hwnd, /* target window */
2288 UINT msg, /* message */
2289 WPARAM wParam, /* message dependent parameter */
2290 LPARAM lParam /* message dependent parameter */
2292 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2294 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2296 #if testing
2297 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2298 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2299 #endif
2301 switch(proc->type)
2303 case WIN_PROC_16:
2304 if (!proc->thunk.t_from32.proc) return 0;
2305 return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
2306 hwnd, msg, wParam, lParam );
2307 case WIN_PROC_32A:
2308 if (!proc->thunk.t_from16.proc) return 0;
2309 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2310 hwnd, msg, wParam, lParam );
2311 case WIN_PROC_32W:
2312 if (!proc->thunk.t_from16.proc) return 0;
2313 return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
2314 hwnd, msg, wParam, lParam );
2315 default:
2316 WARN_(relay)("Invalid proc %p\n", proc );
2317 return 0;
2322 /**********************************************************************
2323 * CallWindowProc32W (USER32.19)
2325 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
2326 WPARAM wParam, LPARAM lParam )
2328 WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
2330 if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2332 #if testing
2333 func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2334 return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2335 #endif
2337 switch(proc->type)
2339 case WIN_PROC_16:
2340 if (!proc->thunk.t_from32.proc) return 0;
2341 return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
2342 hwnd, msg, wParam, lParam );
2343 case WIN_PROC_32A:
2344 if (!proc->thunk.t_from16.proc) return 0;
2345 return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
2346 hwnd, msg, wParam, lParam );
2347 case WIN_PROC_32W:
2348 if (!proc->thunk.t_from16.proc) return 0;
2349 return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
2350 hwnd, msg, wParam, lParam );
2351 default:
2352 WARN_(relay)("Invalid proc %p\n", proc );
2353 return 0;