|
|
/*++
* * WOW v1.0 * * Copyright (c) 1991, Microsoft Corporation * * RMLOAD.C * WOW16 user resource services * * History: * * Created 12-Apr-1991 by Nigel Thompson (nigelt) * Much hacked about version of the Win 3.1 rmload.c source * It doesn't attempt any device driver resource loading * or do anything to support Win 2.x apps. * * Revised 19-May-1991 by Jeff Parsons (jeffpar) * IFDEF'ed everything except LoadString; because of the client/server * split in USER32, most resources are copied to the server's context and * freed in the client's, meaning the client no longer gets a handle to * a global memory object. We could give it one, but it would be a separate * object, which we would have to keep track of, and which would be difficult * to keep in sync with the server's copy if changes were made. --*/
/****************************************************************************/ /* */ /* RMLOAD.C - */ /* */ /* Resource Loading Routines. */ /* */ /****************************************************************************/
#define RESOURCESTRINGS
#include "user.h"
#include "multires.h"
//
// We define certain things here because including mvdm\inc\*.h files here
// will lead to endless mess.
//
DWORD API NotifyWow(WORD, LPBYTE);
typedef struct _LOADACCEL16 { /* ldaccel */ WORD hInst; WORD hAccel; LPBYTE pAccel; DWORD cbAccel; } LOADACCEL16, FAR *PLOADACCEL16;
/* This must match its counterpart in mvdm\inc\wowusr.h */ #define NW_LOADACCELERATORS 3 //
/*--------------------------------------------------------------------------*/ /* */ /* LoadAccelerators() - */ /* */ /*--------------------------------------------------------------------------*/
HACCEL API ILoadAccelerators(HINSTANCE hInstance, LPCSTR lpszAccName) { HRSRC hrl; HACCEL hAccel = NULL; LOADACCEL16 loadaccel;
hrl = FindResource(hInstance, lpszAccName, RT_ACCELERATOR); #ifdef WOW
if (hrl) { hAccel = (HACCEL)LoadResource(hInstance, hrl); if (hAccel) {
// create 32bit accelerator and 16-32 alias.
loadaccel.hInst = (WORD)hInstance; loadaccel.hAccel = (WORD)hAccel; loadaccel.pAccel = (LPBYTE)LockResource(hAccel); loadaccel.cbAccel = (DWORD)SizeofResource(hInstance, hrl);
if (NotifyWow(NW_LOADACCELERATORS, (LPBYTE)&loadaccel)) { UnlockResource(hAccel); } else { UnlockResource(hAccel); hAccel = NULL; } }
}
return (hAccel); #else
if (!hrl) return NULL;
return (HACCEL)LoadResource(hInstance, hrl); #endif
}
int API ILoadString( HINSTANCE h16Task, UINT wID, LPSTR lpBuffer, register int nBufferMax) { HANDLE hResInfo; HANDLE hStringSeg; LPSTR lpsz; register int cch, i;
/* Make sure the parms are valid. */ if (!lpBuffer || (nBufferMax-- == 0)) return(0);
cch = 0;
/* String Tables are broken up into 16 string segments. Find the segment
* containing the string we are interested in. */ if (hResInfo = FindResource(h16Task, (LPSTR)((LONG)((wID >> 4) + 1)), RT_STRING)) { /* Load that segment. */ hStringSeg = LoadResource(h16Task, hResInfo);
/* Lock the resource. */ if (lpsz = (LPSTR)LockResource(hStringSeg)) { /* Move past the other strings in this segment. */ wID &= 0x0F; while (TRUE) { cch = *((BYTE FAR *)lpsz++); if (wID-- == 0) break; lpsz += cch; }
/* Don't copy more than the max allowed. */ if (cch > nBufferMax) cch = nBufferMax;
/* Copy the string into the buffer. */ LCopyStruct(lpsz, lpBuffer, cch);
GlobalUnlock(hStringSeg);
/* BUG: If we free the resource here, we will have to reload it
* immediately for many apps with sequential strings. * Force it to be discardable however because non-discardable * string resources make no sense. Chip */ GlobalReAlloc(hStringSeg, 0L, GMEM_MODIFY | GMEM_MOVEABLE | GMEM_DISCARDABLE); } }
/* Append a NULL. */ lpBuffer[cch] = 0;
return(cch); }
#ifdef NEEDED
#define DIB_RGB_COLORS 0
HBITMAP FAR PASCAL ConvertBitmap(HBITMAP hBitmap); HANDLE NEAR PASCAL LoadDIBCursorIconHandler(HANDLE, HANDLE, HANDLE, BOOL); WORD FAR PASCAL GetIconId(HANDLE, LPSTR); HBITMAP FAR PASCAL StretchBitmap(int, int, int, int, HBITMAP, BYTE, BYTE); WORD NEAR PASCAL StretchIcon(LPCURSORSHAPE, WORD, HBITMAP, BOOL); WORD NEAR PASCAL SizeReqd(BOOL, WORD, WORD, BOOL, int, int); WORD NEAR PASCAL CrunchAndResize(LPCURSORSHAPE, BOOL, BOOL, BOOL, BOOL); HANDLE FAR PASCAL LoadCursorIconHandler2(HANDLE, LPCURSORSHAPE, WORD); HANDLE FAR PASCAL LoadDIBCursorIconHandler2(HANDLE, LPCURSORSHAPE, WORD, BOOL);
/*--------------------------------------------------------------------------*/ /* */ /* LoadIconHandler() - */ /* */ /*--------------------------------------------------------------------------*/
HICON FAR PASCAL LoadIconHandler(hIcon, fNewFormat)
HICON hIcon; BOOL fNewFormat;
{ LPCURSORSHAPE lpIcon; WORD wSize;
dprintf(7,"LoadIconHandler"); wSize = (WORD)GlobalSize(hIcon); lpIcon = (LPCURSORSHAPE)(GlobalLock(hIcon));
if (fNewFormat) return(LoadDIBCursorIconHandler2(hIcon, lpIcon, wSize, TRUE)); else return(LoadCursorIconHandler2(hIcon, lpIcon, wSize)); }
/*--------------------------------------------------------------------------*/ /* */ /* FindIndividualResource() */ /* */ /*--------------------------------------------------------------------------*/
HANDLE NEAR PASCAL FindIndividualResource(register HANDLE hResFile, LPSTR lpszName, LPSTR lpszType)
{ WORD idIcon; register HANDLE h;
dprintf(7,"FindIndividualResource"); /* Check if the resource is to be taken from the display driver.
* If so, check the driver version; If the resource is to be taken from * the application, check the app version. */
if ((lpszType != RT_BITMAP) && ((LOWORD(GetExpWinVer(hResFile)) >= VER))) { /* Locate the directory resource */ h = SplFindResource(hResFile, lpszName, (LPSTR)(lpszType + DIFFERENCE)); if (h == NULL) return((HANDLE)0);
/* Load the directory resource */ h = LoadResource(hResFile, h);
/* Get the name of the matching resource */ idIcon = GetIconId(h, lpszType);
/* NOTE: Don't free the (discardable) directory resource!!! - ChipA */ /*
* We should not call SplFindResource here, because idIcon is * internal to us and GetDriverResourceId won't know how tomap it. */ return(FindResource(hResFile, MAKEINTRESOURCE(idIcon), lpszType)); } else /* It is an Old app; The resource is in old format */ return(SplFindResource(hResFile, lpszName, lpszType)); }
/*--------------------------------------------------------------------------*/ /* */ /* GetBestFormIcon() */ /* */ /* Among the different forms of Icons present, choose the one that */ /* matches the PixelsPerInch values and the number of colors of the */ /* current display. */ /* */ /*--------------------------------------------------------------------------*/
WORD NEAR PASCAL GetBestFormIcon(LPRESDIR ResDirPtr, WORD ResCount)
{ register WORD wIndex; register WORD ColorCount; WORD MaxColorCount; WORD MaxColorIndex; WORD MoreColorCount; WORD MoreColorIndex; WORD LessColorCount; WORD LessColorIndex; WORD DevColorCount;
dprintf(7,"GetBestFormIcon"); /* Initialse all the values to zero */ MaxColorCount = MaxColorIndex = MoreColorCount = MoreColorIndex = LessColorIndex = LessColorCount = 0;
/* get number of colors on device. if device is very colorful,
** set to a high number without doing meaningless 1<<X operation. */ if (oemInfo.ScreenBitCount >= 16) DevColorCount = 32000; else DevColorCount = 1 << oemInfo.ScreenBitCount;
for (wIndex=0; wIndex < ResCount; wIndex++, ResDirPtr++) { /* Check for the number of colors */ if ((ColorCount = (ResDirPtr->ResInfo.Icon.ColorCount)) <= DevColorCount) { if (ColorCount > MaxColorCount) { MaxColorCount = ColorCount; MaxColorIndex = wIndex; } }
/* Check for the size */ /* Match the pixels per inch information */ if ((ResDirPtr->ResInfo.Icon.Width == (BYTE)oemInfo.cxIcon) && (ResDirPtr->ResInfo.Icon.Height == (BYTE)oemInfo.cyIcon)) { /* Matching size found */ /* Check if the color also matches */ if (ColorCount == DevColorCount) return(wIndex); /* Exact match found */
if (ColorCount < DevColorCount) { /* Choose the one with max colors, but less than reqd */ if (ColorCount > LessColorCount) { LessColorCount = ColorCount; LessColorIndex = wIndex; } } else { if ((LessColorCount == 0) && (ColorCount < MoreColorCount)) { MoreColorCount = ColorCount; MoreColorIndex = wIndex; } } } }
/* Check if we have a correct sized but with less colors than reqd */ if (LessColorCount) return(LessColorIndex);
/* Check if we have a correct sized but with more colors than reqd */ if (MoreColorCount) return(MoreColorIndex);
/* Check if we have one that has maximum colors but less than reqd */ if (MaxColorCount) return(MaxColorIndex);
return(0); }
/*--------------------------------------------------------------------------*/ /* */ /* GetBestFormCursor() */ /* */ /* Among the different forms of cursors present, choose the one that */ /* matches the width and height defined by the current display driver. */ /* */ /*--------------------------------------------------------------------------*/
WORD NEAR PASCAL GetBestFormCursor(LPRESDIR ResDirPtr, WORD ResCount)
{ register WORD wIndex;
dprintf(7,"GetBestFormCursor"); for (wIndex=0; wIndex < ResCount; wIndex++, ResDirPtr++) { /* Match the Width and Height of the cursor */ if ((ResDirPtr->ResInfo.Cursor.Width == oemInfo.cxCursor) && ((ResDirPtr->ResInfo.Cursor.Height >> 1) == oemInfo.cyCursor)) return(wIndex); }
return(0); }
/*--------------------------------------------------------------------------*/ /* */ /* GetIconId() */ /* */ /*--------------------------------------------------------------------------*/
WORD FAR PASCAL GetIconId(hRes, lpszType)
HANDLE hRes; LPSTR lpszType;
{ WORD w; LPRESDIR ResDirPtr; LPNEWHEADER DataPtr; register WORD RetIndex; register WORD ResCount;
dprintf(7,"GetIconId"); if ((DataPtr = (LPNEWHEADER)LockResource(hRes)) == NULL) return(0);
ResCount = DataPtr->ResCount; ResDirPtr = (LPRESDIR)(DataPtr + 1);
switch (LOWORD((DWORD)lpszType)) { case RT_ICON: RetIndex = GetBestFormIcon(ResDirPtr, ResCount); break;
case RT_CURSOR: RetIndex = GetBestFormCursor(ResDirPtr, ResCount); break; }
if (RetIndex == ResCount) RetIndex = 0;
ResCount = ((LPRESDIR)(ResDirPtr+RetIndex))->idIcon;
UnlockResource(hRes);
return(ResCount); }
/*--------------------------------------------------------------------------*/ /* */ /* UT_LoadCursorIconBitmap() - */ /* */ /*--------------------------------------------------------------------------*/
HANDLE NEAR PASCAL UT_LoadCursorIconBitmap(register HANDLE hrf, LPSTR lpszName, int type)
{ register HANDLE h;
dprintf(7,"LoadCursorIconBitmap"); if (hrf == NULL) return (HANDLE)0; // no 2.x support - NigelT
h = FindIndividualResource(hrf, lpszName, MAKEINTRESOURCE(type));
if (h != NULL) h = LoadResource(hrf, h);
return(h); }
/*--------------------------------------------------------------------------*/ /* */ /* fCheckMono() - */ /* Checks a DIB for being truely monochrome. Only called if */ /* BitCount == 1. This function checks the color table (address */ /* passed) for true black and white RGB's */ /* */ /*--------------------------------------------------------------------------*/
BOOL NEAR PASCAL fCheckMono(LPVOID lpColorTable, BOOL fNewDIB)
{ LPLONG lpRGB; LPWORD lpRGBw;
dprintf(7,"fCheckMono"); lpRGB = lpColorTable; if (fNewDIB) { if ((*lpRGB == 0 && *(lpRGB + 1) == 0x00FFFFFF) || (*lpRGB == 0x00FFFFFF && *(lpRGB + 1) == 0)) return(TRUE); } else { lpRGBw = lpColorTable; if (*(LPSTR)lpRGBw == 0) { if (*lpRGBw == 0 && *(lpRGBw+1) == 0xFF00 && *(lpRGBw+2) == 0xFFFF) return(TRUE); } else if (*lpRGBw == 0xFFFF && *(lpRGBw+1) == 0x00FF && *(lpRGBw+2) == 0) return(TRUE); } return(FALSE); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadNewBitmap() - */ /* */ /*--------------------------------------------------------------------------*/
/* Loads a 3.x format bitmap into the DIB structure. */
HBITMAP NEAR PASCAL LoadNewBitmap(HANDLE hRes, LPSTR lpName)
{ register HBITMAP hbmS; register HBITMAP hBitmap;
dprintf(7,"LoadNewBitmap");
if ((hbmS = hBitmap = UT_LoadCursorIconBitmap(hRes,lpName,(WORD)RT_BITMAP))) { /* Convert the DIB bitmap into a bitmap in the internal format */ hbmS = ConvertBitmap(hBitmap);
/* Converted bitmap is in hbmS; So, release the DIB */ FreeResource(hBitmap); } return(hbmS); }
/*--------------------------------------------------------------------------*/ /* */ /* ConvertBitmap() */ /* */ /* This takes in a handle to data in PM 1.1 or 1.2 DIB format or */ /* Windows 3.0 DIB format and creates a bitmap in the internal */ /* bitmap format and returns the handle to it. */ /* */ /* NOTE: */ /* This function is exported because it is called from CLIPBRD.EXE */ /* */ /*--------------------------------------------------------------------------*/
HBITMAP FAR PASCAL ConvertBitmap(HBITMAP hBitmap)
{ int Width; register int Height; HDC hDC; BOOL fMono = FALSE; LPSTR lpBits; register HBITMAP hbmS; LPBITMAPINFOHEADER lpBitmap1; LPBITMAPCOREHEADER lpBitmap2;
dprintf(7,"ConvertBitmap"); lpBitmap1 = (LPBITMAPINFOHEADER)LockResource(hBitmap);
if (!lpBitmap1) return(NULL);
if ((WORD)lpBitmap1->biSize == sizeof(BITMAPCOREHEADER)) { /* This is an "old form" DIB. This matches the PM 1.1 format. */ lpBitmap2 = (LPBITMAPCOREHEADER)lpBitmap1; Width = lpBitmap2->bcWidth; Height = lpBitmap2->bcHeight;
/* Calcluate the pointer to the Bits information */ /* First skip over the header structure */ lpBits = (LPSTR)(lpBitmap2 + 1);
/* Skip the color table entries, if any */ if (lpBitmap2->bcBitCount != 24) { if (lpBitmap2->bcBitCount == 1) fMono = fCheckMono(lpBits, FALSE); lpBits += (1 << (lpBitmap2->bcBitCount)) * sizeof(RGBTRIPLE); } } else { Width = (WORD)lpBitmap1->biWidth; Height = (WORD)lpBitmap1->biHeight;
/* Calcluate the pointer to the Bits information */ /* First skip over the header structure */ lpBits = (LPSTR)(lpBitmap1 + 1);
/* Skip the color table entries, if any */ if (lpBitmap1->biClrUsed != 0) { if (lpBitmap1->biClrUsed == 2) fMono = fCheckMono(lpBits, TRUE); lpBits += lpBitmap1->biClrUsed * sizeof(RGBQUAD); } else { if (lpBitmap1->biBitCount != 24) { if (lpBitmap1->biBitCount == 1) fMono = fCheckMono(lpBits, TRUE); lpBits += (1 << (lpBitmap1->biBitCount)) * sizeof(RGBQUAD); } } }
/* Create a bitmap */ if (fMono) hbmS = CreateBitmap(Width, Height, 1, 1, (LPSTR)NULL); else { /* Create a color bitmap compatible with the display device */ hDC = GetScreenDC(); hbmS = CreateCompatibleBitmap(hDC, Width, Height); InternalReleaseDC(hDC); }
/* Initialize the new bitmap by converting from PM format */ if (hbmS != NULL) SetDIBits(hdcBits, hbmS, 0, Height, lpBits, (LPBITMAPINFO)lpBitmap1, DIB_RGB_COLORS);
GlobalUnlock(hBitmap);
return(hbmS); }
HANDLE NEAR PASCAL Helper_LoadCursorOrIcon(HANDLE hRes, LPSTR lpName, WORD type) { HANDLE h;
dprintf(7,"Helper_LoadCursorOrIcon");
/* If we can't find the cursor/icon in the app, and this is a 2.x app, we
* need to search into the display driver to find it. */ h = UT_LoadCursorIconBitmap(hRes, lpName, type); return(h); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadCursor() - */ /* */ /*--------------------------------------------------------------------------*/
HCURSOR API LoadCursor(hRes, lpName)
HANDLE hRes; LPSTR lpName;
{ HCURSOR hcur;
dprintf(5,"LoadCursor");
if (hRes == NULL) { dprintf(9," Calling Win32 to load Cursor"); hcur = WOWLoadCursor32(hRes, lpName); } else { hcur = ((HCURSOR)Helper_LoadCursorOrIcon(hRes, lpName, (WORD)RT_CURSOR)); } #ifdef DEBUG
if (hcur == NULL) { dprintf(9," Failed, BUT returning 1 so app won't die (yet)"); return (HCURSOR)1; } #endif
dprintf(5,"LoadCursor returning %4.4XH", hcur);
return hcur; }
/*--------------------------------------------------------------------------*/ /* */ /* LoadIcon() - */ /* */ /*--------------------------------------------------------------------------*/
HICON API LoadIcon(hRes, lpName)
HANDLE hRes; LPSTR lpName;
{ HICON hicon;
dprintf(5,"LoadIcon");
if (hRes == NULL) { dprintf(9," Calling Win32 to load Icon"); hicon = WOWLoadIcon32(hRes, lpName); } else { hicon = ((HICON)Helper_LoadCursorOrIcon(hRes, lpName, (WORD)RT_ICON)); } #ifdef DEBUG
if (hicon == NULL) { dprintf(9," Failed, BUT returning 1 so app won't die (yet)"); return (HICON)1; } #endif
dprintf(5,"LoadIcon returning %4.4XH", hicon);
return hicon; }
/*--------------------------------------------------------------------------*/ /* */ /* StretchBitmap() - */ /* */ /* This routine stretches a bitmap into another bitmap, */ /* and returns the stretched bitmap. */ /*--------------------------------------------------------------------------*/
HBITMAP FAR PASCAL StretchBitmap(iOWidth, iOHeight, iNWidth, iNHeight, hbmS, byPlanes, byBitsPixel)
int iOWidth; int iOHeight; int iNWidth; int iNHeight; HBITMAP hbmS; BYTE byPlanes; BYTE byBitsPixel;
{ register HBITMAP hbmD; HBITMAP hbmDSave; register HDC hdcSrc;
dprintf(7,"StretchBitmap"); if ((hdcSrc = CreateCompatibleDC(hdcBits)) != NULL) { if ((hbmD = (HBITMAP)CreateBitmap(iNWidth, iNHeight, byPlanes, byBitsPixel, (LPINT)NULL)) == NULL) goto GiveUp;
if ((hbmDSave = SelectObject(hdcBits, hbmD)) == NULL) goto GiveUp;
if (SelectObject(hdcSrc, hbmS) != NULL) { /* NOTE: We don't have to save the bitmap returned from
* SelectObject(hdcSrc) and select it back in to hdcSrc, * because we delete hdcSrc. */ SetStretchBltMode(hdcBits, COLORONCOLOR);
StretchBlt(hdcBits, 0, 0, iNWidth, iNHeight, hdcSrc, 0, 0, iOWidth, iOHeight, SRCCOPY);
SelectObject(hdcBits, hbmDSave);
DeleteDC(hdcSrc);
return(hbmD); } else { GiveUp: if (hbmD != NULL) DeleteObject(hbmD); DeleteDC(hdcSrc); goto Step1; }
} else { Step1: return(NULL); } }
/*--------------------------------------------------------------------------*/ /* */ /* LoadOldBitmap() - */ /* */ /* This loads bitmaps in old formats( Version 2.10 and below) */ /*--------------------------------------------------------------------------*/
HANDLE NEAR PASCAL LoadOldBitmap(HANDLE hRes, LPSTR lpName)
{ int oWidth; int oHeight; BYTE planes; BYTE bitsPixel; WORD wCount; DWORD dwCount; LPBITMAP lpBitmap; register HBITMAP hbmS; HBITMAP hbmD; register HBITMAP hBitmap; BOOL fCrunch; WORD wDevDep;
dprintf(7,"LoadOldBitmap");
if (hbmS = hBitmap = UT_LoadCursorIconBitmap(hRes, lpName, BMR_BITMAP)) { lpBitmap = (LPBITMAP)LockResource(hBitmap);
fCrunch = ((*(((BYTE FAR *)lpBitmap) + 1) & 0x0F) != BMR_DEVDEP); lpBitmap = (LPBITMAP)((BYTE FAR *)lpBitmap + 2);
oWidth = lpBitmap->bmWidth; oHeight = lpBitmap->bmHeight; planes = lpBitmap->bmPlanes; bitsPixel = lpBitmap->bmBitsPixel;
if (!(*(((BYTE FAR *)lpBitmap) + 1) & 0x80)) { hbmS = CreateBitmap(oWidth, oHeight, planes, bitsPixel, (LPSTR)(lpBitmap + 1)); } else { hbmS = (HBITMAP)CreateDiscardableBitmap(hdcBits, oWidth, oHeight); wCount = (((oWidth * bitsPixel + 0x0F) & ~0x0F) >> 3); dwCount = wCount * oHeight * planes; SetBitmapBits(hbmS, dwCount, (LPSTR)(lpBitmap + 1)); }
GlobalUnlock(hBitmap); FreeResource(hBitmap);
if (hbmS != NULL) { if (fCrunch && ((64/oemInfo.cxIcon + 64/oemInfo.cyIcon) > 2)) { /* Stretch the Bitmap to suit the device */ hbmD = StretchBitmap(oWidth, oHeight, (oWidth * oemInfo.cxIcon/64), (oHeight * oemInfo.cyIcon/64), hbmS, planes, bitsPixel);
/* Delete the old bitmap */ DeleteObject(hbmS);
if (hbmD == NULL) return(NULL); /* Some problem in stretching */ else return(hbmD); /* Return the stretched bitmap */ } } } else { return (HANDLE)0; } return(hbmS); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadBitmap() - */ /* */ /* This routine decides whether the bitmap to be loaded is in old or */ /* new (DIB) format and calls appropriate handlers. */ /* */ /*--------------------------------------------------------------------------*/
HANDLE API LoadBitmap(hRes, lpName)
HANDLE hRes; LPSTR lpName;
{ HANDLE hbmp;
dprintf(5,"LoadBitmap"); if (hRes == NULL) { dprintf(9," Calling Win32 to load Bitmap"); hbmp = WOWLoadBitmap32(hRes, lpName); } else {
/* Check if the resource is to be taken from the display driver. If so,
* check the driver version; If the resource is to be taken from the * application, check the app version */ if (((hRes == NULL) && (oemInfo.DispDrvExpWinVer >= VER)) || ((hRes != NULL) && (LOWORD(GetExpWinVer(hRes)) >= VER))) { hbmp = (LoadNewBitmap(hRes, lpName)); } else { hbmp = (LoadOldBitmap(hRes, lpName)); } } #ifdef DEBUG
if (hbmp == NULL) { dprintf(9," Failed, BUT returning 1 so app won't die (yet)"); return (HANDLE)1; } #endif
dprintf(5,"LoadBitmap returning %4.4XH", hbmp);
return hbmp; }
/*--------------------------------------------------------------------------*/ /* */ /* CrunchAndResize() - */ /* This Crunches the monochrome icons and cursors if required and */ /* returns the newsize of the resource after crunching. */ /* This routine is also called to resize the monochrome AND mask of a */ /* color icon. */ /* Parameters: */ /* lpIcon: Ptr to the resource */ /* fIcon : TRUE, if the resource is an icon. FALSE, if it is a cursor. */ /* fCrunch : TRUE if resource is to be resized. */ /* fSinglePlane: TRUE if only AND mask of a color icon is passed */ /* through lpIcon */ /* fUseSysMetrics: Whether to use the icon/cursor values found in */ /* oemInfo or not. */ /* Returns: */ /* The new size of the resource is returned. */ /* */ /*--------------------------------------------------------------------------*/
WORD NEAR PASCAL CrunchAndResize(lpIcon, fIcon, fCrunch, fSinglePlane, fUseSysMetrics)
LPCURSORSHAPE lpIcon; BOOL fIcon; BOOL fCrunch; BOOL fSinglePlane; BOOL fUseSysMetrics;
{ WORD size; register int cx; register int cy; int oHeight; int nHeight; int iNewcbWidth; BOOL bStretch; HBITMAP hbmS; HBITMAP hbmD;
dprintf(7,"CrunhAndResize"); if(fUseSysMetrics) { if(fIcon) { cx = oemInfo.cxIcon; cy = oemInfo.cyIcon; } else { cx = oemInfo.cxCursor; cy = oemInfo.cyCursor; } } else { cx = lpIcon->cx; cy = lpIcon->cy; }
if (fIcon) { lpIcon->xHotSpot = cx >> 1; lpIcon->yHotSpot = cy >> 1; if (fSinglePlane) { /* Only the AND mask exists */ oHeight = lpIcon->cy; nHeight = cy; } else { /* Both AND ans XOR masks exist; So, height must be twice */ oHeight = lpIcon->cy << 1; nHeight = cy << 1; } } else { oHeight = lpIcon->cy << 1; nHeight = cy << 1; }
iNewcbWidth = ((cx + 0x0F) & ~0x0F) >> 3; size = iNewcbWidth * nHeight;
if (fCrunch && ((lpIcon->cx != cx) || (lpIcon->cy != cy))) { if (!fIcon) { lpIcon->xHotSpot = (lpIcon->xHotSpot * cx)/(lpIcon->cx); lpIcon->yHotSpot = (lpIcon->yHotSpot * cy)/(lpIcon->cy); }
/* To begin with, assume that no stretching is required */ bStretch = FALSE;
/* Check if the width is to be reduced */ if (lpIcon->cx != cx) { /* Stretching the Width is necessary */ bStretch = TRUE; }
/* Check if the Height is to be reduced */ if (lpIcon->cy != cy) { /* Stretching in Y direction is necessary */ bStretch = TRUE; }
/* Check if stretching is necessary */ if (bStretch) { /* Create a monochrome bitmap with the icon/cursor bits */ if ((hbmS = CreateBitmap(lpIcon->cx, oHeight, 1, 1, (LPSTR)(lpIcon + 1))) == NULL) return(NULL);
if ((hbmD = StretchBitmap(lpIcon->cx, oHeight, cx, nHeight, hbmS, 1, 1)) == NULL) { DeleteObject(hbmS); return(NULL); }
DeleteObject(hbmS);
lpIcon->cx = cx; lpIcon->cy = cy; lpIcon->cbWidth = iNewcbWidth;
GetBitmapBits(hbmD, (DWORD)size, (LPSTR)(lpIcon + 1)); DeleteObject(hbmD); } }
return(size + sizeof(CURSORSHAPE)); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadCursorIconHandler() - */ /* */ /* This handles 2.x (and less) Cursors and Icons */ /* */ /*--------------------------------------------------------------------------*/
HANDLE FAR PASCAL LoadCursorIconHandler(hRes, hResFile, hResIndex)
register HANDLE hRes; HANDLE hResFile; HANDLE hResIndex;
{ register int fh = 0; BOOL bNew = FALSE; WORD wMemSize; LPCURSORSHAPE lpIcon; HANDLE hTempRes;
dprintf(7,"LoadCursorIconHandler"); wMemSize = SizeofResource(hResFile, hResIndex);
#if 1 // was 0 - NigelT
if (!hRes) { if (!(hRes = AllocResource(hResFile, hResIndex, 0L))) return(NULL); fh = -1; bNew = TRUE; }
while (!(lpIcon = (LPCURSORSHAPE)GlobalLock(hRes))) { if (!GlobalReAlloc(hRes, (DWORD)wMemSize, 0)) goto LoadCIFail; else fh = -1; }
if (fh) { fh = AccessResource(hResFile, hResIndex); if (fh != -1 && _lread(fh, (LPSTR)lpIcon, wMemSize) != 0xFFFF) _lclose(fh); else { if (fh != -1) _lclose(fh); GlobalUnlock(hRes); goto LoadCIFail; }
} #else
/* Call kernel's resource handler instead of doing the stuff ourselves
* because we use cached file handles that way. davidds */ // For resources which are not preloaded, hRes will be NULL at this point.
// For such cases, the default resource handler does the memory allocation
// and returns a valid handle.
// Fix for Bug #4257 -- 01/21/91 -- SANKAR
if (!(hTempRes = lpDefaultResourceHandler(hRes, hResFile, hResIndex))) goto LoadCIFail; // We must use the handle returned by lpDefaultResourceHandler.
hRes = hTempRes;
lpIcon = (LPCURSORSHAPE)GlobalLock(hRes); #endif
if (LoadCursorIconHandler2(hRes, lpIcon, wMemSize)) return(hRes);
LoadCIFail: /* If the loading of the resource fails, we MUST discard the memory we
* reallocated above, or kernel will simply globallock the thing on the * next call to LockResource(), leaving invalid data in the object. */ if (bNew) GlobalFree(hRes); else GlobalDiscard(hRes);
return(NULL); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadCursorIconHandler2() - */ /* */ /* This handles all 2.x Cursors and Icons */ /* */ /*--------------------------------------------------------------------------*/
HANDLE FAR PASCAL LoadCursorIconHandler2(hRes, lpIcon, wMemSize)
register HANDLE hRes; LPCURSORSHAPE lpIcon; register WORD wMemSize;
{ BOOL fCrunch; BOOL fIcon; WORD wNewSize; BOOL fStretchInXdirection; BOOL fStretchInYdirection;
dprintf(7,"LoadCursorIconHandler2"); fIcon = (*(LPSTR)lpIcon == BMR_ICON);
/* Is this a device dependant icon/cursor?. */ fCrunch = (*((LPSTR)lpIcon+1) != BMR_DEVDEP);
LCopyStruct((LPSTR)lpIcon+2, (LPSTR)lpIcon, wMemSize-2);
fCrunch = fCrunch || (lpIcon->cx != GetSystemMetrics(SM_CXICON)) || (lpIcon->cy != GetSystemMetrics(SM_CYICON));
/* Only support monochrome cursors. */ lpIcon->Planes = lpIcon->BitsPixel = 1;
fStretchInXdirection = fStretchInYdirection = TRUE; // Assume we need stretching.
if(fIcon) { if((oemInfo.cxIcon > STD_ICONWIDTH) && (lpIcon->cx <= oemInfo.cxIcon)) fStretchInXdirection = FALSE; // No Need to stretch in X direction;
if((oemInfo.cyIcon > STD_ICONHEIGHT) && (lpIcon->cy <= oemInfo.cyIcon)) fStretchInYdirection = FALSE; // No need to stretch in Y direction;
} else { if((oemInfo.cxCursor > STD_CURSORWIDTH) && (lpIcon->cx <= oemInfo.cxCursor)) fStretchInXdirection = FALSE; // No need to stretch in X direction.
if((oemInfo.cyCursor > STD_CURSORHEIGHT) && (lpIcon->cy <= oemInfo.cyCursor)) fStretchInYdirection = FALSE; // No need to stretch in Y direction.
}
// Check if the Icon/Cursor needs to be stretched now or not
if(!(fStretchInXdirection || fStretchInYdirection)) { GlobalUnlock(hRes); return(hRes); } wNewSize = SizeReqd(fIcon, 1, 1, TRUE, 0, 0);
/* Before we crunch, let us make sure we have a big enough resource. */ if (fCrunch) { if (wNewSize > wMemSize) { GlobalUnlock(hRes);
/* Make this non discardable so that kernel will try to move this
* block when reallocing. DavidDS */ GlobalReAlloc(hRes, 0L, GMEM_MODIFY | GMEM_NODISCARD);
if (!GlobalReAlloc(hRes, (DWORD)wNewSize, 0)) { /* So it gets discarded. Note that since the above realloc is
* less than 64K, the handle won't change. */ GlobalReAlloc(hRes, 0L, GMEM_MODIFY | GMEM_DISCARDABLE); return(NULL); }
/* So it gets discarded */ GlobalReAlloc(hRes, 0L, GMEM_MODIFY | GMEM_DISCARDABLE);
if (!(lpIcon = (LPCURSORSHAPE)GlobalLock(hRes))) return(NULL); wMemSize = wNewSize; } }
wNewSize = CrunchAndResize(lpIcon, fIcon, fCrunch, FALSE, TRUE);
GlobalUnlock(hRes);
/* Has it already been resized? */ if (wNewSize < wMemSize) { /* Make it an exact fit. */ if (!GlobalReAlloc(hRes, (DWORD)wNewSize, 0)) return(NULL); }
return(hRes); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadDIBCursorHandler() - */ /* */ /* This is called when a Cursor in DIB format is loaded */ /* This converts the cursor into Old format and returns the handle */ /* */ /*--------------------------------------------------------------------------*/
HANDLE FAR PASCAL LoadDIBCursorHandler(hRes, hResFile, hResIndex)
HANDLE hRes; HANDLE hResFile; HANDLE hResIndex;
{ dprintf(7,"LoadDIBCursorIconHandler"); return(LoadDIBCursorIconHandler(hRes, hResFile, hResIndex, FALSE)); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadDIBIconHandler() - */ /* */ /* This is called when an Icon in DIB format is loaded */ /* This converts the cursor into Old format and returns the handle */ /* */ /*--------------------------------------------------------------------------*/
HANDLE FAR PASCAL LoadDIBIconHandler(hRes, hResFile, hResIndex)
HANDLE hRes; HANDLE hResFile; HANDLE hResIndex;
{ dprintf(7,"LoadDIBIconHandler"); return(LoadDIBCursorIconHandler(hRes, hResFile, hResIndex, TRUE)); }
/*--------------------------------------------------------------------------*/ /* */ /* StretchIcon() - */ /* When this routine is called, lpIcon already has the monochrome */ /* AND bitmap properly sized. This routine adds the color XOR bitmap at */ /* end of lpIcon and updates the header with the values of the color */ /* info(bitcount and Planes); */ /* wOldSize : Contains the size of AND mask + CURSORSHAPE */ /* */ /* Returns: The new size ( Size of AND mask + XOR bitmap + CURSORSHAPE) */ /* */ /*--------------------------------------------------------------------------*/
WORD NEAR PASCAL StretchIcon(lpIcon, wOldSize, hXORbitmap, fStretchToSysMetrics)
LPCURSORSHAPE lpIcon; WORD wOldSize; register HBITMAP hXORbitmap; BOOL fStretchToSysMetrics;
{ WORD wCount; BITMAP bitmap; register HBITMAP hNewBitmap;
dprintf(7,"StretchIcon"); GetObject(hXORbitmap, sizeof(BITMAP), (LPSTR)&bitmap);
if(fStretchToSysMetrics) { /* Do we need to resize things? */ if ((oemInfo.cxIcon != bitmap.bmWidth) || (oemInfo.cyIcon != bitmap.bmHeight)) { hNewBitmap = StretchBitmap(bitmap.bmWidth, bitmap.bmHeight, oemInfo.cxIcon, oemInfo.cyIcon, hXORbitmap, bitmap.bmPlanes, bitmap.bmBitsPixel); DeleteObject(hXORbitmap);
if (hNewBitmap == NULL) return(0);
GetObject(hNewBitmap, sizeof(BITMAP), (LPSTR)&bitmap); hXORbitmap = hNewBitmap; } }
/* Update the Planes and BitsPixels field with the color values */ lpIcon->Planes = bitmap.bmPlanes; lpIcon->BitsPixel = bitmap.bmBitsPixel;
wCount = bitmap.bmWidthBytes * bitmap.bmHeight * bitmap.bmPlanes; GetBitmapBits(hXORbitmap, (DWORD)wCount, (LPSTR)((LPSTR)lpIcon + wOldSize)); DeleteObject(hXORbitmap);
return(wCount + wOldSize); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadDIBCursorIconHandler() - */ /* */ /* This is called when a Cursor/Icon in DIB format is loaded */ /* This converts the cursor/icon internal format and returns the */ /* handle */ /* */ /*--------------------------------------------------------------------------*/
HANDLE NEAR PASCAL LoadDIBCursorIconHandler(hRes, hResFile, hResIndex, fIcon)
register HANDLE hRes; HANDLE hResFile; HANDLE hResIndex; BOOL fIcon;
{ register int fh = 0; BOOL bNew = FALSE; WORD wMemBlkSize; LPCURSORSHAPE lpCurSh; HANDLE hTempRes;
dprintf(7,"LoadDIBCursorIconHandler"); wMemBlkSize = (WORD)SizeofResource(hResFile, hResIndex);
#if 1 // was 0 - NigelT
if (!hRes) { if (!(hRes = AllocResource(hResFile, hResIndex, 0L))) goto LoadDIBFail; fh = -1; bNew = TRUE; }
while (!(lpCurSh = (LPCURSORSHAPE)GlobalLock(hRes))) { if (!GlobalReAlloc(hRes, (DWORD)wMemBlkSize, 0)) goto LoadDIBFail; else fh = -1; }
if (fh) { fh = AccessResource(hResFile, hResIndex); if (fh != -1 && _lread(fh, (LPSTR)lpCurSh, wMemBlkSize) != 0xFFFF) _lclose(fh); else { if (fh != -1) _lclose(fh); GlobalUnlock(hRes); goto LoadDIBFail; } } #else
/* Call kernel's resource handler instead of doing the stuff ourselves
* because we use cached file handles that way. davidds */ // For resources which are not preloaded, hRes will be NULL at this point.
// For such cases, the default resource handler does the memory allocation
// and returns a valid handle.
// Fix for Bug #4257 -- 01/21/91 -- SANKAR
if (!(hTempRes = lpDefaultResourceHandler(hRes, hResFile, hResIndex))) goto LoadDIBFail; // We must use the handle returned by lpDefaultResourceHandler.
hRes = hTempRes;
lpCurSh = (LPCURSORSHAPE)GlobalLock(hRes); #endif
if (LoadDIBCursorIconHandler2(hRes, lpCurSh, wMemBlkSize, fIcon)) return(hRes);
LoadDIBFail: /* if the loading of the resource fails, we MUST discard the memory we
* reallocated above, or kernel will simply globallock the thing on the * next call to LockResource(), leaving invalid data in the object. */ if (bNew) FreeResource(hRes); else GlobalDiscard(hRes);
return(NULL); }
/*--------------------------------------------------------------------------*/ /* */ /* LoadDIBCursorIconHandler2() - */ /* */ /* This is called when a Cursor/Icon in DIB format is loaded */ /* This converts the cursor/icon into Old format and returns the */ /* handle */ /* */ /* NOTE: All cursors(always monochrome) and Monochrome Icons are treated */ /* alike by this routine. Color Icons are treated as special case */ /* determined by the local flag "fMono". */ /* */ /*--------------------------------------------------------------------------*/
HANDLE FAR PASCAL LoadDIBCursorIconHandler2(hRes, lpCurSh, wMemBlkSize, fIcon)
register HANDLE hRes; WORD wMemBlkSize; LPCURSORSHAPE lpCurSh; register BOOL fIcon;
{ HDC hDC; BOOL fMono = FALSE; WORD Width; WORD Height; WORD wCount; WORD BitCount; WORD Planes; LPSTR lpBits; BITMAP bitmap; HBITMAP hBitmap; WORD wNewSize; HBITMAP hANDbitmap; HBITMAP hXORbitmap; LPWORD lpColorTable; LPBITMAPINFOHEADER lpHeader; LPBITMAPCOREHEADER lpHeader1 = 0; BOOL fStretchToSysMetrics; BOOL fStretchInXdirection; BOOL fStretchInYdirection;
dprintf(7,"LoadDIBCursorIconHandler2"); lpHeader = (LPBITMAPINFOHEADER)lpCurSh;
if (!fIcon) { /* Skip over the cursor hotspot data in the first 2 words. */ lpHeader = (LPBITMAPINFOHEADER)((LPSTR)lpHeader + 4); }
if ((WORD)lpHeader->biSize == sizeof(BITMAPCOREHEADER)) { /* This is an "old form" DIB. This matches the PM 1.1 format. */ lpHeader1 = (LPBITMAPCOREHEADER)lpHeader;
Width = lpHeader1->bcWidth; Height = lpHeader1->bcHeight; BitCount = lpHeader1->bcBitCount; Planes = lpHeader1->bcPlanes;
/* Calcluate the pointer to the Bits information */ /* First skip over the header structure */ lpColorTable = (LPWORD)(lpBits = (LPSTR)(lpHeader1 + 1));
/* Skip the color table entries, if any */ if (lpHeader1->bcBitCount != 24) { if (lpHeader1->bcBitCount == 1) fMono = fCheckMono(lpBits, FALSE); lpBits += (1 << (lpHeader1->bcBitCount)) * sizeof(RGBTRIPLE); } } else { Width = (WORD)lpHeader->biWidth; Height = (WORD)lpHeader->biHeight; BitCount = lpHeader->biBitCount; Planes = lpHeader->biPlanes;
/* Calcluate the pointer to the Bits information */ /* First skip over the header structure */ lpColorTable = (LPWORD)(lpBits = (LPSTR)(lpHeader + 1));
/* Skip the color table entries, if any */ if (lpHeader->biClrUsed != 0) { if (lpHeader->biClrUsed == 2) fMono = fCheckMono(lpBits, TRUE); lpBits += lpHeader->biClrUsed * sizeof(RGBQUAD); } else { if (lpHeader->biBitCount != 24) { if (lpHeader->biBitCount == 1) fMono = fCheckMono(lpBits, TRUE); lpBits += (1 << (lpHeader->biBitCount)) * sizeof(RGBQUAD); } } }
// By default Stretch the icon/cursor to the dimensions in oemInfo;
// If this is FALSE, then the stretching will take place during DrawIcon();
fStretchInXdirection = TRUE; fStretchInYdirection = TRUE;
// Check if the Icon/Cursor needs to be stretched to the dimensions in
// oemInfo now or not.
if(fIcon) { if((oemInfo.cxIcon > STD_ICONWIDTH) && (Width <= oemInfo.cxIcon)) fStretchInXdirection = FALSE; // No Need to stretch in X direction;
if((oemInfo.cyIcon > STD_ICONHEIGHT) && (Height <= oemInfo.cyIcon)) fStretchInYdirection = FALSE; // No need to stretch in Y direction;
} else { if((oemInfo.cxCursor > STD_CURSORWIDTH) && (Width <= oemInfo.cxCursor)) fStretchInXdirection = FALSE; // No need to stretch in X direction.
if((oemInfo.cyCursor > STD_CURSORHEIGHT) && (Height <= oemInfo.cyCursor)) fStretchInYdirection = FALSE; // No need to stretch in Y direction.
}
fStretchToSysMetrics = fStretchInXdirection || fStretchInYdirection;
if (fMono) { /* Create a bitmap */ if (!(hBitmap = CreateBitmap(Width, Height, 1, 1, (LPSTR)NULL))) { GlobalUnlock(hRes); return(NULL); }
/* Convert the DIBitmap format into internal format */ SetDIBits(hdcBits, hBitmap, 0, Height, lpBits, (LPBITMAPINFO)lpHeader, DIB_RGB_COLORS); // Cursors/Icons in DIB format have a height twice the actual height.
wNewSize = SizeReqd(fIcon, BitCount, Planes, fStretchToSysMetrics, Width, Height>>1); } else { /* The height is twice that of icons */ Height >>= 1; if (lpHeader1) lpHeader1->bcHeight = Height; else lpHeader->biHeight = Height;
/* Create the XOR bitmap Compatible with the current device */ hDC = GetScreenDC(); if (!(hXORbitmap = CreateCompatibleBitmap(hDC, Width, Height))) { InternalReleaseDC(hDC); GlobalUnlock(hRes); return(NULL); } InternalReleaseDC(hDC);
/* Convert the DIBitmap into internal format */ SetDIBits(hdcBits, hXORbitmap, 0, Height, lpBits, (LPBITMAPINFO)lpHeader, DIB_RGB_COLORS);
GetObject(hXORbitmap, sizeof(BITMAP), (LPSTR)(&bitmap)); wNewSize = SizeReqd(fIcon, bitmap.bmBitsPixel, bitmap.bmPlanes, fStretchToSysMetrics, Width, Height);
/* Create the monochrome AND bitmap */ if (!(hANDbitmap = CreateBitmap(Width, Height, 1, 1, (LPSTR)NULL))) { GlobalUnlock(hRes); return(NULL); }
/* Get the offset to the AND bitmap */ lpBits += (((Width * BitCount + 0x1F) & ~0x1F) >> 3) * Height;
/* Set the header with data for a monochrome bitmap */ Planes = BitCount = 1;
/* Set the color table for a monochrome bitmap */ *lpColorTable++ = 0; *lpColorTable++ = 0xFF00; *lpColorTable = 0xFFFF;
if (lpHeader1) { lpHeader1->bcWidth = Width; lpHeader1->bcHeight = Height; lpHeader1->bcPlanes = Planes; lpHeader1->bcBitCount = BitCount; } else { lpHeader->biWidth = Width; lpHeader->biHeight = Height; lpHeader->biPlanes = Planes; lpHeader->biBitCount = BitCount; }
SetDIBits(hdcBits, hANDbitmap, 0, Height, lpBits, (LPBITMAPINFO)lpHeader, DIB_RGB_COLORS); hBitmap = hANDbitmap; }
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bitmap);
if (fIcon) { lpCurSh->xHotSpot = 0; lpCurSh->yHotSpot = 0; }
/* The following lines are replaced by a single functon call
* * lpCurSh->cx = bitmap.bmwidth; * lpCurSh->cy = bitmap.bmHeight; * lpCurSh->cbWidth = bitmap.bmWidthBytes; * lpCurSh->Planes = bitmap.bmPlanes; * lpCurSh->BitsPixel = bitmap.bmBitsPixel; */
LCopyStruct((LPSTR)&(bitmap.bmWidth), (LPSTR)&(lpCurSh->cx), (sizeof(WORD)) << 2);
/* Cursors in PM format have twice the actual height. */ if (fMono) lpCurSh->cy = lpCurSh->cy >> 1;
wCount = bitmap.bmWidthBytes * bitmap.bmHeight * bitmap.bmPlanes;
lpBits = (LPSTR)(lpCurSh + 1);
/* Copy the bits in Bitmap into the resource */ GetBitmapBits(hBitmap, (DWORD)wCount, lpBits);
/* Delete the bitmap */ DeleteObject(hBitmap);
/* Before crunching, let us make sure we have a big enough resource */ if (wNewSize > wMemBlkSize) { GlobalUnlock(hRes);
/* Make this non discardable so that kernel will try to move this block
* when reallocing. DavidDS */ GlobalReAlloc(hRes, 0L, GMEM_MODIFY | GMEM_NODISCARD);
if (!GlobalReAlloc(hRes, (DWORD)wNewSize, 0)) { /* So it gets discarded. Note that since the above realloc is less
* than 64K, the handle won't change. */ GlobalReAlloc(hRes, 0L, GMEM_MODIFY | GMEM_DISCARDABLE); return(NULL); }
GlobalReAlloc(hRes, 0L, GMEM_MODIFY | GMEM_DISCARDABLE); if (!(lpCurSh = (LPCURSORSHAPE)GlobalLock(hRes))) return(NULL);
wMemBlkSize = wNewSize; }
wNewSize = CrunchAndResize(lpCurSh, fIcon, TRUE, !fMono, fStretchToSysMetrics);
if (!fMono) { if (!(wNewSize = StretchIcon(lpCurSh, wNewSize, hXORbitmap, fStretchToSysMetrics))) { GlobalUnlock(hRes); return(NULL); } }
GlobalUnlock(hRes);
/* Does it need to be resized? */ if (wNewSize < wMemBlkSize) { if (!GlobalReAlloc(hRes, (DWORD)wNewSize, 0)) return(NULL); }
return(hRes); }
/*--------------------------------------------------------------------------*/ /* */ /* SizeReqd() - */ /* This returns the size of an Icon or Cursor after it is stretched */ /* or crunched */ /* */ /*--------------------------------------------------------------------------*/
WORD NEAR PASCAL SizeReqd(fIcon, BitCount, Planes, fUseSysMetrics, iWidth, iHeight)
BOOL fIcon; WORD BitCount; WORD Planes; BOOL fUseSysMetrics; int iWidth; int iHeight;
{ WORD size;
dprintf(7,"SizeReqd"); if(fUseSysMetrics) //Use the dimensions in oemInfo; Else, use given dimensions
{ if(fIcon) { iWidth = oemInfo.cxIcon; iHeight = oemInfo.cyIcon; } else { iWidth = oemInfo.cxCursor; iHeight = oemInfo.cyCursor; } }
size = (((iWidth*BitCount+0x0F) & ~0x0F) >> 3) * iHeight * Planes;
if ((BitCount == 1) && (Planes == 1)) size <<= 1; else size += (((iWidth+0x0F) & ~0x0F) >> 3)*iHeight;
return(size + sizeof(CURSORSHAPE)); }
#endif // NEEDED
|