I followed Huw Collingbourne program in creating a screen capture program with C#. However, I noticed a couple of weird items, and whether I use his created program or my modified program does the same. Specifically I created a program that opens a window that allows you to capture the area. I think it has to do with sittings on my computer, but need to know how to anticipate and fix this if others are going to use my screen capture program! If my display for windows 10 is set to 100% I get a little more than the selected window and if I set display to 125% text then I get a lot of the selected area. Leaving at default size I should be 555, 484 in size. but I capture much larger.
public partial class Form1 : Form
{
//https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getwindowrect
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, ref Rectangle lpRect);
//ICON info
//https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getcursorinfo
[DllImport("user32.dll")]
private static extern bool GetIconInfo(IntPtr hIcon, out ICONINFO piconinfo);
[DllImport("user32.dll")]
private static extern bool GetCursorInfo(out CURSORINFO pci);
public struct POINT
{
public Int32 x;
public Int32 y;
}
public struct ICONINFO
{
public bool fIcon;
public Int32 xHotspot;
public Int32 yHotspot;
public IntPtr hbmMask;
public IntPtr hbmColor;
}
public struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
public Point ptScreenPos;
}
GrabRegionForm grabForm;
public void GrabRect(Rectangle rect)
{
int rectWidth = rect.Width - rect.Left;
int rectHeight = rect.Height - rect.Top;
Bitmap bm = new Bitmap(rectWidth, rectHeight);
Graphics g = Graphics.FromImage(bm);
g.CopyFromScreen(rect.Left, rect.Top, 0, 0, new Size(rectWidth, rectHeight));
DrawMousePointer(g, Cursor.Position.X - rect.Left, Cursor.Position.Y - rect.Top);
this.pb_screengrab.Image = bm;
Clipboard.SetImage(bm);
}
}
public partial class GrabRegionForm : Form
{
public Rectangle formRect;
private Form1 mainForm;
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
private void buttonOK_Click(object sender, EventArgs e)
{
formRect = new Rectangle(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
this.Hide();
mainForm.GrabRect(formRect);
Close();
}
}
ScreenGrab with Display at 100%
IF using earlier than 4.7 and not windows 10 follow Jimi's examples and ensure you sign out and back into windows.
From Jimi https://stackoverflow.com/users/7444103/jimi How to configure an app to run correctly on a machine with a high DPI setting How to configure an app to run correctly on a machine with a high DPI setting (e.g. 150%)?
From Jimi https://stackoverflow.com/users/7444103/jimi Using SetWindowPos with multiple monitors Using SetWindowPos with multiple monitors
If I target my app for windows 10 Only it is incredibly simple now. Microsoft made it even easier to change DPI settings with using 4.7 if using Windows 10.
https://learn.microsoft.com/en-us/dotnet/framework/winforms/high-dpi-support-in-windows-forms
Declare compatibility with Windows 10. Then add the following to the app.manifest file in the XML under the commend for Windows 10 compatibility.
supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"
Enable per-monitor DPI awareness in the app.config file. Windows Forms introduces a new element to support new features and customizations added starting with the .NET Framework 4.7. To take advantage of the new features that support high DPI, add the following to your application configuration file.
Go to the XML line for System.Windows.Forms.ApplicationConfigurationSection
add key="DpiAwareness" value="PerMonitorV2"