Get rid of the non-standard CONV_POINT and CONV_RECT functions.
[wine] / dlls / user / hook16.c
1 /*
2  * Windows 16-bit hook functions
3  *
4  * Copyright 1994, 1995, 2002 Alexandre Julliard
5  * Copyright 1996 Andrew Lewycky
6  *
7  * Based on investigations by Alex Korobka
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "wownt32.h"
30 #include "wine/winuser16.h"
31 #include "message.h"
32 #include "win.h"
33 #include "winproc.h"
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(hook);
37
38
39 static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp );
40 static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp );
41 static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp );
42 static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp );
43 static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp );
44 static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp );
45 static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp );
46
47 #define WH_MAXHOOK16 WH_SHELL  /* Win16 only supports up to WH_SHELL */
48 #define NB_HOOKS16 (WH_MAXHOOK16 - WH_MINHOOK + 1)
49
50 static const HOOKPROC hook_procs[NB_HOOKS16] =
51 {
52     call_WH_MSGFILTER,   /* WH_MSGFILTER        */
53     NULL,                /* WH_JOURNALRECORD */
54     NULL,                /* WH_JOURNALPLAYBACK */
55     call_WH_KEYBOARD,    /* WH_KEYBOARD */
56     call_WH_GETMESSAGE,  /* WH_GETMESSAGE */
57     call_WH_CALLWNDPROC, /* WH_CALLWNDPROC */
58     call_WH_CBT,         /* WH_CBT */
59     NULL,                /* WH_SYSMSGFILTER */
60     call_WH_MOUSE,       /* WH_MOUSE */
61     NULL,                /* WH_HARDWARE */
62     NULL,                /* WH_DEBUG */
63     call_WH_SHELL        /* WH_SHELL */
64 };
65
66
67 /* this structure is stored in the thread queue */
68 struct hook16_queue_info
69 {
70     INT        id;                /* id of current hook */
71     HHOOK      hook[NB_HOOKS16];  /* Win32 hook handles */
72     HOOKPROC16 proc[NB_HOOKS16];  /* 16-bit hook procedures */
73 };
74
75
76
77 /***********************************************************************
78  *           map_msg_16_to_32
79  */
80 inline static void map_msg_16_to_32( const MSG16 *msg16, MSG *msg32 )
81 {
82     msg32->hwnd    = WIN_Handle32(msg16->hwnd);
83     msg32->message = msg16->message;
84     msg32->wParam  = msg16->wParam;
85     msg32->lParam  = msg16->lParam;
86     msg32->time    = msg16->time;
87     msg32->pt.x    = msg16->pt.x;
88     msg32->pt.y    = msg16->pt.y;
89 }
90
91
92 /***********************************************************************
93  *           map_msg_32_to_16
94  */
95 inline static void map_msg_32_to_16( const MSG *msg32, MSG16 *msg16 )
96 {
97     msg16->hwnd    = HWND_16(msg32->hwnd);
98     msg16->message = msg32->message;
99     msg16->wParam  = msg32->wParam;
100     msg16->lParam  = msg32->lParam;
101     msg16->time    = msg32->time;
102     msg16->pt.x    = msg32->pt.x;
103     msg16->pt.y    = msg32->pt.y;
104 }
105
106
107 /***********************************************************************
108  *           call_hook_16
109  */
110 static LRESULT call_hook_16( INT id, INT code, WPARAM wp, LPARAM lp )
111 {
112     struct hook16_queue_info *info = QUEUE_Current()->hook16_info;
113     WORD args[4];
114     LRESULT ret;
115     INT prev_id = info->id;
116     info->id = id;
117
118     args[3] = code;
119     args[2] = wp;
120     args[1] = HIWORD(lp);
121     args[0] = LOWORD(lp);
122     WOWCallback16Ex( (DWORD)info->proc[id - WH_MINHOOK], WCB16_PASCAL, sizeof(args), args, &ret );
123
124     info->id = prev_id;
125
126     /* Grrr. While the hook procedure is supposed to have an LRESULT return
127        value even in Win16, it seems that for those hook types where the
128        return value is interpreted as BOOL, Windows doesn't actually check
129        the HIWORD ...  Some buggy Win16 programs, notably WINFILE, rely on
130        that, because they neglect to clear DX ... */
131     if (id != WH_JOURNALPLAYBACK) ret = LOWORD( ret );
132     return ret;
133 }
134
135
136 /***********************************************************************
137  *              call_WH_MSGFILTER
138  */
139 static LRESULT CALLBACK call_WH_MSGFILTER( INT code, WPARAM wp, LPARAM lp )
140 {
141     MSG *msg32 = (MSG *)lp;
142     MSG16 msg16;
143     LRESULT ret;
144
145     map_msg_32_to_16( msg32, &msg16 );
146     lp = MapLS( &msg16 );
147     ret = call_hook_16( WH_MSGFILTER, code, wp, lp );
148     UnMapLS( lp );
149     return ret;
150 }
151
152
153 /***********************************************************************
154  *              call_WH_KEYBOARD
155  */
156 static LRESULT CALLBACK call_WH_KEYBOARD( INT code, WPARAM wp, LPARAM lp )
157 {
158     return call_hook_16( WH_KEYBOARD, code, wp, lp );
159 }
160
161
162 /***********************************************************************
163  *              call_WH_GETMESSAGE
164  */
165 static LRESULT CALLBACK call_WH_GETMESSAGE( INT code, WPARAM wp, LPARAM lp )
166 {
167     MSG *msg32 = (MSG *)lp;
168     MSG16 msg16;
169     LRESULT ret;
170
171     map_msg_32_to_16( msg32, &msg16 );
172
173     lp = MapLS( &msg16 );
174     ret = call_hook_16( WH_GETMESSAGE, code, wp, lp );
175     UnMapLS( lp );
176
177     map_msg_16_to_32( &msg16, msg32 );
178     return ret;
179 }
180
181
182 /***********************************************************************
183  *              call_WH_CALLWNDPROC
184  */
185 static LRESULT CALLBACK call_WH_CALLWNDPROC( INT code, WPARAM wp, LPARAM lp )
186 {
187     CWPSTRUCT *cwp32 = (CWPSTRUCT *)lp;
188     CWPSTRUCT16 cwp16;
189     MSGPARAM16 mp16;
190     LRESULT ret;
191
192     cwp16.hwnd   = HWND_16(cwp32->hwnd);
193     cwp16.lParam = cwp32->lParam;
194
195     WINPROC_MapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam,
196                            &cwp16.message, &cwp16.wParam, &cwp16.lParam );
197
198     lp = MapLS( &cwp16 );
199     ret = call_hook_16( WH_CALLWNDPROC, code, wp, lp );
200     UnMapLS( lp );
201
202     mp16.wParam  = cwp16.wParam;
203     mp16.lParam  = cwp16.lParam;
204     mp16.lResult = 0;
205     WINPROC_UnmapMsg32ATo16( cwp32->hwnd, cwp32->message, cwp32->wParam, cwp32->lParam, &mp16 );
206     return ret;
207 }
208
209
210 /***********************************************************************
211  *              call_WH_CBT
212  */
213 static LRESULT CALLBACK call_WH_CBT( INT code, WPARAM wp, LPARAM lp )
214 {
215     LRESULT ret = 0;
216
217     switch (code)
218     {
219     case HCBT_CREATEWND:
220         {
221             CBT_CREATEWNDA *cbtcw32 = (CBT_CREATEWNDA *)lp;
222             CBT_CREATEWND16 cbtcw16;
223             CREATESTRUCT16 cs16;
224
225             cs16.lpCreateParams = (SEGPTR)cbtcw32->lpcs->lpCreateParams;
226             cs16.hInstance      = HINSTANCE_16(cbtcw32->lpcs->hInstance);
227             cs16.hMenu          = HMENU_16(cbtcw32->lpcs->hMenu);
228             cs16.hwndParent     = HWND_16(cbtcw32->lpcs->hwndParent);
229             cs16.cy             = cbtcw32->lpcs->cy;
230             cs16.cx             = cbtcw32->lpcs->cx;
231             cs16.y              = cbtcw32->lpcs->y;
232             cs16.x              = cbtcw32->lpcs->x;
233             cs16.style          = cbtcw32->lpcs->style;
234             cs16.lpszName       = MapLS( cbtcw32->lpcs->lpszName );
235             cs16.lpszClass      = MapLS( cbtcw32->lpcs->lpszClass );
236             cs16.dwExStyle      = cbtcw32->lpcs->dwExStyle;
237
238             cbtcw16.lpcs = (CREATESTRUCT16 *)MapLS( &cs16 );
239             cbtcw16.hwndInsertAfter = HWND_16( cbtcw32->hwndInsertAfter );
240
241             lp = MapLS( &cbtcw16 );
242             ret = call_hook_16( WH_CBT, code, wp, lp );
243             UnMapLS( cs16.lpszName );
244             UnMapLS( cs16.lpszClass );
245
246             cbtcw32->hwndInsertAfter = WIN_Handle32( cbtcw16.hwndInsertAfter );
247             UnMapLS( (SEGPTR)cbtcw16.lpcs );
248             UnMapLS( lp );
249             break;
250         }
251
252     case HCBT_ACTIVATE:
253         {
254             CBTACTIVATESTRUCT *cas32 = (CBTACTIVATESTRUCT *)lp;
255             CBTACTIVATESTRUCT16 cas16;
256
257             cas16.fMouse     = cas32->fMouse;
258             cas16.hWndActive = HWND_16( cas32->hWndActive );
259
260             lp = MapLS( &cas16 );
261             ret = call_hook_16( WH_CBT, code, wp, lp );
262             UnMapLS( lp );
263             break;
264         }
265     case HCBT_CLICKSKIPPED:
266         {
267             MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
268             MOUSEHOOKSTRUCT16 ms16;
269
270             ms16.pt.x         = ms32->pt.x;
271             ms16.pt.y         = ms32->pt.y;
272             ms16.hwnd         = HWND_16( ms32->hwnd );
273             ms16.wHitTestCode = ms32->wHitTestCode;
274             ms16.dwExtraInfo  = ms32->dwExtraInfo;
275
276             lp = MapLS( &ms16 );
277             ret = call_hook_16( WH_CBT, code, wp, lp );
278             UnMapLS( lp );
279             break;
280         }
281     case HCBT_MOVESIZE:
282         {
283             RECT *rect32 = (RECT *)lp;
284             RECT16 rect16;
285
286             rect16.left   = rect32->left;
287             rect16.top    = rect32->top;
288             rect16.right  = rect32->right;
289             rect16.bottom = rect32->bottom;
290             lp = MapLS( &rect16 );
291             ret = call_hook_16( WH_CBT, code, wp, lp );
292             UnMapLS( lp );
293             break;
294         }
295     }
296     return ret;
297 }
298
299
300 /***********************************************************************
301  *              call_WH_MOUSE
302  */
303 static LRESULT CALLBACK call_WH_MOUSE( INT code, WPARAM wp, LPARAM lp )
304 {
305     MOUSEHOOKSTRUCT *ms32 = (MOUSEHOOKSTRUCT *)lp;
306     MOUSEHOOKSTRUCT16 ms16;
307     LRESULT ret;
308
309     ms16.pt.x         = ms32->pt.x;
310     ms16.pt.y         = ms32->pt.y;
311     ms16.hwnd         = HWND_16( ms32->hwnd );
312     ms16.wHitTestCode = ms32->wHitTestCode;
313     ms16.dwExtraInfo  = ms32->dwExtraInfo;
314
315     lp = MapLS( &ms16 );
316     ret = call_hook_16( WH_MOUSE, code, wp, lp );
317     UnMapLS( lp );
318     return ret;
319 }
320
321
322 /***********************************************************************
323  *              call_WH_SHELL
324  */
325 static LRESULT CALLBACK call_WH_SHELL( INT code, WPARAM wp, LPARAM lp )
326 {
327     return call_hook_16( WH_SHELL, code, wp, lp );
328 }
329
330
331 /***********************************************************************
332  *              SetWindowsHook (USER.121)
333  */
334 FARPROC16 WINAPI SetWindowsHook16( INT16 id, HOOKPROC16 proc )
335 {
336     HINSTANCE16 hInst = FarGetOwner16( HIWORD(proc) );
337
338     /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
339     HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
340
341     return (FARPROC16)SetWindowsHookEx16( id, proc, hInst, hTask );
342 }
343
344
345 /***********************************************************************
346  *              SetWindowsHookEx (USER.291)
347  */
348 HHOOK WINAPI SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst, HTASK16 hTask )
349 {
350     MESSAGEQUEUE *queue = QUEUE_Current();
351     struct hook16_queue_info *info;
352     HHOOK hook;
353     int index = id - WH_MINHOOK;
354
355     if (!queue) return 0;
356     if (id < WH_MINHOOK || id > WH_MAXHOOK16) return 0;
357     if (!hook_procs[index])
358     {
359         FIXME( "hook type %d broken in Win16\n", id );
360         return 0;
361     }
362     if (!hTask) FIXME( "System-global hooks (%d) broken in Win16\n", id );
363     else if (hTask != GetCurrentTask())
364     {
365         FIXME( "setting hook (%d) on other task not supported\n", id );
366         return 0;
367     }
368
369     if (!(info = queue->hook16_info))
370     {
371         if (!(info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*info) ))) return 0;
372         queue->hook16_info = info;
373     }
374     if (info->hook[index])
375     {
376         FIXME( "Multiple hooks (%d) for the same task not supported yet\n", id );
377         return 0;
378     }
379     if (!(hook = SetWindowsHookExA( id, hook_procs[index], 0, GetCurrentThreadId() ))) return 0;
380     info->hook[index] = hook;
381     info->proc[index] = proc;
382     return hook;
383 }
384
385
386 /***********************************************************************
387  *              UnhookWindowsHook (USER.234)
388  */
389 BOOL16 WINAPI UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
390 {
391     MESSAGEQUEUE *queue = QUEUE_Current();
392     struct hook16_queue_info *info;
393     int index = id - WH_MINHOOK;
394
395     if (id < WH_MINHOOK || id > WH_MAXHOOK16) return FALSE;
396     if (!queue || !(info = queue->hook16_info)) return FALSE;
397     if (info->proc[index] != proc) return FALSE;
398     if (!UnhookWindowsHookEx( info->hook[index] )) return FALSE;
399     info->hook[index] = 0;
400     info->proc[index] = 0;
401     return TRUE;
402 }
403
404
405 /***********************************************************************
406  *              UnhookWindowsHookEx (USER.292)
407  */
408 BOOL16 WINAPI UnhookWindowsHookEx16( HHOOK hhook )
409 {
410     MESSAGEQUEUE *queue = QUEUE_Current();
411     struct hook16_queue_info *info;
412     int index;
413
414     if (!queue || !(info = queue->hook16_info)) return FALSE;
415     for (index = 0; index < NB_HOOKS16; index++)
416     {
417         if (info->hook[index] == hhook)
418         {
419             info->hook[index] = 0;
420             info->proc[index] = 0;
421             return UnhookWindowsHookEx( hhook );
422         }
423     }
424     return FALSE;
425 }
426
427
428 /***********************************************************************
429  *              CallMsgFilter32 (USER.823)
430  */
431 BOOL16 WINAPI CallMsgFilter32_16( MSG32_16 *lpmsg16_32, INT16 code, BOOL16 wHaveParamHigh )
432 {
433     MSG msg32;
434     BOOL16 ret;
435
436     if (GetSysModalWindow16()) return FALSE;
437     msg32.hwnd      = WIN_Handle32( lpmsg16_32->msg.hwnd );
438     msg32.message   = lpmsg16_32->msg.message;
439     msg32.lParam    = lpmsg16_32->msg.lParam;
440     msg32.time      = lpmsg16_32->msg.time;
441     msg32.pt.x      = lpmsg16_32->msg.pt.x;
442     msg32.pt.y      = lpmsg16_32->msg.pt.y;
443     if (wHaveParamHigh) msg32.wParam = MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
444     else msg32.wParam = lpmsg16_32->msg.wParam;
445
446     ret = (BOOL16)CallMsgFilterA(&msg32, code);
447
448     lpmsg16_32->msg.hwnd    = HWND_16( msg32.hwnd );
449     lpmsg16_32->msg.message = msg32.message;
450     lpmsg16_32->msg.wParam  = LOWORD(msg32.wParam);
451     lpmsg16_32->msg.lParam  = msg32.lParam;
452     lpmsg16_32->msg.time    = msg32.time;
453     lpmsg16_32->msg.pt.x    = msg32.pt.x;
454     lpmsg16_32->msg.pt.y    = msg32.pt.y;
455     if (wHaveParamHigh) lpmsg16_32->wParamHigh = HIWORD(msg32.wParam);
456     return ret;
457 }
458
459
460 /***********************************************************************
461  *              CallMsgFilter (USER.123)
462  */
463 BOOL16 WINAPI CallMsgFilter16( MSG16 *msg, INT16 code )
464 {
465     return CallMsgFilter32_16( (MSG32_16 *)msg, code, FALSE );
466 }
467
468
469 /***********************************************************************
470  *              CallNextHookEx (USER.293)
471  */
472 LRESULT WINAPI CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wparam, LPARAM lparam )
473 {
474     MESSAGEQUEUE *queue = QUEUE_Current();
475     struct hook16_queue_info *info;
476     LRESULT ret = 0;
477
478     if (!queue || !(info = queue->hook16_info)) return 0;
479
480     switch (info->id)
481     {
482     case WH_MSGFILTER:
483     {
484         MSG16 *msg16 = MapSL(lparam);
485         MSG msg32;
486
487         map_msg_16_to_32( msg16, &msg32 );
488         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
489         break;
490     }
491
492     case WH_GETMESSAGE:
493     {
494         MSG16 *msg16 = MapSL(lparam);
495         MSG msg32;
496
497         map_msg_16_to_32( msg16, &msg32 );
498         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&msg32 );
499         map_msg_32_to_16( &msg32, msg16 );
500         break;
501     }
502
503     case WH_CALLWNDPROC:
504     {
505         CWPSTRUCT16 *cwp16 = MapSL(lparam);
506         CWPSTRUCT cwp32;
507
508         cwp32.hwnd   = WIN_Handle32(cwp16->hwnd);
509         cwp32.lParam = cwp16->lParam;
510
511         WINPROC_MapMsg16To32A( cwp32.hwnd, cwp16->message, cwp16->wParam,
512                                &cwp32.message, &cwp32.wParam, &cwp32.lParam );
513         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cwp32 );
514         WINPROC_UnmapMsg16To32A( cwp32.hwnd, cwp32.message, cwp32.wParam, cwp32.lParam, 0 );
515         break;
516     }
517
518     case WH_CBT:
519         switch (code)
520         {
521         case HCBT_CREATEWND:
522             {
523                 CBT_CREATEWNDA cbtcw32;
524                 CREATESTRUCTA cs32;
525                 CBT_CREATEWND16 *cbtcw16 = MapSL(lparam);
526                 CREATESTRUCT16 *cs16 = MapSL( (SEGPTR)cbtcw16->lpcs );
527
528                 cbtcw32.lpcs = &cs32;
529                 cbtcw32.hwndInsertAfter = WIN_Handle32( cbtcw16->hwndInsertAfter );
530
531                 cs32.lpCreateParams = (LPVOID)cs16->lpCreateParams;
532                 cs32.hInstance      = HINSTANCE_32(cs16->hInstance);
533                 cs32.hMenu          = HMENU_32(cs16->hMenu);
534                 cs32.hwndParent     = WIN_Handle32(cs16->hwndParent);
535                 cs32.cy             = cs16->cy;
536                 cs32.cx             = cs16->cx;
537                 cs32.y              = cs16->y;
538                 cs32.x              = cs16->x;
539                 cs32.style          = cs16->style;
540                 cs32.lpszName       = MapSL( cs16->lpszName );
541                 cs32.lpszClass      = MapSL( cs16->lpszClass );
542                 cs32.dwExStyle      = cs16->dwExStyle;
543
544                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cbtcw32 );
545                 cbtcw16->hwndInsertAfter = HWND_16( cbtcw32.hwndInsertAfter );
546                 break;
547             }
548         case HCBT_ACTIVATE:
549             {
550                 CBTACTIVATESTRUCT16 *cas16 = MapSL(lparam);
551                 CBTACTIVATESTRUCT cas32;
552                 cas32.fMouse = cas16->fMouse;
553                 cas32.hWndActive = WIN_Handle32(cas16->hWndActive);
554                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&cas32 );
555                 break;
556             }
557         case HCBT_CLICKSKIPPED:
558             {
559                 MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
560                 MOUSEHOOKSTRUCT ms32;
561
562                 ms32.pt.x = ms16->pt.x;
563                 ms32.pt.y = ms16->pt.y;
564                 /* wHitTestCode may be negative, so convince compiler to do
565                    correct sign extension. Yay. :| */
566                 ms32.wHitTestCode = (INT)(INT16)ms16->wHitTestCode;
567                 ms32.dwExtraInfo = ms16->dwExtraInfo;
568                 ms32.hwnd = WIN_Handle32( ms16->hwnd );
569                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
570                 break;
571             }
572         case HCBT_MOVESIZE:
573             {
574                 RECT16 *rect16 = MapSL(lparam);
575                 RECT rect32;
576
577                 rect32.left   = rect16->left;
578                 rect32.top    = rect16->top;
579                 rect32.right  = rect16->right;
580                 rect32.bottom = rect16->bottom;
581                 ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&rect32 );
582                 break;
583             }
584         }
585         break;
586
587     case WH_MOUSE:
588     {
589         MOUSEHOOKSTRUCT16 *ms16 = MapSL(lparam);
590         MOUSEHOOKSTRUCT ms32;
591
592         ms32.pt.x = ms16->pt.x;
593         ms32.pt.y = ms16->pt.y;
594         /* wHitTestCode may be negative, so convince compiler to do
595            correct sign extension. Yay. :| */
596         ms32.wHitTestCode = (INT)((INT16)ms16->wHitTestCode);
597         ms32.dwExtraInfo = ms16->dwExtraInfo;
598         ms32.hwnd = WIN_Handle32(ms16->hwnd);
599         ret = CallNextHookEx( hhook, code, wparam, (LPARAM)&ms32 );
600         break;
601     }
602
603     case WH_SHELL:
604     case WH_KEYBOARD:
605         ret = CallNextHookEx( hhook, code, wparam, lparam );
606         break;
607
608     case WH_HARDWARE:
609     case WH_FOREGROUNDIDLE:
610     case WH_CALLWNDPROCRET:
611     case WH_SYSMSGFILTER:
612     case WH_JOURNALRECORD:
613     case WH_JOURNALPLAYBACK:
614     default:
615         FIXME("\t[%i] 16to32 translation unimplemented\n", info->id);
616         ret = CallNextHookEx( hhook, code, wparam, lparam );
617         break;
618     }
619     return ret;
620 }
621
622
623 /***********************************************************************
624  *              DefHookProc (USER.235)
625  */
626 LRESULT WINAPI DefHookProc16( INT16 code, WPARAM16 wparam, LPARAM lparam, HHOOK *hhook )
627 {
628     return CallNextHookEx16( *hhook, code, wparam, lparam );
629 }