701 lines
16 KiB
C
701 lines
16 KiB
C
|
/*++
|
||
|
*
|
||
|
* Windows NT v5.0 WOW
|
||
|
*
|
||
|
* Copyright (c) 1997, Microsoft Corporation
|
||
|
*
|
||
|
* WIN95.C
|
||
|
*
|
||
|
* WOW32 Hand-coded (as opposed to interpreted) thunks for new-for-Win95
|
||
|
* exports.
|
||
|
*
|
||
|
* History:
|
||
|
* 16 Feb 97 Created davehart
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
MODNAME(win95.c);
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32TileWindows(PVDMFRAME pFrame)
|
||
|
{
|
||
|
return W32TileOrCascadeWindows(pFrame, TileWindows);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32CascadeWindows(PVDMFRAME pFrame)
|
||
|
{
|
||
|
return W32TileOrCascadeWindows(pFrame, CascadeWindows);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL W32TileOrCascadeWindows(PVDMFRAME pFrame, PFNTILECASCADEWINDOWS pfnWin32)
|
||
|
{
|
||
|
register PCASCADEWINDOWS16 parg16;
|
||
|
ULONG ul;
|
||
|
RECT rc;
|
||
|
PRECT prc;
|
||
|
HWND ahwnd[8];
|
||
|
DWORD chwnd;
|
||
|
HWND16 UNALIGNED *phwnd16;
|
||
|
HWND *phwnd;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
chwnd = parg16->chwnd;
|
||
|
|
||
|
if (parg16->lpRect) {
|
||
|
GETRECT16(parg16->lpRect, &rc);
|
||
|
prc = &rc;
|
||
|
} else {
|
||
|
prc = NULL;
|
||
|
}
|
||
|
|
||
|
if (parg16->ahwnd) {
|
||
|
phwnd = STACKORHEAPALLOC( chwnd * sizeof(HWND), sizeof(ahwnd), ahwnd);
|
||
|
phwnd16 = VDMPTR(parg16->ahwnd, chwnd * sizeof(HWND16));
|
||
|
|
||
|
for (ul = 0; ul < chwnd; ul++) {
|
||
|
phwnd[ul] = HWND32(phwnd16[ul]);
|
||
|
}
|
||
|
|
||
|
FREEVDMPTR(phwnd16);
|
||
|
} else {
|
||
|
phwnd = NULL;
|
||
|
}
|
||
|
|
||
|
ul = (*pfnWin32)(
|
||
|
HWND32(parg16->hwndParent),
|
||
|
parg16->wFlags,
|
||
|
prc,
|
||
|
chwnd,
|
||
|
phwnd
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Memory movement may have occurred due to message activity,
|
||
|
// so throw away flat pointers to 16-bit memory.
|
||
|
//
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
if (phwnd) {
|
||
|
STACKORHEAPFREE(phwnd, ahwnd);
|
||
|
}
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32DrawAnimatedRects(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PDRAWANIMATEDRECTS16 parg16;
|
||
|
ULONG ul;
|
||
|
RECT rcFrom, rcTo;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETRECT16(parg16->lprcStart, &rcFrom);
|
||
|
GETRECT16(parg16->lprcEnd, &rcTo);
|
||
|
|
||
|
ul = DrawAnimatedRects(
|
||
|
HWND32(parg16->hwndClip),
|
||
|
parg16->idAnimation,
|
||
|
&rcFrom,
|
||
|
&rcTo
|
||
|
);
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32DrawCaption(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PDRAWCAPTION16 parg16;
|
||
|
ULONG ul;
|
||
|
RECT rc;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETRECT16(parg16->lprc, &rc);
|
||
|
|
||
|
ul = DrawCaption(
|
||
|
HWND32(parg16->hwnd),
|
||
|
HDC32(parg16->hdc),
|
||
|
&rc,
|
||
|
parg16->wFlags
|
||
|
);
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32DrawEdge(PVDMFRAME pFrame)
|
||
|
{
|
||
|
return W32DrawEdgeOrFrameControl(pFrame, DrawEdge);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32DrawFrameControl(PVDMFRAME pFrame)
|
||
|
{
|
||
|
return W32DrawEdgeOrFrameControl(pFrame, DrawFrameControl);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL W32DrawEdgeOrFrameControl(PVDMFRAME pFrame, PFNDRAWEDGEFRAMECONTROL pfnWin32)
|
||
|
{
|
||
|
register PDRAWEDGE16 parg16;
|
||
|
ULONG ul;
|
||
|
RECT rc;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETRECT16(parg16->lprc, &rc);
|
||
|
|
||
|
ul = (*pfnWin32)(
|
||
|
HDC32(parg16->hdc),
|
||
|
&rc,
|
||
|
parg16->wEdge,
|
||
|
parg16->wFlags
|
||
|
);
|
||
|
|
||
|
PUTRECT16(parg16->lprc, &rc);
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32DrawTextEx(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PDRAWTEXTEX16 parg16;
|
||
|
ULONG ul;
|
||
|
PSZ psz;
|
||
|
RECT rc;
|
||
|
DRAWTEXTPARAMS dtp, *pdtp;
|
||
|
PDRAWTEXTPARAMS16 pdtp16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETVARSTRPTR(parg16->lpchText, parg16->cchText, psz);
|
||
|
GETRECT16(parg16->lprc, &rc);
|
||
|
|
||
|
if ( (parg16->lpDTparams) &&
|
||
|
(pdtp16 = VDMPTR(parg16->lpDTparams, sizeof(DRAWTEXTPARAMS16))) ) {
|
||
|
|
||
|
pdtp = &dtp;
|
||
|
dtp.cbSize = sizeof(dtp);
|
||
|
dtp.iTabLength = pdtp16->iTabLength;
|
||
|
dtp.iLeftMargin = pdtp16->iLeftMargin;
|
||
|
dtp.iRightMargin = pdtp16->iRightMargin;
|
||
|
dtp.uiLengthDrawn = 0;
|
||
|
} else {
|
||
|
pdtp = NULL;
|
||
|
}
|
||
|
|
||
|
ul = DrawTextEx(
|
||
|
HDC32(parg16->hdc),
|
||
|
psz,
|
||
|
parg16->cchText,
|
||
|
&rc,
|
||
|
parg16->dwDTformat,
|
||
|
pdtp
|
||
|
);
|
||
|
|
||
|
if (pdtp) {
|
||
|
pdtp16->uiLengthDrawn = (WORD)dtp.uiLengthDrawn;
|
||
|
}
|
||
|
|
||
|
FREEVDMPTR(pdtp16);
|
||
|
FREEVDMPTR(psz);
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32GetIconInfo(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PGETICONINFO16 parg16;
|
||
|
ULONG ul;
|
||
|
ICONINFO ii;
|
||
|
PICONINFO16 pii16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
ul = GetIconInfo(
|
||
|
HICON32(parg16->hicon),
|
||
|
&ii
|
||
|
);
|
||
|
|
||
|
pii16 = VDMPTR(parg16->lpiconinfo, sizeof(*pii16));
|
||
|
pii16->fIcon = (BOOL16)ii.fIcon;
|
||
|
pii16->xHotspot = (INT16)ii.xHotspot;
|
||
|
pii16->yHotspot = (INT16)ii.yHotspot;
|
||
|
pii16->hbmMask = GETHBITMAP16(ii.hbmMask);
|
||
|
pii16->hbmColor = GETHBITMAP16(ii.hbmColor);
|
||
|
FREEVDMPTR(pii16);
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32GetMenuItemInfo(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PGETMENUITEMINFO16 parg16;
|
||
|
ULONG ul;
|
||
|
MENUITEMINFO mii;
|
||
|
PMENUITEMINFO16 pmii16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETVDMPTR(parg16->lpmii, sizeof(*pmii16), pmii16);
|
||
|
|
||
|
mii.cbSize = sizeof(mii);
|
||
|
mii.fMask = pmii16->fMask;
|
||
|
|
||
|
FREEVDMPTR(pmii16);
|
||
|
|
||
|
ul = GetMenuItemInfo(
|
||
|
HMENU32(parg16->hmenu),
|
||
|
parg16->wIndex,
|
||
|
parg16->fByPosition,
|
||
|
&mii
|
||
|
);
|
||
|
|
||
|
putmenuiteminfo16(parg16->lpmii, &mii);
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32InsertMenuItem(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PINSERTMENUITEM16 parg16;
|
||
|
ULONG ul;
|
||
|
MENUITEMINFO mii;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
getmenuiteminfo16(parg16->lpmii, &mii);
|
||
|
|
||
|
ul = InsertMenuItem(
|
||
|
HMENU32(parg16->hmenu),
|
||
|
parg16->wIndex,
|
||
|
parg16->fByPosition,
|
||
|
&mii
|
||
|
);
|
||
|
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32SetMenuItemInfo(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PSETMENUITEMINFO16 parg16;
|
||
|
ULONG ul;
|
||
|
MENUITEMINFO mii;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
getmenuiteminfo16(parg16->lpmii, &mii);
|
||
|
|
||
|
ul = SetMenuItemInfo(
|
||
|
HMENU32(parg16->hmenu),
|
||
|
parg16->wIndex,
|
||
|
parg16->fByPosition,
|
||
|
&mii
|
||
|
);
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32GetMenuItemRect(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PGETMENUITEMRECT16 parg16;
|
||
|
ULONG ul;
|
||
|
RECT rc;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
ul = GetMenuItemRect(
|
||
|
HWND32(parg16->hwnd),
|
||
|
HMENU32(parg16->hmenu),
|
||
|
parg16->wIndex,
|
||
|
&rc
|
||
|
);
|
||
|
|
||
|
PUTRECT16(parg16->lprcScreen, &rc);
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32TrackPopupMenuEx(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PTRACKPOPUPMENUEX16 parg16;
|
||
|
ULONG ul;
|
||
|
TPMPARAMS tpmp;
|
||
|
LPTPMPARAMS lptpmp;
|
||
|
VPRECT16 vprcExclude;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
if (parg16->lpTpm) {
|
||
|
lptpmp = &tpmp;
|
||
|
tpmp.cbSize = sizeof(tpmp);
|
||
|
vprcExclude = parg16->lpTpm + offsetof(TPMPARAMS16, rcExclude);
|
||
|
GETRECT16(vprcExclude, &tpmp.rcExclude);
|
||
|
} else {
|
||
|
lptpmp = NULL;
|
||
|
}
|
||
|
|
||
|
ul = TrackPopupMenuEx(
|
||
|
HMENU32(parg16->hmenu),
|
||
|
parg16->wFlags,
|
||
|
parg16->x,
|
||
|
parg16->y,
|
||
|
HWND32(parg16->hwndOwner),
|
||
|
lptpmp
|
||
|
);
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WG32GetCharacterPlacement(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PGETCHARACTERPLACEMENT16 parg16;
|
||
|
ULONG ul;
|
||
|
PSZ pszText;
|
||
|
PGCP_RESULTS16 pgcp16;
|
||
|
GCP_RESULTS gcp;
|
||
|
|
||
|
//
|
||
|
// Thankfully on Win95 the 16-bit GCP_RESULTS structure
|
||
|
// points to 32-bit ints, so the structure thunking
|
||
|
// is trivial.
|
||
|
//
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETPSZPTR(parg16->lpszText, pszText);
|
||
|
GETVDMPTR(parg16->lpResults, sizeof(*pgcp16), pgcp16);
|
||
|
|
||
|
gcp.lStructSize = sizeof gcp;
|
||
|
gcp.nGlyphs = pgcp16->nGlyphs;
|
||
|
gcp.nMaxFit = pgcp16->nMaxFit;
|
||
|
GETOPTPTR(pgcp16->lpOutString, 1, gcp.lpOutString);
|
||
|
GETOPTPTR(pgcp16->lpOrder, 4, gcp.lpOrder);
|
||
|
GETOPTPTR(pgcp16->lpDx, 4, gcp.lpDx);
|
||
|
GETOPTPTR(pgcp16->lpCaretPos, 4, gcp.lpCaretPos);
|
||
|
GETOPTPTR(pgcp16->lpClass, 1, gcp.lpClass);
|
||
|
GETOPTPTR(pgcp16->lpGlyphs, 4, gcp.lpGlyphs);
|
||
|
|
||
|
ul = GetCharacterPlacement(
|
||
|
HDC32(parg16->hdc),
|
||
|
pszText,
|
||
|
parg16->wCount,
|
||
|
parg16->wMaxExtent,
|
||
|
&gcp,
|
||
|
parg16->dwFlags
|
||
|
);
|
||
|
|
||
|
pgcp16->nGlyphs = (SHORT)gcp.nGlyphs;
|
||
|
pgcp16->nMaxFit = (SHORT)gcp.nMaxFit;
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// On Win95, GetProductName returns "Windows 95".
|
||
|
// We'll return "Windows NT" unless something forces us
|
||
|
// to be identical.
|
||
|
//
|
||
|
// Two flavors: call with cbBuffer == 0 and it returns
|
||
|
// the length required minus 1 (a bug I think). Call with
|
||
|
// cbBuffer > 0 and it copies as much as possible and returns
|
||
|
// lpBuffer.
|
||
|
//
|
||
|
|
||
|
ULONG FASTCALL WK32GetProductName(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PGETPRODUCTNAME16 parg16;
|
||
|
ULONG ul;
|
||
|
PSZ pszBuffer;
|
||
|
static char szProductName[] = "Windows NT";
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
if (0 == parg16->cbBuffer) {
|
||
|
ul = (sizeof szProductName) - 1;
|
||
|
} else {
|
||
|
GETVDMPTR(parg16->lpBuffer, parg16->cbBuffer, pszBuffer);
|
||
|
WOW32VERIFY(pszBuffer == lstrcpyn(pszBuffer, szProductName, parg16->cbBuffer));
|
||
|
FREEVDMPTR(pszBuffer);
|
||
|
ul = parg16->lpBuffer;
|
||
|
}
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
typedef struct _tagWOWDRAWSTATECALLBACK {
|
||
|
VPVOID vpfnCallback;
|
||
|
LPARAM lparamUser;
|
||
|
} WOWDRAWSTATECALLBACK, *PWOWDRAWSTATECALLBACK;
|
||
|
|
||
|
|
||
|
BOOL CALLBACK WOWDrawStateCallback(HDC hdc, LPARAM lData, WPARAM wData, int cx, int cy)
|
||
|
{
|
||
|
PWOWDRAWSTATECALLBACK pwds = (PWOWDRAWSTATECALLBACK) lData;
|
||
|
ULONG ul;
|
||
|
WORD awCallbackArgs[6];
|
||
|
|
||
|
awCallbackArgs[0] = (WORD)(SHORT)cy;
|
||
|
awCallbackArgs[1] = (WORD)(SHORT)cx;
|
||
|
awCallbackArgs[2] = (WORD)wData;
|
||
|
awCallbackArgs[3] = LOWORD(pwds->lparamUser);
|
||
|
awCallbackArgs[4] = HIWORD(pwds->lparamUser);
|
||
|
awCallbackArgs[5] = GETHDC16(hdc);
|
||
|
|
||
|
WOWCallback16Ex(
|
||
|
pwds->vpfnCallback,
|
||
|
WCB16_PASCAL,
|
||
|
sizeof awCallbackArgs,
|
||
|
awCallbackArgs,
|
||
|
&ul // retcode filled into ul
|
||
|
);
|
||
|
|
||
|
return LOWORD(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32DrawState(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PDRAWSTATE16 parg16;
|
||
|
ULONG ul;
|
||
|
WOWDRAWSTATECALLBACK wds;
|
||
|
DRAWSTATEPROC pDrawStateCallback = NULL;
|
||
|
LPARAM lData;
|
||
|
HBRUSH hbr;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
switch (parg16->uFlags & DST_TYPEMASK) {
|
||
|
|
||
|
case DST_COMPLEX:
|
||
|
if (parg16->pfnCallBack) {
|
||
|
wds.vpfnCallback = parg16->pfnCallBack;
|
||
|
wds.lparamUser = parg16->lData;
|
||
|
lData = (LPARAM) &wds;
|
||
|
pDrawStateCallback = (DRAWSTATEPROC) WOWDrawStateCallback;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case DST_TEXT:
|
||
|
case DST_PREFIXTEXT:
|
||
|
lData = (LPARAM) VDMPTR(parg16->lData, parg16->wData);
|
||
|
break;
|
||
|
|
||
|
case DST_ICON:
|
||
|
lData = (LPARAM) HICON32( (WORD) parg16->lData );
|
||
|
break;
|
||
|
|
||
|
case DST_BITMAP:
|
||
|
lData = (LPARAM) HBITMAP32(parg16->lData);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
WOW32WARNMSGF(FALSE, ("WOW32: Unknown DST_ code to DrawState %x.\n",
|
||
|
parg16->uFlags & DST_TYPEMASK));
|
||
|
}
|
||
|
|
||
|
hbr = (parg16->uFlags & DSS_MONO)
|
||
|
? HBRUSH32(parg16->hbrFore)
|
||
|
: NULL;
|
||
|
|
||
|
ul = GETBOOL16(DrawState(
|
||
|
HDC32(parg16->hdcDraw),
|
||
|
hbr,
|
||
|
pDrawStateCallback,
|
||
|
lData,
|
||
|
parg16->wData,
|
||
|
parg16->x,
|
||
|
parg16->y,
|
||
|
parg16->cx,
|
||
|
parg16->cy,
|
||
|
parg16->uFlags
|
||
|
));
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32GetAppVer(PVDMFRAME pFrame)
|
||
|
{
|
||
|
return ((PTDB)SEGPTR(pFrame->wTDB,0))->TDB_ExpWinVer;
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32CopyImage(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PCOPYIMAGE16 parg16;
|
||
|
ULONG ul;
|
||
|
BOOL fIconCursor; // as opposed to bitmap
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
|
||
|
//
|
||
|
// NOTE first parameter to Win16 CopyImage is hinstOwner,
|
||
|
// which isn't a parameter to Win32 CopyImage. It may
|
||
|
// be that we'll need to special-case LR_COPYFROMRESOURCE
|
||
|
// to work correctly.
|
||
|
//
|
||
|
|
||
|
fIconCursor = (parg16->wType != IMAGE_BITMAP);
|
||
|
|
||
|
ul = (ULONG) CopyImage(
|
||
|
(fIconCursor)
|
||
|
? HICON32(parg16->hImage)
|
||
|
: HBITMAP32(parg16->hImage),
|
||
|
parg16->wType,
|
||
|
parg16->cxNew,
|
||
|
parg16->cyNew,
|
||
|
parg16->wFlags
|
||
|
);
|
||
|
|
||
|
ul = (fIconCursor)
|
||
|
? GETHICON16(ul)
|
||
|
: GETHBITMAP16(ul);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// WowMsgBoxIndirectCallback is called by User32 when a 16-bit app
|
||
|
// calls MessageBoxIndirect and specifies a help callback proc.
|
||
|
// User32 passes the 16:16 callback address to us along with a
|
||
|
// flat pointer to the HELPINFO structure to pass to the callback.
|
||
|
//
|
||
|
|
||
|
VOID FASTCALL WowMsgBoxIndirectCallback(DWORD vpfnCallback, LPHELPINFO lpHelpInfo)
|
||
|
{
|
||
|
VPVOID vpHelpInfo16;
|
||
|
LPHELPINFO lpHelpInfo16;
|
||
|
|
||
|
//
|
||
|
// As best as I can tell Win95 passes the WIN32 HELPINFO struct back to the
|
||
|
// 16-bit callback proc (i.e. there is no HELPINFO16).
|
||
|
//
|
||
|
|
||
|
// be sure allocation size matches stackfree16() size below
|
||
|
vpHelpInfo16 = stackalloc16( sizeof(*lpHelpInfo16) );
|
||
|
|
||
|
GETVDMPTR(vpHelpInfo16, sizeof(*lpHelpInfo16), lpHelpInfo16);
|
||
|
RtlCopyMemory(lpHelpInfo16, lpHelpInfo, sizeof(*lpHelpInfo16));
|
||
|
FREEVDMPTR(lpHelpInfo16);
|
||
|
|
||
|
WOWCallback16(
|
||
|
vpfnCallback,
|
||
|
vpHelpInfo16
|
||
|
);
|
||
|
|
||
|
if(vpHelpInfo16) {
|
||
|
stackfree16(vpHelpInfo16, sizeof(*lpHelpInfo16));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WU32MessageBoxIndirect(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PMESSAGEBOXINDIRECT16 parg16;
|
||
|
ULONG ul;
|
||
|
PMSGBOXPARAMS16 pmbp16;
|
||
|
MSGBOXPARAMS mbp;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETVDMPTR(parg16->lpmbp, sizeof *pmbp16, pmbp16);
|
||
|
|
||
|
mbp.cbSize = sizeof mbp;
|
||
|
mbp.hwndOwner = HWND32(pmbp16->hwndOwner);
|
||
|
mbp.hInstance = HINSTRES32(pmbp16->hInstance);
|
||
|
GETPSZIDPTR(pmbp16->lpszText, mbp.lpszText);
|
||
|
GETPSZIDPTR(pmbp16->lpszCaption, mbp.lpszCaption);
|
||
|
mbp.dwStyle = pmbp16->dwStyle;
|
||
|
GETPSZIDPTR(pmbp16->lpszIcon, mbp.lpszIcon);
|
||
|
mbp.dwContextHelpId = pmbp16->dwContextHelpId;
|
||
|
if (pmbp16->vpfnMsgBoxCallback) {
|
||
|
MarkWOWProc(pmbp16->vpfnMsgBoxCallback, mbp.lpfnMsgBoxCallback)
|
||
|
} else {
|
||
|
mbp.lpfnMsgBoxCallback = 0;
|
||
|
}
|
||
|
mbp.dwLanguageId = pmbp16->dwLanguageId;
|
||
|
|
||
|
ul = GETINT16( MessageBoxIndirect(&mbp) );
|
||
|
|
||
|
FREEARGPTR(pFrame);
|
||
|
|
||
|
return ul;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// was in wow.it: HGDI CreateEnhMetaFile(HGDI, PTR, PTR, PTR);
|
||
|
// Using real thunk to ensure Win32 curdir matches Win16.
|
||
|
//
|
||
|
ULONG FASTCALL WG32CreateEnhMetaFile(PVDMFRAME pFrame)
|
||
|
{
|
||
|
register PCREATEENHMETAFILE16 parg16;
|
||
|
ULONG ul;
|
||
|
LPCSTR lpszFile, lpszDescription;
|
||
|
CONST RECT *prclFrame;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(*parg16), parg16);
|
||
|
GETVDMPTR(parg16->lpszFile, 1, lpszFile);
|
||
|
// note lpszDescription is really two SZs with extra terminator
|
||
|
GETVDMPTR(parg16->lpszDescription, 3, lpszDescription);
|
||
|
// note lprclFrame is a LPRECTL, a Win32 RECT
|
||
|
GETVDMPTR(parg16->lprclFrame, sizeof(*prclFrame), prclFrame);
|
||
|
|
||
|
//
|
||
|
// Make sure the Win32 current directory matches this task's.
|
||
|
//
|
||
|
|
||
|
UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
|
||
|
|
||
|
ul = GETHDC16(CreateEnhMetaFile(
|
||
|
HDC32(parg16->hdcRef),
|
||
|
lpszFile,
|
||
|
prclFrame,
|
||
|
lpszDescription
|
||
|
));
|
||
|
|
||
|
FREEVDMPTR(prclFrame);
|
||
|
FREEVDMPTR(lpszDescription);
|
||
|
FREEVDMPTR(lpszFile);
|
||
|
|
||
|
return ul;
|
||
|
}
|