Draw/Create ID2D1RenderTarget with Transparent Color - c++

I have a written a class which is able to display animated GIF files with Direct 2d as in this example from MSDN:
https://code.msdn.microsoft.com/windowsapps/Windows-Imaging-Component-65abbc6a/sourcecode?fileId=127204&pathId=969071766
The GIF which I display is a continuously growing/shrinking not filled blue circle. All other pixels are White / the Background is White.
Unlike the example posted I create a CWnd, without Caption and Border, with the size of the GIF, with a ID2D1RenderTarget filling the whole CWnd and place it above the Content of my MainFrame.
Since I never used Direct2d before I assumed I can simply apply SetLayerdWindow() on my CWnd to reach my goal of only displaying the blue Circle.
SetLayeredWindowAttributes(RGB(255,255,255), 204, LWA_ALPHA | LWA_COLORKEY);
This should result in a CWnd with no White Pixels + 80% Transparency. Unfortunately the resulting Window is 80% transparent but none of the WhitePixels where removed/ the white pixels are still drawn.
Why does LWA_COLORKEY not work in this case?
And how can I achieve that either my CWnd or ID2D1HwndRenderTarget will draw white as fully transparent?!
Note:
Besides that I've tried just for fun to draw a fully transparent background with the ID2D1HwndRenderTarget like:
m_pHwndRT->Clear(D2D1::ColorF(D2D1::ColorF::White, 0.0f));
With Microsoft stating: "The alpha value for the color to be constructed. An alpha channel value ranges from 0.0 to 1.0, where 0.0 represents a fully transparent color and 1.0 represents a fully opaque color. The default value is 1.0."
Which results in a fully white opaque window... Which made me wonder if this whole Transparency stuff is working at all

Related

Draw semi transparent shadow around Window

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.

How to render in the title bar with D3D11 in Windows 7?

I have a program that renders to a D3D11 swapchain created with IDXGIFactory2::CreateSwapChainForHwnd. It clears the swap chain to a particular color, specifically green, and draws a textured rectangle. Following the guide at https://learn.microsoft.com/en-us/windows/desktop/dwm/customframe, I extended the window caption downward using DwmExtendFrameIntoClientArea and I extended the client area to the entire window by handling the WM_NCCALCSIZE message. When the swap chain is presented, the contents of the swap chain buffer is drawn on top of the window, completely covering the DWM-drawn glass frame and caption buttons. How can I leave regions of the glass frame and caption buttons to be drawn by DWM while still drawing in the window frame using D3D11?
I have already tried to clear the RenderTargetView to a color of {0.0f, 0.0f, 0.0f, 0.0f} with ID3D11DeviceContext::ClearRenderTargetView but the alpha component appears to be ignored. I've tried to specify DXGI_ALPHA_MODE_STRAIGHT and DXGI_ALPHA_MODE_PREMULTIPLIED in the AlphaMode member of the DXGI_SWAP_CHAIN_DESC1 used to create the swap chain, but it crashes because alpha-blended swapchains must be created by CreateSwapChainForComposition or CreateSwapChainForCoreWindow. Those functions are not viable since I would like to support Windows 7.
Another thing I've tried is creating a blend state and making parts of the texture transparent. All this does is blend the transparent parts of texture with the clear color. Nothing is getting rendered by DWM though.

ClearType ruins transparency

I have a bitmap which background needs to be replaced with part of another bitmap. Everything works fine until I enable ClearFont on my WindowsXP.
In order to explain my problem better, let us label first bitmap as bmpDestination and second as bmpSource.
Here is how the bmpSource looks like :
Here is how bmpDestination looks like :
When ClearType is off, here is how the correct result looks like :
And here is the incorrect result of their combining when ClearType is on:
ClearType alters some parts of the text background color, so they aren't white anymore ( RGB( 255, 255, 255 ) ) but a combination of white and text color.
I am using BitBlt() and monochrome bitmap to create a mask, and to simulate transparency. I have tried using TransparentBlt() too, but got the same result.
How can I combine bmpSource and bmpDestination, when ClearType is enabled, so I can create correct result like above ?
Thank you for your help.
Best regards.
Render the treeview with black text on a white background. Use a font with grey-scale anti-aliasing. Don't use ClearType anti-aliasing. I'm moderately sure you can achieve this with one of the fdwQuality parameters to CreateFont, but I wouldn't swear to it.
Each pixel will have a shade of grey between white and black. You can interpret this as transparency. White is fully transparent; black is fully opaque. Use this information to create a bitmap with transparency. Render this transparent bitmap over your multi-coloured background.

How to get color of window

I am trying to use API GetBkColor and GetSysColor(COLOR_WINDOW) to get color of window but its giving me wrong value.
When I get color of wndow by using some tool its diffeent from what I get from API.
Any suggestion of how to get right value of color?
In case if window is using gradient color then how can I find the color at particular pixel?
GetBkColor returns value of a COLORREF value for the current background color on success. To obtain red, green and blue components of the color, use the GetRValue, GetGValue, and GetBValue macros, respectively. Is that what do you need? OR what kind of "right value" do you mean?
To obtain a pixel color, use GetPixel function:
COLORREF color;
HDC hdc_ = GetDC(NULL); //get dc of whole screen
color = GetPixel(hdc_, x, y);
Hope this will help you somehow.
GetBkColor tells you the current background color for text, but the window may change it as it draws, so this isn't going to give you the value.
GetSysColor(COLOR_WINDOW) is the recommended default color for a window given the current color scheme, but many windows choose a different color. You can try to get the WNDCLASS for the window and check the hbrBackground field, but not all windows rely on that mechanism for setting its background color.
To get the color at a particular pixel, you can use GetPixel. This is fine for sampling a couple pixels, but don't try to read every pixel in a window by calling this a zillion times--it's too slow for that.

How can I draw a patternBrush with transparent backround (GDI)?

I can't draw a pattern with a transparent background. This is my snippet :
bitmap.CreateBitmap(8, 8, 1, 1, &bits)
brush.CreatePatternBrush(&bitmap)
hbrush = pCgrCurrentDC->SelectObject(&brush);
// set text color
TextCol = pCgrCurrentDC->SetTextColor(CgrColourPalRGB);
int oldBkgrdMode = pCgrCurrentDC->SetBkMode(TRANSPARENT);
//draw polygon
pCgrCurrentDC->Polygon(CgrBuffer, n);
The doc on msdn doesn't mention anything about transparency. I guess this mode could be used? Or is this a bug ?
Thanks!
Mode TRANSPARENT means that background will not be filled before your brush is drawn. But your brush does not contain any transparent pixels in it and it redraws background pixels anyway. Fourth argument in CreateBitmap was set to 1 in your sample. That means bitmap is monochrome.
You need to use 32-bit bitmap to use transparency in brushes. GDI supports transparency with some limits. Use GDI+ for full transparency support.