加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

wince窗口 屏幕拷贝为位图

发布时间:2020-12-14 04:11:57 所属栏目:大数据 来源:网络整理
导读:wince窗口 屏幕拷贝为位图??????? ??????? 分类:??????????? WINCE应用层开发经验(附代码) 2011-03-17 11:24 559人阅读 评论(0) 收藏 举报 wince null colors bi file delete #define PW_WINDOW????????? 9001 #define PW_CLIENT???????????? 9002 HBITMA
wince窗口 屏幕拷贝为位图???????
??????? 分类:??????????? WINCE应用层开发经验(附代码) 559人阅读 评论(0) 收藏 举报
wince null colors bi file delete

#define PW_WINDOW????????? 9001
#define PW_CLIENT???????????? 9002

HBITMAP CMyProgramDlg::CopyScreenToBitmap(LPRECT lpRect)
{
HDC???????? hScrDC,hMemDC;???????? // screen DC and memory DC????
int???????? nX,nY,nX2,nY2;?????? // coordinates of rectangle to grab????
int???????? nWidth,nHeight;??????? // DIB width and height????
int???????? xScrn,yScrn;?????????? // screen resolution?????

HGDIOBJ???? hOldBitmap,hBitmap;
?
? // check for an empty rectangle
??? if (IsRectEmpty(lpRect))??????
??? return NULL;?????
??? // create a DC for the screen and create????
??? // a memory DC compatible to screen DC?????????

?? hScrDC = CreateDC("DISPLAY",NULL,NULL);????
?? hMemDC = CreateCompatibleDC(hScrDC);????? // get points of rectangle to grab?
??
?? nX = lpRect->left;????
?? nY = lpRect->top;????
?? nX2 = lpRect->right;????
?? nY2 = lpRect->bottom;????? // get screen resolution?????
??
?? xScrn = GetDeviceCaps(hScrDC,HORZRES);????
?? yScrn = GetDeviceCaps(hScrDC,VERTRES);?????
??
?? //make sure bitmap rectangle is visible?????
??
?? if (nX < 0)????????
?? nX = 0;????
??
?? if (nY < 0)????????
????? nY = 0;????
??
?? if (nX2 > xScrn)????????
????? nX2 = xScrn;????
??
?? if (nY2 > yScrn)????????
????? nY2 = yScrn;?????

?? nWidth = nX2 - nX;????
?? nHeight = nY2 - nY;?????
??
?? // create a bitmap compatible with the screen DC????
??
?? hBitmap = CreateCompatibleBitmap(hScrDC,nWidth,nHeight);?????
??
?? // select new bitmap into memory DC????
??
?? hOldBitmap =?? SelectObject (hMemDC,hBitmap);?????
??
?? // bitblt screen DC to memory DC????
??
?? BitBlt(hMemDC,nHeight,hScrDC,nX,SRCCOPY);????
??
?? // select old bitmap back into memory DC and get handle to????
?? // bitmap of the screen?????????
??
?? hBitmap = SelectObject(hMemDC,hOldBitmap);?????

?? // clean up?????
??
?? DeleteDC(hScrDC);????
?? DeleteDC(hMemDC);?????
?
?? // return handle to the bitmap?????
??
?? return (HBITMAP)hBitmap;
}

HBITMAP CYourProgramDlg::CopyWindowToBitmap(CWnd* wnd,HWND hWnd,WORD fPrintArea)
{
HBITMAP???? hBitmap = NULL;? // handle to device-dependent bitmap?????
// check for a valid window handle?????
if (!hWnd)????????
???? return NULL;

??? RECT??? rectWnd;
??? ::GetWindowRect(hWnd,&rectWnd);?

switch (fPrintArea)????
{????????
? case PW_WINDOW: // copy entire window????????
? {????????????
????????? // get the window rectangle?????????????
????????? // get the bitmap of that window by calling????????????
??? // CopyScreenToBitmap and passing it the window rect????????????????????
//??? GetWindowRect(&rectWnd);
??? hBitmap = CopyScreenToBitmap(&rectWnd);????????????
??? break;????????
? }??
?????? case PW_CLIENT: // copy client area????????
??? {????????????
????? RECT rectClient;????????????
????? POINT pt1,pt2;????????????? // get client dimensions?????????????
????? wnd->GetClientRect(&rectClient);????????????? // convert client coords to screen coords????????????
????? pt1.x = rectClient.left;????????????
????? pt1.y = rectClient.top;????????????
????? pt2.x = rectClient.right;????????????
????? pt2.y = rectClient.bottom;????????????
????? wnd->ClientToScreen(&pt1);????????????
????? wnd->ClientToScreen(&pt2);????????????
????? rectClient.left = pt1.x;????????????
????? rectClient.top = pt1.y;????????????
????? rectClient.right = pt2.x;????????????
????? rectClient.bottom = pt2.y;?

???????? // get the bitmap of the client area by calling????????????
????? // CopyScreenToBitmap and passing it the client rect????????????????????????
????? hBitmap = CopyScreenToBitmap(&rectClient);????????????
????? break;????????
??? }?????????????
??? default:??? // invalid print area????????????
???????? return NULL;????
}????? // return handle to the bitmap????

return hBitmap;
}A good usage is :

Code:
HBITMAP hBitmap = CopyWindowToBitmap(this,GetDesktopWindow()->m_hWnd,PW_

1:拷贝屏幕DC成为位图句柄

HBITMAP CopyDCToBitmap(HDC hScrDC,LPRECT lpRect)
{

if(hScrDC==NULL || lpRect==NULL || IsRectEmpty(lpRect))

? {

?? AfxMessageBox("参数错误");

return NULL;

}

HDC??????? hMemDC;????
// 屏幕和内存设备描述表
HBITMAP??? hBitmap,hOldBitmap;?
// 位图句柄
int?????? nX,nY2;????
// 选定区域坐标
int?????? nWidth,nHeight;????
// 位图宽度和高度

// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
? return NULL;

// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;

nWidth = nX2 - nX;
nHeight = nY2 - nY;
//为指定设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 创建一个与指定设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap(hScrDC,nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
StretchBlt(hMemDC,SRCCOPY);
//BitBlt(hMemDC,SRCCOPY);
//得到屏幕位图的句柄

hBitmap = (HBITMAP)SelectObject(hMemDC,hOldBitmap);
//清除

DeleteDC(hMemDC);
DeleteObject(hOldBitmap);
// 返回位图句柄
return hBitmap;
}

//把HBITMAP保存成位图
BOOL SaveBmp(HBITMAP hBitmap,CString FileName)
{

if(hBitmap==NULL || FileName.IsEmpty())

? {

?? AfxMessageBox("参数错误");

return false;

}

2:拷贝屏幕DC包成为BMP格式的文件 ;
//当前分辨率下每象素所占字节数
int iBits;
//位图中每象素所占字节数
WORD wBitCount;
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0,dwBmBitsSize=0,dwDIBSize=0,dwWritten=0;
//位图属性结构
BITMAP Bitmap;
//位图文件头结构
BITMAPFILEHEADER bmfHdr;
//位图信息头结构
BITMAPINFOHEADER bi;
//指向位图信息头结构
LPBITMAPINFOHEADER lpbi;
//定义文件,分配内存句柄,调色板句柄
HANDLE fh,hDib,hPal,hOldPal=NULL;

//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL);
iBits = GetDeviceCaps(hDC,BITSPIXEL) * GetDeviceCaps(hDC,PLANES);
DeleteDC(hDC);
if (iBits <= 1)? wBitCount = 1;
else if (iBits <= 4)? wBitCount = 4;
else if (iBits <= 8)? wBitCount = 8;
else????? wBitCount = 24;

GetObject(hBitmap,sizeof(Bitmap),(LPSTR)&Bitmap);
bi.biSize?? = sizeof(BITMAPINFOHEADER);
bi.biWidth?? = Bitmap.bmWidth;
bi.biHeight?? = Bitmap.bmHeight;
bi.biPlanes?? = 1;
bi.biBitCount? = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage? = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed? = 0;

dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;

// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
? hDC = ::GetDC(NULL);
? hOldPal = ::SelectPalette(hDC,(HPALETTE)hPal,FALSE);
? RealizePalette(hDC);
}

// 获取该调色板下新的像素值
GetDIBits(hDC,hBitmap,(UINT) Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
?? +dwPaletteSize,(BITMAPINFO *)lpbi,DIB_RGB_COLORS);

//恢复调色板
if (hOldPal)
{
? ::SelectPalette(hDC,(HPALETTE)hOldPal,TRUE);
? RealizePalette(hDC);
? ::ReleaseDC(NULL,hDC);
}

//创建位图文件
fh = CreateFile(FileName,GENERIC_WRITE,CREATE_ALWAYS,
???? FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);

if (fh == INVALID_HANDLE_VALUE)? return FALSE;

// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
// 写入位图文件头
WriteFile(fh,(LPSTR)&bmfHdr,sizeof(BITMAPFILEHEADER),&dwWritten,NULL);
// 写入位图文件其余内容
WriteFile(fh,(LPSTR)lpbi,dwDIBSize,NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);

return TRUE;
}

int Engine_2D::SaveBitmapToFile(HBITMAP?? hBitmap,?? LPCWSTR?? lpFileName)?? //hBitmap?? 为刚才的屏幕位图句柄?
{?????????
//lpFileName?? 为位图文件名?
HDC?????????? hDC;???????????????????
//设备描述表?
int?????????? iBits;?????????????
??? //当前显示分辨率下每个像素所占字节数?
WORD???????? wBitCount;???????
//位图中每个像素所占字节数?
//定义调色板大小,?? 位图中像素字节大小?? ,???? 位图文件大小?? ,?? 写入文件字节数?
DWORD?????????????????????? dwPaletteSize=0,dwBmBitsSize,?? dwWritten;?
BITMAP???????????????????? Bitmap;?????????????????
//位图属性结构?
BITMAPFILEHEADER?????? bmfHdr;?????????????????
//位图文件头结构?
BITMAPINFOHEADER?????? bi;?????????????????????????
//位图信息头结构???
LPBITMAPINFOHEADER?? lpbi;?????????????????????
//指向位图信息头结构?
HANDLE???????????????????? fh,?? hDib,?? hPal;

HPALETTE?????????? hOldPal=NULL;?
//定义文件,分配内存句柄,调色板句柄?
//计算位图文件每个像素所占字节数?
hDC?? =?? CreateDC(L"DISPLAY",NULL);?
iBits?? =?? GetDeviceCaps(hDC,?? BITSPIXEL)?? *???? GetDeviceCaps(hDC,?? PLANES);?
DeleteDC(hDC);?
??? if?? (iBits?? <=?? 1)?
????????? wBitCount?? =?? 1;?
??? else?? if?? (iBits?? <=?? 4)?
????????? wBitCount?? =?? 4;?
??? else?? if?? (iBits?? <=?? 8)?
????????? wBitCount?? =?? 8;?
else?? if?? (iBits?? <=?? 16)
? wBitCount?? =?? 16;
??? else?? if?? (iBits?? <=?? 24)?
????????? wBitCount?? =?? 24;
else
??? wBitCount = 32;
??? //计算调色板大小?
??? if(wBitCount?? <=?? 8)?
????????? dwPaletteSize=(1<<wBitCount)*sizeof(RGBQUAD);?
//设置位图信息头结构?
??? GetObject(hBitmap,?? sizeof(BITMAP),?? (LPSTR)&Bitmap);?
??? bi.biSize???????????????????????? =?? sizeof(BITMAPINFOHEADER);?
??? bi.biWidth?????????????????????? =?? Bitmap.bmWidth;?
??? bi.biHeight???????????????????? =?? Bitmap.bmHeight;?
??? bi.biPlanes???????????????????? =?? 1;?
??? bi.biBitCount?????????????????? =?? wBitCount;?
??? bi.biCompression???????????? =?? BI_RGB;?
??? bi.biSizeImage???????????????? =?? 0;?
??? bi.biXPelsPerMeter?????????? =?? 0;?
??? bi.biYPelsPerMeter?????????? =?? 0;?
??? bi.biClrUsed?????????????????? =?? 0;?
??? bi.biClrImportant???????????? =?? 0;?
??
??? dwBmBitsSize?? =?? ((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight;?
??? //为位图内容分配内存?
??? hDib???? =?? GlobalAlloc(GHND,dwBmBitsSize+dwPaletteSize+sizeof(BITMAPINFOHEADER));?
??? lpbi?? =?? (LPBITMAPINFOHEADER)GlobalLock(hDib);?
??? *lpbi?? =?? bi;?
??? //?? 处理调色板???
??? hPal?? =?? GetStockObject(DEFAULT_PALETTE);?
??? if?? (hPal)?
??? {?
????????? hDC?? =?? GetDC(NULL);?
????????? hOldPal=SelectPalette(hDC,FALSE);?
????????? RealizePalette(hDC);?
??? }?
??? //?? 获取该调色板下新的像素值?
??? GetDIBits(hDC,(UINT)Bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize,?? (BITMAPINFO?? *)lpbi,DIB_RGB_COLORS);?
??? //恢复调色板???????
??? if?? (hOldPal)?
??? {?
????????? SelectPalette(hDC,?? hOldPal,?? TRUE);?
????????? RealizePalette(hDC);?
????????? ReleaseDC(NULL,?? hDC);?
??? }?
//创建位图文件?????????
fh=CreateFile(lpFileName,?? GENERIC_WRITE,?? NULL,?? CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL?? |?? FILE_FLAG_SEQUENTIAL_SCAN,?? NULL);?
??? if?? (fh==INVALID_HANDLE_VALUE)?
????????? return?? FALSE;?
??? //?? 设置位图文件头?
??? bmfHdr.bfType?? =?? 0x4D42;???? //?? "BM"?
dwDIBSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize+dwBmBitsSize;?????
bmfHdr.bfSize?? =?? dwDIBSize;?
bmfHdr.bfReserved1?? =?? 0;?
bmfHdr.bfReserved2?? =?? 0;?
bmfHdr.bfOffBits?? =?? (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;?
//?? 写入位图文件头?
WriteFile(fh,?? (LPSTR)&bmfHdr,?? sizeof(BITMAPFILEHEADER),?? &dwWritten,?? NULL);?
//?? 写入位图文件其余内容?
WriteFile(fh,?? (LPSTR)lpbi,?? dwDIBSize,???? &dwWritten,?? NULL);?
??? //清除???????
??? GlobalUnlock(hDib);?
??? GlobalFree(hDib);?
??? CloseHandle(fh);?
??? return?? TRUE;?
}

3创建WINCE下16位格式位图实现快速BitBlt

在WINCE下,如果创建的位图与屏幕设备格式不一样,将会导致BitBlt函数极为缓慢,因此需要创建一幅16位色565格式位图,用此方法创建出的位图可以提供1ms的快速BitBlt绘制。当然,如果设备不是565颜色格式的,更改代码中的颜色掩码位bmiColors就可以了。

  1. /////////////////////////////////////////////////////////////////////////?
  2. /// @brief????? 创建一幅缓存图像。?
  3. /// @param[out]? pHBitmap 生成的位图句柄。?
  4. /// @param[out]? pData? 生成的位图中的数据位置。?
  5. /// @param[in]? hDC 目标DC句柄。?
  6. /// @param[in]? width 位图宽度。?
  7. /// @param[in]? height 位图高度。?
  8. /// @param[in]? bitCount 每个像素占多少个bit。?
  9. /// @attention? 创建的位图是无压缩格式的。?
  10. /// @author??? Loongee?
  11. /// @date????? 2010/01/15?
  12. //////////////////////////////////////////////////////////////////////////?
  13. void CreateBufferBitmap(HBITMAP* pHBitmap,void** pData,??
  14. ??????????????????????????? HDC hDC,LONG width,LONG height,WORD bitCount)?
  15. {?
  16. ??? BITMAPINFO& bmpInfo = *(BITMAPINFO*)new BYTE[sizeof(bmpInfo) + sizeof(RGBQUAD) * 3];?
  17. ??? bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);?
  18. ??? bmpInfo.bmiHeader.biWidth = width;?
  19. ??? bmpInfo.bmiHeader.biHeight = height;?
  20. ??? bmpInfo.bmiHeader.biPlanes = 1;?
  21. ??? bmpInfo.bmiHeader.biBitCount = bitCount;?
  22. ??? if (bitCount == 16)?
  23. ??? {?
  24. ??????? bmpInfo.bmiHeader.biCompression = BI_BITFIELDS;?
  25. ??????? *(DWORD *)(&bmpInfo.bmiColors[0]) = 0xF800;?
  26. ??????? *(DWORD *)(&bmpInfo.bmiColors[1]) = 0x07E0;?
  27. ??????? *(DWORD *)(&bmpInfo.bmiColors[2]) = 0x001F;?
  28. ??? }?
  29. ??? else?
  30. ??? {?
  31. ??????? bmpInfo.bmiHeader.biCompression = BI_RGB;?
  32. ??? bmpInfo.bmiHeader.biSizeImage = 0;?
  33. ??? bmpInfo.bmiHeader.biXPelsPerMeter = 1000;?
  34. ??? bmpInfo.bmiHeader.biYPelsPerMeter = 1000;?
  35. ??? bmpInfo.bmiHeader.biClrUsed = 0;?
  36. ??? bmpInfo.bmiHeader.biClrImportant = 0;?
  37. ??? *pHBitmap = CreateDIBSection(hDC,&bmpInfo,DIB_RGB_COLORS?
  38. ???????,pData,0);?
  39. ??? delete[] (BYTE*)&bmpInfo;?
  40. }?

待续。。。。。。。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读