| /* |
| * Window procedure callbacks |
| * |
| * Copyright 1995 Martin von Loewis |
| * Copyright 1996 Alexandre Julliard |
| */ |
| |
| #include <stdio.h> |
| #include "windows.h" |
| #include "callback.h" |
| #include "heap.h" |
| #include "ldt.h" |
| #include "stackframe.h" |
| #include "string32.h" |
| #include "struct32.h" |
| #include "win.h" |
| #include "winproc.h" |
| |
| |
| typedef struct |
| { |
| UINT32 magic; /* Magic number */ |
| WINDOWPROCTYPE type; /* Function type */ |
| UINT32 count; /* Reference count */ |
| UINT32 func; /* 16- or 32-bit function */ |
| } WINDOWPROC; |
| |
| #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24)) |
| |
| |
| static HANDLE32 WinProcHeap = 0; |
| |
| |
| /********************************************************************** |
| * WINPROC_GetPtr |
| * |
| * Return a pointer to the win proc. |
| */ |
| static WINDOWPROC *WINPROC_GetPtr( HANDLE32 handle ) |
| { |
| WINDOWPROC *proc; |
| |
| /* Check for a linear pointer */ |
| |
| if (HEAP_IsInsideHeap( WinProcHeap, 0, (LPVOID)handle )) |
| { |
| proc = (WINDOWPROC *)handle; |
| if (proc->magic == WINPROC_MAGIC) return proc; |
| } |
| |
| /* Check for a segmented pointer */ |
| |
| if (!IsBadReadPtr( (SEGPTR)handle, sizeof(WINDOWPROC) )) |
| { |
| proc = (WINDOWPROC *)PTR_SEG_TO_LIN(handle); |
| if (proc->magic == WINPROC_MAGIC) return proc; |
| } |
| |
| return NULL; |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_AllocWinProc |
| * |
| * Allocate a new window procedure. |
| */ |
| HANDLE32 WINPROC_AllocWinProc( UINT32 func, WINDOWPROCTYPE type ) |
| { |
| WINDOWPROC *proc; |
| |
| /* Create the heap if necessary */ |
| |
| if (!WinProcHeap) |
| { |
| if (!(WinProcHeap = HeapCreate( HEAP_WINE_SEGPTR, 0, 0 ))) return 0; |
| } |
| |
| /* Check if function is already a win proc */ |
| |
| if ((proc = WINPROC_GetPtr( (HANDLE32)func ))) |
| { |
| proc->count++; |
| return (HANDLE32)func; |
| } |
| |
| /* Now allocate a new one */ |
| |
| if (!(proc = HeapAlloc( WinProcHeap, 0, sizeof(WINDOWPROC) ))) return 0; |
| proc->magic = WINPROC_MAGIC; |
| proc->type = type; |
| proc->count = 1; |
| proc->func = func; |
| return (HANDLE32)proc; |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_CopyWinProc |
| * |
| * Copy a window procedure. |
| */ |
| HANDLE32 WINPROC_CopyWinProc( HANDLE32 handle ) |
| { |
| WINDOWPROC *proc; |
| if ((proc = WINPROC_GetPtr( (HANDLE32)handle ))) |
| { |
| proc->count++; |
| return handle; |
| } |
| return (HANDLE32)0; |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_FreeWinProc |
| * |
| * Free a window procedure. |
| */ |
| void WINPROC_FreeWinProc( HANDLE32 handle ) |
| { |
| WINDOWPROC *proc; |
| |
| if (!(proc = WINPROC_GetPtr( handle ))) |
| { |
| fprintf( stderr, "WINPROC_FreeWinProc: invalid proc %08x\n", handle ); |
| return; |
| } |
| if (--proc->count == 0) |
| { |
| proc->magic = 0; /* Just in case */ |
| HeapFree( WinProcHeap, 0, proc ); |
| } |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_GetWinProcType |
| * |
| * Return the window procedure type. |
| */ |
| WINDOWPROCTYPE WINPROC_GetWinProcType( HANDLE32 handle ) |
| { |
| WINDOWPROC *proc = WINPROC_GetPtr( handle ); |
| if (!proc) return WIN_PROC_INVALID; |
| return proc->type; |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_GetFunc16 |
| * |
| * Return the 16-bit function pointer, or NULL if none. |
| */ |
| WNDPROC16 WINPROC_GetFunc16( HANDLE32 handle ) |
| { |
| WINDOWPROC *proc = WINPROC_GetPtr( handle ); |
| if (!proc) return (WNDPROC16)0; |
| return (WNDPROC16)HEAP_GetSegptr( WinProcHeap, 0, proc ); |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_GetFunc32 |
| * |
| * Return the 32-bit function pointer, or NULL if none. |
| */ |
| WNDPROC32 WINPROC_GetFunc32( HANDLE32 handle ) |
| { |
| WINDOWPROC *proc = WINPROC_GetPtr( handle ); |
| if (!proc) return (WNDPROC32)0; |
| return (WNDPROC32)proc; |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_CallProc32ATo32W |
| * |
| * Call a window procedure, translating args from Ansi to Unicode. |
| */ |
| static LRESULT WINPROC_CallProc32ATo32W( WNDPROC32 func, HWND32 hwnd, |
| UINT32 msg, WPARAM32 wParam, |
| LPARAM lParam ) |
| { |
| LRESULT result; |
| |
| switch(msg) |
| { |
| case WM_GETTEXT: |
| { |
| LPWSTR str = (LPWSTR)HeapAlloc(SystemHeap,0,wParam*sizeof(WCHAR)); |
| if (!str) return 0; |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str ); |
| STRING32_UniToAnsi( (LPSTR)lParam, str ); |
| HeapFree( SystemHeap, 0, str ); |
| } |
| return result; /* FIXME? */ |
| |
| case WM_SETTEXT: |
| { |
| LPWSTR str = STRING32_DupAnsiToUni( (LPCSTR)lParam ); |
| if (!str) return 0; |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str ); |
| free( str ); |
| } |
| return result; |
| |
| case WM_NCCREATE: |
| case WM_CREATE: |
| { |
| CREATESTRUCT32W cs = *(CREATESTRUCT32W *)lParam; |
| cs.lpszName = STRING32_DupAnsiToUni( (LPCSTR)cs.lpszName ); |
| cs.lpszClass = STRING32_DupAnsiToUni( (LPCSTR)cs.lpszName ); |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs ); |
| free( (LPVOID)cs.lpszName ); |
| free( (LPVOID)cs.lpszClass ); |
| } |
| return result; |
| |
| default: /* No translation needed */ |
| return CallWndProc32( func, hwnd, msg, wParam, lParam ); |
| } |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_CallProc32WTo32A |
| * |
| * Call a window procedure, translating args from Unicode to Ansi. |
| */ |
| static LRESULT WINPROC_CallProc32WTo32A( WNDPROC32 func, HWND32 hwnd, |
| UINT32 msg, WPARAM32 wParam, |
| LPARAM lParam ) |
| { |
| LRESULT result; |
| |
| switch(msg) |
| { |
| case WM_GETTEXT: |
| { |
| LPSTR str = (LPSTR)HeapAlloc( SystemHeap, 0, wParam ); |
| if (!str) return 0; |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str ); |
| STRING32_AnsiToUni( (LPWSTR)lParam, str ); |
| HeapFree( SystemHeap, 0, str ); |
| } |
| return result; /* FIXME? */ |
| |
| case WM_SETTEXT: |
| { |
| LPSTR str = STRING32_DupUniToAnsi( (LPCWSTR)lParam ); |
| if (!str) return 0; |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)str ); |
| free( str ); |
| } |
| return result; |
| |
| case WM_NCCREATE: |
| case WM_CREATE: |
| { |
| CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam; |
| if (HIWORD(cs.lpszName)) |
| cs.lpszName = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName ); |
| if (HIWORD(cs.lpszClass)) |
| cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName ); |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs ); |
| if (HIWORD(cs.lpszName)) free( (LPVOID)cs.lpszName ); |
| if (HIWORD(cs.lpszClass)) free( (LPVOID)cs.lpszClass ); |
| } |
| return result; |
| |
| default: /* No translation needed */ |
| return CallWndProc32( func, hwnd, msg, wParam, lParam ); |
| } |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_CallProc16To32A |
| * |
| * Call a 32-bit window procedure, translating the 16-bit args. |
| */ |
| static LRESULT WINPROC_CallProc16To32A(WNDPROC32 func, HWND16 hwnd, UINT16 msg, |
| WPARAM16 wParam, LPARAM lParam ) |
| { |
| LRESULT result; |
| |
| switch(msg) |
| { |
| case WM_ACTIVATE: |
| case WM_CHARTOITEM: |
| case WM_COMMAND: |
| case WM_HSCROLL: |
| case WM_VKEYTOITEM: |
| case WM_VSCROLL: |
| return CallWndProc32( func, hwnd, msg, |
| MAKEWPARAM( wParam, HIWORD(lParam) ), |
| (LPARAM)(HWND32)LOWORD(lParam) ); |
| case WM_CTLCOLOR: |
| return CallWndProc32( func, hwnd, WM_CTLCOLORMSGBOX + HIWORD(lParam), |
| (WPARAM32)(HDC32)wParam, |
| (LPARAM)(HWND32)LOWORD(lParam) ); |
| case WM_DRAWITEM: |
| { |
| DRAWITEMSTRUCT16*dis16 = (DRAWITEMSTRUCT16*)PTR_SEG_TO_LIN(lParam); |
| DRAWITEMSTRUCT32 dis; |
| 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 ); |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&dis ); |
| /* We don't bother to translate it back */ |
| } |
| return result; |
| |
| case WM_GETMINMAXINFO: |
| { |
| MINMAXINFO32 mmi; |
| STRUCT32_MINMAXINFO16to32( (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam), |
| &mmi ); |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&mmi); |
| STRUCT32_MINMAXINFO32to16( &mmi, |
| (MINMAXINFO16 *)PTR_SEG_TO_LIN(lParam)); |
| } |
| return result; |
| |
| case WM_GETTEXT: |
| return CallWndProc32( func, hwnd, msg, wParam, |
| (LPARAM)PTR_SEG_TO_LIN(lParam) ); |
| case WM_MDISETMENU: |
| return CallWndProc32( func, hwnd, msg, |
| (WPARAM32)(HMENU32)LOWORD(lParam), |
| (LPARAM)(HMENU32)HIWORD(lParam) ); |
| case WM_MENUCHAR: |
| case WM_MENUSELECT: |
| return CallWndProc32( func, hwnd, msg, |
| MAKEWPARAM( wParam, LOWORD(lParam) ), |
| (LPARAM)(HMENU32)HIWORD(lParam) ); |
| case WM_NCCALCSIZE: |
| { |
| NCCALCSIZE_PARAMS16 *pnc16; |
| NCCALCSIZE_PARAMS32 nc; |
| WINDOWPOS32 wp; |
| |
| pnc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam); |
| CONV_RECT16TO32( &pnc16->rgrc[0], &nc.rgrc[0] ); |
| if (wParam) |
| { |
| CONV_RECT16TO32( &pnc16->rgrc[1], &nc.rgrc[1] ); |
| CONV_RECT16TO32( &pnc16->rgrc[2], &nc.rgrc[2] ); |
| STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(pnc16->lppos), |
| &wp ); |
| nc.lppos = ℘ |
| } |
| |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&nc ); |
| |
| pnc16 = (NCCALCSIZE_PARAMS16 *)PTR_SEG_TO_LIN(lParam); |
| CONV_RECT32TO16( &nc.rgrc[0], &pnc16->rgrc[0] ); |
| if (wParam) |
| { |
| CONV_RECT32TO16( &nc.rgrc[1], &pnc16->rgrc[1] ); |
| CONV_RECT32TO16( &nc.rgrc[2], &pnc16->rgrc[2] ); |
| STRUCT32_WINDOWPOS32to16( nc.lppos, |
| (WINDOWPOS16 *)PTR_SEG_TO_LIN(pnc16->lppos)); |
| } |
| } |
| return result; |
| |
| case WM_NCCREATE: |
| case WM_CREATE: |
| { |
| CREATESTRUCT16 *pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam); |
| CREATESTRUCT32A cs; |
| |
| STRUCT32_CREATESTRUCT16to32A( pcs16, &cs ); |
| /* FIXME: Unicode */ |
| cs.lpszName = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName); |
| cs.lpszClass = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass); |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&cs ); |
| pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam); |
| STRUCT32_CREATESTRUCT32Ato16( &cs, pcs16 ); |
| |
| if (cs.lpszName != (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName)) |
| fprintf( stderr, "CallWindowProc16: WM_NCCREATE(%04x) changed lpszName (%p->%p), please report.\n", |
| msg, (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName), cs.lpszName); |
| if (cs.lpszClass != (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass)) |
| fprintf( stderr, "CallWindowProc16: WM_NCCREATE(%04x) changed lpszClass (%p->%p), please report.\n", |
| msg, (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass), cs.lpszClass); |
| } |
| return result; |
| |
| case WM_PARENTNOTIFY: |
| if ((wParam == WM_CREATE) || (wParam == WM_DESTROY)) |
| return CallWndProc32( func, hwnd, msg, |
| MAKEWPARAM( wParam, HIWORD(lParam) ), |
| (LPARAM)(HWND32)LOWORD(lParam) ); |
| else return CallWndProc32( func, hwnd, msg, |
| MAKEWPARAM( wParam, 0 /* FIXME? */ ), |
| lParam ); |
| case WM_SETTEXT: |
| /* FIXME: Unicode */ |
| return CallWndProc32( func, hwnd, msg, wParam, |
| (LPARAM)PTR_SEG_TO_LIN(lParam) ); |
| |
| case WM_WINDOWPOSCHANGING: |
| case WM_WINDOWPOSCHANGED: |
| { |
| WINDOWPOS32 wp; |
| STRUCT32_WINDOWPOS16to32( (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam), |
| &wp ); |
| result = CallWndProc32( func, hwnd, msg, wParam, (LPARAM)&wp ); |
| STRUCT32_WINDOWPOS32to16( &wp, |
| (WINDOWPOS16 *)PTR_SEG_TO_LIN(lParam) ); |
| } |
| return result; |
| |
| case WM_ASKCBFORMATNAME: |
| case WM_COMPAREITEM: |
| case WM_DELETEITEM: |
| case WM_DEVMODECHANGE: |
| case WM_MDIACTIVATE: |
| case WM_MDICREATE: |
| case WM_MEASUREITEM: |
| case WM_PAINTCLIPBOARD: |
| case WM_SIZECLIPBOARD: |
| case WM_WININICHANGE: |
| fprintf( stderr, "CallWindowProc16To32: message %04x needs translation\n", msg ); |
| |
| default: /* No translation needed */ |
| return CallWndProc32( func, hwnd, msg, (WPARAM32)wParam, lParam ); |
| } |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_CallProc16To32W |
| * |
| * Call a 32-bit window procedure, translating the 16-bit args. |
| */ |
| static LRESULT WINPROC_CallProc16To32W(WNDPROC32 func, HWND16 hwnd, UINT16 msg, |
| WPARAM16 wParam, LPARAM lParam ) |
| { |
| LRESULT result = 0; |
| |
| switch(msg) |
| { |
| case WM_GETTEXT: |
| case WM_SETTEXT: |
| return WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam, |
| (LPARAM)PTR_SEG_TO_LIN(lParam) ); |
| |
| case WM_NCCREATE: |
| case WM_CREATE: |
| { |
| CREATESTRUCT16 *pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam); |
| CREATESTRUCT32A cs; |
| |
| STRUCT32_CREATESTRUCT16to32A( pcs16, &cs ); |
| cs.lpszName = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszName); |
| cs.lpszClass = (LPCSTR)PTR_SEG_TO_LIN(pcs16->lpszClass); |
| result = WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam, |
| (LPARAM)&cs ); |
| pcs16 = (CREATESTRUCT16 *)PTR_SEG_TO_LIN(lParam); |
| STRUCT32_CREATESTRUCT32Ato16( &cs, pcs16 ); |
| } |
| return result; |
| |
| default: /* No Unicode translation needed */ |
| return WINPROC_CallProc16To32A( func, hwnd, msg, wParam, lParam ); |
| } |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_CallProc32ATo16 |
| * |
| * Call a 16-bit window procedure, translating the 32-bit args. |
| */ |
| static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, WORD ds, HWND32 hwnd, |
| UINT32 msg, WPARAM32 wParam, |
| LPARAM lParam ) |
| { |
| LRESULT result; |
| |
| switch(msg) |
| { |
| case WM_ACTIVATE: |
| case WM_CHARTOITEM: |
| case WM_COMMAND: |
| case WM_HSCROLL: |
| case WM_VKEYTOITEM: |
| case WM_VSCROLL: |
| return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| MAKELPARAM( (HWND16)lParam, HIWORD(wParam) ) ); |
| |
| case WM_CTLCOLORMSGBOX: |
| case WM_CTLCOLOREDIT: |
| case WM_CTLCOLORLISTBOX: |
| case WM_CTLCOLORBTN: |
| case WM_CTLCOLORDLG: |
| case WM_CTLCOLORSCROLLBAR: |
| case WM_CTLCOLORSTATIC: |
| return CallWndProc16( func, ds, hwnd, WM_CTLCOLOR, (WPARAM16)wParam, |
| MAKELPARAM( (HWND16)lParam, |
| (WORD)msg - WM_CTLCOLORMSGBOX ) ); |
| case WM_DRAWITEM: |
| { |
| DRAWITEMSTRUCT32 *dis32 = (DRAWITEMSTRUCT32 *)lParam; |
| DRAWITEMSTRUCT16 *dis = SEGPTR_NEW(DRAWITEMSTRUCT16); |
| if (!dis) return 0; |
| 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 ); |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(dis) ); |
| /* We don't bother to translate it back */ |
| SEGPTR_FREE(dis); |
| } |
| return result; |
| |
| case WM_GETMINMAXINFO: |
| { |
| MINMAXINFO16 *mmi = SEGPTR_NEW(MINMAXINFO16); |
| if (!mmi) return 0; |
| STRUCT32_MINMAXINFO32to16( (MINMAXINFO32 *)lParam, mmi ); |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(mmi) ); |
| STRUCT32_MINMAXINFO16to32( mmi, (MINMAXINFO32 *)lParam ); |
| SEGPTR_FREE(mmi); |
| } |
| return result; |
| |
| case WM_GETTEXT: |
| { |
| LPSTR str; |
| wParam = MIN( wParam, 0xff80 ); /* Size must be < 64K */ |
| if (!(str = SEGPTR_ALLOC( wParam ))) return 0; |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(str) ); |
| if (result > 0) memcpy( (LPSTR)lParam, str, result ); |
| SEGPTR_FREE(str); |
| } |
| return result; |
| |
| case WM_MDISETMENU: |
| return CallWndProc16( func, ds, hwnd, msg, TRUE /* FIXME? */, |
| MAKELPARAM( (HMENU16)LOWORD(lParam), |
| (HMENU16)HIWORD(lParam) ) ); |
| case WM_MENUCHAR: |
| case WM_MENUSELECT: |
| return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)LOWORD(wParam), |
| MAKELPARAM( HIWORD(wParam), (HMENU16)lParam ) ); |
| case WM_NCCALCSIZE: |
| { |
| NCCALCSIZE_PARAMS32 *nc32 = (NCCALCSIZE_PARAMS32 *)lParam; |
| NCCALCSIZE_PARAMS16 *nc; |
| WINDOWPOS16 *wp = NULL; |
| |
| if (!(nc = SEGPTR_NEW(NCCALCSIZE_PARAMS16))) return 0; |
| CONV_RECT32TO16( &nc32->rgrc[0], &nc->rgrc[0] ); |
| if (wParam) |
| { |
| CONV_RECT32TO16( &nc32->rgrc[1], &nc->rgrc[1] ); |
| CONV_RECT32TO16( &nc32->rgrc[2], &nc->rgrc[2] ); |
| if (!(wp = SEGPTR_NEW(WINDOWPOS16))) |
| { |
| SEGPTR_FREE(nc); |
| return 0; |
| } |
| STRUCT32_WINDOWPOS32to16( nc32->lppos, wp ); |
| nc->lppos = SEGPTR_GET(wp); |
| } |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(nc) ); |
| CONV_RECT16TO32( &nc->rgrc[0], &nc32->rgrc[0] ); |
| if (wParam) |
| { |
| 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(wp); |
| } |
| SEGPTR_FREE(nc); |
| } |
| return result; |
| |
| case WM_NCCREATE: |
| case WM_CREATE: |
| { |
| CREATESTRUCT16 *cs; |
| CREATESTRUCT32A *cs32 = (CREATESTRUCT32A *)lParam; |
| LPSTR name, cls; |
| |
| if (!(cs = SEGPTR_NEW(CREATESTRUCT16))) return 0; |
| STRUCT32_CREATESTRUCT32Ato16( cs32, cs ); |
| name = SEGPTR_STRDUP( cs32->lpszName ); |
| cls = SEGPTR_STRDUP( cs32->lpszClass ); |
| cs->lpszName = SEGPTR_GET(name); |
| cs->lpszClass = SEGPTR_GET(cls); |
| #ifdef WINELIB |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(cs) ); |
| #else |
| /* Build the CREATESTRUCT on the 16-bit stack. */ |
| /* This is really ugly, but some programs (notably the */ |
| /* "Undocumented Windows" examples) want it that way. */ |
| result = CallWndProcNCCREATE16( func, ds, cs->dwExStyle, |
| cs->lpszClass, cs->lpszName, cs->style, cs->x, cs->y, |
| cs->cx, cs->cy, cs->hwndParent, cs->hMenu, cs->hInstance, |
| (LONG)cs->lpCreateParams, hwnd, msg, (WPARAM16)wParam, |
| MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16), |
| IF1632_Saved16_ss ) ); |
| #endif /* WINELIB */ |
| /* We don't bother to translate the structure back */ |
| SEGPTR_FREE(name); |
| SEGPTR_FREE(cls); |
| SEGPTR_FREE(cs); |
| } |
| return result; |
| |
| case WM_PARENTNOTIFY: |
| if ((wParam == WM_CREATE) || (wParam == WM_DESTROY)) |
| return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| MAKELPARAM( (HWND16)lParam, LOWORD(wParam))); |
| else |
| return CallWndProc16( func, ds, hwnd, msg, |
| (WPARAM16)wParam, lParam ); |
| |
| case WM_SETTEXT: |
| { |
| LPSTR str = SEGPTR_STRDUP( (LPSTR)lParam ); |
| if (!str) return 0; |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(str) ); |
| SEGPTR_FREE(str); |
| } |
| return result; |
| |
| case WM_WINDOWPOSCHANGING: |
| case WM_WINDOWPOSCHANGED: |
| { |
| WINDOWPOS16 *wp; |
| if (!(wp = SEGPTR_NEW(WINDOWPOS16))) return 0; |
| STRUCT32_WINDOWPOS32to16( (WINDOWPOS32 *)lParam, wp ); |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(wp) ); |
| STRUCT32_WINDOWPOS16to32( wp, (WINDOWPOS32 *)lParam ); |
| SEGPTR_FREE(wp); |
| } |
| return result; |
| |
| case WM_ASKCBFORMATNAME: |
| case WM_COMPAREITEM: |
| case WM_DELETEITEM: |
| case WM_DEVMODECHANGE: |
| case WM_MDIACTIVATE: |
| case WM_MDICREATE: |
| case WM_MEASUREITEM: |
| case WM_PAINTCLIPBOARD: |
| case WM_SIZECLIPBOARD: |
| case WM_WININICHANGE: |
| fprintf( stderr, "CallWindowProc32To16: message %04x needs translation\n", msg ); |
| |
| default: /* No translation needed */ |
| return CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, lParam ); |
| } |
| } |
| |
| |
| /********************************************************************** |
| * WINPROC_CallProc32WTo16 |
| * |
| * Call a 16-bit window procedure, translating the 32-bit args. |
| */ |
| static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, WORD ds, HWND32 hwnd, |
| UINT32 msg, WPARAM32 wParam, |
| LPARAM lParam ) |
| { |
| LRESULT result; |
| |
| switch(msg) |
| { |
| case WM_GETTEXT: |
| { |
| LPSTR str; |
| wParam = MIN( wParam, 0xff80 ); /* Size must be < 64K */ |
| if (!(str = SEGPTR_ALLOC( wParam ))) return 0; |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(str) ); |
| if (result > 0) STRING32_AnsiToUni( (LPWSTR)lParam, str ); |
| SEGPTR_FREE(str); |
| } |
| return result; |
| |
| case WM_NCCREATE: |
| case WM_CREATE: |
| { |
| CREATESTRUCT32A cs = *(CREATESTRUCT32A *)lParam; |
| if (HIWORD(cs.lpszName)) |
| cs.lpszName = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName ); |
| if (HIWORD(cs.lpszClass)) |
| cs.lpszClass = STRING32_DupUniToAnsi( (LPCWSTR)cs.lpszName ); |
| result = WINPROC_CallProc32ATo16( func, ds, hwnd, msg, wParam, |
| (LPARAM)&cs ); |
| if (HIWORD(cs.lpszName)) free( (LPVOID)cs.lpszName ); |
| if (HIWORD(cs.lpszClass)) free( (LPVOID)cs.lpszClass ); |
| } |
| return result; |
| |
| case WM_SETTEXT: |
| { |
| LPSTR str = SEGPTR_ALLOC( lstrlen32W( (LPWSTR)lParam ) ); |
| if (!str) return 0; |
| STRING32_UniToAnsi( str, (LPWSTR)lParam ); |
| result = CallWndProc16( func, ds, hwnd, msg, (WPARAM16)wParam, |
| (LPARAM)SEGPTR_GET(str) ); |
| SEGPTR_FREE(str); |
| } |
| return result; |
| |
| default: /* No Unicode translation needed */ |
| return WINPROC_CallProc32ATo16( func, ds, hwnd, msg, wParam, lParam ); |
| } |
| } |
| |
| |
| /********************************************************************** |
| * CallWindowProc16 (USER.122) |
| */ |
| LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg, |
| WPARAM16 wParam, LPARAM lParam ) |
| { |
| WND *wndPtr; |
| WINDOWPROC *proc = WINPROC_GetPtr( (HANDLE32)func ); |
| |
| if (!proc) |
| { |
| wndPtr = WIN_FindWndPtr( hwnd ); |
| return CallWndProc16( (FARPROC)func, |
| wndPtr ? wndPtr->hInstance : CURRENT_DS, |
| hwnd, msg, wParam, lParam ); |
| } |
| |
| switch(proc->type) |
| { |
| case WIN_PROC_16: |
| wndPtr = WIN_FindWndPtr( hwnd ); |
| return CallWndProc16( (FARPROC)proc->func, |
| wndPtr ? wndPtr->hInstance : CURRENT_DS, |
| hwnd, msg, wParam, lParam ); |
| case WIN_PROC_32A: |
| return WINPROC_CallProc16To32A( (WNDPROC32)proc->func, |
| hwnd, msg, wParam, lParam ); |
| case WIN_PROC_32W: |
| return WINPROC_CallProc16To32W( (WNDPROC32)proc->func, |
| hwnd, msg, wParam, lParam ); |
| default: |
| fprintf( stderr, "CallWindowProc16: invalid proc %p\n", proc ); |
| return 0; |
| } |
| } |
| |
| |
| /********************************************************************** |
| * CallWindowProc32A (USER32.17) |
| */ |
| LRESULT CallWindowProc32A( WNDPROC32 func, HWND32 hwnd, UINT32 msg, |
| WPARAM32 wParam, LPARAM lParam ) |
| { |
| WND *wndPtr; |
| WINDOWPROC *proc = WINPROC_GetPtr( (HANDLE32)func ); |
| |
| if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam ); |
| |
| switch(proc->type) |
| { |
| case WIN_PROC_16: |
| wndPtr = WIN_FindWndPtr( hwnd ); |
| return WINPROC_CallProc32ATo16( (FARPROC)proc->func, |
| wndPtr ? wndPtr->hInstance : CURRENT_DS, |
| hwnd, msg, wParam, lParam ); |
| case WIN_PROC_32A: |
| return CallWndProc32( (WNDPROC32)proc->func, |
| hwnd, msg, wParam, lParam ); |
| case WIN_PROC_32W: |
| return WINPROC_CallProc32ATo32W( (WNDPROC32)proc->func, |
| hwnd, msg, wParam, lParam ); |
| default: |
| fprintf( stderr, "CallWindowProc32A: invalid proc %p\n", proc ); |
| return 0; |
| } |
| } |
| |
| |
| /********************************************************************** |
| * CallWindowProc32W (USER32.18) |
| */ |
| LRESULT CallWindowProc32W( WNDPROC32 func, HWND32 hwnd, UINT32 msg, |
| WPARAM32 wParam, LPARAM lParam ) |
| { |
| WND *wndPtr; |
| WINDOWPROC *proc = WINPROC_GetPtr( (HANDLE32)func ); |
| |
| if (!proc) return CallWndProc32( func, hwnd, msg, wParam, lParam ); |
| |
| switch(proc->type) |
| { |
| case WIN_PROC_16: |
| wndPtr = WIN_FindWndPtr( hwnd ); |
| return WINPROC_CallProc32WTo16( (FARPROC)proc->func, |
| wndPtr ? wndPtr->hInstance : CURRENT_DS, |
| hwnd, msg, wParam, lParam ); |
| case WIN_PROC_32A: |
| return WINPROC_CallProc32WTo32A( (WNDPROC32)proc->func, |
| hwnd, msg, wParam, lParam ); |
| case WIN_PROC_32W: |
| return CallWndProc32( (WNDPROC32)proc->func, |
| hwnd, msg, wParam, lParam ); |
| default: |
| fprintf( stderr, "CallWindowProc32W: invalid proc %p\n", proc ); |
| return 0; |
| } |
| } |