The old and new MFC versions implement CEdit transparent 2 methods of the instance code

  • 2020-04-01 21:38:19
  • OfStack

MFC 4.2(Visual Studio 6) is easy to implement, just need to process the WM_CTLCOLOR message in the dialog class, and then the following code can:


HBRUSH CAlphaEditboxDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)  
{ 
    HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); 

    // TODO: Change any attributes of the DC here 
    pDC->SetBkMode(TRANSPARENT); 
    hbr=(HBRUSH)GetStockObject(HOLLOW_BRUSH); 
    // TODO: Return a different brush if the default is not desired 
    return hbr; 
}

Then call Invalidate in the edit control's related event.


void CAlphaEditboxDlg::OnKillfocusEditkey()  
{ 
    // TODO: Add your control notification handler code here 
    Invalidate(); 
} 

void CAlphaEditboxDlg::OnKillfocusEditmessage()  
{ 
    // TODO: Add your control notification handler code here 
    Invalidate(); 
} 

void CAlphaEditboxDlg::OnKillfocusEditpath()  
{ 
    // TODO: Add your control notification handler code here 
    Invalidate(); 
}

Don't forget to redraw the background if you delete characters. Only a few are listed here.

The new MFC is a bit of a hassle because by setting the background to CLR_NONE or the brush to HOLLOW_BRUSH, Microsoft will default to a black background, which is a step backwards. Needless to say, subclassing the edit control is inevitable, so be sure to handle the messages WM_PAINT, WM_CHAR, WM_LBUTTONDOWN, and WM_LBUTTONUP. If you want to remove the border that comes with the edit control, you'll still have to deal with the WM_NCPAINT message, but you won't have to write any code in order to avoid using the default CDialogEx::OnNcPaint() method to draw a border. The following code implements the basic transparent effect, normal input is ok, if you want to implement the delete, check and uncheck function, please append processing WM_LBUTTONDOWN, WM_LBUTTONUP message.


////////////////////////////////////////////////////////////////////////// 
//Draw the window.
////////////////////////////////////////////////////////////////////////// 
void CMyEdit::OnPaint() 
{ 
    PAINTSTRUCT ps; 
    TEXTMETRIC tm; 
    int nSelStart=0,nSelEnd=0,nDrawStart=0,nDrawLen=0,nTxtLen=0; 
    RECT r; 
    CBitmap b; 
    LPTSTR sz=(LPTSTR)calloc(1024,sizeof(TCHAR)); 
    CPaintDC* d2=(CPaintDC*)BeginPaint(&ps); 
    CDC d1; 
    CFont f; 
    CWnd* p=GetParent(); 
    nTxtLen=GetWindowText(sz,1024); 
    b.LoadBitmap(IDB_BITMAP1); 
    d1.CreateCompatibleDC(p->GetDC()); 
    GetWindowRect(&r); 
    p->ScreenToClient(&r); 
    d1.SelectObject(b); 
    d2->BitBlt(0,0,r.right-r.left,r.bottom-r.top,&d1,r.left,r.top,SRCCOPY); 
    f.CreateFontIndirect(&m_lf); 
    d2->SelectObject(f); 
    d2->SetBkMode(TRANSPARENT); 
    d2->GetTextMetrics(&tm); 
    GetSel(nSelStart,nSelEnd); 
    if (r.right-r.left<nTxtLen*tm.tmAveCharWidth) 
    { 
        nDrawStart=0-tm.tmAveCharWidth*nSelStart; 
        nDrawLen=(r.right-r.left)/tm.tmAveCharWidth; 
    } 
    else
    { 
        nDrawStart=0; 
        nDrawLen=nTxtLen; 
    } 
    d2->TextOut(nDrawStart,3,sz,nDrawLen); 
    d2->SelectObject(GetStockObject(NULL_BRUSH)); 
    d2->SelectObject(CreatePen(PS_DOT,1,RGB(255,0,0))); 
    d2->Rectangle(0,0,r.right-r.left,r.bottom-r.top); 
    POINT pt; 
    pt=GetCaretPos(); 
    pt.x=nDrawLen*tm.tmAveCharWidth; 
    SetCaretPos(pt); 
    delete sz; 
    EndPaint(&ps); 
} 

////////////////////////////////////////////////////////////////////////// 
//Do not deal with the sticky key and function key these two cases.
////////////////////////////////////////////////////////////////////////// 
void CMyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{ 
    TEXTMETRIC tm; 
    int nSelStart=0,nSelEnd=0,nDrawStart=0,nDrawLen=0,nTxtLen=0; 
    RECT r; 
    CBitmap b; 
    LPTSTR sz=(LPTSTR)calloc(1024,sizeof(TCHAR)); 
    LPTSTR input=(LPTSTR)calloc(1024,sizeof(TCHAR)); 
    CClientDC d2(this); 
    CDC d1; 
    CFont f; 
    CWnd* p=GetParent(); 
    nTxtLen=GetWindowText(sz,1024); 
    wsprintf(input,L"%c",nChar); 
    lstrcat(sz,input); 
    SetWindowText(sz); 
    b.LoadBitmap(IDB_BITMAP1); 
    d1.CreateCompatibleDC(p->GetDC()); 
    GetWindowRect(&r); 
    p->ScreenToClient(&r); 
    d1.SelectObject(b); 
    d2.BitBlt(0,0,r.right-r.left,r.bottom-r.top,&d1,r.left,r.top,SRCCOPY); 
    f.CreateFontIndirect(&m_lf); 
    d2.SelectObject(f); 
    d2.SetBkMode(TRANSPARENT); 
    d2.GetTextMetrics(&tm); 
    GetSel(nSelStart,nSelEnd); 
    if (r.right-r.left<nTxtLen*tm.tmAveCharWidth) 
    { 
        nDrawStart=0-tm.tmAveCharWidth*nSelStart; 
        nDrawLen=(r.right-r.left)/tm.tmAveCharWidth; 
    } 
    else
    { 
        nDrawStart=0; 
        nDrawLen=nTxtLen; 
    } 
    d2.TextOut(nDrawStart,3,sz,nDrawLen); 
    d2.SelectObject(GetStockObject(NULL_BRUSH)); 
    d2.SelectObject(CreatePen(PS_DOT,1,RGB(255,0,0))); 
    d2.Rectangle(0,0,r.right-r.left,r.bottom-r.top); 
    POINT pt; 
    pt=GetCaretPos(); 
    pt.x=nDrawLen*tm.tmAveCharWidth; 
    SetCaretPos(pt); 
    delete sz; 
    delete input; 
    //CEdit::OnChar(nChar, nRepCnt, nFlags); 
}

That's all, and welcome to the discussion on how to implement the functionality that is not implemented in the notes. I'm a newbie. Please don't laugh at me. I hope you can give me some advice.


Related articles: