The function of screen capture small program developed by C + +

Time:2021-3-2

C + + development screen capture small program, Win32 program, can display the screen capture area and save.

The last meteor shower screen program is simply related to GDI drawing. This time, we will briefly introduce several API functions, which are related to GDI drawing.

在这里插入图片描述

GetDC to get the device environment of the currently created window.
Create DC to get the device environment of the current screen.
Create compatible DC to create a compatible device environment (equivalent to a virtual device environment)
BitBlt, this function, is equivalent to copy, which copies the device content of one environment to another.
Create compatible bitmap, create a canvas and put it in the compatible DC, so that you can draw pictures in it. Of course, you also need to put in brushes and brushes.

After introducing these functions, here comes the design idea:

1. Of course, the first thing to do is to define and create windows and message loops.

ATOM MyRegisterClass(HINSTANCE hInstance)
{
 WNDCLASSEX wcex;
 
 wcex.cbSize = sizeof(WNDCLASSEX);
 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 wcex.lpfnWndProc = WndProc;
 wcex.cbClsExtra = 0;
 wcex.cbWndExtra = 0;
 wcex.hInstance = hInstance;
 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDC_CAPTURESCREEN));
 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)(BLACK_BRUSH);
 wcex.lpszMenuName = NULL;
 wcex.lpszClassName = szWindowClass;
 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

 return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{

 Hinst = hinstance; // store the instance handle in the global variable
 //Create your own windows
 hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP,
 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

 if (!hWnd)
 {
 return FALSE;
 }
 //Display and update windows
 ShowWindow(hWnd, SW_MAXIMIZE);
 UpdateWindow(hWnd);

 return TRUE;
}

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
 _In_opt_ HINSTANCE hPrevInstance,
 _In_ LPTSTR lpCmdLine,
 _In_ int  nCmdShow)
{
 //Playsound can only play wav format, while mciSendString can play any format.
 
 //PlaySound("yixi.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
 mciSendString("open ./abc.mp3 alias bk",
 0, 0, 0);
 mciSendString("play bk repeat", 0, 0, 0);

 UNREFERENCED_PARAMETER(hPrevInstance);
 UNREFERENCED_PARAMETER(lpCmdLine);

 //Todo: place the code here.
 MSG msg;
 HACCEL hAccelTable;

 //Initialize global string
 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
 LoadString(hInstance, IDC_CAPTURESCREEN, szWindowClass, MAX_LOADSTRING);
 
 Myregisterclass (hinstance); // register class

 //Perform application initialization: 
 If (! InitInstance (hinstance, nCmdShow)) // initialize window
 {

 return FALSE;
 }

 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CAPTURESCREEN));

 //Main message loop: 
 while (GetMessage(&msg, NULL, 0, 0))
 {
 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
 {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 }
 return (int)msg.wParam;
}

2. Then get the device environment of the current screen,

3. Then save it to a compatible DC, which is equivalent to putting the current screen image into a buffer. stayWM_CREATEDo this in the message.


void ScreenDisplay()
{
 HDC disDc = ::CreateDC("DISPLAY", NULL, NULL, NULL);
 g_memDC = ::CreateCompatibleDC(disDc);
 g_ScreenW = GetDeviceCaps(disDc, HORZRES);
 g_ScreenH = GetDeviceCaps(disDc, VERTRES);
 HBITMAP hbitmap = CreateCompatibleBitmap(disDc, g_ScreenW, g_ScreenH);
 SelectObject(g_memDC, hbitmap);
 BitBlt(g_memDC, 0, 0, g_ScreenW, g_ScreenH, disDc, 0, 0, SRCCOPY);
}

4. Then put it in the window we created. At this time, you will see that the whole desktop will not move and a picture will be displayed,

5. Then we can draw the area we want to capture on this picture.

6. It presents a still picture. If it needs to be updated after drawing, a function will be usedInvalidateRgn, the selected region is invalid, which triggers the message WM_ So in this message, the graph will be redrawn and displayed.

case WM_PAINT:
 hdc = BeginPaint(hWnd, &ps);
 //Todo: add any drawing code here
 SelectObject(hdc, hpen);
 SelectObject(hdc, hBrush);
 BitBlt(hdc, 0, 0, g_ScreenW, g_ScreenH, g_memDC, 0, 0, SRCCOPY);
 Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
 EndPaint(hWnd, &ps);
break;

Next is the operation of drawing the desired area, several mouse message functions need to be used, mouse down, mouse up, mouse move, mouse double-click.
So here’s the idea:

Press down the mouse to determine the point in the upper left corner, then move the mouse to draw the rectangular area, and then pop up the mouse to determine the point in the lower right corner, so that the rectangular area is drawn.


case WM_LBUTTONDOWN:
{
  if (!Iselect)
  {
   POINT pt;
   GetCursorPos(&pt);
   rect.left = pt.x;
   rect.top = pt.y;
   rect.right = pt.x;
   rect.bottom = pt.x;
   InvalidateRgn(hWnd, 0, FALSE);
   Isdowmn = TRUE;
  }


}
 break;
case WM_LBUTTONUP:
{
  if (Isdowmn == TRUE&&!Iselect)
  {
  POINT pt;
  GetCursorPos(&pt);
  rect.right = pt.x;
  rect.bottom = pt.y;
  InvalidateRgn(hWnd, 0, FALSE);
  Isdowmn = FALSE;
  Iselect = TRUE;
  }
}
 break;
case WM_MOUSEMOVE:
{
  if (Isdowmn == TRUE&&!Iselect)
  {
  POINT pt;
  GetCursorPos(&pt);
  rect.right = pt.x;
  rect.bottom = pt.y;
  InvalidateRgn(hWnd, 0, FALSE);
  }
}
 break;

Finally, double-click the mouse to save the captured image to the clipboard, which completes the screen capture.

case WM_LBUTTONDBLCLK:
 if (Iselect == TRUE)
 {
 Int inum = message box (hWnd), "screenshot succeeded! Zhang Yixi, MB_ OKCANCEL | MB_ ICONINFORMATION);
 if (iNum == 1)
 {
  CopyToCliboard();
  Iselect = FALSE;
  PostQuitMessage(0);
 }
 else
 {
  Iselect = FALSE;
 }
 }
 break;
void CopyToCliboard()
{
 HDC hScreenDC = ::CreateDC("DISPLAY", 0, 0, 0);
 HDC memDC = ::CreateCompatibleDC(hScreenDC);
 int Width = rect.right - rect.left-2;
 int Height = rect.bottom - rect.top-2;
 HBITMAP hBmap = CreateCompatibleBitmap(hScreenDC, Width, Height);
 HBITMAP hOldBmap = (HBITMAP)SelectObject(memDC, hBmap);
 BitBlt(memDC, 0, 0, Width, Height, hScreenDC, rect.left+1, rect.top+1, SRCCOPY);
 HBITMAP hNewBmap = (HBITMAP)SelectObject(memDC, hOldBmap);
 If (openclipboard (0)) // open the pasteboard
 {
 Emptyclipboard(); // empty the pasteboard
 SetClipboardData(CF_ Bitmap, hnewbmap); // put the picture in the pasteboard
 Closeclipboard(); // close the pasteboard
 }
}

Code address: http://xiazai.jb51.net/202004/yuanma/CaptureScreen_ jb51.rar

summary

This article about the development of C + + screen capture applet is introduced here. For more content about the development of C + + screen capture applet, please search the previous articles of developer or continue to browse the following related articles. I hope you can support developer more in the future!

Recommended Today

Practice analysis of rust built-in trait: partialeq and EQ

Abstract:Rust uses traits in many places, from simple operator overloading to subtle features like send and sync. This article is shared from Huawei cloud community《Analysis of rust built-in trait: partialeq and EQ》Author: debugzhang Rust uses traits in many places, from simple operator overloading to subtle features like send and sync. Some traits can be automatically […]