winproc.c 80.9 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4 5 6 7
/*
 * Window procedure callbacks
 *
 * Copyright 1995 Martin von Loewis
 * Copyright 1996 Alexandre Julliard
 */

8
#include <string.h>
9 10
#include "wine/winbase16.h"
#include "winuser.h"
11 12
#include "stackframe.h"
#include "builtin16.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
13
#include "heap.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
14
#include "selectors.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
15 16
#include "struct32.h"
#include "win.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
17
#include "winproc.h"
18
#include "debugtools.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
19
#include "spy.h"
20
#include "commctrl.h"
21 22
#include "task.h"
#include "thread.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
23

24 25 26 27
DECLARE_DEBUG_CHANNEL(msg)
DECLARE_DEBUG_CHANNEL(relay)
DECLARE_DEBUG_CHANNEL(win)

Alexandre Julliard's avatar
Alexandre Julliard committed
28
/* Window procedure 16-to-32-bit thunk,
Alexandre Julliard's avatar
Alexandre Julliard committed
29 30
 * see BuildSpec16Files() in tools/build.c */

31
#include "pshpack1.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
32 33
typedef struct
{
34
    WORD       pushw_bp;             /* pushw %bp */
Alexandre Julliard's avatar
Alexandre Julliard committed
35
    BYTE       pushl_func;           /* pushl $proc */
36 37 38 39 40 41 42 43 44
    WNDPROC    proc;
    WORD       pushw_ax;             /* pushw %ax */
    BYTE       pushl_relay;          /* pushl $relay */
    void     (*relay)();             /* WINPROC_Thunk16To32A/W() */
    BYTE       lcall;                /* lcall cs:glue */
    void     (*glue)();              /* CallFrom16Long */
    WORD       cs;                   /* __FLATCS */
    WORD       lret;                 /* lret $10 */
    WORD       nArgs;
Alexandre Julliard's avatar
Alexandre Julliard committed
45
} WINPROC_THUNK_FROM16;
46
#include "poppack.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
47

Alexandre Julliard's avatar
Alexandre Julliard committed
48 49 50
/* Window procedure 32-to-16-bit thunk,
 * see BuildSpec32Files() in tools/build.c */

Alexandre Julliard's avatar
Alexandre Julliard committed
51 52
typedef struct
{
Alexandre Julliard's avatar
Alexandre Julliard committed
53
    BYTE       popl_eax;             /* popl  %eax (return address) */
Alexandre Julliard's avatar
Alexandre Julliard committed
54
    BYTE       pushl_func;           /* pushl $proc */
Alexandre Julliard's avatar
Alexandre Julliard committed
55 56
    WNDPROC16  proc WINE_PACKED;
    BYTE       pushl_eax;            /* pushl %eax */
Alexandre Julliard's avatar
Alexandre Julliard committed
57
    BYTE       jmp;                  /* jmp   relay (relative jump)*/
Alexandre Julliard's avatar
Alexandre Julliard committed
58
    void     (*relay)() WINE_PACKED; /* WINPROC_CallProc32ATo16() */
Alexandre Julliard's avatar
Alexandre Julliard committed
59 60
} WINPROC_THUNK_FROM32;

Alexandre Julliard's avatar
Alexandre Julliard committed
61 62 63 64
/* Simple jmp to call 32-bit procedure directly */
typedef struct
{
    BYTE       jmp;                  /* jmp  proc (relative jump) */
65
    WNDPROC  proc WINE_PACKED;
Alexandre Julliard's avatar
Alexandre Julliard committed
66 67
} WINPROC_JUMP;

Alexandre Julliard's avatar
Alexandre Julliard committed
68 69 70 71 72 73 74 75 76
typedef union
{
    WINPROC_THUNK_FROM16  t_from16;
    WINPROC_THUNK_FROM32  t_from32;
} WINPROC_THUNK;

typedef struct tagWINDOWPROC
{
    WINPROC_THUNK         thunk;    /* Thunk */
Alexandre Julliard's avatar
Alexandre Julliard committed
77
    WINPROC_JUMP          jmp;      /* Jump */
Alexandre Julliard's avatar
Alexandre Julliard committed
78
    struct tagWINDOWPROC *next;     /* Next window proc */
79
    UINT                magic;    /* Magic number */
Alexandre Julliard's avatar
Alexandre Julliard committed
80
    WINDOWPROCTYPE        type;     /* Function type */
Alexandre Julliard's avatar
Alexandre Julliard committed
81
    WINDOWPROCUSER        user;     /* Function user */
Alexandre Julliard's avatar
Alexandre Julliard committed
82 83
} WINDOWPROC;

Alexandre Julliard's avatar
Alexandre Julliard committed
84
#define WINPROC_MAGIC  ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
Alexandre Julliard's avatar
Alexandre Julliard committed
85

Alexandre Julliard's avatar
Alexandre Julliard committed
86 87 88 89 90
#define WINPROC_THUNKPROC(pproc) \
    (((pproc)->type == WIN_PROC_16) ? \
          (WNDPROC16)((pproc)->thunk.t_from32.proc) : \
          (WNDPROC16)((pproc)->thunk.t_from16.proc))

91 92
static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
                                               UINT msg, WPARAM wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
93
                                               LPARAM lParam );
94 95
static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
                                               UINT msg, WPARAM wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
96
                                               LPARAM lParam );
97 98
static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args );
static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args );
Alexandre Julliard's avatar
Alexandre Julliard committed
99

100
static HANDLE WinProcHeap;
Alexandre Julliard's avatar
Alexandre Julliard committed
101

Alexandre Julliard's avatar
Alexandre Julliard committed
102

Alexandre Julliard's avatar
Alexandre Julliard committed
103 104 105
/**********************************************************************
 *	     WINPROC_Init
 */
106
BOOL WINPROC_Init(void)
Alexandre Julliard's avatar
Alexandre Julliard committed
107 108 109 110
{
    WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR | HEAP_WINE_CODESEG, 0, 0 );
    if (!WinProcHeap)
    {
111
        WARN_(relay)("Unable to create winproc heap\n" );
Alexandre Julliard's avatar
Alexandre Julliard committed
112 113 114 115
        return FALSE;
    }
    return TRUE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
116

Alexandre Julliard's avatar
Alexandre Julliard committed
117

Alexandre Julliard's avatar
Alexandre Julliard committed
118 119 120 121 122
/**********************************************************************
 *	     WINPROC_CallWndProc32
 *
 * Call a 32-bit WndProc.
 */
123 124
static LRESULT WINPROC_CallWndProc( WNDPROC proc, HWND hwnd, UINT msg,
                                      WPARAM wParam, LPARAM lParam )
Alexandre Julliard's avatar
Alexandre Julliard committed
125
{
126 127 128
    LRESULT retvalue;
    int iWndsLocks;
    
129
    TRACE_(relay)("(wndproc=%p,hwnd=%08x,msg=%s,wp=%08x,lp=%08lx)\n",
Alexandre Julliard's avatar
Alexandre Julliard committed
130
                   proc, hwnd, SPY_GetMsgName(msg), wParam, lParam );
131 132 133 134 135 136
    /* To avoid any deadlocks, all the locks on the windows structures
       must be suspended before the control is passed to the application */
    iWndsLocks = WIN_SuspendWndsLock();
    retvalue = proc( hwnd, msg, wParam, lParam );
    WIN_RestoreWndsLock(iWndsLocks);
    return retvalue;
Alexandre Julliard's avatar
Alexandre Julliard committed
137 138
}

139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
/***********************************************************************
 *           WINPROC_CallWndProc16
 *
 * Call a 16-bit window procedure
 */
static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
                                             UINT16 msg, WPARAM16 wParam,
                                             LPARAM lParam )
{
    CONTEXT86 context;
    LRESULT ret;
    WORD *args;
    WND *wndPtr = WIN_FindWndPtr( hwnd );
    DWORD offset = 0;
    TEB *teb = NtCurrentTeb();
    int iWndsLocks;

    /* Window procedures want ax = hInstance, ds = es = ss */

    memset(&context, '\0', sizeof(context));
    DS_reg(&context)  = SELECTOROF(teb->cur_stack);
    ES_reg(&context)  = DS_reg(&context);
    EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context);
    CS_reg(&context)  = SELECTOROF(proc);
    EIP_reg(&context) = OFFSETOF(proc);
    EBP_reg(&context) = OFFSETOF(teb->cur_stack)
                        + (WORD)&((STACK16FRAME*)0)->bp;

    WIN_ReleaseWndPtr(wndPtr);

    if (lParam)
    {
        /* Some programs (eg. the "Undocumented Windows" examples, JWP) only
           work if structures passed in lParam are placed in the stack/data
           segment. Programmers easily make the mistake of converting lParam
           to a near rather than a far pointer, since Windows apparently
           allows this. We copy the structures to the 16 bit stack; this is
           ugly but makes these programs work. */
        switch (msg)
        {
          case WM_CREATE:
          case WM_NCCREATE:
            offset = sizeof(CREATESTRUCT16); break;
          case WM_DRAWITEM:
            offset = sizeof(DRAWITEMSTRUCT16); break;
          case WM_COMPAREITEM:
            offset = sizeof(COMPAREITEMSTRUCT16); break;
        }
        if (offset)
        {
            void *s = PTR_SEG_TO_LIN(lParam);
            lParam = stack16_push( offset );
            memcpy( PTR_SEG_TO_LIN(lParam), s, offset );
        }
    }

    iWndsLocks = WIN_SuspendWndsLock();

    args = (WORD *)THREAD_STACK16(teb) - 5;
    args[0] = LOWORD(lParam);
    args[1] = HIWORD(lParam);
    args[2] = wParam;
    args[3] = msg;
    args[4] = hwnd;

    ret = CallTo16RegisterShort( &context, 5 * sizeof(WORD) );
    if (offset) stack16_pop( offset );

    WIN_RestoreWndsLock(iWndsLocks);

    return ret;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
212

Alexandre Julliard's avatar
Alexandre Julliard committed
213
/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
214
 *	     WINPROC_GetPtr
Alexandre Julliard's avatar
Alexandre Julliard committed
215
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
216
 * Return a pointer to the win proc.
Alexandre Julliard's avatar
Alexandre Julliard committed
217
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
218
static WINDOWPROC *WINPROC_GetPtr( WNDPROC16 handle )
Alexandre Julliard's avatar
Alexandre Julliard committed
219
{
Alexandre Julliard's avatar
Alexandre Julliard committed
220
    BYTE *ptr;
Alexandre Julliard's avatar
Alexandre Julliard committed
221
    WINDOWPROC *proc;
Alexandre Julliard's avatar
Alexandre Julliard committed
222 223 224 225

    /* Check for a linear pointer */

    if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle ))
Alexandre Julliard's avatar
Alexandre Julliard committed
226
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
227 228
        ptr = (BYTE *)handle;
        /* First check if it is the jmp address */
Alexandre Julliard's avatar
Alexandre Julliard committed
229 230
        if (*ptr == 0xe9 /* jmp */) ptr -= (int)&((WINDOWPROC *)0)->jmp -
                                           (int)&((WINDOWPROC *)0)->thunk;
Alexandre Julliard's avatar
Alexandre Julliard committed
231
        /* Now it must be the thunk address */
Alexandre Julliard's avatar
Alexandre Julliard committed
232
        if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
Alexandre Julliard's avatar
Alexandre Julliard committed
233 234 235
        /* Now we have a pointer to the WINDOWPROC struct */
        if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
            return (WINDOWPROC *)ptr;
Alexandre Julliard's avatar
Alexandre Julliard committed
236
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
237 238 239

    /* Check for a segmented pointer */

Alexandre Julliard's avatar
Alexandre Julliard committed
240
    if (!IsBadReadPtr16((SEGPTR)handle,sizeof(WINDOWPROC)-sizeof(proc->thunk)))
Alexandre Julliard's avatar
Alexandre Julliard committed
241
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
242
        ptr = (BYTE *)PTR_SEG_TO_LIN(handle);
Alexandre Julliard's avatar
Alexandre Julliard committed
243
        if (!HEAP_IsInsideHeap( WinProcHeap, 0, ptr )) return NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
244
        /* It must be the thunk address */
Alexandre Julliard's avatar
Alexandre Julliard committed
245
        if (*ptr == 0x58 /* popl eax */) ptr -= (int)&((WINDOWPROC *)0)->thunk;
Alexandre Julliard's avatar
Alexandre Julliard committed
246 247 248
        /* Now we have a pointer to the WINDOWPROC struct */
        if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
            return (WINDOWPROC *)ptr;
Alexandre Julliard's avatar
Alexandre Julliard committed
249
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
250 251

    return NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
252 253 254 255
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
256
 *	     WINPROC_AllocWinProc
Alexandre Julliard's avatar
Alexandre Julliard committed
257
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
258
 * Allocate a new window procedure.
Alexandre Julliard's avatar
Alexandre Julliard committed
259
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
260 261
static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC16 func, WINDOWPROCTYPE type,
                                         WINDOWPROCUSER user )
Alexandre Julliard's avatar
Alexandre Julliard committed
262
{
Alexandre Julliard's avatar
Alexandre Julliard committed
263
    WINDOWPROC *proc, *oldproc;
Alexandre Julliard's avatar
Alexandre Julliard committed
264

Alexandre Julliard's avatar
Alexandre Julliard committed
265
    /* Allocate a window procedure */
Alexandre Julliard's avatar
Alexandre Julliard committed
266

Alexandre Julliard's avatar
Alexandre Julliard committed
267
    if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
268

Alexandre Julliard's avatar
Alexandre Julliard committed
269
    /* Check if the function is already a win proc */
Alexandre Julliard's avatar
Alexandre Julliard committed
270

Alexandre Julliard's avatar
Alexandre Julliard committed
271
    if ((oldproc = WINPROC_GetPtr( func )))
Alexandre Julliard's avatar
Alexandre Julliard committed
272
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
273
        *proc = *oldproc;
Alexandre Julliard's avatar
Alexandre Julliard committed
274
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
275 276 277 278 279
    else
    {
        switch(type)
        {
        case WIN_PROC_16:
Alexandre Julliard's avatar
Alexandre Julliard committed
280 281 282 283 284 285
            proc->thunk.t_from32.popl_eax    = 0x58;   /* popl  %eax */
            proc->thunk.t_from32.pushl_func  = 0x68;   /* pushl $proc */
            proc->thunk.t_from32.proc        = func;
            proc->thunk.t_from32.pushl_eax   = 0x50;   /* pushl %eax */
            proc->thunk.t_from32.jmp         = 0xe9;   /* jmp   relay*/
            proc->thunk.t_from32.relay =  /* relative jump */
Alexandre Julliard's avatar
Alexandre Julliard committed
286
                (void(*)())((DWORD)WINPROC_CallProc32ATo16 -
Alexandre Julliard's avatar
Alexandre Julliard committed
287 288 289 290
                                     (DWORD)(&proc->thunk.t_from32.relay + 1));
            break;
        case WIN_PROC_32A:
        case WIN_PROC_32W:
291
            proc->thunk.t_from16.pushw_bp    = 0x5566; /* pushw %bp */
Alexandre Julliard's avatar
Alexandre Julliard committed
292
            proc->thunk.t_from16.pushl_func  = 0x68;   /* pushl $proc */
293
            proc->thunk.t_from16.proc        = (FARPROC)func;
294 295 296 297 298 299 300
            proc->thunk.t_from16.pushw_ax    = 0x5066; /* pushw %ax */
            proc->thunk.t_from16.pushl_relay = 0x68;   /* pushl $relay */
            proc->thunk.t_from16.relay       = (type == WIN_PROC_32A) ?
                                           (void(*)())WINPROC_Thunk16To32A :
                                           (void(*)())WINPROC_Thunk16To32W;
            proc->thunk.t_from16.lcall       = 0x9a;   /* lcall cs:glue */
            proc->thunk.t_from16.glue        = (void*)CallFrom16Long;
Alexandre Julliard's avatar
Alexandre Julliard committed
301
            GET_CS(proc->thunk.t_from16.cs);
302 303
            proc->thunk.t_from16.lret        = 0xca66;
            proc->thunk.t_from16.nArgs       = 10;
Alexandre Julliard's avatar
Alexandre Julliard committed
304
            proc->jmp.jmp  = 0xe9;
Alexandre Julliard's avatar
Alexandre Julliard committed
305
            /* Fixup relative jump */
306
            proc->jmp.proc = (WNDPROC)((DWORD)func -
Alexandre Julliard's avatar
Alexandre Julliard committed
307
                                                 (DWORD)(&proc->jmp.proc + 1));
Alexandre Julliard's avatar
Alexandre Julliard committed
308 309 310 311 312 313 314
            break;
        default:
            /* Should not happen */
            break;
        }
        proc->magic = WINPROC_MAGIC;
        proc->type  = type;
Alexandre Julliard's avatar
Alexandre Julliard committed
315
        proc->user  = user;
Alexandre Julliard's avatar
Alexandre Julliard committed
316 317
    }
    proc->next  = NULL;
318
    TRACE_(win)("(%08x,%d): returning %08x\n",
319
                 (UINT)func, type, (UINT)proc );
Alexandre Julliard's avatar
Alexandre Julliard committed
320
    return proc;
Alexandre Julliard's avatar
Alexandre Julliard committed
321 322 323 324
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
325
 *	     WINPROC_GetProc
Alexandre Julliard's avatar
Alexandre Julliard committed
326
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
327
 * Get a window procedure pointer that can be passed to the Windows program.
Alexandre Julliard's avatar
Alexandre Julliard committed
328
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
329
WNDPROC16 WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
Alexandre Julliard's avatar
Alexandre Julliard committed
330
{
Alexandre Julliard's avatar
Alexandre Julliard committed
331
    if (!proc) return NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
332
    if (type == WIN_PROC_16)  /* We want a 16:16 address */
Alexandre Julliard's avatar
Alexandre Julliard committed
333
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
334 335 336
        if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
            return ((WINDOWPROC *)proc)->thunk.t_from32.proc;
        else
Alexandre Julliard's avatar
Alexandre Julliard committed
337 338
            return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0,
                                              &((WINDOWPROC *)proc)->thunk );
Alexandre Julliard's avatar
Alexandre Julliard committed
339 340 341 342
    }
    else  /* We want a 32-bit address */
    {
        if (((WINDOWPROC *)proc)->type == WIN_PROC_16)
Alexandre Julliard's avatar
Alexandre Julliard committed
343
            return (WNDPROC16)&((WINDOWPROC *)proc)->thunk;
Alexandre Julliard's avatar
Alexandre Julliard committed
344 345 346
        else if (type != ((WINDOWPROC *)proc)->type)
            /* Have to return the jmp address if types don't match */
            return (WNDPROC16)&((WINDOWPROC *)proc)->jmp;
Alexandre Julliard's avatar
Alexandre Julliard committed
347
        else
Alexandre Julliard's avatar
Alexandre Julliard committed
348 349
            /* Some Win16 programs want to get back the proc they set */
            return (WNDPROC16)((WINDOWPROC *)proc)->thunk.t_from16.proc;
Alexandre Julliard's avatar
Alexandre Julliard committed
350
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
351 352 353 354
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
355
 *	     WINPROC_SetProc
Alexandre Julliard's avatar
Alexandre Julliard committed
356
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
 * Set the window procedure for a window or class. There are
 * three tree classes of winproc callbacks:
 *
 * 1) class  -> wp                 	-	not subclassed
 *    class  -> wp -> wp -> wp -> wp 	-	SetClassLong()
 *             /           /
 * 2) window -'           /		-	not subclassed
 *    window -> wp -> wp '           	-	SetWindowLong()
 *
 * 3) timer  -> wp                   	-	SetTimer()
 *
 * Initially, winproc of the window points to the current winproc 
 * thunk of its class. Subclassing prepends a new thunk to the 
 * window winproc chain at the head of the list. Thus, window thunk 
 * list includes class thunks and the latter are preserved when the 
 * window is destroyed.
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
374
 */
375
BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC16 func,
Alexandre Julliard's avatar
Alexandre Julliard committed
376
                        WINDOWPROCTYPE type, WINDOWPROCUSER user )
Alexandre Julliard's avatar
Alexandre Julliard committed
377
{
378
    BOOL bRecycle = FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
379
    WINDOWPROC *proc, **ppPrev;
Alexandre Julliard's avatar
Alexandre Julliard committed
380

Alexandre Julliard's avatar
Alexandre Julliard committed
381 382 383 384 385
    /* Check if function is already in the list */

    ppPrev = (WINDOWPROC **)pFirst;
    proc = WINPROC_GetPtr( func );
    while (*ppPrev)
Alexandre Julliard's avatar
Alexandre Julliard committed
386
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
387 388
        if (proc)
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
389 390 391 392 393 394 395 396 397 398 399 400 401
            if (*ppPrev == proc)
            {
                if ((*ppPrev)->user != user)
		{
		    /* terminal thunk is being restored */

		    WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
		    *(WINDOWPROC **)pFirst = *ppPrev;
		    return TRUE;
		}
		bRecycle = TRUE;
		break;
	    }
Alexandre Julliard's avatar
Alexandre Julliard committed
402 403 404 405
        }
        else
        {
            if (((*ppPrev)->type == type) &&
Alexandre Julliard's avatar
Alexandre Julliard committed
406 407 408 409 410
                (func == WINPROC_THUNKPROC(*ppPrev)))
            {
                bRecycle = TRUE;
                break;
            }
Alexandre Julliard's avatar
Alexandre Julliard committed
411
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
412 413 414
            
        /* WPF_CLASS thunk terminates window thunk list */
        if ((*ppPrev)->user != user) break;
Alexandre Julliard's avatar
Alexandre Julliard committed
415
        ppPrev = &(*ppPrev)->next;
Alexandre Julliard's avatar
Alexandre Julliard committed
416
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
417

Alexandre Julliard's avatar
Alexandre Julliard committed
418
    if (bRecycle)
Alexandre Julliard's avatar
Alexandre Julliard committed
419
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
420
        /* Extract this thunk from the list */
Alexandre Julliard's avatar
Alexandre Julliard committed
421 422
        proc = *ppPrev;
        *ppPrev = proc->next;
Alexandre Julliard's avatar
Alexandre Julliard committed
423
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
424 425 426 427 428 429 430
    else  /* Allocate a new one */
    {
        if (proc)  /* Was already a win proc */
        {
            type = proc->type;
            func = WINPROC_THUNKPROC(proc);
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
431
        proc = WINPROC_AllocWinProc( func, type, user );
Alexandre Julliard's avatar
Alexandre Julliard committed
432 433 434 435 436
        if (!proc) return FALSE;
    }

    /* Add the win proc at the head of the list */

437
    TRACE_(win)("(%08x,%08x,%d): res=%08x\n",
438
                 (UINT)*pFirst, (UINT)func, type, (UINT)proc );
Alexandre Julliard's avatar
Alexandre Julliard committed
439 440 441
    proc->next  = *(WINDOWPROC **)pFirst;
    *(WINDOWPROC **)pFirst = proc;
    return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
442 443 444
}


Alexandre Julliard's avatar
Alexandre Julliard committed
445
/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
446
 *	     WINPROC_FreeProc
Alexandre Julliard's avatar
Alexandre Julliard committed
447
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
448
 * Free a list of win procs.
Alexandre Julliard's avatar
Alexandre Julliard committed
449
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
450
void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
Alexandre Julliard's avatar
Alexandre Julliard committed
451
{
Alexandre Julliard's avatar
Alexandre Julliard committed
452 453 454
    while (proc)
    {
        WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
Alexandre Julliard's avatar
Alexandre Julliard committed
455
        if (((WINDOWPROC *)proc)->user != user) break;
456
        TRACE_(win)("freeing %08x\n", (UINT)proc);
Alexandre Julliard's avatar
Alexandre Julliard committed
457 458 459
        HeapFree( WinProcHeap, 0, proc );
        proc = next;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
460 461 462 463
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
464
 *	     WINPROC_GetProcType
Alexandre Julliard's avatar
Alexandre Julliard committed
465
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
466
 * Return the window procedure type.
Alexandre Julliard's avatar
Alexandre Julliard committed
467
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
468
WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
Alexandre Julliard's avatar
Alexandre Julliard committed
469
{
Alexandre Julliard's avatar
Alexandre Julliard committed
470 471 472 473
    if (!proc ||
        (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
        return WIN_PROC_INVALID;
    return ((WINDOWPROC *)proc)->type;
Alexandre Julliard's avatar
Alexandre Julliard committed
474
}
475 476 477 478 479
/**********************************************************************
 *	     WINPROC_TestCBForStr
 *
 * Return TRUE if the lparam is a string
 */
Patrik Stridvall's avatar
Patrik Stridvall committed
480
static BOOL WINPROC_TestCBForStr ( HWND hwnd )
481 482 483 484
{
    BOOL retvalue;
    WND * wnd = WIN_FindWndPtr(hwnd);
    retvalue = ( !(LOWORD(wnd->dwStyle) & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) ||
485
	      (LOWORD(wnd->dwStyle) & CBS_HASSTRINGS) );
486 487
    WIN_ReleaseWndPtr(wnd);
    return retvalue;
488 489 490 491 492 493
}
/**********************************************************************
 *	     WINPROC_TestLBForStr
 *
 * Return TRUE if the lparam is a string
 */
Patrik Stridvall's avatar
Patrik Stridvall committed
494
static BOOL WINPROC_TestLBForStr ( HWND hwnd )
495 496 497 498
{
    BOOL retvalue;
    WND * wnd = WIN_FindWndPtr(hwnd); 
    retvalue = ( !(LOWORD(wnd->dwStyle) & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) ||
499
	    (LOWORD(wnd->dwStyle) & LBS_HASSTRINGS) );
500 501 502
    WIN_ReleaseWndPtr(wnd);
    return retvalue;

503
}
Alexandre Julliard's avatar
Alexandre Julliard committed
504
/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
505
 *	     WINPROC_MapMsg32ATo32W
Alexandre Julliard's avatar
Alexandre Julliard committed
506
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
507 508
 * Map a message from Ansi to Unicode.
 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
Juergen Schmied's avatar
Juergen Schmied committed
509 510 511 512 513 514 515 516
 *
 * FIXME:
 *  WM_CHAR, WM_CHARTOITEM, WM_DEADCHAR, WM_MENUCHAR, WM_SYSCHAR, WM_SYSDEADCHAR
 *
 * FIXME:
 *  WM_GETTEXT/WM_SETTEXT and static control with SS_ICON style:
 *  the first four bytes are the handle of the icon 
 *  when the WM_SETTEXT message has been used to set the icon
Alexandre Julliard's avatar
Alexandre Julliard committed
517
 */
518
INT WINPROC_MapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
Juergen Schmied's avatar
Juergen Schmied committed
519 520
{
    switch(msg)
Alexandre Julliard's avatar
Alexandre Julliard committed
521 522 523 524 525 526 527 528 529 530
    {
    case WM_GETTEXT:
        {
            LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
                                     wParam * sizeof(WCHAR) + sizeof(LPARAM) );
            if (!ptr) return -1;
            *ptr++ = *plparam;  /* Store previous lParam */
            *plparam = (LPARAM)ptr;
        }
        return 1;
531
    /* lparam is string (0-terminated) */
Alexandre Julliard's avatar
Alexandre Julliard committed
532
    case WM_SETTEXT:
533
    case WM_WININICHANGE:
534 535 536 537 538 539 540 541 542
    case CB_DIR:
    case CB_FINDSTRING:
    case CB_FINDSTRINGEXACT:
    case CB_SELECTSTRING:
    case LB_DIR:
    case LB_ADDFILE:
    case LB_FINDSTRING:
    case LB_SELECTSTRING:
    case EM_REPLACESEL:
Alexandre Julliard's avatar
Alexandre Julliard committed
543
        *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
544
        return (*plparam ? 1 : -1);
545

Alexandre Julliard's avatar
Alexandre Julliard committed
546 547 548
    case WM_NCCREATE:
    case WM_CREATE:
        {
549
            CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
550 551
                                                                sizeof(*cs) );
            if (!cs) return -1;
552
            *cs = *(CREATESTRUCTW *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
553
            if (HIWORD(cs->lpszName))
Alexandre Julliard's avatar
Alexandre Julliard committed
554 555
                cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
                                                (LPCSTR)cs->lpszName );
Alexandre Julliard's avatar
Alexandre Julliard committed
556
            if (HIWORD(cs->lpszClass))
Alexandre Julliard's avatar
Alexandre Julliard committed
557 558
                cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
                                                 (LPCSTR)cs->lpszClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
559 560 561
            *plparam = (LPARAM)cs;
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
562 563
    case WM_MDICREATE:
        {
564 565
            MDICREATESTRUCTW *cs =
                (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
Alexandre Julliard's avatar
Alexandre Julliard committed
566
            if (!cs) return -1;
567
            *cs = *(MDICREATESTRUCTW *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
568
            if (HIWORD(cs->szClass))
Alexandre Julliard's avatar
Alexandre Julliard committed
569 570
                cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
                                               (LPCSTR)cs->szClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
571
            if (HIWORD(cs->szTitle))
Alexandre Julliard's avatar
Alexandre Julliard committed
572 573
                cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
                                               (LPCSTR)cs->szTitle );
Alexandre Julliard's avatar
Alexandre Julliard committed
574 575 576
            *plparam = (LPARAM)cs;
        }
        return 1;
577 578

/* Listbox */
579 580
    case LB_ADDSTRING:
    case LB_INSERTSTRING:
581 582 583 584
	if ( WINPROC_TestLBForStr( hwnd ))
          *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
        return (*plparam ? 1 : -1);

585
    case LB_GETTEXT:		    /* fixme: fixed sized buffer */
586 587 588 589 590 591 592 593 594 595
        { if ( WINPROC_TestLBForStr( hwnd ))
	  { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
            if (!ptr) return -1;
            *ptr++ = *plparam;  /* Store previous lParam */
            *plparam = (LPARAM)ptr;
	  }
        }
        return 1;

/* Combobox */
596 597
    case CB_ADDSTRING:
    case CB_INSERTSTRING:
598 599 600 601
	if ( WINPROC_TestCBForStr( hwnd ))
          *plparam = (LPARAM)HEAP_strdupAtoW( SystemHeap, 0, (LPCSTR)*plparam );
        return (*plparam ? 1 : -1);

602
    case CB_GETLBTEXT:    /* fixme: fixed sized buffer */
603 604 605 606 607 608 609 610 611 612
        { if ( WINPROC_TestCBForStr( hwnd ))
          { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 * sizeof(WCHAR) + sizeof(LPARAM) );
            if (!ptr) return -1;
            *ptr++ = *plparam;  /* Store previous lParam */
            *plparam = (LPARAM)ptr;
	  }
        }
        return 1;

/* Multiline edit */
613
    case EM_GETLINE:
614 615 616 617
        { WORD len = (WORD)*plparam;
	  LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(WCHAR) );
          if (!ptr) return -1;
          *ptr++ = *plparam;  /* Store previous lParam */
618
	  *((WORD *) ptr) = len;   /* Store the length */
619 620 621 622
          *plparam = (LPARAM)ptr;
	}
        return 1;

Alexandre Julliard's avatar
Alexandre Julliard committed
623 624 625 626
    case WM_ASKCBFORMATNAME:
    case WM_DEVMODECHANGE:
    case WM_PAINTCLIPBOARD:
    case WM_SIZECLIPBOARD:
627
    case EM_SETPASSWORDCHAR:
628
        FIXME_(msg)("message %s (0x%x) needs translation, please report\n", SPY_GetMsgName(msg), msg );
Alexandre Julliard's avatar
Alexandre Julliard committed
629
        return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
630 631 632
    default:  /* No translation needed */
        return 0;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
633 634 635
}


Alexandre Julliard's avatar
Alexandre Julliard committed
636
/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
637
 *	     WINPROC_UnmapMsg32ATo32W
Alexandre Julliard's avatar
Alexandre Julliard committed
638
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
639
 * Unmap a message that was mapped from Ansi to Unicode.
Alexandre Julliard's avatar
Alexandre Julliard committed
640
 */
641
void WINPROC_UnmapMsg32ATo32W( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
Juergen Schmied's avatar
Juergen Schmied committed
642 643
{
    switch(msg)
Alexandre Julliard's avatar
Alexandre Julliard committed
644 645 646
    {
    case WM_GETTEXT:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
647
            LPARAM *ptr = (LPARAM *)lParam - 1;
Juergen Schmied's avatar
Juergen Schmied committed
648
            lstrcpynWtoA( (LPSTR)*ptr, (LPWSTR)lParam, wParam );
649 650 651 652
            HeapFree( SystemHeap, 0, ptr );
        }
        break;

Alexandre Julliard's avatar
Alexandre Julliard committed
653 654
    case WM_NCCREATE:
    case WM_CREATE:
Alexandre Julliard's avatar
Alexandre Julliard committed
655
        {
656
            CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
657 658 659 660
            if (HIWORD(cs->lpszName))
                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
            if (HIWORD(cs->lpszClass))
                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
661
            HeapFree( SystemHeap, 0, cs );
Alexandre Julliard's avatar
Alexandre Julliard committed
662
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
663
        break;
664

Alexandre Julliard's avatar
Alexandre Julliard committed
665 666
    case WM_MDICREATE:
        {
667
            MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
668 669 670 671
            if (HIWORD(cs->szTitle))
                HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
            if (HIWORD(cs->szClass))
                HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
672 673 674
            HeapFree( SystemHeap, 0, cs );
        }
        break;
675 676

    case WM_SETTEXT:
677
    case WM_WININICHANGE:
678 679 680 681 682 683 684 685 686
    case CB_DIR:
    case CB_FINDSTRING:
    case CB_FINDSTRINGEXACT:
    case CB_SELECTSTRING:
    case LB_DIR:
    case LB_ADDFILE:
    case LB_FINDSTRING:
    case LB_SELECTSTRING:
    case EM_REPLACESEL:
687 688 689 690
        HeapFree( SystemHeap, 0, (void *)lParam );
        break;

/* Listbox */
691 692
    case LB_ADDSTRING:
    case LB_INSERTSTRING:
693 694 695 696
	if ( WINPROC_TestLBForStr( hwnd ))
          HeapFree( SystemHeap, 0, (void *)lParam );
        break;

697
    case LB_GETTEXT:
698 699 700 701 702 703 704 705 706
        { if ( WINPROC_TestLBForStr( hwnd ))
          { LPARAM *ptr = (LPARAM *)lParam - 1;
	    lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
            HeapFree( SystemHeap, 0, ptr );
	  }
        }
        break;

/* Combobox */
707 708
    case CB_ADDSTRING:
    case CB_INSERTSTRING:
709 710 711 712
	if ( WINPROC_TestCBForStr( hwnd ))
          HeapFree( SystemHeap, 0, (void *)lParam );
        break;

713
    case CB_GETLBTEXT:
714 715 716 717 718 719 720 721 722
        { if ( WINPROC_TestCBForStr( hwnd ))
	  { LPARAM *ptr = (LPARAM *)lParam - 1;
            lstrcpyWtoA( (LPSTR)*ptr, (LPWSTR)(lParam) );
            HeapFree( SystemHeap, 0, ptr );
	  }
        }
        break;

/* Multiline edit */
723
    case EM_GETLINE:
724 725 726
        { LPARAM * ptr = (LPARAM *)lParam - 1;  /* get the old lParam */
	  WORD len = *(WORD *) lParam;
          lstrcpynWtoA( (LPSTR)*ptr , (LPWSTR)lParam, len );
727 728 729
          HeapFree( SystemHeap, 0, ptr );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
730 731
    }
}
Alexandre Julliard's avatar
Alexandre Julliard committed
732

Alexandre Julliard's avatar
Alexandre Julliard committed
733 734 735 736 737 738 739

/**********************************************************************
 *	     WINPROC_MapMsg32WTo32A
 *
 * Map a message from Unicode to Ansi.
 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
 */
740
INT WINPROC_MapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM *plparam )
741
{   switch(msg)
Alexandre Julliard's avatar
Alexandre Julliard committed
742 743 744 745 746 747 748 749 750 751
    {
    case WM_GETTEXT:
        {
            LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0,
                                               wParam + sizeof(LPARAM) );
            if (!ptr) return -1;
            *ptr++ = *plparam;  /* Store previous lParam */
            *plparam = (LPARAM)ptr;
        }
        return 1;
752

753
    case WM_SETTEXT:
754
    case WM_WININICHANGE:
755 756 757 758 759 760 761 762 763
    case CB_DIR:
    case CB_FINDSTRING:
    case CB_FINDSTRINGEXACT:
    case CB_SELECTSTRING:
    case LB_DIR:
    case LB_ADDFILE:
    case LB_FINDSTRING:
    case LB_SELECTSTRING:
    case EM_REPLACESEL:
Alexandre Julliard's avatar
Alexandre Julliard committed
764
        *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
765
        return (*plparam ? 1 : -1);
766

Alexandre Julliard's avatar
Alexandre Julliard committed
767 768 769
    case WM_NCCREATE:
    case WM_CREATE:
        {
770
            CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
771 772
                                                                sizeof(*cs) );
            if (!cs) return -1;
773
            *cs = *(CREATESTRUCTA *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
774
            if (HIWORD(cs->lpszName))
Alexandre Julliard's avatar
Alexandre Julliard committed
775 776
                cs->lpszName  = HEAP_strdupWtoA( SystemHeap, 0,
                                                 (LPCWSTR)cs->lpszName );
Alexandre Julliard's avatar
Alexandre Julliard committed
777
            if (HIWORD(cs->lpszClass))
Alexandre Julliard's avatar
Alexandre Julliard committed
778 779
                cs->lpszClass = HEAP_strdupWtoA( SystemHeap, 0,
                                                 (LPCWSTR)cs->lpszClass);
Alexandre Julliard's avatar
Alexandre Julliard committed
780
            *plparam = (LPARAM)cs;
Alexandre Julliard's avatar
Alexandre Julliard committed
781
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
782
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
783 784
    case WM_MDICREATE:
        {
785 786
            MDICREATESTRUCTA *cs =
                (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0, sizeof(*cs) );
Alexandre Julliard's avatar
Alexandre Julliard committed
787
            if (!cs) return -1;
788
            *cs = *(MDICREATESTRUCTA *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
789
            if (HIWORD(cs->szTitle))
Alexandre Julliard's avatar
Alexandre Julliard committed
790 791
                cs->szTitle = HEAP_strdupWtoA( SystemHeap, 0,
                                               (LPCWSTR)cs->szTitle );
Alexandre Julliard's avatar
Alexandre Julliard committed
792
            if (HIWORD(cs->szClass))
Alexandre Julliard's avatar
Alexandre Julliard committed
793 794
                cs->szClass = HEAP_strdupWtoA( SystemHeap, 0,
                                               (LPCWSTR)cs->szClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
795 796 797
            *plparam = (LPARAM)cs;
        }
        return 1;
798 799

/* Listbox */
800 801
    case LB_ADDSTRING:
    case LB_INSERTSTRING:
802 803 804 805
	if ( WINPROC_TestLBForStr( hwnd ))
          *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
        return (*plparam ? 1 : -1);

806
    case LB_GETTEXT:			/* fixme: fixed sized buffer */
807 808 809 810 811 812 813 814 815 816
        { if ( WINPROC_TestLBForStr( hwnd ))
	  { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
            if (!ptr) return -1;
            *ptr++ = *plparam;  /* Store previous lParam */
            *plparam = (LPARAM)ptr;
	  }
        }
        return 1;

/* Combobox */
817 818
    case CB_ADDSTRING:
    case CB_INSERTSTRING:
819 820 821 822
	if ( WINPROC_TestCBForStr( hwnd ))
          *plparam = (LPARAM)HEAP_strdupWtoA( SystemHeap, 0, (LPCWSTR)*plparam );
        return (*plparam ? 1 : -1);

823
    case CB_GETLBTEXT:		/* fixme: fixed sized buffer */
824 825 826 827 828 829 830 831 832 833
        { if ( WINPROC_TestCBForStr( hwnd ))
	  { LPARAM *ptr = (LPARAM *)HeapAlloc( SystemHeap, 0, 256 + sizeof(LPARAM) );
            if (!ptr) return -1;
            *ptr++ = *plparam;  /* Store previous lParam */
            *plparam = (LPARAM)ptr;
	  }
        }
        return 1;

/* Multiline edit */
834
    case EM_GETLINE:
835 836 837 838
        { WORD len = (WORD)*plparam;
	  LPARAM *ptr = (LPARAM *) HEAP_xalloc( SystemHeap, 0, sizeof(LPARAM) + sizeof (WORD) + len*sizeof(CHAR) );
          if (!ptr) return -1;
          *ptr++ = *plparam;  /* Store previous lParam */
839
	  *((WORD *) ptr) = len;   /* Store the length */
840 841 842 843
          *plparam = (LPARAM)ptr;
	}
        return 1;

Alexandre Julliard's avatar
Alexandre Julliard committed
844 845 846 847
    case WM_ASKCBFORMATNAME:
    case WM_DEVMODECHANGE:
    case WM_PAINTCLIPBOARD:
    case WM_SIZECLIPBOARD:
848
    case EM_SETPASSWORDCHAR:
849
        FIXME_(msg)("message %s (%04x) needs translation, please report\n",SPY_GetMsgName(msg),msg );
Alexandre Julliard's avatar
Alexandre Julliard committed
850
        return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
851
    default:  /* No translation needed */
Alexandre Julliard's avatar
Alexandre Julliard committed
852
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
853 854 855 856 857
    }
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
858
 *	     WINPROC_UnmapMsg32WTo32A
Alexandre Julliard's avatar
Alexandre Julliard committed
859
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
860
 * Unmap a message that was mapped from Unicode to Ansi.
Alexandre Julliard's avatar
Alexandre Julliard committed
861
 */
862
void WINPROC_UnmapMsg32WTo32A( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
Juergen Schmied's avatar
Juergen Schmied committed
863 864
{
    switch(msg)
Alexandre Julliard's avatar
Alexandre Julliard committed
865 866 867
    {
    case WM_GETTEXT:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
868
            LPARAM *ptr = (LPARAM *)lParam - 1;
Juergen Schmied's avatar
Juergen Schmied committed
869
            lstrcpynAtoW( (LPWSTR)*ptr, (LPSTR)lParam, wParam );
870 871 872
            HeapFree( SystemHeap, 0, ptr );
        }
        break;
873 874

    case WM_SETTEXT:
875
    case WM_WININICHANGE:
876 877 878 879 880 881 882 883 884
    case CB_DIR:
    case CB_FINDSTRING:
    case CB_FINDSTRINGEXACT:
    case CB_SELECTSTRING:
    case LB_DIR:
    case LB_ADDFILE:
    case LB_FINDSTRING:
    case LB_SELECTSTRING:
    case EM_REPLACESEL:
Alexandre Julliard's avatar
Alexandre Julliard committed
885
        HeapFree( SystemHeap, 0, (void *)lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
886
        break;
887

Alexandre Julliard's avatar
Alexandre Julliard committed
888 889 890
    case WM_NCCREATE:
    case WM_CREATE:
        {
891
            CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
892 893 894 895
            if (HIWORD(cs->lpszName))
                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
            if (HIWORD(cs->lpszClass))
                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
896 897 898
            HeapFree( SystemHeap, 0, cs );
        }
        break;
899

Alexandre Julliard's avatar
Alexandre Julliard committed
900 901
    case WM_MDICREATE:
        {
902
            MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
903 904 905 906
            if (HIWORD(cs->szTitle))
                HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
            if (HIWORD(cs->szClass))
                HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
907 908 909
            HeapFree( SystemHeap, 0, cs );
        }
        break;
910 911

/* Listbox */
912 913
    case LB_ADDSTRING:
    case LB_INSERTSTRING:
914 915 916 917
	if ( WINPROC_TestLBForStr( hwnd ))
          HeapFree( SystemHeap, 0, (void *)lParam );
        break;

918
    case LB_GETTEXT:
919 920 921 922 923 924 925 926 927
        { if ( WINPROC_TestLBForStr( hwnd ))
          { LPARAM *ptr = (LPARAM *)lParam - 1;
            lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
            HeapFree( SystemHeap, 0, ptr );
	  }
        }
        break;

/* Combobox */
928 929
    case CB_ADDSTRING:
    case CB_INSERTSTRING:
930 931 932 933
	if ( WINPROC_TestCBForStr( hwnd ))
          HeapFree( SystemHeap, 0, (void *)lParam );
        break;

934
    case CB_GETLBTEXT:
935 936 937 938 939 940 941 942 943
        { if ( WINPROC_TestCBForStr( hwnd ))
          { LPARAM *ptr = (LPARAM *)lParam - 1;
            lstrcpyAtoW( (LPWSTR)*ptr, (LPSTR)(lParam) );
            HeapFree( SystemHeap, 0, ptr );
	  }
        }
        break;

/* Multiline edit */
944
    case EM_GETLINE:
945
        { LPARAM * ptr = (LPARAM *)lParam - 1;  /* get the old lparam */
946
	  WORD len = *(WORD *)ptr;
947
          lstrcpynAtoW( (LPWSTR) *ptr, (LPSTR)lParam, len );
948 949 950
          HeapFree( SystemHeap, 0, ptr );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
951 952
    }
}
Alexandre Julliard's avatar
Alexandre Julliard committed
953 954 955


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
956
 *	     WINPROC_MapMsg16To32A
Alexandre Julliard's avatar
Alexandre Julliard committed
957
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
958 959
 * Map a message from 16- to 32-bit Ansi.
 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
Alexandre Julliard's avatar
Alexandre Julliard committed
960
 */
961 962
INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
                             WPARAM *pwparam32, LPARAM *plparam )
Alexandre Julliard's avatar
Alexandre Julliard committed
963
{
964 965
    *pmsg32 = (UINT)msg16;
    *pwparam32 = (WPARAM)wParam16;
Alexandre Julliard's avatar
Alexandre Julliard committed
966
    switch(msg16)
Alexandre Julliard's avatar
Alexandre Julliard committed
967 968 969 970 971
    {
    case WM_ACTIVATE:
    case WM_CHARTOITEM:
    case WM_COMMAND:
    case WM_VKEYTOITEM:
Alexandre Julliard's avatar
Alexandre Julliard committed
972
        *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
973
        *plparam   = (LPARAM)(HWND)LOWORD(*plparam);
Alexandre Julliard's avatar
Alexandre Julliard committed
974
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
975 976 977
    case WM_HSCROLL:
    case WM_VSCROLL:
        *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
978
        *plparam   = (LPARAM)(HWND)HIWORD(*plparam);
Alexandre Julliard's avatar
Alexandre Julliard committed
979
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
980
    case WM_CTLCOLOR:
981
    	if ( HIWORD(*plparam) > CTLCOLOR_STATIC ) return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
982
        *pmsg32    = WM_CTLCOLORMSGBOX + HIWORD(*plparam);
983 984
        *pwparam32 = (WPARAM)(HDC)wParam16;
        *plparam   = (LPARAM)(HWND)LOWORD(*plparam);
Alexandre Julliard's avatar
Alexandre Julliard committed
985
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
986 987 988
    case WM_COMPAREITEM:
        {
            COMPAREITEMSTRUCT16* cis16 = (COMPAREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
989
            COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)
Alexandre Julliard's avatar
Alexandre Julliard committed
990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
                                        HeapAlloc(SystemHeap, 0, sizeof(*cis));
            if (!cis) return -1;
            cis->CtlType    = cis16->CtlType;
            cis->CtlID      = cis16->CtlID;
            cis->hwndItem   = cis16->hwndItem;
            cis->itemID1    = cis16->itemID1;
            cis->itemData1  = cis16->itemData1;
            cis->itemID2    = cis16->itemID2;
            cis->itemData2  = cis16->itemData2;
            cis->dwLocaleId = 0;  /* FIXME */
            *plparam = (LPARAM)cis;
        }
        return 1;
    case WM_DELETEITEM:
        {
            DELETEITEMSTRUCT16* dis16 = (DELETEITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1006
            DELETEITEMSTRUCT *dis = (DELETEITEMSTRUCT *)
Alexandre Julliard's avatar
Alexandre Julliard committed
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
                                        HeapAlloc(SystemHeap, 0, sizeof(*dis));
            if (!dis) return -1;
            dis->CtlType  = dis16->CtlType;
            dis->CtlID    = dis16->CtlID;
            dis->hwndItem = dis16->hwndItem;
            dis->itemData = dis16->itemData;
            *plparam = (LPARAM)dis;
        }
        return 1;
    case WM_MEASUREITEM:
        {
            MEASUREITEMSTRUCT16* mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1019
            MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)
Alexandre Julliard's avatar
Alexandre Julliard committed
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
                                        HeapAlloc(SystemHeap, 0,
                                                sizeof(*mis) + sizeof(LPARAM));
            if (!mis) return -1;
            mis->CtlType    = mis16->CtlType;
            mis->CtlID      = mis16->CtlID;
            mis->itemID     = mis16->itemID;
            mis->itemWidth  = mis16->itemWidth;
            mis->itemHeight = mis16->itemHeight;
            mis->itemData   = mis16->itemData;
            *(LPARAM *)(mis + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)mis;
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1033 1034
    case WM_DRAWITEM:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1035
            DRAWITEMSTRUCT16* dis16 = (DRAWITEMSTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1036
            DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT*)HeapAlloc(SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050
                                                                 sizeof(*dis));
            if (!dis) return -1;
            dis->CtlType    = dis16->CtlType;
            dis->CtlID      = dis16->CtlID;
            dis->itemID     = dis16->itemID;
            dis->itemAction = dis16->itemAction;
            dis->itemState  = dis16->itemState;
            dis->hwndItem   = dis16->hwndItem;
            dis->hDC        = dis16->hDC;
            dis->itemData   = dis16->itemData;
            CONV_RECT16TO32( &dis16->rcItem, &dis->rcItem );
            *plparam = (LPARAM)dis;
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1051 1052
    case WM_GETMINMAXINFO:
        {
1053
            MINMAXINFO *mmi = (MINMAXINFO *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1054 1055 1056 1057 1058 1059
                                                sizeof(*mmi) + sizeof(LPARAM));
            if (!mmi) return -1;
            STRUCT32_MINMAXINFO16to32( (MINMAXINFO16*)PTR_SEG_TO_LIN(*plparam),
                                       mmi );
            *(LPARAM *)(mmi + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)mmi;
Alexandre Julliard's avatar
Alexandre Julliard committed
1060
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1061
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1062
    case WM_GETTEXT:
Ove Kaaven's avatar
Ove Kaaven committed
1063
    case WM_SETTEXT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1064 1065
        *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1066 1067 1068 1069
    case WM_MDICREATE:
        {
            MDICREATESTRUCT16 *cs16 =
                (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1070 1071
            MDICREATESTRUCTA *cs =
                (MDICREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1072 1073 1074 1075 1076 1077 1078 1079 1080
                                                sizeof(*cs) + sizeof(LPARAM) );
            if (!cs) return -1;
            STRUCT32_MDICREATESTRUCT16to32A( cs16, cs );
            cs->szTitle = (LPCSTR)PTR_SEG_TO_LIN(cs16->szTitle);
            cs->szClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->szClass);
            *(LPARAM *)(cs + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)cs;
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1081
    case WM_MDIGETACTIVE:
1082 1083
        *plparam = (LPARAM)HeapAlloc( SystemHeap, 0, sizeof(BOOL) );
        *(BOOL*)(*plparam) = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1084
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1085
    case WM_MDISETMENU:
Alexandre Julliard's avatar
Alexandre Julliard committed
1086 1087
        if(wParam16==TRUE)
           *pmsg32=WM_MDIREFRESHMENU;
1088 1089
        *pwparam32 = (WPARAM)(HMENU)LOWORD(*plparam);
        *plparam   = (LPARAM)(HMENU)HIWORD(*plparam);
Alexandre Julliard's avatar
Alexandre Julliard committed
1090
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1091 1092
    case WM_MENUCHAR:
    case WM_MENUSELECT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1093
        *pwparam32 = MAKEWPARAM( wParam16, LOWORD(*plparam) );
1094
        *plparam   = (LPARAM)(HMENU)HIWORD(*plparam);
Alexandre Julliard's avatar
Alexandre Julliard committed
1095
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1096
    case WM_MDIACTIVATE:
Alexandre Julliard's avatar
Alexandre Julliard committed
1097 1098
	if( *plparam )
	{
1099 1100
	    *pwparam32 = (WPARAM)(HWND)HIWORD(*plparam);
	    *plparam   = (LPARAM)(HWND)LOWORD(*plparam);
Alexandre Julliard's avatar
Alexandre Julliard committed
1101 1102 1103
	}
	else /* message sent to MDI client */
	    *pwparam32 = wParam16;
Alexandre Julliard's avatar
Alexandre Julliard committed
1104
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1105 1106
    case WM_NCCALCSIZE:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1107
            NCCALCSIZE_PARAMS16 *nc16;
1108
            NCCALCSIZE_PARAMS *nc;
Alexandre Julliard's avatar
Alexandre Julliard committed
1109

1110
            nc = (NCCALCSIZE_PARAMS *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1111 1112 1113 1114 1115
                                                sizeof(*nc) + sizeof(LPARAM) );
            if (!nc) return -1;
            nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(*plparam);
            CONV_RECT16TO32( &nc16->rgrc[0], &nc->rgrc[0] );
            if (wParam16)
Alexandre Julliard's avatar
Alexandre Julliard committed
1116
            {
1117
                nc->lppos = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1118 1119 1120 1121
                                                      sizeof(*nc->lppos) );
                CONV_RECT16TO32( &nc16->rgrc[1], &nc->rgrc[1] );
                CONV_RECT16TO32( &nc16->rgrc[2], &nc->rgrc[2] );
                if (nc->lppos) STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos), nc->lppos );
Alexandre Julliard's avatar
Alexandre Julliard committed
1122
            }
Alexandre Julliard's avatar
Alexandre Julliard committed
1123 1124
            *(LPARAM *)(nc + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)nc;
Alexandre Julliard's avatar
Alexandre Julliard committed
1125
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1126
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1127 1128 1129
    case WM_NCCREATE:
    case WM_CREATE:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1130
            CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1131
            CREATESTRUCTA *cs = (CREATESTRUCTA *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1132 1133 1134 1135 1136 1137 1138
                                                sizeof(*cs) + sizeof(LPARAM) );
            if (!cs) return -1;
            STRUCT32_CREATESTRUCT16to32A( cs16, cs );
            cs->lpszName  = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszName);
            cs->lpszClass = (LPCSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
            *(LPARAM *)(cs + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)cs;
Alexandre Julliard's avatar
Alexandre Julliard committed
1139
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1140
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1141
    case WM_PARENTNOTIFY:
Alexandre Julliard's avatar
Alexandre Julliard committed
1142 1143 1144
        if ((wParam16 == WM_CREATE) || (wParam16 == WM_DESTROY))
        {
            *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
1145
            *plparam   = (LPARAM)(HWND)LOWORD(*plparam);
Alexandre Julliard's avatar
Alexandre Julliard committed
1146 1147
        }
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1148 1149 1150
    case WM_WINDOWPOSCHANGING:
    case WM_WINDOWPOSCHANGED:
        {
1151
            WINDOWPOS *wp = (WINDOWPOS *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1152 1153 1154 1155 1156 1157
                                                sizeof(*wp) + sizeof(LPARAM) );
            if (!wp) return -1;
            STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(*plparam),
                                      wp );
            *(LPARAM *)(wp + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)wp;
Alexandre Julliard's avatar
Alexandre Julliard committed
1158
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1159
        return 1;
Ove Kaaven's avatar
Ove Kaaven committed
1160
    case WM_GETDLGCODE:
1161
        if (*plparam)
Ove Kaaven's avatar
Ove Kaaven committed
1162 1163
        {
            LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1164
            LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
Ove Kaaven's avatar
Ove Kaaven committed
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178

            if (!msg32) return -1;
            msg32->hwnd = msg16->hwnd;
            msg32->lParam = msg16->lParam;
            msg32->time = msg16->time;
            CONV_POINT16TO32(&msg16->pt,&msg32->pt);
            /* this is right, right? */
            if (WINPROC_MapMsg16To32A(msg16->message,msg16->wParam,
                                     &msg32->message,&msg32->wParam,
                                     &msg32->lParam)<0) {
                HeapFree( SystemHeap, 0, msg32 );
                return -1;
            }
            *plparam = (LPARAM)msg32;
1179
            return 1;
Ove Kaaven's avatar
Ove Kaaven committed
1180
        }
1181
        else return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1182 1183 1184
    case WM_NOTIFY:
    	*plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
    	return 1;
1185 1186 1187 1188 1189 1190 1191
    case WM_ACTIVATEAPP:
    	if (*plparam)
	{ /* We need this when SetActiveWindow sends a Sendmessage16() to
	     a 32bit window. Might be superflous with 32bit interprocess
	     message queues.
	  */
	  HTASK16 htask = (HTASK16) *plparam;
1192
	  DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->teb->tid;
1193 1194 1195
	  *plparam = (LPARAM) idThread;
	}
	return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1196 1197 1198 1199 1200
    case WM_ASKCBFORMATNAME:
    case WM_DEVMODECHANGE:
    case WM_PAINTCLIPBOARD:
    case WM_SIZECLIPBOARD:
    case WM_WININICHANGE:
1201
        FIXME_(msg)("message %04x needs translation\n",msg16 );
Alexandre Julliard's avatar
Alexandre Julliard committed
1202
        return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1203 1204

    default:  /* No translation needed */
Alexandre Julliard's avatar
Alexandre Julliard committed
1205
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1206 1207 1208 1209 1210
    }
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1211
 *	     WINPROC_UnmapMsg16To32A
Alexandre Julliard's avatar
Alexandre Julliard committed
1212
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
1213
 * Unmap a message that was mapped from 16- to 32-bit Ansi.
Alexandre Julliard's avatar
Alexandre Julliard committed
1214
 */
1215
LRESULT WINPROC_UnmapMsg16To32A( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
1216
                                 LRESULT result )
Alexandre Julliard's avatar
Alexandre Julliard committed
1217 1218 1219
{
    switch(msg)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
1220 1221
    case WM_COMPAREITEM:
    case WM_DELETEITEM:
Alexandre Julliard's avatar
Alexandre Julliard committed
1222 1223 1224
    case WM_DRAWITEM:
        HeapFree( SystemHeap, 0, (LPVOID)lParam );
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1225 1226 1227
    case WM_MEASUREITEM:
        {
            MEASUREITEMSTRUCT16 *mis16;
1228
            MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1229 1230 1231 1232 1233 1234 1235
            lParam = *(LPARAM *)(mis + 1);
            mis16 = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(lParam);
            mis16->itemWidth  = (UINT16)mis->itemWidth;
            mis16->itemHeight = (UINT16)mis->itemHeight;
            HeapFree( SystemHeap, 0, mis );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1236 1237
    case WM_GETMINMAXINFO:
        {
1238
            MINMAXINFO *mmi = (MINMAXINFO *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1239 1240 1241 1242 1243 1244
            lParam = *(LPARAM *)(mmi + 1);
            STRUCT32_MINMAXINFO32to16( mmi,
                                       (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam));
            HeapFree( SystemHeap, 0, mmi );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1245 1246
    case WM_MDICREATE:
        {
1247
            MDICREATESTRUCTA *cs = (MDICREATESTRUCTA *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1248 1249 1250 1251 1252 1253
            lParam = *(LPARAM *)(cs + 1);
            STRUCT32_MDICREATESTRUCT32Ato16( cs,
                                 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
            HeapFree( SystemHeap, 0, cs );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1254
    case WM_MDIGETACTIVE:
1255 1256
        result = MAKELONG( LOWORD(result), (BOOL16)(*(BOOL *)lParam) );
        HeapFree( SystemHeap, 0, (BOOL *)lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
1257
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1258 1259 1260
    case WM_NCCALCSIZE:
        {
            NCCALCSIZE_PARAMS16 *nc16;
1261
            NCCALCSIZE_PARAMS *nc = (NCCALCSIZE_PARAMS *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
            lParam = *(LPARAM *)(nc + 1);
            nc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam);
            CONV_RECT32TO16( &nc->rgrc[0], &nc16->rgrc[0] );
            if (wParam)
            {
                CONV_RECT32TO16( &nc->rgrc[1], &nc16->rgrc[1] );
                CONV_RECT32TO16( &nc->rgrc[2], &nc16->rgrc[2] );
                if (nc->lppos)
                {
                    STRUCT32_WINDOWPOS32to16( nc->lppos,
                                   (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc16->lppos));
                    HeapFree( SystemHeap, 0, nc->lppos );
                }
            }
            HeapFree( SystemHeap, 0, nc );
        }
	break;
    case WM_NCCREATE:
    case WM_CREATE:
        {
1282
            CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1283 1284 1285 1286 1287 1288 1289 1290 1291
            lParam = *(LPARAM *)(cs + 1);
            STRUCT32_CREATESTRUCT32Ato16( cs,
                                    (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
            HeapFree( SystemHeap, 0, cs );
        }
        break;
    case WM_WINDOWPOSCHANGING:
    case WM_WINDOWPOSCHANGED:
        {
1292
            WINDOWPOS *wp = (WINDOWPOS *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1293 1294 1295 1296 1297
            lParam = *(LPARAM *)(wp + 1);
            STRUCT32_WINDOWPOS32to16(wp,(WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam));
            HeapFree( SystemHeap, 0, wp );
        }
        break;
Ove Kaaven's avatar
Ove Kaaven committed
1298
    case WM_GETDLGCODE:
1299
        if (lParam)
Ove Kaaven's avatar
Ove Kaaven committed
1300
        {
1301
            LPMSG msg32 = (LPMSG)lParam;
Ove Kaaven's avatar
Ove Kaaven committed
1302

1303
            WINPROC_UnmapMsg16To32A( hwnd, msg32->message, msg32->wParam, msg32->lParam,
Ove Kaaven's avatar
Ove Kaaven committed
1304 1305 1306 1307
                                     result);
            HeapFree( SystemHeap, 0, msg32 );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1308
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
1309
    return result;
Alexandre Julliard's avatar
Alexandre Julliard committed
1310 1311 1312 1313 1314 1315 1316 1317 1318
}


/**********************************************************************
 *	     WINPROC_MapMsg16To32W
 *
 * Map a message from 16- to 32-bit Unicode.
 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
 */
1319 1320
INT WINPROC_MapMsg16To32W( HWND16 hwnd, UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32,
                             WPARAM *pwparam32, LPARAM *plparam )
Alexandre Julliard's avatar
Alexandre Julliard committed
1321 1322 1323
{
    switch(msg16)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
1324 1325
    case WM_GETTEXT:
    case WM_SETTEXT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1326
        *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
1327
        return WINPROC_MapMsg32ATo32W( hwnd, *pmsg32, *pwparam32, plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
1328 1329 1330
    case WM_NCCREATE:
    case WM_CREATE:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1331
            CREATESTRUCT16 *cs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1332
            CREATESTRUCTW *cs = (CREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1333 1334
                                                sizeof(*cs) + sizeof(LPARAM) );
            if (!cs) return -1;
1335
            STRUCT32_CREATESTRUCT16to32A( cs16, (CREATESTRUCTA *)cs );
Alexandre Julliard's avatar
Alexandre Julliard committed
1336 1337 1338
            cs->lpszName  = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszName);
            cs->lpszClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->lpszClass);
            if (HIWORD(cs->lpszName))
Alexandre Julliard's avatar
Alexandre Julliard committed
1339 1340
                cs->lpszName = HEAP_strdupAtoW( SystemHeap, 0,
                                                (LPCSTR)cs->lpszName );
Alexandre Julliard's avatar
Alexandre Julliard committed
1341
            if (HIWORD(cs->lpszClass))
Alexandre Julliard's avatar
Alexandre Julliard committed
1342 1343
                cs->lpszClass = HEAP_strdupAtoW( SystemHeap, 0,
                                                 (LPCSTR)cs->lpszClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
1344 1345
            *(LPARAM *)(cs + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)cs;
Alexandre Julliard's avatar
Alexandre Julliard committed
1346
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1347
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1348 1349 1350 1351
    case WM_MDICREATE:
        {
            MDICREATESTRUCT16 *cs16 =
                (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(*plparam);
1352 1353
            MDICREATESTRUCTW *cs =
                (MDICREATESTRUCTW *)HeapAlloc( SystemHeap, 0,
Alexandre Julliard's avatar
Alexandre Julliard committed
1354 1355
                                                sizeof(*cs) + sizeof(LPARAM) );
            if (!cs) return -1;
1356
            STRUCT32_MDICREATESTRUCT16to32A( cs16, (MDICREATESTRUCTA *)cs );
Alexandre Julliard's avatar
Alexandre Julliard committed
1357 1358 1359
            cs->szTitle = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szTitle);
            cs->szClass = (LPCWSTR)PTR_SEG_TO_LIN(cs16->szClass);
            if (HIWORD(cs->szTitle))
Alexandre Julliard's avatar
Alexandre Julliard committed
1360 1361
                cs->szTitle = HEAP_strdupAtoW( SystemHeap, 0,
                                               (LPCSTR)cs->szTitle );
Alexandre Julliard's avatar
Alexandre Julliard committed
1362
            if (HIWORD(cs->szClass))
Alexandre Julliard's avatar
Alexandre Julliard committed
1363 1364
                cs->szClass = HEAP_strdupAtoW( SystemHeap, 0,
                                               (LPCSTR)cs->szClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
1365 1366 1367 1368
            *(LPARAM *)(cs + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)cs;
        }
        return 1;
Ove Kaaven's avatar
Ove Kaaven committed
1369
    case WM_GETDLGCODE:
1370
        if (*plparam)
Ove Kaaven's avatar
Ove Kaaven committed
1371 1372
        {
            LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(*plparam);
1373
            LPMSG msg32 = (LPMSG)HeapAlloc( SystemHeap, 0, sizeof(MSG) );
Ove Kaaven's avatar
Ove Kaaven committed
1374 1375 1376 1377 1378 1379 1380

            if (!msg32) return -1;
            msg32->hwnd = msg16->hwnd;
            msg32->lParam = msg16->lParam;
            msg32->time = msg16->time;
            CONV_POINT16TO32(&msg16->pt,&msg32->pt);
            /* this is right, right? */
1381
            if (WINPROC_MapMsg16To32W(hwnd, msg16->message,msg16->wParam,
Ove Kaaven's avatar
Ove Kaaven committed
1382 1383 1384 1385 1386 1387
                                     &msg32->message,&msg32->wParam,
                                     &msg32->lParam)<0) {
                HeapFree( SystemHeap, 0, msg32 );
                return -1;
            }
            *plparam = (LPARAM)msg32;
1388
            return 1;
Ove Kaaven's avatar
Ove Kaaven committed
1389
        }
1390
        else return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1391
    default:  /* No Unicode translation needed */
Alexandre Julliard's avatar
Alexandre Julliard committed
1392 1393
        return WINPROC_MapMsg16To32A( msg16, wParam16, pmsg32,
                                      pwparam32, plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
1394 1395 1396 1397 1398
    }
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1399
 *	     WINPROC_UnmapMsg16To32W
Alexandre Julliard's avatar
Alexandre Julliard committed
1400
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
1401
 * Unmap a message that was mapped from 16- to 32-bit Unicode.
Alexandre Julliard's avatar
Alexandre Julliard committed
1402
 */
1403
LRESULT WINPROC_UnmapMsg16To32W( HWND16 hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
1404
                                 LRESULT result )
Alexandre Julliard's avatar
Alexandre Julliard committed
1405 1406 1407
{
    switch(msg)
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
1408 1409
    case WM_GETTEXT:
    case WM_SETTEXT:
1410
        WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
1411 1412 1413 1414
        break;
    case WM_NCCREATE:
    case WM_CREATE:
        {
1415
            CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1416
            lParam = *(LPARAM *)(cs + 1);
1417
            STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs,
Alexandre Julliard's avatar
Alexandre Julliard committed
1418
                                    (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
Alexandre Julliard's avatar
Alexandre Julliard committed
1419 1420 1421 1422
            if (HIWORD(cs->lpszName))
                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszName );
            if (HIWORD(cs->lpszClass))
                HeapFree( SystemHeap, 0, (LPVOID)cs->lpszClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
1423 1424 1425
            HeapFree( SystemHeap, 0, cs );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1426 1427
    case WM_MDICREATE:
        {
1428
            MDICREATESTRUCTW *cs = (MDICREATESTRUCTW *)lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1429
            lParam = *(LPARAM *)(cs + 1);
1430
            STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs,
Alexandre Julliard's avatar
Alexandre Julliard committed
1431
                                 (MDICREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam) );
Alexandre Julliard's avatar
Alexandre Julliard committed
1432 1433 1434 1435
            if (HIWORD(cs->szTitle))
                HeapFree( SystemHeap, 0, (LPVOID)cs->szTitle );
            if (HIWORD(cs->szClass))
                HeapFree( SystemHeap, 0, (LPVOID)cs->szClass );
Alexandre Julliard's avatar
Alexandre Julliard committed
1436 1437 1438
            HeapFree( SystemHeap, 0, cs );
        }
        break;
Ove Kaaven's avatar
Ove Kaaven committed
1439
    case WM_GETDLGCODE:
1440
        if (lParam)
Ove Kaaven's avatar
Ove Kaaven committed
1441
        {
1442
            LPMSG msg32 = (LPMSG)lParam;
Ove Kaaven's avatar
Ove Kaaven committed
1443

1444
            WINPROC_UnmapMsg16To32W( hwnd, msg32->message, msg32->wParam, msg32->lParam,
Ove Kaaven's avatar
Ove Kaaven committed
1445 1446 1447 1448
                                     result);
            HeapFree( SystemHeap, 0, msg32 );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1449
    default:
1450
        return WINPROC_UnmapMsg16To32A( hwnd, msg, wParam, lParam, result );
Alexandre Julliard's avatar
Alexandre Julliard committed
1451
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
1452
    return result;
Alexandre Julliard's avatar
Alexandre Julliard committed
1453 1454 1455 1456 1457 1458 1459 1460 1461
}


/**********************************************************************
 *	     WINPROC_MapMsg32ATo16
 *
 * Map a message from 32-bit Ansi to 16-bit.
 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
 */
1462
INT WINPROC_MapMsg32ATo16( HWND hwnd, UINT msg32, WPARAM wParam32,
Alexandre Julliard's avatar
Alexandre Julliard committed
1463 1464
                             UINT16 *pmsg16, WPARAM16 *pwparam16,
                             LPARAM *plparam )
Alexandre Julliard's avatar
Alexandre Julliard committed
1465 1466 1467 1468 1469
{
    *pmsg16 = (UINT16)msg32;
    *pwparam16 = (WPARAM16)LOWORD(wParam32);
    switch(msg32)
    {
1470 1471 1472 1473 1474 1475
    case BM_GETCHECK:
    case BM_SETCHECK:
    case BM_GETSTATE:
    case BM_SETSTATE:
    case BM_SETSTYLE:
        *pmsg16 = (UINT16)msg32 + (BM_GETCHECK16 - BM_GETCHECK);
Alexandre Julliard's avatar
Alexandre Julliard committed
1476
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1477

1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
    case EM_GETSEL:
    case EM_GETRECT:
    case EM_SETRECT:
    case EM_SETRECTNP:
    case EM_SCROLL:
    case EM_LINESCROLL:
    case EM_SCROLLCARET:
    case EM_GETMODIFY:
    case EM_SETMODIFY:
    case EM_GETLINECOUNT:
    case EM_LINEINDEX:
    case EM_SETHANDLE:
    case EM_GETHANDLE:
    case EM_GETTHUMB:
    case EM_LINELENGTH:
    case EM_REPLACESEL:
    case EM_GETLINE:
    case EM_LIMITTEXT:
    case EM_CANUNDO:
    case EM_UNDO:
    case EM_FMTLINES:
    case EM_LINEFROMCHAR:
    case EM_SETTABSTOPS:
    case EM_SETPASSWORDCHAR:
    case EM_EMPTYUNDOBUFFER:
    case EM_GETFIRSTVISIBLELINE:
    case EM_SETREADONLY:
    case EM_SETWORDBREAKPROC:
    case EM_GETWORDBREAKPROC:
    case EM_GETPASSWORDCHAR:
        *pmsg16 = (UINT16)msg32 + (EM_GETSEL16 - EM_GETSEL);
Alexandre Julliard's avatar
Alexandre Julliard committed
1509 1510
        return 0;

1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537
    case LB_CARETOFF:
    case LB_CARETON:
    case LB_DELETESTRING:
    case LB_GETANCHORINDEX:
    case LB_GETCARETINDEX:
    case LB_GETCOUNT:
    case LB_GETCURSEL:
    case LB_GETHORIZONTALEXTENT:
    case LB_GETITEMDATA:
    case LB_GETITEMHEIGHT:
    case LB_GETSEL:
    case LB_GETSELCOUNT:
    case LB_GETTEXTLEN:
    case LB_GETTOPINDEX:
    case LB_RESETCONTENT:
    case LB_SELITEMRANGE:
    case LB_SELITEMRANGEEX:
    case LB_SETANCHORINDEX:
    case LB_SETCARETINDEX:
    case LB_SETCOLUMNWIDTH:
    case LB_SETCURSEL:
    case LB_SETHORIZONTALEXTENT:
    case LB_SETITEMDATA:
    case LB_SETITEMHEIGHT:
    case LB_SETSEL:
    case LB_SETTOPINDEX:
        *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
Alexandre Julliard's avatar
Alexandre Julliard committed
1538
        return 0;
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
    case CB_DELETESTRING:
    case CB_GETCOUNT:
    case CB_GETLBTEXTLEN:
    case CB_LIMITTEXT:
    case CB_RESETCONTENT:
    case CB_SETEDITSEL:
    case CB_GETCURSEL:
    case CB_SETCURSEL:
    case CB_SHOWDROPDOWN:
    case CB_SETITEMDATA:
    case CB_SETITEMHEIGHT:
    case CB_GETITEMHEIGHT:
    case CB_SETEXTENDEDUI:
    case CB_GETEXTENDEDUI:
    case CB_GETDROPPEDSTATE:
	*pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
Alexandre Julliard's avatar
Alexandre Julliard committed
1555
	return 0;
1556
    case CB_GETEDITSEL:
Alexandre Julliard's avatar
Alexandre Julliard committed
1557 1558 1559
	*pmsg16 = CB_GETEDITSEL16;
	return 1;

1560 1561 1562 1563 1564 1565 1566
    case LB_ADDSTRING:
    case LB_FINDSTRING:
    case LB_FINDSTRINGEXACT:
    case LB_INSERTSTRING:
    case LB_SELECTSTRING:
    case LB_DIR:
    case LB_ADDFILE:
Alexandre Julliard's avatar
Alexandre Julliard committed
1567 1568 1569 1570 1571
        {
            LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
            if (!str) return -1;
            *plparam = (LPARAM)SEGPTR_GET(str);
        }
1572
        *pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
Alexandre Julliard's avatar
Alexandre Julliard committed
1573
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1574

1575 1576 1577 1578 1579 1580
    case CB_ADDSTRING:
    case CB_FINDSTRING:
    case CB_FINDSTRINGEXACT:
    case CB_INSERTSTRING:
    case CB_SELECTSTRING:
    case CB_DIR:
Alexandre Julliard's avatar
Alexandre Julliard committed
1581 1582 1583 1584 1585
	{
	    LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
	    if (!str) return -1;
	    *plparam = (LPARAM)SEGPTR_GET(str);
	}
1586
	*pmsg16 = (UINT16)msg32 + (CB_GETEDITSEL16 - CB_GETEDITSEL);
Alexandre Julliard's avatar
Alexandre Julliard committed
1587 1588
	return 1;

1589
    case LB_GETITEMRECT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1590 1591 1592 1593 1594 1595 1596
        {
            RECT16 *rect;
            rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
            if (!rect) return -1;
            *(LPARAM *)(rect + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)SEGPTR_GET(rect);
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1597
	*pmsg16 = LB_GETITEMRECT16;
Alexandre Julliard's avatar
Alexandre Julliard committed
1598
        return 1;
1599
    case LB_GETSELITEMS:
Alexandre Julliard's avatar
Alexandre Julliard committed
1600 1601 1602 1603 1604 1605 1606 1607
        {
            LPINT16 items;
            *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
            if (!(items = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
                                        + sizeof(LPARAM)))) return -1;
            *((LPARAM *)items)++ = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)SEGPTR_GET(items);
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1608
	*pmsg16 = LB_GETSELITEMS16;
Alexandre Julliard's avatar
Alexandre Julliard committed
1609
        return 1;
1610
    case LB_SETTABSTOPS:
Alexandre Julliard's avatar
Alexandre Julliard committed
1611 1612
        if (wParam32)
        {
1613
            INT i;
Alexandre Julliard's avatar
Alexandre Julliard committed
1614 1615 1616 1617
            LPINT16 stops;
            *pwparam16 = (WPARAM16)MIN( wParam32, 0x7f80 ); /* Must be < 64K */
            if (!(stops = SEGPTR_ALLOC( *pwparam16 * sizeof(INT16)
                                        + sizeof(LPARAM)))) return -1;
1618
            for (i = 0; i < *pwparam16; i++) stops[i] = *((LPINT)*plparam+i);
Alexandre Julliard's avatar
Alexandre Julliard committed
1619 1620 1621 1622 1623
            *plparam = (LPARAM)SEGPTR_GET(stops);
            return 1;
        }
        *pmsg16 = LB_SETTABSTOPS16;
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1624

1625
    case CB_GETDROPPEDCONTROLRECT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1626 1627 1628 1629 1630 1631 1632 1633 1634 1635
        {
	    RECT16 *rect;
	    rect = (RECT16 *)SEGPTR_ALLOC( sizeof(RECT16) + sizeof(LPARAM) );
	    if (!rect) return -1;
	    *(LPARAM *)(rect + 1) = *plparam;  /* Store the previous lParam */
	    *plparam = (LPARAM)SEGPTR_GET(rect);
        }
	*pmsg16 = CB_GETDROPPEDCONTROLRECT16;
        return 1;

1636
    case LB_GETTEXT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1637 1638 1639 1640
	*plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
	*pmsg16 = LB_GETTEXT16;
	return 1;

1641
    case CB_GETLBTEXT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1642 1643 1644 1645
	*plparam = (LPARAM)MapLS( (LPVOID)(*plparam) );
	*pmsg16 = CB_GETLBTEXT16;
	return 1;

1646
    case EM_SETSEL:
Alexandre Julliard's avatar
Alexandre Julliard committed
1647
	*pwparam16 = 0;
1648
	*plparam = MAKELONG( (INT16)(INT)wParam32, (INT16)*plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
1649 1650 1651
	*pmsg16 = EM_SETSEL16;
	return 0;

Alexandre Julliard's avatar
Alexandre Julliard committed
1652 1653 1654 1655
    case WM_ACTIVATE:
    case WM_CHARTOITEM:
    case WM_COMMAND:
    case WM_VKEYTOITEM:
Alexandre Julliard's avatar
Alexandre Julliard committed
1656 1657
        *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32) );
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1658 1659 1660 1661
    case WM_HSCROLL:
    case WM_VSCROLL:
        *plparam = MAKELPARAM( HIWORD(wParam32), (HWND16)*plparam );
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1662 1663 1664 1665 1666 1667 1668
    case WM_CTLCOLORMSGBOX:
    case WM_CTLCOLOREDIT:
    case WM_CTLCOLORLISTBOX:
    case WM_CTLCOLORBTN:
    case WM_CTLCOLORDLG:
    case WM_CTLCOLORSCROLLBAR:
    case WM_CTLCOLORSTATIC:
Alexandre Julliard's avatar
Alexandre Julliard committed
1669 1670 1671 1672
        *pmsg16  = WM_CTLCOLOR;
        *plparam = MAKELPARAM( (HWND16)*plparam,
                               (WORD)msg32 - WM_CTLCOLORMSGBOX );
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1673 1674
    case WM_COMPAREITEM:
        {
1675
            COMPAREITEMSTRUCT *cis32 = (COMPAREITEMSTRUCT *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689
            COMPAREITEMSTRUCT16 *cis = SEGPTR_NEW(COMPAREITEMSTRUCT16);
            if (!cis) return -1;
            cis->CtlType    = (UINT16)cis32->CtlType;
            cis->CtlID      = (UINT16)cis32->CtlID;
            cis->hwndItem   = (HWND16)cis32->hwndItem;
            cis->itemID1    = (UINT16)cis32->itemID1;
            cis->itemData1  = cis32->itemData1;
            cis->itemID2    = (UINT16)cis32->itemID2;
            cis->itemData2  = cis32->itemData2;
            *plparam = (LPARAM)SEGPTR_GET(cis);
        }
        return 1;
    case WM_DELETEITEM:
        {
1690
            DELETEITEMSTRUCT *dis32 = (DELETEITEMSTRUCT *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
            DELETEITEMSTRUCT16 *dis = SEGPTR_NEW(DELETEITEMSTRUCT16);
            if (!dis) return -1;
            dis->CtlType  = (UINT16)dis32->CtlType;
            dis->CtlID    = (UINT16)dis32->CtlID;
            dis->itemID   = (UINT16)dis32->itemID;
            dis->hwndItem = (HWND16)dis32->hwndItem;
            dis->itemData = dis32->itemData;
            *plparam = (LPARAM)SEGPTR_GET(dis);
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1701 1702
    case WM_DRAWITEM:
        {
1703
            DRAWITEMSTRUCT *dis32 = (DRAWITEMSTRUCT *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1704
            DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16);
Alexandre Julliard's avatar
Alexandre Julliard committed
1705
            if (!dis) return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1706 1707 1708 1709 1710 1711 1712 1713 1714
            dis->CtlType    = (UINT16)dis32->CtlType;
            dis->CtlID      = (UINT16)dis32->CtlID;
            dis->itemID     = (UINT16)dis32->itemID;
            dis->itemAction = (UINT16)dis32->itemAction;
            dis->itemState  = (UINT16)dis32->itemState;
            dis->hwndItem   = (HWND16)dis32->hwndItem;
            dis->hDC        = (HDC16)dis32->hDC;
            dis->itemData   = dis32->itemData;
            CONV_RECT32TO16( &dis32->rcItem, &dis->rcItem );
Alexandre Julliard's avatar
Alexandre Julliard committed
1715
            *plparam = (LPARAM)SEGPTR_GET(dis);
Alexandre Julliard's avatar
Alexandre Julliard committed
1716
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1717
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1718 1719
    case WM_MEASUREITEM:
        {
1720
            MEASUREITEMSTRUCT *mis32 = (MEASUREITEMSTRUCT *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733
            MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)
                                     SEGPTR_ALLOC(sizeof(*mis)+sizeof(LPARAM));
            if (!mis) return -1;
            mis->CtlType    = (UINT16)mis32->CtlType;
            mis->CtlID      = (UINT16)mis32->CtlID;
            mis->itemID     = (UINT16)mis32->itemID;
            mis->itemWidth  = (UINT16)mis32->itemWidth;
            mis->itemHeight = (UINT16)mis32->itemHeight;
            mis->itemData   = mis32->itemData;
            *(LPARAM *)(mis + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)SEGPTR_GET(mis);
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1734 1735
    case WM_GETMINMAXINFO:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1736 1737 1738
            MINMAXINFO16 *mmi = (MINMAXINFO16 *)SEGPTR_ALLOC( sizeof(*mmi) +
                                                              sizeof(LPARAM) );
            if (!mmi) return -1;
1739
            STRUCT32_MINMAXINFO32to16( (MINMAXINFO *)*plparam, mmi );
Alexandre Julliard's avatar
Alexandre Julliard committed
1740 1741
            *(LPARAM *)(mmi + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)SEGPTR_GET(mmi);
Alexandre Julliard's avatar
Alexandre Julliard committed
1742
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1743
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1744 1745 1746
    case WM_GETTEXT:
        {
            LPSTR str;
Alexandre Julliard's avatar
Alexandre Julliard committed
1747 1748 1749 1750
            *pwparam16 = (WPARAM16)MIN( wParam32, 0xff80 ); /* Must be < 64K */
            if (!(str = SEGPTR_ALLOC(*pwparam16 + sizeof(LPARAM)))) return -1;
            *((LPARAM *)str)++ = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)SEGPTR_GET(str);
Alexandre Julliard's avatar
Alexandre Julliard committed
1751
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1752
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1753 1754 1755
    case WM_MDICREATE:
        {
            MDICREATESTRUCT16 *cs;
1756
            MDICREATESTRUCTA *cs32 = (MDICREATESTRUCTA *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767
            LPSTR name, cls;

            if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
            STRUCT32_MDICREATESTRUCT32Ato16( cs32, cs );
            name = SEGPTR_STRDUP( cs32->szTitle );
            cls  = SEGPTR_STRDUP( cs32->szClass );
            cs->szTitle = SEGPTR_GET(name);
            cs->szClass = SEGPTR_GET(cls);
            *plparam = (LPARAM)SEGPTR_GET(cs);
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1768 1769
    case WM_MDIGETACTIVE:
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1770
    case WM_MDISETMENU:
Alexandre Julliard's avatar
Alexandre Julliard committed
1771 1772
        *plparam   = MAKELPARAM( (HMENU16)LOWORD(wParam32),
                                 (HMENU16)LOWORD(*plparam) );
Alexandre Julliard's avatar
Alexandre Julliard committed
1773
        *pwparam16 = (*plparam == 0);
Alexandre Julliard's avatar
Alexandre Julliard committed
1774
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1775 1776
    case WM_MENUCHAR:
    case WM_MENUSELECT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1777 1778
        *plparam = MAKELPARAM( HIWORD(wParam32), (HMENU16)*plparam );
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1779
    case WM_MDIACTIVATE:
Alexandre Julliard's avatar
Alexandre Julliard committed
1780
	{
1781 1782 1783
            WND *tempWnd = WIN_FindWndPtr(hwnd);
            if( WIDGETS_IsControl(tempWnd, BIC32_MDICLIENT) )
            {
1784
	    *pwparam16 = (HWND)wParam32;
Alexandre Julliard's avatar
Alexandre Julliard committed
1785 1786 1787 1788
	    *plparam = 0;
	}
	else
	{
1789
	    *pwparam16 = ((HWND)*plparam == hwnd);
Alexandre Julliard's avatar
Alexandre Julliard committed
1790 1791 1792
	    *plparam = MAKELPARAM( (HWND16)LOWORD(*plparam),
				   (HWND16)LOWORD(wParam32) );
	}
1793 1794
            WIN_ReleaseWndPtr(tempWnd);
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1795
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1796 1797
    case WM_NCCALCSIZE:
        {
1798
            NCCALCSIZE_PARAMS *nc32 = (NCCALCSIZE_PARAMS *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1799 1800
            NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)SEGPTR_ALLOC( sizeof(*nc) + sizeof(LPARAM) );
            if (!nc) return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1801 1802

            CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] );
Alexandre Julliard's avatar
Alexandre Julliard committed
1803
            if (wParam32)
Alexandre Julliard's avatar
Alexandre Julliard committed
1804
            {
Alexandre Julliard's avatar
Alexandre Julliard committed
1805
                WINDOWPOS16 *wp;
Alexandre Julliard's avatar
Alexandre Julliard committed
1806 1807 1808 1809 1810
                CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] );
                CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] );
                if (!(wp = SEGPTR_NEW(WINDOWPOS16)))
                {
                    SEGPTR_FREE(nc);
Alexandre Julliard's avatar
Alexandre Julliard committed
1811
                    return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1812 1813 1814 1815
                }
                STRUCT32_WINDOWPOS32to16( nc32->lppos, wp );
                nc->lppos = SEGPTR_GET(wp);
            }
Alexandre Julliard's avatar
Alexandre Julliard committed
1816 1817
            *(LPARAM *)(nc + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)SEGPTR_GET(nc);
Alexandre Julliard's avatar
Alexandre Julliard committed
1818
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1819
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1820 1821 1822 1823
    case WM_NCCREATE:
    case WM_CREATE:
        {
            CREATESTRUCT16 *cs;
1824
            CREATESTRUCTA *cs32 = (CREATESTRUCTA *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
1825 1826
            LPSTR name, cls;

Alexandre Julliard's avatar
Alexandre Julliard committed
1827
            if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1828 1829 1830 1831 1832
            STRUCT32_CREATESTRUCT32Ato16( cs32, cs );
            name = SEGPTR_STRDUP( cs32->lpszName );
            cls  = SEGPTR_STRDUP( cs32->lpszClass );
            cs->lpszName  = SEGPTR_GET(name);
            cs->lpszClass = SEGPTR_GET(cls);
Alexandre Julliard's avatar
Alexandre Julliard committed
1833
            *plparam = (LPARAM)SEGPTR_GET(cs);
Alexandre Julliard's avatar
Alexandre Julliard committed
1834
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1835
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1836
    case WM_PARENTNOTIFY:
Alexandre Julliard's avatar
Alexandre Julliard committed
1837 1838 1839 1840
        if ((LOWORD(wParam32)==WM_CREATE) || (LOWORD(wParam32)==WM_DESTROY))
            *plparam = MAKELPARAM( (HWND16)*plparam, HIWORD(wParam32));
        /* else nothing to do */
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1841 1842 1843
    case WM_NOTIFY:
	*plparam = MapLS( (NMHDR *)*plparam ); /* NMHDR is already 32-bit */
	return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1844 1845
    case WM_SETTEXT:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1846 1847 1848
            LPSTR str = SEGPTR_STRDUP( (LPSTR)*plparam );
            if (!str) return -1;
            *plparam = (LPARAM)SEGPTR_GET(str);
Alexandre Julliard's avatar
Alexandre Julliard committed
1849
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1850
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1851 1852 1853
    case WM_WINDOWPOSCHANGING:
    case WM_WINDOWPOSCHANGED:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1854 1855 1856
            WINDOWPOS16 *wp = (WINDOWPOS16 *)SEGPTR_ALLOC( sizeof(*wp) +
                                                           sizeof(LPARAM) );
            if (!wp) return -1;
1857
            STRUCT32_WINDOWPOS32to16( (WINDOWPOS *)*plparam, wp );
Alexandre Julliard's avatar
Alexandre Julliard committed
1858 1859
            *(LPARAM *)(wp + 1) = *plparam;  /* Store the previous lParam */
            *plparam = (LPARAM)SEGPTR_GET(wp);
Alexandre Julliard's avatar
Alexandre Julliard committed
1860
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1861
        return 1;
1862 1863
    case WM_GETDLGCODE:
         if (*plparam) {
1864
            LPMSG msg32 = (LPMSG) *plparam;
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882
            LPMSG16 msg16 = (LPMSG16) SEGPTR_NEW( MSG16 );

            if (!msg16) return -1;
            msg16->hwnd = msg32->hwnd;
            msg16->lParam = msg32->lParam;
            msg16->time = msg32->time;
            CONV_POINT32TO16(&msg32->pt,&msg16->pt);
            /* this is right, right? */
            if (WINPROC_MapMsg32ATo16(msg32->hwnd,msg32->message,msg32->wParam,
                         &msg16->message,&msg16->wParam, &msg16->lParam)<0) {
                SEGPTR_FREE( msg16 );
                return -1;
            }
            *plparam = (LPARAM)SEGPTR_GET(msg16);
            return 1;
        }
        return 0;

1883
    case WM_ACTIVATEAPP:
1884
	if (*plparam) {
1885
	*plparam = (LPARAM)THREAD_IdToTEB((DWORD) *plparam)->htask16;
1886 1887
	}
	return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1888 1889 1890 1891 1892
    case WM_ASKCBFORMATNAME:
    case WM_DEVMODECHANGE:
    case WM_PAINTCLIPBOARD:
    case WM_SIZECLIPBOARD:
    case WM_WININICHANGE:
1893
        FIXME_(msg)("message %04x needs translation\n", msg32 );
Alexandre Julliard's avatar
Alexandre Julliard committed
1894
        return -1;
Alexandre Julliard's avatar
Alexandre Julliard committed
1895
    default:  /* No translation needed */
Alexandre Julliard's avatar
Alexandre Julliard committed
1896
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1897 1898 1899 1900
    }
}


Alexandre Julliard's avatar
Alexandre Julliard committed
1901
/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
1902
 *	     WINPROC_UnmapMsg32ATo16
Alexandre Julliard's avatar
Alexandre Julliard committed
1903
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
1904
 * Unmap a message that was mapped from 32-bit Ansi to 16-bit.
Alexandre Julliard's avatar
Alexandre Julliard committed
1905
 */
1906
void WINPROC_UnmapMsg32ATo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
1907
                              MSGPARAM16* p16 ) 
Alexandre Julliard's avatar
Alexandre Julliard committed
1908 1909 1910
{
    switch(msg)
    {
1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924
    case LB_ADDFILE:
    case LB_ADDSTRING:
    case LB_DIR:
    case LB_FINDSTRING:
    case LB_FINDSTRINGEXACT:
    case LB_INSERTSTRING:
    case LB_SELECTSTRING:
    case LB_SETTABSTOPS:
    case CB_ADDSTRING:
    case CB_FINDSTRING:
    case CB_FINDSTRINGEXACT:
    case CB_INSERTSTRING:
    case CB_SELECTSTRING:
    case CB_DIR:
Alexandre Julliard's avatar
Alexandre Julliard committed
1925 1926
    case WM_COMPAREITEM:
    case WM_DELETEITEM:
Alexandre Julliard's avatar
Alexandre Julliard committed
1927
    case WM_DRAWITEM:
Alexandre Julliard's avatar
Alexandre Julliard committed
1928
    case WM_SETTEXT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1929
        SEGPTR_FREE( PTR_SEG_TO_LIN(p16->lParam) );
Alexandre Julliard's avatar
Alexandre Julliard committed
1930
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1931

1932 1933
    case CB_GETDROPPEDCONTROLRECT:
    case LB_GETITEMRECT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1934
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1935 1936
            RECT16 *rect = (RECT16 *)PTR_SEG_TO_LIN(p16->lParam);
            p16->lParam = *(LPARAM *)(rect + 1);
1937
            CONV_RECT16TO32( rect, (RECT *)(p16->lParam));
Alexandre Julliard's avatar
Alexandre Julliard committed
1938 1939 1940
            SEGPTR_FREE( rect );
        }
        break;
1941
    case LB_GETSELITEMS:
Alexandre Julliard's avatar
Alexandre Julliard committed
1942
        {
1943
            INT i;
Alexandre Julliard's avatar
Alexandre Julliard committed
1944
            LPINT16 items = (LPINT16)PTR_SEG_TO_LIN(lParam);
Alexandre Julliard's avatar
Alexandre Julliard committed
1945
            p16->lParam = *((LPARAM *)items - 1);
1946
            for (i = 0; i < p16->wParam; i++) *((LPINT)(p16->lParam) + i) = items[i];
Alexandre Julliard's avatar
Alexandre Julliard committed
1947 1948 1949
            SEGPTR_FREE( (LPARAM *)items - 1 );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1950

1951
    case CB_GETEDITSEL:
Alexandre Julliard's avatar
Alexandre Julliard committed
1952
	if( wParam )
1953
	    *((LPUINT)(wParam)) = LOWORD(p16->lResult);
Alexandre Julliard's avatar
Alexandre Julliard committed
1954
	if( lParam )
1955
	    *((LPUINT)(lParam)) = HIWORD(p16->lResult);	/* FIXME: substract 1? */
Alexandre Julliard's avatar
Alexandre Julliard committed
1956 1957
	break;

1958 1959
    case LB_GETTEXT:
    case CB_GETLBTEXT:
Alexandre Julliard's avatar
Alexandre Julliard committed
1960
	UnMapLS( (SEGPTR)(p16->lParam) );
Alexandre Julliard's avatar
Alexandre Julliard committed
1961 1962
	break;

Alexandre Julliard's avatar
Alexandre Julliard committed
1963 1964
    case WM_MEASUREITEM:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1965
            MEASUREITEMSTRUCT16 *mis = (MEASUREITEMSTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
1966
            MEASUREITEMSTRUCT *mis32 = *(MEASUREITEMSTRUCT **)(mis + 1);
Alexandre Julliard's avatar
Alexandre Julliard committed
1967 1968 1969 1970 1971
            mis32->itemWidth  = mis->itemWidth;
            mis32->itemHeight = mis->itemHeight;
            SEGPTR_FREE(mis);
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1972 1973
    case WM_GETMINMAXINFO:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1974 1975
            MINMAXINFO16 *mmi = (MINMAXINFO16 *)PTR_SEG_TO_LIN(p16->lParam);
            p16->lParam = *(LPARAM *)(mmi + 1);
1976
            STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO *)(p16->lParam) );
Alexandre Julliard's avatar
Alexandre Julliard committed
1977 1978 1979
            SEGPTR_FREE(mmi);
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1980 1981
    case WM_GETTEXT:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1982 1983
            LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
            p16->lParam = *((LPARAM *)str - 1);
1984
            lstrcpynA( (LPSTR)(p16->lParam), str, p16->wParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
1985
            SEGPTR_FREE( (LPARAM *)str - 1 );
Alexandre Julliard's avatar
Alexandre Julliard committed
1986
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
1987
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1988 1989
    case WM_MDICREATE:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
1990
            MDICREATESTRUCT16 *cs = (MDICREATESTRUCT16*)PTR_SEG_TO_LIN(p16->lParam);
Alexandre Julliard's avatar
Alexandre Julliard committed
1991 1992 1993 1994 1995
            SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szTitle) );
            SEGPTR_FREE( PTR_SEG_TO_LIN(cs->szClass) );
            SEGPTR_FREE( cs );
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
1996
    case WM_MDIGETACTIVE:
1997 1998
        if (lParam) *(BOOL *)lParam = (BOOL16)HIWORD(p16->lResult);
        p16->lResult = (HWND)LOWORD(p16->lResult);
Alexandre Julliard's avatar
Alexandre Julliard committed
1999
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
2000 2001
    case WM_NCCALCSIZE:
        {
2002
            NCCALCSIZE_PARAMS *nc32;
Alexandre Julliard's avatar
Alexandre Julliard committed
2003 2004
            NCCALCSIZE_PARAMS16 *nc = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(p16->lParam);
            p16->lParam = *(LPARAM *)(nc + 1);
2005
            nc32 = (NCCALCSIZE_PARAMS *)(p16->lParam);
Alexandre Julliard's avatar
Alexandre Julliard committed
2006
            CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] );
Alexandre Julliard's avatar
Alexandre Julliard committed
2007
            if (p16->wParam)
Alexandre Julliard's avatar
Alexandre Julliard committed
2008 2009 2010 2011 2012 2013 2014 2015 2016 2017
            {
                CONV_RECT16TO32( &nc->rgrc[1], &nc32->rgrc[1] );
                CONV_RECT16TO32( &nc->rgrc[2], &nc32->rgrc[2] );
                STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(nc->lppos),
                                          nc32->lppos );
                SEGPTR_FREE( PTR_SEG_TO_LIN(nc->lppos) );
            }
            SEGPTR_FREE(nc);
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
2018 2019 2020
    case WM_NCCREATE:
    case WM_CREATE:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
2021
            CREATESTRUCT16 *cs = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(p16->lParam);
Alexandre Julliard's avatar
Alexandre Julliard committed
2022 2023 2024 2025 2026 2027 2028
            SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszName) );
            SEGPTR_FREE( PTR_SEG_TO_LIN(cs->lpszClass) );
            SEGPTR_FREE( cs );
        }
        break;
    case WM_WINDOWPOSCHANGING:
    case WM_WINDOWPOSCHANGED:
Alexandre Julliard's avatar
Alexandre Julliard committed
2029
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
2030 2031
            WINDOWPOS16 *wp = (WINDOWPOS16 *)PTR_SEG_TO_LIN(p16->lParam);
            p16->lParam = *(LPARAM *)(wp + 1);
2032
            STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS *)p16->lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2033
            SEGPTR_FREE(wp);
Alexandre Julliard's avatar
Alexandre Julliard committed
2034
        }
Alexandre Julliard's avatar
Alexandre Julliard committed
2035
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
2036 2037 2038
    case WM_NOTIFY:
	UnMapLS(p16->lParam);
	break;
2039 2040 2041 2042 2043 2044 2045
    case WM_GETDLGCODE:
        if (p16->lParam)
        {
            LPMSG16 msg16 = (LPMSG16)PTR_SEG_TO_LIN(p16->lParam);
            MSGPARAM16 msgp16;
            msgp16.wParam=msg16->wParam;
            msgp16.lParam=msg16->lParam;
2046 2047
            WINPROC_UnmapMsg32ATo16(((LPMSG)lParam)->hwnd, ((LPMSG)lParam)->message,
                    ((LPMSG)lParam)->wParam, ((LPMSG)lParam)->lParam,
2048 2049 2050 2051
                    &msgp16 );
            SEGPTR_FREE(msg16);
        }
        break;
Alexandre Julliard's avatar
Alexandre Julliard committed
2052 2053 2054 2055 2056 2057 2058 2059 2060 2061
    }
}


/**********************************************************************
 *	     WINPROC_MapMsg32WTo16
 *
 * Map a message from 32-bit Unicode to 16-bit.
 * Return value is -1 on error, 0 if OK, 1 if an UnmapMsg call is needed.
 */
2062
INT WINPROC_MapMsg32WTo16( HWND hwnd, UINT msg32, WPARAM wParam32,
Alexandre Julliard's avatar
Alexandre Julliard committed
2063 2064
                             UINT16 *pmsg16, WPARAM16 *pwparam16,
                             LPARAM *plparam )
Alexandre Julliard's avatar
Alexandre Julliard committed
2065 2066 2067
{
    switch(msg32)
    {
2068 2069 2070 2071 2072 2073 2074
    case LB_ADDSTRING:
    case LB_FINDSTRING:
    case LB_FINDSTRINGEXACT:
    case LB_INSERTSTRING:
    case LB_SELECTSTRING:
    case LB_DIR:
    case LB_ADDFILE:
Alexandre Julliard's avatar
Alexandre Julliard committed
2075
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
2076
            LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2077 2078 2079 2080
            if (!str) return -1;
            *pwparam16 = (WPARAM16)LOWORD(wParam32);
            *plparam   = (LPARAM)SEGPTR_GET(str);
        }
2081
	*pmsg16 = (UINT16)msg32 + (LB_ADDSTRING16 - LB_ADDSTRING);
Alexandre Julliard's avatar
Alexandre Julliard committed
2082
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
2083

2084 2085 2086 2087 2088 2089
    case CB_ADDSTRING:
    case CB_FINDSTRING:
    case CB_FINDSTRINGEXACT:
    case CB_INSERTSTRING:
    case CB_SELECTSTRING:
    case CB_DIR:
Alexandre Julliard's avatar
Alexandre Julliard committed
2090 2091 2092 2093 2094 2095
        {
            LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
            if (!str) return -1;
            *pwparam16 = (WPARAM16)LOWORD(wParam32);
            *plparam   = (LPARAM)SEGPTR_GET(str);
        }
2096
	*pmsg16 = (UINT16)msg32 + (CB_ADDSTRING16 - CB_ADDSTRING);
Alexandre Julliard's avatar
Alexandre Julliard committed
2097 2098
        return 1;

Alexandre Julliard's avatar
Alexandre Julliard committed
2099 2100 2101 2102
    case WM_NCCREATE:
    case WM_CREATE:
        {
            CREATESTRUCT16 *cs;
2103
            CREATESTRUCTW *cs32 = (CREATESTRUCTW *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
2104
            LPSTR name, cls;
Alexandre Julliard's avatar
Alexandre Julliard committed
2105

Alexandre Julliard's avatar
Alexandre Julliard committed
2106
            if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return -1;
2107
            STRUCT32_CREATESTRUCT32Ato16( (CREATESTRUCTA *)cs32, cs );
Alexandre Julliard's avatar
Alexandre Julliard committed
2108 2109 2110 2111
            name = SEGPTR_STRDUP_WtoA( cs32->lpszName );
            cls  = SEGPTR_STRDUP_WtoA( cs32->lpszClass );
            cs->lpszName  = SEGPTR_GET(name);
            cs->lpszClass = SEGPTR_GET(cls);
Alexandre Julliard's avatar
Alexandre Julliard committed
2112 2113 2114 2115 2116
            *pmsg16    = (UINT16)msg32;
            *pwparam16 = (WPARAM16)LOWORD(wParam32);
            *plparam   = (LPARAM)SEGPTR_GET(cs);
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
2117 2118 2119
    case WM_MDICREATE:
        {
            MDICREATESTRUCT16 *cs;
2120
            MDICREATESTRUCTW *cs32 = (MDICREATESTRUCTW *)*plparam;
Alexandre Julliard's avatar
Alexandre Julliard committed
2121
            LPSTR name, cls;
Alexandre Julliard's avatar
Alexandre Julliard committed
2122 2123

            if (!(cs = SEGPTR_NEW(MDICREATESTRUCT16))) return -1;
2124
            STRUCT32_MDICREATESTRUCT32Ato16( (MDICREATESTRUCTA *)cs32, cs );
Alexandre Julliard's avatar
Alexandre Julliard committed
2125 2126 2127 2128
            name = SEGPTR_STRDUP_WtoA( cs32->szTitle );
            cls  = SEGPTR_STRDUP_WtoA( cs32->szClass );
            cs->szTitle = SEGPTR_GET(name);
            cs->szClass = SEGPTR_GET(cls);
Alexandre Julliard's avatar
Alexandre Julliard committed
2129 2130 2131 2132 2133
            *pmsg16    = (UINT16)msg32;
            *pwparam16 = (WPARAM16)LOWORD(wParam32);
            *plparam   = (LPARAM)SEGPTR_GET(cs);
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
2134 2135
    case WM_SETTEXT:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
2136
            LPSTR str = SEGPTR_STRDUP_WtoA( (LPWSTR)*plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2137 2138 2139 2140 2141 2142
            if (!str) return -1;
            *pmsg16    = (UINT16)msg32;
            *pwparam16 = (WPARAM16)LOWORD(wParam32);
            *plparam   = (LPARAM)SEGPTR_GET(str);
        }
        return 1;
Alexandre Julliard's avatar
Alexandre Julliard committed
2143
    default:  /* No Unicode translation needed */
Alexandre Julliard's avatar
Alexandre Julliard committed
2144
        return WINPROC_MapMsg32ATo16( hwnd, msg32, wParam32, pmsg16,
Alexandre Julliard's avatar
Alexandre Julliard committed
2145
                                      pwparam16, plparam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2146 2147 2148 2149
    }
}


Alexandre Julliard's avatar
Alexandre Julliard committed
2150 2151 2152 2153 2154
/**********************************************************************
 *	     WINPROC_UnmapMsg32WTo16
 *
 * Unmap a message that was mapped from 32-bit Unicode to 16-bit.
 */
2155
void WINPROC_UnmapMsg32WTo16( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
2156
                              MSGPARAM16* p16 )
Alexandre Julliard's avatar
Alexandre Julliard committed
2157 2158 2159 2160 2161
{
    switch(msg)
    {
    case WM_GETTEXT:
        {
Alexandre Julliard's avatar
Alexandre Julliard committed
2162 2163 2164
            LPSTR str = (LPSTR)PTR_SEG_TO_LIN(p16->lParam);
            p16->lParam = *((LPARAM *)str - 1);
            lstrcpyAtoW( (LPWSTR)(p16->lParam), str );
Alexandre Julliard's avatar
Alexandre Julliard committed
2165 2166 2167 2168
            SEGPTR_FREE( (LPARAM *)str - 1 );
        }
        break;
    default:
2169
        WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, p16 );
Alexandre Julliard's avatar
Alexandre Julliard committed
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179
        break;
    }
}


/**********************************************************************
 *	     WINPROC_CallProc32ATo32W
 *
 * Call a window procedure, translating args from Ansi to Unicode.
 */
2180 2181
static LRESULT WINPROC_CallProc32ATo32W( WNDPROC func, HWND hwnd,
                                         UINT msg, WPARAM wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
2182 2183 2184 2185
                                         LPARAM lParam )
{
    LRESULT result;

2186
    if (WINPROC_MapMsg32ATo32W( hwnd, msg, wParam, &lParam ) == -1) return 0;
2187
    result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2188
    WINPROC_UnmapMsg32ATo32W( hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2189 2190 2191 2192 2193 2194 2195 2196 2197
    return result;
}


/**********************************************************************
 *	     WINPROC_CallProc32WTo32A
 *
 * Call a window procedure, translating args from Unicode to Ansi.
 */
2198 2199
static LRESULT WINPROC_CallProc32WTo32A( WNDPROC func, HWND hwnd,
                                         UINT msg, WPARAM wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
2200 2201 2202 2203
                                         LPARAM lParam )
{
    LRESULT result;

2204
    if (WINPROC_MapMsg32WTo32A( hwnd, msg, wParam, &lParam ) == -1) return 0;
2205
    result = WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
2206
    WINPROC_UnmapMsg32WTo32A( hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2207 2208 2209 2210 2211 2212 2213 2214 2215
    return result;
}


/**********************************************************************
 *	     WINPROC_CallProc16To32A
 *
 * Call a 32-bit window procedure, translating the 16-bit args.
 */
2216 2217 2218
static LRESULT WINPROC_CallProc16To32A( WNDPROC func, HWND16 hwnd,
                                        UINT16 msg, WPARAM16 wParam,
                                        LPARAM lParam )
Alexandre Julliard's avatar
Alexandre Julliard committed
2219 2220
{
    LRESULT result;
2221 2222
    UINT msg32;
    WPARAM wParam32;
Alexandre Julliard's avatar
Alexandre Julliard committed
2223 2224 2225

    if (WINPROC_MapMsg16To32A( msg, wParam, &msg32, &wParam32, &lParam ) == -1)
        return 0;
2226
    result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2227
    return WINPROC_UnmapMsg16To32A( hwnd, msg32, wParam32, lParam, result );
Alexandre Julliard's avatar
Alexandre Julliard committed
2228 2229
}

2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242
/**********************************************************************
 *	     WINPROC_Thunk16To32A
 */
static LRESULT WINAPI WINPROC_Thunk16To32A( WNDPROC func, LPBYTE args )
{
    HWND16   hwnd   = *(HWND16 *)( args+8 );
    UINT16   msg    = *(HWND16 *)( args+6 );
    WPARAM16 wParam = *(HWND16 *)( args+4 );
    LPARAM   lParam = *(LPARAM *)( args+0 );

    return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam );
}

Alexandre Julliard's avatar
Alexandre Julliard committed
2243 2244 2245 2246 2247 2248

/**********************************************************************
 *	     WINPROC_CallProc16To32W
 *
 * Call a 32-bit window procedure, translating the 16-bit args.
 */
2249 2250 2251
static LRESULT WINPROC_CallProc16To32W( WNDPROC func, HWND16 hwnd,
                                        UINT16 msg, WPARAM16 wParam,
                                        LPARAM lParam )
Alexandre Julliard's avatar
Alexandre Julliard committed
2252 2253
{
    LRESULT result;
2254 2255
    UINT msg32;
    WPARAM wParam32;
Alexandre Julliard's avatar
Alexandre Julliard committed
2256

2257
    if (WINPROC_MapMsg16To32W( hwnd, msg, wParam, &msg32, &wParam32, &lParam ) == -1)
Alexandre Julliard's avatar
Alexandre Julliard committed
2258
        return 0;
2259

2260
    result = WINPROC_CallWndProc( func, hwnd, msg32, wParam32, lParam );
2261
    
2262
    return WINPROC_UnmapMsg16To32W( hwnd, msg32, wParam32, lParam, result );
Alexandre Julliard's avatar
Alexandre Julliard committed
2263 2264
}

2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276
/**********************************************************************
 *	     WINPROC_Thunk16To32W
 */
static LRESULT WINAPI WINPROC_Thunk16To32W( WNDPROC func, LPBYTE args )
{
    HWND16   hwnd   = *(HWND16 *)( args+8 );
    UINT16   msg    = *(HWND16 *)( args+6 );
    WPARAM16 wParam = *(HWND16 *)( args+4 );
    LPARAM   lParam = *(LPARAM *)( args+0 );

    return WINPROC_CallProc16To32W( func, hwnd, msg, wParam, lParam );
}
Alexandre Julliard's avatar
Alexandre Julliard committed
2277 2278 2279 2280 2281 2282

/**********************************************************************
 *	     WINPROC_CallProc32ATo16
 *
 * Call a 16-bit window procedure, translating the 32-bit args.
 */
2283 2284
static LRESULT WINAPI WINPROC_CallProc32ATo16( WNDPROC16 func, HWND hwnd,
                                               UINT msg, WPARAM wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
2285
                                               LPARAM lParam )
Alexandre Julliard's avatar
Alexandre Julliard committed
2286 2287
{
    UINT16 msg16;
Alexandre Julliard's avatar
Alexandre Julliard committed
2288
    MSGPARAM16 mp16;
Alexandre Julliard's avatar
Alexandre Julliard committed
2289

Alexandre Julliard's avatar
Alexandre Julliard committed
2290
    mp16.lParam = lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
2291 2292
    if (WINPROC_MapMsg32ATo16( hwnd, msg, wParam, 
                               &msg16, &mp16.wParam, &mp16.lParam ) == -1)
Alexandre Julliard's avatar
Alexandre Julliard committed
2293
        return 0;
2294 2295
    mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
                                          mp16.wParam, mp16.lParam );
2296
    WINPROC_UnmapMsg32ATo16( hwnd, msg, wParam, lParam, &mp16 );
Alexandre Julliard's avatar
Alexandre Julliard committed
2297
    return mp16.lResult;
Alexandre Julliard's avatar
Alexandre Julliard committed
2298 2299 2300 2301 2302 2303 2304 2305
}


/**********************************************************************
 *	     WINPROC_CallProc32WTo16
 *
 * Call a 16-bit window procedure, translating the 32-bit args.
 */
2306 2307
static LRESULT WINAPI WINPROC_CallProc32WTo16( WNDPROC16 func, HWND hwnd,
                                               UINT msg, WPARAM wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
2308
                                               LPARAM lParam )
Alexandre Julliard's avatar
Alexandre Julliard committed
2309 2310
{
    UINT16 msg16;
Alexandre Julliard's avatar
Alexandre Julliard committed
2311
    MSGPARAM16 mp16;
Alexandre Julliard's avatar
Alexandre Julliard committed
2312

Alexandre Julliard's avatar
Alexandre Julliard committed
2313
    mp16.lParam = lParam;
Alexandre Julliard's avatar
Alexandre Julliard committed
2314 2315
    if (WINPROC_MapMsg32WTo16( hwnd, msg, wParam, &msg16, &mp16.wParam,
                               &mp16.lParam ) == -1)
Alexandre Julliard's avatar
Alexandre Julliard committed
2316
        return 0;
2317 2318
    mp16.lResult = WINPROC_CallWndProc16( func, hwnd, msg16,
                                          mp16.wParam, mp16.lParam );
2319
    WINPROC_UnmapMsg32WTo16( hwnd, msg, wParam, lParam, &mp16 );
Alexandre Julliard's avatar
Alexandre Julliard committed
2320
    return mp16.lResult;
Alexandre Julliard's avatar
Alexandre Julliard committed
2321 2322 2323
}


Alexandre Julliard's avatar
Alexandre Julliard committed
2324 2325 2326
/**********************************************************************
 *	     CallWindowProc16    (USER.122)
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
2327 2328
LRESULT WINAPI CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
                                 WPARAM16 wParam, LPARAM lParam )
Alexandre Julliard's avatar
Alexandre Julliard committed
2329
{
Alexandre Julliard's avatar
Alexandre Julliard committed
2330
    WINDOWPROC *proc = WINPROC_GetPtr( func );
Alexandre Julliard's avatar
Alexandre Julliard committed
2331

Alexandre Julliard's avatar
Alexandre Julliard committed
2332
    if (!proc)
2333
        return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2334

Alexandre Julliard's avatar
Alexandre Julliard committed
2335
#if testing
Alexandre Julliard's avatar
Alexandre Julliard committed
2336
    func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16 );
2337
    return WINPROC_CallWndProc16( func, hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2338 2339
#endif
    
Alexandre Julliard's avatar
Alexandre Julliard committed
2340 2341 2342
    switch(proc->type)
    {
    case WIN_PROC_16:
Alexandre Julliard's avatar
Alexandre Julliard committed
2343
        if (!proc->thunk.t_from32.proc) return 0;
2344 2345
        return WINPROC_CallWndProc16( proc->thunk.t_from32.proc,
                                      hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2346
    case WIN_PROC_32A:
Alexandre Julliard's avatar
Alexandre Julliard committed
2347
        if (!proc->thunk.t_from16.proc) return 0;
2348 2349
        return WINPROC_CallProc16To32A( proc->thunk.t_from16.proc,
                                        hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2350
    case WIN_PROC_32W:
Alexandre Julliard's avatar
Alexandre Julliard committed
2351
        if (!proc->thunk.t_from16.proc) return 0;
2352 2353
        return WINPROC_CallProc16To32W( proc->thunk.t_from16.proc,
                                        hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2354
    default:
2355
        WARN_(relay)("Invalid proc %p\n", proc );
Alexandre Julliard's avatar
Alexandre Julliard committed
2356
        return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
2357 2358 2359 2360 2361
    }
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383
 *	     CallWindowProc32A    (USER32.18) 
 *
 * The CallWindowProc() function invokes the windows procedure _func_,
 * with _hwnd_ as the target window, the message specified by _msg_, and
 * the message parameters _wParam_ and _lParam_.
 *
 * Some kinds of argument conversion may be done, I'm not sure what.
 *
 * CallWindowProc() may be used for windows subclassing. Use
 * SetWindowLong() to set a new windows procedure for windows of the
 * subclass, and handle subclassed messages in the new windows
 * procedure. The new windows procedure may then use CallWindowProc()
 * with _func_ set to the parent class's windows procedure to dispatch
 * the message to the superclass.
 *
 * RETURNS
 *
 *    The return value is message dependent.
 *
 * CONFORMANCE
 *
 *   ECMA-234, Win32 
Alexandre Julliard's avatar
Alexandre Julliard committed
2384
 */
2385 2386 2387 2388 2389
LRESULT WINAPI CallWindowProcA( 
    WNDPROC func, /* window procedure */
    HWND hwnd, /* target window */
    UINT msg,  /* message */
    WPARAM wParam, /* message dependent parameter */
Alexandre Julliard's avatar
Alexandre Julliard committed
2390 2391
    LPARAM lParam    /* message dependent parameter */
) {
Alexandre Julliard's avatar
Alexandre Julliard committed
2392
    WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
Alexandre Julliard's avatar
Alexandre Julliard committed
2393

2394
    if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2395

Alexandre Julliard's avatar
Alexandre Julliard committed
2396 2397
#if testing
    func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32A );
2398
    return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2399 2400
#endif

Alexandre Julliard's avatar
Alexandre Julliard committed
2401
    switch(proc->type)
Alexandre Julliard's avatar
Alexandre Julliard committed
2402
    {
Alexandre Julliard's avatar
Alexandre Julliard committed
2403
    case WIN_PROC_16:
Alexandre Julliard's avatar
Alexandre Julliard committed
2404 2405 2406
        if (!proc->thunk.t_from32.proc) return 0;
        return WINPROC_CallProc32ATo16( proc->thunk.t_from32.proc,
                                        hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2407
    case WIN_PROC_32A:
Alexandre Julliard's avatar
Alexandre Julliard committed
2408
        if (!proc->thunk.t_from16.proc) return 0;
2409
        return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
Alexandre Julliard's avatar
Alexandre Julliard committed
2410
                                      hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2411
    case WIN_PROC_32W:
Alexandre Julliard's avatar
Alexandre Julliard committed
2412 2413
        if (!proc->thunk.t_from16.proc) return 0;
        return WINPROC_CallProc32ATo32W( proc->thunk.t_from16.proc,
Alexandre Julliard's avatar
Alexandre Julliard committed
2414
                                         hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2415
    default:
2416
        WARN_(relay)("Invalid proc %p\n", proc );
Alexandre Julliard's avatar
Alexandre Julliard committed
2417 2418 2419 2420 2421 2422
        return 0;
    }
}


/**********************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
2423
 *	     CallWindowProc32W    (USER32.19)
Alexandre Julliard's avatar
Alexandre Julliard committed
2424
 */
2425 2426
LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
                                  WPARAM wParam, LPARAM lParam )
Alexandre Julliard's avatar
Alexandre Julliard committed
2427
{
Alexandre Julliard's avatar
Alexandre Julliard committed
2428
    WINDOWPROC *proc = WINPROC_GetPtr( (WNDPROC16)func );
Alexandre Julliard's avatar
Alexandre Julliard committed
2429

2430
    if (!proc) return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2431

Alexandre Julliard's avatar
Alexandre Julliard committed
2432 2433
#if testing
    func = WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_32W );
2434
    return WINPROC_CallWndProc( func, hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2435 2436
#endif

Alexandre Julliard's avatar
Alexandre Julliard committed
2437
    switch(proc->type)
Alexandre Julliard's avatar
Alexandre Julliard committed
2438 2439
    {
    case WIN_PROC_16:
Alexandre Julliard's avatar
Alexandre Julliard committed
2440 2441 2442
        if (!proc->thunk.t_from32.proc) return 0;
        return WINPROC_CallProc32WTo16( proc->thunk.t_from32.proc,
                                        hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2443
    case WIN_PROC_32A:
Alexandre Julliard's avatar
Alexandre Julliard committed
2444 2445
        if (!proc->thunk.t_from16.proc) return 0;
        return WINPROC_CallProc32WTo32A( proc->thunk.t_from16.proc,
Alexandre Julliard's avatar
Alexandre Julliard committed
2446
                                         hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2447
    case WIN_PROC_32W:
Alexandre Julliard's avatar
Alexandre Julliard committed
2448
        if (!proc->thunk.t_from16.proc) return 0;
2449
        return WINPROC_CallWndProc( proc->thunk.t_from16.proc,
Alexandre Julliard's avatar
Alexandre Julliard committed
2450
                                      hwnd, msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
2451
    default:
2452
        WARN_(relay)("Invalid proc %p\n", proc );
Alexandre Julliard's avatar
Alexandre Julliard committed
2453 2454
        return 0;
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
2455
}