📄 bitmap.c
字号:
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)
{
/*
* BUGS
* Only Windows NT 4.0 supports the LR_COPYRETURNORG flag for bitmaps,
* all other versions (95/2000/XP have been tested) ignore it.
*
* NOTES
* If LR_CREATEDIBSECTION is absent, the copy will be monochrome for
* a monochrome source bitmap or if LR_MONOCHROME is present, otherwise
* the copy will have the same depth as the screen.
* The content of the image will only be copied if the bit depth of the
* original image is compatible with the bit depth of the screen, or
* if the source is a DIB section.
* The LR_MONOCHROME flag is ignored if LR_CREATEDIBSECTION is present.
*/
switch (type)
{
case IMAGE_BITMAP:
{
HBITMAP res = NULL;
DIBSECTION ds;
int objSize;
BITMAPINFO * bi;
objSize = GetObjectW( hnd, sizeof(ds), &ds );
if (!objSize) return 0;
if ((desiredx < 0) || (desiredy < 0)) return 0;
if (flags & LR_COPYFROMRESOURCE)
{
DPRINT1("FIXME: The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
}
if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
/* Allocate memory for a BITMAPINFOHEADER structure and a
color table. The maximum number of colors in a color table
is 256 which corresponds to a bitmap with depth 8.
Bitmaps with higher depths don't have color tables. */
bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
if (!bi) return 0;
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
bi->bmiHeader.biPlanes = ds.dsBm.bmPlanes;
bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
bi->bmiHeader.biCompression = BI_RGB;
if (flags & LR_CREATEDIBSECTION)
{
/* Create a DIB section. LR_MONOCHROME is ignored */
void * bits;
HDC dc = CreateCompatibleDC(NULL);
if (objSize == sizeof(DIBSECTION))
{
/* The source bitmap is a DIB.
Get its attributes to create an exact copy */
memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
}
/* Get the color table or the color masks */
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
bi->bmiHeader.biWidth = desiredx;
bi->bmiHeader.biHeight = desiredy;
bi->bmiHeader.biSizeImage = 0;
res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
DeleteDC(dc);
}
else
{
/* Create a device-dependent bitmap */
BOOL monochrome = (flags & LR_MONOCHROME);
if (objSize == sizeof(DIBSECTION))
{
/* The source bitmap is a DIB section.
Get its attributes */
HDC dc = CreateCompatibleDC(NULL);
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
DeleteDC(dc);
if (!monochrome && ds.dsBm.bmBitsPixel == 1)
{
/* Look if the colors of the DIB are black and white */
monochrome =
(bi->bmiColors[0].rgbRed == 0xff
&& bi->bmiColors[0].rgbGreen == 0xff
&& bi->bmiColors[0].rgbBlue == 0xff
&& bi->bmiColors[0].rgbReserved == 0
&& bi->bmiColors[1].rgbRed == 0
&& bi->bmiColors[1].rgbGreen == 0
&& bi->bmiColors[1].rgbBlue == 0
&& bi->bmiColors[1].rgbReserved == 0)
||
(bi->bmiColors[0].rgbRed == 0
&& bi->bmiColors[0].rgbGreen == 0
&& bi->bmiColors[0].rgbBlue == 0
&& bi->bmiColors[0].rgbReserved == 0
&& bi->bmiColors[1].rgbRed == 0xff
&& bi->bmiColors[1].rgbGreen == 0xff
&& bi->bmiColors[1].rgbBlue == 0xff
&& bi->bmiColors[1].rgbReserved == 0);
}
}
else if (!monochrome)
{
monochrome = ds.dsBm.bmBitsPixel == 1;
}
if (monochrome)
{
res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
}
else
{
HDC screenDC = GetDC(NULL);
res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
ReleaseDC(NULL, screenDC);
}
}
if (res)
{
/* Only copy the bitmap if it's a DIB section or if it's
compatible to the screen */
BOOL copyContents;
if (objSize == sizeof(DIBSECTION))
{
copyContents = TRUE;
}
else
{
HDC screenDC = GetDC(NULL);
int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
ReleaseDC(NULL, screenDC);
copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
}
if (copyContents)
{
/* The source bitmap may already be selected in a device context,
use GetDIBits/StretchDIBits and not StretchBlt */
HDC dc;
void * bits;
dc = CreateCompatibleDC(NULL);
bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
bi->bmiHeader.biSizeImage = 0;
bi->bmiHeader.biClrUsed = 0;
bi->bmiHeader.biClrImportant = 0;
/* Fill in biSizeImage */
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
if (bits)
{
HBITMAP oldBmp;
/* Get the image bits of the source bitmap */
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
/* Copy it to the destination bitmap */
oldBmp = SelectObject(dc, res);
StretchDIBits(dc, 0, 0, desiredx, desiredy,
0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
bits, bi, DIB_RGB_COLORS, SRCCOPY);
SelectObject(dc, oldBmp);
HeapFree(GetProcessHeap(), 0, bits);
}
DeleteDC(dc);
}
if (flags & LR_COPYDELETEORG)
{
DeleteObject(hnd);
}
}
HeapFree(GetProcessHeap(), 0, bi);
return (HICON)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);
// return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);
}
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;
}
/* Should call CURSORICON_ExtCopy but more testing
* needs to be done before we change this
*/
if (flags) DPRINT1("FIXME: Flags are ignored\n");
return CopyCursor(hnd);
}
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -