bitmap.c
来自「一个类似windows」· C语言 代码 · 共 622 行 · 第 1/2 页
C
622 行
ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
/*
* FIXME:
* Remove this after proper support for alpha icons will be finished.
*/
if (ColorBits > 8)
ColorBits = 8;
}
/* Pick the best size. */
dirEntry = CURSORICON_FindBestCursorFile( IconDIR, width, height, ColorBits );
if (!dirEntry)
{
DeleteDC(hScreenDc);
UnmapViewOfFile(IconDIR);
return NULL;
}
if ( dirEntry->dwDIBOffset > filesize )
{
DeleteDC(hScreenDc);
UnmapViewOfFile(IconDIR);
return NULL;
}
if ( dirEntry->dwDIBOffset + dirEntry->dwDIBSize > filesize ){
DeleteDC(hScreenDc);
UnmapViewOfFile(IconDIR);
return NULL;
}
SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwDIBSize);
if (SafeIconImage == NULL)
{
DeleteDC(hScreenDc);
UnmapViewOfFile(IconDIR);
return NULL;
}
memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwDIBOffset, dirEntry->dwDIBSize);
UnmapViewOfFile(IconDIR);
/* At this point we have a copy of the icon image to play with. */
SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
ColorCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
HeaderSize = sizeof(BITMAPCOREHEADER) + ColorCount * sizeof(RGBTRIPLE);
}
else
{
ColorCount = SafeIconImage->icHeader.biClrUsed;
if (ColorCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
ColorCount = 1 << SafeIconImage->icHeader.biBitCount;
HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
}
/* Make data point to the start of the XOR image data. */
Data = (PBYTE)SafeIconImage + HeaderSize;
hIcon = ICON_CreateIconFromData(hScreenDc, Data, SafeIconImage, width, height, width/2, height/2);
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
DeleteDC(hScreenDc);
return hIcon;
}
static HANDLE
LoadBitmapImage(HINSTANCE hInstance, LPCWSTR lpszName, UINT fuLoad)
{
HANDLE hResource;
HANDLE hFile;
HANDLE hSection;
LPBITMAPINFO BitmapInfo;
LPBITMAPINFO PrivateInfo;
HDC hScreenDc;
HANDLE hBitmap;
ULONG HeaderSize;
ULONG ColorCount;
PVOID Data;
if (!(fuLoad & LR_LOADFROMFILE))
{
if (hInstance == NULL)
hInstance = User32Instance;
hResource = FindResourceW(hInstance, lpszName, RT_BITMAP);
if (hResource == NULL)
return NULL;
hResource = LoadResource(hInstance, hResource);
if (hResource == NULL)
return NULL;
BitmapInfo = LockResource(hResource);
if (BitmapInfo == NULL)
return NULL;
}
else
{
hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return NULL;
hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
CloseHandle(hFile);
if (hSection == NULL)
return NULL;
BitmapInfo = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
CloseHandle(hSection);
if (BitmapInfo == NULL)
return NULL;
BitmapInfo = (LPBITMAPINFO)((ULONG_PTR)BitmapInfo + sizeof(BITMAPFILEHEADER));
}
if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)BitmapInfo;
ColorCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
HeaderSize = sizeof(BITMAPCOREHEADER) + ColorCount * sizeof(RGBTRIPLE);
}
else
{
ColorCount = BitmapInfo->bmiHeader.biClrUsed;
if (ColorCount == 0 && BitmapInfo->bmiHeader.biBitCount <= 8)
ColorCount = 1 << BitmapInfo->bmiHeader.biBitCount;
HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
}
Data = (PVOID)((ULONG_PTR)BitmapInfo + HeaderSize);
PrivateInfo = RtlAllocateHeap(GetProcessHeap(), 0, HeaderSize);
if (PrivateInfo == NULL)
{
if (fuLoad & LR_LOADFROMFILE)
UnmapViewOfFile(BitmapInfo);
return NULL;
}
memcpy(PrivateInfo, BitmapInfo, HeaderSize);
/* FIXME: Handle color conversion and transparency. */
hScreenDc = CreateCompatibleDC(NULL);
if (hScreenDc == NULL)
{
RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
if (fuLoad & LR_LOADFROMFILE)
UnmapViewOfFile(BitmapInfo);
return NULL;
}
if (fuLoad & LR_CREATEDIBSECTION)
{
DIBSECTION Dib;
hBitmap = CreateDIBSection(hScreenDc, PrivateInfo, DIB_RGB_COLORS, NULL,
0, 0);
GetObjectA(hBitmap, sizeof(DIBSECTION), &Dib);
SetDIBits(hScreenDc, hBitmap, 0, Dib.dsBm.bmHeight, Data, BitmapInfo,
DIB_RGB_COLORS);
}
else
{
hBitmap = CreateDIBitmap(hScreenDc, &PrivateInfo->bmiHeader, CBM_INIT,
Data, PrivateInfo, DIB_RGB_COLORS);
}
RtlFreeHeap(GetProcessHeap(), 0, PrivateInfo);
DeleteDC(hScreenDc);
if (fuLoad & LR_LOADFROMFILE)
UnmapViewOfFile(BitmapInfo);
return hBitmap;
}
HANDLE STDCALL
LoadImageW(
IN HINSTANCE hinst,
IN LPCWSTR lpszName,
IN UINT uType,
IN INT cxDesired,
IN INT cyDesired,
IN UINT fuLoad)
{
if (fuLoad & LR_DEFAULTSIZE)
{
if (uType == IMAGE_ICON)
{
if (cxDesired == 0)
cxDesired = GetSystemMetrics(SM_CXICON);
if (cyDesired == 0)
cyDesired = GetSystemMetrics(SM_CYICON);
}
else if (uType == IMAGE_CURSOR)
{
if (cxDesired == 0)
cxDesired = GetSystemMetrics(SM_CXCURSOR);
if (cyDesired == 0)
cyDesired = GetSystemMetrics(SM_CYCURSOR);
}
}
switch (uType)
{
case IMAGE_BITMAP:
return LoadBitmapImage(hinst, lpszName, fuLoad);
case IMAGE_CURSOR:
case IMAGE_ICON:
return LoadCursorIconImage(hinst, lpszName, cxDesired, cyDesired,
fuLoad, uType);
default:
break;
}
return NULL;
}
/*
* @implemented
*/
HBITMAP STDCALL
LoadBitmapA(HINSTANCE hInstance, LPCSTR lpBitmapName)
{
return LoadImageA(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0);
}
/*
* @implemented
*/
HBITMAP STDCALL
LoadBitmapW(HINSTANCE hInstance, LPCWSTR lpBitmapName)
{
return LoadImageW(hInstance, lpBitmapName, IMAGE_BITMAP, 0, 0, 0);
}
/*
* @unimplemented
*/
HANDLE WINAPI
CopyImage(
IN HANDLE hnd,
IN UINT type,
IN INT desiredx,
IN INT desiredy,
IN UINT flags)
{
HBITMAP res;
BITMAP bm;
switch (type)
{
case IMAGE_BITMAP:
{
DPRINT("WARNING: Incomplete implementation of CopyImage!\n");
/*
* FIXME: Support flags LR_COPYDELETEORG, LR_COPYFROMRESOURCE,
* LR_COPYRETURNORG, LR_CREATEDIBSECTION and LR_MONOCHROME.
*/
if (!GetObjectW(hnd, sizeof(bm), &bm))
return NULL;
bm.bmBits = NULL;
if ((res = CreateBitmapIndirect(&bm)))
{
char *buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight);
if (buf == NULL)
{
DeleteObject(res);
return NULL;
}
GetBitmapBits(hnd, bm.bmWidthBytes * bm.bmHeight, buf);
SetBitmapBits(res, bm.bmWidthBytes * bm.bmHeight, buf);
HeapFree(GetProcessHeap(), 0, buf);
}
return res;
}
case IMAGE_ICON:
{
static BOOL IconMsgDisplayed = FALSE;
/* FIXME: support loading the image as shared from an instance */
if (!IconMsgDisplayed)
{
DPRINT("FIXME: CopyImage doesn't support IMAGE_ICON correctly!\n");
IconMsgDisplayed = TRUE;
}
return CopyIcon(hnd);
}
case IMAGE_CURSOR:
{
static BOOL IconMsgDisplayed = FALSE;
/* FIXME: support loading the image as shared from an instance */
if (!IconMsgDisplayed)
{
DPRINT("FIXME: CopyImage doesn't support IMAGE_CURSOR correctly!\n");
IconMsgDisplayed = TRUE;
}
return CopyCursor(hnd);
}
}
return NULL;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?