Implementation of irregular forms ------ based on MFC DLG

Source: Internet
Author: User

The implementation interface is as follows: (the source code is provided at the end of this Article. If you are writing a technical blog, please criticize and correct it)

 

Implementation process:

1. Create a DLG-based MFC application named tryBGDlg, set the DLG attribute to Title Bar: False, and keep other settings unchanged.
2. Create two images, one of which is a black and white image based on the player's appearance. The white area is the area to be preserved and finally displayed on the desktop. Add the two images to the project. Set the first idnumber to IDB_INTERFACE, and the second idnumber to IDB_MASK.


3. Add a function in the CtryBGDlg class:

// Function Description: cBitmap is the mask location variable to be passed in. Here it refers to the object created by IDB_MASK, and TransColor refers to the RGB value to be set as transparent Prime.
[Cpp]
Void CtryBGDlg: SetupRegion (CDC * pDC, CBitmap & cBitmap, COLORREF TransColor)
{
CDC memDC;
MemDC. CreateCompatibleDC (pDC );
 
CBitmap * pOldMemBmp = NULL;
POldMemBmp = memDC. SelectObject (& cBitmap );
 
BITMAP bit;
CBitmap. GetBitmap (& bit );
 
CRgn crRgn, crRgnTmp;
CrRgn. CreateRectRgn (0, 0, 0, 0); // create an empty area
 
Int iX = 0; int iY = 0;
For (iY = 0; iY <bit. bmHeight; iY ++)
{
Do
{
// Skip over transparent pixels at start of lines.
While (iX <= bit. bmWidth & memDC. GetPixel (iX, iY) = TransColor)
IX ++;
// Remember this pixel
Int iLeftX = iX;
// Now find first non transparent pixel
While (iX <= bit. bmWidth & memDC. GetPixel (iX, iY )! = TransColor)
++ IX;
// Create a temp region on this info
CrRgnTmp. CreateRectRgn (iLeftX, iY, iX, iY + 1 );
// Combine into main region.
CrRgn. CombineRgn (& crRgn, & crRgnTmp, RGN_XOR );
// Delete the temp region for next pass (otherwise you'll get an ASSERT)
CrRgnTmp. DeleteObject ();
} While (iX <bit. bmWidth );
IX = 0;
}
 
Setjavaswrgn (crRgn, TRUE );
 
IX = (GetSystemMetrics (SM_CXSCREEN)-700;
IY = (GetSystemMetrics (SM_CYSCREEN)/2-(bit. bmHeight/2 );
SetWindowPos (& wndTop, iX, iY, bit. bmWidth, bit. bmHeight, NULL );

// Free resources.
MemDC. SelectObject (pOldMemBmp); // Put the original bitmap back (prevents memory leaks)
MemDC. DeleteDC ();
CrRgn. DeleteObject ();
}
4. Add the following code to the BOOL CtryBGDlg: OnInitDialog () function:

[Cpp]
CBitmap bmp;
Bmp. LoadBitmapW (IDB_MASK );
This-> SetupRegion (this-> GetWindowDC (), bmp, RGB (0, 0 ));
5. Add a message response to WM_ERASEBKGND and add the following code in the BOOL CtryBGDlg: OnEraseBkgnd (CDC * pDC) function:

[Cpp]
BOOL CtryBGDlg: OnEraseBkgnd (CDC * pDC)
{
// TODO: add the message processing program code and/or call the default value here
CRect rect;
This-> GetWindowRect (& rect );
 
CDC memDC;
CBitmap bmp;
CBitmap * pOldBmp = NULL;
 
Bmp. LoadBitmapW (IDB_INTERFACE );
MemDC. CreateCompatibleDC (pDC );
POldBmp = memDC. SelectObject (& bmp );
 
PDC-> BitBlt (0, 0, rect. Width (), rect. Height (), & memDC, 0, 0, SRCCOPY );
 
 
If (pOldBmp)
{
MemDC. SelectObject (pOldBmp );
}
Return true;
 
// Return CDialog: OnEraseBkgnd (pDC );
}
This allows you to create irregular forms. The created view is shown at the beginning.

6. Generally, we also need to perform the operation on the form. The implementation method is as follows:

Add a response to the WM_NCHITTEST message and add the following code in the generated LRESULT CtryBGDlg: OnNcHitTest (CPoint point) function:
 
LRESULT CtryBGDlg: OnNcHitTest (CPoint point)
{
// TODO: add the message processing program code and/or call the default value here
CRect rc;
GetClientRect (& rc );
ClientToScreen (& rc );
Return rc. PtInRect (point )? HTCAPTION: CDialog: OnNcHitTest (point );
// Return CDialog: OnNcHitTest (point );
}
So far, it is fully implemented. The creation of irregular forms and the response to the form-initiated messages are complete.


The following describes the implementation principles and code analysis in detail:
General principle: the principle of this program is to first use the IDB_MASK image to calculate the outline of the form to be set, and then use the setw.wrgn () function to change it. Finally, the WM_ERASEBKGND message is returned when the window is weighed, and the IDB_INTERFACE of the form background image is pasted to the form.

 

The principle of using the IDB_MASK image to calculate the form profile is as follows:

The code for calculating the form outline is mainly implemented by the SetupRegion () function. Considering the irregular form, mask bitmap should be used to describe it. For this example, the white area is the contour area of the irregular form to be retained. This Code uses crRgn first. createRectRgn (0, 0, 0, 0) creates an empty area, and then enumerates the pixel information of the IDB_MASK image in a column, it is calculated that no transparent area is set in each column and then merged with crRgn. Therefore, the final crRgn is the area to be set.

The core code is:

[Cpp]
CRgn crRgn, crRgnTmp;
// Create an empty region
CrRgn. CreateRectRgn (0, 0, 0, 0 );
 
Int iX = 0; int iY = 0;
For (iY = 0; iY <bit. bmHeight; iY ++)
{
Do
{
// Skip over transparent pixels at start of lines.
// In the unit of a prime column, locate the first vertex iX that is not set to transparent prime in this prime column.
// Then find the starting point of this iX. In this prime column, the last vertex nearest to him is not transparent.
// Merge them into crRgn.
While (iX <= bit. bmWidth & memDC. GetPixel (iX, iY) = TransColor)
IX ++; // In the column iY and iY + 1, the X coordinate of the first vertex is not transparent.
Int iLeftX = iX; // Save the coordinates of the vertex
While (iX <= bit. bmWidth & memDC. GetPixel (iX, iY )! = TransColor)
+ + IX; // This is the X coordinate that finds the opacity nearest to iX.
CrRgnTmp. CreateRectRgn (iLeftX, iY, iX, iY + 1); // these four points are the just-found opaque areas.
// Merge Region
CrRgn. CombineRgn (& crRgn, & crRgnTmp, RGN_OR );
// Remember to manually delete the crRgnTmp object
CrRgnTmp. DeleteObject ();
} While (iX <bit. bmWidth); // If iX does not reach the end of the image, it indicates that this row has not been enumerated, then perform the next round of // enumeration on the line iY and iY + 1.
IX = 0;
}

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.