Xp-themed transparent control background

I have several window controls drawn on a bitmap as well as a colored background in a dialog box. Could there be some possible way of background transparency in the control window? They currently show the default background color of the dialog box.

Example. I tried to insert a solid blue bitmap, and the two button controls have a noticeable colored rectangle by default.

Dialog window containing two UI-buttons in the middle: 'OK' and 'Cancel'. Though the buttons are a default off-white, most of the inside area of ​​the dialog-box has a shocking bright blue background.

+4
source share
2 answers

This is easily solved by providing a Windows handle to any brush you want to use to paint the button background. You do this every time you receive the WM_CTLCOLORBTN message in the message handler of the parent window of the button.

I mocked a small demo application that compares two different buttons side by side. Both are standard Win32 BUTTON controls, but one on the left handles the WM_CTLCOLORBTN message and indicates a brush with the same color as the background of the window. You can immediately see the difference - light gray (or, more precisely, the default color for three-dimensional controls, COLOR_3DFACE ) bordering the button’s rectangle has disappeared and the button looks much better than the custom background color:

Transparent Buttons Sample in Windows Vista

The effect also works in Windows XP with visual themes turned on - a screenshot of the same application:

Transparent Buttons Sample in Windows XP

And the code I used to create the above effect is almost ridiculously simple. Add this to the application main window procedure ( MainWndProc ) as described above. You do not need to touch the buttons.

 HBRUSH hButtonBackColor = NULL; LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CTLCOLORBTN: { if (!hButtonBackColor) { // Create the brush, if it hasn't already been created. // (You can use any type of brush here; this is just an example.) hButtonBackColor = GetSysColorBrush(COLOR_3DDKSHADOW); } return (LRESULT)hButtonBackColor; } // ... } } 

However, make sure that the specified brush is the same color as the background color of your window - a transparent brush may not work correctly. Similarly, for a pattern brush (does anyone use them more?), The name of the brush should be set according to the background.

Always make sure that you open any brushes you created by calling DeleteObject !! In C ++, you do this by making the CBrush object (or equivalent) a member of your dialog class so that it is automatically destroyed. In C, you need to process the WM_NCDESTROY message and manually remove the brush.

Also note that you do not need to specify BS_OWNERDRAW style to make this trick work. The above example uses two standard button controls created using only the following window style flags: WS_CHILD , WS_VISIBLE and BS_PUSHBUTTON .

Of course, if your design is more complex than the example above (for example, your buttons overlap several backgrounds), you will most likely have to go along the owner’s route. I just think that an unnecessary task for a task is as simple as the one you seem to be describing.

+6
source

I don’t know if you can make a really transparent background, but my solution can help you anyway. I always solved this using the WM_CTLCOLORBTN message in the main window procedure.
Suppose we have a switch in which we process messages received in the main window.

 case WM_CTLCOLORBTN: return (LRESULT)hBgColor; break; 

where hBgColor is HBRUSH , for example:

 HBRUSH hBgColor=CreateSolidBrush(RGB(0, 0, 255)); 

As I said, this does not make a transparent control background - it just sets it to the specified color.
EDIT: Sorry, I already made a mistake. I wrote LPARAM instead of LRESULT . Now this is correct.

0
source

Source: https://habr.com/ru/post/1332671/


All Articles