Release 960521
[wine.git] / windows / winproc.c
blob16ce933337ec41496fa7692f26d2ceaaf95eef96
1 /*
2 * Window procedure callbacks
4 * Copyright 1995 Martin von Loewis
5 * Copyright 1996 Alexandre Julliard
6 */
8 #include <stdio.h>
9 #include "windows.h"
10 #include "callback.h"
11 #include "heap.h"
12 #include "ldt.h"
13 #include "stackframe.h"
14 #include "string32.h"
15 #include "struct32.h"
16 #include "win.h"
17 #include "winproc.h"
20 typedef struct
22 WNDPROC32 func; /* 32-bit function, or 0 if free */
23 unsigned int count : 30; /* Reference count, or next free if func==0 */
24 WINDOWPROCTYPE type : 2; /* Function type */
25 } WINDOWPROC;
27 #define NB_WINPROCS 1024 /* Must be < 64K; 1024 should be enough for now */
29 static WINDOWPROC winProcs[NB_WINPROCS];
30 static int lastWinProc = 0;
31 static int freeWinProc = NB_WINPROCS;
33 /* Check if a win proc was created by WINPROC_AllocWinProc */
34 #define IS_ALLOCATED_WINPROC(func) (HIWORD(func) == 0xffff)
36 /**********************************************************************
37 * WINPROC_AllocWinProc
39 * Allocate a new window procedure.
41 WNDPROC16 WINPROC_AllocWinProc( WNDPROC32 func, WINDOWPROCTYPE type )
43 WINDOWPROC *proc;
44 if (!func) return (WNDPROC16)0; /* Null win proc remains null */
45 if (IS_ALLOCATED_WINPROC(func)) /* Already allocated? */
47 if (LOWORD(func) >= NB_WINPROCS) return (WNDPROC16)0;
48 proc = &winProcs[LOWORD(func)];
49 if (!proc->func) return (WNDPROC16)0;
50 proc->count++;
51 return (WNDPROC16)func;
53 if (freeWinProc < NB_WINPROCS) /* There is a free entry */
55 proc = &winProcs[freeWinProc];
56 proc->func = func;
57 func = (WNDPROC32)MAKELONG( freeWinProc, 0xffff );
58 freeWinProc = proc->count; /* Next free entry */
59 proc->count = 1;
60 proc->type = type;
61 return (WNDPROC16)func;
63 if (lastWinProc < NB_WINPROCS) /* There's a free entry at the end */
65 proc = &winProcs[lastWinProc];
66 proc->func = func;
67 func = (WNDPROC32)MAKELONG( lastWinProc, 0xffff );
68 lastWinProc++;
69 proc->count = 1;
70 proc->type = type;
71 return (WNDPROC16)func;
73 fprintf( stderr, "WINPROC_AllocWinProc: out of window procedures.\n"
74 "Please augment NB_WINPROCS in winproc.c\n" );
75 return (WNDPROC16)0;
79 /**********************************************************************
80 * WINPROC_GetWinProcType
82 * Return the type of a window procedure.
84 WINDOWPROCTYPE WINPROC_GetWinProcType( WNDPROC16 func )
86 WORD id = LOWORD(func);
87 if (!IS_ALLOCATED_WINPROC(func)) return WIN_PROC_16;
88 if ((id >= NB_WINPROCS) || !winProcs[id].func) return WIN_PROC_INVALID;
89 return winProcs[id].type;
93 /**********************************************************************
94 * WINPROC_GetWinProcFunc
96 * Return the 32-bit window procedure for a winproc.
98 WNDPROC32 WINPROC_GetWinProcFunc( WNDPROC16 func )
100 WORD id = LOWORD(func);
101 if (!IS_ALLOCATED_WINPROC(func)) return NULL;
102 if (id >= NB_WINPROCS) return NULL;
103 return winProcs[id].func;
107 /**********************************************************************
108 * WINPROC_FreeWinProc
110 * Free a window procedure.
112 void WINPROC_FreeWinProc( WNDPROC16 func )
114 WORD id = LOWORD(func);
115 if (!IS_ALLOCATED_WINPROC(func)) return;
116 if ((id >= NB_WINPROCS) || !winProcs[id].func)
118 fprintf( stderr, "WINPROC_FreeWinProc: invalid proc %08x\n",
119 (UINT32)func );
120 return;
122 if (--winProcs[id].count == 0)
124 winProcs[id].func = 0;
125 winProcs[id].count = freeWinProc;
126 freeWinProc = id;
131 /**********************************************************************
132 * WINPROC_CallProc32ATo32W
134 * Call a window procedure, translating args from Ansi to Unicode.
136 static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd,
137 UINT32 msg, WPARAM32 wParam,
138 LPARAM lParam )
140 LRESULT result;
142 switch(msg)
144 case WM_GETTEXT:
146 LPWSTR str = (LPWSTR)HeapAlloc(SystemHeap,0,wParam*sizeof(WCHAR));
147 if (!str) return 0;
148 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
149 STRING32_UniToAnsi( (LPSTR)lParam, str );
150 HeapFree( SystemHeap, 0, str );
151 return strlen( (LPSTR)lParam ) + 1;
154 case WM_SETTEXT:
156 LPWSTR str = STRING32_DupAnsiToUni( (LPCSTR)lParam );
157 if (!str) return 0;
158 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
159 free( str );
161 return result;
163 case WM_NCCREATE:
164 case WM_CREATE:
166 CREATESTRUCT32W cs = *(CREATESTRUCT32W *)lParam;
167 cs.lpszName = STRING32_DupAnsiToUni( (LPCSTR)cs.lpszName );
168 cs.lpszClass = STRING32_DupAnsiToUni( (LPCSTR)cs.lpszName );
169 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs );
170 free( (LPVOID)cs.lpszName );
171 free( (LPVOID)cs.lpszClass );
173 return result;
175 default: /* No translation needed */
176 return CallWndProc32( func, hwnd, msg, wParam, lParam );
181 /**********************************************************************
182 * WINPROC_CallProc32WTo32A
184 * Call a window procedure, translating args from Unicode to Ansi.
186 static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd,
187 UINT32 msg, WPARAM32 wParam,
188 LPARAM lParam )
190 LRESULT result;
192 switch(msg)
194 case WM_GETTEXT:
196 LPSTR str = (LPSTR)HeapAlloc( SystemHeap, 0, wParam );
197 if (!str) return 0;
198 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
199 STRING32_AnsiToUni( (LPWSTR)lParam, str );
200 HeapFree( SystemHeap, 0, str );
201 return STRING32_lstrlenW( (LPWSTR)lParam ) + 1; /* FIXME? */
204 case WM_SETTEXT:
206 LPSTR str = STRING32_DupUniToAnsi( (LPCWSTR)lParam );
207 if (!str) return 0;
208 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str );
209 free( str );
211 return result;
213 case WM_NCCREATE:
214 case WM_CREATE:
216 CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam;
217 cs.lpszName = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
218 cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
219 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs );
220 free( (LPVOID)cs.lpszName );
221 free( (LPVOID)cs.lpszClass );
223 return result;
225 default: /* No translation needed */
226 return CallWndProc32( func, hwnd, msg, wParam, lParam );
231 /**********************************************************************
232 * WINPROC_CallProc16To32A
234 * Call a 32-bit window procedure, translating the 16-bit args.
236 static LRESULT WINPROC_CallProc16To32A(WNDPROC32 func, HWND16 hwnd, UINT16 msg,
237 WPARAM16 wParam, LPARAM lParam )
239 LRESULT result;
241 switch(msg)
243 case WM_ACTIVATE:
244 case WM_CHARTOITEM:
245 case WM_COMMAND:
246 case WM_HSCROLL:
247 case WM_VKEYTOITEM:
248 case WM_VSCROLL:
249 return CallWndProc32( func, hwnd, msg,
250 MAKEWPARAM( wParam, HIWORD(lParam) ),
251 (LPARAM)(HWND32)LOWORD(lParam) );
252 case WM_CTLCOLOR:
253 return CallWndProc32( func, hwnd, WM_CTLCOLORMSGBOX + HIWORD(lParam),
254 (WPARAM32)(HDC32)wParam,
255 (LPARAM)(HWND32)LOWORD(lParam) );
256 case WM_DRAWITEM:
258 DRAWITEMSTRUCT16*dis16 = (DRAWITEMSTRUCT16*)PTR_SEG_TO_LIN(lParam);
259 DRAWITEMSTRUCT32 dis;
260 dis.CtlType = dis16->CtlType;
261 dis.CtlID = dis16->CtlID;
262 dis.itemID = dis16->itemID;
263 dis.itemAction = dis16->itemAction;
264 dis.itemState = dis16->itemState;
265 dis.hwndItem = dis16->hwndItem;
266 dis.hDC = dis16->hDC;
267 dis.itemData = dis16->itemData;
268 CONV_RECT16TO32( &dis16->rcItem, &dis.rcItem );
269 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&dis );
270 /* We don't bother to translate it back */
272 return result;
274 case WM_GETMINMAXINFO:
276 MINMAXINFO32 mmi;
277 STRUCT32_MINMAXINFO16to32( (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam),
278 &mmi );
279 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&mmi);
280 STRUCT32_MINMAXINFO32to16( &mmi,
281 (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
283 return result;
285 case WM_GETTEXT:
286 return CallWndProc32( func, hwnd, msg, wParam,
287 (LPARAM)PTR_SEG_TO_LIN(lParam) );
288 case WM_MDISETMENU:
289 return CallWndProc32( func, hwnd, msg,
290 (WPARAM32)(HMENU32)LOWORD(lParam),
291 (LPARAM)(HMENU32)HIWORD(lParam) );
292 case WM_MENUCHAR:
293 case WM_MENUSELECT:
294 return CallWndProc32( func, hwnd, msg,
295 MAKEWPARAM( wParam, LOWORD(lParam) ),
296 (LPARAM)(HMENU32)HIWORD(lParam) );
297 case WM_NCCALCSIZE:
299 NCCALCSIZE_PARAMS16 *pnc16;
300 NCCALCSIZE_PARAMS32 nc;
301 WINDOWPOS32 wp;
303 pnc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
304 CONV_RECT16TO32( &pnc16->rgrc[0], &nc.rgrc[0] );
305 if (wParam)
307 CONV_RECT16TO32( &pnc16->rgrc[1], &nc.rgrc[1] );
308 CONV_RECT16TO32( &pnc16->rgrc[2], &nc.rgrc[2] );
309 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(pnc16->lppos),
310 &wp );
311 nc.lppos = &wp;
314 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&nc );
316 pnc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
317 CONV_RECT32TO16( &nc.rgrc[0], &pnc16->rgrc[0] );
318 if (wParam)
320 CONV_RECT32TO16( &nc.rgrc[1], &pnc16->rgrc[1] );
321 CONV_RECT32TO16( &nc.rgrc[2], &pnc16->rgrc[2] );
322 STRUCT32_WINDOWPOS32to16( nc.lppos,
323 (WINDOWPOS16 *)PTR_SEG_TO_LIN(pnc16->lppos));
326 return result;
328 case WM_NCCREATE:
329 case WM_CREATE:
331 CREATESTRUCT16 *pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
332 CREATESTRUCT32A cs;
334 STRUCT32_CREATESTRUCT16to32A( pcs16, &cs );
335 /* FIXME: Unicode */
336 cs.lpszName = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName);
337 cs.lpszClass = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass);
338 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs );
339 pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
340 STRUCT32_CREATESTRUCT32Ato16( &cs, pcs16 );
342 if (cs.lpszName != (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName))
343 fprintf( stderr, "CallWindowProc16: WM_NCCREATE(%04x) changed lpszName (%p->%p), please report.\n",
344 msg, (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName), cs.lpszName);
345 if (cs.lpszClass != (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass))
346 fprintf( stderr, "CallWindowProc16: WM_NCCREATE(%04x) changed lpszClass (%p->%p), please report.\n",
347 msg, (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass), cs.lpszClass);
349 return result;
351 case WM_PARENTNOTIFY:
352 if ((wParam == WM_CREATE) || (wParam == WM_DESTROY))
353 return CallWndProc32( func, hwnd, msg,
354 MAKEWPARAM( wParam, HIWORD(lParam) ),
355 (LPARAM)(HWND32)LOWORD(lParam) );
356 else return CallWndProc32( func, hwnd, msg,
357 MAKEWPARAM( wParam, 0 /* FIXME? */ ),
358 lParam );
359 case WM_SETTEXT:
360 /* FIXME: Unicode */
361 return CallWndProc32( func, hwnd, msg, wParam,
362 (LPARAM)PTR_SEG_TO_LIN(lParam) );
364 case WM_WINDOWPOSCHANGING:
365 case WM_WINDOWPOSCHANGED:
367 WINDOWPOS32 wp;
368 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam),
369 &wp );
370 result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&wp );
371 STRUCT32_WINDOWPOS32to16( &wp,
372 (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam) );
374 return result;
376 case WM_ASKCBFORMATNAME:
377 case WM_COMPAREITEM:
378 case WM_DELETEITEM:
379 case WM_DEVMODECHANGE:
380 case WM_MDIACTIVATE:
381 case WM_MDICREATE:
382 case WM_MEASUREITEM:
383 case WM_PAINTCLIPBOARD:
384 case WM_SIZECLIPBOARD:
385 case WM_WININICHANGE:
386 fprintf( stderr, "CallWindowProc16To32: message %04x needs translation\n", msg );
388 default: /* No translation needed */
389 return CallWndProc32( func, hwnd, msg, (WPARAM32)wParam, lParam );
394 /**********************************************************************
395 * WINPROC_CallProc16To32W
397 * Call a 32-bit window procedure, translating the 16-bit args.
399 static LRESULT WINPROC_CallProc16To32W(WNDPROC32 func, HWND16 hwnd, UINT16 msg,
400 WPARAM16 wParam, LPARAM lParam )
402 LRESULT result = 0;
404 switch(msg)
406 case WM_GETTEXT:
407 case WM_SETTEXT:
408 return WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam,
409 (LPARAM)PTR_SEG_TO_LIN(lParam) );
411 case WM_NCCREATE:
412 case WM_CREATE:
414 CREATESTRUCT16 *pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
415 CREATESTRUCT32A cs;
417 STRUCT32_CREATESTRUCT16to32A( pcs16, &cs );
418 cs.lpszName = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName);
419 cs.lpszClass = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass);
420 result = WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam,
421 (LPARAM)&cs );
422 pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam);
423 STRUCT32_CREATESTRUCT32Ato16( &cs, pcs16 );
425 return result;
427 default: /* No Unicode translation needed */
428 return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
433 /**********************************************************************
434 * WINPROC_CallProc32ATo16
436 * Call a 16-bit window procedure, translating the 32-bit args.
438 static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, WORD ds, HWND32 hwnd,
439 UINT32 msg, WPARAM32 wParam,
440 LPARAM lParam )
442 LRESULT result;
444 switch(msg)
446 case WM_ACTIVATE:
447 case WM_CHARTOITEM:
448 case WM_COMMAND:
449 case WM_HSCROLL:
450 case WM_VKEYTOITEM:
451 case WM_VSCROLL:
452 return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
453 MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) );
455 case WM_CTLCOLORMSGBOX:
456 case WM_CTLCOLOREDIT:
457 case WM_CTLCOLORLISTBOX:
458 case WM_CTLCOLORBTN:
459 case WM_CTLCOLORDLG:
460 case WM_CTLCOLORSCROLLBAR:
461 case WM_CTLCOLORSTATIC:
462 return CallWndProc16( func, ds, hwnd, WM_CTLCOLOR, (WPARAM16)wParam,
463 MAKELPARAM( (HWND16)lParam,
464 (WORD)msg - WM_CTLCOLORMSGBOX ) );
465 case WM_DRAWITEM:
467 DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)lParam;
468 DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
469 if (!dis) return 0;
470 dis->CtlType = (UINT16)dis32->CtlType;
471 dis->CtlID = (UINT16)dis32->CtlID;
472 dis->itemID = (UINT16)dis32->itemID;
473 dis->itemAction = (UINT16)dis32->itemAction;
474 dis->itemState = (UINT16)dis32->itemState;
475 dis->hwndItem = (HWND16)dis32->hwndItem;
476 dis->hDC = (HDC16)dis32->hDC;
477 dis->itemData = dis32->itemData;
478 CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
479 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
480 (LPARAM)SEGPTR_GET(dis) );
481 /* We don't bother to translate it back */
482 SEGPTR_FREE(dis);
484 return result;
486 case WM_GETMINMAXINFO:
488 MINMAXINFO16 *mmi = SEGPTR_NEW(MINMAXINFO16);
489 if (!mmi) return 0;
490 STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)lParam, mmi );
491 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
492 (LPARAM)SEGPTR_GET(mmi) );
493 STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)lParam );
494 SEGPTR_FREE(mmi);
496 return result;
498 case WM_GETTEXT:
500 LPSTR str;
501 wParam = MIN( wParam, 0xff80 ); /* Size must be < 64K */
502 if (!(str = SEGPTR_ALLOC( wParam ))) return 0;
503 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
504 (LPARAM)SEGPTR_GET(str) );
505 if (result > 0) memcpy( (LPSTR)lParam, str, result );
506 SEGPTR_FREE(str);
508 return result;
510 case WM_MDISETMENU:
511 return CallWndProc16( func, ds, hwnd, msg, TRUE /* FIXME? */,
512 MAKELPARAM( (HMENU16)LOWORD(lParam),
513 (HMENU16)HIWORD(lParam) ) );
514 case WM_MENUCHAR:
515 case WM_MENUSELECT:
516 return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)LOWORD(wParam),
517 MAKELPARAM( HIWORD(wParam), (HMENU16)lParam ) );
518 case WM_NCCALCSIZE:
520 NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)lParam;
521 NCCALCSIZE_PARAMS16 *nc;
522 WINDOWPOS16 *wp = NULL;
524 if (!(nc = SEGPTR_NEW(NCCALCSIZE_PARAMS16))) return 0;
525 CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
526 if (wParam)
528 CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
529 CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
530 if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
532 SEGPTR_FREE(nc);
533 return 0;
535 STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
536 nc->lppos = SEGPTR_GET(wp);
538 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
539 (LPARAM)SEGPTR_GET(nc) );
540 CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
541 if (wParam)
543 CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
544 CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
545 STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
546 nc32->lppos );
547 SEGPTR_FREE(wp);
549 SEGPTR_FREE(nc);
551 return result;
553 case WM_NCCREATE:
554 case WM_CREATE:
556 CREATESTRUCT16 *cs;
557 CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)lParam;
558 LPSTR name, cls;
560 if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return 0;
561 STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
562 name = SEGPTR_STRDUP( cs32->lpszName );
563 cls = SEGPTR_STRDUP( cs32->lpszClass );
564 cs->lpszName = SEGPTR_GET(name);
565 cs->lpszClass = SEGPTR_GET(cls);
566 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
567 (LPARAM)SEGPTR_GET(cs) );
568 STRUCT32_CREATESTRUCT16to32A( cs, cs32 );
569 if (PTR_SEG_TO_LIN(cs->lpszName) != name)
570 cs32->lpszName = (LPCSTR)PTR_SEG_TO_LIN( cs->lpszName );
571 if (PTR_SEG_TO_LIN(cs->lpszClass) != cls)
572 cs32->lpszClass = (LPCSTR)PTR_SEG_TO_LIN( cs->lpszClass );
573 SEGPTR_FREE(name);
574 SEGPTR_FREE(cls);
575 SEGPTR_FREE(cs);
577 return result;
579 case WM_PARENTNOTIFY:
580 if ((wParam == WM_CREATE) || (wParam == WM_DESTROY))
581 return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
582 MAKELPARAM( (HWND16)lParam, LOWORD(wParam)));
583 case WM_SETTEXT:
585 LPSTR str = SEGPTR_STRDUP( (LPSTR)lParam );
586 if (!str) return 0;
587 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
588 (LPARAM)SEGPTR_GET(str) );
589 SEGPTR_FREE(str);
591 return result;
593 case WM_WINDOWPOSCHANGING:
594 case WM_WINDOWPOSCHANGED:
596 WINDOWPOS16 *wp;
597 if (!(wp = SEGPTR_NEW(WINDOWPOS16))) return 0;
598 STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)lParam, wp );
599 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
600 (LPARAM)SEGPTR_GET(wp) );
601 STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)lParam );
602 SEGPTR_FREE(wp);
604 return result;
606 case WM_ASKCBFORMATNAME:
607 case WM_COMPAREITEM:
608 case WM_DELETEITEM:
609 case WM_DEVMODECHANGE:
610 case WM_MDIACTIVATE:
611 case WM_MDICREATE:
612 case WM_MEASUREITEM:
613 case WM_PAINTCLIPBOARD:
614 case WM_SIZECLIPBOARD:
615 case WM_WININICHANGE:
616 fprintf( stderr, "CallWindowProc32To16: message %04x needs translation\n", msg );
618 default: /* No translation needed */
619 return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, lParam );
624 /**********************************************************************
625 * WINPROC_CallProc32WTo16
627 * Call a 16-bit window procedure, translating the 32-bit args.
629 static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, WORD ds, HWND32 hwnd,
630 UINT32 msg, WPARAM32 wParam,
631 LPARAM lParam )
633 LRESULT result;
635 switch(msg)
637 case WM_GETTEXT:
639 LPSTR str;
640 wParam = MIN( wParam, 0xff80 ); /* Size must be < 64K */
641 if (!(str = SEGPTR_ALLOC( wParam ))) return 0;
642 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
643 (LPARAM)SEGPTR_GET(str) );
644 if (result > 0) STRING32_AnsiToUni( (LPWSTR)lParam, str );
645 SEGPTR_FREE(str);
647 return result;
649 case WM_NCCREATE:
650 case WM_CREATE:
652 CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam;
653 cs.lpszName = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
654 cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName );
655 result = WINPROC_CallProc32ATo16( func, ds, hwnd, msg, wParam,
656 (LPARAM)&cs );
657 free( (LPVOID)cs.lpszName );
658 free( (LPVOID)cs.lpszClass );
660 return result;
662 case WM_SETTEXT:
664 LPSTR str = SEGPTR_ALLOC( STRING32_lstrlenW( (LPWSTR)lParam ) );
665 if (!str) return 0;
666 STRING32_UniToAnsi( str, (LPWSTR)lParam );
667 result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam,
668 (LPARAM)SEGPTR_GET(str) );
669 SEGPTR_FREE(str);
671 return result;
673 default: /* No Unicode translation needed */
674 return WINPROC_CallProc32ATo16( func, ds, hwnd, msg, wParam, lParam );
679 /**********************************************************************
680 * CallWindowProc16 (USER.122)
682 LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
683 WPARAM16 wParam, LPARAM lParam )
685 WND *wndPtr;
687 switch(WINPROC_GetWinProcType(func))
689 case WIN_PROC_16:
690 wndPtr = WIN_FindWndPtr( hwnd );
691 return CallWndProc16( (FARPROC)func,
692 wndPtr ? wndPtr->hInstance : CURRENT_DS,
693 hwnd, msg, wParam, lParam );
694 case WIN_PROC_32A:
695 return WINPROC_CallProc16To32A( WINPROC_GetWinProcFunc(func),
696 hwnd, msg, wParam, lParam );
697 case WIN_PROC_32W:
698 return WINPROC_CallProc16To32W( WINPROC_GetWinProcFunc(func),
699 hwnd, msg, wParam, lParam );
700 default:
701 fprintf(stderr, "CallWindowProc16: invalid func %08x\n", (UINT32)func);
702 return 0;
707 /**********************************************************************
708 * CallWindowProc32A (USER32.17)
710 LRESULT CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
711 WPARAM32 wParam, LPARAM lParam )
713 WND *wndPtr;
715 switch(WINPROC_GetWinProcType( (WNDPROC16)func ))
717 case WIN_PROC_16:
718 wndPtr = WIN_FindWndPtr( hwnd );
719 return WINPROC_CallProc32ATo16( (FARPROC)func,
720 wndPtr ? wndPtr->hInstance : CURRENT_DS,
721 hwnd, msg, wParam, lParam );
722 case WIN_PROC_32A:
723 return CallWndProc32( WINPROC_GetWinProcFunc( (WNDPROC16)func ),
724 hwnd, msg, wParam, lParam );
725 case WIN_PROC_32W:
726 return WINPROC_CallProc32ATo32W(WINPROC_GetWinProcFunc((WNDPROC16)func),
727 hwnd, msg, wParam, lParam );
728 default:
729 fprintf(stderr,"CallWindowProc32A: invalid func %08x\n",(UINT32)func);
730 return 0;
735 /**********************************************************************
736 * CallWindowProc32W (USER32.18)
738 LRESULT CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg,
739 WPARAM32 wParam, LPARAM lParam )
741 WND *wndPtr;
743 switch(WINPROC_GetWinProcType( (WNDPROC16)func ))
745 case WIN_PROC_16:
746 wndPtr = WIN_FindWndPtr( hwnd );
747 return WINPROC_CallProc32WTo16( (FARPROC)func,
748 wndPtr ? wndPtr->hInstance : CURRENT_DS,
749 hwnd, msg, wParam, lParam );
750 case WIN_PROC_32A:
751 return WINPROC_CallProc32WTo32A(WINPROC_GetWinProcFunc((WNDPROC16)func),
752 hwnd, msg, wParam, lParam );
753 case WIN_PROC_32W:
754 return CallWndProc32( WINPROC_GetWinProcFunc( (WNDPROC16)func ),
755 hwnd, msg, wParam, lParam );
756 default:
757 fprintf(stderr,"CallWindowProc32W: invalid func %08x\n",(UINT32)func);
758 return 0;