6

I'm trying to create a transparent window with a "glass" effect in Windows 10. This worked until recently:

Screenshot

What I have been doing is:

  • Paint to the target DC including an alpha channel. One way to do this in plain GDI is to construct an image with an alpha channel, and BitBlt it using SRCCOPY to the DC. You can also use the AlphaBlend function.
  • Then I use SetWindowCompositionAttribute (or DwmExtendFrameIntoClientArea) to enable blur behind on windows 10 (or earlier).

This worked until today, and suddenly stopped working after an update - the window is now opaque. I used System Restore and went back one day, and it actually worked again! Any ideas how can I fix this?

jdm
  • 9,470
  • 12
  • 58
  • 110
  • "Since GDI doesn't support alpha channels, this also sets the alpha value of each pixel to zero." That's not necessarily true; it's an implementation detail. The common way to create a window with per-pixel alphas is to use a layered window and call UpdateLayeredWindow. – Adrian McCarthy Sep 01 '15 at 20:13
  • @AdrianMcCarthy: Of course it is an undocumented implementation detail. But so is calling SetWindowCompositionAttribute to create the glass effect, so I'm in undocumented land anyway. Switching to layered windows would require a major rewrite of the WM_PAINT based code, and I'm not sure it would work either (I'd like an opaque standard titlebar, but a semitransparent content area). Also, the "glass" transparency since Vista is not based on layered windows, but regular windows with an alpha channel (blending is done by the DWM). – jdm Sep 03 '15 at 07:20
  • 1
    Do you know of any way to use `SetWindowCompositionAttribute` to set the blur region (as was possible with `DwmEnableBlurBehindWindow`), to stop it from blurring outside of the client area? – melak47 Feb 18 '17 at 15:27
  • 1
    @melak47 You can't blur only a part of the window. Windows 10 replaced the old blur with a solid background color. The new function, SetWindowCompositionAttribute, can only blur everything AFAIK. And I haven't found a way to remove the artifacts it makes when blurring outside the client area (the shadows). – jdm Feb 18 '17 at 17:36

1 Answers1

4

It turns out I was calling SetWindowCompositionAttribute incorrectly. Namely, one of the parameters has a size field, and I was putting the wrong size in. That it used to work at some point was a pure accident.

jdm
  • 9,470
  • 12
  • 58
  • 110
  • Could you expand on this `size` field? – Charles Milette Jan 29 '17 at 16:31
  • @charles.milette It's been a while, but the function takes a pointer to struct WINCOMPATTR. In this struct, you specify which attribute you want to set, a pointer to the new data, and the size of the data field. Example: https://github.com/jdmansour/mintty/blob/glass/src/winmain.c#L683 – jdm Jan 29 '17 at 17:26