ExcludeClipRect and non-blinking Image

Source: Internet
Author: User

Chapter I: ExcludeClipRect exclude a rectangle in a cut area. As a result, this rectangle is not drawn when the cut area is drawn. for details about the ExcludeClipRect function, see MSDN. This function is used to exclude a part of a region and is often used to draw pictures. For example, you can draw an image in the customer area of a window, as shown in the following code:

 
 
  1. Case WM_PAINT:
  2. {
  3. Hdc = BeginPaint (hWnd, & ps );
  4. RECT rc = {0 };
  5. GetClientRect (hWnd, & rc );
  6. HDC hMemDC = CreateCompatibleDC (ps. hdc );
  7. SelectObject (hMemDC, g_hBmpAllWstDskWallpaper); // select a bitmap
  8.  
  9. // ExcludeClipRect (ps. hdc, 200,100,); // exclude some regions. A line
  10. BitBlt (ps. hdc, 300,200, hMemDC, SRCCOPY );
  11. DeleteDC (hMemDC );
  12. EndPaint (hWnd, & ps );
  13. }
This Code creates a bitmap in the client area of the window. but pay attention to line A, which is commented out, and then removed from the comment, run the program again, you can see that although this bitmap is still drawn in the customer area of the window, however, the rectangle area {0, 0,200,100} still displays the background color of the window. In other words, the bitmap is missing. this is because ExcludeClipRect removes the {0, 0,200,100} rectangle from the cut area of the window, so that GDI will not draw this rectangular area. the Chaper II: ExcludeClipRect function does not release the excluded rectangular area. Change Row A in Chapter I code:
 
 
  1. BOOL g_bCall = TRUE; // global variable.
  2. If (g_bCall)
  3. {
  4. G_bCall = FALSE;
  5. ExcludeClipRect (ps. hdc, 200,100,); // exclude some regions and call. A line only once.
  6. }
Run the program again and change the window size. We can find that the rectangle area {0, 0,200,100} of the customer area is never drawn. it can be seen that once this function is called, the rectangular area excluded by this function will never be drawn on the DC. Is there any way to restore the area? In fact, it is very simple. Just "retrieve" the rectangular area that has been "Exclude. the method is that the program creates another cut area, so that its size and location are the same as the previous "Exclude", and then calls ExtSelectClipRgn. Note that the last parameter must use RGN_OR, this indicates merging two cut regions. this is equivalent to retrieving the rectangular area of the "Exclude. the following code is used:
 
 
  1. # Define RECT_WIDTH (rt) (rt. right-rt.left)
  2. # Define RECT_HEIGHT (rt) (rt. bottom-rt.top)
  3. RECT g_rcExclud = {0 };
  4. BOOL g_bCancelExcludeRect = FALSE;
  5. Case WM_PAINT:
  6. {
  7. Hdc = BeginPaint (hWnd, & ps );
  8. RECT rc = {0 };
  9. GetClientRect (hWnd, & rc );
  10. HDC hMemDC = CreateCompatibleDC (ps. hdc );
  11. SelectObject (hMemDC, g_hBmpAllWstDskWallpaper); // select a bitmap
  12.  
  13. // The "exclud" drop area is in the lower right corner.
  14. G_rcExclud.left = rc. right-200;
  15. G_rcExclud.top = rc. bottomtom-100;
  16. G_rcExclud.right = rc. right;
  17. G_rcExclud.bottom = rc. bottom;
  18.  
  19. HRGN hrgn = NULL; // fill the last "exclud" drop area back.
  20. If (g_bCancelExcludeRect & RECT_WIDTH (g_rcExclud) & RECT_HEIGHT (g_rcExclud ))
  21. {
  22. Hrgn = CreateRectRgn (g_rcExclud.left, g_rcExclud.top, g_rcExclud.right, g_rcExclud.bottom );
  23. ExtSelectClipRgn (ps. hdc, hrgn, RGN_OR );
  24. FillRect (ps. hdc, & g_rcExclud, (HBRUSH) GetStockObject (COLOR_WINDOW); // erase the area of the last drawn image.
  25. }
  26.  
  27. (! G_bCancelExcludeRect) // "exclud" Drop the area in the lower right corner of the window.
  28. ExcludeClipRect (ps. hdc, g_rcExclud.left, g_rcExclud.top, RECT_WIDTH (g_rcExclud), RECT_HEIGHT (g_rcExclud ));
  29. BitBlt (ps. hdc, 400,300, hMemDC, SRCCOPY); // draw a bitmap in the lower right corner.
  30.  
  31. DeleteDC (hMemDC );
  32. If (hrgn! = NULL) DeleteObject (hrgn );
  33. EndPaint (hWnd, & ps );
  34. }
Chapter III: Using ExcludeClipRect to achieve non-blinking images some netizens wrote related articles: http://dev.10086.cn/cmdn/wiki/index.php? Edition-view-6349-1.html this article some good, but there is still a problem, that is, Chapter II mentioned ExcludeClipRect will not release the "exclude" drop area, in this way, if the location of the bitmap changes due to the size of the window, the "exclude" area will not be erased by the background. in addition, this article still does not clarify clearly, that is, the solution to image flickering is that the background of the window does not need to be erased, while the foreground view of the window is drawn, and the image area is drawn using a bitmap, other areas are drawn with the background color of the window, which is equivalent to sticking the canvas with a hole (this part is the image, and the other part is drawn with the background color) to the window, so that no overlap is drawn, the modified code is as follows:
 
 
  1. Case WM_PAINT:
  2. {
  3. Hdc = BeginPaint (hWnd, & ps );
  4. RECT rc = {0 };
  5. GetClientRect (hWnd, & rc );
  6.  
  7. HDC hMemDC = CreateCompatibleDC (ps. hdc );
  8. SelectObject (hMemDC, g_hBmpAllWstDskWallpaper );
  9.  
  10. HRGN hrgn = NULL;
  11. If (RECT_WIDTH (g_rcExclud) & RECT_HEIGHT (g_rcExclud ))
  12. {
  13. Hrgn = CreateRectRgn (g_rcExclud.left, g_rcExclud.top, g_rcExclud.right, g_rcExclud.bottom );
  14. ExtSelectClipRgn (ps. hdc, hrgn, RGN_OR); // restore the region that was "excude" last time. required. Otherwise, this part will not be drawn.
  15. FillRect (ps. hdc, & g_rcExclud, (HBRUSH) GetStockObject (COLOR_WINDOW); // erase the area of the last drawn image.
  16. }
  17.  
  18. G_rcExclud.left = rc. right-300;
  19. G_rcExclud.top = rc. bottomtom-200;
  20. G_rcExclud.right = rc. right;
  21. G_rcExclud.bottom = rc. bottom;
  22.  
  23. BitBlt (ps. hdc, g_rcExclud.left, g_rcExclud.top, g_rcExclud.right-g_rcExclud.left, g_rcExclud.bottom-g_rcExclud.top, hMemDC, SRCCOPY );
  24. ExcludeClipRect (ps. hdc, g_rcExclud.left, g_rcExclud.top, g_rcExclud.right, g_rcExclud.bottom); // exclude the region occupied by the image
  25. FillRect (ps. hdc, & rc, (HBRUSH) GetStockObject (COLOR_WINDOW); // draw other regions with the background color of the window.
  26.  
  27. DeleteObject (hrgn );
  28. DeleteDC (hMemDC); // releases the memory device Environment
  29. EndPaint (hWnd, & ps );
  30. Return 0;
  31. }
  32. Break;
  33. Case WM_SIZE:
  34. InvalidateRect (hWnd, NULL, FALSE); // The last parameter is FALSE, indicating that the background is not erased.
  35. Break;
Finally, change the window size and observe the image, which is always in the lower right corner of the window, and the image does not flash any more.

 

This article from the "zero one small building" blog, please be sure to keep this source http://jetyi.blog.51cto.com/1460128/642401

Related Article

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.