博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
msdn原版纯c实现的截屏代码
阅读量:1992 次
发布时间:2019-04-27

本文共 11862 字,大约阅读时间需要 39 分钟。

前言

在找反截屏的资料,看到msdn上有段纯C实现的截屏代码。

这才是网上其他截屏代码的原始出处 :)

资料

Capturing an ImageYou can use a bitmap to capture an image, and you can store the captured image in memory, display it at a different location in your application's window, or display it in another window.In some cases, you may want your application to capture images and store them only temporarily. For example, when you scale or zoom a picture created in a drawing application, the application must temporarily save the normal view of the image and display the zoomed view. Later, when the user selects the normal view, the application must replace the zoomed image with a copy of the normal view that it temporarily saved.To store an image temporarily, your application must call CreateCompatibleDC to create a DC that is compatible with the current window DC. After you create a compatible DC, you create a bitmap with the appropriate dimensions by calling the CreateCompatibleBitmap function and then select it into this device context by calling the SelectObject function.After the compatible device context is created and the appropriate bitmap has been selected into it, you can capture the image. The BitBlt function captures images. This function performs a bit block transfer that is, it copies data from a source bitmap into a destination bitmap. However, the two arguments to this function are not bitmap handles. Instead, BitBlt receives handles that identify two device contexts and copies the bitmap data from a bitmap selected into the source DC into a bitmap selected into the target DC. In this case, the target DC is the compatible DC, so when BitBlt completes the transfer, the image has been stored in memory. To redisplay the image, call BitBlt a second time, specifying the compatible DC as the source DC and a window (or printer) DC as the target DC.The following example code is from an application that captures an image of the entire desktop, scales it down to the current window size and then saves it to a file.
// GDI_CapturingAnImage.cpp : Defines the entry point for the application.//#include "stdafx.h"#include "GDI_CapturingAnImage.h"#define MAX_LOADSTRING 100// Global Variables:HINSTANCE hInst;                        // current instanceTCHAR szTitle[MAX_LOADSTRING];          // The title bar textTCHAR szWindowClass[MAX_LOADSTRING];    // the main window class name// Forward declarations of functions included in this code module:ATOM                MyRegisterClass(HINSTANCE hInstance);BOOL                InitInstance(HINSTANCE, int);LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPTSTR    lpCmdLine,                     int       nCmdShow){    UNREFERENCED_PARAMETER(hPrevInstance);    UNREFERENCED_PARAMETER(lpCmdLine);    MSG msg;    HACCEL hAccelTable;    // Initialize global strings    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);    LoadString(hInstance, IDC_GDI_CAPTURINGANIMAGE, szWindowClass, MAX_LOADSTRING);    MyRegisterClass(hInstance);    // Perform application initialization:    if (!InitInstance (hInstance, nCmdShow))    {        return FALSE;    }    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GDI_CAPTURINGANIMAGE));    // Main message loop:    while (GetMessage(&msg, NULL, 0, 0))    {        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))        {            TranslateMessage(&msg);            DispatchMessage(&msg);        }    }    return (int) msg.wParam;}////  FUNCTION: MyRegisterClass()////  PURPOSE: Registers the window class.////  COMMENTS:////    This function and its usage are only necessary if you want this code//    to be compatible with Win32 systems prior to the 'RegisterClassEx'//    function that was added to Windows 95. It is important to call this function//    so that the application will get 'well formed' small icons associated//    with it.//ATOM MyRegisterClass(HINSTANCE hInstance){    WNDCLASSEX wcex;    wcex.cbSize = sizeof(WNDCLASSEX);    wcex.style            = CS_HREDRAW | CS_VREDRAW;    wcex.lpfnWndProc    = WndProc;    wcex.cbClsExtra        = 0;    wcex.cbWndExtra        = 0;    wcex.hInstance        = hInstance;    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GDI_CAPTURINGANIMAGE));    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);    wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_GDI_CAPTURINGANIMAGE);    wcex.lpszClassName    = szWindowClass;    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));    return RegisterClassEx(&wcex);}////   FUNCTION: InitInstance(HINSTANCE, int)////   PURPOSE: Saves instance handle and creates main window////   COMMENTS:////        In this function, we save the instance handle in a global variable and//        create and display the main program window.//BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){   HWND hWnd;   hInst = hInstance; // Store instance handle in our global variable   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   if (!hWnd)   {      return FALSE;   }   ShowWindow(hWnd, nCmdShow);   UpdateWindow(hWnd);   return TRUE;}// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A// PARTICULAR PURPOSE.//// Copyright (c) Microsoft Corporation. All rights reserved////   FUNCTION: CaptureAnImage(HWND hWnd)////   PURPOSE: Captures a screenshot into a window and then saves it in a .bmp file.////   COMMENTS: ////      Note: This sample will attempt to create a file called captureqwsx.bmp //        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(hWnd);    // Create a compatible DC which is used in a BitBlt from the window DC    hdcMemDC = CreateCompatibleDC(hdcWindow);     if(!hdcMemDC)    {        MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);        goto done;    }    // Get the client area for size calculation    RECT rcClient;    GetClientRect(hWnd, &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))    {        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 updone:    DeleteObject(hbmScreen);    DeleteObject(hdcMemDC);    ReleaseDC(NULL,hdcScreen);    ReleaseDC(hWnd,hdcWindow);    return 0;}////  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)////  PURPOSE:  Processes messages for the main window.////  WM_COMMAND    - process the application menu//  WM_PAINT    - Paint the main window//  WM_DESTROY    - post a quit message and return////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    int wmId, wmEvent;    PAINTSTRUCT ps;    HDC hdc;    switch (message)    {    case WM_CREATE:        {        break;        }    case WM_COMMAND:        wmId    = LOWORD(wParam);        wmEvent = HIWORD(wParam);        // Parse the menu selections:        switch (wmId)        {        case IDM_ABOUT:            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);            break;        case IDM_EXIT:            DestroyWindow(hWnd);            break;        default:            return DefWindowProc(hWnd, message, wParam, lParam);        }        break;    case WM_MOVE:    case WM_PAINT:        hdc = BeginPaint(hWnd, &ps);        CaptureAnImage(hWnd);        EndPaint(hWnd, &ps);        break;    case WM_DESTROY:        PostQuitMessage(0);        break;    default:        return DefWindowProc(hWnd, message, wParam, lParam);    }    return 0;}// Message handler for about box.INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){    UNREFERENCED_PARAMETER(lParam);    switch (message)    {    case WM_INITDIALOG:        return (INT_PTR)TRUE;    case WM_COMMAND:        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)        {            EndDialog(hDlg, LOWORD(wParam));            return (INT_PTR)TRUE;        }        break;    }    return (INT_PTR)FALSE;}

转载地址:http://gymvf.baihongyu.com/

你可能感兴趣的文章
JAVA学习笔记8 - Stream 和 File I/O
查看>>
JAVA学习笔记9 - 异常
查看>>
JAVA学习笔记10 - 继承
查看>>
JAVA学习笔记11 - 接口interface
查看>>
Android 开发学习笔记 00 - Getting Started
查看>>
【学习笔记】Android Activity
查看>>
Android使用Retrofit_00_Getting Started
查看>>
Android使用Retrofit_01_OAuth2 + GitHub
查看>>
Django oauth toolkit + Android + Retrofit 实现 OAuth2 的 access token 获取
查看>>
Android + Django + OAuth2 + Stub Authenticator
查看>>
Django + REST学习笔记
查看>>
Android Sync Adapter (使用Stub Content Provider) 笔记
查看>>
诡异的 Scroll view may have only one direct child placed within it 错误
查看>>
【转载】将Ubuntu16.04 中gedit在仅显示一个文件时显示文件名tab
查看>>
fstream 对象多次使用时注意clear
查看>>
调试 LenaCV 3D Camera (Linux)
查看>>
OpenCV杂记 - Mat in C++
查看>>
location区段
查看>>
nginx访问控制、基于用户认证、https配置
查看>>
SaltStack
查看>>