mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
[New Utility]Mouse Without Borders
* Integrate Mouse Without Borders into PowerToys --------- Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
This commit is contained in:
committed by
Jaime Bernardo
parent
a0b9af039d
commit
29eebe16a4
59
src/modules/MouseWithoutBorders/App/Helper/FormDot.Designer.cs
generated
Normal file
59
src/modules/MouseWithoutBorders/App/Helper/FormDot.Designer.cs
generated
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
partial class FormDot
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// FormDot
|
||||
//
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.ClientSize = new System.Drawing.Size(2, 2);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "FormDot";
|
||||
this.Opacity = 0.5D;
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.TopMost = true;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormDot_FormClosing);
|
||||
this.Shown += new System.EventHandler(this.FormDot_Shown);
|
||||
this.VisibleChanged += new System.EventHandler(this.FormDot_VisibleChanged);
|
||||
this.Click += new System.EventHandler(this.FormDot_Click);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
84
src/modules/MouseWithoutBorders/App/Helper/FormDot.cs
Normal file
84
src/modules/MouseWithoutBorders/App/Helper/FormDot.cs
Normal file
@@ -0,0 +1,84 @@
|
||||
// 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.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Windows.Forms;
|
||||
using static MouseWithoutBorders.NativeMethods;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal sealed partial class FormDot : System.Windows.Forms.Form
|
||||
{
|
||||
private int left;
|
||||
private int top;
|
||||
|
||||
internal FormDot()
|
||||
{
|
||||
InitializeComponent();
|
||||
Cursor = CreateDotCursor();
|
||||
}
|
||||
|
||||
public void SetPosition(int left, int top)
|
||||
{
|
||||
this.left = left - 2;
|
||||
this.top = top - 2;
|
||||
}
|
||||
|
||||
private Cursor CreateCursor(Bitmap bmp, int xHotSpot, int yHotSpot)
|
||||
{
|
||||
IconInfo tmp = default;
|
||||
tmp.xHotspot = xHotSpot;
|
||||
tmp.yHotspot = yHotSpot;
|
||||
tmp.fIcon = false;
|
||||
tmp.hbmColor = bmp.GetHbitmap();
|
||||
tmp.hbmMask = bmp.GetHbitmap();
|
||||
return new Cursor(NativeMethods.CreateIconIndirect(ref tmp));
|
||||
}
|
||||
|
||||
private Cursor CreateDotCursor()
|
||||
{
|
||||
Bitmap bitmap = new(32, 32, PixelFormat.Format24bppRgb);
|
||||
bitmap.MakeTransparent(Color.Black);
|
||||
Graphics g = Graphics.FromImage(bitmap);
|
||||
g.DrawLine(Pens.Gray, 0, 0, 1, 1);
|
||||
Cursor c = CreateCursor(bitmap, 0, 0);
|
||||
bitmap.Dispose();
|
||||
return c;
|
||||
}
|
||||
|
||||
private void FormDot_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
if (e.CloseReason == CloseReason.UserClosing)
|
||||
{
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void FormDot_Shown(object sender, EventArgs e)
|
||||
{
|
||||
MoveMe();
|
||||
}
|
||||
|
||||
private void MoveMe()
|
||||
{
|
||||
Left = left;
|
||||
Top = top;
|
||||
Width = 4;
|
||||
Height = 4;
|
||||
}
|
||||
|
||||
private void FormDot_Click(object sender, EventArgs e)
|
||||
{
|
||||
IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();
|
||||
Program.FormHelper.SendLog($"{nameof(FormDot_Click)}.Foreground window ({foreGroundWindow}) is " + (foreGroundWindow == Handle ? string.Empty : "not ") + $"the dot form: {Program.DotForm.Handle}.");
|
||||
}
|
||||
|
||||
private void FormDot_VisibleChanged(object sender, EventArgs e)
|
||||
{
|
||||
MoveMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
120
src/modules/MouseWithoutBorders/App/Helper/FormDot.resx
Normal file
120
src/modules/MouseWithoutBorders/App/Helper/FormDot.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
77
src/modules/MouseWithoutBorders/App/Helper/FormHelper.Designer.cs
generated
Normal file
77
src/modules/MouseWithoutBorders/App/Helper/FormHelper.Designer.cs
generated
Normal file
@@ -0,0 +1,77 @@
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
partial class FormHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormHelper));
|
||||
this.timerHelper = new System.Windows.Forms.Timer(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// timerHelper
|
||||
//
|
||||
this.timerHelper.Interval = 2000;
|
||||
this.timerHelper.Tick += new System.EventHandler(this.TimerHelper_Tick);
|
||||
//
|
||||
// FormHelper
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
|
||||
this.ClientSize = new System.Drawing.Size(60, 60);
|
||||
this.ControlBox = false;
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.KeyPreview = true;
|
||||
this.Name = "FormHelper";
|
||||
this.Opacity = 0.11D;
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "Mouse without Borders Helper";
|
||||
this.TopMost = true;
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormHelper_FormClosing);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormHelper_FormClosed);
|
||||
this.Shown += new System.EventHandler(this.FormHelper_Shown);
|
||||
this.LocationChanged += new System.EventHandler(this.FormHelper_LocationChanged);
|
||||
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.FormHelper_DragEnter);
|
||||
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FormHelper_KeyDown);
|
||||
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.FormHelper_KeyUp);
|
||||
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FormHelper_MouseDown);
|
||||
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FormHelper_MouseMove);
|
||||
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FormHelper_MouseUp);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Timer timerHelper;
|
||||
}
|
||||
}
|
||||
782
src/modules/MouseWithoutBorders/App/Helper/FormHelper.cs
Normal file
782
src/modules/MouseWithoutBorders/App/Helper/FormHelper.cs
Normal file
@@ -0,0 +1,782 @@
|
||||
// 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();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
198
src/modules/MouseWithoutBorders/App/Helper/FormHelper.resx
Normal file
198
src/modules/MouseWithoutBorders/App/Helper/FormHelper.resx
Normal file
@@ -0,0 +1,198 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="timerHelper.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAIAICAAAAAAGACoDAAAJgAAABAQAAAAABgAaAMAAM4MAAAoAAAAIAAAAEAAAAABABgAAAAAAAAM
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAEo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAEo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32FIv3Eo32AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32EYv3Eo32AAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32BIf3GJD2Eov3Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAEo32CYn3GZD2DIf4Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
QZv0FI72GpH2FIv3Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32Con3HJH2FI72QJv0
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANJb1FI72GZD2Ho/2Eo32AAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAEo32Eo32G5H2FI72NJb1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAPpr0Fo72GZD2Don3Eo32AAAAAAAAAAAAAAAAAAAAAAAAEo32BIj3HJH2
|
||||
Fo72Ppr0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpn0
|
||||
Fo/2GZD2II/2Eo32AAAAAAAAAAAAAAAAEo32E432HJH2Fo/2Opn0AAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIo/2HJH2GZD2Foz3Eo32AAAAAAAAEo32
|
||||
Cor3HJH2HJH2Io/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZ7zA4f3Con3Con3Con3Con3
|
||||
Con3Con3Con3DYv3HJH2HpL2HZH2GZD2GIz2Eo32Eo32C4v3HJH2HpL2HpL2HJH2DYv3Con3Con3Con3
|
||||
Con3Con3Con3Con3AIX4Eo32WqLzD432Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2F4/2HZH2HpL2HpL2HZH2
|
||||
EY32O5j0Npf0FI72HZH2HpL2HpL2HJH2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2C4v3Eo32frPvSaPy
|
||||
TqTyTqTyTqTyTqTyTqTyTqTyT6XyV6jxIJH2HZH2HpL2Eo32Opv0AAAAAAAALJT2FY/2HpL2HJH2K5T1
|
||||
V6nxT6TyTqTyTqTyTqTyTqTyTqTyTqTyRqHzEo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZH2
|
||||
GY72HZH2Eo32OJr0AAAAAAAAAAAAAAAAKZP1FY/2G5H2I5H2Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZH2Ho/2GpH2Eo32PZz0AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAL5b1FY/2GJD2KJT2Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAHZH2G472GZD2E432Npn0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKJL1Fo/2Fo/2J5P2Eo32AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZH2HpD2GJD2FI72MZj1AAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAJZL2Fo/2Fo/2KpT1Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAHZH2FIv3GZD2E472MZf1AAAAAAAABAQEBAQEAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAA
|
||||
JZL2Fo/2Fo/2H4/3Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32H5D2Doz2M5j0AAAA
|
||||
AAAABAQEBAQEBAQEBAQEAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAJpL1D4z2J5T1Eo32AAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32NJj1AAAAAAAAAAAABAQE//jwBAQEBAQEAAAAAAAABAQE
|
||||
//jwBAQEBAQEAAAAAAAAAAAAMJb1Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQE
|
||||
AAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////////////////v//f/x/
|
||||
/j/4P/wf/B/4P/4P8H//B+D//4PB///Bg/8AAAAAAAAAAAABgAD/g8H//wfg//4P8H/8H/g/+DPMH/hh
|
||||
hh/84Yc//+GH///zz/////////////////////////////////8oAAAAEAAAACAAAAABABgAAAAAAAAD
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32AAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32GJD2Eo32AAAAAAAAAAAAAAAAAAAA
|
||||
AAAACYn3DIf4AAAAAAAAAAAAAAAAAAAAAAAANJb1GZD2Eo32AAAAAAAAAAAAAAAAEo32FI72AAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAOpn0GZD2Eo32AAAAAAAAE432Fo/2AAAAAAAAAAAAAAAAAAAAA4f3Con3
|
||||
Con3Con3DYv3HpL2GZD2Eo32C4v3HpL2HJH2Con3Con3Con3Con3Eo32SaPyTqTyTqTyTqTyV6jxHZH2
|
||||
Eo32AAAALJT2HpL2K5T1T6TyTqTyTqTyTqTyEo32AAAAAAAAAAAAAAAAHo/2Eo32AAAAAAAAAAAAL5b1
|
||||
GJD2Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAHpD2FI72AAAAAAAAAAAAAAAAAAAAJZL2Fo/2Eo32AAAA
|
||||
AAAAAAAAAAAAAAAAEo32Doz2AAAABAQEBAQEAAAABAQEBAQEAAAAJpL1J5T1AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAABAQEBAQEAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA//8AAP//AAD//wAA7/8AAMfnAADjzwAA8Z8AAAAAAAABAAAA848AAOfHAADJJwAA+T8AAP//
|
||||
AAD//wAA//8AAA==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,84 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\..\Version.props" />
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<AssemblyName>PowerToys.MouseWithoutBordersHelper</AssemblyName>
|
||||
<DisableWinExeOutputInference>true</DisableWinExeOutputInference>
|
||||
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\MouseWithoutBorders</OutputPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<SelfContained>true</SelfContained>
|
||||
<Version>$(Version).0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'">
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
|
||||
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DefineConstants>MM_HELPER;TRACE;DEBUG;SHOW_ON_WINLOGON CODE_ANALYSIS CUSTOMIZE_LOGON_SCREEN</DefineConstants>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DefineConstants>MM_HELPER;TRACE;SHOW_ON_WINLOGON CODE_ANALYSIS CUSTOMIZE_LOGON_SCREEN</DefineConstants>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<NoWarn>
|
||||
</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>..\Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<NoWin32Manifest>true</NoWin32Manifest>
|
||||
</PropertyGroup>
|
||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||
<PropertyGroup>
|
||||
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="Resources\**" />
|
||||
<Compile Remove="Service\**" />
|
||||
<EmbeddedResource Remove="Resources\**" />
|
||||
<EmbeddedResource Remove="Service\**" />
|
||||
<ExcludeFromStyleCop Remove="Service\**" />
|
||||
<None Remove="Resources\**" />
|
||||
<None Remove="Service\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Class\IClipboardHelper.cs">
|
||||
<Link>IClipboardHelper.cs</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="MouseWithoutBordersHelper.exe.manifest">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.CsWinRT"/>
|
||||
<PackageReference Include="Microsoft.DotNet.UpgradeAssistant.Extensions.Default.Analyzers">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Windows.Compatibility" />
|
||||
<PackageReference Include="StreamJsonRpc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
<ProjectReference Include="..\..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
874
src/modules/MouseWithoutBorders/App/Helper/NativeMethods.cs
Normal file
874
src/modules/MouseWithoutBorders/App/Helper/NativeMethods.cs
Normal file
@@ -0,0 +1,874 @@
|
||||
// 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.
|
||||
|
||||
// <summary>
|
||||
// Windows APIs.
|
||||
// </summary>
|
||||
// <history>
|
||||
// 2008 created by Truong Do (ductdo).
|
||||
// 2009-... modified by Truong Do (TruongDo).
|
||||
// 2023- Included in PowerToys.
|
||||
// </history>
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
// We are sure we dont have managed resource in KEYBDINPUT, IntPtr just holds a value
|
||||
[module: SuppressMessage("Microsoft.Design", "CA1049:TypesThatOwnNativeResourcesShouldBeDisposable", Scope = "type", Target = "MouseWithoutBorders.NativeMethods+KEYBDINPUT", Justification = "Dotnet port with style preservation")]
|
||||
|
||||
// Some other minor issues
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#ConvertStringSidToSid(System.String,System.IntPtr&)", MessageId = "0", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#DrawText(System.IntPtr,System.String,System.Int32,MouseWithoutBorders.NativeMethods+RECT&,System.UInt32)", MessageId = "1", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#SetWindowText(System.IntPtr,System.String)", MessageId = "1", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#FindWindow(System.String,System.String)", MessageId = "0", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#FindWindow(System.String,System.String)", MessageId = "1", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#GetWindowText(System.IntPtr,System.Text.StringBuilder,System.Int32)", MessageId = "1", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#keybd_event(System.Byte,System.Byte,System.UInt32,System.Int32)", MessageId = "3", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#SendMessage(System.IntPtr,System.Int32,System.IntPtr,System.IntPtr)", MessageId = "return", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Scope = "member", Target = "MouseWithoutBorders.NativeMethods+KEYBDINPUT.#dwExtraInfo", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Scope = "member", Target = "MouseWithoutBorders.NativeMethods+INPUT64.#type", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#TerminateProcess(System.IntPtr,System.IntPtr)", MessageId = "1", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#GetClassName(System.IntPtr,System.Text.StringBuilder,System.Int32)", MessageId = "1", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#GetClassName(System.IntPtr,System.Text.StringBuilder,System.Int32)", MessageId = "return", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#GetAsyncKeyState(System.IntPtr)", MessageId = "0", Justification = "Dotnet port with style preservation")]
|
||||
[module: SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Scope = "member", Target = "MouseWithoutBorders.NativeMethods.#GetAsyncKeyState(System.IntPtr)", MessageId = "return", Justification = "Dotnet port with style preservation")]
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal sealed partial class NativeMethods
|
||||
{
|
||||
internal struct IconInfo
|
||||
{
|
||||
internal bool fIcon;
|
||||
internal int xHotspot;
|
||||
internal int yHotspot;
|
||||
internal IntPtr hbmMask;
|
||||
internal IntPtr hbmColor;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr CreateIconIndirect(ref IconInfo icon);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool SetProcessDPIAware();
|
||||
|
||||
[DllImport("Shcore.dll", SetLastError = true)]
|
||||
internal static extern int SetProcessDpiAwareness(uint type); // Win 8.1 and up, DPI can be per monitor.
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
internal static extern uint WTSGetActiveConsoleSessionId();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, int action, IntPtr changeInfo);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool PostMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = false)]
|
||||
internal static extern IntPtr GetDesktopWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr GetWindowDC(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern int DrawText(IntPtr hDC, string lpString, int nCount, ref RECT lpRect, uint uFormat);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern uint SetTextColor(IntPtr hdc, int crColor);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern uint SetBkColor(IntPtr hdc, int crColor);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetWindowText(IntPtr hWnd, string lpString);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern int GetWindowTextLength(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DestroyIcon(IntPtr handle);
|
||||
|
||||
[DllImport("user32")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetCursorPos(int X, int Y);
|
||||
|
||||
[DllImport("user32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool GetCursorPos(ref Point p);
|
||||
|
||||
[DllImport("advapi32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool DuplicateTokenEx(
|
||||
IntPtr ExistingTokenHandle,
|
||||
uint dwDesiredAccess,
|
||||
ref SECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
int TokenType,
|
||||
int ImpersonationLevel,
|
||||
ref IntPtr DuplicateTokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool ConvertStringSidToSid(string StringSid, out IntPtr ptrSid);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, ref TOKEN_MANDATORY_LABEL TokenInformation, uint TokenInformationLength);
|
||||
|
||||
[SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", Justification = "Dotnet port with style preservation")]
|
||||
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CreateProcessAsUser(
|
||||
IntPtr hToken,
|
||||
string lpApplicationName,
|
||||
string lpCommandLine,
|
||||
ref SECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
ref SECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
|
||||
int dwCreationFlags,
|
||||
IntPtr lpEnvironment,
|
||||
string lpCurrentDirectory,
|
||||
ref STARTUPINFO lpStartupInfo,
|
||||
out PROCESS_INFORMATION lpProcessInformation);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool EnumDisplayMonitors(
|
||||
IntPtr hdc,
|
||||
IntPtr lprcClip,
|
||||
EnumMonitorsDelegate lpfnEnum,
|
||||
IntPtr dwData);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool GetMonitorInfo(IntPtr hMonitor, ref MonitorInfoEx lpmi);
|
||||
|
||||
[DllImport("User32.dll")]
|
||||
internal static extern int FindWindow(string ClassName, string WindowName);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
internal static extern uint GetCurrentThreadId();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern IntPtr GetThreadDesktop(uint dwThreadId);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern short GetAsyncKeyState(IntPtr vKey);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct POINT
|
||||
{
|
||||
internal int x;
|
||||
internal int y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CURSORINFO
|
||||
{
|
||||
public int cbSize;
|
||||
public int flags;
|
||||
public IntPtr hCursor;
|
||||
public POINT ptScreenPos;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern bool GetCursorInfo(out CURSORINFO ci);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool AddClipboardFormatListener(IntPtr hwnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool RemoveClipboardFormatListener(IntPtr hwnd);
|
||||
|
||||
#if USE_GetSecurityDescriptorSacl
|
||||
internal enum SE_OBJECT_TYPE
|
||||
{
|
||||
SE_UNKNOWN_OBJECT_TYPE = 0,
|
||||
SE_FILE_OBJECT,
|
||||
SE_SERVICE,
|
||||
SE_PRINTER,
|
||||
SE_REGISTRY_KEY,
|
||||
SE_LMSHARE,
|
||||
SE_KERNEL_OBJECT,
|
||||
SE_WINDOW_OBJECT,
|
||||
SE_DS_OBJECT,
|
||||
SE_DS_OBJECT_ALL,
|
||||
SE_PROVIDER_DEFINED_OBJECT,
|
||||
SE_WMIGUID_OBJECT,
|
||||
SE_REGISTRY_WOW64_32KEY
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum SECURITY_INFORMATION : uint
|
||||
{
|
||||
LABEL_SECURITY_INFORMATION = 0x00000010
|
||||
}
|
||||
|
||||
[StructLayoutAttribute(LayoutKind.Explicit)]
|
||||
internal struct SECURITY_DESCRIPTOR
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public byte revision;
|
||||
|
||||
[FieldOffset(1)]
|
||||
public byte size;
|
||||
|
||||
[FieldOffset(2)]
|
||||
public short control;
|
||||
|
||||
[FieldOffset(4)]
|
||||
public IntPtr owner;
|
||||
|
||||
[FieldOffset(8)]
|
||||
public IntPtr group;
|
||||
|
||||
[FieldOffset(12)]
|
||||
public IntPtr sacl;
|
||||
|
||||
[FieldOffset(16)]
|
||||
public IntPtr dacl;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ACL { public byte AclRevision; public byte Sbz1; public int AclSize; public int AceCount; public int Sbz2; }
|
||||
|
||||
[DllImport("advapi32", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor(string StringSecurityDescriptor,
|
||||
UInt32 StringSDRevision, out SECURITY_DESCRIPTOR SecurityDescriptor, out UInt64 SecurityDescriptorSize);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
internal static extern int GetSecurityDescriptorSacl([MarshalAs(UnmanagedType.Struct)] ref SECURITY_DESCRIPTOR pSecurityDescriptor, int lpbSaclPresent, [MarshalAs(UnmanagedType.Struct)] ref ACL pSacl, int lpbSaclDefaulted);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
|
||||
internal static extern uint SetNamedSecurityInfo(
|
||||
string pObjectName,
|
||||
SE_OBJECT_TYPE ObjectType,
|
||||
SECURITY_INFORMATION SecurityInfo,
|
||||
IntPtr psidOwner,
|
||||
IntPtr psidGroup,
|
||||
IntPtr pDacl,
|
||||
IntPtr pSacl);
|
||||
#endif
|
||||
|
||||
#if SINGLE_PROCESS
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetThreadDesktop(IntPtr hDesktop);
|
||||
#endif
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern IntPtr OpenInputDesktop(uint dwFlags, [MarshalAs(UnmanagedType.Bool)] bool fInherit, uint dwDesiredAccess);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool GetUserObjectInformation(IntPtr hObj, int nIndex, [Out] byte[] pvInfo, int nLength, out uint lpnLengthNeeded);
|
||||
|
||||
[DllImport("gdi32.dll")]
|
||||
internal static extern uint SetPixel(IntPtr hdc, int X, int Y, uint crColor);
|
||||
|
||||
internal const int WM_SHOW_DRAG_DROP = 0x400;
|
||||
internal const int WM_HIDE_DRAG_DROP = 0x401;
|
||||
internal const int WM_CHECK_EXPLORER_DRAG_DROP = 0x402;
|
||||
internal const int WM_QUIT = 0x403;
|
||||
internal const int WM_SWITCH = 0x404;
|
||||
internal const int WM_HIDE_DD_HELPER = 0x405;
|
||||
internal const int WM_SHOW_SETTINGS_FORM = 0x406;
|
||||
|
||||
internal static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
|
||||
|
||||
// internal static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
|
||||
// internal static readonly IntPtr HWND_TOP = new IntPtr(0);
|
||||
// internal static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
|
||||
internal const uint SWP_NOSIZE = 0x0001;
|
||||
internal const uint SWP_NOMOVE = 0x0002;
|
||||
internal const uint SWP_NOZORDER = 0x0004;
|
||||
internal const uint SWP_NOREDRAW = 0x0008;
|
||||
internal const uint SWP_SHOWWINDOW = 0x0040;
|
||||
internal const uint SWP_HIDEWINDOW = 0x0080;
|
||||
|
||||
internal const int UOI_FLAGS = 1;
|
||||
internal const int UOI_NAME = 2;
|
||||
internal const int UOI_TYPE = 3;
|
||||
internal const int UOI_USER_SID = 4;
|
||||
internal const uint DESKTOP_WRITEOBJECTS = 0x0080;
|
||||
internal const uint DESKTOP_READOBJECTS = 0x0001;
|
||||
internal const uint DF_ALLOWOTHERACCOUNTHOOK = 0x0001;
|
||||
|
||||
// internal const UInt32 GENERIC_READ = 0x80000000;
|
||||
internal const uint GENERIC_WRITE = 0x40000000;
|
||||
|
||||
// internal const UInt32 GENERIC_EXECUTE = 0x20000000;
|
||||
internal const uint GENERIC_ALL = 0x10000000;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
internal struct RECT
|
||||
{
|
||||
internal int Left;
|
||||
internal int Top;
|
||||
internal int Right;
|
||||
internal int Bottom;
|
||||
}
|
||||
|
||||
// size of a device name string
|
||||
internal const int CCHDEVICENAME = 32;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
internal struct MonitorInfoEx
|
||||
{
|
||||
internal int cbSize;
|
||||
internal RECT rcMonitor;
|
||||
internal RECT rcWork;
|
||||
internal uint dwFlags;
|
||||
|
||||
// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
|
||||
// internal string szDeviceName;
|
||||
}
|
||||
|
||||
// We are WOW
|
||||
[SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Justification = "Dotnet port with style preservation")]
|
||||
[DllImport(
|
||||
"user32.dll",
|
||||
CharSet = CharSet.Auto,
|
||||
CallingConvention = CallingConvention.StdCall,
|
||||
SetLastError = true)]
|
||||
internal static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);
|
||||
|
||||
[DllImport(
|
||||
"user32.dll",
|
||||
CharSet = CharSet.Auto,
|
||||
CallingConvention = CallingConvention.StdCall,
|
||||
SetLastError = true)]
|
||||
internal static extern int UnhookWindowsHookEx(int idHook);
|
||||
|
||||
// In X64, we are running WOW
|
||||
[SuppressMessage("Microsoft.Portability", "CA1901:PInvokeDeclarationsShouldBePortable", Justification = "Dotnet port with style preservation")]
|
||||
[DllImport(
|
||||
"user32.dll",
|
||||
CharSet = CharSet.Auto,
|
||||
CallingConvention = CallingConvention.StdCall)]
|
||||
internal static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
|
||||
|
||||
private enum InputType
|
||||
{
|
||||
INPUT_MOUSE = 0,
|
||||
INPUT_KEYBOARD = 1,
|
||||
INPUT_HARDWARE = 2,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum MOUSEEVENTF
|
||||
{
|
||||
MOVE = 0x0001,
|
||||
LEFTDOWN = 0x0002,
|
||||
LEFTUP = 0x0004,
|
||||
RIGHTDOWN = 0x0008,
|
||||
RIGHTUP = 0x0010,
|
||||
MIDDLEDOWN = 0x0020,
|
||||
MIDDLEUP = 0x0040,
|
||||
XDOWN = 0x0080,
|
||||
XUP = 0x0100,
|
||||
WHEEL = 0x0800,
|
||||
VIRTUALDESK = 0x4000,
|
||||
ABSOLUTE = 0x8000,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum KEYEVENTF
|
||||
{
|
||||
KEYDOWN = 0x0000,
|
||||
EXTENDEDKEY = 0x0001,
|
||||
KEYUP = 0x0002,
|
||||
UNICODE = 0x0004,
|
||||
SCANCODE = 0x0008,
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms646273(VS.85).aspx
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct MOUSEINPUT
|
||||
{
|
||||
internal int dx;
|
||||
internal int dy;
|
||||
internal int mouseData;
|
||||
internal int dwFlags;
|
||||
internal int time;
|
||||
internal IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct KEYBDINPUT
|
||||
{
|
||||
internal short wVk;
|
||||
internal short wScan;
|
||||
internal int dwFlags;
|
||||
internal int time;
|
||||
internal IntPtr dwExtraInfo;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct HARDWAREINPUT
|
||||
{
|
||||
internal int uMsg;
|
||||
internal short wParamL;
|
||||
internal short wParamH;
|
||||
}
|
||||
|
||||
[SuppressMessage("Microsoft.Portability", "CA1900:ValueTypeFieldsShouldBePortable", Justification = "Dotnet port with style preservation")]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct INPUT
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal int type;
|
||||
|
||||
[FieldOffset(4)]
|
||||
internal MOUSEINPUT mi;
|
||||
|
||||
[FieldOffset(4)]
|
||||
internal KEYBDINPUT ki;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct INPUT64
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
internal int type;
|
||||
|
||||
[FieldOffset(8)]
|
||||
internal MOUSEINPUT mi;
|
||||
|
||||
[FieldOffset(8)]
|
||||
internal KEYBDINPUT ki;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
|
||||
internal static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
|
||||
internal static extern uint SendInput64(uint nInputs, INPUT64[] pInputs, int cbSize);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "GetMessageExtraInfo", SetLastError = true)]
|
||||
internal static extern IntPtr GetMessageExtraInfo();
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "LockWorkStation", SetLastError = true)]
|
||||
internal static extern uint LockWorkStation();
|
||||
|
||||
// [DllImport("user32.dll")]
|
||||
// internal static extern void keybd_event(byte bVk, byte bScan, UInt32 dwFlags, int dwExtraInfo);
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern uint MapVirtualKey(uint uCode, uint uMapType);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct LUID
|
||||
{
|
||||
internal int LowPart;
|
||||
internal int HighPart;
|
||||
}// end struct
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct LUID_AND_ATTRIBUTES
|
||||
{
|
||||
internal LUID Luid;
|
||||
internal int Attributes;
|
||||
}// end struct
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct TOKEN_PRIVILEGES
|
||||
{
|
||||
internal int PrivilegeCount;
|
||||
|
||||
// LUID_AND_ATTRIBUTES
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
internal int[] Privileges;
|
||||
}
|
||||
|
||||
internal const int READ_CONTROL = 0x00020000;
|
||||
|
||||
internal const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
|
||||
|
||||
internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
|
||||
internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
|
||||
internal const int STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
|
||||
|
||||
internal const int STANDARD_RIGHTS_ALL = 0x001F0000;
|
||||
|
||||
internal const int SPECIFIC_RIGHTS_ALL = 0x0000FFFF;
|
||||
|
||||
internal const int TOKEN_IMPERSONATE = 0x0004;
|
||||
internal const int TOKEN_QUERY_SOURCE = 0x0010;
|
||||
internal const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
|
||||
internal const int TOKEN_ADJUST_GROUPS = 0x0040;
|
||||
internal const int TOKEN_ADJUST_SESSIONID = 0x0100;
|
||||
|
||||
internal const int TOKEN_ALL_ACCESS_P = STANDARD_RIGHTS_REQUIRED |
|
||||
TOKEN_ASSIGN_PRIMARY |
|
||||
TOKEN_DUPLICATE |
|
||||
TOKEN_IMPERSONATE |
|
||||
TOKEN_QUERY |
|
||||
TOKEN_QUERY_SOURCE |
|
||||
TOKEN_ADJUST_PRIVILEGES |
|
||||
TOKEN_ADJUST_GROUPS |
|
||||
TOKEN_ADJUST_DEFAULT;
|
||||
|
||||
internal const int TOKEN_ALL_ACCESS = TOKEN_ALL_ACCESS_P | TOKEN_ADJUST_SESSIONID;
|
||||
|
||||
internal const int TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY;
|
||||
|
||||
internal const int TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
|
||||
TOKEN_ADJUST_PRIVILEGES |
|
||||
TOKEN_ADJUST_GROUPS |
|
||||
TOKEN_ADJUST_DEFAULT;
|
||||
|
||||
internal const int TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE;
|
||||
|
||||
internal const int CREATE_NEW_PROCESS_GROUP = 0x00000200;
|
||||
internal const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
|
||||
|
||||
internal const int IDLE_PRIORITY_CLASS = 0x40;
|
||||
internal const int NORMAL_PRIORITY_CLASS = 0x20;
|
||||
internal const int HIGH_PRIORITY_CLASS = 0x80;
|
||||
internal const int REALTIME_PRIORITY_CLASS = 0x100;
|
||||
|
||||
internal const int CREATE_NEW_CONSOLE = 0x00000010;
|
||||
|
||||
internal const string SE_DEBUG_NAME = "SeDebugPrivilege";
|
||||
internal const string SE_RESTORE_NAME = "SeRestorePrivilege";
|
||||
internal const string SE_BACKUP_NAME = "SeBackupPrivilege";
|
||||
|
||||
internal const int SE_PRIVILEGE_ENABLED = 0x0002;
|
||||
|
||||
internal const int ERROR_NOT_ALL_ASSIGNED = 1300;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct PROCESSENTRY32
|
||||
{
|
||||
internal uint dwSize;
|
||||
internal uint cntUsage;
|
||||
internal uint th32ProcessID;
|
||||
internal IntPtr th32DefaultHeapID;
|
||||
internal uint th32ModuleID;
|
||||
internal uint cntThreads;
|
||||
internal uint th32ParentProcessID;
|
||||
internal int pcPriClassBase;
|
||||
internal uint dwFlags;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
||||
internal string szExeFile;
|
||||
}
|
||||
|
||||
internal const uint TH32CS_SNAPPROCESS = 0x00000002;
|
||||
|
||||
// internal static int INVALID_HANDLE_VALUE = -1;
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CloseHandle(IntPtr hSnapshot);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
internal int Length;
|
||||
internal IntPtr lpSecurityDescriptor;
|
||||
internal bool bInheritHandle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct PROCESS_INFORMATION
|
||||
{
|
||||
internal IntPtr hProcess;
|
||||
internal IntPtr hThread;
|
||||
internal uint dwProcessId;
|
||||
internal uint dwThreadId;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct STARTUPINFO
|
||||
{
|
||||
internal int cb;
|
||||
internal string lpReserved;
|
||||
internal string lpDesktop;
|
||||
internal string lpTitle;
|
||||
internal uint dwX;
|
||||
internal uint dwY;
|
||||
internal uint dwXSize;
|
||||
internal uint dwYSize;
|
||||
internal uint dwXCountChars;
|
||||
internal uint dwYCountChars;
|
||||
internal uint dwFillAttribute;
|
||||
internal uint dwFlags;
|
||||
internal short wShowWindow;
|
||||
internal short cbReserved2;
|
||||
internal IntPtr lpReserved2;
|
||||
internal IntPtr hStdInput;
|
||||
internal IntPtr hStdOutput;
|
||||
internal IntPtr hStdError;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct SID_AND_ATTRIBUTES
|
||||
{
|
||||
internal IntPtr Sid;
|
||||
internal int Attributes;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct TOKEN_MANDATORY_LABEL
|
||||
{
|
||||
internal SID_AND_ATTRIBUTES Label;
|
||||
}
|
||||
|
||||
internal const int TOKEN_DUPLICATE = 0x0002;
|
||||
internal const int TOKEN_QUERY = 0x0008;
|
||||
internal const int TOKEN_ADJUST_DEFAULT = 0x0080;
|
||||
internal const int TOKEN_ASSIGN_PRIMARY = 0x0001;
|
||||
internal const uint MAXIMUM_ALLOWED = 0x2000000;
|
||||
internal const int SE_GROUP_INTEGRITY = 0x00000020;
|
||||
|
||||
internal enum SECURITY_IMPERSONATION_LEVEL : int
|
||||
{
|
||||
SecurityAnonymous = 0,
|
||||
SecurityIdentification = 1,
|
||||
SecurityImpersonation = 2,
|
||||
SecurityDelegation = 3,
|
||||
}
|
||||
|
||||
internal enum TOKEN_TYPE : int
|
||||
{
|
||||
TokenPrimary = 1,
|
||||
TokenImpersonation = 2,
|
||||
}
|
||||
|
||||
internal enum TOKEN_INFORMATION_CLASS : int
|
||||
{
|
||||
TokenUser = 1,
|
||||
TokenGroups,
|
||||
TokenPrivileges,
|
||||
TokenOwner,
|
||||
TokenPrimaryGroup,
|
||||
TokenDefaultDacl,
|
||||
TokenSource,
|
||||
TokenType,
|
||||
TokenImpersonationLevel,
|
||||
TokenStatistics,
|
||||
TokenRestrictedSids,
|
||||
TokenSessionId,
|
||||
TokenGroupsAndPrivileges,
|
||||
TokenSessionReference,
|
||||
TokenSandBoxInert,
|
||||
TokenAuditPolicy,
|
||||
TokenOrigin,
|
||||
TokenElevationType,
|
||||
TokenLinkedToken,
|
||||
TokenElevation,
|
||||
TokenHasRestrictions,
|
||||
TokenAccessInformation,
|
||||
TokenVirtualizationAllowed,
|
||||
TokenVirtualizationEnabled,
|
||||
TokenIntegrityLevel,
|
||||
TokenUIAccess,
|
||||
TokenMandatoryPolicy,
|
||||
TokenLogonSid,
|
||||
MaxTokenInfoClass,
|
||||
}
|
||||
|
||||
// [DllImport("kernel32.dll")]
|
||||
// internal static extern int Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
|
||||
|
||||
// [DllImport("kernel32.dll")]
|
||||
// internal static extern int Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
|
||||
|
||||
// [DllImport("kernel32.dll", SetLastError = true)]
|
||||
// internal static extern IntPtr CreateToolhelp32Snapshot(UInt32 dwFlags, UInt32 th32ProcessID);
|
||||
[DllImport("Wtsapi32.dll")]
|
||||
internal static extern uint WTSQueryUserToken(uint SessionId, ref IntPtr phToken);
|
||||
|
||||
[SuppressMessage("Microsoft.Globalization", "CA2101:SpecifyMarshalingForPInvokeStringArguments", MessageId = "1", Justification = "Dotnet port with style preservation")]
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool LookupPrivilegeValue(IntPtr lpSystemName, string lpname, [MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);
|
||||
|
||||
// [DllImport("kernel32.dll")]
|
||||
// [return: MarshalAs(UnmanagedType.Bool)]
|
||||
// static extern bool ProcessIdToSessionId(UInt32 dwProcessId, ref UInt32 pSessionId);
|
||||
[DllImport("kernel32.dll")]
|
||||
internal static extern IntPtr OpenProcess(uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState, int BufferLength, IntPtr PreviousState, IntPtr ReturnLength);
|
||||
|
||||
[DllImport("userenv.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, [MarshalAs(UnmanagedType.Bool)] bool bInherit);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool RevertToSelf();
|
||||
|
||||
internal delegate bool EnumMonitorsDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref NativeMethods.RECT lprcMonitor, IntPtr dwData);
|
||||
|
||||
internal delegate int HookProc(int nCode, int wParam, IntPtr lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||
internal sealed class MEMORYSTATUSEX
|
||||
{
|
||||
public uint dwLength;
|
||||
public uint dwMemoryLoad;
|
||||
public ulong ullTotalPhys;
|
||||
public ulong ullAvailPhys;
|
||||
public ulong ullTotalPageFile;
|
||||
public ulong ullAvailPageFile;
|
||||
public ulong ullTotalVirtual;
|
||||
public ulong ullAvailVirtual;
|
||||
public ulong ullAvailExtendedVirtual;
|
||||
|
||||
public MEMORYSTATUSEX()
|
||||
{
|
||||
this.dwLength = (uint)Marshal.SizeOf(typeof(NativeMethods.MEMORYSTATUSEX));
|
||||
}
|
||||
}
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
internal static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
|
||||
|
||||
/*
|
||||
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||
internal extern static int NetUserGetInfo([MarshalAs(UnmanagedType.LPWStr)] string ServerName,
|
||||
[MarshalAs(UnmanagedType.LPWStr)] string UserName, int level,out IntPtr BufPtr);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
internal struct USER_INFO_10
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string usri10_name;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string usri10_comment;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string usri10_usr_comment;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public string usri10_full_name;
|
||||
}
|
||||
|
||||
[DllImport("Netapi32.dll", SetLastError = true)]
|
||||
internal static extern int NetApiBufferFree(IntPtr Buffer);
|
||||
*/
|
||||
|
||||
internal enum EXTENDED_NAME_FORMAT
|
||||
{
|
||||
NameUnknown = 0,
|
||||
NameFullyQualifiedDN = 1,
|
||||
NameSamCompatible = 2,
|
||||
NameDisplay = 3,
|
||||
NameUniqueId = 6,
|
||||
NameCanonical = 7,
|
||||
NameUserPrincipal = 8,
|
||||
NameCanonicalEx = 9,
|
||||
NameServicePrincipal = 10,
|
||||
NameDnsDomain = 12,
|
||||
}
|
||||
|
||||
[DllImport("secur32.dll", CharSet = CharSet.Unicode)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
internal static extern bool GetUserNameEx(int nameFormat, StringBuilder userName, ref uint userNameSize);
|
||||
|
||||
[DllImport("Shcore.dll", SetLastError = true)]
|
||||
internal static extern int GetDpiForMonitor(IntPtr hMonitor, uint dpiType, out uint dpiX, out uint dpiY);
|
||||
|
||||
private static string GetDNSDomain()
|
||||
{
|
||||
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder userName = new StringBuilder(1024);
|
||||
uint userNameSize = (uint)userName.Capacity;
|
||||
|
||||
if (GetUserNameEx((int)EXTENDED_NAME_FORMAT.NameDnsDomain, userName, ref userNameSize))
|
||||
{
|
||||
string[] nameParts = userName.ToString().Split('\\');
|
||||
if (nameParts.Length != 2)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return nameParts[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this method to figure out if your code is running on a Microsoft computer.
|
||||
/// </summary>
|
||||
internal static bool IsRunningAtMicrosoft()
|
||||
{
|
||||
string domain = GetDNSDomain();
|
||||
|
||||
if (!string.IsNullOrEmpty(domain) && domain.EndsWith("microsoft.com", true, System.Globalization.CultureInfo.CurrentCulture))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
src/modules/MouseWithoutBorders/App/Helper/Program.cs
Normal file
80
src/modules/MouseWithoutBorders/App/Helper/Program.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
// 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.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using ManagedCommon;
|
||||
|
||||
namespace MouseWithoutBorders
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
internal static FormHelper FormHelper;
|
||||
|
||||
private static FormDot dotForm;
|
||||
|
||||
internal static FormDot DotForm
|
||||
{
|
||||
get
|
||||
{
|
||||
return dotForm != null && !dotForm.IsDisposed ? dotForm : (dotForm = new FormDot());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
private static void Main()
|
||||
{
|
||||
if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||
{
|
||||
// TODO: Add logging.
|
||||
// Logger.LogWarning("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.");
|
||||
return;
|
||||
}
|
||||
|
||||
RunnerHelper.WaitForPowerToysRunnerExitFallback(() =>
|
||||
{
|
||||
Application.Exit();
|
||||
});
|
||||
|
||||
string[] args = Environment.GetCommandLineArgs();
|
||||
|
||||
if (args.Length > 1 && !string.IsNullOrEmpty(args[1]))
|
||||
{
|
||||
string command = args[1];
|
||||
string arg = args.Length > 2 && !string.IsNullOrEmpty(args[2]) ? args[2] : string.Empty;
|
||||
|
||||
if (command.Equals("SvcExec", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Process.Start(Path.GetDirectoryName(Application.ExecutablePath) + "\\MouseWithoutBorders.exe", "\"" + arg + "\"");
|
||||
}
|
||||
else if (command.Equals("install", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Process.Start(Path.GetDirectoryName(Application.ExecutablePath) + "\\MouseWithoutBorders.exe");
|
||||
}
|
||||
else if (command.Equals("help-ex", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Process.Start(@"http://www.aka.ms/mm");
|
||||
}
|
||||
else if (command.Equals("InternalError", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
MessageBox.Show(arg, Application.ProductName);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
dotForm = new FormDot();
|
||||
Application.Run(FormHelper = new FormHelper());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user