Set background color of a control? (WinAPI) - c++

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

Related

C++ WinAPI Conflict between SetLayeredWindowAttributes and BitBlt

I have created a custom window using DWM. I painted the caption by using PaintCustomCaption() ,which is an example from MSDN. It worked properly until I added SetLayeredWindowAttributes().
Window before adding
SetLayeredWindowAttributes(hWnd,RGB(0,0,1),0,LWA_COLORKEY);
After adding
I tried changing RGB values but it was still black except RGB(0,0,0).
I wonder if BitBlt() works properly.
Edited:
The reason I added SetLayeredWindowAttributes is to solve this problem
Do you have other ways to paint the caption?
case WM_ACTIVATE: {
DwmExtendFrameIntoClientArea(hWnd,&m); // m={-1,-1,-1,-1};
break;
}
case WM_INITDIALOG: {
SetWindowPos(hWnd,NULL,0,0,500,500,SWP_NOMOVE|SWP_FRAMECHANGED);
SetWindowLongPtr(hWnd,GWL_STYLE,WS_VISIBLE|WS_OVERLAPPEDWINDOW);
SetWindowLongPtr(hWnd,GWL_EXSTYLE,WS_EX_LAYERED);
SetLayeredWindowAttributes(hWnd,RGB(0,0,1),0,LWA_COLORKEY);
RedrawWindow(hWnd,NULL,NULL,RDW_INVALIDATE|RDW_ERASE);
return true;
}
case WM_PAINT: {
hdc=BeginPaint(hWnd,&paintstruct);
PaintCustomCaption(hWnd,hdc)
EndPaint(hWnd,&paintstruct);
break;
}
If you keep the window border, you don't need to paint the caption yourself unless you want to add something to your caption.
That is, handle WM_NCCALCSIZE and WM_NCHITTEST normally.
First, use RGB(200,201,202) as the transparency key instead of RGB(0,0,1).
You may try other values but it is the best one so far I have tested.
Then, add this after HBITMAP hbmOld=(HBITMAP)SelectObject(hdcPaint,hbm); in PaintCustomCaption():
FillRect(hdcPaint,&rcClient,CreateSolidBrush(RGB(200,201,202)));

C\C++ - win32: how avoid flickers with transparent controls\child controls?

i have read several tutorials\threads(even from here) and i didn't get the property answer :(
for not draw the window backgound i must do(make the control\child control transparent):
case WM_ERASEBKGND:
{
return (LRESULT)GetStockObject(NULL_BRUSH);
}
break;
until here fine.
for avoid flicker i must use Double-Buffering way and the parent window must have the WS_CLIPCHILDREN style.
if the control isn't transparent, the flicker is out. when it's not transparent, the image is drawed 1 above other. if i use the FillRect() on WM_PAINT the control is 'clean' and then show the new image... but isn't transparent :(
what can anyone advice me?

CPropertySheet and CPropertyPages are appear in white color

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;
}

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.