📄 loadimg.c
字号:
_WinGdi_ConvertImageColorValue(
lpDrv,
(_LPBITMAP_DIB)lpImage, // dest
NULL,
lpbi,
NULL,
dwStartScanLine,
dwReadScanLine,
iScanLineBytes,
lpbData,
DIB_PAL_COLORS
);
//下几扫描行
dwStartScanLine += dwReadScanLine;
}
//释放临时内存 ?
free( lpbData );
}
}
return hbmp;
}
// **************************************************
// 声明:static HBITMAP _HandleBitmapFile( HANDLE hFile, BOOL bShare )
// 参数:
// IN hFile - 文件句柄
// IN bShare - 是否共享
// 返回值:
// 假如成功,返回有效的非NULL位图句柄;否则,返回NULL
// 功能描述:
// 根据文件创建一个内存位图对象
// 引用:
//
// ************************************************
#define DEBUG_HANDLE_BITMAP_FILE 0
static HBITMAP _HandleBitmapFile( HANDLE hFile, BOOL bShare )
{
MYBITMAPFILEHEADER bfh;
DWORD dwReadSize;
HBITMAP hBitmap = NULL;
RETAILMSG( DEBUG_HANDLE_BITMAP_FILE, ( "_HandleBitmapFile entry.\r\n" ) );
//对文件头
ReadFile( hFile, &bfh.bfType, sizeof(MYBITMAPFILEHEADER) - sizeof(WORD), &dwReadSize, NULL );
//是否位图文件 ?
if( dwReadSize == (sizeof(MYBITMAPFILEHEADER) - sizeof(WORD)) &&
*((LPBYTE)&bfh.bfType) == 'B' &&
*( ((LPBYTE)&bfh.bfType) + 1 ) == 'M' )
{ //是
hBitmap = HandleBitmapData( hFile, bShare );
}
else
{ //否
SetLastError( ERROR_BAD_FORMAT );
WARNMSG( DEBUG_HANDLE_BITMAP_FILE, ( "_HandleBitmapFile error: invalid bitmap format !" ) );
}
RETAILMSG( DEBUG_HANDLE_BITMAP_FILE, ( "_HandleBitmapFile leave.\r\n" ) );
return hBitmap;
}
typedef struct _ICOCURSORHDR
{
WORD wReserved; // always 0
WORD wResourceType;
WORD wResourceCount; // number of resources in file
}ICOCURSORHDR;
//某些编译器可能有对齐结构功能
#define ICOCURSORHDR_REAL_SIZE 6
typedef struct _ICOCURSORDESC
{
BYTE bWidth; // width of image (icons only )
BYTE bHeight; // height of image(icons only)
BYTE bColorCount; // number of colors in image
BYTE bUnused; //
WORD wHotspotX; // hotspot x coordinate (CURSORS only)
WORD wHotspotY; // hotspot y coordinate (CURSORS only)
DWORD dwDIBSize; // size of DIB for this image
DWORD dwDIBOffset; // offset to DIB for this image
} ICOCURSORDESC, FAR * LPICOCURSORDESC;
#define MAXIMAGES 64 // Maximum images in an ico/cur file.
// **************************************************
// 声明:static BOOL IsValidIcoCursorData(
// DWORD dwFilePos,
// LPICOCURSORDESC lpDesc,
// int nImages,
// DWORD dwFileSize )
// 参数:
// IN dwFilePos - ICON 和 CURSOR 数据在文件中的偏移值
// IN lpDesc - 包含每个ICON 和 CURSOR项目数据的结构
// IN nImages - ICON 和 CURSOR项目数据结构的个数
// IN dwFileSize - 文件总大小
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 检查文件中的ICON 和 CURSOR项目数据是否有效
// 引用:
//
// ************************************************
#define DEBUG_IsValidIcoCursorData 0
static BOOL IsValidIcoCursorData( DWORD dwFilePos,
LPICOCURSORDESC lpDesc,
int nImages,
DWORD dwFileSize )
{
int i;
for (i = 0; i < nImages; i++)
{
if (lpDesc->dwDIBOffset != dwFilePos ||
dwFilePos + lpDesc->dwDIBSize > dwFileSize )
{
WARNMSG( DEBUG_IsValidIcoCursorData, ( "IsValidIcoCursorData: error i(%d),lpDesc->dwDIBOffset(%d),dwFilePos(%d),lpDesc->dwDIBSize(%d),dwFileSize(%d).\r\n",i,lpDesc->dwDIBOffset,dwFilePos,lpDesc->dwDIBSize,dwFileSize ) );
return FALSE;
}
dwFilePos += lpDesc->dwDIBSize;
lpDesc++;
}
return TRUE;
}
// **************************************************
// 声明:static int GetNeedImageIndex(
// HANDLE hFile,
// LPICOCURSORDESC lpDesc,
// int nImages,
// int cxDesired,
// int cyDesired )
// 参数:
// IN hFile - 位图文件句柄
// IN lpDesc - 包含每个ICON 和 CURSOR项目数据的结构
// IN nImages - 需要查找的文件名
// IN cxDesired - 要求的宽度
// IN cyDesired - 要求的高度
// 返回值:
// 假如成功,返回匹配的项目索引号;否则,返回-1
// 功能描述:
// 得到符合要求的项目在文件里的索引号/位置
// 引用:
//
// ************************************************
static int GetNeedImageIndex(
HANDLE hFile,
LPICOCURSORDESC lpDesc,
int nImages,
int cxDesired,
int cyDesired )
{
int i;
BITMAPINFO bi;
if( cxDesired == 0 || cyDesired == 0 )
return 0;
for (i = 0; i < nImages; i++)
{
DWORD dwReaded;
SetFilePointer( hFile, lpDesc->dwDIBOffset, NULL, FILE_BEGIN );
ReadFile( hFile, &bi, sizeof( bi ), &dwReaded, NULL );
if( IS_SIZE_MATCH( bi.bmiHeader.biWidth, bi.bmiHeader.biHeight / 2, cxDesired, cyDesired ) )
{ //符合要求
return i;
}
lpDesc++; //下一个项目
}
return -1;
}
// **************************************************
// 声明:HANDLE IconCursorCreate(
// int xHot,
// int yHot,
// BITMAPINFO * lpbi,
// int uiType,
// int uiName )
// 参数:
// IN xHot - 光标的热点
// IN yHot - 光标的热点
// IN lpbi - 位图信息
// IN uiType - 位图类型:
// IMAGE_ICON - 图标
// IMAGE_CURSOR - 光标
// IN uiName - 对象ID
// 返回值:
// 假如成功,返回创建的位图句柄;否则,返回NULL
// 功能描述:
// 创建图标或光标资源
// 引用:
//
// ************************************************
HANDLE IconCursorCreate(
int xHot,
int yHot,
BITMAPINFO * lpbi,
int uiType,
int uiName )
{
int iBitCount;
int cx;
int cy;
DWORD cbColorTable;
DWORD cbBits;
LPBYTE lpDIBBits;
HICON hIcon = NULL;
ICONINFO icon;
DWORD dwStartScanLine;
int iDir;
int iScanLineBytes;
HBITMAP hbmp;
HBITMAP hbmpMono;
lpbi->bmiHeader.biHeight /= 2;
dwStartScanLine = 0;
if( (int)lpbi->bmiHeader.biHeight > 0 )
{ //反向
cy = lpbi->bmiHeader.biHeight;
iDir = -1;
}
else
{ //正向
cy = -(int)lpbi->bmiHeader.biHeight;
iDir = 1;
}
//创建彩色位图
if( lpbi->bmiHeader.biBitCount != 1 )
hbmp = WinGdi_CreateBitmap( lpbi->bmiHeader.biWidth, cy, lpDisplayBitmap->bmPlanes, lpDisplayBitmap->bmBitsPixel, 0 );
else
hbmp = WinGdi_CreateBitmap( lpbi->bmiHeader.biWidth, cy, 1, 1, 0 );
//创建黑白位模位图
hbmpMono = WinGdi_CreateBitmap( lpbi->bmiHeader.biWidth, cy, 1, 1, 0 );
if( hbmp && hbmpMono )
{
iBitCount = lpbi->bmiHeader.biBitCount;
cx = (int)lpbi->bmiHeader.biWidth;
cbColorTable = GetColorTableNum( &lpbi->bmiHeader ) * sizeof(RGBQUAD);
//指向位图数据
lpDIBBits = (LPBYTE)lpbi + sizeof(BITMAPINFOHEADER) + cbColorTable;
//对齐到DWORD
iScanLineBytes = (cx * iBitCount + 31 ) / 32 * 4; // align to dword
cbBits = iScanLineBytes * cy;
//转换ICON/CURSOR的颜色部分
if( lpbi->bmiHeader.biBitCount != 1 )
{
_LPBITMAPDATA lpImage = _GetHBITMAPPtr(hbmp);
//转换颜色表从RQBQUAD格式到PAL格式
_ConvertRGBQUADColorToPalColor( lpbi );
//转换位图数据到目标
_WinGdi_ConvertImageColorValue(
GetDisplayDeviceDriver( lpImage ),
(_LPBITMAP_DIB)lpImage,
NULL,
lpbi,
NULL,
dwStartScanLine,
cy,
iScanLineBytes,
lpDIBBits,
DIB_PAL_COLORS
);
}
else
{ //转换位图数据到目标
_ConvertMonoBitmap(
_GetHBITMAPPtr(hbmp),
dwStartScanLine,
cy,
iScanLineBytes,
lpDIBBits,
lpbi,
0 );
}
//指向位模部分
//位模是紧跟着颜色部分
lpDIBBits += cbBits;
lpbi->bmiHeader.biBitCount = 1;
//对齐到DWORD
iScanLineBytes = (cx * 1 + 31) / 32 * 4; //align to dword
//转换ICON/CURSOR的位模部分
_ConvertMonoBitmap(
_GetHBITMAPPtr(hbmpMono),
dwStartScanLine,
cy,
iScanLineBytes,
lpDIBBits,
lpbi,
1 );
icon.fIcon = uiType;
icon.hbmColor = hbmp;
icon.hbmMask = hbmpMono;
icon.xHotspot = xHot;
icon.yHotspot = yHot;
//创建ICON对象
hIcon = _CreateIconIndirect( &icon, uiName, 0 );
if( hIcon == NULL )
{ //失败,清除
DeleteObject( hbmp );
DeleteObject( hbmpMono );
}
}
else
{ //失败,清除
if( hbmp )
WinGdi_DeleteObject( hbmp );
if( hbmp )
WinGdi_DeleteObject( hbmpMono );
}
return hIcon;
}
// **************************************************
// 声明:static ICOCURSORDESC * AllocDescAndCheck(
// HANDLE hFile,
// int iResourceCount,
// DWORD dwFileSize )
// 参数:
// IN hFile - 文件句柄
// IN iResourceCount - 需要分配的资源数
// IN dwFileSize - 文件的大小
// 返回值:
// 假如成功,返回分配/并初始化好的ICOCURSORDESC结构;否则,返回NULL
// 功能描述:
// 分配需要的的ICOCURSORDESC结构
// 从文件里读出ICOCURSORDESC结构数据
// 引用:
//
// ************************************************
#define DEBUG_AllocDescAndCheck 0
static ICOCURSORDESC * AllocDescAndCheck( HANDLE hFile, int iResourceCount, DWORD dwFileSize )
{
DWORD dwReaded;
UINT uiDescSize = sizeof(ICOCURSORDESC) * iResourceCount;
ICOCURSORDESC *lpDesc = (ICOCURSORDESC *)malloc( uiDescSize );
DEBUGMSG( DEBUG_AllocDescAndCheck, ( "AllocDescAndCheck: entry.\r\n" ) );
if( lpDesc )
{ //读需要的 ICOCURSORDESC 结构数据
if( ReadFile( hFile, lpDesc, uiDescSize, &dwReaded, NULL ) )
{ //检查是否有效
if( dwReaded == uiDescSize )
{ // check valid ?
DWORD dwFilePos = (DWORD)SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
//检查是否有效
if( IsValidIcoCursorData( dwFilePos, lpDesc, iResourceCount, dwFileSize ) )
return lpDesc;
else
{
WARNMSG( DEBUG_AllocDescAndCheck, ( "AllocDescAndCheck: invalid data.\r\n" ) );
}
}
else
{
WARNMSG( DEBUG_AllocDescAndCheck, ( "AllocDescAndCheck: dwReaded(%d) != uiDescSize(%d).\r\n", dwReaded, uiDescSize ) );
}
}
else
{
WARNMSG( DEBUG_AllocDescAndCheck, ( "AllocDescAndCheck: can't read file.\r\n" ) );
}
free( lpDesc );
return NULL;
}
else
{
WARNMSG( DEBUG_AllocDescAndCheck, ( "AllocDescAndCheck: can't alloc memory.\r\n" ) );
}
return NULL;
}
// **************************************************
// 声明:void FreeDesc( ICOCURSORDESC *lpDesc )
// 参数:
// IN lpDesc - ICOCURSORDESC 结构指针
// 返回值:
// 无
// 功能描述:
// 与 AllocDescAndCheck 相反,释放 ICOCURSORDESC 结构内存
// 引用:
//
// ************************************************
void FreeDesc( ICOCURSORDESC *lpDesc )
{
free( lpDesc );
}
// **************************************************
// 声明:static HANDLE _HandleIconCursorFile(
// HANDLE hFile,
// UINT uType,
// int cxDesired,
// int cyDesired,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -