Window capture with embeded (setparent) directx game C# - c#

Goal:
- Capture a winform window containing a directx game window (like screenshot, but specific handle).
Scenario:
- Inside a winform I insert a panel1 normally.
- I used the winapi SETPARENT to insert a directx main game window inside the penel1
Problem:
When capturing the winform window (this.handle), the image of the embedded game in the panel1 does not appear. Only the panel appears.
I can't use the ScreenShot method, because it will get another window over.
Example:
public Image CaptureWindow(IntPtr handle, int imgX = 0, int imgY = 0, int largura = 0, int altura = 0)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
if(largura == 0 || altura == 0)
{
largura = windowRect.right - windowRect.left;
altura = windowRect.bottom - windowRect.top;
}
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, largura, altura);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
//GDI32.BitBlt(hdcDest, 0, 0, largura, altura, hdcSrc, 0, 0, GDI32.SRCCOPY);
GDI32.BitBlt(hdcDest, 0, 0, largura, altura, hdcSrc, imgX, imgY, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}

After use SetParent with Directx window, need to refresh the winform.
Just: this.Refresh();

Related

can't capture Full Screen image ?? (with taskbar and any other open windows)

i have a problem with this code :
i need to screenshot the full screen that i see with all things (taskbar, anything open).
my code is just giving me a cropped pic of just one window
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save("D://Changes.jpg", ImageFormat.Jpeg);
Your display settings are set to 125% (or higher) zoom.
Your application isn't DPI aware. You can correct that by updating your application's manifest.
If that doesn't work for you (or you'd rather not use the manifest), you can pinvoke GetDeviceCaps API to get the correct width and height for CopyFromScreen.
Here are your native definitions:
private static class Win32Native
{
public const int DESKTOPVERTRES = 0x75;
public const int DESKTOPHORZRES = 0x76;
[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(IntPtr hDC, int index);
}
And you'd call it as so:
int width, height;
using(var g = Graphics.FromHwnd(IntPtr.Zero))
{
var hDC = g.GetHdc();
width = Win32Native.GetDeviceCaps(hDC, Win32Native.DESKTOPHORZRES);
height = Win32Native.GetDeviceCaps(hDC, Win32Native.DESKTOPVERTRES);
g.ReleaseHdc(hDC);
}
using (var img = new Bitmap(width, height))
{
using (var g = Graphics.FromImage(img))
{
g.CopyFromScreen(0, 0, 0, 0, img.Size);
}
img.Save(#"C:\users\andy\desktop\test.jpg", ImageFormat.Jpeg);
}

Capture a image in specified region in a window

So my goal is to make my program that can take a picture in a rectangular region in a specific window.
Eg.) If I want to capture the black square (full) and only the square (not the any part of the window Y). How would I achieve this ?.
I have tried to use GDI32.dll but I can't seem to be able to configure it to capture only the black square.
public static Bitmap CaptureWindow(IntPtr handle) {
IntPtr hdcSrc = User32.GetWindowDC(handle);
User32.RECT windowRect = new User32.RECT {
left = 467,
right = 1432,
top = 381,
bottom = 994
};
int width = 965;
int height = 613;
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
GDI32.BitBlt(hdcDest, windowRect.right, windowRect.bottom, width, height, hdcSrc, windowRect.left, windowRect.top, GDI32.SRCCOPY);
GDI32.SelectObject(hdcDest, hOld);
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
Image img = Image.FromHbitmap(hBitmap);
GDI32.DeleteObject(hBitmap);
return (Bitmap) img;
}

BitBlt not capturing windows in Hardware accelerated mode

I'm currently working on capturing window snapshots using GDI32.dll though I'm having an issue with Hardware Accelerated Windows that I was wondering if there was a way to circumvent.
I found this amazing bit of code here:
public static Image CaptureWindow(IntPtr handle)
{
IntPtr hdcSrc = User32.GetWindowDC(handle);
Rect windowRect = new Rect();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.Right - windowRect.Left;
int height = windowRect.Bottom - windowRect.Top;
IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);
IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);
Gdi32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
Gdi32.SelectObject(hdcDest, hOld);
Gdi32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
Image image = Image.FromHbitmap(hBitmap);
Gdi32.DeleteObject(hBitmap);
return image;
}
which works for all windows except my chrome windows. Disabling Hardware Acceleration in chrome fixed this though I would prefer not to have to do this.
Anyone have any suggestions/ solutions for this problem?
Thanks for any and all help,
-Paul

Windows7 Winapi Image returns black clientrect

I am having a problem with capturing the graphics of another proccess, because for some users it is just a pure black screen which I capture. Unfortunately I have no idea why this is happening for some users only. I am using the sub window directly instead of the window handle and I ensured by posting the address of the windowhandle and checking with spy++ that this window handle is actually the right one.
const string className = "BlueStacksApp";
const string windowName = "_ctl.Window";
processMainHWND = process.MainWindowHandle;
clientRectangleHandle = User32.FindWindowEx(processMainHWND, 0, className, windowName);
internal Bitmap MakeSnapshot(IntPtr AppWndHandle, RECT rect)
{
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
IntPtr hdcTo = IntPtr.Zero;
IntPtr hdcFrom = IntPtr.Zero;
IntPtr hBitmap = IntPtr.Zero;
try
{
Bitmap clsRet = null;
// get device context of the window...
hdcFrom = User32.GetWindowDC(AppWndHandle);
// create dc that we can draw to...
hdcTo = GDI32.CreateCompatibleDC(hdcFrom);
hBitmap = GDI32.CreateCompatibleBitmap(hdcFrom, width, height);
// validate
if (hBitmap != IntPtr.Zero)
{
// adjust and copy
IntPtr hLocalBitmap = GDI32.SelectObject(hdcTo, hBitmap);
bool result = GDI32.BitBlt(hdcTo, 0, 0, width, height, hdcFrom, 0, 0, GDI32.SRCCOPY);
GDI32.SelectObject(hdcTo, hLocalBitmap);
// create bitmap for window image...
clsRet = Image.FromHbitmap(hBitmap);
}
return clsRet;
}
finally
{
// release the unmanaged resources
if (hdcFrom != IntPtr.Zero)
User32.ReleaseDC(AppWndHandle, hdcFrom);
if (hdcTo != IntPtr.Zero)
GDI32.DeleteDC(hdcTo);
if (hBitmap != IntPtr.Zero)
GDI32.DeleteObject(hBitmap);
}
}

GDI printing not triggering printer

I am writing a printing application in c#. In my application i done following steps
Created Device context (hdc)
Created and started Document StartDoc
Created and Started Page StartPage
Assigned images to context
called BitBlt and assigned conext to right hdc
EndPage(hdc)
EndDoc(hdc)
After all these steps, printing is not trigered. I want to ask that printing should be trigered itself
after all these steps or i need to trigger it by some other method?
Following is source code where CardPrinterLib is class in which i imported gdi32.dll and mapped its function
IntPtr hdc = IntPtr.Zero;
hdc = CardPrinterLib.CreateDC(null, ps.PrinterName, null, IntPtr.Zero);
CardPrinterLib.DOCINFO docinfo = new CardPrinterLib.DOCINFO();
docinfo.cbSize = Marshal.SizeOf(docinfo);
docinfo.pDocName = "PrinterTest";
docinfo.pOutputFile = null;
docinfo.pDataType = null;
docinfo.fwType = 0;
if (CardPrinterLib.StartDoc(hdc, ref docinfo) > 0)
{
if (CardPrinterLib.StartPage(hdc) > 0)
{
Bitmap bmpFrontCard = (Bitmap)imgFrontCard;
Graphics grFrontCard = this.CreateGraphics();
IntPtr dcFrontCard = grFrontCard.GetHdc();
IntPtr chdcFrontCard = CardPrinterLib.CreateCompatibleDC(dcFrontCard);
CardPrinterLib.SelectObject(chdcFrontCard, bmpFrontCard.GetHbitmap());
Graphics ghdcFrontCard = Graphics.FromHdc(chdcFrontCard);
grFrontCard.ReleaseHdc(dcFrontCard);
IntPtr hhdcFrontCard = ghdcFrontCard.GetHdc();
bool resultFrontCard = CardPrinterLib.BitBlt(hdc, 0, 0, 994, 624, hhdcFrontCard, 0, 0, 13369376);
CardPrinterLib.EndPage(hdc);
}
CardPrinterLib.EndDoc(hdc);
CardPrinterLib.DeleteDC(hdc);

Categories

Resources