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.
Related
I'm very new to win32api programming. I have 3 questions.
how to change the background colour in the parent window. i did it as folows but it dont work
wClass.hbrBackground=(HBRUSH)(RGB(255,255,255));
second question is, I use to add text in the window as follows. the text is in bold font and with a background colour. I want the text to be in normal and without background colour.
PAINTSTRUCT ps;
HDC hDC;
char szBuffer[]="Hello, World!";
hDC=BeginPaint(hWnd,&ps);
TextOut(hDC,10,10,szBuffer,strlen(szBuffer));
third question is how to add group boxes in the parent window. i searched it in the internet but this was discribed how to add group boxes on dialog boxes using resources.
pls some one help me with these isue...
> wClass.hbrBackground=(HBRUSH)(RGB(255,255,255));
I suppose the class structure requiers the handle of the brush, not the color value itself (but I'm not sure). Something like this:
wClass.hbrBackground=(HBRUSH)(CreateSolidBrush(RGB(255,255,255)));
To make the text background transparent use special WinAPI function, SetBkMode(TRANSPARENT); (Oof, spend some time to remember it's name:) ).
In most tasks it will be much better to make a dialog resource and use it like an ordinary window (drawing smth in it, putting simple windows in which you draw, etc) than take an ordinary window and try to add dialog controls in it. It became a common practice since WinForms and then WPF - every window in them is a "form" in which you can add controls, draw in it and so on.
I'm trying to remember if Microsoft put in code to clear the client area. I know at the minimum, you can get the client rect and then use that to base a drawRect() command to the whole client area. You also may have to trap the command to erase the background
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;
I have created the above simple GUI in c++. I would like the static text control background to be same as the main window (which is white) or how can i make the main window background (hbrBackground) to be the same color as the background in the static text control?
Many thanks!
You can set the background of the static control by responding to WM_CTLCOLORSTATIC.
You can change the background color of your window by responding to WM_ERASEBKGND and calling (for one possibility) FillRect.
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;
}
I am currently writing a program in c++ (no MFC) and want to update a label (win32 static control) using the win32 DrawText function. However when i call the function nothing is written to the label. I use the following code:
HDC devCon = ::GetDC(GetDlgItem(IDC_TITLE).m_hWnd);
RECT rect = {10, 10, 100, 15};
::DrawText(devCon, _T("TEST DC TEXT!!!"), -1, &rect, DT_NOCLIP);
::ReleaseDC(GetDlgItem(IDC_TITLE).m_hWnd, devCon);
As you see with the GetDlgItem(...) I am using ATL but that should not be a problem in my opinion. When I specify NULL in the GetDC method the text is drawn in the upper left corner of the screen as it is supossed to be since the method return the DC to the entire screen.
Why doesn't this work with the DC of the label?
Hope you folks can help me.
If you want to draw the text manually because setting the control text doesn't do what you want, then you need to tell Windows that you're doing that. Otherwise the control will draw itself over whatever you do whenever it needs to be redrawn.
To draw it yourself, mark your control as owner draw by setting the SS_OWNERDRAW style, and then handle the WM_DRAWITEM message to draw it in the window procedure of the parent window, or subclass the window and handle the WM_PAINT message in your new window procedure.
I guess that the text is drawn but at the next window message is set to the default text.
Try to set the text with SendMessage(..,WM_SETTEXT,...);
Use SetDlgItemText() to set the text for the control.
You are trying to paint directly onto the static control's device context.
This is not going to be so simple, because:
the control will repaint itself whenever it's update region is invalidated
usually the controls share the device context with the parent window, so what you are getting in GetDC(...) is actually your dialog's device context.
So, use SetDlgItemText, or SetWindowText to set the text of the window.
To use a custom font (or set the text/background color), handle the WM_CTLCOLORSTATIC message in your WindowProc.