📄 ximawnd.cpp
字号:
HBITMAP Oldbmp = CreateDIBSection(dc,(LPBITMAPINFO)pDib,DIB_RGB_COLORS, &pBit32, NULL, 0);
HGDIOBJ hobj = SelectObject(dc, Oldbmp);
::SelectObject(dc,hbmp); //select old bmp
if (pBit32) memcpy(info.pImage ,pBit32, head.biSizeImage);
::DeleteObject(Oldbmp);
::ReleaseDC(NULL, dc);
return true;
}
#endif
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::CreateFromHICON(HICON hico)
{
if (!Destroy())
return false;
if (hico)
{
ICONINFO iinfo;
#if 0
GetIconInfo(hico,&iinfo);
#else
memcpy(&iinfo,hico,sizeof(ICONINFO));
#endif
if (!CreateFromHBITMAP(iinfo.hbmColor))
return false;
#if CXIMAGE_SUPPORT_ALPHA
CxImage mask;
mask.CreateFromHBITMAP(iinfo.hbmMask);
mask.GrayScale();
mask.Negative();
AlphaSet(mask);
#endif
DeleteObject(iinfo.hbmColor); //<Sims>
DeleteObject(iinfo.hbmMask); //<Sims>
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Draws (stretch) the image with transparency & alpha support
// > hdc: destination device context
// > x,y: (optional) offset
// > cx,cy: (optional) size.
long CxImage::Draw(HDC hdc, long x, long y, long cx, long cy, RECT* pClipRect)
{
if((pDib==0)||(hdc==0)||(cx==0)||(cy==0)||(!info.bEnabled)) return 0;
if (cx < 0) cx = head.biWidth;
if (cy < 0) cy = head.biHeight;
bool bTransparent = info.nBkgndIndex != -1;
bool bAlpha = pAlpha != 0;
RECT mainbox; // (experimental)
if (pClipRect){
GetClipBox(hdc,&mainbox);
HRGN rgn = CreateRectRgnIndirect(pClipRect);
#if 0
ExtSelectClipRgn(hdc,rgn,RGN_AND);
#else
HRGN Desrgn = NULL,ClipRgn = NULL;
int ret = 0;
GetClipRgn(hdc,ClipRgn);
if(ClipRgn != NULL)
{
ret = CombineRgn(Desrgn,ClipRgn,rgn,RGN_COPY);
if (NULLREGION != ret && ERROR != ret )
SelectClipRgn(hdc,Desrgn);
}
else
{
SelectClipRgn(hdc,rgn);
}
DeleteObject(Desrgn);
#endif
DeleteObject(rgn);
}
if (!(bTransparent || bAlpha || info.bAlphaPaletteEnabled)){
if (cx==head.biWidth && cy==head.biHeight)
{ //NORMAL
#if 0
SetStretchBltMode(hdc,COLORONCOLOR);
SetDIBitsToDevice(hdc, x, y, cx, cy, 0, 0, 0, cy,info.pImage,(BITMAPINFO*)pDib,DIB_RGB_COLORS);
#else
LPVOID pBit32;
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC != NULL)
{
HBITMAP hbm = CreateDIBSection(hMemDC, (BITMAPINFO*)pDib, DIB_RGB_COLORS, &pBit32, NULL, 0);
if(hbm != NULL)
{
HGDIOBJ hobj = SelectObject(hMemDC, hbm);
StretchBlt(hdc, x, y, cx, cy,hMemDC, 0, 0, 0, cy,SRCCOPY);
SelectObject(hMemDC, hobj);
DeleteObject(hbm);
DeleteDC(hMemDC);
}
}
#endif
} else { //STRETCH
RECT clipbox,paintbox;
GetClipBox(hdc,&clipbox);
paintbox.left = min(clipbox.right,max(clipbox.left,x));
paintbox.right = max(clipbox.left,min(clipbox.right,x+cx));
paintbox.top = min(clipbox.bottom,max(clipbox.top,y));
paintbox.bottom = max(clipbox.top,min(clipbox.bottom,y+cy));
long destw = paintbox.right - paintbox.left;
long desth = paintbox.bottom - paintbox.top;
//pixel informations
RGBQUAD c={0,0,0,0};
//Preparing Bitmap Info
BITMAPINFO bmInfo;
memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biWidth=destw;
bmInfo.bmiHeader.biHeight=desth;
bmInfo.bmiHeader.biPlanes=1;
bmInfo.bmiHeader.biBitCount=24;
BYTE *pbase; //points to the final dib
BYTE *pdst; //current pixel from pbase
BYTE *ppix; //current pixel from image
//get the background
HDC TmpDC=CreateCompatibleDC(hdc);
HBITMAP TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
if (pbase){
long xx,yy,yoffset;
long ew = ((((24 * destw) + 31) / 32) * 4);
long ymax = paintbox.bottom;
long xmin = paintbox.left;
float fx=(float)head.biWidth/(float)cx;
float fy=(float)head.biHeight/(float)cy;
long sx,sy;
for(yy=0;yy<desth;yy++){
sy=max(0L,head.biHeight-(long)ceil(((ymax-yy-y)*fy)));
yoffset=sy*head.biWidth;
pdst=pbase+yy*ew;
for(xx=0;xx<destw;xx++){
sx=(long)floor(((xx+xmin-x)*fx));
if (head.biClrUsed){
c=GetPaletteColor(GetPixelIndex(sx,sy));
} else {
ppix=info.pImage+sy*info.dwEffWidth+sx*3;
c.rgbBlue = *ppix++;
c.rgbGreen= *ppix++;
c.rgbRed = *ppix;
}
*pdst++=c.rgbBlue;
*pdst++=c.rgbGreen;
*pdst++=c.rgbRed;
}
}
}
//paint the image & cleanup
#if 0
SetDIBitsToDevice(hdc,paintbox.left,paintbox.top,destw,desth,0,0,0,desth,pbase,&bmInfo,0);
#else
LPVOID temp_pBit32;
HDC temp_hMemDC = CreateCompatibleDC(NULL);
if (temp_hMemDC != NULL)
{
HBITMAP temp_hbm = CreateDIBSection(temp_hMemDC, (BITMAPINFO*)pDib, DIB_RGB_COLORS, &temp_pBit32, NULL, 0);
if(temp_hbm != NULL)
{
HGDIOBJ temp_hobj = SelectObject(temp_hMemDC, temp_hbm);
StretchBlt(hdc, x, y, cx, cy,temp_hMemDC, 0, 0, 0, cy,SRCCOPY);
SelectObject(temp_hMemDC, temp_hobj);
DeleteObject(temp_hbm);
DeleteDC(temp_hMemDC);
}
}
#endif
DeleteObject(SelectObject(TmpDC,TmpObj));
DeleteDC(TmpDC);
}
} else { // draw image with transparent/alpha blending
//////////////////////////////////////////////////////////////////
//Alpha blend - Thanks to Florian Egel
//find the smallest area to paint
RECT clipbox,paintbox;
GetClipBox(hdc,&clipbox);
paintbox.left = min(clipbox.right,max(clipbox.left,x));
paintbox.right = max(clipbox.left,min(clipbox.right,x+cx));
paintbox.top = min(clipbox.bottom,max(clipbox.top,y));
paintbox.bottom = max(clipbox.top,min(clipbox.bottom,y+cy));
long destw = paintbox.right - paintbox.left;
long desth = paintbox.bottom - paintbox.top;
//pixel informations
RGBQUAD c={0,0,0,0};
RGBQUAD ct = GetTransColor();
long* pc = (long*)&c;
long* pct= (long*)&ct;
long cit = GetTransIndex();
long ci;
//Preparing Bitmap Info
BITMAPINFO bmInfo;
memset(&bmInfo.bmiHeader,0,sizeof(BITMAPINFOHEADER));
bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
bmInfo.bmiHeader.biWidth=destw;
bmInfo.bmiHeader.biHeight=desth;
bmInfo.bmiHeader.biPlanes=1;
bmInfo.bmiHeader.biBitCount=24;
BYTE *pbase; //points to the final dib
BYTE *pdst; //current pixel from pbase
BYTE *ppix; //current pixel from image
//get the background
HDC TmpDC=CreateCompatibleDC(hdc);
HBITMAP TmpBmp=CreateDIBSection(hdc,&bmInfo,DIB_RGB_COLORS,(void**)&pbase,0,0);
HGDIOBJ TmpObj=SelectObject(TmpDC,TmpBmp);
BitBlt(TmpDC,0,0,destw,desth,hdc,paintbox.left,paintbox.top,SRCCOPY);
if (pbase)
{
long xx,yy,yoffset,ix,iy;
BYTE a,a1;
long ew = ((((24 * destw) + 31) / 32) * 4);
long ymax = paintbox.bottom;
long xmin = paintbox.left;
if (cx!=head.biWidth || cy!=head.biHeight)
{
//STRETCH
float fx=(float)head.biWidth/(float)cx;
float fy=(float)head.biHeight/(float)cy;
long sx,sy;
for(yy=0;yy<desth;yy++)
{
sy=max(0L,head.biHeight-(long)ceil(((ymax-yy-y)*fy)));
yoffset=sy*head.biWidth;
pdst=pbase+yy*ew;
for(xx=0;xx<destw;xx++)
{
sx=(long)floor(((xx+xmin-x)*fx));
if (bAlpha) a=pAlpha[yoffset+sx]; else a=255;
a =(BYTE)((a*(1+info.nAlphaMax))>>8);
if (head.biClrUsed){
ci = GetPixelIndex(sx,sy);
c = GetPaletteColor(GetPixelIndex(sx,sy));
if (info.bAlphaPaletteEnabled)
{
a = (BYTE)((a*(1+c.rgbReserved))>>8);
}
}
else
{
ppix=info.pImage+sy*info.dwEffWidth+sx*3;
c.rgbBlue = *ppix++;
c.rgbGreen= *ppix++;
c.rgbRed = *ppix;
}
//if (*pc!=*pct || !bTransparent){
if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent)
{
// DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
if (a == 0) // Transparent, retain dest
{
pdst+=3;
}
else if (a == 255) // opaque, ignore dest
{
*pdst++= c.rgbBlue;
*pdst++= c.rgbGreen;
*pdst++= c.rgbRed;
}
else
{ // semi transparent
a1=(BYTE)~a;
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbBlue)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbGreen)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbRed)>>8);
}
}
else
{
pdst+=3;
}
}
}
}
else
{
//NORMAL
iy=head.biHeight-ymax+y;
for(yy=0;yy<desth;yy++,iy++)
{
yoffset=iy*head.biWidth;
ix=xmin-x;
pdst=pbase+yy*ew;
ppix=info.pImage+iy*info.dwEffWidth+ix*3;
for(xx=0;xx<destw;xx++,ix++)
{
if (bAlpha) a=pAlpha[yoffset+ix]; else a=255;
a = (BYTE)((a*(1+info.nAlphaMax))>>8);
if (head.biClrUsed)
{
ci = GetPixelIndex(ix,iy);
c = GetPaletteColor(GetPixelIndex(ix,iy));
if (info.bAlphaPaletteEnabled)
{
a = (BYTE)((a*(1+c.rgbReserved))>>8);
}
}
else
{
c.rgbBlue = *ppix++;
c.rgbGreen= *ppix++;
c.rgbRed = *ppix++;
}
//if (*pc!=*pct || !bTransparent){
if ((head.biClrUsed && ci!=cit) || (!head.biClrUsed && *pc!=*pct) || !bTransparent)
{
// DJT, assume many pixels are fully transparent or opaque and thus avoid multiplication
if (a == 0) // Transparent, retain dest
{
pdst+=3;
}
else if (a == 255) // opaque, ignore dest
{
*pdst++= c.rgbBlue;
*pdst++= c.rgbGreen;
*pdst++= c.rgbRed;
}
else // semi transparent
{
a1=(BYTE)~a;
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbBlue)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbGreen)>>8);
*pdst++=(BYTE)((*pdst * a1 + a * c.rgbRed)>>8);
}
}
else
{
pdst+=3;
}
}
}
}
}
//paint the image & cleanup
#if 0
SetDIBitsToDevice(hdc,paintbox.left,paintbox.top,destw,desth,0,0,0,desth,pbase,&bmInfo,0);
#else
LPVOID tmp_pBit32;
HDC tmp_hMemDC = CreateCompatibleDC(NULL);
if (tmp_hMemDC != NULL)
{
HBITMAP tmp_hbm = CreateDIBSection(tmp_hMemDC, (BITMAPINFO*)pDib, DIB_RGB_COLORS, &tmp_pBit32, NULL, 0);
if(tmp_hbm != NULL)
{
HGDIOBJ tmp_hobj = SelectObject(tmp_hMemDC, tmp_hbm);
StretchBlt(hdc, x, y, cx, cy,tmp_hMemDC, 0, 0, 0, cy,SRCCOPY);
SelectObject(tmp_hMemDC, tmp_hobj);
DeleteObject(tmp_hbm);
DeleteDC(tmp_hMemDC);
}
}
#endif
DeleteObject(SelectObject(TmpDC,TmpObj));
DeleteDC(TmpDC);
}
if (pClipRect)
{ // (experimental)
HRGN rgn = CreateRectRgnIndirect(&mainbox);
#if 0
ExtSelectClipRgn(hdc,rgn,RGN_OR);
#else
HRGN Desrgn = NULL,ClipRgn = NULL;
int ret = 0;
GetClipRgn(hdc,ClipRgn);
if(ClipRgn != NULL)
{
ret = CombineRgn(Desrgn,ClipRgn,rgn,RGN_OR);
if (NULLREGION != ret && ERROR != ret )
SelectClipRgn(hdc,Desrgn);
}
else
{
SelectClipRgn(hdc,rgn);
}
DeleteObject(Desrgn);
#endif
DeleteObject(rgn);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -