[win32 API/c++] Text on transparent backgound
Hi,
Now we all know drawing windows in the win32 API is frustrating.... well, for me anyway!
I'm trying to draw a static text control with no background (transparent bg) over video.
The video plays fine in a child window of my app. However, when I'm trying to draw the text I have problems.
Can anyone suggest a simple way of drawing text with a transparent background in a child window?
Thanks
Simon
This should work (Assume hDC is the device context handle to your child window):
The default background mode is OPAQUE, which cuases the GDI to draw a filled rectangle the same colour as the current background colour over the area text is drawn over (Which is what I assume you mean by "I have problems").
SetBkMode(hDC, TRANSPARENT);DrawText(...);
The default background mode is OPAQUE, which cuases the GDI to draw a filled rectangle the same colour as the current background colour over the area text is drawn over (Which is what I assume you mean by "I have problems").
Hello Steve,
Thanks for your suggestion, and I apologise for my (un?)characteristic vagueness!
I'm not having much success though. I tried this:
and this in the Message processor:
Still that lovely grey background to my static text control :)
Thanks
Si
Thanks for your suggestion, and I apologise for my (un?)characteristic vagueness!
I'm not having much success though. I tried this:
g_textHWND = CreateWindow( "STATIC", "Textbox", WS_CHILD | WS_VISIBLE, 20, 20, 200, 100, g_hWnd,(HMENU)IDC_hLB_Output,g_hInstance,NULL); SetWindowText( g_textHWND, "I am visible" ); HDC hdc = GetDC(g_textHWND); SetBkMode ( hdc, TRANSPARENT ); //SetTextColor( hdc, RGB(255, 0, 0)); ReleaseDC( g_textHWND, hdc );
and this in the Message processor:
case WM_CTLCOLORSTATIC: hdc = GetDC(g_textHWND); SetBkMode ( hdc, TRANSPARENT ); SetTextColor( hdc, RGB(255, 0, 0)); ReleaseDC( g_textHWND, hdc ); break;
Still that lovely grey background to my static text control :)
Thanks
Si
Forget using a static control for this. That will only work with lots of hassle. Do you get an event once the child control with the video on it gets updated?
You might force an update and draw your text directly onto the HDC. Not sure if this works with the overlaying though.
You might force an update and draw your text directly onto the HDC. Not sure if this works with the overlaying though.
Quote:Original post by Endurion
Forget using a static control for this. That will only work with lots of hassle.
Are you saying its not possible to change the bg and font colour of a text control? surely not, although this is win32api....
Quote:Original post by EndurionDo you get an event once the child control with the video on it gets updated?
You might force an update and draw your text directly onto the HDC. Not sure if this works with the overlaying though.
To be honest, I am not worried about it overlaying the video (yet). Something else is up since I have not control over it at all. Heres the window, with the nasty grey background refusing to be altered:
Ok, some progress...
My WM_CTLCOLORSTATIC needed to return a NULL_BRUSH. This is because, before the draw text, the entire static control is painted with the return value of WM_CTLCOLORSTATIC.
This works nicely:
Now when my video starts up, it appears over the text, even if I create the window with WS_EX_TOPMOST.
I thought it would be invalidated by the video child window then repainted automatically.... hmmm
My WM_CTLCOLORSTATIC needed to return a NULL_BRUSH. This is because, before the draw text, the entire static control is painted with the return value of WM_CTLCOLORSTATIC.
This works nicely:
case WM_CTLCOLORSTATIC: texthdc = (HDC) wParam; hwndtext = (HWND) lParam; SetBkMode ( texthdc, TRANSPARENT ); SetTextColor( texthdc, RGB(255, 0, 0)); hbr = (HBRUSH)GetStockObject( NULL_BRUSH ); return (LRESULT)hbr; break;
Now when my video starts up, it appears over the text, even if I create the window with WS_EX_TOPMOST.
I thought it would be invalidated by the video child window then repainted automatically.... hmmm
To use a static control in the way you want (i.e. a transparent background) you'll need to do the following:
1) Create the static control using CreateWindowEx specifying the WS_EX_TRANSPARENT extended style. This will cause the parts of any window underneath the control to be painted. Normally, the window manager clips the update region to remove areas of the window being updated that are obscured, so even if the window did draw correctly, there wouldn't be anything underneath it.
2) Sub class the static control.
3) Overload the WM_ERASEBKGND message handler for the static control to perfrom no drawing, all other messages should be passed to the static control.
4) Process the WM_CTLCOLORSTATIC in the owner window to set the text colour and text transparent background flag.
The main problem is that the default handler for the WM_ERASEBKGND fills in the background with the brush specified in the return value of WM_CTLCOLORSTATIC or the brush defined in the WNDCLASSEX structure for the control. The latter can't be changed for system controls. It may be possible to use the former using a hollow brush (if that worked, remove steps 2 and 3).
Skizz
1) Create the static control using CreateWindowEx specifying the WS_EX_TRANSPARENT extended style. This will cause the parts of any window underneath the control to be painted. Normally, the window manager clips the update region to remove areas of the window being updated that are obscured, so even if the window did draw correctly, there wouldn't be anything underneath it.
2) Sub class the static control.
3) Overload the WM_ERASEBKGND message handler for the static control to perfrom no drawing, all other messages should be passed to the static control.
4) Process the WM_CTLCOLORSTATIC in the owner window to set the text colour and text transparent background flag.
The main problem is that the default handler for the WM_ERASEBKGND fills in the background with the brush specified in the return value of WM_CTLCOLORSTATIC or the brush defined in the WNDCLASSEX structure for the control. The latter can't be changed for system controls. It may be possible to use the former using a hollow brush (if that worked, remove steps 2 and 3).
Skizz
Thanks for the advice skizz.
hbr = (HBRUSH)GetStockObject( NULL_BRUSH ) does work tho. It prevents the child window area being filled in.
I didn't have much luck with WS_EX_TRANSPARENT. Don't you mean WS_EX_LAYERED? I thought WS_EX_LAYERED meant see-thru, while WS_EX_TRANSPARENT meant clickthru?
hbr = (HBRUSH)GetStockObject( NULL_BRUSH ) does work tho. It prevents the child window area being filled in.
I didn't have much luck with WS_EX_TRANSPARENT. Don't you mean WS_EX_LAYERED? I thought WS_EX_LAYERED meant see-thru, while WS_EX_TRANSPARENT meant clickthru?
From the MSDN:
Looking elsewhere, WS_EX_TRANSPARENT lets all mouse events pass down to windows underneath. WS_EX_LAYERED only lets mouse events pass to lower windows if the alpha is zero or the point is colour keyed. WS_EX_LAYERED appears to be a more complex, but more powerful, method to use. I'm not sure how the WS_EX_LAYERED method would work with a common control.
Skizz
Quote:
Specifies that a window created with this style is to be transparent. That is, any windows that are beneath the window are not obscured by the window.
Looking elsewhere, WS_EX_TRANSPARENT lets all mouse events pass down to windows underneath. WS_EX_LAYERED only lets mouse events pass to lower windows if the alpha is zero or the point is colour keyed. WS_EX_LAYERED appears to be a more complex, but more powerful, method to use. I'm not sure how the WS_EX_LAYERED method would work with a common control.
Skizz
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement