Windows GDI-based screen recording software authoring process

Source: Internet
Author: User

I know, the headline is not loud, you're not going to come in here. (smirking), well, the blogger has always wanted to write a screen video software, I believe everyone has used screen video software, professional-level or business-level screen recording software is their own write drive to obtain video card data, or write hooks To hook up some graphics functions to obtain graphics data and so on, but Bo Master does not have this ability, the only thing that can be used is the GDI function of Windows, have seen a game development related books, which explains how to use the GetDIBits function to quickly obtain the color data in the HDC, compared to GetPixel fast hundreds of orders of magnitude more than, Bo master a flash, then it means that as long as I can get arbitrary form of HDC, you can use GetDIBits to get the color data of the form, based on this idea, Bo Master began to implement this screen video software, of course, the practice of real knowledge, The end result was a surprise-I succeeded!! I obtained the color data of the target form, then saved to the file, then through some code to replay the video, and then realized a simple screen recording software, Next, let us look at the entire software implementation process.

First, let's take a look at the technical points involved in the whole screen recording software, and then implement them one by one:

1. How to get information about all windows, including: Handle, HDC, title, style, form size, customer area size, etc.

2. How to quickly get color data from the HDC inside the target form

3. How to quickly draw color data to the preview area

4. How to save the color data to a file and replay the video

OK, next we have a problem to solve, the first is the first, to get the information of all windows, this is very simple, with the EnumWindows function can be, the concrete implementation is as follows:

1 //2 //form Information3 //4 structWindow_info5 {6 HWND handle;7 DWORD style;8 DWORD style_ex;9 RECT rect_client;Ten RECT Rect_window; One CORE::STRINGW title; A Core::stringw class_name; - }; -  theUnsignedintEnumwindow (core::list< window_info > &window_list) - { -EnumWindows (EnumThreadWndProc, (LPARAM) &window_list); -  +     returnwindow_list.size (); - } +  A BOOL CALLBACK EnumThreadWndProc (HWND hwnd, LPARAM LPARAM) at { -Window_info WI = {0 }; -core::list< window_info > * window_list = (core::list< window_info > *) lparam; -  -Wi.handle =hwnd; -Wi.style =GetWindowLong (hwnd, gwl_style); inWI.STYLE_EX =GetWindowLong (hwnd, gwl_exstyle); -  toWi.title.alloc (1024x768,true ); +GETWINDOWTEXTW (hwnd, Wi.title.getBuffer (),1024x768 ); -  theWi.class_name.alloc (1024x768,true ); *Getclassnamew (hwnd, Wi.class_name.getBuffer (),1024x768 ); $ Panax NotoginsengGetClientRect (hwnd, &wi.rect_client); -GetWindowRect (hwnd, &Wi.rect_window); the  +     if(window_list) window_list->Pushtail (WI); A  the     returnTRUE; +}

In the code above, the WINDOW_INFO structure contains some of the necessary information about the form, and you can, of course, expand the structure yourself, such as HDC, the list of child controls, and so on.

The Enumwindow () function calls the EnumWindows () function of Windows, and then whenever a form is discovered, a enumthreadwndproc () callback function is called, and the handle of the form is passed in as a parameter, We can be based on this form handle to get form data, in this example, I use a list linked list to save all forms of information, this list is my own writing, so and STL std::list must have a big discrepancy, we do not have to tangle, know is linked list on it;

Next is how to get the color data of the target form, assuming we want to record the desktop, then get the HWND handle of the desktop is the GetDesktopWindow () function, then use GetDC () or GETWINDOWDC () can get the desktop HDC, next Is the point--using the GetDIBits () function to quickly get the color data from the desktop HDC;

A quick way to get the color data of a desktop DC is to create an HDC that is compatible with the desktop, called a compatible DC, creates a bitmap object that is compatible with a compatible DC, is called a compatible bitmap, the compatible bitmap is selected into a compatible DC, and then the contents of the desktop DC are BitBlt () function quickly transferred to a compatible DC, and then through the GetDIBits () function from the compatible DC to obtain color data, these color data is actually the desktop color data, said so much, or directly on the code to intuitive:

1 structcapture_info_internal2 {3 HDC dlg_dc;4 HWND Target_wnd;5 HDC target_dc;6 HDC comp_dc;7 hbitmap comp_bmp;8 hbitmap old_bmp;9     intwidth;Ten     intheight; One bitmapinfo Bmp_info; ABYTE *buf; - }; -  the BOOLPrepareforrecord (Capture_info_internal &CII) - { -Bitmapinfo bi = {0 }; -  +Cii.width =int(wi->rect_client.right-wi->rect_client.left); -Cii.height =int(wi->rect_client.bottom-wi->rect_client.top); +  ACii.target_wnd = wi->handle; at     if(NULL = =Cii.target_wnd) -         return false; -  -CII.TARGET_DC =GetDC (cii.target_wnd); -     if(NULL = =cii.target_dc) -         return false; in  -CII.COMP_DC =CreateCompatibleDC (CII.TARGET_DC); to     if(NULL = =cii.comp_dc) +         return false; -  theCii.comp_bmp =CreateCompatibleBitmap ( * CII.TARGET_DC, $ Cii.width,Panax Notoginseng cii.height); -     if(NULL = =cii.comp_bmp) the         return false; +  ACii.old_bmp =(HBITMAP) SelectObject ( the CII.COMP_DC, + cii.comp_bmp); -  $Cii.bmp_info.bmiHeader.biSize =sizeof(bitmapinfoheader); $Cii.bmp_info.bmiHeader.biBitCount = -; -Cii.bmp_info.bmiHeader.biCompression =Bi_rgb; -Cii.bmp_info.bmiHeader.biWidth =Cii.width; theCii.bmp_info.bmiHeader.biHeight =-Cii.height; -Cii.bmp_info.bmiHeader.biPlanes =1;Wuyi  thecii.bmp_info.bmicolors[0].rgbblue =8; -cii.bmp_info.bmicolors[0].rgbgreen =8; Wucii.bmp_info.bmicolors[0].rgbred =8; -cii.bmp_info.bmicolors[0].rgbreserved =0; About  $Bi.bmiHeader.biSize =sizeof(bitmapinfoheader); -Bi.bmiHeader.biBitCount = -; -Bi.bmiHeader.biCompression =Bi_rgb; -Bi.bmiHeader.biWidth =Cii.width; ABi.bmiHeader.biHeight =-Cii.height; +Bi.bmiHeader.biPlanes =1; the  -bi.bmicolors[0].rgbblue =8; $bi.bmicolors[0].rgbgreen =8; thebi.bmicolors[0].rgbred =8; thebi.bmicolors[0].rgbreserved =0; the  theGetDIBits (CII.COMP_DC, Cii.comp_bmp,0, Cii.height, NULL, &Bi, dib_rgb_colors); -  inCii.buf =Newbyte[Bi.bmiHeader.biSizeImage]; the  the     return true; About}

in the above code, the capture_info_internal struct is used to hold some necessary variables, and the WI variable holds a window_info form information structure, which I have already explained in the section of the enumeration form. The Prepareforrecord () function is used to initialize the capture_info_internal struct, and then I get the color data in the timer callback function, see the following code:

1 voidOnTimer (Capture_info_internal &CII)2 {3 BitBlt (4 PREVIEW_INFO.COMP_DC,5         0,6         0,7 Preview_info.width,8 Preview_info.height,9 PREVIEW_INFO.TARGET_DC,Ten         0, One         0, A srccopy); -  - GetDIBits ( the PREVIEW_INFO.COMP_DC, - Preview_info.comp_bmp, -         0, - Preview_info.height, + Preview_info.buf, -&Preview_info.bmp_info, + dib_rgb_colors); A}

Yes, it's that simple, just need two GDI functions can get to the desktop color data, where CII is a capture_info_internal structure, BitBlt () function is responsible for the desktop DC color data transfer to a compatible DC, and then GetDIBits () function negative Responsible for the color data from the compatible DC to take out, such as a one-time data transmission and data acquisition, compared to the use of GetPixel () and SetPixel () quickly do not know how many times, using this technique, even can be used to make some simple 2D games, performance is almost comparable to Dire Ctdraw!!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.