2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
13 #include "registers.h"
14 #include "stackframe.h"
22 /* Window procedure 16-bit thunk; see BuildSpec16Files() in tools/build.c */
25 BYTE popl_eax
; /* popl %eax (return address) */
26 BYTE pushl_func
; /* pushl $proc */
27 WNDPROC32 proc WINE_PACKED
;
28 BYTE pushl_eax
; /* pushl %eax */
29 WORD pushw_bp WINE_PACKED
; /* pushw %bp */
30 BYTE pushl_thunk
; /* pushl $thunkfrom16 */
31 void (*thunk32
)() WINE_PACKED
;
32 BYTE lcall
; /* lcall cs:relay */
33 void (*relay
)() WINE_PACKED
;
35 } WINPROC_THUNK_FROM16
;
37 /* Window procedure 32-bit thunk; see BuildSpec32Files() in tools/build.c */
40 BYTE popl_eax
; /* popl %eax (return address) */
41 BYTE pushl_func
; /* pushl $proc */
42 WNDPROC16 proc WINE_PACKED
;
43 BYTE pushl_eax
; /* pushl %eax */
44 BYTE pushl_ebp
; /* pushl %ebp */
45 BYTE pushl_name
; /* pushl $name */
46 LPCSTR name WINE_PACKED
;
47 BYTE pushl_thunk
; /* pushl $thunkfrom32 */
48 void (*thunk32
)() WINE_PACKED
;
49 BYTE jmp
; /* jmp relay (relative jump)*/
50 void (*relay
)() WINE_PACKED
;
51 } WINPROC_THUNK_FROM32
;
53 /* Simple jmp to call 32-bit procedure directly */
56 BYTE jmp
; /* jmp proc (relative jump) */
57 WNDPROC32 proc WINE_PACKED
;
62 WINPROC_THUNK_FROM16 t_from16
;
63 WINPROC_THUNK_FROM32 t_from32
;
66 typedef struct tagWINDOWPROC
68 WINPROC_THUNK thunk
; /* Thunk */
69 WINPROC_JUMP jmp
; /* Jump */
70 struct tagWINDOWPROC
*next
; /* Next window proc */
71 UINT32 magic
; /* Magic number */
72 WINDOWPROCTYPE type
; /* Function type */
75 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
77 #define WINPROC_THUNKPROC(pproc) \
78 (((pproc)->type == WIN_PROC_16) ? \
79 (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
80 (WNDPROC16)((pproc)->thunk.t_from16.proc))
82 LRESULT
WINPROC_CallProc16To32A( HWND16 hwnd
, UINT16 msg
,
83 WPARAM16 wParam
, LPARAM lParam
,
85 LRESULT
WINPROC_CallProc16To32W( HWND16 hwnd
, UINT16 msg
,
86 WPARAM16 wParam
, LPARAM lParam
,
88 static LRESULT
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND32 hwnd
,
89 UINT32 msg
, WPARAM32 wParam
,
91 static LRESULT
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND32 hwnd
,
92 UINT32 msg
, WPARAM32 wParam
,
96 extern void CallFrom16_long_wwwll(void);
97 extern void CallFrom32_stdcall_5(void);
99 static void CallFrom16_long_wwwll(void) {}
100 static void CallFrom32_stdcall_5(void) {}
103 static HANDLE32 WinProcHeap
;
105 /**********************************************************************
108 BOOL32
WINPROC_Init(void)
110 WinProcHeap
= HeapCreate( HEAP_WINE_SEGPTR
| HEAP_WINE_CODESEG
, 0, 0 );
113 fprintf( stderr
, "Unable to create winproc heap\n" );
120 /**********************************************************************
123 * Return a pointer to the win proc.
125 static WINDOWPROC
*WINPROC_GetPtr( WNDPROC16 handle
)
130 /* Check for a linear pointer */
132 if (HEAP_IsInsideHeap( WinProcHeap
, 0, (LPVOID
)handle
))
134 ptr
= (BYTE
*)handle
;
135 /* First check if it is the jmp address */
136 if (*ptr
== 0xe9 /* jmp */) ptr
-= (int)&((WINDOWPROC
*)0)->jmp
-
137 (int)&((WINDOWPROC
*)0)->thunk
;
138 /* Now it must be the thunk address */
139 if (*ptr
== 0x58 /* popl eax */) ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
140 /* Now we have a pointer to the WINDOWPROC struct */
141 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
142 return (WINDOWPROC
*)ptr
;
145 /* Check for a segmented pointer */
147 if (!IsBadReadPtr16((SEGPTR
)handle
,sizeof(WINDOWPROC
)-sizeof(proc
->thunk
)))
149 ptr
= (BYTE
*)PTR_SEG_TO_LIN(handle
);
150 if (!HEAP_IsInsideHeap( WinProcHeap
, 0, ptr
)) return NULL
;
151 /* It must be the thunk address */
152 if (*ptr
== 0x58 /* popl eax */) ptr
-= (int)&((WINDOWPROC
*)0)->thunk
;
153 /* Now we have a pointer to the WINDOWPROC struct */
154 if (((WINDOWPROC
*)ptr
)->magic
== WINPROC_MAGIC
)
155 return (WINDOWPROC
*)ptr
;
162 /**********************************************************************
163 * WINPROC_AllocWinProc
165 * Allocate a new window procedure.
167 static WINDOWPROC
*WINPROC_AllocWinProc( WNDPROC16 func
, WINDOWPROCTYPE type
)
169 WINDOWPROC
*proc
, *oldproc
;
171 /* Allocate a window procedure */
173 if (!(proc
= HeapAlloc( WinProcHeap
, 0, sizeof(WINDOWPROC
) ))) return 0;
175 /* Check if the function is already a win proc */
177 if ((oldproc
= WINPROC_GetPtr( func
)))
186 proc
->thunk
.t_from32
.popl_eax
= 0x58; /* popl %eax */
187 proc
->thunk
.t_from32
.pushl_func
= 0x68; /* pushl $proc */
188 proc
->thunk
.t_from32
.proc
= func
;
189 proc
->thunk
.t_from32
.pushl_eax
= 0x50; /* pushl %eax */
190 proc
->thunk
.t_from32
.pushl_ebp
= 0x55; /* pushl %ebp */
191 proc
->thunk
.t_from32
.pushl_name
= 0x68; /* pushl $name */
192 proc
->thunk
.t_from32
.name
= "WINPROC_CallProc32ATo16";
193 proc
->thunk
.t_from32
.pushl_thunk
= 0x68; /* pushl $thunkfrom32 */
194 proc
->thunk
.t_from32
.thunk32
= (void(*)())WINPROC_CallProc32ATo16
;
195 proc
->thunk
.t_from32
.jmp
= 0xe9; /* jmp relay*/
196 proc
->thunk
.t_from32
.relay
= /* relative jump */
197 (void (*)())((DWORD
)CallFrom32_stdcall_5
-
198 (DWORD
)(&proc
->thunk
.t_from32
.relay
+ 1));
202 proc
->thunk
.t_from16
.popl_eax
= 0x58; /* popl %eax */
203 proc
->thunk
.t_from16
.pushl_func
= 0x68; /* pushl $proc */
204 proc
->thunk
.t_from16
.proc
= (FARPROC32
)func
;
205 proc
->thunk
.t_from16
.pushl_eax
= 0x50; /* pushl %eax */
206 proc
->thunk
.t_from16
.pushw_bp
= 0x5566; /* pushw %bp */
207 proc
->thunk
.t_from16
.pushl_thunk
= 0x68; /* pushl $thunkfrom16 */
208 proc
->thunk
.t_from16
.thunk32
= (type
== WIN_PROC_32A
) ?
209 (void(*)())WINPROC_CallProc16To32A
:
210 (void(*)())WINPROC_CallProc16To32W
;
211 proc
->thunk
.t_from16
.lcall
= 0x9a; /* lcall cs:relay */
212 proc
->thunk
.t_from16
.relay
= CallFrom16_long_wwwll
;
213 proc
->thunk
.t_from16
.cs
= WINE_CODE_SELECTOR
;
214 proc
->jmp
.jmp
= 0xe9;
215 /* Fixup relative jump */
216 proc
->jmp
.proc
= (WNDPROC32
)((DWORD
)func
-
217 (DWORD
)(&proc
->jmp
.proc
+ 1));
220 /* Should not happen */
223 proc
->magic
= WINPROC_MAGIC
;
227 dprintf_win( stddeb
, "WINPROC_AllocWinProc(%08x,%d): returning %08x\n",
228 (UINT32
)func
, type
, (UINT32
)proc
);
233 /**********************************************************************
236 * Get a window procedure pointer that can be passed to the Windows program.
238 WNDPROC16
WINPROC_GetProc( HWINDOWPROC proc
, WINDOWPROCTYPE type
)
240 if (type
== WIN_PROC_16
) /* We want a 16:16 address */
242 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
243 return ((WINDOWPROC
*)proc
)->thunk
.t_from32
.proc
;
245 return (WNDPROC16
)HEAP_GetSegptr( WinProcHeap
, 0,
246 &((WINDOWPROC
*)proc
)->thunk
);
248 else /* We want a 32-bit address */
250 if (((WINDOWPROC
*)proc
)->type
== WIN_PROC_16
)
251 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->thunk
;
253 return (WNDPROC16
)&((WINDOWPROC
*)proc
)->jmp
;
258 /**********************************************************************
261 * Set the window procedure for a window or class.
263 BOOL32
WINPROC_SetProc( HWINDOWPROC
*pFirst
, WNDPROC16 func
,
264 WINDOWPROCTYPE type
)
266 WINDOWPROC
*proc
, **ppPrev
;
268 /* Check if function is already in the list */
270 ppPrev
= (WINDOWPROC
**)pFirst
;
271 proc
= WINPROC_GetPtr( func
);
276 if (*ppPrev
== proc
) break;
280 if (((*ppPrev
)->type
== type
) &&
281 (func
== WINPROC_THUNKPROC(*ppPrev
))) break;
283 ppPrev
= &(*ppPrev
)->next
;
286 if (*ppPrev
) /* Remove it from the list */
289 *ppPrev
= proc
->next
;
291 else /* Allocate a new one */
293 if (proc
) /* Was already a win proc */
296 func
= WINPROC_THUNKPROC(proc
);
298 proc
= WINPROC_AllocWinProc( func
, type
);
299 if (!proc
) return FALSE
;
302 /* Add the win proc at the head of the list */
304 dprintf_win( stddeb
, "WINPROC_SetProc(%08x,%08x,%d): res=%08x\n",
305 (UINT32
)*pFirst
, (UINT32
)func
, type
, (UINT32
)proc
);
306 proc
->next
= *(WINDOWPROC
**)pFirst
;
307 *(WINDOWPROC
**)pFirst
= proc
;
312 /**********************************************************************
315 * Free a list of win procs.
317 void WINPROC_FreeProc( HWINDOWPROC proc
)
321 WINDOWPROC
*next
= ((WINDOWPROC
*)proc
)->next
;
322 dprintf_win( stddeb
, "WINPROC_FreeProc: freeing %08x\n", (UINT32
)proc
);
323 HeapFree( WinProcHeap
, 0, proc
);
329 /**********************************************************************
330 * WINPROC_GetProcType
332 * Return the window procedure type.
334 WINDOWPROCTYPE
WINPROC_GetProcType( HWINDOWPROC proc
)
337 (((WINDOWPROC
*)proc
)->magic
!= WINPROC_MAGIC
))
338 return WIN_PROC_INVALID
;
339 return ((WINDOWPROC
*)proc
)->type
;
343 /**********************************************************************
344 * WINPROC_MapMsg32ATo32W
346 * Map a message from Ansi to Unicode.
347 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
349 INT32
WINPROC_MapMsg32ATo32W( UINT32 msg
, WPARAM32 wParam
, LPARAM
*plparam
)
355 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0,
356 wParam
* sizeof(WCHAR
) + sizeof(LPARAM
) );
358 *ptr
++ = *plparam
; /* Store previous lParam */
359 *plparam
= (LPARAM
)ptr
;
363 *plparam
= (LPARAM
)STRING32_DupAnsiToUni( (LPCSTR
)*plparam
);
364 return (*plparam
? 1 : -1);
368 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)HeapAlloc( SystemHeap
, 0,
371 *cs
= *(CREATESTRUCT32W
*)*plparam
;
372 if (HIWORD(cs
->lpszName
))
373 cs
->lpszName
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszName
);
374 if (HIWORD(cs
->lpszClass
))
375 cs
->lpszClass
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszClass
);
376 *plparam
= (LPARAM
)cs
;
381 MDICREATESTRUCT32W
*cs
=
382 (MDICREATESTRUCT32W
*)HeapAlloc( SystemHeap
, 0, sizeof(*cs
) );
384 *cs
= *(MDICREATESTRUCT32W
*)*plparam
;
385 if (HIWORD(cs
->szClass
))
386 cs
->szClass
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->szClass
);
387 if (HIWORD(cs
->szTitle
))
388 cs
->szTitle
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->szTitle
);
389 *plparam
= (LPARAM
)cs
;
392 case WM_ASKCBFORMATNAME
:
393 case WM_DEVMODECHANGE
:
395 case WM_PAINTCLIPBOARD
:
396 case WM_SIZECLIPBOARD
:
397 case WM_WININICHANGE
:
398 fprintf( stderr
, "MapMsg32ATo32W: message %04x needs translation\n",
401 default: /* No translation needed */
407 /**********************************************************************
408 * WINPROC_UnmapMsg32ATo32W
410 * Unmap a message that was mapped from Ansi to Unicode.
412 void WINPROC_UnmapMsg32ATo32W( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
418 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
419 lstrcpynWtoA( (LPSTR
)*ptr
, (LPWSTR
)(ptr
+ 1), wParam
);
420 HeapFree( SystemHeap
, 0, ptr
);
424 free( (void *)lParam
);
429 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)lParam
;
430 if (HIWORD(cs
->lpszName
)) free( (LPVOID
)cs
->lpszName
);
431 if (HIWORD(cs
->lpszClass
)) free( (LPVOID
)cs
->lpszClass
);
432 HeapFree( SystemHeap
, 0, cs
);
437 MDICREATESTRUCT32W
*cs
= (MDICREATESTRUCT32W
*)lParam
;
438 if (HIWORD(cs
->szTitle
)) free( (LPVOID
)cs
->szTitle
);
439 if (HIWORD(cs
->szClass
)) free( (LPVOID
)cs
->szClass
);
440 HeapFree( SystemHeap
, 0, cs
);
447 /**********************************************************************
448 * WINPROC_MapMsg32WTo32A
450 * Map a message from Unicode to Ansi.
451 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
453 INT32
WINPROC_MapMsg32WTo32A( UINT32 msg
, WPARAM32 wParam
, LPARAM
*plparam
)
459 LPARAM
*ptr
= (LPARAM
*)HeapAlloc( SystemHeap
, 0,
460 wParam
+ sizeof(LPARAM
) );
462 *ptr
++ = *plparam
; /* Store previous lParam */
463 *plparam
= (LPARAM
)ptr
;
467 *plparam
= (LPARAM
)STRING32_DupUniToAnsi( (LPCWSTR
)*plparam
);
468 return (*plparam
? 1 : -1);
472 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)HeapAlloc( SystemHeap
, 0,
475 *cs
= *(CREATESTRUCT32A
*)*plparam
;
476 if (HIWORD(cs
->lpszName
))
477 cs
->lpszName
= STRING32_DupUniToAnsi( (LPCWSTR
)cs
->lpszName
);
478 if (HIWORD(cs
->lpszClass
))
479 cs
->lpszClass
= STRING32_DupUniToAnsi( (LPCWSTR
)cs
->lpszClass
);
480 *plparam
= (LPARAM
)cs
;
485 MDICREATESTRUCT32A
*cs
=
486 (MDICREATESTRUCT32A
*)HeapAlloc( SystemHeap
, 0, sizeof(*cs
) );
488 *cs
= *(MDICREATESTRUCT32A
*)*plparam
;
489 if (HIWORD(cs
->szTitle
))
490 cs
->szTitle
= STRING32_DupUniToAnsi( (LPCWSTR
)cs
->szTitle
);
491 if (HIWORD(cs
->szClass
))
492 cs
->szClass
= STRING32_DupUniToAnsi( (LPCWSTR
)cs
->szClass
);
493 *plparam
= (LPARAM
)cs
;
496 case WM_ASKCBFORMATNAME
:
497 case WM_DEVMODECHANGE
:
499 case WM_PAINTCLIPBOARD
:
500 case WM_SIZECLIPBOARD
:
501 case WM_WININICHANGE
:
502 fprintf( stderr
, "MapMsg32WTo32A: message %04x needs translation\n",
505 default: /* No translation needed */
511 /**********************************************************************
512 * WINPROC_UnmapMsg32WTo32A
514 * Unmap a message that was mapped from Unicode to Ansi.
516 void WINPROC_UnmapMsg32WTo32A( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
522 LPARAM
*ptr
= (LPARAM
*)lParam
- 1;
523 lstrcpynAtoW( (LPWSTR
)*ptr
, (LPSTR
)(ptr
+ 1), wParam
);
524 HeapFree( SystemHeap
, 0, ptr
);
528 free( (void *)lParam
);
533 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
534 if (HIWORD(cs
->lpszName
)) free( (LPVOID
)cs
->lpszName
);
535 if (HIWORD(cs
->lpszClass
)) free( (LPVOID
)cs
->lpszClass
);
536 HeapFree( SystemHeap
, 0, cs
);
541 MDICREATESTRUCT32A
*cs
= (MDICREATESTRUCT32A
*)lParam
;
542 if (HIWORD(cs
->szTitle
)) free( (LPVOID
)cs
->szTitle
);
543 if (HIWORD(cs
->szClass
)) free( (LPVOID
)cs
->szClass
);
544 HeapFree( SystemHeap
, 0, cs
);
551 /**********************************************************************
552 * WINPROC_MapMsg16To32A
554 * Map a message from 16- to 32-bit Ansi.
555 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
557 INT32
WINPROC_MapMsg16To32A( UINT16 msg16
, WPARAM16 wParam16
, UINT32
*pmsg32
,
558 WPARAM32
*pwparam32
, LPARAM
*plparam
)
560 *pmsg32
= (UINT32
)msg16
;
561 *pwparam32
= (WPARAM32
)wParam16
;
568 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
569 *plparam
= (LPARAM
)(HWND32
)LOWORD(*plparam
);
573 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
574 *plparam
= (LPARAM
)(HWND32
)HIWORD(*plparam
);
577 *pmsg32
= WM_CTLCOLORMSGBOX
+ HIWORD(*plparam
);
578 *pwparam32
= (WPARAM32
)(HDC32
)wParam16
;
579 *plparam
= (LPARAM
)(HWND32
)LOWORD(*plparam
);
583 COMPAREITEMSTRUCT16
* cis16
= (COMPAREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
584 COMPAREITEMSTRUCT32
*cis
= (COMPAREITEMSTRUCT32
*)
585 HeapAlloc(SystemHeap
, 0, sizeof(*cis
));
587 cis
->CtlType
= cis16
->CtlType
;
588 cis
->CtlID
= cis16
->CtlID
;
589 cis
->hwndItem
= cis16
->hwndItem
;
590 cis
->itemID1
= cis16
->itemID1
;
591 cis
->itemData1
= cis16
->itemData1
;
592 cis
->itemID2
= cis16
->itemID2
;
593 cis
->itemData2
= cis16
->itemData2
;
594 cis
->dwLocaleId
= 0; /* FIXME */
595 *plparam
= (LPARAM
)cis
;
600 DELETEITEMSTRUCT16
* dis16
= (DELETEITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
601 DELETEITEMSTRUCT32
*dis
= (DELETEITEMSTRUCT32
*)
602 HeapAlloc(SystemHeap
, 0, sizeof(*dis
));
604 dis
->CtlType
= dis16
->CtlType
;
605 dis
->CtlID
= dis16
->CtlID
;
606 dis
->hwndItem
= dis16
->hwndItem
;
607 dis
->itemData
= dis16
->itemData
;
608 *plparam
= (LPARAM
)dis
;
613 MEASUREITEMSTRUCT16
* mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
614 MEASUREITEMSTRUCT32
*mis
= (MEASUREITEMSTRUCT32
*)
615 HeapAlloc(SystemHeap
, 0,
616 sizeof(*mis
) + sizeof(LPARAM
));
618 mis
->CtlType
= mis16
->CtlType
;
619 mis
->CtlID
= mis16
->CtlID
;
620 mis
->itemID
= mis16
->itemID
;
621 mis
->itemWidth
= mis16
->itemWidth
;
622 mis
->itemHeight
= mis16
->itemHeight
;
623 mis
->itemData
= mis16
->itemData
;
624 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
625 *plparam
= (LPARAM
)mis
;
630 DRAWITEMSTRUCT16
* dis16
= (DRAWITEMSTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
631 DRAWITEMSTRUCT32
*dis
= (DRAWITEMSTRUCT32
*)HeapAlloc(SystemHeap
, 0,
634 dis
->CtlType
= dis16
->CtlType
;
635 dis
->CtlID
= dis16
->CtlID
;
636 dis
->itemID
= dis16
->itemID
;
637 dis
->itemAction
= dis16
->itemAction
;
638 dis
->itemState
= dis16
->itemState
;
639 dis
->hwndItem
= dis16
->hwndItem
;
640 dis
->hDC
= dis16
->hDC
;
641 dis
->itemData
= dis16
->itemData
;
642 CONV_RECT16TO32( &dis16
->rcItem
, &dis
->rcItem
);
643 *plparam
= (LPARAM
)dis
;
646 case WM_GETMINMAXINFO
:
648 MINMAXINFO32
*mmi
= (MINMAXINFO32
*)HeapAlloc( SystemHeap
, 0,
649 sizeof(*mmi
) + sizeof(LPARAM
));
651 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16
*)PTR_SEG_TO_LIN(*plparam
),
653 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
654 *plparam
= (LPARAM
)mmi
;
658 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
662 MDICREATESTRUCT16
*cs16
=
663 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
664 MDICREATESTRUCT32A
*cs
=
665 (MDICREATESTRUCT32A
*)HeapAlloc( SystemHeap
, 0,
666 sizeof(*cs
) + sizeof(LPARAM
) );
668 STRUCT32_MDICREATESTRUCT16to32A( cs16
, cs
);
669 cs
->szTitle
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
670 cs
->szClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
671 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
672 *plparam
= (LPARAM
)cs
;
676 *pwparam32
= (WPARAM32
)(HMENU32
)LOWORD(*plparam
);
677 *plparam
= (LPARAM
)(HMENU32
)HIWORD(*plparam
);
681 *pwparam32
= MAKEWPARAM( wParam16
, LOWORD(*plparam
) );
682 *plparam
= (LPARAM
)(HMENU32
)HIWORD(*plparam
);
686 NCCALCSIZE_PARAMS16
*nc16
;
687 NCCALCSIZE_PARAMS32
*nc
;
689 nc
= (NCCALCSIZE_PARAMS32
*)HeapAlloc( SystemHeap
, 0,
690 sizeof(*nc
) + sizeof(LPARAM
) );
692 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(*plparam
);
693 CONV_RECT16TO32( &nc16
->rgrc
[0], &nc
->rgrc
[0] );
696 nc
->lppos
= (WINDOWPOS32
*)HeapAlloc( SystemHeap
, 0,
697 sizeof(*nc
->lppos
) );
698 CONV_RECT16TO32( &nc16
->rgrc
[1], &nc
->rgrc
[1] );
699 CONV_RECT16TO32( &nc16
->rgrc
[2], &nc
->rgrc
[2] );
700 if (nc
->lppos
) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
), nc
->lppos
);
702 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
703 *plparam
= (LPARAM
)nc
;
709 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
710 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)HeapAlloc( SystemHeap
, 0,
711 sizeof(*cs
) + sizeof(LPARAM
) );
713 STRUCT32_CREATESTRUCT16to32A( cs16
, cs
);
714 cs
->lpszName
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
715 cs
->lpszClass
= (LPCSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
716 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
717 *plparam
= (LPARAM
)cs
;
720 case WM_PARENTNOTIFY
:
721 if ((wParam16
== WM_CREATE
) || (wParam16
== WM_DESTROY
))
723 *pwparam32
= MAKEWPARAM( wParam16
, HIWORD(*plparam
) );
724 *plparam
= (LPARAM
)(HWND32
)LOWORD(*plparam
);
728 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
730 case WM_WINDOWPOSCHANGING
:
731 case WM_WINDOWPOSCHANGED
:
733 WINDOWPOS32
*wp
= (WINDOWPOS32
*)HeapAlloc( SystemHeap
, 0,
734 sizeof(*wp
) + sizeof(LPARAM
) );
736 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(*plparam
),
738 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
739 *plparam
= (LPARAM
)wp
;
742 case WM_ASKCBFORMATNAME
:
743 case WM_DEVMODECHANGE
:
745 case WM_PAINTCLIPBOARD
:
746 case WM_SIZECLIPBOARD
:
747 case WM_WININICHANGE
:
748 fprintf( stderr
, "MapMsg16To32A: message %04x needs translation\n",
752 default: /* No translation needed */
758 /**********************************************************************
759 * WINPROC_UnmapMsg16To32A
761 * Unmap a message that was mapped from 16- to 32-bit Ansi.
763 void WINPROC_UnmapMsg16To32A( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
770 HeapFree( SystemHeap
, 0, (LPVOID
)lParam
);
774 MEASUREITEMSTRUCT16
*mis16
;
775 MEASUREITEMSTRUCT32
*mis
= (MEASUREITEMSTRUCT32
*)lParam
;
776 lParam
= *(LPARAM
*)(mis
+ 1);
777 mis16
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
778 mis16
->itemWidth
= (UINT16
)mis
->itemWidth
;
779 mis16
->itemHeight
= (UINT16
)mis
->itemHeight
;
780 HeapFree( SystemHeap
, 0, mis
);
783 case WM_GETMINMAXINFO
:
785 MINMAXINFO32
*mmi
= (MINMAXINFO32
*)lParam
;
786 lParam
= *(LPARAM
*)(mmi
+ 1);
787 STRUCT32_MINMAXINFO32to16( mmi
,
788 (MINMAXINFO16
*)PTR_SEG_TO_LIN(lParam
));
789 HeapFree( SystemHeap
, 0, mmi
);
794 MDICREATESTRUCT32A
*cs
= (MDICREATESTRUCT32A
*)lParam
;
795 lParam
= *(LPARAM
*)(cs
+ 1);
796 STRUCT32_MDICREATESTRUCT32Ato16( cs
,
797 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
798 HeapFree( SystemHeap
, 0, cs
);
803 NCCALCSIZE_PARAMS16
*nc16
;
804 NCCALCSIZE_PARAMS32
*nc
= (NCCALCSIZE_PARAMS32
*)lParam
;
805 lParam
= *(LPARAM
*)(nc
+ 1);
806 nc16
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(lParam
);
807 CONV_RECT32TO16( &nc
->rgrc
[0], &nc16
->rgrc
[0] );
810 CONV_RECT32TO16( &nc
->rgrc
[1], &nc16
->rgrc
[1] );
811 CONV_RECT32TO16( &nc
->rgrc
[2], &nc16
->rgrc
[2] );
814 STRUCT32_WINDOWPOS32to16( nc
->lppos
,
815 (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc16
->lppos
));
816 HeapFree( SystemHeap
, 0, nc
->lppos
);
819 HeapFree( SystemHeap
, 0, nc
);
825 CREATESTRUCT32A
*cs
= (CREATESTRUCT32A
*)lParam
;
826 lParam
= *(LPARAM
*)(cs
+ 1);
827 STRUCT32_CREATESTRUCT32Ato16( cs
,
828 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
829 HeapFree( SystemHeap
, 0, cs
);
832 case WM_WINDOWPOSCHANGING
:
833 case WM_WINDOWPOSCHANGED
:
835 WINDOWPOS32
*wp
= (WINDOWPOS32
*)lParam
;
836 lParam
= *(LPARAM
*)(wp
+ 1);
837 STRUCT32_WINDOWPOS32to16(wp
,(WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
));
838 HeapFree( SystemHeap
, 0, wp
);
845 /**********************************************************************
846 * WINPROC_MapMsg16To32W
848 * Map a message from 16- to 32-bit Unicode.
849 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
851 INT32
WINPROC_MapMsg16To32W( UINT16 msg16
, WPARAM16 wParam16
, UINT32
*pmsg32
,
852 WPARAM32
*pwparam32
, LPARAM
*plparam
)
858 *plparam
= (LPARAM
)PTR_SEG_TO_LIN(*plparam
);
859 return WINPROC_MapMsg32ATo32W( *pmsg32
, *pwparam32
, plparam
);
863 CREATESTRUCT16
*cs16
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
864 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)HeapAlloc( SystemHeap
, 0,
865 sizeof(*cs
) + sizeof(LPARAM
) );
867 STRUCT32_CREATESTRUCT16to32A( cs16
, (CREATESTRUCT32A
*)cs
);
868 cs
->lpszName
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszName
);
869 cs
->lpszClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->lpszClass
);
870 if (HIWORD(cs
->lpszName
))
871 cs
->lpszName
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszName
);
872 if (HIWORD(cs
->lpszClass
))
873 cs
->lpszClass
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->lpszClass
);
874 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
875 *plparam
= (LPARAM
)cs
;
880 MDICREATESTRUCT16
*cs16
=
881 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(*plparam
);
882 MDICREATESTRUCT32W
*cs
=
883 (MDICREATESTRUCT32W
*)HeapAlloc( SystemHeap
, 0,
884 sizeof(*cs
) + sizeof(LPARAM
) );
886 STRUCT32_MDICREATESTRUCT16to32A( cs16
, (MDICREATESTRUCT32A
*)cs
);
887 cs
->szTitle
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szTitle
);
888 cs
->szClass
= (LPCWSTR
)PTR_SEG_TO_LIN(cs16
->szClass
);
889 if (HIWORD(cs
->szTitle
))
890 cs
->szTitle
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->szTitle
);
891 if (HIWORD(cs
->szClass
))
892 cs
->szClass
= STRING32_DupAnsiToUni( (LPCSTR
)cs
->szClass
);
893 *(LPARAM
*)(cs
+ 1) = *plparam
; /* Store the previous lParam */
894 *plparam
= (LPARAM
)cs
;
897 default: /* No Unicode translation needed */
898 return WINPROC_MapMsg16To32A( msg16
, wParam16
, pmsg32
,
899 pwparam32
, plparam
);
904 /**********************************************************************
905 * WINPROC_UnmapMsg16To32W
907 * Unmap a message that was mapped from 16- to 32-bit Unicode.
909 void WINPROC_UnmapMsg16To32W( UINT32 msg
, WPARAM32 wParam
, LPARAM lParam
)
915 WINPROC_UnmapMsg32ATo32W( msg
, wParam
, lParam
);
920 CREATESTRUCT32W
*cs
= (CREATESTRUCT32W
*)lParam
;
921 lParam
= *(LPARAM
*)(cs
+ 1);
922 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A
*)cs
,
923 (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
924 if (HIWORD(cs
->lpszName
)) free( (LPVOID
)cs
->lpszName
);
925 if (HIWORD(cs
->lpszClass
)) free( (LPVOID
)cs
->lpszClass
);
926 HeapFree( SystemHeap
, 0, cs
);
931 MDICREATESTRUCT32W
*cs
= (MDICREATESTRUCT32W
*)lParam
;
932 lParam
= *(LPARAM
*)(cs
+ 1);
933 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A
*)cs
,
934 (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
) );
935 if (HIWORD(cs
->szTitle
)) free( (LPVOID
)cs
->szTitle
);
936 if (HIWORD(cs
->szClass
)) free( (LPVOID
)cs
->szClass
);
937 HeapFree( SystemHeap
, 0, cs
);
941 WINPROC_UnmapMsg16To32A( msg
, wParam
, lParam
);
947 /**********************************************************************
948 * WINPROC_MapMsg32ATo16
950 * Map a message from 32-bit Ansi to 16-bit.
951 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
953 INT32
WINPROC_MapMsg32ATo16( UINT32 msg32
, WPARAM32 wParam32
, UINT16
*pmsg16
,
954 WPARAM16
*pwparam16
, LPARAM
*plparam
)
956 *pmsg16
= (UINT16
)msg32
;
957 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
965 *pmsg16
= (UINT16
)msg32
+ (BM_GETCHECK16
- BM_GETCHECK32
);
969 case LB_DELETESTRING32
:
970 case LB_GETANCHORINDEX32
:
971 case LB_GETCARETINDEX32
:
974 case LB_GETHORIZONTALEXTENT32
:
975 case LB_GETITEMDATA32
:
976 case LB_GETITEMHEIGHT32
:
978 case LB_GETSELCOUNT32
:
979 case LB_GETTEXTLEN32
:
980 case LB_GETTOPINDEX32
:
981 case LB_RESETCONTENT32
:
982 case LB_SELITEMRANGE32
:
983 case LB_SELITEMRANGEEX32
:
984 case LB_SETANCHORINDEX32
:
985 case LB_SETCARETINDEX32
:
986 case LB_SETCOLUMNWIDTH32
:
988 case LB_SETHORIZONTALEXTENT32
:
989 case LB_SETITEMDATA32
:
990 case LB_SETITEMHEIGHT32
:
992 case LB_SETTOPINDEX32
:
993 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING32
);
996 case LB_FINDSTRING32
:
997 case LB_FINDSTRINGEXACT32
:
998 case LB_INSERTSTRING32
:
999 case LB_SELECTSTRING32
:
1002 /* case LB_GETTEXT32: FIXME */
1004 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1005 if (!str
) return -1;
1006 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1008 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING32
);
1010 case LB_GETITEMRECT32
:
1013 rect
= (RECT16
*)SEGPTR_ALLOC( sizeof(RECT16
) + sizeof(LPARAM
) );
1014 if (!rect
) return -1;
1015 *(LPARAM
*)(rect
+ 1) = *plparam
; /* Store the previous lParam */
1016 *plparam
= (LPARAM
)SEGPTR_GET(rect
);
1019 case LB_GETSELITEMS32
:
1022 *pwparam16
= (WPARAM16
)MIN( wParam32
, 0x7f80 ); /* Must be < 64K */
1023 if (!(items
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1024 + sizeof(LPARAM
)))) return -1;
1025 *((LPARAM
*)items
)++ = *plparam
; /* Store the previous lParam */
1026 *plparam
= (LPARAM
)SEGPTR_GET(items
);
1029 case LB_SETTABSTOPS32
:
1034 *pwparam16
= (WPARAM16
)MIN( wParam32
, 0x7f80 ); /* Must be < 64K */
1035 if (!(stops
= SEGPTR_ALLOC( *pwparam16
* sizeof(INT16
)
1036 + sizeof(LPARAM
)))) return -1;
1037 for (i
= 0; i
< *pwparam16
; i
++) stops
[i
] = *((LPINT32
)*plparam
+i
);
1038 *plparam
= (LPARAM
)SEGPTR_GET(stops
);
1041 *pmsg16
= LB_SETTABSTOPS16
;
1047 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
) );
1051 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HWND16
)*plparam
);
1053 case WM_CTLCOLORMSGBOX
:
1054 case WM_CTLCOLOREDIT
:
1055 case WM_CTLCOLORLISTBOX
:
1056 case WM_CTLCOLORBTN
:
1057 case WM_CTLCOLORDLG
:
1058 case WM_CTLCOLORSCROLLBAR
:
1059 case WM_CTLCOLORSTATIC
:
1060 *pmsg16
= WM_CTLCOLOR
;
1061 *plparam
= MAKELPARAM( (HWND16
)*plparam
,
1062 (WORD
)msg32
- WM_CTLCOLORMSGBOX
);
1064 case WM_COMPAREITEM
:
1066 COMPAREITEMSTRUCT32
*cis32
= (COMPAREITEMSTRUCT32
*)*plparam
;
1067 COMPAREITEMSTRUCT16
*cis
= SEGPTR_NEW(COMPAREITEMSTRUCT16
);
1068 if (!cis
) return -1;
1069 cis
->CtlType
= (UINT16
)cis32
->CtlType
;
1070 cis
->CtlID
= (UINT16
)cis32
->CtlID
;
1071 cis
->hwndItem
= (HWND16
)cis32
->hwndItem
;
1072 cis
->itemID1
= (UINT16
)cis32
->itemID1
;
1073 cis
->itemData1
= cis32
->itemData1
;
1074 cis
->itemID2
= (UINT16
)cis32
->itemID2
;
1075 cis
->itemData2
= cis32
->itemData2
;
1076 *plparam
= (LPARAM
)SEGPTR_GET(cis
);
1081 DELETEITEMSTRUCT32
*dis32
= (DELETEITEMSTRUCT32
*)*plparam
;
1082 DELETEITEMSTRUCT16
*dis
= SEGPTR_NEW(DELETEITEMSTRUCT16
);
1083 if (!dis
) return -1;
1084 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1085 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1086 dis
->itemID
= (UINT16
)dis32
->itemID
;
1087 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1088 dis
->itemData
= dis32
->itemData
;
1089 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1094 DRAWITEMSTRUCT32
*dis32
= (DRAWITEMSTRUCT32
*)*plparam
;
1095 DRAWITEMSTRUCT16
*dis
= SEGPTR_NEW(DRAWITEMSTRUCT16
);
1096 if (!dis
) return -1;
1097 dis
->CtlType
= (UINT16
)dis32
->CtlType
;
1098 dis
->CtlID
= (UINT16
)dis32
->CtlID
;
1099 dis
->itemID
= (UINT16
)dis32
->itemID
;
1100 dis
->itemAction
= (UINT16
)dis32
->itemAction
;
1101 dis
->itemState
= (UINT16
)dis32
->itemState
;
1102 dis
->hwndItem
= (HWND16
)dis32
->hwndItem
;
1103 dis
->hDC
= (HDC16
)dis32
->hDC
;
1104 dis
->itemData
= dis32
->itemData
;
1105 CONV_RECT32TO16( &dis32
->rcItem
, &dis
->rcItem
);
1106 *plparam
= (LPARAM
)SEGPTR_GET(dis
);
1109 case WM_MEASUREITEM
:
1111 MEASUREITEMSTRUCT32
*mis32
= (MEASUREITEMSTRUCT32
*)*plparam
;
1112 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)
1113 SEGPTR_ALLOC(sizeof(*mis
)+sizeof(LPARAM
));
1114 if (!mis
) return -1;
1115 mis
->CtlType
= (UINT16
)mis32
->CtlType
;
1116 mis
->CtlID
= (UINT16
)mis32
->CtlID
;
1117 mis
->itemID
= (UINT16
)mis32
->itemID
;
1118 mis
->itemWidth
= (UINT16
)mis32
->itemWidth
;
1119 mis
->itemHeight
= (UINT16
)mis32
->itemHeight
;
1120 mis
->itemData
= mis32
->itemData
;
1121 *(LPARAM
*)(mis
+ 1) = *plparam
; /* Store the previous lParam */
1122 *plparam
= (LPARAM
)SEGPTR_GET(mis
);
1125 case WM_GETMINMAXINFO
:
1127 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)SEGPTR_ALLOC( sizeof(*mmi
) +
1129 if (!mmi
) return -1;
1130 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32
*)*plparam
, mmi
);
1131 *(LPARAM
*)(mmi
+ 1) = *plparam
; /* Store the previous lParam */
1132 *plparam
= (LPARAM
)SEGPTR_GET(mmi
);
1138 *pwparam16
= (WPARAM16
)MIN( wParam32
, 0xff80 ); /* Must be < 64K */
1139 if (!(str
= SEGPTR_ALLOC(*pwparam16
+ sizeof(LPARAM
)))) return -1;
1140 *((LPARAM
*)str
)++ = *plparam
; /* Store the previous lParam */
1141 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1146 MDICREATESTRUCT16
*cs
;
1147 MDICREATESTRUCT32A
*cs32
= (MDICREATESTRUCT32A
*)*plparam
;
1150 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
1151 STRUCT32_MDICREATESTRUCT32Ato16( cs32
, cs
);
1152 name
= SEGPTR_STRDUP( cs32
->szTitle
);
1153 cls
= SEGPTR_STRDUP( cs32
->szClass
);
1154 cs
->szTitle
= SEGPTR_GET(name
);
1155 cs
->szClass
= SEGPTR_GET(cls
);
1156 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1160 *pwparam16
= TRUE
; /* FIXME? */
1161 *plparam
= MAKELPARAM( (HMENU16
)LOWORD(wParam32
),
1162 (HMENU16
)LOWORD(*plparam
) );
1166 *plparam
= MAKELPARAM( HIWORD(wParam32
), (HMENU16
)*plparam
);
1170 NCCALCSIZE_PARAMS32
*nc32
= (NCCALCSIZE_PARAMS32
*)*plparam
;
1171 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)SEGPTR_ALLOC( sizeof(*nc
) + sizeof(LPARAM
) );
1174 CONV_RECT32TO16( &nc32
->rgrc
[0], &nc
->rgrc
[0] );
1178 CONV_RECT32TO16( &nc32
->rgrc
[1], &nc
->rgrc
[1] );
1179 CONV_RECT32TO16( &nc32
->rgrc
[2], &nc
->rgrc
[2] );
1180 if (!(wp
= SEGPTR_NEW(WINDOWPOS16
)))
1185 STRUCT32_WINDOWPOS32to16( nc32
->lppos
, wp
);
1186 nc
->lppos
= SEGPTR_GET(wp
);
1188 *(LPARAM
*)(nc
+ 1) = *plparam
; /* Store the previous lParam */
1189 *plparam
= (LPARAM
)SEGPTR_GET(nc
);
1196 CREATESTRUCT32A
*cs32
= (CREATESTRUCT32A
*)*plparam
;
1199 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
1200 STRUCT32_CREATESTRUCT32Ato16( cs32
, cs
);
1201 name
= SEGPTR_STRDUP( cs32
->lpszName
);
1202 cls
= SEGPTR_STRDUP( cs32
->lpszClass
);
1203 cs
->lpszName
= SEGPTR_GET(name
);
1204 cs
->lpszClass
= SEGPTR_GET(cls
);
1205 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1208 case WM_PARENTNOTIFY
:
1209 if ((LOWORD(wParam32
)==WM_CREATE
) || (LOWORD(wParam32
)==WM_DESTROY
))
1210 *plparam
= MAKELPARAM( (HWND16
)*plparam
, HIWORD(wParam32
));
1211 /* else nothing to do */
1215 LPSTR str
= SEGPTR_STRDUP( (LPSTR
)*plparam
);
1216 if (!str
) return -1;
1217 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1220 case WM_WINDOWPOSCHANGING
:
1221 case WM_WINDOWPOSCHANGED
:
1223 WINDOWPOS16
*wp
= (WINDOWPOS16
*)SEGPTR_ALLOC( sizeof(*wp
) +
1226 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32
*)*plparam
, wp
);
1227 *(LPARAM
*)(wp
+ 1) = *plparam
; /* Store the previous lParam */
1228 *plparam
= (LPARAM
)SEGPTR_GET(wp
);
1231 case WM_ASKCBFORMATNAME
:
1232 case WM_DEVMODECHANGE
:
1233 case WM_MDIACTIVATE
:
1234 case WM_PAINTCLIPBOARD
:
1235 case WM_SIZECLIPBOARD
:
1236 case WM_WININICHANGE
:
1237 fprintf( stderr
, "MapMsg32ATo16: message %04x needs translation\n",
1241 default: /* No translation needed */
1247 /**********************************************************************
1248 * WINPROC_UnmapMsg32ATo16
1250 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
1252 void WINPROC_UnmapMsg32ATo16( UINT32 msg
, WPARAM16 wParam
, LPARAM lParam
)
1257 case LB_ADDSTRING32
:
1259 case LB_FINDSTRING32
:
1260 case LB_FINDSTRINGEXACT32
:
1261 case LB_INSERTSTRING32
:
1262 case LB_SELECTSTRING32
:
1263 case LB_SETTABSTOPS32
:
1264 case WM_COMPAREITEM
:
1268 SEGPTR_FREE( PTR_SEG_TO_LIN(lParam
) );
1270 case LB_GETITEMRECT32
:
1272 RECT16
*rect
= (RECT16
*)PTR_SEG_TO_LIN(lParam
);
1273 lParam
= *(LPARAM
*)(rect
+ 1);
1274 CONV_RECT16TO32( rect
, (RECT32
*)lParam
);
1275 SEGPTR_FREE( rect
);
1278 case LB_GETSELITEMS32
:
1281 LPINT16 items
= (LPINT16
)PTR_SEG_TO_LIN(lParam
);
1282 lParam
= *((LPARAM
*)items
- 1);
1283 for (i
= 0; i
< wParam
; i
++) *((LPINT32
)lParam
+ i
) = items
[i
];
1284 SEGPTR_FREE( (LPARAM
*)items
- 1 );
1287 case WM_MEASUREITEM
:
1289 MEASUREITEMSTRUCT16
*mis
= (MEASUREITEMSTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1290 MEASUREITEMSTRUCT32
*mis32
= *(MEASUREITEMSTRUCT32
**)(mis
+ 1);
1291 mis32
->itemWidth
= mis
->itemWidth
;
1292 mis32
->itemHeight
= mis
->itemHeight
;
1296 case WM_GETMINMAXINFO
:
1298 MINMAXINFO16
*mmi
= (MINMAXINFO16
*)PTR_SEG_TO_LIN(lParam
);
1299 lParam
= *(LPARAM
*)(mmi
+ 1);
1300 STRUCT32_MINMAXINFO16to32( mmi
, (MINMAXINFO32
*)lParam
);
1306 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(lParam
);
1307 lParam
= *((LPARAM
*)str
- 1);
1308 lstrcpyn32A( (LPSTR
)lParam
, str
, wParam
);
1309 SEGPTR_FREE( (LPARAM
*)str
- 1 );
1314 MDICREATESTRUCT16
*cs
= (MDICREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1315 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szTitle
) );
1316 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->szClass
) );
1322 NCCALCSIZE_PARAMS32
*nc32
;
1323 NCCALCSIZE_PARAMS16
*nc
= (NCCALCSIZE_PARAMS16
*)PTR_SEG_TO_LIN(lParam
);
1324 lParam
= *(LPARAM
*)(nc
+ 1);
1325 nc32
= (NCCALCSIZE_PARAMS32
*)lParam
;
1326 CONV_RECT16TO32( &nc
->rgrc
[0], &nc32
->rgrc
[0] );
1329 CONV_RECT16TO32( &nc
->rgrc
[1], &nc32
->rgrc
[1] );
1330 CONV_RECT16TO32( &nc
->rgrc
[2], &nc32
->rgrc
[2] );
1331 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16
*)PTR_SEG_TO_LIN(nc
->lppos
),
1333 SEGPTR_FREE( PTR_SEG_TO_LIN(nc
->lppos
) );
1341 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1342 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszName
) );
1343 SEGPTR_FREE( PTR_SEG_TO_LIN(cs
->lpszClass
) );
1347 case WM_WINDOWPOSCHANGING
:
1348 case WM_WINDOWPOSCHANGED
:
1350 WINDOWPOS16
*wp
= (WINDOWPOS16
*)PTR_SEG_TO_LIN(lParam
);
1351 lParam
= *(LPARAM
*)(wp
+ 1);
1352 STRUCT32_WINDOWPOS16to32( wp
, (WINDOWPOS32
*)lParam
);
1360 /**********************************************************************
1361 * WINPROC_MapMsg32WTo16
1363 * Map a message from 32-bit Unicode to 16-bit.
1364 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
1366 INT32
WINPROC_MapMsg32WTo16( UINT32 msg32
, WPARAM32 wParam32
, UINT16
*pmsg16
,
1367 WPARAM16
*pwparam16
, LPARAM
*plparam
)
1371 case LB_ADDSTRING32
:
1372 case LB_FINDSTRING32
:
1373 case LB_FINDSTRINGEXACT32
:
1374 case LB_INSERTSTRING32
:
1375 case LB_SELECTSTRING32
:
1379 LPSTR str
= SEGPTR_ALLOC( lstrlen32W((LPWSTR
)*plparam
) + 1 );
1380 if (!str
) return -1;
1381 STRING32_UniToAnsi( str
, (LPWSTR
)*plparam
);
1382 *pmsg16
= (UINT16
)msg32
+ (LB_ADDSTRING16
- LB_ADDSTRING32
);
1383 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1384 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1391 CREATESTRUCT32W
*cs32
= (CREATESTRUCT32W
*)*plparam
;
1393 if (!(cs
= SEGPTR_NEW(CREATESTRUCT16
))) return -1;
1394 STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCT32A
*)cs32
, cs
);
1395 if (HIWORD(cs32
->lpszName
))
1397 LPSTR name
= SEGPTR_ALLOC( lstrlen32W(cs32
->lpszName
) + 1 );
1398 STRING32_UniToAnsi( name
, cs32
->lpszName
);
1399 cs
->lpszName
= SEGPTR_GET(name
);
1401 else cs
->lpszName
= (SEGPTR
)cs32
->lpszName
;
1402 if (HIWORD(cs32
->lpszClass
))
1404 LPSTR name
= SEGPTR_ALLOC( lstrlen32W(cs32
->lpszClass
) + 1 );
1405 STRING32_UniToAnsi( name
, cs32
->lpszClass
);
1406 cs
->lpszClass
= SEGPTR_GET(name
);
1408 else cs
->lpszClass
= (SEGPTR
)cs32
->lpszClass
;
1409 *pmsg16
= (UINT16
)msg32
;
1410 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1411 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1416 MDICREATESTRUCT16
*cs
;
1417 MDICREATESTRUCT32W
*cs32
= (MDICREATESTRUCT32W
*)*plparam
;
1419 if (!(cs
= SEGPTR_NEW(MDICREATESTRUCT16
))) return -1;
1420 STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCT32A
*)cs32
, cs
);
1421 if (HIWORD(cs32
->szTitle
))
1423 LPSTR name
= SEGPTR_ALLOC( lstrlen32W(cs32
->szTitle
) + 1 );
1424 STRING32_UniToAnsi( name
, cs32
->szTitle
);
1425 cs
->szTitle
= SEGPTR_GET(name
);
1427 else cs
->szTitle
= (SEGPTR
)cs32
->szTitle
;
1428 if (HIWORD(cs32
->szClass
))
1430 LPSTR name
= SEGPTR_ALLOC( lstrlen32W(cs32
->szClass
) + 1 );
1431 STRING32_UniToAnsi( name
, cs32
->szClass
);
1432 cs
->szClass
= SEGPTR_GET(name
);
1434 else cs
->szClass
= (SEGPTR
)cs32
->szClass
;
1435 *pmsg16
= (UINT16
)msg32
;
1436 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1437 *plparam
= (LPARAM
)SEGPTR_GET(cs
);
1442 LPSTR str
= SEGPTR_ALLOC( lstrlen32W((LPWSTR
)*plparam
) + 1 );
1443 if (!str
) return -1;
1444 STRING32_UniToAnsi( str
, (LPWSTR
)*plparam
);
1445 *pmsg16
= (UINT16
)msg32
;
1446 *pwparam16
= (WPARAM16
)LOWORD(wParam32
);
1447 *plparam
= (LPARAM
)SEGPTR_GET(str
);
1450 default: /* No Unicode translation needed */
1451 return WINPROC_MapMsg32ATo16( msg32
, wParam32
, pmsg16
,
1452 pwparam16
, plparam
);
1457 /**********************************************************************
1458 * WINPROC_UnmapMsg32WTo16
1460 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
1462 void WINPROC_UnmapMsg32WTo16( UINT32 msg
, WPARAM16 wParam
, LPARAM lParam
)
1468 LPSTR str
= (LPSTR
)PTR_SEG_TO_LIN(lParam
);
1469 lParam
= *((LPARAM
*)str
- 1);
1470 STRING32_AnsiToUni( (LPWSTR
)lParam
, str
);
1471 SEGPTR_FREE( (LPARAM
*)str
- 1 );
1475 WINPROC_UnmapMsg32ATo16( msg
, wParam
, lParam
);
1481 /**********************************************************************
1482 * WINPROC_CallProc32ATo32W
1484 * Call a window procedure, translating args from Ansi to Unicode.
1486 static LRESULT
WINPROC_CallProc32ATo32W( WNDPROC32 func
, HWND32 hwnd
,
1487 UINT32 msg
, WPARAM32 wParam
,
1492 if (WINPROC_MapMsg32ATo32W( msg
, wParam
, &lParam
) == -1) return 0;
1493 result
= CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1494 WINPROC_UnmapMsg32ATo32W( msg
, wParam
, lParam
);
1499 /**********************************************************************
1500 * WINPROC_CallProc32WTo32A
1502 * Call a window procedure, translating args from Unicode to Ansi.
1504 static LRESULT
WINPROC_CallProc32WTo32A( WNDPROC32 func
, HWND32 hwnd
,
1505 UINT32 msg
, WPARAM32 wParam
,
1510 if (WINPROC_MapMsg32WTo32A( msg
, wParam
, &lParam
) == -1) return 0;
1511 result
= CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1512 WINPROC_UnmapMsg32WTo32A( msg
, wParam
, lParam
);
1517 /**********************************************************************
1518 * WINPROC_CallProc16To32A
1520 * Call a 32-bit window procedure, translating the 16-bit args.
1522 LRESULT
WINPROC_CallProc16To32A( HWND16 hwnd
, UINT16 msg
,
1523 WPARAM16 wParam
, LPARAM lParam
,
1530 if (WINPROC_MapMsg16To32A( msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
1532 result
= CallWndProc32( func
, hwnd
, msg32
, wParam32
, lParam
);
1533 WINPROC_UnmapMsg16To32A( msg32
, wParam32
, lParam
);
1538 /**********************************************************************
1539 * WINPROC_CallProc16To32W
1541 * Call a 32-bit window procedure, translating the 16-bit args.
1543 LRESULT
WINPROC_CallProc16To32W( HWND16 hwnd
, UINT16 msg
,
1544 WPARAM16 wParam
, LPARAM lParam
,
1551 if (WINPROC_MapMsg16To32W( msg
, wParam
, &msg32
, &wParam32
, &lParam
) == -1)
1553 result
= CallWndProc32( func
, hwnd
, msg32
, wParam32
, lParam
);
1554 WINPROC_UnmapMsg16To32W( msg32
, wParam32
, lParam
);
1559 /**********************************************************************
1560 * WINPROC_CallProc32ATo16
1562 * Call a 16-bit window procedure, translating the 32-bit args.
1564 static LRESULT
WINPROC_CallProc32ATo16( WNDPROC16 func
, HWND32 hwnd
,
1565 UINT32 msg
, WPARAM32 wParam
,
1571 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1572 WORD ds
= CURRENT_DS
;
1574 if (WINPROC_MapMsg32ATo16( msg
, wParam
, &msg16
, &wParam16
, &lParam
) == -1)
1576 if (wndPtr
) CURRENT_DS
= wndPtr
->hInstance
;
1577 result
= CallWndProc16( func
, hwnd
, msg16
, wParam16
, lParam
);
1579 WINPROC_UnmapMsg32ATo16( msg
, wParam16
, lParam
);
1584 /**********************************************************************
1585 * WINPROC_CallProc32WTo16
1587 * Call a 16-bit window procedure, translating the 32-bit args.
1589 static LRESULT
WINPROC_CallProc32WTo16( WNDPROC16 func
, HWND32 hwnd
,
1590 UINT32 msg
, WPARAM32 wParam
,
1596 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1597 WORD ds
= CURRENT_DS
;
1599 if (WINPROC_MapMsg32WTo16( msg
, wParam
, &msg16
, &wParam16
, &lParam
) == -1)
1601 if (wndPtr
) CURRENT_DS
= wndPtr
->hInstance
;
1602 result
= CallWndProc16( func
, hwnd
, msg16
, wParam16
, lParam
);
1604 WINPROC_UnmapMsg32WTo16( msg
, wParam16
, lParam
);
1609 /**********************************************************************
1610 * CallWindowProc16 (USER.122)
1612 LRESULT
CallWindowProc16( WNDPROC16 func
, HWND16 hwnd
, UINT16 msg
,
1613 WPARAM16 wParam
, LPARAM lParam
)
1617 WINDOWPROC
*proc
= WINPROC_GetPtr( func
);
1618 WORD ds
= CURRENT_DS
;
1622 wndPtr
= WIN_FindWndPtr( hwnd
);
1623 if (wndPtr
) CURRENT_DS
= wndPtr
->hInstance
;
1624 result
= CallWndProc16( (FARPROC16
)func
, hwnd
, msg
, wParam
, lParam
);
1629 wndPtr
= WIN_FindWndPtr( hwnd
);
1630 if (wndPtr
) CURRENT_DS
= wndPtr
->hInstance
;
1631 result
= CallWndProc16( WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_16
),
1632 hwnd
, msg
, wParam
, lParam
);
1640 if (!proc
->thunk
.t_from32
.proc
) return 0;
1641 wndPtr
= WIN_FindWndPtr( hwnd
);
1642 if (wndPtr
) CURRENT_DS
= wndPtr
->hInstance
;
1644 if ((msg
== WM_CREATE
) || (msg
== WM_NCCREATE
))
1646 CREATESTRUCT16
*cs
= (CREATESTRUCT16
*)PTR_SEG_TO_LIN(lParam
);
1647 /* Build the CREATESTRUCT on the 16-bit stack. */
1648 /* This is really ugly, but some programs (notably the */
1649 /* "Undocumented Windows" examples) want it that way. */
1650 result
= CallWndProcNCCREATE16( proc
->thunk
.t_from32
.proc
,
1651 cs
->dwExStyle
, cs
->lpszClass
, cs
->lpszName
, cs
->style
,
1652 cs
->x
, cs
->y
, cs
->cx
, cs
->cy
, cs
->hwndParent
, cs
->hMenu
,
1653 cs
->hInstance
, (LONG
)cs
->lpCreateParams
, hwnd
, msg
, wParam
,
1654 MAKELONG( IF1632_Saved16_sp
-sizeof(CREATESTRUCT16
),
1655 IF1632_Saved16_ss
) );
1660 result
= CallWndProc16( proc
->thunk
.t_from32
.proc
,
1661 hwnd
, msg
, wParam
, lParam
);
1666 if (!proc
->thunk
.t_from16
.proc
) return 0;
1667 return WINPROC_CallProc16To32A( hwnd
, msg
, wParam
, lParam
,
1668 proc
->thunk
.t_from16
.proc
);
1670 if (!proc
->thunk
.t_from16
.proc
) return 0;
1671 return WINPROC_CallProc16To32W( hwnd
, msg
, wParam
, lParam
,
1672 proc
->thunk
.t_from16
.proc
);
1674 fprintf( stderr
, "CallWindowProc16: invalid proc %p\n", proc
);
1680 /**********************************************************************
1681 * CallWindowProc32A (USER32.17)
1683 LRESULT
CallWindowProc32A( WNDPROC32 func
, HWND32 hwnd
, UINT32 msg
,
1684 WPARAM32 wParam
, LPARAM lParam
)
1686 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
1688 if (!proc
) return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1691 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32A
);
1692 return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1698 if (!proc
->thunk
.t_from32
.proc
) return 0;
1699 return WINPROC_CallProc32ATo16( proc
->thunk
.t_from32
.proc
,
1700 hwnd
, msg
, wParam
, lParam
);
1702 if (!proc
->thunk
.t_from16
.proc
) return 0;
1703 return CallWndProc32( proc
->thunk
.t_from16
.proc
,
1704 hwnd
, msg
, wParam
, lParam
);
1706 if (!proc
->thunk
.t_from16
.proc
) return 0;
1707 return WINPROC_CallProc32ATo32W( proc
->thunk
.t_from16
.proc
,
1708 hwnd
, msg
, wParam
, lParam
);
1710 fprintf( stderr
, "CallWindowProc32A: invalid proc %p\n", proc
);
1716 /**********************************************************************
1717 * CallWindowProc32W (USER32.18)
1719 LRESULT
CallWindowProc32W( WNDPROC32 func
, HWND32 hwnd
, UINT32 msg
,
1720 WPARAM32 wParam
, LPARAM lParam
)
1722 WINDOWPROC
*proc
= WINPROC_GetPtr( (WNDPROC16
)func
);
1724 if (!proc
) return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1727 func
= WINPROC_GetProc( (HWINDOWPROC
)proc
, WIN_PROC_32W
);
1728 return CallWndProc32( func
, hwnd
, msg
, wParam
, lParam
);
1734 if (!proc
->thunk
.t_from32
.proc
) return 0;
1735 return WINPROC_CallProc32WTo16( proc
->thunk
.t_from32
.proc
,
1736 hwnd
, msg
, wParam
, lParam
);
1738 if (!proc
->thunk
.t_from16
.proc
) return 0;
1739 return WINPROC_CallProc32WTo32A( proc
->thunk
.t_from16
.proc
,
1740 hwnd
, msg
, wParam
, lParam
);
1742 if (!proc
->thunk
.t_from16
.proc
) return 0;
1743 return CallWndProc32( proc
->thunk
.t_from16
.proc
,
1744 hwnd
, msg
, wParam
, lParam
);
1746 fprintf( stderr
, "CallWindowProc32W: invalid proc %p\n", proc
);