[win32 API/c++] Text on transparent backgound

Started by
8 comments, last by Skizz 16 years, 9 months ago
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
Advertisement
This should work (Assume hDC is the device context handle to your child window):
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:

	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.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

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:
       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

Ok, I just need to InvalidateRect on the whole window, lovely!

Time for a new thread?
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
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?


From the MSDN:
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