📄 ximawnd.cpp
字号:
// xImaWnd.cpp : Windows functions
/* 07/08/2001 v1.00 - Davide Pizzolato - www.xdp.it
* CxImage version 5.99c 17/Oct/2004
*/
#include "ximage.h"
#include "ximaiter.h"
#include "ximabmp.h"
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_WINCE
////////////////////////////////////////////////////////////////////////////////
long CxImage::Blt(HDC pDC, long x, long y)
{
if((pDib==0)||(pDC==0)||(!info.bEnabled)) return 0;
HBRUSH brImage = CreateDIBPatternBrushPt(pDib, DIB_RGB_COLORS);
HBRUSH brOld = (HBRUSH) SelectObject(pDC, brImage);
PatBlt(pDC, 0, 0, head.biWidth, head.biHeight, PATCOPY);
SelectObject(pDC, brOld);
DeleteObject(brImage);
return 1;
}
#endif //CXIMAGE_SUPPORT_WINCE
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_WINDOWS
////////////////////////////////////////////////////////////////////////////////
/**
* Transfer the image in a global bitmap handle (clipboard copy)
*/
HANDLE CxImage::CopyToHandle()
{
HANDLE hMem=NULL;
if (pDib){
hMem= GlobalAlloc(GHND, GetSize());
if (hMem){
BYTE* pDst=(BYTE*)GlobalLock(hMem);
if (pDst){
memcpy(pDst,pDib,GetSize());
}
GlobalUnlock(hMem);
}
}
return hMem;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Global object (clipboard paste) constructor
* \param hMem: source bitmap object, the clipboard format must be CF_DIB
* \return true if everything is ok
*/
bool CxImage::CreateFromHANDLE(HANDLE hMem)
{
if (!Destroy())
return false;
DWORD dwSize = GlobalSize(hMem);
if (!dwSize) return false;
BYTE *lpVoid; //pointer to the bitmap
lpVoid = (BYTE *)GlobalLock(hMem);
BITMAPINFOHEADER *pHead; //pointer to the bitmap header
pHead = (BITMAPINFOHEADER *)lpVoid;
if (lpVoid){
//CxMemFile hFile(lpVoid,dwSize);
//copy the bitmap header
memcpy(&head,pHead,sizeof(BITMAPINFOHEADER));
//create the image
if(!Create(head.biWidth,head.biHeight,head.biBitCount)){
GlobalUnlock(lpVoid);
return false;
}
//preserve DPI
if (head.biXPelsPerMeter) SetXDPI((long)floor(head.biXPelsPerMeter * 254.0 / 10000.0 + 0.5)); else SetXDPI(96);
if (head.biYPelsPerMeter) SetYDPI((long)floor(head.biYPelsPerMeter * 254.0 / 10000.0 + 0.5)); else SetYDPI(96);
/*//copy the pixels (old way)
if((pHead->biCompression != BI_RGB) || (pHead->biBitCount == 32)){ //<J鰎gen Alfredsson>
// BITFIELD case
// set the internal header in the dib
memcpy(pDib,&head,sizeof(head));
// get the bitfield masks
DWORD bf[3];
memcpy(bf,lpVoid+pHead->biSize,12);
// transform into RGB
Bitfield2RGB(lpVoid+pHead->biSize+12,(WORD)bf[0],(WORD)bf[1],(WORD)bf[2],(BYTE)pHead->biBitCount);
} else { //normal bitmap
memcpy(pDib,lpVoid,GetSize());
}*/
// <Michael Gandyra>
// fill in color map
bool bIsOldBmp = (head.biSize == sizeof(BITMAPCOREHEADER));
RGBQUAD *pRgb = GetPalette();
if (pRgb) {
// number of colors to fill in
int nColors = DibNumColors(pHead);
if (bIsOldBmp) {
/* get pointer to BITMAPCOREINFO (old style 1.x) */
LPBITMAPCOREINFO lpbmc = (LPBITMAPCOREINFO)lpVoid;
for (int i = nColors - 1; i >= 0; i--) {
pRgb[i].rgbRed = lpbmc->bmciColors[i].rgbtRed;
pRgb[i].rgbGreen = lpbmc->bmciColors[i].rgbtGreen;
pRgb[i].rgbBlue = lpbmc->bmciColors[i].rgbtBlue;
pRgb[i].rgbReserved = (BYTE)0;
}
} else {
/* get pointer to BITMAPINFO (new style 3.x) */
LPBITMAPINFO lpbmi = (LPBITMAPINFO)lpVoid;
for (int i = nColors - 1; i >= 0; i--) {
pRgb[i].rgbRed = lpbmi->bmiColors[i].rgbRed;
pRgb[i].rgbGreen = lpbmi->bmiColors[i].rgbGreen;
pRgb[i].rgbBlue = lpbmi->bmiColors[i].rgbBlue;
pRgb[i].rgbReserved = (BYTE)0;
}
}
}
// <Michael Gandyra>
DWORD dwCompression = pHead->biCompression;
// compressed bitmap ?
if(dwCompression!=BI_RGB || pHead->biBitCount==32) {
// get the bitmap bits
LPSTR lpDIBBits = (LPSTR)((BYTE*)pHead + *(DWORD*)pHead + (WORD)(GetNumColors() * sizeof(RGBQUAD)));
// decode and copy them to our image
switch (pHead->biBitCount) {
case 32 :
{
// BITFIELD case
if (dwCompression == BI_BITFIELDS || dwCompression == BI_RGB) {
// get the bitfield masks
DWORD bf[3];
memcpy(bf,lpVoid+pHead->biSize,12);
// transform into RGB
Bitfield2RGB(lpVoid+pHead->biSize+12,(WORD)bf[0],(WORD)bf[1],(WORD)bf[2],(BYTE)pHead->biBitCount);
} else
throw "unknown compression";
}
break;
case 16 :
{
// get the bitfield masks
long offset=0;
DWORD bf[3];
if (dwCompression == BI_BITFIELDS) {
memcpy(bf,lpVoid+pHead->biSize,12);
offset= 12;
} else {
bf[0] = 0x7C00;
bf[1] = 0x3E0;
bf[2] = 0x1F; // RGB555
}
// copy the pixels
memcpy(info.pImage, lpDIBBits + offset, head.biHeight*((head.biWidth+1)/2)*4);
// transform into RGB
Bitfield2RGB(info.pImage, (WORD)bf[0], (WORD)bf[1], (WORD)bf[2], 16);
}
break;
case 8 :
case 4 :
case 1 :
{
switch (dwCompression) {
case BI_RLE4:
{
BYTE status_byte = 0;
BYTE second_byte = 0;
int scanline = 0;
int bits = 0;
BOOL low_nibble = FALSE;
CImageIterator iter(this);
for (BOOL bContinue = TRUE; bContinue; ) {
status_byte = *(lpDIBBits++);
switch (status_byte) {
case RLE_COMMAND :
status_byte = *(lpDIBBits++);
switch (status_byte) {
case RLE_ENDOFLINE :
bits = 0;
scanline++;
low_nibble = FALSE;
break;
case RLE_ENDOFBITMAP :
bContinue = FALSE;
break;
case RLE_DELTA :
{
// read the delta values
BYTE delta_x;
BYTE delta_y;
delta_x = *(lpDIBBits++);
delta_y = *(lpDIBBits++);
// apply them
bits += delta_x / 2;
scanline += delta_y;
break;
}
default :
second_byte = *(lpDIBBits++);
BYTE* sline = iter.GetRow(scanline);
for (int i = 0; i < status_byte; i++) {
if (low_nibble) {
if ((DWORD)(sline + bits) < (DWORD)(info.pImage + head.biSizeImage)) {
*(sline + bits) |= second_byte & 0x0F;
}
if (i != status_byte - 1)
second_byte = *(lpDIBBits++);
bits++;
} else {
if ((DWORD)(sline + bits) <(DWORD)(info.pImage + head.biSizeImage)) {
*(sline + bits) = (BYTE)(second_byte & 0xF0);
}
}
low_nibble = !low_nibble;
}
if ((((status_byte+1) >> 1) & 1 )== 1)
second_byte = *(lpDIBBits++);
break;
};
break;
default :
{
BYTE* sline = iter.GetRow(scanline);
second_byte = *(lpDIBBits++);
for (unsigned i = 0; i < status_byte; i++) {
if (low_nibble) {
if ((DWORD)(sline + bits) <(DWORD)(info.pImage + head.biSizeImage)) {
*(sline + bits) |= second_byte & 0x0F;
}
bits++;
} else {
if ((DWORD)(sline + bits) <(DWORD)(info.pImage + head.biSizeImage)) {
*(sline + bits) = (BYTE)(second_byte & 0xF0);
}
}
low_nibble = !low_nibble;
}
}
break;
};
}
}
break;
case BI_RLE8 :
{
BYTE status_byte = 0;
BYTE second_byte = 0;
int scanline = 0;
int bits = 0;
CImageIterator iter(this);
for (BOOL bContinue = TRUE; bContinue; ) {
status_byte = *(lpDIBBits++);
if (status_byte==RLE_COMMAND) {
status_byte = *(lpDIBBits++);
switch (status_byte) {
case RLE_ENDOFLINE :
bits = 0;
scanline++;
break;
case RLE_ENDOFBITMAP :
bContinue = FALSE;
break;
case RLE_DELTA :
{
// read the delta values
BYTE delta_x;
BYTE delta_y;
delta_x = *(lpDIBBits++);
delta_y = *(lpDIBBits++);
// apply them
bits += delta_x;
scanline += delta_y;
}
break;
default :
int nNumBytes = sizeof(BYTE) * status_byte;
memcpy((void *)(iter.GetRow(scanline) + bits), lpDIBBits, nNumBytes);
lpDIBBits += nNumBytes;
// align run length to even number of bytes
if ((status_byte & 1) == 1)
second_byte = *(lpDIBBits++);
bits += status_byte;
break;
};
} else {
BYTE *sline = iter.GetRow(scanline);
second_byte = *(lpDIBBits++);
for (unsigned i = 0; i < status_byte; i++) {
if ((DWORD)bits<info.dwEffWidth){
*(sline + bits) = second_byte;
bits++;
} else {
bContinue = FALSE;
break;
}
}
}
}
}
break;
default :
throw "compression type not supported";
}
}
}
} else {
//normal bitmap (not compressed)
memcpy(pDib,lpVoid,GetSize());
}
GlobalUnlock(lpVoid);
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Transfer the image in a bitmap handle
* \param hdc: target device context (the screen, usually)
* \return bitmap handle, or NULL if an error occurs.
*/
HBITMAP CxImage::MakeBitmap(HDC hdc)
{
if (!pDib)
return NULL;
if (!hdc){
// this call to CreateBitmap doesn't create a DIB <jaslet>
// // Create a device-independent bitmap <CSC>
// return CreateBitmap(head.biWidth,head.biHeight, 1, head.biBitCount, GetBits());
// use instead this code
HDC hMemDC = CreateCompatibleDC(NULL);
LPVOID pBit32;
HBITMAP bmp = CreateDIBSection(hMemDC,(LPBITMAPINFO)pDib,DIB_RGB_COLORS, &pBit32, NULL, 0);
if (pBit32) memcpy(pBit32, GetBits(), head.biSizeImage);
DeleteDC(hMemDC);
return bmp;
}
// this single line seems to work very well
HBITMAP bmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)pDib, CBM_INIT,
GetBits(), (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
return bmp;
}
////////////////////////////////////////////////////////////////////////////////
/**
* Bitmap resource constructor
* \param hbmp : bitmap resource handle
* \param hpal : (optional) palette, useful for 8bpp DC
* \return true if everything is ok
*/
bool CxImage::CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal)
{
if (!Destroy())
return false;
if (hbmp) {
BITMAP bm;
// get informations about the bitmap
GetObject(hbmp, sizeof(BITMAP), (LPSTR) &bm);
// create the image
if (!Create(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel, 0))
return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -