|
|
//*****************************************************************************
//
// Cursor and Icon compatibility Support -
//
// Support for apps - which do a GlobalLock on Cursors and Icons to
// create headaches for us.
//
// A compatibility issue.
//
//
// 21-Apr-92 NanduriR Created.
//
//*****************************************************************************
#include "precomp.h"
#pragma hdrstop
MODNAME(wcuricon.c);
extern void FreeAccelAliasEntry(LPACCELALIAS lpT);
LPCURSORICONALIAS lpCIAlias = NULL; UINT cPendingCursorIconUpdates = 0;
//*****************************************************************************
//
// W32CreateCursorIcon32 -
//
// Creates a 32bit Cursor or Icon given a WIN31 Cursor or Icon HANDLE.
// The Cursor of Icon handle must correspond to an object that has
// been created (like CreateIcon). That is because the format of a
// resource cursor differs from that of a 'created' cursor.
//
// Returns the 32bit handle
//
//*****************************************************************************
HANDLE W32CreateCursorIcon32(LPCURSORICONALIAS lpCIAliasIn) { HANDLE hT; PCURSORSHAPE16 pcurs16; UINT flType;
int nWidth; int nHeight; int nPlanes; int nBitsPixel; DWORD nBytesAND; LPBYTE lpBitsAND; LPBYTE lpBitsXOR; int ScanLen16;
pcurs16 = (PCURSORSHAPE16)lpCIAliasIn->pbDataNew;
flType = lpCIAliasIn->flType; if (flType & HANDLE_TYPE_UNKNOWN) { if (PROBABLYCURSOR(FETCHWORD(pcurs16->BitsPixel), FETCHWORD(pcurs16->Planes))) flType = HANDLE_TYPE_CURSOR; else flType = HANDLE_TYPE_ICON; }
nWidth = INT32(FETCHWORD(pcurs16->cx)); nHeight = INT32(FETCHWORD(pcurs16->cy));
nPlanes = 1; nBitsPixel = 1; // Monochrome
// Get the AND mask bits
ScanLen16 = (((nWidth*nBitsPixel)+15)/16) * 2 ; // bytes/scan in 16 bit world
// effectively nBitsPixel is 1
nBytesAND = ScanLen16*nHeight*nPlanes; lpBitsAND = (LPBYTE)pcurs16 + sizeof(CURSORSHAPE16);
// Get the XOR mask bits
if (flType == HANDLE_TYPE_ICON) { nPlanes = INT32(FETCHWORD(pcurs16->Planes)); nBitsPixel = INT32(FETCHWORD(pcurs16->BitsPixel)); // the actual value
}
lpBitsXOR = (LPBYTE)lpBitsAND + nBytesAND;
lpCIAliasIn->flType = (BYTE)flType;
if (flType & HANDLE_TYPE_CURSOR) { hT = CreateCursor(HMODINST32(lpCIAliasIn->hInst16), (INT)FETCHWORD(pcurs16->xHotSpot), (INT)FETCHWORD(pcurs16->yHotSpot), nWidth, nHeight, lpBitsAND, lpBitsXOR); } else if (flType & HANDLE_TYPE_ICON) { hT = CreateIcon(HMODINST32(lpCIAliasIn->hInst16), nWidth, nHeight, (BYTE)nPlanes, (BYTE)nBitsPixel, lpBitsAND, lpBitsXOR);
}
return hT; }
//*****************************************************************************
//
// W32Create16BitCursorIcon -
//
// Creates a WIN31 compatible Cursor or Icon given the full 16bit
// definition of the object to be created.
//
//
//*****************************************************************************
HAND16 W32Create16BitCursorIcon(HAND16 hInst16, INT xHotSpot, INT yHotSpot, INT nWidth, INT nHeight, INT nPlanes, INT nBitsPixel, LPBYTE lpBitsAND, LPBYTE lpBitsXOR, INT nBytesAND, INT nBytesXOR ) { WORD h16 = 0; WORD wTotalSize; PCURSORSHAPE16 pcshape16; VPVOID vp; LPBYTE lpT;
UNREFERENCED_PARAMETER(hInst16);
wTotalSize = (WORD)(sizeof(CURSORSHAPE16) + nBytesAND + nBytesXOR);
vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE, wTotalSize, &h16); if (vp != (VPVOID)NULL) { GETVDMPTR(vp, wTotalSize, pcshape16);
STOREWORD(pcshape16->xHotSpot, xHotSpot); STOREWORD(pcshape16->yHotSpot, yHotSpot); STOREWORD(pcshape16->cx, nWidth); STOREWORD(pcshape16->cy, nHeight); STOREWORD(pcshape16->cbWidth, (((nWidth + 0x0F) & ~0x0F) >> 3)); pcshape16->Planes = (BYTE)nPlanes; pcshape16->BitsPixel = (BYTE)nBitsPixel;
lpT = (LPBYTE)pcshape16 + sizeof(CURSORSHAPE16); RtlCopyMemory(lpT, lpBitsAND, nBytesAND); RtlCopyMemory(lpT+nBytesAND, lpBitsXOR, nBytesXOR);
FLUSHVDMPTR(vp, wTotalSize, pcshape16); FREEVDMPTR(pcshape16); }
GlobalUnlock16(h16); return (HAND16)h16; }
//*****************************************************************************
//
// GetCursorIconAlias32 -
//
// Returns a 32bit handle given a 16bit Cursor or Icon HANDLE
// Creates the 32bit Cursor or Icon if necessary.
//
// Returns the 32bit handle
//
//*****************************************************************************
HANDLE GetCursorIconAlias32(HAND16 h16, UINT flType) {
LPCURSORICONALIAS lpT; VPVOID vp; UINT cb; PCURSORSHAPE16 pcurs16;
if (h16 == (HAND16)0) return (ULONG)NULL;
lpT = FindCursorIconAlias((ULONG)h16, HANDLE_16BIT); if (lpT) { return lpT->h32; } else {
//
// BEGIN: Check for Bogus handle
//
if (BOGUSHANDLE(h16)) return (HANDLE)NULL;
#if defined(FE_SB)
//In Excel95, XLVISEX.EXE use wrong cursor handle
//that is already freed. So, we double check this handle
//whether it is valid or not. 09/27/96 bklee.
if (!FindCursorIconAliasInUse((ULONG)h16)) return (HANDLE)NULL; #endif
vp = RealLockResource16(h16, (PINT)&cb); if (vp == (VPVOID)NULL) return (ULONG)NULL;
GETVDMPTR(vp, cb, pcurs16);
if (pcurs16->cbWidth != (SHORT)(((pcurs16->cx + 0x0f) & ~0x0f) >> 3)) return (ULONG)NULL;
//
// END: Check for Bogus handle
//
lpT = AllocCursorIconAlias(); if (!lpT) { return (ULONG)NULL; }
lpT->h16 = h16; lpT->hTask16 = CURRENTPTD()->htask16;
lpT->vpData = vp; lpT->cbData = (WORD)cb; lpT->pbDataNew = (LPBYTE)pcurs16;
lpT->pbDataOld = malloc_w(cb); if (lpT->pbDataOld) { RtlCopyMemory(lpT->pbDataOld, lpT->pbDataNew, cb); }
lpT->h32 = (HAND32)W32CreateCursorIcon32(lpT);
GlobalUnlock16(h16); FREEVDMPTR(pcurs16); lpT->pbDataNew = (LPBYTE)NULL;
if (lpT->h32) { lpT->fInUse = TRUE; SetCursorIconFlag(h16, TRUE); } else lpT->fInUse = FALSE;
return lpT->h32; } }
//*****************************************************************************
//
// GetCursorIconAlias16 -
//
// Returns a 16bit handle given a 32bit Cursor or Icon HANDLE
// Creates the 16bit Cursor or Icon if necessary.
//
// Returns the 16bit handle
//
//*****************************************************************************
HAND16 GetCursorIconAlias16(HAND32 h32, UINT flType) {
LPCURSORICONALIAS lpT;
if (h32 == (HAND32)0) return (HAND16)NULL;
lpT = FindCursorIconAlias((ULONG)h32, HANDLE_32BIT); if (lpT) { return lpT->h16; } else { HAND16 h16;
// HACK:
// From experience: numeric values of 32bit standard cursors and icons
// are very small. so check for these handles.
// we should not create aliases for standard cursors and
// icons here.
WOW32ASSERT((UINT)h32 >= 100);
//
// Always generate valid handles.
//
h16 = W32Create16BitCursorIconFrom32BitHandle(h32, (HAND16)NULL, (PUINT)NULL); if (h16) { h16 = SetupCursorIconAlias((HAND16)NULL, h32, h16, flType, NULL, (WORD)NULL); } return h16; } }
//*****************************************************************************
//
// AllocCursorIconAlias -
//
// Allocates and reurns pointer to CURSORICONALIAS buffer.
//
//*****************************************************************************
LPCURSORICONALIAS AllocCursorIconAlias() { LPCURSORICONALIAS lpT;
for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) { if (!lpT->fInUse) break; }
if (lpT == NULL) { lpT = (LPCURSORICONALIAS)malloc_w_small(sizeof(CURSORICONALIAS)); if (lpT) { lpT->lpNext = lpCIAlias; lpCIAlias = lpT; } else { LOGDEBUG(0, ("AllocCursorIconAlias: malloc_w_small for alias failed\n")); } }
if (lpT != NULL) { lpT->fInUse = TRUE; lpT->h16 = (HAND16)0; lpT->h32 = (HAND32)0; lpT->vpData = (VPVOID)NULL; lpT->cLock = 0; lpT->cbData = 0; lpT->pbDataOld = (LPBYTE)NULL; lpT->pbDataNew = (LPBYTE)NULL; lpT->lpszName = (LPBYTE)NULL;
lpT->flType = HANDLE_TYPE_UNKNOWN; lpT->hInst16 = (HAND16)0; lpT->hMod16 = (HAND16)0; lpT->hTask16 = (HTASK16)0; lpT->hRes16 = 0; }
return lpT; }
//*****************************************************************************
//
// FindCursorIconAlias -
//
// Searches for the given handle and returns corresponding
// LPCURSORICONALIAS.
//
//*****************************************************************************
LPCURSORICONALIAS FindCursorIconAlias(ULONG hCI, UINT flHandleSize) { LPCURSORICONALIAS lpT; LPCURSORICONALIAS lpTprev;
lpTprev = (LPCURSORICONALIAS)NULL; for (lpT = lpCIAlias; lpT != NULL; lpTprev = lpT, lpT = lpT->lpNext) { if (lpT->fInUse) { if ((flHandleSize == HANDLE_16BIT && lpT->h16 == (HAND16)hCI) || (flHandleSize == HANDLE_32BIT && lpT->h32 == (HAND32)hCI)) break; else if (flHandleSize == HANDLE_16BITRES && lpT->hRes16 && (lpT->hRes16 == (HAND16)hCI))
break; }
}
if (lpT) { if (lpTprev) { lpTprev->lpNext = lpT->lpNext; lpT->lpNext = lpCIAlias; lpCIAlias = lpT; } } return lpT; }
#if defined(FE_SB)
//*****************************************************************************
//
// FindCursorIconAliasInUse -
//
// Searches for the given handle and returns corresponding
// lpT->fInUse.
//
// 09/27/96 bklee
//*****************************************************************************
BOOL FindCursorIconAliasInUse(ULONG hCI) { LPCURSORICONALIAS lpT; LPCURSORICONALIAS lpTprev;
lpTprev = (LPCURSORICONALIAS)NULL; for (lpT = lpCIAlias; lpT != NULL; lpTprev = lpT, lpT = lpT->lpNext) { if (lpT->h16 == (HAND16)hCI) return lpT->fInUse; }
return TRUE; } #endif
//*****************************************************************************
//
// DeleteCursorIconAlias -
//
// Searches for the given handle and if a 16bit handle frees the memory
// allocated for the Object. The alias table is not freed.
//
//*****************************************************************************
BOOL DeleteCursorIconAlias(ULONG hCI, UINT flHandleSize) { LPCURSORICONALIAS lpT;
WOW32ASSERT(flHandleSize == HANDLE_16BIT);
for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) { if (lpT->fInUse && !(lpT->flType & HANDLE_TYPE_WOWGLOBAL)) {
// Have we found the handle mapping?
if (flHandleSize == HANDLE_16BIT && lpT->h16 == (HAND16)hCI) {
if (lpT->hTask16) {
// We don't want to free the handle mapping when
// the handle corresponds to a 16-bit resource, i.e.
// hRes16 is non-null.
if (!(lpT->hRes16)) { SetCursorIconFlag(lpT->h16, FALSE); GlobalUnlockFree16(RealLockResource16((HMEM16)hCI, NULL)); free_w(lpT->pbDataOld); lpT->fInUse = FALSE; return TRUE; } } else { WOW32ASSERT(FALSE); }
break; } }
}
return FALSE; }
//*****************************************************************************
//
// FreeCursorIconAlias -
//
// Frees all Cursors and Icons of the specified task.
//
//
//*****************************************************************************
BOOL FreeCursorIconAlias(HAND16 hand16, ULONG ulFlags) { LPCURSORICONALIAS lpT;
for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) { if (lpT->fInUse && (((ulFlags & CIALIAS_HMOD) && (lpT->hMod16 == hand16)) || ((ulFlags & CIALIAS_HTASK) && (lpT->hTask16 == hand16)))) {
if (ulFlags & CIALIAS_TASKISGONE) { // We're here if this function is called after the task
// cleanup on the 16bit side... then we really can't
// callback. Setting appropriate fields to NULL will
// avoid callbacks, but will leak the corresponding
// memory. The asserts will catch this on a checked
// build.
WOW32ASSERT(lpT->h16==(HAND16)NULL); WOW32ASSERT(lpT->hRes16==(HAND16)NULL); lpT->h16 = (HAND16)NULL; lpT->hRes16 = (HAND16)NULL; } InvalidateCursorIconAlias(lpT); } }
return TRUE; }
//*****************************************************************************
//
// SetupCursorIconAlias -
//
// Sets up association (alias) between a 32bit and a 16bit handle.
// given both the handles.
//
//
//*****************************************************************************
HAND16 SetupCursorIconAlias(HAND16 hInst16, HAND32 h32, HAND16 h16, UINT flType, LPBYTE lpResName, WORD hRes16)
{ LPCURSORICONALIAS lpT; VPVOID vp; INT cb;
lpT = AllocCursorIconAlias(); // paranoid check for memory exaust
if (!lpT) { return (HAND16)NULL; }
lpT->fInUse = TRUE; lpT->h16 = h16; lpT->h32 = h32; lpT->flType = (BYTE)flType; if (!(flType & HANDLE_TYPE_WOWGLOBAL)) { lpT->hInst16 = hInst16; lpT->hMod16 = GETHMOD16(HMODINST32(hInst16)); lpT->hTask16 = CURRENTPTD()->htask16; lpT->hRes16 = hRes16;
vp = RealLockResource16(h16, &cb); if (vp == (VPVOID)NULL) return (HAND16)NULL;
lpT->vpData = vp; lpT->cbData = (WORD)cb; GETVDMPTR(vp, cb, lpT->pbDataNew);
lpT->pbDataOld = malloc_w(cb); if (lpT->pbDataOld) { RtlCopyMemory(lpT->pbDataOld, lpT->pbDataNew, cb); }
if (hRes16) { lpT->lpszName = lpResName; // if this is a string...
if ((WORD)HIWORD(lpResName) != (WORD)NULL) { UINT cbStr; cbStr = strlen(lpResName)+1; // note: strlen+1 will force memcpy to copy the null from the
// src string.
if (lpT->lpszName = malloc_w_small(cbStr)) { memcpy (lpT->lpszName, lpResName, cbStr); } } }
} // the alias has been setup. Now turn on the GAH_CURSORICON flag.
SetCursorIconFlag(h16, TRUE);
return h16; }
//*****************************************************************************
//
// SetupResCursorIconAlias -
//
// Sets up association (alias) between a 32bit and a 16bit handle.
// given the 32bit handle and a handle to a 16bit resource.
//
//
//*****************************************************************************
HAND16 SetupResCursorIconAlias(HAND16 hInst16, HAND32 h32, LPBYTE lpResName, WORD hRes16, UINT flType) { LPCURSORICONALIAS lpT; HAND16 h16 = 0; HAND16 h16Res = 0; UINT cb;
if (hRes16) { // 16bit resource has been loaded. We always want to return the
// SAME 16bit handle no matter howmany times the 'LoadIcon' or
// LoadCursor has been called.
h16Res = LOWORD(hRes16); lpT = FindCursorIconAlias(h16Res, HANDLE_16BITRES); } else {
// Resource handle is NULL. The Resource must have been a
// standard predefined resource like ARROW etc.
lpT = FindCursorIconAlias((ULONG)h32, HANDLE_32BIT); flType |= HANDLE_TYPE_WOWGLOBAL; }
if (lpT == NULL) { h16 = W32Create16BitCursorIconFrom32BitHandle(h32, hInst16, &cb); h16 = SetupCursorIconAlias(hInst16, h32, h16, flType, lpResName, hRes16); } else { if (lpT->flType & HANDLE_TYPE_WOWGLOBAL) {
// eachtime we should get the same h32 from usersrv.
//
WOW32ASSERT(lpT->h32 == h32); } else { if (lpT->h32 != h32) { if (lpT->flType == HANDLE_TYPE_CURSOR) DestroyCursor(h32); else DestroyIcon(h32); } ReplaceCursorIcon(lpT); }
h16 = lpT->h16; }
return h16; }
//*****************************************************************************
//
// SetCursorIconFlag -
//
// Sets/Clears the GAH_CURSORICONFLAG in the global arean header. This flag
// is used to identify Cursors and Icon when they are GlobaLocked and
// GlobalUnlocked
//
//*****************************************************************************
ULONG SetCursorIconFlag(HAND16 h16, BOOL fSet) { PARM16 Parm16; VPVOID vp = 0;
Parm16.WndProc.wParam = h16; Parm16.WndProc.wMsg = (WORD)fSet; CallBack16(RET_SETCURSORICONFLAG, &Parm16, 0, &vp); return (ULONG)0; }
//*****************************************************************************
//
// UpdateCursorIcon -
//
// Compares the new object data with the old. If any of the bytes differ
// the old object is replaced with the new.
//
//*****************************************************************************
VOID UpdateCursorIcon() { LPCURSORICONALIAS lpT; UINT cbData; LPBYTE lpBitsNew, lpBitsOld; UINT i = 0;
for (lpT = lpCIAlias; lpT != NULL ; lpT = lpT->lpNext) { if (lpT->fInUse && lpT->cLock) { GETVDMPTR(lpT->vpData, lpT->cbData, lpT->pbDataNew); if (lpT->hRes16) { if (lpT->flType == HANDLE_TYPE_ICON) { lpBitsNew = lpT->pbDataNew + sizeof(BITMAPINFOHEADER16); lpBitsOld = lpT->pbDataOld + sizeof(BITMAPINFOHEADER16); cbData = lpT->cbData - sizeof(BITMAPINFOHEADER16); } else { lpBitsNew = lpT->pbDataNew + sizeof(CURSORRESOURCE16); lpBitsOld = lpT->pbDataOld + sizeof(CURSORRESOURCE16); cbData = lpT->cbData - sizeof(CURSORRESOURCE16); }
} else { lpBitsNew = lpT->pbDataNew + sizeof(CURSORSHAPE16); lpBitsOld = lpT->pbDataOld + sizeof(CURSORSHAPE16); cbData = lpT->cbData - sizeof(CURSORSHAPE16); }
if (! RtlEqualMemory(lpBitsNew, lpBitsOld, cbData)) ReplaceCursorIcon(lpT);
if (cPendingCursorIconUpdates == ++i) break; }
}
}
//*****************************************************************************
//
// ReplaceCursorIcon -
//
// Updates the current cursor or icon. Creates a new icon or cursor and
// replaces the contents of the old handle with that of the new.
//
// returns TRUE for success.
//
//*****************************************************************************
BOOL ReplaceCursorIcon(LPCURSORICONALIAS lpIn) { HANDLE hT32;
if (lpIn != NULL) {
// Get the data
GETVDMPTR(lpIn->vpData, lpIn->cbData, lpIn->pbDataNew);
// Create the object
hT32 = (HAND32)W32CreateCursorIcon32(lpIn);
// SetCursorConents will replace the contents of OLD cursor/icon
// with that of the new handle and destroy the new handle
SetCursorContents(lpIn->h32, hT32);
// replace the old object data with the new
RtlCopyMemory(lpIn->pbDataOld, lpIn->pbDataNew, lpIn->cbData); FREEVDMPTR(lpIn->pbDataNew); lpIn->pbDataNew = (LPBYTE)NULL;
}
return (BOOL)TRUE;
}
//*****************************************************************************
//
// WK32WowCursorIconOp -
//
// Gets called when/from GlobalLock or GlobalUnlock are called. The fLock
// flag is TRUE if called from GlobalLock else it is FALSE.
//
//*****************************************************************************
BOOL FASTCALL WK32WowCursorIconOp(PVDMFRAME pFrame) {
PWOWCURSORICONOP16 prci16; HAND16 h16; LPCURSORICONALIAS lpT; BOOL fLock; WORD wFuncId; UINT cLockT;
GETARGPTR(pFrame, sizeof(WOWCURSORICONOP16), prci16); wFuncId = FETCHWORD(prci16->wFuncId); h16 = (HAND16)FETCHWORD(prci16->h16);
lpT = FindCursorIconAlias((ULONG)h16, HANDLE_16BIT); // This is a Cursor or Icon
if (lpT != NULL) {
if (wFuncId == FUN_GLOBALLOCK || wFuncId == FUN_GLOBALUNLOCK) {
if (!(lpT->flType & HANDLE_TYPE_WOWGLOBAL)) {
fLock = (wFuncId == FUN_GLOBALLOCK);
// Store the current lockcount.
cLockT = lpT->cLock;
// Update the Lock count
lpT->cLock = fLock ? ++lpT->cLock : --lpT->cLock;
if (lpT->cLock == 0) {
// New lock count == 0 implies that it was decremented from
// 1 to 0 thereby impling that it was one of the cursors that
// was being updated regularly.
// Decrement the global count and update the cursor one last
// time
cPendingCursorIconUpdates--; ReplaceCursorIcon(lpT); } else if (fLock && cLockT == 0) {
// If previous Lockcount was zero and the object is being locked
// then it means that this is the very first time that the object
// is being locked
cPendingCursorIconUpdates++; } } } else if (wFuncId == FUN_GLOBALFREE) {
// The h16 has not yet been GlobalFreed. We return TRUE if h16 can
// be freed else FALSE. The h16 can be freed only if it is not a
// global handle. ie, it doesn't correspond to a predefined cursor
// Also we donot free the handle if h16 corresponds to a resource.
// CorelDraw 3.0 calls FreeResource(h16) and then SetCursor(h16)
// thus GPing.
BOOL fFree;
fFree = !((lpT->flType & HANDLE_TYPE_WOWGLOBAL) || lpT->hRes16); if (fFree) { // Set handle to NULL so that InvalidateCursorIconAlias
// doesn't try to free it.
lpT->h16 = 0; InvalidateCursorIconAlias(lpT); }
return (BOOL)fFree;
} else { LOGDEBUG(0, ("WK32WowCursorIconOp: Unknown Func Id\n")); } }
// else if this is a GlobalFree call
else if (wFuncId == FUN_GLOBALFREE) {
// and if this is a handle to an accelerator
if(lpT = (LPCURSORICONALIAS)FindAccelAlias((HANDLE)h16, HANDLE_16BIT)) {
// free it from the accelerator alias list
FreeAccelAliasEntry((LPACCELALIAS) lpT);
// cause this hMem16 to really be free'd in 16-bit GlobalFree
return TRUE; } }
return TRUE; }
//*****************************************************************************
//
// W32Create16BitResCursorIconFrom32BitHandle -
//
// Creates a WIN31 compatible Cursor or Icon given a 32bit cursor or icon
// handle. This is primarily used to create a 16bit Cursor or Icon which
// has been loaded from a 16bit resource.
//
//
// returns 16bit handle
//*****************************************************************************
HAND16 W32Create16BitCursorIconFrom32BitHandle(HANDLE h32, HAND16 hInst16, PUINT pcbData) { HAND16 h16 = 0; ICONINFO iinfo; BITMAP bm; BITMAP bmClr; UINT nBytesAND = 0; UINT nBytesXOR = 0; LPBYTE lpBitsAND, lpBitsXOR;
if (GetIconInfo(h32, &iinfo)) { if (GetObject(iinfo.hbmMask, sizeof(BITMAP), &bm)) { nBytesAND = GetBitmapBits(iinfo.hbmMask, 0, (LPBYTE)NULL); WOW32WARNMSG(nBytesAND,("WOW: W32C16BCIFBH: nBytesAND == 0\n")); if (iinfo.hbmColor) { GetObject(iinfo.hbmColor, sizeof(BITMAP), &bmClr); nBytesXOR = GetBitmapBits(iinfo.hbmColor, 0, (LPBYTE)NULL); WOW32WARNMSG(nBytesXOR,("WOW: W32C16BCIFBH: nBytesAND == 0\n")); } else { bm.bmHeight /= 2; nBytesAND /= 2; nBytesXOR = nBytesAND; }
if (pcbData) { *pcbData = nBytesAND + nBytesXOR + sizeof(CURSORSHAPE16); }
lpBitsAND = malloc_w(nBytesAND + nBytesXOR); if (lpBitsAND != NULL) { lpBitsXOR = lpBitsAND + nBytesAND; GetBitmapBits(iinfo.hbmMask, (iinfo.hbmColor) ? nBytesAND : (nBytesAND * 2), lpBitsAND); if (iinfo.hbmColor) GetBitmapBits(iinfo.hbmColor, nBytesXOR, lpBitsXOR);
h16 = W32Create16BitCursorIcon(hInst16, iinfo.xHotspot, iinfo.yHotspot, bm.bmWidth, bm.bmHeight, (iinfo.hbmColor) ? bmClr.bmPlanes : bm.bmPlanes, (iinfo.hbmColor) ? bmClr.bmBitsPixel : bm.bmBitsPixel, lpBitsAND, lpBitsXOR, (INT)nBytesAND, (INT)nBytesXOR); free_w(lpBitsAND);
}
} DeleteObject(iinfo.hbmMask); if (iinfo.hbmColor) { DeleteObject(iinfo.hbmColor); } }
return h16;
}
//*****************************************************************************
//
// GetClassCursorIconAlias32 -
//
// Returns a 32bit handle given a 16bit Cursor or Icon HANDLE
// DOES NOT Create the 32bit Cursor or Icon if there is no alias.
// This is called in RegisterClass only - to support those apps which
// pass a bogus handle for WNDCLASS.hIcon.
//
// Returns the 32bit handle
//
//*****************************************************************************
HANDLE GetClassCursorIconAlias32(HAND16 h16) {
LPCURSORICONALIAS lpT;
if (h16 == (HAND16)0) return (ULONG)NULL;
lpT = FindCursorIconAlias((ULONG)h16, HANDLE_16BIT); if (lpT) { return lpT->h32; } else return (HANDLE)NULL; }
//*****************************************************************************
//
// InvalidateCursorIconAlias -
//
// Frees the allocated objects.
//
//*****************************************************************************
VOID InvalidateCursorIconAlias(LPCURSORICONALIAS lpT) { VPVOID vp=0; PARM16 Parm16;
if (!lpT->fInUse) return;
if (lpT->h16) { SetCursorIconFlag(lpT->h16, FALSE); GlobalUnlockFree16(RealLockResource16((HMEM16)lpT->h16, NULL)); }
if (lpT->hRes16) { Parm16.WndProc.wParam = (HAND16) lpT->hRes16; CallBack16(RET_FREERESOURCE, &Parm16, 0, &vp); }
if (lpT->h32) { if (lpT->flType == HANDLE_TYPE_CURSOR) DestroyCursor(lpT->h32); else DestroyIcon(lpT->h32); }
if (lpT->pbDataOld) free_w(lpT->pbDataOld);
if (lpT->cLock) cPendingCursorIconUpdates--;
if ((WORD)HIWORD(lpT->lpszName) != (WORD)NULL) { free_w_small ((PVOID)lpT->lpszName); }
lpT->fInUse = FALSE; }
//*****************************************************************************
//
// InitStdCursorIconAlias -
//
// Creates the aliases of standard cursors and icons.
//
// NOTES:
//
// The idea is to createaliases for all the standard cursors and icons to
// make sure that we indeed generate valid handles.
//
// This problem cameup because of the following scenario
// the app turbotax does the following:
//
// h16Cursor1 = GetClassWord(hwndEditControl, GCL_HCURSOR);
// (bydefault, this is an I-beam)
// .....
// h16Cursor2 = LoadCursor(NULL, IDC_IBEAM);
// Because of the way we create and maintain our 32-16 alias hCursor1 is a
// a WOW bogus handle (ie > 0xf000) and since by default the "Edit" class is
// registered with hCursor = IDC_IBEAM, the h32s are same ie.
//
// GetClassWord(hwndEditControl, GCL_HCURSOR) == LoadCursor(..IDC_IBEAM);
//
// Thus h16Cursor2 will be same as h16Cursor1 and that's a problem because we
// are NOT returning a valid wow handle for a predefined cursor.
//
//
// The solution is to createaliases for all standard cursors and icons during
// init time so that we don't run into this problem. However I think this
// approach as wasteful and am creating the alias for the only known case
// ie IDC_IBEAM.
//
// - Nanduri Ramakrishna
//*****************************************************************************
DWORD InitCursorIds[] = { (DWORD)IDC_ARROW, (DWORD)IDC_IBEAM, (DWORD)IDC_WAIT, (DWORD)IDC_CROSS, (DWORD)IDC_UPARROW, (DWORD)IDC_SIZE, (DWORD)IDC_ICON, (DWORD)IDC_SIZENWSE, (DWORD)IDC_SIZENESW, (DWORD)IDC_SIZEWE, (DWORD)IDC_SIZENS };
BOOL InitStdCursorIconAlias() {
HCURSOR h32; UINT i;
for (i = 0; i < (sizeof(InitCursorIds) / sizeof(DWORD)); i++) {
//
// Create the alias for each standard cursor in the list
//
h32 = (HCURSOR)LoadCursor((HINSTANCE)NULL, (LPCSTR)InitCursorIds[i]); WOW32ASSERT(h32);
if (h32) { SetupResCursorIconAlias((HAND16)NULL, (HAND32)h32, NULL, (WORD)NULL, HANDLE_TYPE_CURSOR); }
}
//
// Add similar lines for standard icons.
//
return TRUE; }
//*****************************************************************************
//
// W32CheckIfAlreadyLoaded -
//
// returns h16 if a cursoricon has previously been loaded.
//
//*****************************************************************************
HAND16 W32CheckIfAlreadyLoaded(VPVOID pData, WORD ResType) { LPCURSORICONALIAS lpT; PICONCUR16 parg16; PSZ psz;
GETMISCPTR(pData, parg16); GETPSZIDPTR(parg16->lpStr, psz);
ResType = (ResType == NW_LOADCURSOR) ? HANDLE_TYPE_CURSOR : HANDLE_TYPE_ICON; for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) { if (lpT->fInUse) { LPBYTE lpszNameT = lpT->lpszName; if (lpszNameT && (lpT->flType & ResType) && lpT->hInst16 == parg16->hInst) { WOW32ASSERT(!(lpT->flType & HANDLE_TYPE_WOWGLOBAL)); if (HIWORD(lpszNameT) && HIWORD(psz)) { if (!(WOW32_stricmp(psz, (LPSTR)lpszNameT))) break; } else if (lpszNameT == psz) { break; } } } }
FREEPSZIDPTR(psz); FREEMISCPTR(parg16);
if (lpT && lpT->cLock) ReplaceCursorIcon(lpT);
return (lpT ? lpT->h16 : 0); }
|