So I have this excellent answer that explains how to set the background colour to a CMFCBrowseEditCtrl when it is in focus:
https://stackoverflow.com/a/36394562/2287576
class cmfc_edit : public CMFCEditBrowseCtrl
{
public:
COLORREF bkcolor;
CBrush brush;
void setBrushColor(COLORREF clr)
{
bkcolor = clr;
brush.DeleteObject();
brush.CreateSolidBrush(clr);
}
HBRUSH CtlColor(CDC* pDC, UINT)
{
if (!brush.GetSafeHandle())
return GetSysColorBrush(COLOR_WINDOW);
pDC->SetBkColor(bkcolor);
return brush;
}
//optional, change color on focus change
void OnSetFocus(CWnd* w)
{
setBrushColor(RGB(255, 0, 0));
CMFCEditBrowseCtrl::OnSetFocus(w);
}
void OnKillFocus(CWnd* w)
{
setBrushColor(RGB(255, 255, 255));
CMFCEditBrowseCtrl::OnKillFocus(w);
}
DECLARE_MESSAGE_MAP()
};
It works fine and I have no issues with it. The only problem is when I invoke a popup window. Since the popup window now has focus the background highlight I had set is being reset to the default. Is it possible to retain the requested background even when a popup window is displayed?
So, I only want my edit control to have a yellow background when it has focus, and retain this background whilst a popup window is activated. The yellow should also go when I move to another control on the dialog.
Is this possible?
This works:
void CChristianLifeMinistryStudentEdit::OnKillFocus(CWnd* pNewWnd)
{
if(GetParent()->IsChild(pNewWnd))
SetBrushColour(GetSysColor(COLOR_WINDOW));
CMFCEditBrowseCtrl::OnKillFocus(pNewWnd);
}
Related
I have the color picked from my CMFCColorButton and now I want to set it to the background (if it's not already the current color).
I can't seem to figure out how, so I would really appreciate your help and explanation.
void CMainFrame::OnColor()
{
// m_TextColors is the ID of the color button I created in the resource editor.
CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST(CMFCRibbonColorButton, m_wndRibbonBar.FindByID(m_TextColors));
COLORREF color = pColorBtn->GetColor();
CWnd* pwndParent = this->GetParent();
CRect rcClient;
pwndParent->GetClientRect(&rcClient);
if (color != GetSysColor(COLOR_BACKGROUND)) {
CBrush brush;
CClientDC dc(this);
brush.CreateSolidBrush(color);
dc.FillRect(rcClient, &brush);
}
else {
MessageBox(_T("Same Color."), MB_OK);
}
}
I made some changes:
void CMainFrame::OnColor()
{
// m_TextColors is the ID of the color button I created in the resource editor.
CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST(CMFCRibbonColorButton, m_wndRibbonBar.FindByID(m_TextColors));
COLORREF color = pColorBtn->GetColor();
CBrush brush;
brush.CreateSolidBrush(color);
CRect rc;
GetClientRect(&rc);
GetWindowRect(&rc);
CClientDC dc(this);
dc.SelectObject(&rc);
if (color != GetSysColor(COLOR_WINDOW)) {
dc.FillRect(rc, &brush);
} else {
MessageBox(_T("Same Color."), MB_OK);
}
}
And this is the result:
It's tracing the document's color but not changing it, it's changing the whole window's color.
Update: I've tried the invalidateRect function, this is the result:
It seems like it's adding color on top of my MDI client area not in it in the background like i intended,
Have you tried:
void CMainFrame::OnButColor()
{
HBRUSH hBrush=CreateSolidBrush(RGB(0,0,255));
SetClassLong(m_hWndMDIClient, BGCL_HBRBACKGROUND,(LONG)hBrush);
::InvalidateRect(m_hWndMDIClient,0,TRUE);
}
I created a property sheet inside dialog. But the property sheet is appearing in white background color by default. I want the property sheet in same background color as the dialog on which it is placed. Thanks.
You have to implement the message event OnEraseBkgnd an your CPropertyPage
class CMyPage : public CPropertyPage
{
public:
DECLARE_MESSAGE_MAP()
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
}
Add the application framework message event to your message loop:
BEGIN_MESSAGE_MAP(CMyPage, CPropertyPage)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
Finally implement the message event method. The implementation of the method makes use of
GetSysColor, CDC::FillSolidRect
and CDC::GetClipBox:
BOOL CMyPage::OnEraseBkgnd( CDC *pDC )
{
// get the background color
COLORREF bkCol = ::GetSysColor(COLOR_MENU);
// get the area you have to fill
CRect rect;
pDC->GetClipBox(&rect);
// fill the rectangular area with the color
pdC->FillSolidRect(&rect, bkCol);
}
This is covered on the internet already from what I can see.
For example:
http://forums.codeguru.com/showthread.php?235997-CPropertySheet-color
To change the background color of a window you can use CWnd::OnEraseBkgnd(). You can use the passed CDC object to paint the background to any color.
I am working in an MFC windows application. I am using check boxes in Check List Box control (CCheckListBox class) . While disabling a check box, its color remains gray. Is there any way to change the background color from gray to another color?
You can use the DrawItem method to control the rendering of the control and its list items. To do that, you’ll want to derive your own CCheckListBox class and implement that method. For example, I’ve changed the second item in the list to red.
The sample code to do that looks like…
void MyCheckListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
UINT index = lpDrawItemStruct->itemID;
CDC *pDC = CDC::FromHandle (lpDrawItemStruct->hDC);
if (index == 1)
{
CRect rect = lpDrawItemStruct->rcItem;
pDC->FillSolidRect(&rect, RGB(255, 0, 0));
}
CString str;
GetText(index, str);
pDC->DrawText(str, &lpDrawItemStruct->rcItem, DT_LEFT | DT_VCENTER);
}
The above sample only changes the item’s background color. I’ve left the rest of the processing and any extra rendering up to you.
#rrirower's implementation will work but his code needs some modifications.
(1) Changing the Back ground color of the disabled check Box
void CMyCheckListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc;
dc.Attach(lpDrawItemStruct ->hDC);
RECT rect = lpDrawItemStruct ->rcItem;
UINT nId=lpDrawItemStruct->itemID;
CString strItemText;
GetText(lpDrawItemStruct ->itemID, strItemText);
if(nId==1 ||nId==3){
dc.FillSolidRect(&rect,RGB(255,0,0));
dc.DrawText(strItemText , &rect, DT_LEFT | DT_VCENTER);
}
else{
CCheckListBox::DrawItem(lpDrawItemStruct);
}
dc.Detach();
}
(2) Changing the Disabled check list box text color
replace dc.FillSolidRect(&rect,RGB(255,0,0)); with dc.SetTextColor(RGB(255,0,0));
I've tried this in several ways. Deriving an object from CBCGPRibbonButton (same as CMFCRibbonButton) and using GetRect() from within the class, and having a click event find the button in the ribbon and get the rect.
What happens is that the rect is relative to the window that it is in. But if the panel is collapsed, then the window it is in is not the ribbon bar so it gets the wrong location.
I need a way of getting the location relative to the ribbon bar. Any ideas?
Ok, so I was trying to figure out what the rect was for the button:
When the panel had collapsed:
This is my solution:
class CMyButton : public CBCGPRibbonButton
{
DECLARE_DYNCREATE(CHeaderFooter)
public:
CMyButton()
{
};
CMyButton(
UINT nID,
LPCTSTR lpszText,
int nSmallImageIndex = -1,
int nLargeImageIndex = -1,
BOOL bAlwaysShowDescription = FALSE)
: CBCGPRibbonButton(nID, lpszText, nSmallImageIndex, nLargeImageIndex, bAlwaysShowDescription)
{
}
BOOL HasMenu() const override
{
return true;
}
CWnd* GetButtonWnd() const
{
CBCGPBaseRibbonElement* pDroppedDown = m_pParent->GetDroppedDown();
CWnd* pWnd;
if (pDroppedDown) // Was popup opened from a collapsed panel from the ribbon?
{
pWnd = pDroppedDown->GetPopupMenu()->GetMenuBar();
}
else
{
pWnd = m_pParent->GetParentRibbonBar();
}
return pWnd;
}
void OnShowPopupMenu() override
{
CRect rect = GetRect();
// pt is the bottom left corner of button relative to the window that
// it is contained in.
CPoint pt(rect.left, rect.bottom);
GetButtonWnd()->ClientToScreen(&pt); // convert pt to screen coordinates
... // do other stuff with that point
}
};
IMPLEMENT_DYNCREATE(CHeaderFooter, CBCGPRibbonButton)
which determines the CWnd that the button is part of so that the rect can be converted correctly to screen coordinates.
Calculate in screen coords.
Get the button rectangle from he ribbon. Use ClientToScreen and you have your screen coordinates now use your buttons parent handle with ScreenToClient and you have the cords relative to the ribbon bar.
PS: Even I don't know why to show a button when the ribbon is collapsed.
I am using win32 c++ ,So I want to create dialog, "Message Box, Color Dialog" and it works but the problem I had that when I call that dialog it won't be shown till minimize the parent window and the maximize it again. here is a simple of color dialog
COLORREF choseColor()
{
CHOOSECOLOR color;
COLORREF ccref[16];
COLORREF selcolor=0x000000;
memset(&color,0,sizeof(color));
color.lStructSize=sizeof(CHOOSECOLOR);
color.hwndOwner=NULL;
color.lpCustColors=ccref;
color.rgbResult=selcolor;
color.Flags=CC_RGBINIT;
if(ChooseColor(&color))
{
selcolor=color.rgbResult;
}
return selcolor;
}