HDC to HDC for HDC [closed] - c

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;

Related

Screenshot Windows.UI.Core.CoreWindow Immersive UWP

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?

Keeping elements on top using winapi

I've written a little app in winapi which draws animated background like so:
case WM_PAINT:
SelectObject(canvas, images[frame]);
StretchBlt(hdc, 0, 0, 640, 320, canvas, 0, 0, 64, 32, SRCCOPY);
break;
case WM_TIMER:
SelectObject(canvas, images[frame]);
StretchBlt(hdc, 0, 0, 640, 320, canvas, 0, 0, 64, 32, SRCCOPY);
frame += 1;
if (frame == sizeof(images)/sizeof(images[0]))
frame = 0;
break;
It works flawlessly but generates some problems when it comes to drawing other elements. I got some labels in the same window.
Right after first frame is drawn in WM_PAINT labels are still visible. When I replace canvas' (HDC canvas = CreateCompatibleDC(hdc)) image with second frame (in WM_TIMER), labels suddenly disappear - I guess they stay under that new layer that is drawn.
Is there any way to keep some elements always on top or bring them to top right after I redraw the bitmap?

How to create sprite animation using winapi c?

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.

Void to HBITMAP conversion Issue

I keep getting an error at line 123:
123 C:\Dev-Cpp\Window_main_2.c invalid conversion from `void*' to `HBITMAP__*'
I don't know what to make of this and its driving me crazy.
void DrawBitmap(HDC hdcDest, char *filename, int x, int y)
{
HBITMAP image;
BITMAP bm;
HDC hdcMem;
// This is the line that brings about the issue (just ask me if more code is required because
// there is a lot more. Essentially this whole function points to a file and I call this
// function in another function that will compile a windows screen filled with the following
// image path. But I cant get this HBITMAP to agree with the image datatype. Please let me
// know if more info is required and thank you.) The line is below.
image = LoadImage(0, "C:\\Users\\Lillian\\Pictures\\c.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(image, sizeof(BITMAP), &bm);
hdcMem = CreateCompatibleDC(global_hdc);
SelectObject(hdcMem, image);
BitBlt(
global_hdc,
x,
y,
bm.bmWidth,
bm.bmHeight,
hdcMem,
0,
0,
SRCCOPY);
DeleteDC(hdcMem);
DeleteObject((HBITMAP)image);
}
LoadImage() returns a HANDLE. Your need a cast when assigning the result to your variable:
image = (HBITMAP) LoadImage(0, "C:\\Users\\Lillian\\Pictures\\c.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
Also, before you DeleteDC(), you need to select the original HBITMAP back into hdcMem - you need to save it when you call SelectObject() earlier.

Is it possible to create an XOR pen like DrawFocusRect()?

The Win32 GDI DrawFocusRect(HDC, const RECT*) function draws the dotted outline of a rectangle on the desired devince context. The cool thing about this function is it draws the dots using an XOR function so that when you call it a second time on the same device context and rectangle, it erases itself:
RECT rc = { 0, 0, 100, 100 };
DrawFocusRect(hdc, &rc); // draw rectangle
DrawFocusRect(hdc, &rc); // erase the rectangle we just drew
I want to achieve the same dotted line effect as DrawFocusRect() but I just want a line, not a whole rectangle. I tried doing this by passing a RECT of height 1 to DrawFocusRect() but this doesn't work because it XORs the "bottom line" of the rectange on top of the top line so nothing gets painted.
Can I create a plain HPEN that achieves the same effect as DrawFocusRect() so I can draw just a single line?
As #IInspectable commented, you want to use SetROP2(). The other half of the battle is creating the correct pen. Here is how the whole thing shakes out:
HPEN create_focus_pen()
{
LONG width(1);
SystemParametersInfo(SPI_GETFOCUSBORDERHEIGHT, 0, &width, 0);
LOGBRUSH lb = { }; // initialize to zero
lb.lbColor = 0xffffff; // white
lb.lbStyle = BS_SOLID;
return ExtCreatePen(PS.GEOMETRIC | PS.DOT, width, &lb, 0, 0);
}
void draw_focus_line(HDC hdc, HPEN hpen, POINT from, POINT to)
{
HPEN old_pen = SelectObject(hdc, hpen);
int old_rop = SetROP2(R2_XORPEN);
MoveToEx(hdc, from.x, from.y, nullptr);
LineTo(hdc, to.x, to.y);
SelectObject(hdc, old_pen);
SetROP2(old_rop);
}

Resources