I ran into a problem...
I am running 2 displays atm, the one on the left is an 4K (running at 3840x2160) the second one is running on 1280x1024.
The 4k-Display is set to scale 150% via the Windows Settings Menu.
I am currently trying to write an C#-Screenshot-Capture the following way:
for (int f = 0; f < Screen.AllScreens.Length; f++)
{
//Create new Form & FormData
Form rectangleForm = new displayForm();
FormData rectangleFormData = new FormData();
//Set Location
rectangleForm.StartPosition = FormStartPosition.Manual;
rectangleForm.Location = Screen.AllScreens[f].WorkingArea.Location;
//Set BackgroundColor
rectangleForm.BackColor = Color.Wheat;
//Set TranspacencyKey to BackgroundColor
rectangleForm.TransparencyKey = rectangleForm.BackColor;
//Hide Control-, Maximze- and Minimize-Box
rectangleForm.ControlBox = false;
rectangleForm.MaximizeBox = false;
rectangleForm.MinimizeBox = false;
//Set Form-Style
rectangleForm.FormBorderStyle = FormBorderStyle.None;
//Set it to maximze
rectangleForm.WindowState = FormWindowState.Maximized;
//Register Mouse-Events
rectangleForm.MouseDown += rectangleForm_MouseDown;
rectangleForm.MouseMove += rectangleForm_MouseMove;
rectangleForm.Paint += rectangleForm_Paint;
rectangleForm.MouseUp += rectangleForm_MouseUp;
//Initialize FormData
rectangleFormData.rectangleForm = rectangleForm;
resetFormData(rectangleFormData);
}
void rectangleForm_MouseDown(object sender, MouseEventArgs e)
{
FormData formData = rectangleForms[(Form)sender];
formData.formMouseDown = e.Location;
formData.screenshotMouseDown = Cursor.Position;
}
void rectangleForm_MouseMove(object sender, MouseEventArgs e)
{
FormData formData = rectangleForms[(Form)sender];
formData.rectangleForm.Invalidate();
if (e.Button != MouseButtons.Left) return;
formData.formMouseMove = e.Location;
formData.screenshotMouseMove = Cursor.Position;
formData.formRectangle = new Rectangle(Math.Min(formData.formMouseDown.X, formData.formMouseMove.X), Math.Min(formData.formMouseDown.Y, formData.formMouseMove.Y),
Math.Abs(formData.formMouseDown.X - formData.formMouseMove.X), Math.Abs(formData.formMouseDown.Y - formData.formMouseMove.Y));
formData.screenshotRectangle = new Rectangle(Math.Min(formData.screenshotMouseDown.X, formData.screenshotMouseMove.X), Math.Min(formData.screenshotMouseDown.Y, formData.screenshotMouseMove.Y),
Math.Abs(formData.screenshotMouseDown.X - formData.screenshotMouseMove.X), Math.Abs(formData.screenshotMouseDown.Y - formData.screenshotMouseMove.Y));
}
void rectangleForm_Paint(object sender, PaintEventArgs e)
{
FormData formData = rectangleForms[(Form)sender];
formData.rectangleForm.Invalidate();
e.Graphics.DrawRectangle(Pens.Red, formData.formRectangle);
}
void rectangleForm_MouseUp(object sender, MouseEventArgs e) { FormData formData = rectangleForms[(Form)sender]; formData.rectangleForm.Invalidate(); formData.rectangleForm.Hide();
Bitmap bmp = new Bitmap(formData.screenshotRectangle.Width, formData.screenshotRectangle.Height);
using (Graphics G = Graphics.FromImage(bmp))
{
System.Diagnostics.Trace.WriteLine("TOP: " + formData.rectangleForm.Bounds.Top);
System.Diagnostics.Trace.WriteLine("LEFT: " + formData.rectangleForm.Location.X);
System.Diagnostics.Trace.WriteLine("MOUSE X: " + GetCursorPosition().X);
int sourceX = formData.formRectangle.Location.X + formData.rectangleForm.Left;
int sourceY = formData.formRectangle.Location.Y + formData.rectangleForm.Top;
G.CopyFromScreen(new Point(sourceX, sourceY), Point.Empty, formData.screenshotRectangle.Size,
CopyPixelOperation.SourceCopy);
bmp.Save("file.png");
}
endScreenshot();
}
The main problem here is that CopyFromScreen isnt using the windows-scaling which means my Cursor-Position at the TOP-LEFT corner of Display 2 (the small one) is X:5760 Y: 1692 but when I capture an screenshot of ALL Monitors via:
int screenLeft = SystemInformation.VirtualScreen.Left;
int screenTop = SystemInformation.VirtualScreen.Top;
int screenWidth = SystemInformation.VirtualScreen.Width;
int screenHeight = SystemInformation.VirtualScreen.Height;
using (Bitmap bmp = new Bitmap(screenWidth, screenHeight))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.CopyFromScreen(screenLeft, screenTop, 0, 0, bmp.Size);
}
bmp.Save("desktop.png");
}
The TOP-LEFT Corner position of Display 2 is (as mentioned and should normally be without scaling) X: 3840 Y: 1128 (Y seems to be uninteresting for now)
So is there like any option to tell CopyFromScreen to take care of the Windows Scaling (which in my situation only affects display 1 (4k)) or any other solutions?
greetings kevin