I created window with this window styles:
WS_CLIPCHILDREN | WS_POPUP | WS_BORDER | WS_SIZEBOX | WS_VISIBLE.
But for unknown reason WS_CLIPSIBLINGS style is automatically added.
Do you somebody know reason for this?
Sample code:
hWnd = CreateWindowExW(0, szWindowClass, szTitle, WS_CLIPCHILDREN | WS_POPUP | WS_BORDER | WS_SIZEBOX | WS_VISIBLE, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
Only child windows are mentioned in the MSDN.
Clips child windows relative to each other; that is, when a particular
child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style
clips all other overlapping child windows out of the region of the
child window to be updated. If WS_CLIPSIBLINGS is not specified and
child windows overlap, it is possible, when drawing within the client
area of a child window, to draw within the client area of a
neighboring child window.
Actually, All overlapped and popup-style windows have WS_CLIPSIBLINGS properties. That is to say, you can't get rid of WS_CLIPSIBLINGS attributes and draw in its overlapping brothers'windows.
If it's just a child window, you can add WS_CLIPSIBLINGS yourself.
Add WS_CLIPSIBLINGS
After redrawing
I'm trying to render some contents using both Gdi and Direct 2D on a compatible render target. I create the compatible target with D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE option and then I do as follows:
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
// Direct2D content
D2D1_RECT_F rect1 = D2D1::RectF(50.0f, 50.0f, 200.0f, 100.0f);
m_pRenderTarget->FillRectangle(&rect1, m_pCornflowerBlueBrush);
// GDI content
HDC hDC = NULL;
HRESULT hr = m_pGDIRT->GetDC(D2D1_DC_INITIALIZE_MODE_COPY, &hDC);
::SetBkMode(hDC, TRANSPARENT);
::TextOut(hDC, 30, 50, _T("stackoverflow"), 13);
::TextOut(hDC, 80, 70, _T("stackoverflow"), 13);
::TextOut(hDC, 150, 85, _T("stackoverflow"), 13);
m_pGDIRT->ReleaseDC(NULL);
hr = m_pRenderTarget->EndDraw();
I find the GDI content not rendered completely, just like it is clipped by the Direct2D content, like this:
If I don't call "m_pRenderTarget->Clear()" method, the GDI content can rendered correctly, like this:
So what's wrong with my code, how to draw Gdi content to a compatible target correctly?
Pay close attention to the documentation and sample code at https://msdn.microsoft.com/en-us/library/windows/desktop/dd370971(v=vs.85).aspx
In particular, you should not overlap Direct2D and GDI rendering. Call EndDraw before GetDC.
Does anyone know how to assign a window region (SetWindowRgn or Control.Region in WinForms) without killing the theming in the non-client area?
For example, running the following generates a Windows 2000-style unthemed title bar, border, etc:
var form = new Form { Width=500, Height=500, BackColor = Color.Azure };
form.Text = "But soft, what light through yonder window breaks?";
var region = new Region (new Rectangle (Point.Empty, form.Size));
region.Exclude (new Rectangle (100, 100, 300, 300));
form.Region = region;
form.ShowDialog();
I'm guessing it's to do with this MSDN article which says:
As long as a window has a non-NULL
region applied to it (SetWindowRgn),
the UxTheme Manager assumes that this
is a specialized window and the window
will not use visual styles.
...hence UxThemes assumes it's a specialized window. Is there a way to tell the UxTheme Manager explicitly to theme a window?
The answer to your question is that you cannot.
But a workaround, to give you a transparent section in your form, would be to add the WS_EX_LAYERED extended window style to your form. Then you can tell the Window Manager that you want to use a chroma-color key to make part of your form transparent:
SetLayeredWindowAttributes(
Form.Handle, // __in HWND hwnd,
RGB(0, 255, 0), //green is the color key __in COLORREF crKey,
255, //window is opaque otherwise __in BYTE bAlpha,
LWA_COLORKEY //use color-key (rather than per-pixel alpha) __in DWORD dwFlags
);
Then you can put your "transparent" area as lime green:
Which then at runtime will be transparent:
Update: When i use layered window to have full transparency mouse events do trickle through to what's underneath. Notice the "flag" icon highlight:
See also
Window Overview -> Window Features -> Layered Windows
SetLayeredWindowAttributes Function
Extended Window Styles
Layered Windows
I am doing the screen shots of IE using PrintWindow. The problem is that some times I get images with black areas. It may be a whole html content what is black, some times only certain areas are black.
The content of the IE is NOT changed between taking shots.
What is strange is that on some computers I get black images very oftern, on some I never get them.
I tested with Fx, and had same black images.
HBITMAP ShootWindow(HWND hWnd)
{
RECT rect = {0};
GetWindowRect(hWnd, & rect);
HDC hDC = GetDC(hWnd);
if(hDC == NULL)
throw "GetDC failed.";
HDC hTargetDC = CreateCompatibleDC(hDC);
if(hTargetDC == NULL)
throw "CreateCompatibleDC failed.";
HBITMAP hBitmap = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
if(hBitmap == NULL)
throw "CreateCompatibleBitmap failed.";
if(!SelectObject(hTargetDC, hBitmap))
throw "SelectObject failed.";
if(!PrintWindow(hWnd, hTargetDC, 0))
throw "PrintWindow failed.";
ReleaseDC(hWnd, hDC);
ReleaseDC(hWnd, hTargetDC);
return hBitmap;
}
I have found some links, but they give no answer:
http://www.vbforums.com/showthread.php?t=555250
http://www.codeguru.com/forum/archive/index.php/t-357211.html
http://social.msdn.microsoft.com/forums/en-US/winforms/thread/3e3decd8-ced1-4f17-a745-466e5aa91391/
This seems to be common when taking screenshots of applications that are using the GPU. BitBlt can successfully copy pixels where PrintWindow fails.
WINDOWINFO wi;
GetWindowInfo(hWnd, &wi);
BitBlt(hdc, 0, 0, rect.right - rect.left, rect.bottom - rect.top, hDC, wi.rcClient.left, wi.rcClient.top, SRCCOPY);
The issue is that not all programs provide the needed functions to redraw the window when given the PrintWindow function or the WM_PRINT message.
use SetWindowLong to set WS_EX_COMPOSITED do the PrintWindow() set it back to what was before (or leave it with COMPOSITED to speed up... but that will affect the visibility of the real window unless hw acc is disabled) maybe trying to see if WS_EX_LAYERED and setting opacity to 254 would work better
(forgot to say... that this works, but only for the top level window, trying to PrintWindow some child wont work, even if you set the composited on the top level window)
You might take a look at Windows.Graphics.Capture. This a fairly new API that requires Windows 10 version 1803 or better. There is a some code example here.
It should work with applications that use GPU acceleration, such as Chrome.
This is what OBS use being the scenes when you chose "Windows 10" capture method.
EDIT: I've offered a bounty, since I doubt I'll be getting any answers otherwise.
Lately I've been working with listviews and I've decided to add an icon for each item indicating whether it's input or output. The icons add fine, but they're not transparent:
As can be seen, the icons are clearly not transparent. I'm currently doing something like this load the icons:
hImageList = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 2);
if (hImageList != NULL)
{
iIN = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(101)));
iOUT = ImageList_AddIcon(hImageList, LoadIcon(hInstance, MAKEINTRESOURCE(102)));
}
I've tried messing with the flags for ImageList_Create & LoadIcon/LoadImage but have had no luck and to be honest I've run out of ideas.
Any help would be very appreciated.
First up, ImageList_ReplaceIcon copies the icon data when adding it to an image list. So the HICON needs to be released afterwards.
Next, imagelists are natively bitmaps, not icons. And the way you are creating your imagelist makes the conversion of icon to bitmap very ambiguous. ILC_COLOR32 implies the imagelist should be created as a 32bit dib section, which typically contain transparency information via an embedded alpha channel. ILC_MASK instead implies that the internal bitmaps are DDB bitmaps, with the transparency information stored as a 1bpp mask bitmap.
The quickest solution to your problem - take your two icons:
Merge them into a single bitmap resource thats 32 pels wide by 16 high. Fill the background with a mask color :- purple or something.
Create the bitmap using ILC_COLOR|ILC_MASK
Load the bitmap being sure NOT to use LR_TRANSPARENT.
Add the bitmap using ImageList_AddMasked passing in a COLORREF that represents the mask color.
OR, for a better visual effect...
export your PNG data as a 32x16 32bpp bitmap file containing pre-multiplied alpha channel data.
Create the imagelist using the ILC_COLOR32 value.
LoadImage() with LR_CREATEDIBSECTION to load the bitmap as a 32bpp dib section.
Add the image using ImageList_Add()
(the last option is kind of tricky as the number of tools that support writing out 32bit bmp files with properly pre multiplied alpha channels is rather low).
Edited to add the following code sample. Using a 4bpp bitmap created in the dev environment this works just great :-
HWND hwndCtl = CreateWindowEx(0,WC_LISTVIEW,TEXT("ListView1"),WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL,0,0,cx,cy,hWnd,(HMENU)101,hModule,NULL);
HBITMAP hbm = (HBITMAP)LoadImage(hModule,MAKEINTRESOURCE(IDB_BITMAP1),IMAGE_BITMAP,0,0,0);
COLORREF crMask=RGB(255,0,255);
HIMAGELIST himl = ImageList_Create(16,16,ILC_COLOR|ILC_MASK,2,0);
ImageList_AddMasked(himl,hbm,crMask);
ListView_SetImageList(hwndCtl,himl,LVSIL_NORMAL);
You want to make your icons have a background color that isn't used anywhere else in the icon, like a really ugly purple, and then use LoadImage(..., LR_LOADTRANSPARENT); The flag says look at the first pixel at 0,0 and make everything that color transparent.
Your code looks fine to me, I always use LoadImage instead of LoadIcon but I suspect that doesn't matter. Have you checked that the icons do indeed have transparent areas and don't themselves have a solid background?
My LoadImage calls look like:
HICON hIcon = (HICON)LoadImage(hinstResources,MAKEINTRESOURCE(IDI_ICON),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
Here... Create an ImageList, as suggested, make your icons into a Bitmap, 16 pixels high, by 16*n long, where n= the number of icons...
Set the background color to 255, 0, 255, like you have done.
Then, load it, and add it to the image list as I did here:
m_ImageList.Create(16, 16, ILC_COLOR16 | ILC_MASK, 7, 1);
CBitmap bm;
bm.LoadBitmap(IDB_SUPERTREEICONS);
m_ImageList.Add(&bm, RGB(255, 0, 255));
GetTreeCtrl().SetImageList(&m_ImageList, TVSIL_NORMAL);
Of course, this was written in MFC, but as you know, it's just a wrapper to Win32...
Outside of this, you are going to have to go to a custom draw control, in which you draw the icon over whatever background the icon happens to be sitting on. There isn't really any magic "transparent" color, that I know of, in any of these controls.
In the case of a custom draw, you need to use code like the following:
#define TRANSPARENT_COLOR (255,0,255)
UINT iBitmap = IDB_ICON_UP
CDC *dc = GetDC();
int x = 0, y = 0;
CDC *pDisplayMemDC = new CDC;
CDC *pMaskDC = new CDC;
CDC *pMemDC = new CDC;
CBitmap *pBitmap = new CBitmap;
CBitmap *pMaskBitmap = new CBitmap;
CBitmap *pMemBitmap = new CBitmap;
int cxLogo, cyLogo;
BITMAP bm;
pBitmap->LoadBitmap(iBitmap);
pDisplayMemDC->CreateCompatibleDC(dc);
CBitmap *pOldBitmap = (CBitmap *)pDisplayMemDC->SelectObject(pBitmap);
pBitmap->GetObject(sizeof(bm), &bm);
cxLogo = bm.bmWidth;
cyLogo = bm.bmHeight;
pMaskBitmap->CreateBitmap(cxLogo, cyLogo, 1, 1, NULL);
pMaskDC->CreateCompatibleDC(dc);
CBitmap *pOldMask = (CBitmap *)pMaskDC->SelectObject(pMaskBitmap);
COLORREF oldBkColor = pDisplayMemDC->SetBkColor(TRANSPARENT_COLOR);
pMaskDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCCOPY);
pMemBitmap->CreateCompatibleBitmap(dc, cxLogo, cyLogo);
pMemDC->CreateCompatibleDC(dc);
CBitmap *pOldMem = (CBitmap *)pMemDC->SelectObject(pMemBitmap);
pMemDC->BitBlt(0, 0, cxLogo, cyLogo, dc, x, y, SRCCOPY);
pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCINVERT);
pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pMaskDC, 0, 0, SRCAND);
pMemDC->BitBlt(0, 0, cxLogo, cyLogo, pDisplayMemDC, 0, 0, SRCINVERT);
dc->BitBlt(x, y, cxLogo, cyLogo, pMemDC, 0, 0, SRCCOPY);
delete pMemDC->SelectObject(pOldMem);
delete pMemDC;
delete pMaskDC->SelectObject(pOldMask);
delete pMaskDC;
delete pDisplayMemDC->SelectObject(pOldBitmap);
delete pDisplayMemDC;
This code decides where to draw the icon, and takes a snapshot of the background, creates a mask for the icon, and then draws it over the background, giving it a fully transparent background...
Hope that helps somewhat. If not, please explain in more detail what you are trying to make happen, and what you are seeing, or what you are NOT seeing...
I struggled with the same issue using an ImageList in a Tree View. I eventually got Chris Becke's second solution to work, creating an ImageList using the ILC_COLOR32 flag and using LoadImage() with the LR_CREATEDIBSECTION flag. This solution, and probably also the first solution, requires what is described below.
Transparency (and themes) are only supported with comctl32.dll version 6+, to use the correct version, the pre-processor directive on this page worked for me:
https://learn.microsoft.com/en-us/windows/win32/controls/cookbook-overview