CEdit bmp background

lwinkenb
lwinkenb used Ask the Experts™
on
I have tiled a bmp image to create a background for my CEdit object.  This works fine, except when text is selected.  The problem is that when the text is unselected the background of where the text selection was is now white instead of my bmp.  I need a solution to this problem.  I have thought of two possible ways to get around this:

1)
Make it so text selection doesnt highlight the background (it only changes the actual text color).

2)
Have the background redraw when the text selection is gone.

The problem is I'm not sure how to implement either of these solutions.

Here is the code I have to place the background bmp.

pDC->SetBkMode(TRANSPARENT);
            CRect rect;
            this->GetWindowRect(&rect);
   
            CDC* pMemDC = new CDC;
            CBitmap*     pBitmap = new CBitmap;


            pBitmap->LoadBitmap(IDB_BITMAP_TEXT);
            pMemDC->CreateCompatibleDC(pDC);
            HBITMAP hBMPDefault = CreateCompatibleBitmap(pDC->m_hDC, rect.Width(), rect.Height());
        SelectObject(pMemDC->m_hDC, hBMPDefault);
            CBitmap*     pOldBitmap = (CBitmap*)pMemDC->SelectObject(pBitmap);

            int cx = 0;
            int cy = 0;
            int nWidth = rect.Width();
            int nHeight = rect.Height();
            BITMAP bm;
            pBitmap->GetBitmap(&bm);
            for (int y=0;y < nHeight; y += bm.bmHeight )
            {
                  for (int x=0;x < 225; x += bm.bmWidth )
                  {
                        if((x+bm.bmWidth) > nWidth)
                              cx = nWidth;
                        else
                              cx = bm.bmWidth;
                        if((y+bm.bmHeight) > nHeight)
                              cy = nHeight;
                        else
                              cy = bm.bmHeight;
                        pDC->BitBlt(x, y, cx, cy, pMemDC, 0, 0, SRCCOPY);
                  }
            }
            pMemDC->SelectObject(pOldBitmap);
            delete pBitmap;
            pMemDC->DeleteDC();
            delete pMemDC;
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
The CEdit required a brush object when painting its DC, create a bitmapped brush and return the brush handler in your dialog's OnCtlColor.

class CAboutDlg : public CDialog
{
public:
      CAboutDlg();
      CBrush m_BrushEdit;
...
}

BOOL CAboutDlg::OnInitDialog()
{
      CDialog::OnInitDialog();
      
      // TODO: Add extra initialization here
      CBitmap BitmapEdit;
      BitmapEdit.LoadBitmap(IDB_IMAGE);
      m_BrushEdit.CreatePatternBrush(&BitmapEdit);

      return TRUE;  // return TRUE unless you set the focus to a control
                    // EXCEPTION: OCX Property Pages should return FALSE
}

HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
      HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
      
      // TODO: Change any attributes of the DC here
      if(pWnd->GetDlgCtrlID()==IDC_EDIT1)
      {
            pDC->SetBkMode(TRANSPARENT);
            pDC->SetTextColor(RGB(255,0,0));
            pDC->SelectObject(&m_BrushEdit);
            hbr=(HBRUSH)m_BrushEdit;
      }

      // TODO: Return a different brush if the default is not desired
      return hbr;
}
Draw the bitmap by mapping WM_ERASEBKGND.

You can map that message to any CWnd derived class using class wizard.
OR
ON_WM_ERASEBKGND() in message map

and declare
afx_msg BOOL OnEraseBkgnd( CDC* pDC );


Rosh :)

Author

Commented:
Roshmon >>
All the code I posted above is already in my OnEraseBackground() method of my CEdit derived class.

I also forgot to mention that the dialog the CEdit control is on is a CDialogBar (not sure if that makes a difference here).

freewell>>
I will give your idea a try.
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

Map EN_UPDATE in the control class itself, here is some code sample


BEGIN_MESSAGE_MAP(CEditTrans, CEdit)
    //{{AFX_MSG_MAP(CEditTrans)
    ON_WM_CTLCOLOR_REFLECT()
    ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
    ON_WM_LBUTTONDOWN()
    ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

HBRUSH CEditTrans::CtlColor(CDC* pDC, UINT nCtlColor)
{
    m_Brush.DeleteObject();

    if (m_BackColor == TRANS_BACK) {
        m_Brush.CreateStockObject(HOLLOW_BRUSH);
        pDC->SetBkMode(TRANSPARENT);
    }
    else {
        m_Brush.CreateSolidBrush(m_BackColor);
        pDC->SetBkColor(m_BackColor);
    }

    pDC->SetTextColor(m_TextColor);

    return (HBRUSH)m_Brush;
}

void CEditTrans::OnUpdate()
{
    UpdateCtrl();
}
void CEditTrans::UpdateCtrl()
{
    CWnd* pParent = GetParent();
    CRect   rect;

    GetWindowRect(rect);
    pParent->ScreenToClient(rect);
    rect.DeflateRect(2, 2);

    pParent->InvalidateRect(rect, FALSE);
}


Rosh :)
And try this link

http://www.codeproject.com/editctrl/ctrltrans.asp - CEdit & CStatic Transparency Control

Good Luck

Author

Commented:
thanks for the comments.

Freewell's code turned out to work perfectly, the highlighting no longer removes the background.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial