调用Windows api 窗口截图

分别调用windows api函数及CVI自带函数,完成对GRAPH界面的截图

界面设计如下图,右侧为graph控件的位置信息,调用API函数是完成对于选择窗口的固定位置进行截图,调用CVI自带函数则是针对控件。

//CVI自带工具截图
int CVICALLBACK printByCVI (int panel, int control, int event,
					   void *callbackData, int eventData1, int eventData2)
{
	char filePath[500];
	switch (event)
	{
		case EVENT_COMMIT:
			FileSelectPopup ("c:\\Users\\Administrator\\Desktop", "*.bmp", "", "", VAL_SAVE_BUTTON, 0, 0, 1, 1, filePath);
			SetWaitCursor(1);
			Delay(0.1);
			
			SaveCtrlDisplayToFile (panelHandle, PANEL_GRAPH, 0, -1, -1, filePath);
			
			MessagePopup("","");
			
			SetWaitCursor(0);
			break;
	}
	return 0;
}

//Windows API截图
int CVICALLBACK printByAPI (int panel, int control, int event,
					   void *callbackData, int eventData1, int eventData2)
{
	char filePath[500];
	switch (event)
	{
		case EVENT_COMMIT:
			FileSelectPopup ("c:\\Users\\Administrator\\Desktop", "*.bmp", "", "", VAL_SAVE_BUTTON, 0, 0, 1, 1, filePath);
			SetWaitCursor(1);
			Delay(0.1);
			
			CaptureImage (FindWindowA(NULL,"demo"),filePath);
			
			MessagePopup("","");
			
			SetWaitCursor(0);
			break;
	}
	return 0;
}

/**
 * GDI 截取指定窗口
 * 
 * 参数 hwnd   要截屏的窗口句柄
 * 参数 FilePath    截图存放目录
 *
 */
int CaptureImage(HWND hwnd, CHAR *FilePath)
{
    HDC hdcWindow;
    HDC hdcMemDC = NULL;
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;
    RECT rcClient;
    BITMAPFILEHEADER   bmfHeader;    
    BITMAPINFOHEADER   bi;
    DWORD dwBmpSize;
    HANDLE hDIB;
    CHAR *lpbitmap;
    HANDLE hFile;
    DWORD dwSizeofDIB;
    DWORD dwBytesWritten;
 
    hdcWindow = GetWindowDC(hwnd); // 截图目标窗口DC
//    hdcWindow = GetDC(hwnd); // 截图DC
 
    // 创建兼容内存DC
    hdcMemDC = CreateCompatibleDC(hdcWindow); 
 
    if(!hdcMemDC)
    {
		MessagePopup("","CreateCompatibleDC has failed");
        goto done;
    }
 
    // 获取客户端区域用于计算大小
    GetClientRect(hwnd, &rcClient);
 
    // 设置延展模式
    SetStretchBltMode(hdcWindow, HALFTONE);

    // 来源 DC 是整个屏幕而目标 DC 是当前的窗口 (HWND)
/*    if(!StretchBlt(hdcWindow, 					 //-----------注释原因:不需要压缩位图,又不截取全屏
        0,0, 
        rcClient.right, rcClient.bottom, 
        hdcScreen, 							  
        0,0,
        GetSystemMetrics (SM_CXSCREEN),
        GetSystemMetrics (SM_CYSCREEN),
        SRCCOPY))
    {
		MessagePopup("","StretchBlt has failed");
        goto done;
    }
*/ 
    // 通过窗口DC 创建一个兼容位图
    hbmScreen = CreateCompatibleBitmap(
        hdcWindow,
        400, 300//--位图宽高
        );
 
    if(!hbmScreen)
    {
		MessagePopup("","CreateCompatibleBitmap Failed");
        goto done;
    }
 
    // 将位图块传送到我们兼容的内存DC中
    SelectObject(hdcMemDC,hbmScreen);
	/*---------------------------注释原因:截取软件部分界面,需要设定来源DC的坐标以及目标DC的宽高,保留原代码以观赏  
	if(!BitBlt(
        hdcMemDC,   // 目的DC
        0,0,        // 目的DC的 x,y 坐标
        rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, // 目的 DC 的宽高
        hdcWindow,  // 来源DC
        0,0,        // 来源DC的 宽高
        SRCCOPY))   // 粘贴方式
    {
		MessagePopup("","BitBlt has failed");
        goto done;
	}
	*/	
    if(!BitBlt(
        hdcMemDC,   // 目的DC
        0,0,        // 目的DC的 x,y 坐标
        400, 300, // 目的 DC 的宽高
        hdcWindow,  // 来源DC
        50,50+26,        // 来源DC的宽高
        SRCCOPY))   // 粘贴方式
    {
		MessagePopup("","BitBlt has failed");
        goto done;
    }
 
    // 获取位图信息并存放在 bmpScreen 中
    GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);
 
    bi.biSize = sizeof(BITMAPINFOHEADER);    
    bi.biWidth = bmpScreen.bmWidth;    
    bi.biHeight = bmpScreen.bmHeight;  
    bi.biPlanes = 1;    
    bi.biBitCount = 32;    
    bi.biCompression = BI_RGB;    
    bi.biSizeImage = 0;  
    bi.biXPelsPerMeter = 0;    
    bi.biYPelsPerMeter = 0;    
    bi.biClrUsed = 0;    
    bi.biClrImportant = 0;
 
    dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
 
    // 在 32-bit Windows 系统上, GlobalAlloc 和 LocalAlloc 是由 HeapAlloc 封装来的
    // handle 指向进程默认的堆. 所以开销比 HeapAlloc 要大
    hDIB = GlobalAlloc(GHND,dwBmpSize); 
    lpbitmap = (char *)GlobalLock(hDIB);    
 
    // 获取兼容位图的位并且拷贝结果到一个 lpbitmap 中.
    GetDIBits(
        hdcWindow,  // 设备环境句柄
        hbmScreen,  // 位图句柄
        0,          // 指定检索的第一个扫描线
        (UINT)bmpScreen.bmHeight, // 指定检索的扫描线数
        lpbitmap,   // 指向用来检索位图数据的缓冲区的指针
        (BITMAPINFO *)&bi, // 该结构体保存位图的数据格式
        DIB_RGB_COLORS // 颜色表由红、绿、蓝(RGB)三个直接值构成
        );
 
 
 
    // 创建一个文件来保存文件截图
    hFile = CreateFile(
        FilePath,
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );
 
    // 将 图片头(headers)的大小, 加上位图的大小来获得整个文件的大小
    dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
 
    // 设置 Offset 偏移至位图的位(bitmap bits)实际开始的地方
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); 
 
    // 文件大小
    bmfHeader.bfSize = dwSizeofDIB; 
 
    // 位图的 bfType 必须是字符串 "BM"
    bmfHeader.bfType = 0x4D42; //BM   
 
    dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
 
    // 解锁堆内存并释放
    GlobalUnlock(hDIB);    
    GlobalFree(hDIB);
 
    // 关闭文件句柄
    CloseHandle(hFile);
 
    // 清理资源
done:
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(hwnd,hdcWindow);
 
    return 0;
}

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值