Creating a custom dialog in mfc - mfc

I need to create a custom dialog in mfc which has a different appearance than the usual MFC dialogs.For example the color should be blue, the style etc. Is it possible? How can I do this?

I googled the background color:
See
here
//CMyDlg.h
//Add a CBrush object
class CMyDlg : public CDialog
{
// Construction
public:
CTest2Dlg(CWnd* pParent = NULL); // standard constructor
CBrush m_brush;
// Dialog Data
//initialize the brush with the desired color in the OnInitDialog() methodl
BOOL CMyDlg::OnInitDialog()
{
m_brush.CreateSolidBrush(RGB(255,0,0));
CDialog::OnInitDialog();
}
//Return the brush like this:
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Return a different brush if the default is not desired
return m_brush;
}'

Related

MFC CEdit - Painting the Background at a Portion of Length

I would like to have a CEdit control, background-painted half-length or in any other portion of its length.
I have implemented the following code
HBRUSH CMyView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CFormView::OnCtlColor(pDC, pWnd, nCtlColor);
if (nCtlColor == CTLCOLOR_EDIT)
{
if (pWnd->GetDlgCtrlID() == IDC_MY_NORMAL_PERCENT_BOX)
{
// Set the text color to red
pDC->SetTextColor(RGB(255, 0, 0));
CRect rc;
// Get the client area of the edit control
m_CTV_Normal_Percent_Box_Ctrl.GetClientRect(&rc);
m_CTV_Normal_Percent_Box_Ctrl.ScreenToClient(&rc);
// Apply the device context to the client area of the edit control
pDC->Rectangle(0, 0, rc.Width()/2, rc.Height());
// Set the background mode for text to transparent
// so background will show thru.
pDC->SetBkMode(TRANSPARENT);
// Return handle to our CBrush object
hbr = m_brush;
}
}
return hbr;
}
but this could not be achieved. Could anyone possibly assist?
This is what I would like to get
and this is what I get
Thanks in advance.

Do I need to select HBRUSH when replacing background in the edit control?

My goal is to replace a background for the common-control's edit control. My current code does this:
HBITMAP hBmp = ::LoadBitmap(hInstance, MAKEINTRESOURCE(BKGND_ID));
HBRUSH hBkgndBrush = ::CreatePatternBrush(hBmp);
::DeleteObject(hBmp);
HBRUSH CDialog::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() == MY_CTRL_ID && hBkgndBrush)
{
hbr = hBkgndBrush;
//Do I need to select it?
//pDC->SelectObject(hbr); //This line?
pDC->SetBkMode(TRANSPARENT);
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
The question is, do I need to select hbr before returning it? (See commented out line above.) I seem to see it done both ways in different examples online.
EDIT: Also forgot to mention, I override WM_ERASEBKGND as such:
HDC hDc = ::GetDC(hWnd);
if(hDc)
{
RECT rc = {0};
::GetClientRect(hWnd, &rc);
::FillRect(hDc, &rc, hBkgndBrush);
::ReleaseDC(hWnd, hDc);
}
EDIT2: I made a small sample MFC project to illustrate the issue. Basically, when I move the app quickly off the screen and then back, it creates this visual "glitch" but only if control doesn't have ES_MULTILINE style:
When background brush is created from bitmap using CreatePatternBrush, some "repeating artifacts" may occur during dialog resizing or moving.
To remove these artifacts, force the child controls to repaint in response to ON_WM_WINDOWPOSCHANGED message:
void CMyDialog::OnWindowPosChanged(WINDOWPOS *wndpos)
{
CDialog::OnWindowPosChanged(wndpos);
CWnd *wnd = GetWindow(GW_CHILD);
while (wnd)
{
wnd->Invalidate(TRUE);
wnd = wnd->GetWindow(GW_HWNDNEXT);
}
}
or
void CMyDialog::OnWindowPosChanged(WINDOWPOS *wndpos)
{
CDialog::OnWindowPosChanged(wndpos);
edit1.Invalidate(FALSE);
edit2.Invalidate(FALSE);
...
}
OnCtlColor override will be as follows:
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* wnd, UINT nCtlColor)
{
if (nCtlColor == CTLCOLOR_DLG)
return CDialogEx::OnCtlColor(pDC, wnd, nCtlColor);
pDC->SetBkMode(TRANSPARENT);
return hBkgndBrush;
}
You can add other conditions based on wnd or nCtlColor to change the background of edit control only.

CPaneDialog control backgroung (text control)

In my application I have CPaneDialog with controls (e.g. Text control). I try to set background color for this CPanelDialog. For this purpose, I overwrited OnEraseBkgnd
BOOL CBgPaneDialog::OnEraseBkgnd(CDC* pDC)
{
CBrush backBrush(RGB(255, 128, 128));
CBrush* pOldBrush = pDC->SelectObject(&backBrush);
CRect rect;
pDC->GetClipBox(&rect); // Erase the area needed
pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY);
pDC->SelectObject(pOldBrush);
return TRUE;
}
Unfortunately, controls on this CPaneDialog have other background.
http://fotoo.pl//out.php?t=964580_text.png
I overwrot next method: OnCtlColor to set caontrol's backgorund.
HBRUSH CBgPaneDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
CBrush br;
br.CreateSolidBrush(RGB(255,255,255));
HBRUSH hbr = (HBRUSH)br;
CWnd *pCheckBox = GetDlgItem(IDC_STATIC); // put ID of your checkbox here.
int a;
if (*pCheckBox == *pWnd)
{
br.DeleteObject();
br.CreateSolidBrush(a=pDC->SetBkColor(RGB(255, 128, 128)));
hbr = (HBRUSH)br;
}
else
hbr = CPaneDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
The control's background have changed, but not completely. Please see in the picture:
http://fotoo.pl//out.php?i=964579_textcontrol.jpg
How can I change background completely for the text control?
Don't return temporary brush. Your code is okay for OnEraseBkgnd() because it's using the brush, not returning it, but for OnCtlColor use this instead:
class CMyDialog ...
{
COLORREF BkColor;
CBrush BkBrush;
//...
};
CMyDialog::CMyDialog...
{
BkColor = RGB(0, 255, 255);
BkBrush.CreateSolidBrush(BkColor);
}
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
//add conditions...
pDC->SetBkColor(BkColor);
return BkBrush;
}
By the way, you can add mfc tag to your question to get faster answer in future.

Changing the background color of an MFC dialog element

I have an MFC dialog-based program with multiple elements. I'm developing on Windows 7 using VS2010 professional with SP1. I want to change the background color of some of the slider elements (from the CSliderCtrl class). The only thing I've found is to try to override CSliderCtrl's OnCtlColor function. I did this via the following:
class MySlider : public CSliderCtrl
{
public:
MySlider(UINT r, UINT g, UINT b){R=r;G=g;B=b;}
virtual ~MySlider(){}
UINT R;
UINT G;
UINT B;
HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
pDC->SetBkColor(RGB(R, G, B));
return CSliderCtrl::OnCtlColor(pDC, pWnd, nCtlColor);
}
};
Then I replaced all of the CSliderCtrl elements with MySlider elements, and passed in the desired background rgb values to the constructor. However, this did not end up working.
Can someone help me figure out how to properly set the background color of slider elements? (or any other elements for that matter)
Create a brush with the background color and return that HBRUSH to get the color change.
HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
CSliderCtrl::OnCtlColor(pDC, pWnd, nCtlColor);
pDC->SetBkColor(RGB(R, G, B));
static CBrush br(RGB(R, G, B));
return (HBRUSH)br;
}
Override OnPaint and draw a solid rectangle
void MySlider::OnPaint()
{
CPaintDC dc(this); // device context for painting
RECT rect ;
CRect rectButton;
this->GetWindowRect(&rectButton);
COLORREF cr = RGB(60,180,80)
dc.FillSolidRect(&rect, cr); // Background color
// Any other drawing
}

How to change text color in a hotkey using MFC?

The question is like this: define a new class inheritance CHotKeyCtrl, I want to change the text color in hotkey. Using ON_WM_CTLCOLOR_REFLECT,but the test color is not changed.the onctlcolor function cannot run.
MyHotKey.h
class CMyHotKey: public CHotKeyCtrl
{
DECLARE_DYNAMIC(CMyHotKey)
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
};
MyHotKey.cpp
BEGIN_MESSAGE_MAP(CMyHotkey, CHotKeyCtrl)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
HBRUSH CMyHotKey::CtlColor(CDC* pDC, UINT nCtlColor)
{
if(pDC)
{
pDC->SetTextColor(RGB(255,0,0));
pDC->SetBkMode(TRANSPARENT);
}
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
Can anyone suggest what I might be doing wrong?