skinimage.cpp
来自「网狐棋牌(家园版)最新版本7.1.1源代码,共享组件源码」· C++ 代码 · 共 386 行
CPP
386 行
#include "StdAfx.h"
#include "SkinImage.h"
/////////////////////////////////////////////////////////////////////////////////////////
//构造函数
CSkinImage::CSkinImage(void)
{
m_nRefCount=0;
m_bLoadAlways=false;
}
//析构函数
CSkinImage::~CSkinImage(void)
{
Destroy();
}
//增加引用
int CSkinImage::LockResource()
{
if (m_nRefCount==0)
{
if (m_LoadInfo.hResourceDLL==NULL) Load(m_LoadInfo.strFileName);
else LoadFromResource(m_LoadInfo.hResourceDLL,m_LoadInfo.uResourceID);
if (IsNull()) return 0;
}
return ++m_nRefCount;
}
//减少引用
int CSkinImage::UnLockResource()
{
try
{
if (m_nRefCount>0) m_nRefCount--;
if (m_nRefCount==0) Destroy();
}
catch (...) {}
return m_nRefCount;
}
//是否设置加载信息
bool CSkinImage::IsSetLoadInfo()
{
return ((m_LoadInfo.hResourceDLL)||(m_LoadInfo.strFileName.IsEmpty()==false));
}
//清除加载参数
bool CSkinImage::RemoveLoadInfo()
{
m_LoadInfo.uResourceID=0;
m_LoadInfo.hResourceDLL=NULL;
m_LoadInfo.strFileName.Empty();
return true;
}
//获取加载参数
bool CSkinImage::GetLoadInfo(tagImageLoadInfo & LoadInfo)
{
LoadInfo=m_LoadInfo;
return IsSetLoadInfo();
}
//设置加载参数
bool CSkinImage::SetLoadInfo(LPCTSTR pszFileName, bool bLoadAlways)
{
//保存变量
int nOldRefCount=m_nRefCount;
bool bOldLoadAlways=m_bLoadAlways;
//清理资源
Destroy();
m_nRefCount=0;
m_bLoadAlways=bLoadAlways;
//设置变量
m_LoadInfo.uResourceID=0;
m_LoadInfo.hResourceDLL=NULL;
m_LoadInfo.strFileName=pszFileName;
//恢复锁定
if (bOldLoadAlways) nOldRefCount--;
if (m_bLoadAlways) nOldRefCount++;
while (nOldRefCount>0)
{
nOldRefCount--;
LockResource();
};
return true;
}
//设置加载参数
bool CSkinImage::SetLoadInfo(UINT uResourceID, HINSTANCE hResourceDLL, bool bLoadAlways)
{
//保存变量
int nOldRefCount=m_nRefCount;
bool bOldLoadAlways=m_bLoadAlways;
//清理资源
Destroy();
m_nRefCount=0;
m_bLoadAlways=bLoadAlways;
m_LoadInfo.strFileName.Empty();
//设置变量
m_LoadInfo.uResourceID=uResourceID;
m_LoadInfo.hResourceDLL=hResourceDLL;
//恢复锁定
if (bOldLoadAlways) nOldRefCount--;
if (m_bLoadAlways) nOldRefCount++;
while (nOldRefCount>0)
{
nOldRefCount--;
LockResource();
};
return true;
}
//创建区域
HRGN CSkinImage::CreateImageRegion(COLORREF cTranColor)
{
//判断状态
if (IsNull()==true) return NULL;
//创建区域
HRGN hRgn=NULL;
HDC hMemDC=::CreateCompatibleDC(NULL);
if (hMemDC!=NULL)
{
void * pbits32=NULL;
HBITMAP hBitmap=(HBITMAP)this;
BITMAPINFOHEADER RGB32BITSBITMAPINFO={sizeof(BITMAPINFOHEADER),GetWidth(),GetHeight(),1,32,BI_RGB,0,0,0,0,0};
HBITMAP hbm32=CreateDIBSection(hMemDC,(BITMAPINFO *)&RGB32BITSBITMAPINFO,DIB_RGB_COLORS,&pbits32,NULL,0);
if (hbm32)
{
HBITMAP holdBmp=(HBITMAP)SelectObject(hMemDC,hbm32);
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
{
BITMAP bm32;
GetObject(hbm32,sizeof(bm32),&bm32);
while (bm32.bmWidthBytes%4) bm32.bmWidthBytes++;
HBITMAP holdBmp=(HBITMAP)SelectObject(hDC,hBitmap);
::BitBlt(hMemDC,0,0,GetWidth(),GetHeight(),hDC,0,0,SRCCOPY);
DWORD maxRects=100;
HANDLE hData=GlobalAlloc(GMEM_MOVEABLE,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRects));
RGNDATA *pData=(RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize=sizeof(RGNDATAHEADER);
pData->rdh.iType=RDH_RECTANGLES;
pData->rdh.nCount=pData->rdh.nRgnSize=0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
BYTE hr=GetRValue(cTranColor);
BYTE hg=GetGValue(cTranColor);
BYTE hb=GetBValue(cTranColor);
BYTE * p32=(BYTE *)bm32.bmBits+(bm32.bmHeight-1)*bm32.bmWidthBytes;
for (int y=0;y<GetHeight();y++)
{
for (int x=0;x<GetWidth();x++)
{
int x0=x;
LONG *p=(LONG *)p32+x;
while (x<GetWidth())
{
BYTE b=GetRValue(*p);
if ((b>=hr)&&(b<=hr))
{
b=GetGValue(*p);
if (b>=hg&&b<=hg)
{
b=GetBValue(*p);
if (b>=hb&&b<=hb) break;
}
}
p++;
x++;
}
if (x>x0)
{
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += 100;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT * pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0<pData->rdh.rcBound.left) pData->rdh.rcBound.left=x0;
if (y<pData->rdh.rcBound.top) pData->rdh.rcBound.top=y;
if (x>pData->rdh.rcBound.right) pData->rdh.rcBound.right=x;
if (y+1>pData->rdh.rcBound.bottom) pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;
if (pData->rdh.nCount==2000)
{
HRGN h=ExtCreateRegion(NULL,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRects),pData);
if (hRgn)
{
CombineRgn(hRgn,hRgn,h,RGN_OR);
DeleteObject(h);
}
else hRgn = h;
pData->rdh.nCount=0;
SetRect(&pData->rdh.rcBound,MAXLONG, MAXLONG,0,0);
}
}
}
p32 -= bm32.bmWidthBytes;
}
HRGN h=ExtCreateRegion(NULL,sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRects),pData);
if (hRgn)
{
CombineRgn(hRgn,hRgn,h,RGN_OR);
DeleteObject(h);
}
else hRgn=h;
GlobalFree(hData);
SelectObject(hDC,holdBmp);
DeleteDC(hDC);
}
DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
return hRgn;
}
//透明绘画
bool CSkinImage::AlphaDrawImage(CDC * pDestDC, int xDest, int yDest, COLORREF crTrans)
{
return AlphaDrawImage(pDestDC,xDest,yDest,GetWidth(),GetHeight(),0,0,crTrans);
}
//透明绘画
bool CSkinImage::AlphaDrawImage(CDC * pDestDC, int xDest, int yDest, int cxDest, int cyDest, int xSrc, int ySrc, COLORREF crTrans)
{
//效验状态
if (IsNull()) return false;
//建立 DC
CDC DCImage;
DCImage.CreateCompatibleDC(pDestDC);
DCImage.SelectObject(HBITMAP(*this));
DCImage.SetBkColor(crTrans);
DCImage.SetBkMode(TRANSPARENT);
//建立掩码图
CDC DCMask;
CBitmap BMPMask;
BMPMask.CreateBitmap(cxDest,cyDest,1,1,NULL);
DCMask.CreateCompatibleDC(pDestDC);
DCMask.SelectObject(&BMPMask);
DCMask.BitBlt(0,0,cxDest,cyDest,&DCImage,xSrc,ySrc,SRCCOPY);
//绘画目标图
CDC DCDest;
CBitmap BMPDest;
DCDest.CreateCompatibleDC(pDestDC);
BMPDest.CreateCompatibleBitmap(pDestDC,cxDest,cyDest);
DCDest.SelectObject(&BMPDest);
DCDest.BitBlt(0,0,cxDest,cyDest,pDestDC,xDest,yDest,SRCCOPY);
DCDest.BitBlt(0,0,cxDest,cyDest,&DCImage,xSrc,ySrc,SRCINVERT);
DCDest.BitBlt(0,0,cxDest,cyDest,&DCMask,0,0,SRCAND);
DCDest.BitBlt(0,0,cxDest,cyDest,&DCImage,xSrc,ySrc,SRCINVERT);
pDestDC->BitBlt(xDest,yDest,cxDest,cyDest,&DCDest,0,0,SRCCOPY);
//清理资源
DCMask.DeleteDC();
DCDest.DeleteDC();
DCImage.DeleteDC();
BMPMask.DeleteObject();
BMPDest.DeleteObject();
return true;
}
//透明绘画
bool CSkinImage::AlphaDrawImageEx(CDC * pDestDC, int xDest, int yDest, COLORREF crTrans)
{
return AlphaDrawImageEx(pDestDC,xDest,yDest,GetWidth(),GetHeight(),0,0,crTrans);
}
//透明绘画
bool CSkinImage::AlphaDrawImageEx(CDC * pDestDC, int xDest, int yDest, int cxDest, int cyDest, int xSrc, int ySrc, COLORREF crTrans)
{
//效验状态
if (IsNull()) return false;
//建立 DC
CDC DCImage;
DCImage.CreateCompatibleDC(pDestDC);
DCImage.SelectObject(HBITMAP(*this));
DCImage.SetBkColor(crTrans);
DCImage.SetBkMode(TRANSPARENT);
//建立掩码图
CDC DCMask;
CBitmap BMPMask;
BMPMask.CreateBitmap(cxDest,cyDest,1,1,NULL);
DCMask.CreateCompatibleDC(pDestDC);
DCMask.SelectObject(&BMPMask);
DCMask.BitBlt(0,0,cxDest,cyDest,&DCImage,xSrc,ySrc,SRCCOPY);
//绘画目标图
pDestDC->BitBlt(xDest,yDest,cxDest,cyDest,pDestDC,xDest,yDest,SRCCOPY);
pDestDC->BitBlt(xDest,yDest,cxDest,cyDest,&DCImage,xSrc,ySrc,SRCINVERT);
pDestDC->BitBlt(xDest,yDest,cxDest,cyDest,&DCMask,0,0,SRCAND);
pDestDC->BitBlt(xDest,yDest,cxDest,cyDest,&DCImage,xSrc,ySrc,SRCINVERT);
//清理资源
DCMask.DeleteDC();
DCImage.DeleteDC();
BMPMask.DeleteObject();
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
//构造函数
CImageHandle::CImageHandle(CSkinImage * pImageObject)
{
m_pImage=NULL;
AttachResource(pImageObject);
return;
}
//析构函数
CImageHandle::~CImageHandle()
{
DetchResource();
return;
}
//绑定资源
bool CImageHandle::AttachResource(IGDIResource * pImageObject)
{
DetchResource();
if (pImageObject)
{
CSkinImage * pSkinImage=(CSkinImage *)pImageObject;
if (pImageObject->LockResource()>0)
{
m_pImage=pSkinImage;
return true;
}
}
return false;
}
//解除绑定
bool CImageHandle::DetchResource()
{
if (m_pImage)
{
m_pImage->UnLockResource();
m_pImage=NULL;
return true;
}
return false;
}
//是否绑定
bool CImageHandle::IsAttached()
{
return (m_pImage!=NULL);
}
//是否有效
bool CImageHandle::IsResourceValid()
{
return ((m_pImage)&&(m_pImage->IsNull()==false));
}
//获取句柄
HBITMAP CImageHandle::GetBitmapHandle()
{
if (IsResourceValid()==false) return NULL;
return (HBITMAP)(*m_pImage);
}
/////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?