#include <Windows.h>
#include <iostream>

using namespace std;

#if 0
int CaptureAnImage(/*HWND hWnd*/)
{
    HDC hdcScreen;
    HDC hdcWindow;
    HDC hdcMemDC = NULL;
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;

    // Retrieve the handle to a display device context for the client
    // area of the window.
    hdcScreen = GetDC(NULL);
    //hdcWindow = GetDC(hdcScreen);

    // Create a compatible DC which is used in a BitBlt from the window DC
    hdcMemDC = CreateCompatibleDC(hdcScreen);

    if (!hdcMemDC){
        cerr << "failed \n";
        return 1;
    }

    // Get the client area for size calculation
    RECT rcClient;
    GetClientRect(NULL, &rcClient);

    //This is the best stretch mode
    SetStretchBltMode(hdcWindow, HALFTONE);

    //The source DC is the entire screen and the destination DC is the current window (HWND)
    if (!StretchBlt(hdcWindow,
        0, 0,
        rcClient.right, rcClient.bottom,
        hdcScreen,
        0, 0,
        GetSystemMetrics(SM_CXSCREEN),
        GetSystemMetrics(SM_CYSCREEN),
        SRCCOPY))
    {
        cerr << " error \n";
        //MessageBox(hWnd, L"StretchBlt has failed", L"Failed", MB_OK);
        //goto done;
    }

    // Create a compatible bitmap from the Window DC
    hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);

    if (!hbmScreen)
    {
        MessageBox(hWnd, L"CreateCompatibleBitmap Failed", L"Failed", MB_OK);
        goto done;
    }

    // Select the compatible bitmap into the compatible memory DC.
    SelectObject(hdcMemDC, hbmScreen);

    // Bit block transfer into our compatible memory DC.
    if (!BitBlt(hdcMemDC,
        0, 0,
        rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
        hdcWindow,
        0, 0,
        SRCCOPY))
    {
        MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK);
        goto done;
    }

    // Get the BITMAP from the HBITMAP
    GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);

    BITMAPFILEHEADER   bmfHeader;
    BITMAPINFOHEADER   bi;

    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;

    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

    // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
    // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
    // have greater overhead than HeapAlloc.
    HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
    char *lpbitmap = (char *)GlobalLock(hDIB);

    // Gets the "bits" from the bitmap and copies them into a buffer
    // which is pointed to by lpbitmap.
    GetDIBits(hdcWindow, hbmScreen, 0,
        (UINT)bmpScreen.bmHeight,
        lpbitmap,
        (BITMAPINFO *)&bi, DIB_RGB_COLORS);

    // A file is created, this is where we will save the screen capture.
    HANDLE hFile = CreateFile(L"captureqwsx.bmp",
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, NULL);

    // Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);

    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER);

    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB;

    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM   

    DWORD 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);

    //Unlock and Free the DIB from the heap
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);

    //Close the handle for the file that was created
    CloseHandle(hFile);

    //Clean up
done:
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(NULL, hdcScreen);
    ReleaseDC(hWnd, hdcWindow);

    return 0;
}
#endif

void GetScreenShot(void)
{
    int x1, y1, x2, y2, w, h;

    // get screen dimensions
    x1 = GetSystemMetrics(SM_XVIRTUALSCREEN);
    y1 = GetSystemMetrics(SM_YVIRTUALSCREEN);
    x2 = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    y2 = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    w = x2 - x1;
    h = y2 - y1;

    // copy screen to bitmap
    HDC     hScreen = GetDC(NULL);
    HDC     hDC = CreateCompatibleDC(hScreen);
    HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, w, h);
    HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
    BOOL    bRet = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);

    // save bitmap to clipboard
    OpenClipboard(NULL);
    EmptyClipboard();
    SetClipboardData(CF_BITMAP, hBitmap);
    CloseClipboard();

    BITMAPFILEHEADER   bmfHeader;
    BITMAPINFOHEADER   bi;

    BITMAP bmpScreen;
    GetObject(hBitmap, 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;

    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;

    // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
    // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
    // have greater overhead than HeapAlloc.
    HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
    char *lpbitmap = (char *)GlobalLock(hDIB);

    // Gets the "bits" from the bitmap and copies them into a buffer
    // which is pointed to by lpbitmap.
    GetDIBits(hScreen, hBitmap, 0,
        (UINT)bmpScreen.bmHeight,
        lpbitmap,
        (BITMAPINFO *)&bi, DIB_RGB_COLORS);

    // A file is created, this is where we will save the screen capture.
    HANDLE hFile = CreateFile(L"captureqwsx.bmp",
        GENERIC_WRITE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL, NULL);

    // Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);

    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER);

    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB;

    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM   

    DWORD 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);

    //Unlock and Free the DIB from the heap
    GlobalUnlock(hDIB);
    GlobalFree(hDIB);

    //Close the handle for the file that was created
    CloseHandle(hFile);

    // clean up
    SelectObject(hDC, old_obj);
    DeleteDC(hDC);
    ReleaseDC(NULL, hScreen);
    DeleteObject(hBitmap);
}

int main(){
    //CaptureAnImage();
    GetScreenShot();
    return 0;
}

grab window的更多相关文章

  1. Qt刷新机制的一些总结(Qt内部画的时候是相当于画在后台一个对象里,然后在刷新的时候调用bitblt统一画,调用window的api并不会影响到后面的那个对象)

    前段时间做过一个界面刷新的优化,遇到的坑比较多,在这里做一点点总结吧.     优化的方案是滚动滚动条的时候用截屏的方式代替界面全部刷新,优化完成后,界面在滚动时效率能提升大概一倍,背景介绍完毕.   ...

  2. window.external.JavaScriptCallCpp

    方案2: 1.编写html <html> <head> </head> <body> <script language="javascr ...

  3. Taking a screen shot of a window using Delphi code is rather easy.

    Taking a screen shot of a window using Delphi code is rather easy. A screen shot (screen capture) is ...

  4. python 下实现window 截图

    首先安装PIL库,因为PIL官网没有支持python3.6的PIL库我想在3.X中实现,因此使用pip安装pillow pip install pillow 安装 安装完成后,from PIL imp ...

  5. [虾扯蛋] android界面框架-Window

    从纯sdk及framwork的角度看,android中界面框架相关的类型有:Window,WindowManager,View等.下面就以这几个类为出发点来概览下安卓开发的"界面架构&quo ...

  6. JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题

    1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...

  7. 谈谈document.ready和window.onload的区别

    在Jquery里面,我们可以看到两种写法:$(function(){}) 和$(document).ready(function(){}) 这两个方法的效果都是一样的,都是在dom文档树加载完之后执行 ...

  8. X Window 的奥秘

    大名鼎鼎的 X Window 大家肯定不陌生.都知道它是 Unix/Linux 下面的窗口系统,也都知道它基于 Server/Clinet 架构.在网上随便搜一搜,也可以找到不少 X Window 的 ...

  9. Android Starting Window(Preview Window)

    当打开一个Activity时,如果这个Activity所属的应用还没有在运行,系统会为这个Activity所属的应用创建一个进程,但进程的创建与初始化都需要时间,在这个动作完成之前系统要做什么呢?如果 ...

随机推荐

  1. django实现model中choices类型字段,后台自由配置

    该功能主要试用于项目中有大量需要动态配置的字典字段,字典建议做缓存处理. 定义字典类型表,字典值两张表 2.配置对应的字典值 3.重写model的init方法,动态赋值choice 4.列表界面效果 ...

  2. 视觉slam学习之路(一)看高翔十四讲所遇到的问题

      目前实验室做机器人,主要分三个方向,定位导航,建图,图像识别,之前做的也是做了下Qt上位机,后面又弄红外识别,因为这学期上课也没怎么花时间在项目,然后导师让我们确定一个方向来,便于以后发论文什么. ...

  3. 详解vue移动端 下拉刷新

    看完这篇文章,相信大伙也一样可以,做出一个自己的刷新,加载的组件 说这个功能之前,大家要先了解一下,要怎么触发滚动条事件. 一定要注意,所有滚动事件都必须要满足这个条件,横向滚动条也一样, 只要满足子 ...

  4. 十大面试难题解惑,看完秒杀一切 HR 面。程序员必读!

    最能体现求职者能力的就是面试,能不能拿到Offer,取决于你面试时的表现,只有有准备才能在面试过程中游刃有余. 小编收集了10个面试官最爱提的问题,虽然题目千变万化,但是万变不离其宗,只要掌握了答题的 ...

  5. [SDOI 2011]黑白棋

    Description 题库链接 给出一个 \(1\times n\) 的棋盘,棋盘上有 \(k\) 个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色不同. 小 \( ...

  6. [Luogu 1559]运动员最佳匹配问题

    Description 题库链接 求 \(2\times N\) 个点的带权二分图最佳匹配. \(1\leq N\leq 20\) Solution 我还是太菜了啊...到现在才学 \(KM\) . ...

  7. brk和mmap(转)

    进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap: 1.brk是将数据段的(.data)的最高地址指针_edata往高地址推 2.mmap是虚拟地址空间找一个空闲的虚拟内存 如果mal ...

  8. C++ C# python 中常用数学计算函数对比

    1.求x 的n次幂. C++ #include<cmath> f=pow(x,n) C# f=Math.Pow(x,n) python import numpy as np f=np.po ...

  9. Spring学习笔记3——使用注解的方式完成注入对象中的效果

    第一步:修改applicationContext.xml 添加<context:annotation-config/>表示告诉Spring要用注解的方式进行配置 <?xml vers ...

  10. Python中list的功能介绍

    List的功能介绍 1. 列表的两种方法 1. 列表的内置方法 列表的相加 格式:x.__add__(y)等同于x+y 例如:list1 = [1,2,3] print(list1.__add__([ ...