I am trying to capture a specific Window in Windows 10.1. The problem is that this window is a UWP application. I found the class and caption of the window using Spy++. However, when I capture the UWP window with my Screenshot function, the output is a black bitmap. My function works for any other windows except this specific one.
The class of the UWP application is Windows.UI.Core.CoreWindow
Here is my code:
HDC hScreenDC = GetWindowDC(ProgramData->TargetWnd);
RECT Rect = {0};
GetWindowRect(ProgramData->TargetWnd, &Rect);
INT Width = Rect.right - Rect.left;
INT Height = Rect.bottom - Rect.top;
HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, Width, Height);
HBITMAP hOldBitmap = (HBITMAP) SelectObject(hMemoryDC, hBitmap);
BitBlt(hMemoryDC, 0, 0, Width, Height, hScreenDC, 0, 0, SRCCOPY | CAPTUREBLT);
hBitmap = (HBITMAP) SelectObject(hMemoryDC, hOldBitmap);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();
DeleteDC(hMemoryDC);
DeleteDC(hScreenDC);
Why is the window not being captured properly and how can I capture it?
Related
I want to make only certain(rectangular) parts of the window transparent.
I have set the window as WS_EX_LAYERED and the WM_PAINT function is as follows:
case WM_PAINT:;
RECT rect;
GetWindowRect(hwnd, &rect);
HDC hdc = GetDC(hwnd);
HDC hdc1 = CreateCompatibleDC(hdc);
HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rect.right - rect.left, rect.bottom - rect.top);
SelectObject(hdc, hBitmap);
SIZE size = {rect.right - rect.left, rect.bottom - rect.top};
BLENDFUNCTION blendFunc = {AC_SRC_OVER, 0, 0, AC_SRC_ALPHA};
UpdateLayeredWindow(hwnd, hdc1, NULL, &size, hdc, NULL, RGB(0, 0, 0), &blendFunc, ULW_ALPHA);
DeleteObject(hBitmap);
DeleteDC(hdc);
ReleaseDC(hwnd, hdc1);
break;
I tried creating a child window, but that doesn't seem to work if I change it's opacity through SetLayeredWindowAttributes, possibly because it mimics the parent windows opacity. I am currently trying to use UpdateLayeredWindow to make certain parts transparent, but I can't even make the entire part transparent using UpdateLayeredWindow.
What is the general way to make certain parts of the window transparent?
I suggest you could refer to the Doc:Using Layered Windows
To have a dialog box come up as a translucent window, first create the
dialog as usual. Then, on WM_INITDIALOG, set the layered bit of the
window's extended style and call SetLayeredWindowAttributes with the
desired alpha value.
The third parameter of SetLayeredWindowAttributes is a value that ranges from 0 to 255, with 0 making the window completely transparent and 255 making it completely opaque.
In order to use layered child windows, the application has to declare itself Windows 8-aware in the manifest. Refer to the thread: How to use WS_EX_LAYERED on child controls
The client area of my window is not aligning properly with the outer non-client area. Take a look, this is when I am not touching the window, just after I launch it:
It's not aligned, although all dimensions across all functions are ok, 500x500 to be exact.
Now, when I resize it, it kind of aligns correctly:
HWND Window = CreateWindowEx(
0,
WindowClass.lpszClassName,
"Handmade Hero",
WS_OVERLAPPED | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
500,
0,
0,
Instance,
0);
RECT rect;
GetClientRect(Window, &rect);
Win32AllocateMemoryBuffer(&GlobalBackBuffer, rect.right, rect.bottom);
Message handling:
case WM_PAINT:
{
PAINTSTRUCT Paint;
HDC DeviceContext = BeginPaint(Window, &Paint);
Dimension rect;
GetClientRect(Window, &rect);
Win32DisplayBufferInWindow(DeviceContext, &GlobalBackBuffer, Dimension.right, Dimension.bottom);
EndPaint(Window, &Paint);
} break;
The stretchdbits:
StretchDIBits(DeviceContext,
0, 0, WindowWidth, WindowHeight,
0, 0, Buffer->BitmapWidth, Buffer->BitmapHeight,
Buffer->BitmapMemory,
&Buffer->BitmapInfo,
DIB_RGB_COLORS, SRCCOPY);
I've been tracking the dimensions across all the program in VS debugger, but couldn't track the problem. Maybe your intuition would spot something?
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I would like to blit hdc to an other hdc, and this hdc will be blit into hdc containing "BeginPaint". But a problem appears, nothing have been drawn.
this is the code, thanks,
HDC hdcMem3 = CreateCompatibleDC(NULL);
SelectObject(hdcMem3, Picture);
BITMAP bitmap;
GetObject(Picture, sizeof(bitmap), &bitmap);
HDC hdcMem2 = CreateCompatibleDC(NULL);
BitBlt(hdcMem2, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem3, 0, 0, SRCCOPY);
DeleteDC(hdcMem3);
BitBlt(hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem2, 0, 0, SRCCOPY);
DeleteDC(hdcMem2);
CreateCompatibleDC creates a device context with a 1-pixel monochrome bitmap.
In your example, the device context referenced by hdcMem3 has a real bitmap, but the DC referenced by hdcMem2 has only the 1-pixel monochrome bitmap. When you blit from hdcMem3 to hdcMem2, you probably end up with 1 black pixel.
What you need is to create a memory bitmap to select into hdcMem2. I assume that, eventually, you're going to display this in a window. Let's assume that you have a device context for the window called hdcWindow.
// Create a memory bitmap that's compatible with the window (screen) and
// the same size as Picture.
hbmpMem2 = CreateCompatibleBitmap(hdcWindow, bitmap.bmWidth, bitmap.bmHeight);
hbmpOld2 = SelectObject(hdcMem2, hbmpMem2);
Now when you do stuff to hdcMem2, it will draw to a real bitmap.
When you're done with hdcMem2, you need to first take care of hbmpMem2:
SelectObject(hdcMem2, hbmpOld2);
DeleteObject(hbmpMem2);
DestroyDC(hdcMem2);
Okay work ! but i've found one thing see :
BITMAP bitmap;
GetObject(picture, sizeof(bitmap), &bitmap);
LPBITMAPINFO Hbitmap = new BITMAPINFO;
Hbitmap->bmiHeader.biSize = sizeof(Hbitmap->bmiHeader);
Hbitmap->bmiHeader.biWidth = 300;
Hbitmap->bmiHeader.biHeight = 300;
Hbitmap->bmiHeader.biPlanes = 1;
Hbitmap->bmiHeader.biBitCount = 32;
Hbitmap->bmiHeader.biCompression = BI_RGB;
Hbitmap->bmiHeader.biSizeImage = 300 * 4 * 300;
Hbitmap->bmiHeader.biClrUsed = 0;
Hbitmap->bmiHeader.biClrImportant = 0;
HDC hdcMem3 = CreateCompatibleDC(NULL);
SelectObject(hdcMem3, picture);
HDC hdcMem2 = CreateCompatibleDC(NULL);
HBITMAP BhdcMem2 = CreateDIBSection(hdcMem2, Hbitmap, DIB_RGB_COLORS,0, 0, 0);
SelectObject(hdcMem2, BhdcMem2);
BitBlt(hdcMem2, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem3, 0, 0, SRCCOPY);
BitBlt(hdcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem2, 0, 0, SRCCOPY);
DeleteDC(hdcMem2);
DeleteDC(hdcMem3);
delete Hbitmap;
How to create sprite animation using winapi without gdi?
im trying to do this:
Sprite(hDC, L"fon.bmp",150, 14, 30, 30, SRCCOPY);
void Sprite(HDC hdc, CHAR* Path, int x, int y, int Width, int Height, DWORD rop)
{
HBITMAP bmp = (HBITMAP) LoadImage(NULL, Path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
HDC memdc = CreateCompatibleDC(hdc);
SelectObject(memdc, bmp);
BitBlt(hdc, x, y, Width, Height, memdc, 0, 0, rop);
}
How i can change frame?
Create a vector and place frames of the animation. Then using some sort of timer, erase the screen and bitblt the next frame's image. This is common way of doing frame based animation and there is nothing specific for winapi.
I followed this code here to take a screenshot. It puts stuff onto an HDC. I was wondering how to get stuff off from this HDC as an array of pixel data. I want to copy it to clipboard and also draw it to a HTML5 canvas.
Do I have to run GetPixel for every point on the HDC, is this the only way to get an array of the bitmap?
HBITMAP MakePrintScreen()
{
HWND hWindow = GetDesktopWindow();
HDC hdcScreen = GetDC(hWindow);
RECT rect;
HBITMAP hbmC;
GetClientRect(hWindow,&rect);
if((hbmC = CreateCompatibleBitmap(hdcScreen,rect.right,rect.bottom)) != NULL)
{
HDC hdcC;
if((hdcC = CreateCompatibleDC(hdcScreen)) != NULL)
{
HBITMAP hbmOld = (HBITMAP)SelectObject(hdcC,hbmC);
BitBlt(hdcC,0,0,rect.right,rect.bottom,hdcScreen,0,0,SRCCOPY);
SelectObject(hdcC,hbmOld);
DeleteDC(hdcC);
}
}
ReleaseDC(hWindow,hdcScreen);
return hbmC;
}
After you have deselected the bitmap from the device context you call GetDIBits to retrieve the bits from the bitmap.