You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1118 lines
33 KiB
1118 lines
33 KiB
/*++
|
|
*
|
|
* WOW v1.0
|
|
*
|
|
* Copyright (c) 1991, Microsoft Corporation
|
|
*
|
|
* WMSG32.C
|
|
* WOW32 32-bit message thunks
|
|
*
|
|
* History:
|
|
* Created 19-Feb-1992 by Chandan Chauhan (ChandanC)
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
MODNAME(wcntl32.c);
|
|
|
|
// This function thunks the button control messages,
|
|
//
|
|
// BM_GETCHECK
|
|
// BM_SETCHECK
|
|
// BM_GETSTATE
|
|
// BM_SETSTATE
|
|
// BM_SETSTYLE
|
|
//
|
|
|
|
BOOL FASTCALL WM32BMControl(LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - BM_GETCHECK));
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
BOOL FASTCALL WM32BMClick (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WIN31_BM_CLICK);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
|
|
// This function thunks the following edit control messages,
|
|
//
|
|
// EM_GETSEL
|
|
// EM_GETMODIFY
|
|
// EM_SETMODIFY
|
|
// EM_GETLINECOUNT
|
|
// EM_GETLINEINDEX
|
|
// EM_LINELENGTH
|
|
// EM_LIMITTEX
|
|
// EM_CANUNDO
|
|
// EM_UNDO
|
|
// EM_FMTLINES
|
|
// EM_LINEFROMCHAR
|
|
// EM_SETPASSWORDCHAR
|
|
// EM_EMPTYUNDOBUFFER
|
|
|
|
BOOL FASTCALL WM32EMControl(LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the button control messages,
|
|
//
|
|
// EM_SETSEL
|
|
//
|
|
|
|
BOOL FASTCALL WM32EMSetSel (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lpwm32mpex->uParam;
|
|
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD)
|
|
((lpwm32mpex->lParam != -1) ? lpwm32mpex->lParam : 32767);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the edit control messages,
|
|
//
|
|
// EM_GETRECT
|
|
//
|
|
|
|
BOOL FASTCALL WM32EMGetRect (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
} else {
|
|
GETRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the edit control messages,
|
|
//
|
|
// EM_SETRECT
|
|
// EM_SETRECTNP
|
|
//
|
|
|
|
BOOL FASTCALL WM32EMSetRect (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
PUTRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
|
|
} else {
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the edit control messages,
|
|
//
|
|
// EM_LINESCROLL
|
|
//
|
|
|
|
BOOL FASTCALL WM32EMLineScroll (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lpwm32mpex->lParam;
|
|
HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lpwm32mpex->uParam;
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the edit control messages,
|
|
//
|
|
// EM_REPLACESEL
|
|
//
|
|
|
|
BOOL FASTCALL WM32EMReplaceSel (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
if (lpwm32mpex->lParam) {
|
|
INT cb;
|
|
|
|
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
|
|
lpwm32mpex->dwTmp[0] = (DWORD)cb; // save allocation size
|
|
|
|
// winworks2.0a requires DS based string pointers for this message
|
|
|
|
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
|
|
|
|
// be sure allocation size matches stackfree16() size below
|
|
lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(cb);
|
|
|
|
} else {
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
}
|
|
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
|
|
}
|
|
} else {
|
|
if (lpwm32mpex->Parm16.WndProc.lParam) {
|
|
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
|
|
|
|
stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
|
|
((UINT)lpwm32mpex->dwTmp[0]));
|
|
} else {
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
BOOL FASTCALL WM32EMSetFont (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
}
|
|
|
|
LOGDEBUG(0,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the edit control messages,
|
|
//
|
|
// EM_GETLINE
|
|
//
|
|
|
|
BOOL FASTCALL WM32EMGetLine (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
if (lpwm32mpex->lParam) {
|
|
INT cb;
|
|
PBYTE lp;
|
|
|
|
// the first WORD is what USER uses.
|
|
|
|
cb = *(UNALIGNED WORD *)(lpwm32mpex->lParam);
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
ALLOCVDMPTR(lpwm32mpex->Parm16.WndProc.lParam,2,lp);
|
|
*((UNALIGNED WORD *)lp) = (WORD)cb;
|
|
FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam,2,lp); /* first 2 bytes modified */
|
|
}
|
|
} else {
|
|
if (lpwm32mpex->Parm16.WndProc.lParam) {
|
|
PBYTE lp;
|
|
|
|
GETMISCPTR(lpwm32mpex->Parm16.WndProc.lParam,lp);
|
|
RtlCopyMemory((PBYTE)lpwm32mpex->lParam,lp,lpwm32mpex->lReturn);
|
|
FREEVDMPTR(lp);
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
}
|
|
|
|
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
BOOL FASTCALL WM32EMSetWordBreakProc (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
|
|
// take out the marker bits and fix the RPL bits
|
|
UnMarkWOWProc (lpwm32mpex->lParam,lpwm32mpex->Parm16.WndProc.lParam);
|
|
|
|
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
BOOL FASTCALL WM32EMGetWordBreakProc (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
|
|
}
|
|
else {
|
|
|
|
// Mark the address as WOW Proc and store the high bits in the RPL field
|
|
MarkWOWProc (lpwm32mpex->lReturn,lpwm32mpex->lReturn);
|
|
}
|
|
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the edit control messages,
|
|
//
|
|
// EM_SETTABSTOPS
|
|
//
|
|
|
|
BOOL FASTCALL WM32EMSetTabStops (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - EM_GETSEL));
|
|
if (lpwm32mpex->uParam != 0) {
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->uParam * sizeof(WORD));
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
putintarray16((VPINT16)lpwm32mpex->Parm16.WndProc.lParam, (INT)lpwm32mpex->uParam, (LPINT)lpwm32mpex->lParam);
|
|
}
|
|
} else {
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the following combo box control messages,
|
|
//
|
|
// CB_GETEDITSEL
|
|
// CB_LIMITTEXT
|
|
// CB_SETEDITSEL
|
|
// CB_DELETESTRING
|
|
// CB_GETCOUNT
|
|
// CB_GETCURSEL
|
|
// CB_GETLBTEXTLEN
|
|
// CB_SETCURSEL
|
|
// CB_SHOWDROPDOWN
|
|
// CB_GETITEMDATA
|
|
// CB_SETITEMDATA
|
|
|
|
|
|
BOOL FASTCALL WM32CBControl (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the following combo box control messages,
|
|
//
|
|
// CB_ADDSTRING
|
|
// CB_INSERTSTRING
|
|
// CB_FINDSTRING
|
|
// CB_SELECTSTRING
|
|
|
|
BOOL FASTCALL WM32CBAddString (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
PWW pww;
|
|
|
|
|
|
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
if (!(pww = lpwm32mpex->pww)) {
|
|
if (pww = FindPWW (lpwm32mpex->hwnd))
|
|
lpwm32mpex->pww = pww;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
|
|
|
|
//
|
|
// Determine if this combobox has string pointers or handles passed
|
|
// in with CB_ADDSTRING messages. Normal comboboxes have string
|
|
// pointers passed. Owner-draw comboboxes that don't have the
|
|
// CBS_HASSTRINGS style bit set have handles passed in. These handles
|
|
// are simply passed back to the owner at paint time. If the
|
|
// CBS_HASSTRINGS style bit is set, strings are used instead of
|
|
// handles as the "cookie" which is passed back to the application
|
|
// at paint time.
|
|
//
|
|
// We treat lpwm32mpex->dwParam as a BOOL indicating this combobox
|
|
// takes handles instead of strings.
|
|
//
|
|
|
|
lpwm32mpex->dwParam =
|
|
(pww->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) &&
|
|
!(pww->style & CBS_HASSTRINGS);
|
|
|
|
if ( !lpwm32mpex->dwParam ) { // if strings are used
|
|
if (lpwm32mpex->lParam) {
|
|
INT cb;
|
|
|
|
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
|
|
}
|
|
}
|
|
} else {
|
|
if ( !lpwm32mpex->dwParam ) { // if strings are used
|
|
if (lpwm32mpex->Parm16.WndProc.lParam) {
|
|
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, -1);
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
// This function thunks the following combo box control messages,
|
|
//
|
|
// CB_DIR
|
|
//
|
|
// Code in this routine references code in wparam.c in order to circumvent
|
|
// copying memory to 16-bit memory space.
|
|
// GetParam16 verifies that the parameter we get (lparam) had not originated
|
|
// in 16-bit code. If it did come from 16-bit code, then we send an original
|
|
// 16:16 pointer to the application.
|
|
// This fixes PagePlus 3.0 application and (if implemented on a broader scale)
|
|
// will positively affect performance of applications which send a lot of
|
|
// standard messages and use subclassing a lot.
|
|
// -- VadimB
|
|
|
|
BOOL FASTCALL WM32CBDir (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
|
|
if (lpwm32mpex->lParam) {
|
|
INT cb;
|
|
|
|
if (W32CheckThunkParamFlag()) {
|
|
LONG lParam = (LONG)GetParam16(lpwm32mpex->lParam);
|
|
if (lParam) {
|
|
lpwm32mpex->Parm16.WndProc.lParam = lParam;
|
|
return (TRUE);
|
|
}
|
|
}
|
|
|
|
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
|
|
}
|
|
} else {
|
|
if (W32CheckThunkParamFlag()) {
|
|
if (DeleteParamMap(lpwm32mpex->Parm16.WndProc.lParam, PARAM_16, NULL)) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the following combo box control messages,
|
|
//
|
|
// CB_GETLBTEXT
|
|
|
|
BOOL FASTCALL WM32CBGetLBText (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
PWW pww;
|
|
|
|
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
INT cb;
|
|
|
|
if (!(pww = lpwm32mpex->pww)) {
|
|
if (pww = FindPWW (lpwm32mpex->hwnd))
|
|
lpwm32mpex->pww = pww;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
|
|
|
|
//
|
|
// Determine if this combobox has string pointers or handles passed
|
|
// in with CB_ADDSTRING messages. Normal comboboxes have string
|
|
// pointers passed. Owner-draw comboboxes that don't have the
|
|
// CBS_HASSTRINGS style bit set have handles passed in. These handles
|
|
// are simply passed back to the owner at paint time. If the
|
|
// CBS_HASSTRINGS style bit is set, strings are used instead of
|
|
// handles as the "cookie" which is passed back to the application
|
|
// at paint time.
|
|
//
|
|
// We treat lpwm32mpex->dwParam as a BOOL indicating this combobox
|
|
// takes handles instead of strings.
|
|
//
|
|
|
|
lpwm32mpex->dwParam =
|
|
(pww->style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) &&
|
|
!(pww->style & CBS_HASSTRINGS);
|
|
|
|
//
|
|
// Determine the size of the buffer to allocate on the 16-bit side
|
|
// to receive the text.
|
|
//
|
|
|
|
if (lpwm32mpex->dwParam) { // if handles are used
|
|
cb = 4;
|
|
} else {
|
|
cb = SendMessage(lpwm32mpex->hwnd, CB_GETLBTEXTLEN, lpwm32mpex->uParam, 0);
|
|
if (cb == CB_ERR) {
|
|
//
|
|
// lpwm32mpex->dwTmp[0] is initialized to 0 so that nothing
|
|
// gets copied to the buffer by getstr16() while unthunking
|
|
// this message.
|
|
//
|
|
// bug # 24415, ChandanC
|
|
//
|
|
|
|
cb = SIZE_BOGUS;
|
|
lpwm32mpex->dwTmp[0] = 0;
|
|
}
|
|
else {
|
|
//
|
|
// Add one for NULL character.
|
|
//
|
|
cb = cb + 1;
|
|
(INT) lpwm32mpex->dwTmp[0] = (INT) -1;
|
|
}
|
|
}
|
|
if (lpwm32mpex->lParam) {
|
|
BYTE *lpT;
|
|
|
|
// See comment on similar code below
|
|
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(BYTE), lpT);
|
|
*lpT = 0;
|
|
FREEVDMPTR(lpT);
|
|
}
|
|
}
|
|
else {
|
|
if (lpwm32mpex->lParam && lpwm32mpex->Parm16.WndProc.lParam) {
|
|
if (lpwm32mpex->dwParam) { // if handles are used
|
|
UNALIGNED DWORD *lpT;
|
|
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(DWORD), lpT);
|
|
*(UNALIGNED DWORD *)lpwm32mpex->lParam = *lpT;
|
|
FREEVDMPTR(lpT);
|
|
}
|
|
else {
|
|
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam,
|
|
(INT) lpwm32mpex->dwTmp[0]);
|
|
}
|
|
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the following combo box control messages,
|
|
//
|
|
// CB_GETDROPPEDCONTROLRECT
|
|
|
|
BOOL FASTCALL WM32CBGetDropDownControlRect (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - CB_GETEDITSEL));
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
} else {
|
|
GETRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the following combo box control messages,
|
|
//
|
|
// CBEC_SETCOMBOFOCUS (WM_USER+CB_MSGMAX+1)
|
|
// CBEC_KILLCOMBOFOCUS (WM_USER+CB_MSGMAX+2)
|
|
// These undocumented messages are used by Excel 5.0
|
|
//
|
|
|
|
BOOL FASTCALL WM32CBComboFocus (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
#if (CBEC_SETCOMBOFOCUS != 0x166)
|
|
#error The USER Guys changed CBEC_SETCOMBOFOCUS again
|
|
#endif
|
|
|
|
#if (CBEC_KILLCOMBOFOCUS != 0x167)
|
|
#error The USER Guys changed CBEC_KILLCOMBOFOCUS again
|
|
#endif
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg =
|
|
(WORD)((lpwm32mpex->uMsg-CBEC_SETCOMBOFOCUS) + OLDCBEC_SETCOMBOFOCUS);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_RESETCONTENT
|
|
// LB_SETCURSEL
|
|
// LB_GETSEL
|
|
// LB_GETCURSEL
|
|
// LB_GETTEXTLEN
|
|
// LB_GETCOUNT
|
|
// LB_GETCARETINDEX
|
|
// LB_GETTOPINDEX
|
|
// LB_GETSELCOUNT
|
|
// LB_GETHORIZONTALEXTENT
|
|
// LB_SETHORIZONTALEXTENT
|
|
// LB_SETCOLUMNWIDTH
|
|
// LB_SETTOPINDEX
|
|
// LB_SETCARETINDEX
|
|
// LB_SETITEMDATA
|
|
// LB_SELITEMRANGE
|
|
// LB_SETITEMHEIGHT
|
|
// LB_GETITEMHEIGHT
|
|
// LB_DELETESTRING
|
|
//
|
|
|
|
BOOL FASTCALL WM32LBControl (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_GETTEXT
|
|
|
|
BOOL FASTCALL WM32LBGetText (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
PWW pww;
|
|
|
|
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
INT cb;
|
|
|
|
if (!(pww = lpwm32mpex->pww)) {
|
|
if (pww = FindPWW (lpwm32mpex->hwnd))
|
|
lpwm32mpex->pww = pww;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
|
|
//
|
|
// Determine if this listbox has string pointers or handles passed
|
|
// in with LB_ADDSTRING messages. Owner-draw listboxes that don't
|
|
// have the LBS_HASSTRINGS style bit set have handles passed in.
|
|
// These handles are simply passed back to the owner at paint time.
|
|
// If the LBS_HASSTRINGS style bit is set, strings are used instead of
|
|
// handles as the "cookie" which is passed back to the application
|
|
// at paint time.
|
|
//
|
|
// We treat lpwm32mpex->dwParam as a BOOL indicating this listbox
|
|
// takes handles instead of strings.
|
|
//
|
|
|
|
lpwm32mpex->dwParam =
|
|
(pww->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
|
|
!(pww->style & LBS_HASSTRINGS);
|
|
|
|
if (lpwm32mpex->dwParam) { // if this listbox takes handles
|
|
cb = 4;
|
|
}
|
|
else {
|
|
cb = SendMessage(lpwm32mpex->hwnd, LB_GETTEXTLEN, lpwm32mpex->uParam, 0);
|
|
|
|
// Check for LB_ERR (which is -1) on the above SendMessage().
|
|
// When cb is equal to LB_ERR make the size as SIZE_BOGUS (256 bytes),
|
|
// and allocate a buffer just in case if the app diddles the lParam.
|
|
// We will free the buffer while unthunking the message (LB_GETTEXT).
|
|
// This fix makes the app MCAD happy.
|
|
// ChandanC 4-21-93.
|
|
|
|
if (cb == LB_ERR) {
|
|
cb = SIZE_BOGUS;
|
|
}
|
|
else {
|
|
//
|
|
// Add one for NULL character.
|
|
//
|
|
cb = cb + 1;
|
|
}
|
|
|
|
}
|
|
|
|
if (lpwm32mpex->lParam) {
|
|
BYTE *lpT;
|
|
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
|
|
// The reason for this code to be here is that sometimes thunks
|
|
// are executed on a buffer that has not been initialized, e.g.
|
|
// if the hooks are installed by a wow app. That means we will
|
|
// alloc 16-bit buffer while thunking (boils down to uninitialized
|
|
// data buffer and will try to copy the buffer back while unthunking
|
|
// overwriting the stack sometimes (as user allocates temp bufs from
|
|
// the stack). This code initializes data so problem is avoided
|
|
// App: Grammatik/Windows v6.0 -- VadimB
|
|
|
|
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(BYTE), lpT);
|
|
*lpT = 0;
|
|
FREEVDMPTR(lpT);
|
|
}
|
|
}
|
|
else {
|
|
|
|
if ((lpwm32mpex->lReturn != LB_ERR) && lpwm32mpex->lParam && lpwm32mpex->Parm16.WndProc.lParam) {
|
|
if (lpwm32mpex->dwParam) { // if this listbox takes handles
|
|
UNALIGNED DWORD *lpT;
|
|
GETVDMPTR((lpwm32mpex->Parm16.WndProc.lParam), sizeof(DWORD), lpT);
|
|
*(UNALIGNED DWORD *)lpwm32mpex->lParam = *lpT;
|
|
FREEVDMPTR(lpT);
|
|
}
|
|
else {
|
|
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, -1);
|
|
}
|
|
}
|
|
|
|
if (lpwm32mpex->Parm16.WndProc.lParam) {
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_GETTEXTLEN
|
|
|
|
BOOL FASTCALL WM32LBGetTextLen (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
|
|
// USER32 and so do we send the LB_GETTEXTLEN message whenever an
|
|
// LB_GETTEXT message is sent. This LB_GETTEXTLEN message is an
|
|
// additional message that an app normally wouldn't see in WIN31.
|
|
// lParam by definition is NULL.
|
|
//
|
|
// Super Project dies (at times) when it receives the LB_GETTEXTLEN
|
|
// message. It doesn't expect to see this message and as a result does
|
|
// strlen(lParam) and dies.
|
|
// - nanduri
|
|
|
|
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_LB_NONNULLLPARAM) {
|
|
|
|
// be sure allocation size matches stackfree16() size below
|
|
LPBYTE lpT = (LPBYTE)stackalloc16(0x2); // just an even number
|
|
|
|
lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpT;
|
|
GETVDMPTR(lpT, 0x2, lpT);
|
|
*lpT = '\0';
|
|
}
|
|
} else {
|
|
if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_LB_NONNULLLPARAM) {
|
|
if(lpwm32mpex->Parm16.WndProc.lParam) {
|
|
stackfree16((VPVOID)lpwm32mpex->Parm16.WndProc.lParam, 0x2);
|
|
}
|
|
}
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_DIR
|
|
|
|
BOOL FASTCALL WM32LBDir (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
INT cb;
|
|
VPVOID vp;
|
|
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
if (lpwm32mpex->lParam) {
|
|
cb = strlen((LPSTR)lpwm32mpex->lParam)+1;
|
|
if (!(vp = malloc16(cb))) {
|
|
LOGDEBUG(0,(" WOW32.DLL : WM32LBDir() :: Could not allocate memory for string, ChandanC\n"));
|
|
WOW32ASSERT(vp);
|
|
return FALSE;
|
|
}
|
|
putstr16(vp, (LPSTR) lpwm32mpex->lParam, cb);
|
|
lpwm32mpex->Parm16.WndProc.lParam = vp;
|
|
}
|
|
}
|
|
else {
|
|
if (lpwm32mpex->Parm16.WndProc.lParam) {
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_GETSELITEMS
|
|
|
|
BOOL FASTCALL WM32LBGetSelItems (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
if (lpwm32mpex->lParam) {
|
|
INT cb;
|
|
|
|
cb = lpwm32mpex->uParam * sizeof(WORD);
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
|
|
}
|
|
} else {
|
|
getintarray16((VPRECT16)lpwm32mpex->Parm16.WndProc.lParam, (INT)lpwm32mpex->uParam, (LPINT)lpwm32mpex->lParam);
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_SETTABSTOPS
|
|
|
|
BOOL FASTCALL WM32LBSetTabStops (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
if (lpwm32mpex->uParam != 0) {
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->uParam * sizeof(WORD));
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
putintarray16((VPRECT16)lpwm32mpex->Parm16.WndProc.lParam, (INT)lpwm32mpex->uParam, (LPINT)lpwm32mpex->lParam);
|
|
}
|
|
} else {
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_GETITEMRECT
|
|
|
|
BOOL FASTCALL WM32LBGetItemRect (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(RECT16));
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
} else {
|
|
GETRECT16( lpwm32mpex->Parm16.WndProc.lParam, (LPRECT)lpwm32mpex->lParam );
|
|
if (lpwm32mpex->Parm16.WndProc.lParam)
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
|
|
LOGDEBUG(3,(" Window %08lX is receiving Control Message %s(%08x)\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
|
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
|
// This function thunks the list box control messages
|
|
//
|
|
// LB_ADDSTRING
|
|
// LB_INSERTSTRING
|
|
// LB_FINDSTRING
|
|
// LB_SELECTSTRING
|
|
|
|
BOOL FASTCALL WM32LBAddString (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
PWW pww;
|
|
|
|
|
|
if ( lpwm32mpex->fThunk ) {
|
|
if (!(pww = lpwm32mpex->pww)) {
|
|
if (pww = FindPWW (lpwm32mpex->hwnd))
|
|
lpwm32mpex->pww = pww;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
|
|
//
|
|
// Determine if this listbox has string pointers or handles passed
|
|
// in with LB_ADDSTRING messages. Owner-draw listboxes that don't
|
|
// have the LBS_HASSTRINGS style bit set have handles passed in.
|
|
// These handles are simply passed back to the owner at paint time.
|
|
// If the LBS_HASSTRINGS style bit is set, strings are used instead of
|
|
// handles as the "cookie" which is passed back to the application
|
|
// at paint time.
|
|
//
|
|
// We treat lpwm32mpex->dwParam as a BOOL indicating this listbox
|
|
// takes handles instead of strings.
|
|
//
|
|
|
|
lpwm32mpex->dwParam =
|
|
(pww->style & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE)) &&
|
|
!(pww->style & LBS_HASSTRINGS);
|
|
|
|
if ( !lpwm32mpex->dwParam ) { // if this listbox takes strings
|
|
if (lpwm32mpex->lParam) {
|
|
INT cb;
|
|
|
|
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
|
|
lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb);
|
|
if (!(lpwm32mpex->Parm16.WndProc.lParam))
|
|
return FALSE;
|
|
putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
|
|
}
|
|
}
|
|
} else {
|
|
if ( !lpwm32mpex->dwParam ) { // if this listbox takes strings
|
|
if (lpwm32mpex->Parm16.WndProc.lParam) {
|
|
getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, -1);
|
|
free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
// This function thunks the scrollbar control messages,
|
|
//
|
|
// SBM_SETPOS
|
|
// SBM_GETPOS
|
|
// SBM_ENABLE_ARROWS
|
|
//
|
|
|
|
BOOL FASTCALL WM32SBMControl (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = WM_USER + (lpwm32mpex->uMsg - SBM_SETPOS);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// SBM_GETRANGE
|
|
|
|
BOOL FASTCALL WM32SBMGetRange (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
//
|
|
// Changed semantics for this message to support 32-bit
|
|
// scroll bar ranges (vs. 16-bit).
|
|
//
|
|
// Win16:
|
|
// posMin = LOWORD(SendMessage(hwnd, SBM_GETRANGE, 0, 0));
|
|
// posMax = HIWORD(SendMessage(hwnd, SBM_GETRANGE, 0, 0));
|
|
//
|
|
// Win32:
|
|
// SendMessage(hwnd, SBM_GETRANGE,
|
|
// (WPARAM) &posMin, (LPARAM) &posMax);
|
|
//
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = OLDSBM_GETRANGE;
|
|
} else {
|
|
*(DWORD *)lpwm32mpex->uParam = INT32(LOWORD(lpwm32mpex->lReturn));
|
|
*(DWORD *)lpwm32mpex->lParam = INT32(HIWORD(lpwm32mpex->lReturn));
|
|
lpwm32mpex->lReturn = 0;
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// SBM_SETRANGE
|
|
// SBM_SETRANGEREDRAW (new for Win32)
|
|
|
|
BOOL FASTCALL WM32SBMSetRange (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
//
|
|
// Changed semantics to support 32-bit scroll bar range:
|
|
//
|
|
// Win16:
|
|
// SendMessage(hwnd, SBM_SETRANGE, fRedraw, MAKELONG(posMin, posMax);
|
|
//
|
|
// Win32:
|
|
// SendMessage(hwnd, fRedraw ? SBM_SETRANGE : SBM_SETRANGEREDRAW,
|
|
// posMin, posMax);
|
|
//
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = OLDSBM_SETRANGE;
|
|
lpwm32mpex->Parm16.WndProc.wParam = (SBM_SETRANGEREDRAW == lpwm32mpex->uMsg);
|
|
lpwm32mpex->Parm16.WndProc.lParam = MAKELONG( (WORD)lpwm32mpex->uParam, (WORD)lpwm32mpex->lParam);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// LB_SETSEL
|
|
|
|
BOOL FASTCALL WM32LBSetSel (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = (WORD) (WM_USER + (lpwm32mpex->uMsg - LB_ADDSTRING + 1));
|
|
lpwm32mpex->Parm16.WndProc.wParam = (WORD) lpwm32mpex->uParam;
|
|
lpwm32mpex->Parm16.WndProc.lParam = (WORD)lpwm32mpex->lParam; // loword = index, hiword = 0
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the static control messages,
|
|
//
|
|
// STM_SETICON
|
|
// STM_GETICON
|
|
//
|
|
|
|
BOOL FASTCALL WM32STMControl (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
|
|
if (lpwm32mpex->fThunk) {
|
|
switch (lpwm32mpex->uMsg) {
|
|
case STM_SETICON:
|
|
lpwm32mpex->Parm16.WndProc.wParam = (WORD)GETHICON16(lpwm32mpex->uParam);
|
|
break;
|
|
|
|
case STM_GETICON:
|
|
break;
|
|
|
|
}
|
|
lpwm32mpex->Parm16.WndProc.wMsg = WM_USER + (lpwm32mpex->uMsg - STM_SETICON);
|
|
}
|
|
else {
|
|
lpwm32mpex->lReturn = (LONG)HICON32(lpwm32mpex->lReturn);
|
|
}
|
|
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
// This function thunks the messages,
|
|
//
|
|
// MN_FINDMENUWINDOWFROMPOINT
|
|
//
|
|
|
|
// NT - wparam = (PUINT)pitem lParam = MAKELONG(pt.x, pt.y)
|
|
// returns flags or hwnd *pitem = index or -1
|
|
//
|
|
// win31 wParam = 0 lParam = same
|
|
// returns 0 or MAKELONG(-1, item) or MAKELONG(-2, item) or MAKELONG(hwnd, item)
|
|
|
|
|
|
BOOL FASTCALL WM32MNFindMenuWindow (LPWM32MSGPARAMEX lpwm32mpex)
|
|
{
|
|
if (lpwm32mpex->fThunk) {
|
|
lpwm32mpex->Parm16.WndProc.wMsg = WIN30_MN_FINDMENUWINDOWFROMPOINT;
|
|
lpwm32mpex->Parm16.WndProc.wParam = 0;
|
|
|
|
} else {
|
|
USHORT n = LOWORD(lpwm32mpex->lReturn);
|
|
|
|
*(PLONG)lpwm32mpex->uParam = (SHORT)HIWORD(lpwm32mpex->lReturn);
|
|
lpwm32mpex->lReturn = (LONG)HWND32(n); // this sign-extends -1, -2 and leaves 0 as 0
|
|
}
|
|
return TRUE;
|
|
}
|