CPropertySheet and CPropertyPages are appear in white color - mfc

I have created a simple propertySheet(CPropertySheet) and a couple of CPropertyPage derived classes.
While running the application, the ProperySheet, Page and tabs are appeared in white color.
I was expecting them to be like normal widow dialog color.
Any clue to make the property sheet, pages background to be like other normal MFC dialogs appears?
I use Visual Studio 2008 MFC without .NET CLR.

What do you mean 'system color'? Grey (COLOR_BTNFACE) ? What OS are you on? If XP the property sheet should be in COLOR_BTNFACE , Vista/Win7 I don't know what the proper color is. If you don't do anything special, they will show in the system default colors.

This is a MFC bug. Use the spy++ monitor your app, you will find your app receives many WM_GETDLGCODE message, and seems enter a dead loop. Yeah, that is the problem.
Microsoft had post a PRB for the problem. please view:PRB: Child CPropertySheet Hangs If Focus Is Switched
In short, add WS_EX_CONTROLPARENT style to your PropertySheet.
BOOL CMySheet::OnInitDialog()
{
ModifyStyleEx (0, WS_EX_CONTROLPARENT);
return CPropertySheet::OnInitDialog();
}

Process the WM_CTLCOLORDLG message.
case WM_CTLCOLORDLG:
{
HDC hdc = (HDC)wParam;
COLORREF color = GetSysColor(COLOR_3DFACE);
SetBkColor(hdc, color);
static HBRUSH brush = CreateSolidBrush(color);
return (BOOL)brush;
}

Related

StaticText background in TabControl... What events should be processed?

I am rewiting the older application to get the modern look in Windows 7. The GUI elements are created and moved via the explicit code (no special layout manager). Because of some historic reasons, the GUI events were not processed the standard way. They were redirected. It is rather difficult to track them, especially when I do not know what should I focus for.
Here is the example of the window that should be polished. It is not a dialog. It is classical, sizable window placed on the top. However, it should mimic the dialog look. The window uses WTL::CTabControlT<CControl> where the CControl is my class based on the ATL::CWindow -- see the picture first:
It man not be well visible from the picture, but the ends of the red arrows show the grey background of the static texts. However, the backround of the tab itself is white.
What event causes the grey background of the static texts? Is it the WM_CTLCOLORSTATIC. Or, where is the problem? Is the background of the tab expected to be white or grey (standard behaviour)?
Is it recommended (by designers of the visual interface, user experience) to have also the listboxes in the tab the same (white) background?
The outer window has COLOR_3DFACE defined via ATL macro DECLARE_WND_CLASS_EX. What event is responsible for painting the bacground around the tab windows?
Thanks for your help,
Petr
The missing grey background around the tabs was solved by processing the WM_ERASEBKGND message explicitly (the redirection somehow prevented the default processing):
if (uMsg == WM_ERASEBKGND)
{
WTL::CDCHandle dc(reinterpret_cast<HDC>(wParam));
RECT rc;
GetClientRect(&rc);
dc.FillRect(&rc, GetWndClassInfo().m_wc.hbrBackground);
return TRUE;
}
Similarly, the grey background of the static texts on the white tabs was whitened by processing WM_CTLCOLORSTATIC in the ProcessWindowMessage of the TabControl window this way:
else if (uMsg == WM_CTLCOLORSTATIC)
return TRUE;

Set background color of a control? (WinAPI)

How can I set the backcolor of a control (equivilant of control.backcolor in .Net). I tried setBKColor with no luck.
ex: TabHwnd = createWindowEx(NULL,WC_TAB....
then how could I set the back color of TabHwnd?
Thanks
Windows will generate a message when it's painting the background of a control, and it is up to your program to respond to the message appropriately.
WM_CTLCOLORBTN
WM_CTLCOLOREDIT
WM_CTLCOLORDLG
WM_CTLCOLORLISTBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC
I know this question is old, but perhaps this answer will still help some others.
What worked for me was to return a hollow brush for the background color messages. For example:
switch (msg) {
case WM_CTLCOLORDLG:
return (INT_PTR)GetStockObject(HOLLOW_BRUSH);
case WM_CTLCOLORSTATIC:
return (INT_PTR)GetStockObject(HOLLOW_BRUSH);
}
Also, you don't need to worry about deleting the "brushes" created by GetStockObject.
Try subclassing (see SetClassLong) and process WM_ERASEBKGND

How to get CEdit to scroll properly?

I have a CEdit control that's used to display a diagnostics output.
Sometimes the data overflows the screen size, so naturally I set the Vertical Scroll property to true (MFC dialog editor).
But then, when I tried to scroll the text that was in the window before isn't cleared and the new text is written over it.
The result is a big mess of everything I have scrolled past.
I've looked for a draw background property or something similar that will erase everything in the window while scrolling (before redrawing the new data).
Any suggestions?
I think you might want to set Auto VScroll and Multiline to true, and Auto HScroll to false.
We were having a similar problem. We ended up having to invalid the region of the parent window to get it to update when we got WM_VSCROLL. I tried to do as user demorge says here:
SetBkMode(hdc, TRANSPARENT) doesn't work
But our code doesn't use handles, we actually use the class CWnd, so we ended up doing this in the WindowProc instead:
switch(message)
{
...
case WM_VSCROLL:
case WM_HSCROLL:
LRESULT answer;
PAINTSTRUCT ps;
CDC* pdc;
CWnd* MyParentHWnd;
// We want the scroll to work the same way it has always worked for our
// ancestor class. Let them handle the scrolling and save off their
// return.
answer = AncestorClass::WindowProc(message, wParam, lParam);
pdc = BeginPaint(&ps);
// DO NOT change the assignement operator in the conditional below to an
// equality operator. We are actually trying to get the parent window and
// and storing locally, and then verifying that we didn't get back null.
// This is a purposeful design decision.
if (MyParentHWnd = GetParent()){
RECT MyRect;
GetClientRect(&MyRect);
ClientToScreen(&MyRect);
MyParentHWnd->ScreenToClient(&MyRect);
MyParentHWnd->InvalidateRect(&MyRect);
}
EndPaint(&ps);
return answer;
break;
...
}
Of course, I had to genericize it a little bit. I just wanted you to know that yes, there are other people that are seeing your problem, and we found how to fix it.
I tested this with VS2005, which ships with MFC 8.0. I couldn't replicate your problem.
I added one CEdit and one CRichEditCtrl to a dialog based app. Changed properties Multiline, Auto VSCroll and Vertical Scroll to true. Used SetWindowText-method to put loooooong string of text to both of them. I started the app and text scrolled just fine.
What did you do differently?
Just to be sure. You didn't use the SetCaretPos-method, did you? There was some note about that in the MSDN page. Here's the Knowledge Base article.

Visual Studio 2005: static text control won't display with transparent background

I'm using the Dialog editor in Visual Studio 2005 to create a Dialog box with a static text control. I'd like the background of the static text control to be transparent since I'm using an static image control underneath it and the grey text background looks hideous. In the editor, I set the "Transparent" attribute to True and it causes the background to go transparent just like I want it to. But as soon as I run my app and change the text using a SendMessage(hText, WM_SETTEXT, 0L, "newtext"), the background loses its transparency and goes grey again. Any ideas? Btw, I'm doing this in C++.
Thanks in advance for your help!
As Anthony Johnson said, handle the WM_CTLCOLORSTATIC message in the dialog box (you don't have to handle WM_NOTIFY - I don't believe static controls use that message, anyway). But it doesn't seem to be enough to set the background mode to transparent. You also have to set the background brush to a null brush. Something like this should work (in your DialogProc):
case WM_CTLCOLORSTATIC:
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)(HBRUSH)GetStockObject(NULL_BRUSH);
If you change the text on the static control, you may have to invalidate what's underneath it for it to draw correctly when you do this.
Try hiding the control, then setting the text, then showing it.
I don't know how you can do it in the dialog editor, but if you handle the WM_NOTIFY message in the static's parent window, the static will send a WM_CTLCOLORSTATIC message before drawing the static. There, if you call SetBkMode((HDC)wParam, TRANSPARENT);, that should make the static have a transparent background.

How to make the group-box text background transparent

I want to make a transparent dialog. I capture the OnCtlColor message in a CDialog derived class...this is the code:
HBRUSH CMyDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if(bSetBkTransparent_)
{
pDC->SetBkMode(TRANSPARENT);
hbr = (HBRUSH)GetStockObject(NULL_BRUSH);
}
return hbr;
}
It works fine for all the controls but the group-box (CStatic). All the labels (CStatic) are been painted with a transparent text background but the text of the group box it is not transparent.
I already googled for this but I didn't find a solutions. Does anybody know how to make a real transparent group-box?
By the way, I am working in Windows XP. And I don't want to fully draw the control to avoid having to change the code if the application is migrated to another OS.
Thanks,
Javier
Note: I finally changed the dialog so that I don't need to make it transparent. Anyway, I add this information because maybe someone is still trying to do it. The groupbox isn't a CStatic but a CButton (I know this is not new). I changed the Windows XP theme to Windows classic and then the groupbox backgraund was transparent. The bad new is that in this case the frame line gets visible beneath the text...so if someone is following this approach I think maybe he/she would better follow the Adzm's advice.
You have two options.
You can not use Common Controls v6 (the XP-Styled controls), which will make your app lose the fanciness of newer windows versions. However IIRC the groupbox will respect the CTLCOLOR issue. If you are not using that anyway, and it is still not respecting your color, then you only have one option...
Which is to draw it yourself. I know you said you don't want to, but sometimes you have to. Thankfully a group box is a very simple control to draw. This page has an example for drawing a classic-style group box: http://www.codeguru.com/cpp/controls/controls/groupbox/article.php/c2273/ You can also draw it very simply using the UxTheme libraries that come with XP+.
If the application will be migrated to another OS, you will have plenty to deal with migrating over an MFC application in general. If that is your goal, then you should really look into developing with a cross-platform UI toolkit.
Simply set the WS_EX_TRANSPARENT extended window style for the group box.
I knows this is a 12 years old question, but it frustrates me that nobody answered it correctly so far.
All you have to do is handle WM_CTLCOLORSTATIC:
case WM_CTLCOLORSTATIC:
{
HDC hDC = (HDC)wParam;
SetTextColor(hDC, RGB(255, 255, 255));
SetBkMode(hDC, TRANSPARENT);
return (INT_PTR)GetStockObject(HOLLOW_BRUSH);
}
break;