I have enabled blur on my window. I have some edit fields and some custom controls and I would not want these to be affected by the blur, they are semi transparent as a result. How could I only blur the main window itself, not its child controls (sort of like Chrome). Thanks
Black is treated as transparent since good old GDI does not support alpha channel (the alpha byte in ARGB is always 0) I'm thinking you have to do some sort of owner draw.
try to make windows style WS_CLIPCHILDREN
Related
I'm trying to do something like what Auslogics Disk Defrag does with its custom window:
As can be seen, the blurred semi transparent shadow surrounding the window is much darker than the standard one, so the program must be drawing it by itself. The problem is, I can't find a way to paint anything transparent around a window.
In an answer to a similiar question, someone suggested creating a slightly bigger transparent window (using WS_EX_LAYERED + SetLayeredWindowAttributes()) behind the actual application window, and then do the translucent drawing on the transparent one. Not only does it sound like an ugly hack, it doesn't actually work. If, for example, one tries to draw a semi transparent black rectangle on a transparent window via GDI+, alpha blending is applied to the shape's color over the window background color (which would also be the transparency color) and then the shape is drawn with the calculated color, which obviously is not the window transparency, resulting in an opaque rectangle.
The semi transparent shadow is actually done by Gaussian Blur of the black square.
You can use this effect to create glows and drop shadows and use the
composite effect to apply the result to the original image. It is
useful in photo processing for filters like highlights and shadows.
You can use the output of this effect for input into lighting effects,
like the Specular Lighting or Diffuse Lighting effects, because the
alpha channel is blurred, too and lighting effects use the alpha
channel to determine surface geometry as a height map.
This effect is used by the built-in Shadow effect.
Refer: Gaussian blur effect
Then remove the standard frame, the entire window is your client area, so you can draw shadow in the extended frame.
Refer: Drawing in the Extended Frame Window
I think I've found a solution that works for me. I was hoping I wouldn't have to create an extra window just for the shadow, but every method I could find or think of would require me to draw all the controls by myself and/or somehow correct their alpha values.
So, I'm using a layered window with per pixel alpha. I paint over it with Direct2D, or, alternatively, I use some PNGs with transparency for the edges and corners of the shadow and copy them on a memory DC. Either way I simply recreate the shadow with the right dimensions when the window is resized, and call UpdateLayeredWindowIndirect. Both methods seem to be working well on Windows 7 and 10, and so far I haven't found any glitches.
Preventing it from showing on the taskbar was a bit tricky. All the ways I know have drawbacks. What worked best for me was making the layered window owned by the main one. At least that way it will only be visible on the desktop where the program is actually running, unlike other alternatives which would force it to show on every virtual desktop. Finally, because I disable that window, I interact with it by processing WM_SETCURSOR.
I am trying to create a simple transparent window where I can draw with Direct2D.
So far what I have done:
Created window
Set style to WS_EX_LAYERED
Set alpha color key as #FFF
Draw using Windows Graphics a white rectangle
Now window is transparent with per-pixel alpha
Then make a target out of the window and draw using Direct2D
Make ALPHA _PREMULIPLIED target
Clear with #FFF with 0.0f alpha
Window is now black
I just don't know how to make window to transparent. If you can point out my mistake, I would be obliged
Here how it's achievable using DirectComposition API
Russian: http://www.oszone.net/25395/
English: https://msdn.microsoft.com/magazine/dn745861.aspx
Basically what author does is
Sets WS_EX_NOREDIRECTIONBITMAP extended style to remove redirection bitmap of DWM. Content of window is now empty.
Creates DirectComposition device
Creates Composition SwapChain (and not hwnd swapchain)
Places one visual with SwapChain as content as root visual.
Renders into SwapChain using Direct2D API.
It also works well with WS_EX_TRANSPARENT | WS_EX_LAYERED | WS_EX_TOPMOST for creating event-transparent overlays.
I don't think it's possible with directX. However GDI does work.
Take a look at the source here to see how it's done: http://pastebin.com/NJf8wi2V
In the source you can see that there is an option to attempt to use directx/opengl. However as you can see from running they do not work.
I am haveing trouble understanding the concept of the UpdateLayaredWindow api, how it works and how to implement it. Say for example I want to override CFrameWnd and draw a custom, alpha blended frame with UpdateLayeredWindow, as I understand it, the only way to draw child controls is to either: Blend them to the frame's Bitmap buffer (Created with CreateCompatibleBitmap) and redraw the whole frame, or create another window that sits ontop of the layered frame and draws child controls regularly (which defeats the whole idea of layered windows, because the window region wouldn't update anyway).
If I use the first method, the whole frame is redrawn - surely this is inpractical for a large application..? Or is it that the frame is constantly updated anyway so modifying the bitmap buffer wouldn't cause extra redrawing.
An example of a window similar to what I would like to achieve is the Skype notification box/incoming call box. A translucent frame/window with child contorls sitting ontop, that you can move around the screen.
In a practical, commercial world, how do I do it? Please don't refer me to the documentation, I know what it says; I need someone to explain practical methods of the infrastructure I should use to implement this.
Thanks.
It is very unclear exactly what aspect of layered windows gives you a problem, I'll just noodle on about how they are implemented and explaining their limitations from that.
Layered windows are implemented by using a hardware feature of the video adapter called "layers". The adapter has the basic ability to combine the pixels from distinct chunks of video memory, mixing them before sending them to the monitor. Obvious examples of that are the mouse cursor, it gets super-imposed on the pixels of the desktop frame buffer so it doesn't take a lot of effort to animate it when you move the mouse. Or the overlay used to display a video, the video stream decoder writes the video pixels directly to a separate frame buffer. Or the shadow cast by the frame of a toplevel window on top of the windows behind it.
The video adapter allows a few simple logical operations on the two pixel values when combining their values. The first one is an obvious one, the mixing operation that lets some of the pixel value overlap the background pixel. That effect provides opacity, you can see the background partially behind the window.
The second one is color-keying, the kind of effect you see used when the weather man on TV stands in front of a weather map. He actually stands in front of a green screen, the camera mixing panel filters out the green and replaces it with the pixels from the weather map. That effect provides pure transparency.
You see this back in the arguments passed to UpdateLayeredWindow(), the function you must call in your code to setup the layered window. The dwFlags argument select the basic operations supported by the video hardware, ULW_ALPHA flag enables the opacity effect, the ULW_COLORKEY flag enables the transparency effect. The transparency effect requires the color key, that's specified with the crKey argument value. The opacity effect is controlled with the pblend argument. This one is built for future expansion, one that hasn't happened yet. The only interesting field in the BLENDFUNCTION struct is SourceConstantAlpha, it controls the amount of opacity.
So a basic effect available for a layered window is opacity, overlapping the background windows and leaving the partially visible. One restriction to that the entire window is partially opaque, including the border and the title bar. That doesn't look good, you typically want to create a borderless window and take on the burden of creating your own window frame. Requires a bunch of code btw.
And a basic effect is transparency, completely hiding parts of a window. You often want to combine the two effects and that requires two layered windows. One that provides the partial opacity, another on top and owned by the bottom one that displays the parts of the window that are opaque, like the controls. Using the color key to make its background transparent and make the the bottom window visible.
Beyond this, another important feature for custom windows is enabled by SetWindowRgn(). It lets you give the window a shape other than a rectangle. Again it is important to omit the border and title bar, they don't work on a shaped window. The programming effort is to combine these features in a tasteful way that isn't too grossly different from the look-and-feel of windows created by other applications and write the code that paints the replacement window parts and still makes the window functional like a regular window. Things like resizing and moving the window for example, you typically do so by custom handling the WM_NCHITTEST message.
i've implemented a owner draw button into my win32 app (no MFC). The button is a normal 20x20 bitmap (round icon with transparency). The problem is that the button is positioned on a solid background and i can see the buttons gray background (since the bitmap is round). I've tried responding to WM_CTLCOLORBTN with NULL_BRUSH but no luck.. I've tried displaying the button using a bitmap and a ico file but wont budge.. Does anyone know how to solve this problem?
This is my problem, the settings icon should be transparent at the edges (not white/gray)
It sounds like you're trying to make a non-rectangular control.
You could call SetWindowRgn to tell Windows that your control is non-rectangular.
In addition to what #joel's answer, if you want to make some area transperant put a unique color in the area where you want to have transperancy using some image editors (RGB(0xFF,0x00,0xFF)) is mostly used Then use TransperantBlt
You say it's a solid background but your image shows some kind of orange-yellow gradient as a background. If it really was a standard windows button solid color you can load the bitmap with LoadImage using the LR_LOADMAP3DCOLORS or LR_LOADTRANSPARENT. Since you have a gradient you'll have to use a more complicated technique to mask out the bitmap.
http://www.winprog.org/tutorial/transparency.html
It's a while since I've done this, but I'm trying to add a custom button graphic to a windows button, with some transparent areas. I've tried various schemes but can't seem to get the transparent areas to show. Here's my code:
hbmpUpDisabled = LoadImage(instance,MAKEINTRESOURCE(IDB_UPARROWDISABLED), IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
SendMessage(GetDlgItem(hWndDlg, IDC_MOVEUP),BM_SETIMAGE,(WPARAM)IMAGE_BITMAP,(LPARAM)hbmpUpDisabled);
Does anyone notice any problems here? It works if my bitmap is a 1-bit bitmap. I couldn't get a 32 bit bitmap to work, and I'm not sure how to setup a 24 bit or 8 bit bitmap to do it.... I tried a custom 255,0,255 color (which IIRC is a default transparent value), but so far no joy....
LR_LOADMAP3DCOLORS should map grey - in the source image - to to the current button face color. Buttons do not use AlphaBlt or TransparentBlt so there is no way to actually (short of custom painting) set a bitmap with transparent or alpha'd areas onto a button and expect it to work. You just have to pre-prepare the bitmap with the correct button color in its background areas.
That said - I suspect that some of these restrictions may be lifted for buttons implemented by common controls v6. Add commctl 6 as a dependend assembly to your exe and see if the behaviour changes.