mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 18:57:19 +02:00
788 lines
27 KiB
C#
788 lines
27 KiB
C#
// Copyright (c) Microsoft Corporation
|
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
|
|
namespace MouseWithoutBorders
|
|
{
|
|
public partial class FormHelper : System.Windows.Forms.Form
|
|
{
|
|
private readonly List<FocusArea> focusZone = new();
|
|
private readonly object bmScreenLock = new();
|
|
private long lastClipboardEventTime;
|
|
|
|
private IClipboardHelper remoteClipboardHelper;
|
|
private const string TEXT_TYPE_SEP = "{4CFF57F7-BEDD-43d5-AE8F-27A61E886F2F}";
|
|
|
|
private const int MAX_TEXT_SIZE = 20 * 1024 * 1024;
|
|
private const int MAX_IMAGE_SIZE = 50 * 1024 * 1024;
|
|
|
|
private struct FocusArea
|
|
{
|
|
internal RectangleF Rec;
|
|
internal Color Color;
|
|
|
|
internal FocusArea(RectangleF rec, Color color)
|
|
{
|
|
Rec = rec;
|
|
Color = color;
|
|
}
|
|
}
|
|
|
|
private Point focus1 = Point.Empty;
|
|
private Point focus2 = Point.Empty;
|
|
|
|
public FormHelper()
|
|
{
|
|
remoteClipboardHelper = IpcHelper.CreateIpcClient();
|
|
|
|
if (remoteClipboardHelper == null)
|
|
{
|
|
QuitDueToCommunicationError();
|
|
return;
|
|
}
|
|
|
|
SetDPIAwareness();
|
|
InitializeComponent();
|
|
lastClipboardEventTime = GetTick();
|
|
ClipboardMMHelper.HookClipboard(this);
|
|
}
|
|
|
|
private void SetDPIAwareness()
|
|
{
|
|
int setProcessDpiAwarenessResult = -1;
|
|
|
|
try
|
|
{
|
|
setProcessDpiAwarenessResult = NativeMethods.SetProcessDpiAwareness(2);
|
|
SendLog(string.Format(CultureInfo.InvariantCulture, "SetProcessDpiAwareness: {0}.", setProcessDpiAwarenessResult));
|
|
}
|
|
catch (DllNotFoundException)
|
|
{
|
|
SendLog("SetProcessDpiAwareness is unsupported in Windows 7 and lower.");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
SendLog(e.ToString());
|
|
}
|
|
|
|
try
|
|
{
|
|
if (setProcessDpiAwarenessResult != 0)
|
|
{
|
|
SendLog(string.Format(CultureInfo.InvariantCulture, "SetProcessDPIAware: {0}.", NativeMethods.SetProcessDPIAware()));
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
SendLog(e.ToString());
|
|
}
|
|
}
|
|
|
|
private bool quitDueToCommunicationError;
|
|
|
|
private void QuitDueToCommunicationError()
|
|
{
|
|
if (!quitDueToCommunicationError)
|
|
{
|
|
quitDueToCommunicationError = true;
|
|
|
|
if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
|
|
{
|
|
Logger.LogEvent(Application.ProductName + " cannot be used in a remote desktop or virtual machine session.");
|
|
}
|
|
else
|
|
{
|
|
_ = MessageBox.Show(
|
|
"Unable to connect to Mouse Without Borders process, clipboard sharing is no longer working.\r\nSee EventLog for more information.",
|
|
Text,
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Error);
|
|
}
|
|
|
|
Process.GetCurrentProcess().Kill();
|
|
}
|
|
}
|
|
|
|
private void FormHelper_DragEnter(object sender, DragEventArgs e)
|
|
{
|
|
object o = e.Data.GetData(DataFormats.FileDrop);
|
|
|
|
if (o != null)
|
|
{
|
|
e.Effect = DragDropEffects.Copy;
|
|
Array ar = (string[])o;
|
|
|
|
if (ar.Length > 0)
|
|
{
|
|
string fileName = ar.GetValue(0).ToString();
|
|
Hide();
|
|
|
|
try
|
|
{
|
|
remoteClipboardHelper.SendDragFile(fileName);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogEvent("FormHelper_DragEnter: " + ex.Message, EventLogEntryType.Error);
|
|
QuitDueToCommunicationError();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void TimerHelper_Tick(object sender, EventArgs e)
|
|
{
|
|
lock (bmScreenLock)
|
|
{
|
|
if (picScr == null)
|
|
{
|
|
timerHelper.Stop();
|
|
Hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void FormHelper_Shown(object sender, EventArgs e)
|
|
{
|
|
timerHelper.Start(); // To be sure.
|
|
Hide();
|
|
}
|
|
|
|
internal void SendLog(string log)
|
|
{
|
|
try
|
|
{
|
|
Logger.LogEvent(log, EventLogEntryType.Warning);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.LogEvent(log + " ==> SendLog Exception: " + e.Message, EventLogEntryType.Warning);
|
|
}
|
|
}
|
|
|
|
private long GetTick() // ms
|
|
{
|
|
return DateTime.Now.Ticks / 10000;
|
|
}
|
|
|
|
private string GetClipboardText()
|
|
{
|
|
string st = string.Empty, tmp = ClipboardMMHelper.GetText(TextDataFormat.UnicodeText);
|
|
int txtL = 0, rtfL = 0, htmL = 0;
|
|
|
|
if (tmp != null && (txtL = tmp.Length) > 0)
|
|
{
|
|
st += "TXT" + tmp + TEXT_TYPE_SEP;
|
|
}
|
|
|
|
tmp = ClipboardMMHelper.GetText(TextDataFormat.Rtf);
|
|
|
|
if (tmp != null && (rtfL = tmp.Length) > 0)
|
|
{
|
|
st += "RTF" + tmp + TEXT_TYPE_SEP;
|
|
}
|
|
|
|
tmp = ClipboardMMHelper.GetText(TextDataFormat.Html);
|
|
|
|
if (tmp != null && (htmL = tmp.Length) > 0)
|
|
{
|
|
st += "HTM" + tmp + TEXT_TYPE_SEP;
|
|
}
|
|
|
|
if (st.Length > 0)
|
|
{
|
|
if (st.Length > MAX_TEXT_SIZE)
|
|
{
|
|
st = null;
|
|
|
|
SendLog(string.Format(CultureInfo.CurrentCulture, "GetClipboardText, Text too big: TXT = {0}, RTF = {1}, HTM = {2}.", txtL, rtfL, htmL));
|
|
}
|
|
else
|
|
{
|
|
SendLog(string.Format(CultureInfo.CurrentCulture, "GetClipboardText: TXT = {0}, RTF = {1}, HTM = {2}.", txtL, rtfL, htmL));
|
|
}
|
|
}
|
|
|
|
return st;
|
|
}
|
|
|
|
#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager
|
|
private Image bmScreen;
|
|
private Point startOrg;
|
|
private Point start;
|
|
private Point stop;
|
|
private PictureBox left;
|
|
private PictureBox top;
|
|
private PictureBox right;
|
|
private PictureBox bottom;
|
|
private PictureBox picScr;
|
|
#pragma warning restore CA2213
|
|
private int customScreenCaptureInProgress;
|
|
private int screenLeft;
|
|
private int screenTop;
|
|
|
|
protected override void WndProc(ref Message m)
|
|
{
|
|
const int WM_DRAWCLIPBOARD = 0x0308;
|
|
const int WM_CHANGECBCHAIN = 0x030D;
|
|
const int WM_CLIPBOARDUPDATE = 0x031D;
|
|
|
|
switch (m.Msg)
|
|
{
|
|
case WM_DRAWCLIPBOARD:
|
|
case WM_CLIPBOARDUPDATE:
|
|
ClipboardMMHelper.PassMessageToTheNextViewer(m);
|
|
|
|
if (GetTick() - lastClipboardEventTime < 1000)
|
|
{
|
|
lastClipboardEventTime = GetTick();
|
|
return;
|
|
}
|
|
|
|
if (customScreenCaptureInProgress > 0)
|
|
{
|
|
// 10 secs timeout for a failed capture.
|
|
if (GetTick() - lastClipboardEventTime < 10000)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
customScreenCaptureInProgress = 0;
|
|
}
|
|
}
|
|
|
|
lastClipboardEventTime = GetTick();
|
|
|
|
ByteArrayOrString? data = null;
|
|
bool isFile = false;
|
|
|
|
if (ClipboardMMHelper.ContainsText())
|
|
{
|
|
data = GetClipboardText();
|
|
}
|
|
else if (ClipboardMMHelper.ContainsImage())
|
|
{
|
|
MemoryStream ms = new();
|
|
Image im = ClipboardMMHelper.GetImage();
|
|
|
|
if (im != null)
|
|
{
|
|
im.Save(ms, ImageFormat.Png);
|
|
|
|
if (ms.Length > 0)
|
|
{
|
|
if (ms.Length > MAX_IMAGE_SIZE)
|
|
{
|
|
SendLog("Image from clipboard, image too big: " + ms.Length.ToString(CultureInfo.InvariantCulture));
|
|
}
|
|
else
|
|
{
|
|
data = ms.GetBuffer();
|
|
SendLog("Image from clipboard: " + ms.Length.ToString(CultureInfo.InvariantCulture));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SendLog("ClipboardMMHelper image is 0 in length.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SendLog("ClipboardMMHelper image (GetImage) is null.");
|
|
}
|
|
|
|
ms.Dispose();
|
|
}
|
|
else if (ClipboardMMHelper.ContainsFileDropList())
|
|
{
|
|
StringCollection files = ClipboardMMHelper.GetFileDropList();
|
|
|
|
if (files != null)
|
|
{
|
|
if (files.Count > 0)
|
|
{
|
|
data = files[0];
|
|
isFile = true;
|
|
|
|
SendLog("File from clipboard: " + files[0]);
|
|
}
|
|
else
|
|
{
|
|
SendLog("GetFileDropList returned no file.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SendLog("GetFileDropList returned null.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SendLog("ClipboardMMHelper does not have text/image/file data.");
|
|
return;
|
|
}
|
|
|
|
if (data != null)
|
|
{
|
|
try
|
|
{
|
|
remoteClipboardHelper.SendClipboardData((ByteArrayOrString)data, isFile);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogEvent("WM_DRAWCLIPBOARD: " + ex.Message, EventLogEntryType.Error);
|
|
QuitDueToCommunicationError();
|
|
}
|
|
|
|
GC.Collect();
|
|
}
|
|
else
|
|
{
|
|
SendLog("Null clipboard data returned. See previous messages (if any) for more information.");
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CHANGECBCHAIN:
|
|
if (!ClipboardMMHelper.UpdateNextClipboardViewer(m))
|
|
{
|
|
ClipboardMMHelper.PassMessageToTheNextViewer(m);
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x401:
|
|
screenLeft = 0;
|
|
screenTop = 0;
|
|
|
|
foreach (Screen s in Screen.AllScreens)
|
|
{
|
|
if (s.Bounds.Left < screenLeft)
|
|
{
|
|
screenLeft = s.Bounds.Left;
|
|
}
|
|
|
|
if (s.Bounds.Top < screenTop)
|
|
{
|
|
screenTop = s.Bounds.Top;
|
|
}
|
|
}
|
|
|
|
customScreenCaptureInProgress = 1;
|
|
lastClipboardEventTime = GetTick();
|
|
SendLog("**************************************************\r\nScreen capture triggered.");
|
|
m.Result = new IntPtr(1);
|
|
break;
|
|
|
|
case 0x406:
|
|
if (m.Msg == 0x406)
|
|
{
|
|
lock (bmScreenLock)
|
|
{
|
|
bmScreen = null;
|
|
|
|
for (int i = 0; i < 30; i++)
|
|
{
|
|
Thread.Sleep(100);
|
|
|
|
if (ClipboardMMHelper.ContainsImage())
|
|
{
|
|
bmScreen = ClipboardMMHelper.GetImage();
|
|
customScreenCaptureInProgress = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bmScreen == null)
|
|
{
|
|
customScreenCaptureInProgress = 0;
|
|
SendLog("No image found in the clipboard.");
|
|
}
|
|
else
|
|
{
|
|
Opacity = 1;
|
|
picScr = new PictureBox();
|
|
picScr.Dock = DockStyle.Fill;
|
|
picScr.SizeMode = PictureBoxSizeMode.StretchImage;
|
|
picScr.Image = bmScreen;
|
|
picScr.Refresh();
|
|
Controls.Add(picScr);
|
|
AssignEventHandlers(picScr);
|
|
}
|
|
}
|
|
}
|
|
|
|
MouseMoveHandler();
|
|
break;
|
|
|
|
case 0x407:
|
|
Program.DotForm.SetPosition(m.WParam.ToInt32(), m.LParam.ToInt32());
|
|
Program.DotForm.TopMost = true;
|
|
Program.DotForm.Show();
|
|
Application.DoEvents();
|
|
|
|
// Simulate input to help bring to the foreground, as it doesn't seem to work in every case otherwise.
|
|
NativeMethods.INPUT input = new NativeMethods.INPUT { type = (int)NativeMethods.InputType.INPUT_MOUSE, mi = { } };
|
|
NativeMethods.INPUT[] inputs = new NativeMethods.INPUT[] { input };
|
|
_ = NativeMethods.SendInput(1, inputs, Marshal.SizeOf(typeof(NativeMethods.INPUT)));
|
|
m.Result = SetForeGround() ? new IntPtr(1) : IntPtr.Zero;
|
|
break;
|
|
|
|
case 0x408:
|
|
Program.DotForm.Hide();
|
|
break;
|
|
|
|
case 0x400:
|
|
m.Result = Handle;
|
|
break;
|
|
|
|
case SharedConst.QUIT_CMD:
|
|
Process.GetCurrentProcess().Kill();
|
|
break;
|
|
|
|
default:
|
|
base.WndProc(ref m);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private bool SetForeGround()
|
|
{
|
|
string logTag = nameof(SetForeGround);
|
|
IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();
|
|
|
|
if (foreGroundWindow == Program.DotForm.Handle)
|
|
{
|
|
SendLog($"{logTag}.Foreground window is already the dot form: {foreGroundWindow}.");
|
|
return true;
|
|
}
|
|
|
|
Program.DotForm.Activate();
|
|
|
|
bool setForegroundWindow = NativeMethods.SetForegroundWindow(Program.DotForm.Handle);
|
|
SendLog($"{logTag}.{nameof(NativeMethods.SetForegroundWindow)}({Program.DotForm.Handle}) returned: {setForegroundWindow}.");
|
|
|
|
return LogForeGroundWindow(logTag);
|
|
}
|
|
|
|
private bool LogForeGroundWindow(string logTag)
|
|
{
|
|
IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();
|
|
|
|
if (foreGroundWindow == Program.DotForm.Handle)
|
|
{
|
|
SendLog($"{logTag}.Foreground window is now the dot form: {Program.DotForm.Handle}.");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
SendLog($"{logTag}.Foreground window is: [{foreGroundWindow}].");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void AssignEventHandlers(PictureBox p)
|
|
{
|
|
p.MouseDown += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseDown);
|
|
p.MouseMove += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseMove);
|
|
p.MouseUp += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseUp);
|
|
}
|
|
|
|
private void MouseMoveHandler()
|
|
{
|
|
lock (bmScreenLock)
|
|
{
|
|
if (bmScreen != null && Opacity == 1)
|
|
{
|
|
focusZone.Clear();
|
|
TopMost = true;
|
|
Show();
|
|
|
|
startOrg = new Point(MousePosition.X - screenLeft, MousePosition.Y - screenTop);
|
|
|
|
if (left == null)
|
|
{
|
|
left = new PictureBox();
|
|
left.BackColor = Color.Red;
|
|
Controls.Add(left);
|
|
left.BringToFront();
|
|
AssignEventHandlers(left);
|
|
}
|
|
|
|
left.Left = startOrg.X;
|
|
left.Top = startOrg.Y;
|
|
left.Width = 2;
|
|
left.Height = 100;
|
|
left.Show();
|
|
left.Refresh();
|
|
|
|
if (top == null)
|
|
{
|
|
top = new PictureBox();
|
|
top.BackColor = Color.Red;
|
|
Controls.Add(top);
|
|
top.BringToFront();
|
|
AssignEventHandlers(top);
|
|
}
|
|
|
|
top.Left = startOrg.X;
|
|
top.Top = startOrg.Y;
|
|
top.Height = 2;
|
|
top.Width = 100;
|
|
top.Show();
|
|
top.Refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MouseDownMoveHandler()
|
|
{
|
|
lock (bmScreenLock)
|
|
{
|
|
if (bmScreen != null && left != null && top != null)
|
|
{
|
|
int x = MousePosition.X - screenLeft;
|
|
int y = MousePosition.Y - screenTop;
|
|
|
|
start = new Point(startOrg.X < x ? startOrg.X : x, startOrg.Y < y ? startOrg.Y : y);
|
|
stop = new Point(startOrg.X > x ? startOrg.X : x, startOrg.Y > y ? startOrg.Y : y);
|
|
|
|
left.Left = start.X;
|
|
left.Top = start.Y;
|
|
left.Width = 2;
|
|
left.Height = stop.Y - start.Y;
|
|
left.Show();
|
|
|
|
top.Left = start.X;
|
|
top.Top = start.Y;
|
|
top.Height = 2;
|
|
top.Width = stop.X - start.X;
|
|
top.Show();
|
|
|
|
if (right == null)
|
|
{
|
|
right = new PictureBox();
|
|
right.BackColor = Color.Red;
|
|
Controls.Add(right);
|
|
right.BringToFront();
|
|
AssignEventHandlers(right);
|
|
}
|
|
|
|
right.Left = stop.X;
|
|
right.Top = start.Y;
|
|
right.Width = 2;
|
|
right.Height = stop.Y - start.Y;
|
|
right.Show();
|
|
|
|
if (bottom == null)
|
|
{
|
|
bottom = new PictureBox();
|
|
bottom.BackColor = Color.Red;
|
|
Controls.Add(bottom);
|
|
bottom.BringToFront();
|
|
AssignEventHandlers(bottom);
|
|
}
|
|
|
|
bottom.Left = start.X;
|
|
bottom.Top = stop.Y;
|
|
bottom.Height = 2;
|
|
bottom.Width = stop.X - start.X;
|
|
bottom.Show();
|
|
|
|
TopMost = true;
|
|
Show();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MouseUpHandler(bool canceled = false, bool rightMouseButton = false)
|
|
{
|
|
lock (bmScreenLock)
|
|
{
|
|
MouseDownMoveHandler();
|
|
customScreenCaptureInProgress = 0;
|
|
|
|
if (!canceled && bmScreen != null && left != null && top != null && right != null && bottom != null
|
|
&& stop.X - start.X > 0 && stop.Y - start.Y > 0)
|
|
{
|
|
start = PointInStandardDPI(start);
|
|
stop = PointInStandardDPI(stop);
|
|
Bitmap bm = new(stop.X - start.X, stop.Y - start.Y);
|
|
Graphics g = Graphics.FromImage(bm);
|
|
|
|
try
|
|
{
|
|
g.DrawImage(bmScreen, 0, 0, new Rectangle(start, bm.Size), GraphicsUnit.Pixel);
|
|
g.DrawRectangle(Pens.DarkOrange, 0, 0, stop.X - start.X - 1, stop.Y - start.Y - 1);
|
|
|
|
foreach (FocusArea f in focusZone)
|
|
{
|
|
RectangleF rec = RectangleFInStandardDPI(f.Rec);
|
|
rec.X -= start.X;
|
|
rec.Y -= start.Y;
|
|
|
|
g.DrawEllipse(new Pen(f.Color, 2), rec);
|
|
}
|
|
|
|
if (rightMouseButton)
|
|
{
|
|
try
|
|
{
|
|
string tempFile = Path.GetTempPath() + Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".png";
|
|
SendLog(tempFile);
|
|
bm.Save(tempFile, ImageFormat.Png);
|
|
lastClipboardEventTime = GetTick();
|
|
ClipboardMMHelper.SetText(tempFile);
|
|
}
|
|
catch (IOException ioException)
|
|
{
|
|
SendLog("IO!Exception!: " + ioException.Message);
|
|
}
|
|
catch (ArgumentNullException argException)
|
|
{
|
|
SendLog("ArgNull!Exception!: " + argException.Message);
|
|
}
|
|
catch (ExternalException internalException)
|
|
{
|
|
SendLog("Internal!Exception!: " + internalException.Message);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lastClipboardEventTime = GetTick() - 10000;
|
|
ClipboardMMHelper.SetImage(bm);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
g.Dispose();
|
|
bm.Dispose();
|
|
bmScreen.Dispose();
|
|
bmScreen = null;
|
|
}
|
|
}
|
|
|
|
ShowInTaskbar = false;
|
|
Hide();
|
|
Controls.Clear();
|
|
Opacity = 0.11;
|
|
left?.Dispose();
|
|
top?.Dispose();
|
|
right?.Dispose();
|
|
bottom?.Dispose();
|
|
picScr?.Dispose();
|
|
left = top = right = bottom = picScr = null;
|
|
|
|
SendLog("Screen capture ended.\r\n**************************************************");
|
|
}
|
|
}
|
|
|
|
private void FormHelper_FormClosed(object sender, FormClosedEventArgs e)
|
|
{
|
|
ClipboardMMHelper.UnhookClipboard();
|
|
}
|
|
|
|
private void FormHelper_LocationChanged(object sender, EventArgs e)
|
|
{
|
|
lock (bmScreenLock)
|
|
{
|
|
if (picScr == null && !timerHelper.Enabled)
|
|
{
|
|
Opacity = 0.11;
|
|
timerHelper.Start();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void FormHelper_KeyDown(object sender, KeyEventArgs e)
|
|
{
|
|
if (e.KeyCode == Keys.Escape)
|
|
{
|
|
MouseUpHandler(true);
|
|
}
|
|
|
|
if (focus1.IsEmpty)
|
|
{
|
|
focus1 = stop;
|
|
}
|
|
}
|
|
|
|
private void FormHelper_KeyUp(object sender, KeyEventArgs e)
|
|
{
|
|
focus2 = stop;
|
|
|
|
float x = Math.Min(focus1.X, focus2.X);
|
|
float y = Math.Min(focus1.Y, focus2.Y);
|
|
float w = Math.Abs(focus1.X - focus2.X);
|
|
float h = Math.Abs(focus1.Y - focus2.Y);
|
|
x -= 0.25F * w;
|
|
y -= 0.25F * h;
|
|
w *= 1.5F;
|
|
h *= 1.5F;
|
|
|
|
focusZone.Add(new FocusArea(new RectangleF(x, y, w, h), e.KeyCode == Keys.B ? Color.Blue : e.KeyCode == Keys.G ? Color.Green : Color.Red));
|
|
|
|
focus1 = focus2 = Point.Empty;
|
|
}
|
|
|
|
private void FormHelper_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
if (e.CloseReason == CloseReason.UserClosing)
|
|
{
|
|
e.Cancel = true;
|
|
}
|
|
}
|
|
|
|
private void FormHelper_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
SendLog("Screen capture Mouse down.");
|
|
MouseMoveHandler();
|
|
customScreenCaptureInProgress = 2;
|
|
}
|
|
|
|
private void FormHelper_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
if (customScreenCaptureInProgress == 1)
|
|
{
|
|
MouseMoveHandler();
|
|
}
|
|
else if (customScreenCaptureInProgress == 2)
|
|
{
|
|
MouseDownMoveHandler();
|
|
}
|
|
}
|
|
|
|
private void FormHelper_MouseUp(object sender, MouseEventArgs e)
|
|
{
|
|
MouseUpHandler(false, e.Button == MouseButtons.Right);
|
|
}
|
|
|
|
private Point PointInStandardDPI(Point p)
|
|
{
|
|
// Since the process is DPI awareness, just log and return.
|
|
// TODO: Test in Win8/7/XP.
|
|
SendLog(string.Format(CultureInfo.CurrentCulture, "this.Width={0}, this.Height={1}, bmScreen.Width={2}, bmScreen.Height={3}, x={4}, y={5}", Width, Height, bmScreen.Width, bmScreen.Height, p.X, p.Y));
|
|
return p;
|
|
}
|
|
|
|
private RectangleF RectangleFInStandardDPI(RectangleF r)
|
|
{
|
|
// Since the process is DPI awareness, just return.
|
|
return r;
|
|
}
|
|
}
|
|
}
|