mfc realizes background color gradient of a dialog box
If it is a single document view structure, the code is implemented in OnDraw, and if it is a dialog structure, the OnPain function in the cpp where the dialog box is located (if not, please derive from the class wizard) can implement the following code. This example is implemented in the dialog structure, a dialog box, and the effect is as follows
CPaintDC dc(this); // device context for painting CRect Rect; GetClientRect(Rect); CRect rectClient; CDC dcMen, dcBkgnd; CBitmap bitmapTemp, *pOldBitmap; GetClientRect(&rectClient); bitmapTemp.CreateCompatibleBitmap(&dc, rectClient.Width(), rectClient.Height()); dcMen.CreateCompatibleDC(&dc); pOldBitmap = dcMen.SelectObject(&bitmapTemp); /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Main code @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ int r1=217,g1=236,b1=235; int r2=255,g2=255,b2=235; for (int i=0;i<rectClient.Width();i++) { int r,g,b; r=r1+(i*(r2-r1))/rectClient.Width(); g=g1+(i*(g2-g1))/rectClient.Width(); b=b1+(i*(b2-b1))/rectClient.Width(); dcMen.FillSolidRect(i,0,1,rectClient.Height(),RGB(r,g,b)); } /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ dc.BitBlt(0, 0, rectClient.Width(), rectClient.Height(), &dcMen, 0, 0, SRCCOPY);//Draw pictures to main DC dcMen.SelectObject(pOldBitmap);//Memory reset bitmapTemp.DeleteObject();
Above is the horizontal gradient. Longitudinal gradient only needs to modify several parameters, such as:
int r1=217,g1=236,b1=235; int r2=255,g2=255,b2=235; for (int i=0;i<rectClient.Height();i++) { int r,g,b; r=r1+(i*(r2-r1))/rectClient.Height(); g=g1+(i*(g2-g1))/rectClient.Height(); b=b1+(i*(b2-b1))/rectClient.Height(); dcMen.FillSolidRect(0,i,rectClient.Width(),1,RGB(r,g,b)); }
When background images are added to the MFC dialog box, it will cause shadows around the control, which is very beautiful. Therefore, we need to transparent the shadows. At this point, you need to use the message function OnCtlColor() in MFC.
HBRUSH CCPPDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); //< TODO: Change any features of DC here if(nCtlColor == CTLCOLOR_STATIC ) { pDC->SetBkMode(TRANSPARENT);//Setting Background Transparency pDC->SetTextColor(RGB(0,0,0)); hbr=(HBRUSH)::GetStockObject(NULL_BRUSH); } //< TODO: If the default is not the required brush, return another brush return hbr; }
Note that if other check radio s and other controls need background coloring, the code needs to be placed at the front of the function, and the interface property Clip Children property needs to be set to false, otherwise the transparency effect will be invalid.
In addition, when the static control is set to a transparent background, updating the text on the static file will cause text overlap. There are the following solutions
//Scenario 1: CRect rc; GetDlgItem(IDC_STATIC_APPINFO)->GetWindowRect(&rc); ScreenToClient(&rc); InvalidateRect(&rc); SetDlgItemText(IDC_STATIC_APPINFO,str); //Option two GetDlgItem(IDC_STATIC_APPINFO)->ShowWindow(SW_HIDE); SetDlgItemText(IDC_STATIC_APPINFO,str); GetDlgItem(IDC_STATIC_APPINFO)->ShowWindow(SW_SHOW);
Explanation: Although the above methods can solve the problem of text overlap, it will bring the problem of flicker. If not frequent and fast refresh is enough, otherwise it needs to be solved by self-drawing control.
But the above can not handle the background of radio buttons and check boxes, you need to add the following code
HBRUSH CCPPDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); //< TODO: Change any features of DC here UINT id = pWnd->GetDlgCtrlID(); if(id == IDC_RADIO_EXPMODE||IDC_RADIO_TRAINMODE||IDC_CHECK_TRACK||IDC_CHECK_SCENE||IDC_EXIT_BUTTON||IDC_MIN_BUTTON) { pDC->SetBkMode(TRANSPARENT); CRect rc; pWnd->GetWindowRect(&rc); ScreenToClient(&rc); CDC* dc = GetDC(); pDC->BitBlt(0,0,rc.Width(),rc.Height(),dc,rc.left,rc.top,SRCCOPY); //Draw the background picture of the parent window onto the button first ReleaseDC(dc); hbr = (HBRUSH) ::GetStockObject(NULL_BRUSH); } //< TODO: If the default is not the required brush, return another brush return hbr; }
Design sketch:
The background of RADIO control is not transparent in the figure. When the above method has been tested, it is effective.