Transparent background of xp-themed control

左心房为你撑大大i 提交于 2019-12-12 12:14:58

问题


I have a few window controls drawn on a bitmap as well as on colored background on a dialog-box. Would there be some possible way to make the window controls' background transparent? Currently they show the default colored background of a dialog-box.

Example - I tried to paste a solid blue bitmap and the two button controls have the noticeable default colored-rectangle background.


回答1:


This is easily solved by providing Windows with a handle to whichever brush you want it to use to paint your button's background. You do this whenever you receive the WM_CTLCOLORBTN message in the button's parent window's message handler.

I mocked up a little demo application that compares two different buttons side-by-side. Both are standard Win32 BUTTON controls, but the one on the left handles the WM_CTLCOLORBTN message and specifies a brush with the same color as the window background. You can see the difference immediately—the light gray (or, more precisely, the default color for 3D controls, COLOR_3DFACE) fringes around the button's rectangle are gone and the button looks much better against the custom background color:

    

The effect also works in Windows XP with visual themes enabled—here's a screenshot of the same app:

     

And the code that I used to create the above effect is almost ridiculously simple. Add this to your app's main window procedure (MainWndProc), as described above. You don't need to touch your 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 brush you specify represents exactly the same color as your window's background color—a transparent brush may not work properly. Similarly, for a patterned brush (does anyone use those anymore?), the brush's origin will need to be set to match the background.

Always make sure that you release any brushes that you create by calling DeleteObject!! In C++, you would do this by making a CBrush object (or equivalent) a member of your dialog class so that it would be automatically destroyed. In C, you'd need to handle the WM_NCDESTROY message and delete the brush manually.

Also note that you do not need to specify the BS_OWNERDRAW style in order for this trick to work. The example above 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 any more complex than the above example (e.g., your buttons overlap multiple backgrounds), you'll probably have to go the owner-draw route, instead. I just think that's overkill for a task as simple as the one you appear to be describing.




回答2:


I don't know if you can make a truly transparent background, but my solution may help you anyway. I've always solved it by using the WM_CTLCOLORBTN message in the main window's procedure.
Let's assume that we have a switch, in which we process the messages received by the main window.

case WM_CTLCOLORBTN:
    return (LRESULT)hBgColor;
break;

where hBgColor is an HBRUSH, for example:

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

As I said before, this doesn't really make the control's background transparent - it just sets it to the specified color.
EDIT: I'm sorry, I've done a mistake before. I've written LPARAM instead of LRESULT. Now it's correct.



来源:https://stackoverflow.com/questions/4483599/transparent-background-of-xp-themed-control

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!