windowsSDK实现 屏幕实时监控 热键截图 功能
2012-07-11 19:17
344 查看
为了自己做出一个远控程序,自己花了点时间学习了有关绘图方面的知识点。
一.基本概念的了解
为了实现实时屏幕显示的功能,首先学习了下《windows程序设计》的第14章,位图和位块的传输。
理解了下位图和位块的区别,基本概念。
概念一:位图与图元的区别:
位图 图元
点阵 矢量 (位图与图元的主要区别就在这里了)
容易失真 不失真
较大 较小
传输速度快 传输速度慢
概念二:与设备无关的位图
DDB 设备相关位图
DIB 设备无关位图
windows编程里面提到,这两个概念有时候是很难区分的。所以我在这里就不具体讲解两者的区别了,对我们的功能实现应该没什么关系。但是因为这是个经常出现的字眼,所以这里先提一下。
二.BitBlt函数
接下来我们来看BitBlt 函数,这个函数是我们这次功能实现的最关键的一个函数了~~~~
参数虽然多,但是用起来不难
hdcDest 目标设备描述表
nXDest 目标起始x坐标位置
nYDest 目标起始y坐标位置
nWidth 宽度
nHeight 高度
hdcSrc 源设备描述表
nXSrc 源起始x坐标
nYSrc 源起始y坐标
dwRop 这个参数比较复杂,我们这里就是简单的原封不动的复制,所以使用了 SRCCOPY
更多关于这个函数的用法,参照MSDN
当然了,如果你想缩放图片,你还可以使用函数StretchBlt 这个函数比BitBlt多了两个参数。
在我的程序中,将屏幕的图像传输到我自己的程序中:
三.实时显示
我通过设置定时器,每隔1ms刷新一次软件的客户区。当然发消息没有这么快。但是至少这样能保证已经达到了最快的更新速度。
程序开始时触发定时器
有很多镜像!~~~这样的结果是正确的。我如果把我的程序放到我的另一个显示器上面(我有两个显示屏),那么程序显示就正常了,显示的是我原来那个屏幕上的图像。
四:保存bmp图片
这里直接贴代码了:
五.格式转换
一般远控在传输图像的时候都是把图片进行了压缩的。所以我想把bmp格式的图片转换成png。这里使用了GDI+的库。很方便就实现了。
windowsSDK程序需要的注意点:
1.保证是.cpp格式 .c格式的话就不能 因为这个库只有c++下面才能使用。
2.使用前引入头文件 和 库
3.实例代码
参考下面这篇文章,将的非常好:http://blog.csdn.net/yuzl32/article/details/5389919
六.键盘热键实现截图。
按下空格实现截图。其实这里还可以改进,焦点必须在程序里面才能进行截图。其实可以Hook键盘消息来进行截图操作。
最后发一个不完善的版本:
七.改进之处
可以自动根据时间戳创建文件以及文件夹,加上键盘Hook功能。
一.基本概念的了解
为了实现实时屏幕显示的功能,首先学习了下《windows程序设计》的第14章,位图和位块的传输。
理解了下位图和位块的区别,基本概念。
概念一:位图与图元的区别:
位图 图元
点阵 矢量 (位图与图元的主要区别就在这里了)
容易失真 不失真
较大 较小
传输速度快 传输速度慢
概念二:与设备无关的位图
DDB 设备相关位图
DIB 设备无关位图
windows编程里面提到,这两个概念有时候是很难区分的。所以我在这里就不具体讲解两者的区别了,对我们的功能实现应该没什么关系。但是因为这是个经常出现的字眼,所以这里先提一下。
二.BitBlt函数
接下来我们来看BitBlt 函数,这个函数是我们这次功能实现的最关键的一个函数了~~~~
BOOL BitBlt( __in HDC hdcDest, __in int nXDest, __in int nYDest, __in int nWidth, __in int nHeight, __in HDC hdcSrc, __in int nXSrc, __in int nYSrc, __in DWORD dwRop );
参数虽然多,但是用起来不难
hdcDest 目标设备描述表
nXDest 目标起始x坐标位置
nYDest 目标起始y坐标位置
nWidth 宽度
nHeight 高度
hdcSrc 源设备描述表
nXSrc 源起始x坐标
nYSrc 源起始y坐标
dwRop 这个参数比较复杂,我们这里就是简单的原封不动的复制,所以使用了 SRCCOPY
更多关于这个函数的用法,参照MSDN
当然了,如果你想缩放图片,你还可以使用函数StretchBlt 这个函数比BitBlt多了两个参数。
在我的程序中,将屏幕的图像传输到我自己的程序中:
hdcClient = BeginPaint (hwnd, &ps); //获得目标(本程序)设备描述符 hdcWindow = GetWindowDC (NULL); //获得源目标(屏幕)设备描述符 BitBlt (hdcClient, 0, 0, cxClient, cyClient, hdcWindow , 0, 0, SRCCOPY);
三.实时显示
我通过设置定时器,每隔1ms刷新一次软件的客户区。当然发消息没有这么快。但是至少这样能保证已经达到了最快的更新速度。
程序开始时触发定时器
case WM_CREATE: SetTimer (hwnd, ID_TIMER, 100, TimerProc) ; return 0 ;定时器函数
VOID CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime) { InvalidateRect(hwnd, NULL, NULL); //无效整个屏幕客户区,重绘客户区 }当这个功能实现的时候,出现了一个很奇怪的问题~~~。给大家截个图看看当前效果:
有很多镜像!~~~这样的结果是正确的。我如果把我的程序放到我的另一个显示器上面(我有两个显示屏),那么程序显示就正常了,显示的是我原来那个屏幕上的图像。
四:保存bmp图片
这里直接贴代码了:
HBITMAP ScreenCapture(LPWSTR filename ,WORD BitCount,LPRECT lpRect) { HBITMAP hBitmap; // 显示器屏幕DC HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL); HDC hmemDC = CreateCompatibleDC(hScreenDC); // 显示器屏幕的宽和高 int ScreenWidth = GetDeviceCaps(hScreenDC, HORZRES); int ScreenHeight = GetDeviceCaps(hScreenDC, VERTRES); // 旧的BITMAP,用于与所需截取的位置交换 HBITMAP hOldBM; // 保存位图数据 PVOID lpvpxldata; // 截屏获取的长宽及起点 INT ixStart; INT iyStart; INT iX; INT iY; // 位图数据大小 DWORD dwBitmapArraySize; // 几个大小 DWORD nBitsOffset; DWORD lImageSize ; DWORD lFileSize ; // 位图信息头 BITMAPINFO bmInfo; // 位图文件头 BITMAPFILEHEADER bmFileHeader; // 写文件用 HANDLE hbmfile; DWORD dwWritten; // 如果LPRECT 为NULL 截取整个屏幕 ixStart = iyStart = 0; iX = ScreenWidth; iY = ScreenHeight; // 创建BTIMAP hBitmap = CreateCompatibleBitmap(hScreenDC, iX, iY); // 将BITMAP选择入内存DC。 hOldBM = (HBITMAP)SelectObject(hmemDC, hBitmap); // BitBlt屏幕DC到内存DC,根据所需截取的获取设置参数 BitBlt(hmemDC, 0, 0, iX, iY, hScreenDC, ixStart, iyStart, SRCCOPY); // 将旧的BITMAP对象选择回内存DC,返回值为被替换的对象,既所截取的位图 hBitmap = (HBITMAP)SelectObject(hmemDC, hOldBM); if(filename == NULL) { DeleteDC( hScreenDC); DeleteDC(hmemDC); return hBitmap; } // 为位图数据申请内存空间 dwBitmapArraySize = ((((iX*32) + 31) & ~31)>> 3)* iY; lpvpxldata = HeapAlloc(GetProcessHeap(),HEAP_NO_SERIALIZE,dwBitmapArraySize); ZeroMemory(lpvpxldata,dwBitmapArraySize); // 添充 BITMAPINFO 结构 ZeroMemory(&bmInfo,sizeof(BITMAPINFO)); bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = iX; bmInfo.bmiHeader.biHeight = iY; bmInfo.bmiHeader.biPlanes = 1; bmInfo.bmiHeader.biBitCount = BitCount; bmInfo.bmiHeader.biCompression = BI_RGB; // 添充 BITMAPFILEHEADER 结构 ZeroMemory(&bmFileHeader,sizeof(BITMAPFILEHEADER)); nBitsOffset = sizeof(BITMAPFILEHEADER) + bmInfo.bmiHeader.biSize; lImageSize = ((((bmInfo.bmiHeader.biWidth * bmInfo.bmiHeader.biBitCount) + 31) & ~31)>> 3) * bmInfo.bmiHeader.biHeight; lFileSize = nBitsOffset + lImageSize; bmFileHeader.bfType = 'B'+('M'<<8); bmFileHeader.bfSize = lFileSize; bmFileHeader.bfOffBits = nBitsOffset; // 获取DIB用于写入到文件 GetDIBits(hmemDC, hBitmap, 0, bmInfo.bmiHeader.biHeight, lpvpxldata, &bmInfo, DIB_RGB_COLORS); // 写文件 hbmfile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hbmfile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWritten,NULL); WriteFile(hbmfile,&bmInfo,sizeof(BITMAPINFO),&dwWritten,NULL); WriteFile(hbmfile,lpvpxldata,lImageSize,&dwWritten,NULL); CloseHandle(hbmfile); // 释放内存,清除不同的DC。 // 这里没有删除BITMAP对象,需在显示完成后删除 HeapFree(GetProcessHeap(),HEAP_NO_SERIALIZE,lpvpxldata); ReleaseDC(0, hScreenDC); DeleteDC(hmemDC); return hBitmap; }这段代码基本上不加修改就能直接用了。
五.格式转换
一般远控在传输图像的时候都是把图片进行了压缩的。所以我想把bmp格式的图片转换成png。这里使用了GDI+的库。很方便就实现了。
windowsSDK程序需要的注意点:
1.保证是.cpp格式 .c格式的话就不能 因为这个库只有c++下面才能使用。
2.使用前引入头文件 和 库
#include <GdiPlus.h> using namespace Gdiplus; #pragma comment(lib, "gdiplus.lib")
3.实例代码
参考下面这篇文章,将的非常好:http://blog.csdn.net/yuzl32/article/details/5389919
#include <windows.h> #include <gdiplus.h> #include <stdio.h> using namespace Gdiplus; #pragma comment(lib,"gdiplus") int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) { UINT num = 0; // number of image encoders UINT size = 0; // size of the image encoder array in bytes ImageCodecInfo* pImageCodecInfo = NULL; //2.获取GDI+支持的图像格式编码器种类数以及ImageCodecInfo数组的存放大小 GetImageEncodersSize(&num, &size); if(size == 0) return -1; // Failure //3.为ImageCodecInfo数组分配足额空间 pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(pImageCodecInfo == NULL) return -1; // Failure //4.获取所有的图像编码器信息 GetImageEncoders(num, size, pImageCodecInfo); //5.查找符合的图像编码器的Clsid for(UINT j = 0; j < num; ++j) { if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) { *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; // Success } } //6.释放步骤3分配的内存 free(pImageCodecInfo); return -1; // Failure } INT main() { GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; //1.初始化GDI+,以便后续的GDI+函数可以成功调用 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); CLSID encoderClsid; Status stat; //7.创建Image对象并加载图片 Image* image = new Image(L"f://11.bmp"); // Get the CLSID of the PNG encoder. GetEncoderClsid(L"image/png", &encoderClsid); //8.调用Image.Save方法进行图片格式转换,并把步骤3)得到的图像编码器Clsid传递给它 stat = image->Save(L"11.png", &encoderClsid, NULL); if(stat == Ok) printf("Bird.png was saved successfully/n"); else printf("Failure: stat = %d/n", stat); //9.释放Image对象 delete image; //10.清理所有GDI+资源 GdiplusShutdown(gdiplusToken); return 0; }
六.键盘热键实现截图。
按下空格实现截图。其实这里还可以改进,焦点必须在程序里面才能进行截图。其实可以Hook键盘消息来进行截图操作。
最后发一个不完善的版本:
/*---------------------------------------
屏幕实时监控 热键截图软件
作者:Miibotree
---------------------------------------*/
#include <windows.h>
#include <GdiPlus.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
#define ID_TIMER 1
HBITMAP ghBitmap = NULL;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
VOID CALLBACK TimerProc (HWND, UINT, UINT, DWORD );
HBITMAP ScreenCapture(LPWSTR filename ,WORD BitCount,LPRECT lpRect); //全屏截图
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid); // Get the CLSID of the PNG encoder.
BOOL Bmp2Png(); //进行格式转化
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName [] = TEXT ("BitBlt") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_INFORMATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT ("BitBlt Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int cxClient, cyClient, cxSource, cySource ;
HDC hdcClient, hdcWindow ;
int x, y ;
PAINTSTRUCT ps ;
HDC hMemDC; // 内存设备描述表
HBITMAP hBitmap, hOldBitmap; // 位图句柄,用于替换内存中图像
RECT rect; //矩形区域
switch (message)
{
case WM_CREATE:
SetTimer (hwnd, ID_TIMER, 100, TimerProc) ;
return 0 ;
case WM_SIZE:
cxClient = LOWORD (lParam) ; //本程序窗口宽度
cyClient = HIWORD (lParam) ; //本程序窗口长度
return 0 ;
case WM_KEYDOWN:
switch(wParam)
{
case VK_SPACE:
//截图函数
ghBitmap = ScreenCapture(L"D:\\taskmgr.bmp" ,32, NULL);
//格式转换
Bmp2Png();
return 0;
}
return 0;
case WM_PAINT:
hdcClient = BeginPaint (hwnd, &ps); //获得目标(本程序)设备描述符
hdcWindow = GetWindowDC (NULL); //获得源目标(屏幕)设备描述符
BitBlt (hdcClient, 0, 0, cxClient, cyClient, hdcWindow , 0, 0, SRCCOPY);
//目标设备 源设备
cxSource = GetSystemMetrics (SM_CXSCREEN); //获得屏幕分辨率
cySource = GetSystemMetrics (SM_CYSCREEN);
rect.left = 0; rect.right = cxSource; rect.top = 0; rect.bottom = cySource;
ReleaseDC (hwnd, hdcWindow) ;
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
VOID CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
InvalidateRect(hwnd, NULL, NULL);
}
HBITMAP ScreenCapture(LPWSTR filename ,WORD BitCount,LPRECT lpRect) { HBITMAP hBitmap; // 显示器屏幕DC HDC hScreenDC = CreateDC(L"DISPLAY", NULL, NULL, NULL); HDC hmemDC = CreateCompatibleDC(hScreenDC); // 显示器屏幕的宽和高 int ScreenWidth = GetDeviceCaps(hScreenDC, HORZRES); int ScreenHeight = GetDeviceCaps(hScreenDC, VERTRES); // 旧的BITMAP,用于与所需截取的位置交换 HBITMAP hOldBM; // 保存位图数据 PVOID lpvpxldata; // 截屏获取的长宽及起点 INT ixStart; INT iyStart; INT iX; INT iY; // 位图数据大小 DWORD dwBitmapArraySize; // 几个大小 DWORD nBitsOffset; DWORD lImageSize ; DWORD lFileSize ; // 位图信息头 BITMAPINFO bmInfo; // 位图文件头 BITMAPFILEHEADER bmFileHeader; // 写文件用 HANDLE hbmfile; DWORD dwWritten; // 如果LPRECT 为NULL 截取整个屏幕 ixStart = iyStart = 0; iX = ScreenWidth; iY = ScreenHeight; // 创建BTIMAP hBitmap = CreateCompatibleBitmap(hScreenDC, iX, iY); // 将BITMAP选择入内存DC。 hOldBM = (HBITMAP)SelectObject(hmemDC, hBitmap); // BitBlt屏幕DC到内存DC,根据所需截取的获取设置参数 BitBlt(hmemDC, 0, 0, iX, iY, hScreenDC, ixStart, iyStart, SRCCOPY); // 将旧的BITMAP对象选择回内存DC,返回值为被替换的对象,既所截取的位图 hBitmap = (HBITMAP)SelectObject(hmemDC, hOldBM); if(filename == NULL) { DeleteDC( hScreenDC); DeleteDC(hmemDC); return hBitmap; } // 为位图数据申请内存空间 dwBitmapArraySize = ((((iX*32) + 31) & ~31)>> 3)* iY; lpvpxldata = HeapAlloc(GetProcessHeap(),HEAP_NO_SERIALIZE,dwBitmapArraySize); ZeroMemory(lpvpxldata,dwBitmapArraySize); // 添充 BITMAPINFO 结构 ZeroMemory(&bmInfo,sizeof(BITMAPINFO)); bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmInfo.bmiHeader.biWidth = iX; bmInfo.bmiHeader.biHeight = iY; bmInfo.bmiHeader.biPlanes = 1; bmInfo.bmiHeader.biBitCount = BitCount; bmInfo.bmiHeader.biCompression = BI_RGB; // 添充 BITMAPFILEHEADER 结构 ZeroMemory(&bmFileHeader,sizeof(BITMAPFILEHEADER)); nBitsOffset = sizeof(BITMAPFILEHEADER) + bmInfo.bmiHeader.biSize; lImageSize = ((((bmInfo.bmiHeader.biWidth * bmInfo.bmiHeader.biBitCount) + 31) & ~31)>> 3) * bmInfo.bmiHeader.biHeight; lFileSize = nBitsOffset + lImageSize; bmFileHeader.bfType = 'B'+('M'<<8); bmFileHeader.bfSize = lFileSize; bmFileHeader.bfOffBits = nBitsOffset; // 获取DIB用于写入到文件 GetDIBits(hmemDC, hBitmap, 0, bmInfo.bmiHeader.biHeight, lpvpxldata, &bmInfo, DIB_RGB_COLORS); // 写文件 hbmfile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); WriteFile(hbmfile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWritten,NULL); WriteFile(hbmfile,&bmInfo,sizeof(BITMAPINFO),&dwWritten,NULL); WriteFile(hbmfile,lpvpxldata,lImageSize,&dwWritten,NULL); CloseHandle(hbmfile); // 释放内存,清除不同的DC。 // 这里没有删除BITMAP对象,需在显示完成后删除 HeapFree(GetProcessHeap(),HEAP_NO_SERIALIZE,lpvpxldata); ReleaseDC(0, hScreenDC); DeleteDC(hmemDC); return hBitmap; }
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
//2.获取GDI+支持的图像格式编码器种类数以及ImageCodecInfo数组的存放大小
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
//3.为ImageCodecInfo数组分配足额空间
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
//4.获取所有的图像编码器信息
GetImageEncoders(num, size, pImageCodecInfo);
//5.查找符合的图像编码器的Clsid
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
//6.释放步骤3分配的内存
free(pImageCodecInfo);
return -1; // Failure
}
BOOL Bmp2Png()
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
//1.初始化GDI+,以便后续的GDI+函数可以成功调用
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID encoderClsid;
Status stat;
//7.创建Image对象并加载图片
Image* image = new Image(L"D:\\taskmgr.bmp");
// Get the CLSID of the PNG encoder.
GetEncoderClsid(L"image/png", &encoderClsid);
//8.调用Image.Save方法进行图片格式转换,并把步骤3)得到的图像编码器Clsid传递给它
stat = image->Save(L"D:\\taskmgr.png", &encoderClsid, NULL);
if(stat == Ok)
MessageBoxA(NULL, "格式转换成功", "成功", MB_OK);
else
MessageBoxA(NULL, "格式转换失败", "失败", MB_OK | MB_ICONERROR);
//9.释放Image对象
delete image;
//10.清理所有GDI+资源
GdiplusShutdown(gdiplusToken);
return TRUE;
}
七.改进之处
可以自动根据时间戳创建文件以及文件夹,加上键盘Hook功能。
相关文章推荐
- Qt5:Qt中屏幕或窗口截图功能的实现
- VB代码实现屏幕截图(Screenshot功能)
- [Starling] RenderTexture - 屏幕截图、角色残影功能的实现基础
- 在网页中实现QQ的屏幕截图功能
- Android 5.0及以上编程实现屏幕截图功能的方法
- C++实现屏幕截图功能
- Qt5:Qt中屏幕或窗口截图功能的实现
- Android-屏幕截图功能实现
- 屏幕截图功能实现
- java实现屏幕截图功能并保存截图
- C#软件开发实例.私人订制自己的屏幕截图工具(四)基本截图功能实现
- C#软件开发实例.私人订制自己的屏幕截图工具(四)基本截图功能实现
- java代码实现截图功能(屏幕截图)
- 实现windows下屏幕指定区域截图功能
- Android 代码实现屏幕截图功能
- 用gdi 实现屏幕截图功能
- JAVA功能代码《6》----用Java实现屏幕截图
- Vb.net2005实现屏幕截图功能
- cocos2d-x实现简易屏幕截图功能
- JAVA功能代码《6》----用Java实现屏幕截图