求救:如何抓屏,生成bmp文件? 键盘上的_Print Screen键就可以呀,按一下Print Screen键后,在开始->程序->附件->画图,中粘贴就可以了,,,,,。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 hquwl(东北大汉) ,那还用问? 我知道怎么在BCB下实现,得到桌面窗体的设备描述表句柄,再通过TBitmap存就可以了。我手边没有代码,去BCB版里问问,有人会给你代码的。 HWND hDesktop = ::GetDesktopWindow(); HDC hDC = ::GetDC(hDesktop); HDC hMemDC = ::CreateCompatibleDC(hDC); ::GetWindowRect(hDesktop,&rect); int cx,cy; cx = rect.right - rect.left; cy = rect.bottom - rect.top; HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC,cx,cy); HGDIOBJ hOldObject = ::SelectObject(hMemDC,m_hBitmap); ::BitBlt(hMemDC,0,0,cx,cy,hDC,rect.left,rect.top,SRCCOPY); ::SelectObject(hMemDC,hOldObject); ::DeleteObject(hMemDC); ::ReleaseDC(hDesktop,hDC);hBitmap里就是截下来的图像 dysxq() ,如何保存hBitmap成位图呢??? 这个我N个月以前已经答过了LPTSTR CRemoteC::CopyScreenToBitmap(LPRECT lpRect) { HDC hScrDC, hMemDC; // 屏幕和内存设备描述表 HBITMAP hBitmap,hOldBitmap; // 位图句柄 int nX, nY, nX2, nY2; // 选定区域坐标 int nWidth, nHeight; // 位图宽度和高度 int xScrn, yScrn; // 屏幕分辨率 // 确保选定区域不为空矩形 if (IsRectEmpty(lpRect)) return NULL; //为屏幕创建设备描述表 hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); //为屏幕设备描述表创建兼容的内存设备描述表 hMemDC = CreateCompatibleDC(hScrDC); // 获得选定区域坐标 nX = lpRect-> left; nY = lpRect-> top; nX2 = lpRect-> right; nY2 = lpRect-> bottom; // 获得屏幕分辨率 xScrn = GetDeviceCaps(hScrDC, HORZRES); yScrn = GetDeviceCaps(hScrDC, VERTRES); //确保选定区域是可见的 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; // 创建一个与屏幕设备描述表兼容的位图 int *temp=new int(m_szResolution.Find("*")); char *pWidth=new char[10]; char *pHeight=new char[10]; strcpy(pWidth,m_szResolution.Mid(0,*temp)); strcpy(pHeight,m_szResolution.Mid(*temp+1)); delete temp; int nDestResWidth=atoi(pWidth); int nDestResHeight=atoi(pHeight); delete pWidth; delete pHeight; hBitmap = CreateCompatibleBitmap(hScrDC, nDestResWidth, nDestResHeight); // 把新位图选到内存设备描述表中 hOldBitmap=(HBITMAP)::SelectObject(hMemDC, hBitmap); // 把屏幕设备描述表拷贝到内存设备描述表中 StretchBlt(hMemDC, 0, 0, nDestResWidth, nDestResHeight,hScrDC, nX, nY,nWidth,nHeight,SRCCOPY); //得到屏幕位图的句柄 hBitmap =(HBITMAP) ::SelectObject(hMemDC, hOldBitmap); //清除 DeleteDC(hScrDC); DeleteDC(hMemDC); char tmppath[MAX_PATH]; char *tmpname=new char[MAX_PATH]; GetTempPath(MAX_PATH,tmppath); GetTempFileName(tmppath,"AnyServer",0,tmpname);//获得一个唯一的临时文件名 SaveBitmapToFile(hBitmap,tmpname); return tmpname; } int CRemoteC::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName) { //我们也可以把屏幕内容以位图格式存到磁盘文件上. //lpFileName 为位图文件名 HDC hDC; //设备描述表 int iBits; //当前显示分辨率下每个像素所占字节数 WORD wBitCount; //位图中每个像素所占字节数 //定义调色板大小, 位图中像素字节大小,位图文件大小,写入文件字节数 DWORD dwPaletteSize=0, dwBmBitsSize, dwDIBSize, dwWritten; BITMAP Bitmap; //位图属性结构 BITMAPFILEHEADER bmfHdr; //位图文件头结构 BITMAPINFOHEADER bi; //位图信息头结构 LPBITMAPINFOHEADER lpbi; //指向位图信息头结构 HANDLE fh, hDib, hPal,hOldPal=NULL; //定义文件,分配内存句柄,调色板句柄 //计算位图文件每个像素所占字节数 hDC = CreateDC("DISPLAY",NULL,NULL,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 < = 32) wBitCount = 24; //计算调色板大小 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=(HPALETTE)::GetStockObject(DEFAULT_PALETTE);// 处理调色板 if (hPal) { hDC = GetDC(NULL); hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE); RealizePalette(hDC); } // 获取该调色板下新的像素值 GetDIBits(hDC, hBitmap, 0, (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(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL& brvbar;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; } 首先我们要确定屏幕截取的区域,用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.HBITMAP CopyScreenToBitmap(LPRECT lpRect) //lpRect 代表选定区域{HDC hScrDC, hMemDC; // 屏幕和内存设备描述表HBITMAP hBitmap, hOldBitmap; // 位图句柄int nX, nY, nX2, nY2;// 选定区域坐标int nWidth, nHeight;// 位图宽度和高度int xScrn, yScrn;// 屏幕分辨率 // 确保选定区域不为空矩形 if (IsRectEmpty(lpRect)) return NULL; //为屏幕创建设备描述表 hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); //为屏幕设备描述表创建兼容的内存设备描述表 hMemDC = CreateCompatibleDC(hScrDC); // 获得选定区域坐标 nX = lpRect- >left; nY = lpRect- >top; nX2 = lpRect- >right; nY2 = lpRect- >bottom; // 获得屏幕分辨率 xScrn = GetDeviceCaps(hScrDC, HORZRES); yScrn = GetDeviceCaps(hScrDC, VERTRES); //确保选定区域是可见的 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; // 创建一个与屏幕设备描述表兼容的位图hBitmap = CreateCompatibleBitmap (hScrDC, nWidth, nHeight); // 把新位图选到内存设备描述表中 hOldBitmap = SelectObject(hMemDC, hBitmap); // 把屏幕设备描述表拷贝到内存设备描述表中BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY); //得到屏幕位图的句柄 hBitmap = SelectObject(hMemDC, hOldBitmap); //清除 DeleteDC(hScrDC); DeleteDC(hMemDC); // 返回位图句柄 return hBitmap;}得到屏幕位图句柄以后,我们可以把屏幕位图显示在窗口中 求助:如何解决两个进程同时使用一个文件的冲突 简单的问题弄死我了,编译死活不过,哪里错了???指点一下????? DBgriD数据源显示不了 用下面这种方法添加属性页的问题。 简单CSlider Control问题 telnet客户端的界面与控制台程序运行时的那个界面很相似,用什么类做的啊? 在SDI的ClientDC中绘制了很多个矩形,能否清除掉? 请问微软拼音输入法的Candidiate条(就是组字的时候下面显示候选的那个条)是窗口吗?能得到它的句柄吗? 我的程序 编码转化(BIG5) 请问怎么把日期相加? 如何取得对方机器的MAC地址(网关外)?
HDC hDC = ::GetDC(hDesktop);
HDC hMemDC = ::CreateCompatibleDC(hDC); ::GetWindowRect(hDesktop,&rect); int cx,cy;
cx = rect.right - rect.left;
cy = rect.bottom - rect.top;
HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC,cx,cy); HGDIOBJ hOldObject = ::SelectObject(hMemDC,m_hBitmap);
::BitBlt(hMemDC,0,0,cx,cy,hDC,rect.left,rect.top,SRCCOPY);
::SelectObject(hMemDC,hOldObject); ::DeleteObject(hMemDC);
::ReleaseDC(hDesktop,hDC);
hBitmap里就是截下来的图像
LPTSTR CRemoteC::CopyScreenToBitmap(LPRECT lpRect)
{
HDC hScrDC, hMemDC; // 屏幕和内存设备描述表
HBITMAP hBitmap,hOldBitmap; // 位图句柄
int nX, nY, nX2, nY2; // 选定区域坐标
int nWidth, nHeight; // 位图宽度和高度
int xScrn, yScrn; // 屏幕分辨率
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect)) return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect-> left;
nY = lpRect-> top;
nX2 = lpRect-> right;
nY2 = lpRect-> bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
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;
// 创建一个与屏幕设备描述表兼容的位图
int *temp=new int(m_szResolution.Find("*"));
char *pWidth=new char[10];
char *pHeight=new char[10];
strcpy(pWidth,m_szResolution.Mid(0,*temp));
strcpy(pHeight,m_szResolution.Mid(*temp+1));
delete temp;
int nDestResWidth=atoi(pWidth);
int nDestResHeight=atoi(pHeight);
delete pWidth;
delete pHeight;
hBitmap = CreateCompatibleBitmap(hScrDC, nDestResWidth, nDestResHeight);
// 把新位图选到内存设备描述表中
hOldBitmap=(HBITMAP)::SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
StretchBlt(hMemDC, 0, 0, nDestResWidth, nDestResHeight,hScrDC, nX, nY,nWidth,nHeight,SRCCOPY);
//得到屏幕位图的句柄
hBitmap =(HBITMAP) ::SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
char tmppath[MAX_PATH];
char *tmpname=new char[MAX_PATH];
GetTempPath(MAX_PATH,tmppath);
GetTempFileName(tmppath,"AnyServer",0,tmpname);//获得一个唯一的临时文件名
SaveBitmapToFile(hBitmap,tmpname);
return tmpname;
}
int CRemoteC::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
{
//我们也可以把屏幕内容以位图格式存到磁盘文件上.
//lpFileName 为位图文件名
HDC hDC; //设备描述表
int iBits; //当前显示分辨率下每个像素所占字节数
WORD wBitCount; //位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize, dwWritten;
BITMAP Bitmap; //位图属性结构
BITMAPFILEHEADER bmfHdr; //位图文件头结构
BITMAPINFOHEADER bi; //位图信息头结构
LPBITMAPINFOHEADER lpbi; //指向位图信息头结构
HANDLE fh, hDib, hPal,hOldPal=NULL;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,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 < = 32)
wBitCount = 24;
//计算调色板大小
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=(HPALETTE)::GetStockObject(DEFAULT_PALETTE);// 处理调色板
if (hPal)
{
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC,(HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (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(lpFileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL& brvbar;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;
}
区域,
用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域
拷贝到
位图中.
HBITMAP CopyScreenToBitmap(LPRECT lpRect)
//lpRect 代表选定区域
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 位图宽度和高度
int xScrn, yScrn;
// 屏幕分辨率
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect- >left;
nY = lpRect- >top;
nX2 = lpRect- >right;
nY2 = lpRect- >bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
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;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap = SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
return hBitmap;
}
得到屏幕位图句柄以后,我们
可以把屏幕位图显示在窗口中