mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 10:09:43 +02:00
Ready for Review - [Mouse Jump] - port upstream WinUI3 code to Mouse Jump (microsoft#48290) (#48393)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
Changes for #48290 to convert Mouse Jump to a WinUI app and remove all
remaining dependencies on WinForms, based on work already done in the
original "FancyMouse" project
(https://github.com/mikeclayton/FancyMouse).
## Notes for reviewers
* the new WinUI build of the app is output into the "/WinUI3Apps"
subfolder
* there's 2 new assemblies that need to be added to the installation as
well - MouseJump.HotKeys.dll and MouseJump.Models.dll. I'm not sure how
to add those to the installer for signing / shipping...
---
### Summary of changes
* New thumbnail layout and rendering code
* WinUI rewrite (winforms version still committed)
* MouseJump.Kicker (dev launch tool)
* CsWin32 for interop
* New assemblies - code reorganised
---
### 1. New layout code
Incorporates latest FancyMouse core layout and rendering logic into
Mouse Jump:
* includes **support** for multiple devices in layout algorithms
* preview still only shows local machine though
* prerequisite for long-term goal #34126
<img width="650" height="709" alt="image"
src="https://github.com/user-attachments/assets/9d1d996d-ed05-4471-b8a5-bd93442f70dc"
/>
### 2. WinUI rewrite
Port latest stable FancyMouse WinUI implementation into Mouse Jump.
Existing WinForms UI left in-situ side-by-side for now - easy to delete
if not needed.
### 3. MouseJump.Kicker
A small dev utility to start Mouse Jump without needing to build the
runner project:
<img width="283" height="274" alt="image"
src="https://github.com/user-attachments/assets/c81bb3f5-5008-48ce-8bc0-eef18413dee6"
/>
### 4. Cswin32 for interop
All win32 interop is now accessed via CsWin32 bindings.
The original win32 bindings were heavily influenced by CsWin32 generated
code (e.g. ```BOOL```, ```HWND```, etc structs), so there's not actually
much change other than deleting a lot of boilerplate code.
### 5. New assemblies
Some code has been reorganised into new assemblies to make it easier to
keep Mouse Jump in sync with upstream FancyMouse
* MouseJump.HotKeys
* MouseJump.Models
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [x] Closes #48290
- [x] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized
- all ui strings come from Resources.resw
- [x] **Dev docs:** Added/updated
- no changes required
- [x] **New binaries:** Added on the required places
- no changes required
- [x] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [x] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [x] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [x] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [x] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
- no changes required
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- **Workflow tests**
- [x] Automated tests passing locally
- [x] Minimal actions workflow (spelling check) passing for PR
- [ ] Full actions workflow (msbuild) passing for PR
- **UI tests**
- [x] Happy path
- [x] preview image appears when activated
- [x] clicking the preview image moves the mouse cursor to the correct
location
- [x] right-click dismisses the preview image without moving the mouse
- [x] pressing escape dismisses the preview image without moving the
mouse
- [x] left or right clicking another application / desktop dismisses the
preview image without moving the mouse
- [x] Works on multiple monitors with different dpi scaling settings
(e.g. 100% vs 150%)
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1411869418
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1412834413
- [x] Handling negative coordinates on non-primary monitors if higher or
"lefter" than primary monitor
*
https://github.com/microsoft/PowerToys/pull/23566#issuecomment-1404931694
- [x] Mouse crosshair moves when Mouse Jump moves the cursor (mouse
clicks *and* keyboard shortcuts)
* #24523
* #24527
- [x] Activating when the preview window is already visible moves the
form to the new mouse position
- [x] Number and key shortcuts (1-9, Home / End, Left / Right Arrow)
jump to the appropriate monitor
- [x] Number-pad shortcuts (1-9 jump to the appropriate monitor
- **Settings tests**
- [x] Changing thumbnail size settings updates the size of the thumbnail
- [x] Changing preview type between Compact, Bezelled and Custom shows
the correct preview type
- [x] Changing custom preview settings shows the correct settings
- [ ] Launching with settings version 1.0 upgrades settings to version
1.1, with "Bezelled" as the default style and the "Custom" settings
preconfigured to match "Bezelled"
- **Lifecycle tests**
- [x] Starting PowerToys Runner launches MouseJump exe when enabled, and
not when disabled
- [x] Enabling / disabling Mouse Jump in settings starts / stops
MouseJump exe
- [x] Exiting PowerToys Runner stops MouseJump exe
- [x] Killing runner exe via Task Manager stops MouseJump exe
- [x] Stopping Visual Studio local debug run stops MouseJump exe
- note - runner needs to be in *non*-admin mode otherwise Visual Studio
debugger disconnects at launch
- [x] Hotkey and size settings are automatically reloaded when config
file is modified from Settings UI
- [ ] ~~Hotkey and size settings are automatically reloaded when config
file is modified manually (e.g. in notepad) while runner and
MouseJumpUI.exe are running~~
- **[Internal Test
Suite](5bc7201ae2/doc/releases/tests-checklist-template.md (mouse-utils))**
- [x] Enable Mouse Jump. Then:
- [x] Press the activation shortcut and verify the screens preview
appears.
- [x] Change activation shortcut and verify that new shortcut triggers
Mouse Jump.
- [x] Click around the screen preview and ensure that mouse cursor
jumped to clicked location.
- [x] Reorder screens in Display settings and confirm that Mouse Jump
reflects the change and still works correctly.
- [x] Change scaling of screens and confirm that Mouse Jump still works
correctly.
- [ ] Unplug additional monitors and confirm that Mouse Jump still works
correctly.
- [x] Disable Mouse Jump and verify that the module is not activated
when you press the activation shortcut.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Boliang Zhang (from Dev Box) <bozhang@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: moooyo <42196638+moooyo@users.noreply.github.com>
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
Copilot-Session: 8e04a72e-3b0f-4ac4-8156-d04ea9b8bb85
This commit is contained in:
BIN
tools/MouseJump.Kicker/Assets/Icons/MouseJump 16x16.ico
Normal file
BIN
tools/MouseJump.Kicker/Assets/Icons/MouseJump 16x16.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
96
tools/MouseJump.Kicker/KickerForm.Designer.cs
generated
Normal file
96
tools/MouseJump.Kicker/KickerForm.Designer.cs
generated
Normal file
@@ -0,0 +1,96 @@
|
||||
// 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.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace MouseJump.Kicker
|
||||
{
|
||||
partial class KickerForm
|
||||
{
|
||||
/// <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()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(KickerForm));
|
||||
ActivationHotkey = new Button();
|
||||
CloseMouseJump = new Button();
|
||||
StartWinUI3 = new Button();
|
||||
SuspendLayout();
|
||||
//
|
||||
// ActivationHotkey
|
||||
//
|
||||
ActivationHotkey.Location = new Point(12, 89);
|
||||
ActivationHotkey.Name = "ActivationHotkey";
|
||||
ActivationHotkey.Size = new Size(260, 70);
|
||||
ActivationHotkey.TabIndex = 1;
|
||||
ActivationHotkey.Text = "Activate Hotkey";
|
||||
ActivationHotkey.UseVisualStyleBackColor = true;
|
||||
ActivationHotkey.Click += ActivationHotkey_Click;
|
||||
//
|
||||
// CloseMouseJump
|
||||
//
|
||||
CloseMouseJump.Location = new Point(12, 165);
|
||||
CloseMouseJump.Name = "CloseMouseJump";
|
||||
CloseMouseJump.Size = new Size(260, 70);
|
||||
CloseMouseJump.TabIndex = 2;
|
||||
CloseMouseJump.Text = "Close MouseJump";
|
||||
CloseMouseJump.UseVisualStyleBackColor = true;
|
||||
CloseMouseJump.Click += CloseMouseJump_Click;
|
||||
//
|
||||
// StartWinUI3
|
||||
//
|
||||
StartWinUI3.Location = new Point(12, 12);
|
||||
StartWinUI3.Name = "StartWinUI3";
|
||||
StartWinUI3.Size = new Size(260, 70);
|
||||
StartWinUI3.TabIndex = 3;
|
||||
StartWinUI3.Text = "Start MouseJump (WinUI3)";
|
||||
StartWinUI3.UseVisualStyleBackColor = true;
|
||||
StartWinUI3.Click += StartWinUI3_Click;
|
||||
//
|
||||
// KickerForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(281, 242);
|
||||
Controls.Add(StartWinUI3);
|
||||
Controls.Add(CloseMouseJump);
|
||||
Controls.Add(ActivationHotkey);
|
||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "KickerForm";
|
||||
Text = "MouseJump Kicker";
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
private Button ActivationHotkey;
|
||||
private Button CloseMouseJump;
|
||||
private Button StartWinUI3;
|
||||
}
|
||||
}
|
||||
131
tools/MouseJump.Kicker/KickerForm.cs
Normal file
131
tools/MouseJump.Kicker/KickerForm.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
// 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.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using MouseJump.Kicker.NativeMethods;
|
||||
|
||||
using static MouseJump.Kicker.NativeMethods.Core;
|
||||
using static MouseJump.Kicker.NativeMethods.Kernel32;
|
||||
using static MouseJump.Kicker.NativeMethods.User32;
|
||||
|
||||
namespace MouseJump.Kicker;
|
||||
|
||||
public partial class KickerForm : Form
|
||||
{
|
||||
public KickerForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private Process? Process
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private void StartWinUI3_Click(object sender, EventArgs e)
|
||||
{
|
||||
// this project builds into "{RepoRoot}\tools\MouseJump.Kicker\bin\x64\Debug"
|
||||
var kickerDir = AppContext.BaseDirectory;
|
||||
|
||||
// step up to the repo root
|
||||
var repoRoot = Path.Combine(kickerDir, "..", "..", "..", "..", "..");
|
||||
|
||||
// and back down to the mouse jump exe
|
||||
var mouseJumpExe = Path.Combine(repoRoot, "x64", "Debug", "WinUI3Apps", "PowerToys.MouseJump.WinUI3.exe");
|
||||
|
||||
this.Process = this.StartMouseJump(mouseJumpExe);
|
||||
}
|
||||
|
||||
private Process StartMouseJump(string mouseJumpExe)
|
||||
{
|
||||
if (!File.Exists(mouseJumpExe))
|
||||
{
|
||||
throw new FileNotFoundException($"Could not find {mouseJumpExe}");
|
||||
}
|
||||
|
||||
var args = new List<string>
|
||||
{
|
||||
Environment.ProcessId.ToString(CultureInfo.InvariantCulture),
|
||||
};
|
||||
return Process.Start(mouseJumpExe, args);
|
||||
}
|
||||
|
||||
private void ActivationHotkey_Click(object sender, EventArgs e)
|
||||
{
|
||||
// find the winui3 window and call SetForegroundWindow on it before signalling
|
||||
// the event. this mirrors the approach used in on_hotkey() in
|
||||
// src/modules/MouseUtils/MouseJump/dllmain.cpp - see the comment there for a
|
||||
// full explanation.
|
||||
//
|
||||
// in brief: the kicker is the foreground process right now (the user just
|
||||
// clicked the button), so it has permission to call SetForegroundWindow and
|
||||
// transfer foreground status directly to the winui3 window. doing this before
|
||||
// signalling the event means that by the time ShowWindowAsync() calls
|
||||
// SetForegroundWindow on its own window, the winui3 process already owns the
|
||||
// foreground and the call succeeds.
|
||||
//
|
||||
// using AllowSetForegroundWindow here instead would be unreliable — the
|
||||
// permission it grants is revoked as soon as the user generates any input
|
||||
// (e.g. moving the mouse), which is almost certain to happen while the
|
||||
// preview is rendering.
|
||||
if (this.Process is not null)
|
||||
{
|
||||
var targetPid = (uint)this.Process.Id;
|
||||
var winUI3Hwnd = HWND.Null;
|
||||
EnumWindows(
|
||||
(hwnd, _) =>
|
||||
{
|
||||
GetWindowThreadProcessId(hwnd, out var windowPid);
|
||||
if (windowPid == targetPid)
|
||||
{
|
||||
winUI3Hwnd = hwnd;
|
||||
return false; // stop enumeration
|
||||
}
|
||||
|
||||
return true; // continue enumeration
|
||||
},
|
||||
LPARAM.Zero);
|
||||
if (!winUI3Hwnd.IsNull)
|
||||
{
|
||||
SetForegroundWindow(winUI3Hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
const string MOUSE_JUMP_SHOW_PREVIEW_EVENT = "Local\\MouseJumpEvent-aa0be051-3396-4976-b7ba-1a9cc7d236a5";
|
||||
var attributes = new LPSECURITY_ATTRIBUTES(
|
||||
new SECURITY_ATTRIBUTES(
|
||||
(uint)Marshal.SizeOf<SECURITY_ATTRIBUTES>(),
|
||||
LPVOID.Null,
|
||||
false));
|
||||
var hEvent = Kernel32.CreateEventW(
|
||||
attributes,
|
||||
false,
|
||||
false,
|
||||
MOUSE_JUMP_SHOW_PREVIEW_EVENT);
|
||||
if (hEvent.IsNull)
|
||||
{
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
var result = Kernel32.SetEvent(hEvent);
|
||||
if (!result)
|
||||
{
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseMouseJump_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Process?.Kill();
|
||||
}
|
||||
}
|
||||
145
tools/MouseJump.Kicker/KickerForm.resx
Normal file
145
tools/MouseJump.Kicker/KickerForm.resx
Normal file
@@ -0,0 +1,145 @@
|
||||
<?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>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.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>
|
||||
AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAMd2C0LGdQpWxHMJVMRyEFS6ZABUsE4AVcBsA1S+awhUvWoGVLxpBlS8aQZUvGkGVLxp
|
||||
BlS8aQZUvGkGVrxpBkLKegz/yXgL/8h3C//GcwD/xIta/8aljP+7aAD/wnAI/8BuCP+/bQf/vmsH/71q
|
||||
B/+9agb/vGkG/7xpBv+8aQb/0IAO/85/Df/Nfg3/ynUA/9SqhP/w8O7/yKGD/8JsAP/HdQ3/xXMK/8Ny
|
||||
Cf/CcQn/wW8I/8BtCP++bAf/vmsH/9WHEP/UhhD/04QP/9F9AP/Vpnj/8/X1/+zp5v/EjVv/yXYA/8t6
|
||||
Dv/JeAv/yHcL/8Z1Cv/FdAr/xHMK/8NxCf/bjhL/2owS/9mLE//TgAD/0KV5//Pz8//3+fr/5t3U/8V/
|
||||
HP/QfgD/zn8O/81+Df/MfAz/y3sM/8p5DP/IeAv/35QV/9+TFv/ZiwD/ypZb/+Pc1f/19fb/9vb2//r7
|
||||
/P/fzb3/y34A/9SFCv/ThBD/0oMG/9GAAP/QgAz/zn4O/+KZGP/hlgD/16dv/+nn5P/09/n/9ff4//f5
|
||||
+v/6/P3/+/7//9y4kv/YhwD/14kA/8qAAP/Hhzj/zH4A/9SFD//knhz/4poA/+S3e//s2L//69O0/+zT
|
||||
s//s0K3/7tGu/+7Pq//lsXT/3o8A/9WTOv/n2s7/9PHs/9zCqv/ThQD/5qMg/+WiIP/loAr/45wA/+Ob
|
||||
AP/jmgD/4pkA/+GXAP/hlQD/4ZcA/+CTAP/kuYf////////////59Oz/25k7/+epJP/npyL/56Yi/+al
|
||||
If/mpCD/5aMf/+WhHv/koB3/5J8d/+SfHP/jmwD/5a1f//z27v//////9OPP/+CYBP/qrif/6a0m/+ms
|
||||
Jf/oqyX/6Kkk/+ioJP/npyP/56Yi/+alIf/mpCD/5aMf/+SfCP/osV//7MGH/+SkPP/jnA7/67EoQuqv
|
||||
KFbqryhU6q4nVOqtJ1TprCZU6KolVOipJFTnqCNU56ciVOamIlTmpSFU5JwAVOKVAFTkngBW5KAhQgAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA//+sQf//rEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAA
|
||||
rEH//6xB//+sQQ==
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
20
tools/MouseJump.Kicker/MouseJump.Kicker.csproj
Normal file
20
tools/MouseJump.Kicker/MouseJump.Kicker.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<!-- Look at Directory.Build.props in root for common stuff as well -->
|
||||
<Import Project="$(RepoRoot)src\Common.Dotnet.CsWinRT.props" />
|
||||
<Import Project="$(RepoRoot)src\Common.SelfContained.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyName>PowerToys.MouseJump.Kicker</AssemblyName>
|
||||
<AssemblyTitle>PowerToys.MouseJump.Kicker</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys MouseJump.Kicker</AssemblyDescription>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
|
||||
<ApplicationHighDpiMode>PerMonitorV2</ApplicationHighDpiMode>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
10
tools/MouseJump.Kicker/MouseJump.Kicker.slnx
Normal file
10
tools/MouseJump.Kicker/MouseJump.Kicker.slnx
Normal file
@@ -0,0 +1,10 @@
|
||||
<Solution>
|
||||
<Configurations>
|
||||
<Platform Name="ARM64" />
|
||||
<Platform Name="x64" />
|
||||
</Configurations>
|
||||
<Project Path="MouseJump.Kicker.csproj">
|
||||
<Platform Solution="*|ARM64" Project="ARM64" />
|
||||
<Platform Solution="*|x64" Project="x64" />
|
||||
</Project>
|
||||
</Solution>
|
||||
44
tools/MouseJump.Kicker/NativeMethods/Core/BOOL.cs
Normal file
44
tools/MouseJump.Kicker/NativeMethods/Core/BOOL.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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.
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A Boolean variable (should be TRUE or FALSE).
|
||||
/// This type is declared in WinDef.h as follows:
|
||||
/// typedef int BOOL;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
/// </remarks>
|
||||
internal readonly struct BOOL
|
||||
{
|
||||
public readonly int Value;
|
||||
|
||||
public BOOL(int value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public BOOL(bool value)
|
||||
{
|
||||
this.Value = value ? 1 : 0;
|
||||
}
|
||||
|
||||
public static implicit operator bool(BOOL value) => value.Value != 0;
|
||||
|
||||
public static implicit operator BOOL(bool value) => new(value);
|
||||
|
||||
public static implicit operator int(BOOL value) => value.Value;
|
||||
|
||||
public static implicit operator BOOL(int value) => new(value);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
40
tools/MouseJump.Kicker/NativeMethods/Core/DWORD.cs
Normal file
40
tools/MouseJump.Kicker/NativeMethods/Core/DWORD.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A 32-bit unsigned integer. The range is 0 through 4294967295 decimal.
|
||||
/// This type is declared in IntSafe.h as follows:
|
||||
/// typedef unsigned long DWORD;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
/// </remarks>
|
||||
internal readonly struct DWORD
|
||||
{
|
||||
public readonly uint Value;
|
||||
|
||||
public DWORD(uint value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public static int Size =>
|
||||
Marshal.SizeOf<DWORD>();
|
||||
|
||||
public static implicit operator uint(DWORD value) => value.Value;
|
||||
|
||||
public static implicit operator DWORD(uint value) => new(value);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
41
tools/MouseJump.Kicker/NativeMethods/Core/HANDLE.cs
Normal file
41
tools/MouseJump.Kicker/NativeMethods/Core/HANDLE.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A handle to an object.
|
||||
/// This type is declared in WinNT.h as follows:
|
||||
/// typedef PVOID HANDLE;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
/// </remarks>
|
||||
internal readonly struct HANDLE
|
||||
{
|
||||
public static readonly HANDLE Null = new(IntPtr.Zero);
|
||||
|
||||
public readonly IntPtr Value;
|
||||
|
||||
public HANDLE(IntPtr value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public bool IsNull => this.Value == HANDLE.Null.Value;
|
||||
|
||||
public static implicit operator IntPtr(HANDLE value) => value.Value;
|
||||
|
||||
public static explicit operator HANDLE(IntPtr value) => new(value);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
41
tools/MouseJump.Kicker/NativeMethods/Core/HWND.cs
Normal file
41
tools/MouseJump.Kicker/NativeMethods/Core/HWND.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A handle to a window.
|
||||
/// This type is declared in WinDef.h as follows:
|
||||
/// typedef HANDLE HWND;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
/// </remarks>
|
||||
internal readonly struct HWND
|
||||
{
|
||||
public static readonly HWND Null = new(IntPtr.Zero);
|
||||
|
||||
public readonly IntPtr Value;
|
||||
|
||||
public HWND(IntPtr value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public bool IsNull => this.Value == HWND.Null.Value;
|
||||
|
||||
public static implicit operator IntPtr(HWND value) => value.Value;
|
||||
|
||||
public static explicit operator HWND(IntPtr value) => new(value);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
37
tools/MouseJump.Kicker/NativeMethods/Core/LPARAM.cs
Normal file
37
tools/MouseJump.Kicker/NativeMethods/Core/LPARAM.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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.
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A message parameter. This type contains information about a message.
|
||||
/// This type is declared in WinDef.h as follows:
|
||||
/// typedef LONG_PTR LPARAM;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
/// </remarks>
|
||||
internal readonly struct LPARAM
|
||||
{
|
||||
public static readonly LPARAM Zero = new(0);
|
||||
|
||||
public readonly nint Value;
|
||||
|
||||
public LPARAM(nint value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public static implicit operator nint(LPARAM value) => value.Value;
|
||||
|
||||
public static explicit operator LPARAM(nint value) => new(value);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
56
tools/MouseJump.Kicker/NativeMethods/Core/LPCWSTR.cs
Normal file
56
tools/MouseJump.Kicker/NativeMethods/Core/LPCWSTR.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A pointer to a constant null-terminated string of 16-bit Unicode characters.For more information, see Character Sets Used By Fonts.
|
||||
/// This type is declared in WinNT.h as follows:
|
||||
/// typedef CONST WCHAR* LPCWSTR;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
/// </remarks>
|
||||
internal readonly struct LPCWSTR
|
||||
{
|
||||
public static readonly LPCWSTR Null = new(IntPtr.Zero);
|
||||
|
||||
public readonly IntPtr Value;
|
||||
|
||||
public LPCWSTR(IntPtr value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public LPCWSTR(string value)
|
||||
{
|
||||
this.Value = Marshal.StringToHGlobalAuto(value);
|
||||
}
|
||||
|
||||
public bool IsNull => this.Value == LPCWSTR.Null.Value;
|
||||
|
||||
public static implicit operator IntPtr(LPCWSTR value) => value.Value;
|
||||
|
||||
public static explicit operator LPCWSTR(IntPtr value) => new(value);
|
||||
|
||||
public static implicit operator string?(LPCWSTR value) => Marshal.PtrToStringUni(value.Value);
|
||||
|
||||
public static implicit operator LPCWSTR(string value) => new(value);
|
||||
|
||||
public void Free()
|
||||
{
|
||||
Marshal.FreeHGlobal(this.Value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
56
tools/MouseJump.Kicker/NativeMethods/Core/LPVOID.cs
Normal file
56
tools/MouseJump.Kicker/NativeMethods/Core/LPVOID.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A pointer to any type.
|
||||
/// This type is declared in WinDef.h as follows:
|
||||
/// typedef void* LPVOID;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
|
||||
/// </remarks>
|
||||
internal readonly struct LPVOID
|
||||
{
|
||||
public static readonly LPVOID Null = new(IntPtr.Zero);
|
||||
|
||||
public readonly IntPtr Value;
|
||||
|
||||
public LPVOID(IntPtr value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr(LPVOID value) => value.Value;
|
||||
|
||||
public static explicit operator LPVOID(IntPtr value) => new(value);
|
||||
|
||||
public static LPVOID Allocate(int length)
|
||||
{
|
||||
var ptr = Marshal.AllocHGlobal(length);
|
||||
return new LPVOID(ptr);
|
||||
}
|
||||
|
||||
public string? PtrToStringUni()
|
||||
{
|
||||
return Marshal.PtrToStringUni(this.Value);
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
Marshal.FreeHGlobal(this.Value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Kernel32
|
||||
{
|
||||
internal readonly struct LPSECURITY_ATTRIBUTES
|
||||
{
|
||||
public static readonly LPSECURITY_ATTRIBUTES Null = new(IntPtr.Zero);
|
||||
|
||||
public readonly IntPtr Value;
|
||||
|
||||
public LPSECURITY_ATTRIBUTES(IntPtr value)
|
||||
{
|
||||
this.Value = value;
|
||||
}
|
||||
|
||||
public LPSECURITY_ATTRIBUTES(SECURITY_ATTRIBUTES value)
|
||||
{
|
||||
this.Value = LPSECURITY_ATTRIBUTES.ToPtr(value);
|
||||
}
|
||||
|
||||
public bool IsNull => this.Value == LPSECURITY_ATTRIBUTES.Null.Value;
|
||||
|
||||
private static IntPtr ToPtr(SECURITY_ATTRIBUTES value)
|
||||
{
|
||||
var ptr = Marshal.AllocHGlobal(SECURITY_ATTRIBUTES.Size);
|
||||
Marshal.StructureToPtr(value, ptr, false);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
public SECURITY_ATTRIBUTES ToStructure()
|
||||
{
|
||||
return Marshal.PtrToStructure<SECURITY_ATTRIBUTES>(this.Value);
|
||||
}
|
||||
|
||||
public void Free()
|
||||
{
|
||||
Marshal.FreeHGlobal(this.Value);
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr(LPSECURITY_ATTRIBUTES value) => value.Value;
|
||||
|
||||
public static implicit operator LPSECURITY_ATTRIBUTES(IntPtr value) => new(value);
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}({this.Value})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// 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.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using static MouseJump.Kicker.NativeMethods.Core;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Kernel32
|
||||
{
|
||||
[SuppressMessage("SA1304", "SA1304:NonPrivateReadonlyFieldsMustBeginWithUpperCaseLetter", Justification = "Names match Win32 api")]
|
||||
[SuppressMessage("SA1307", "SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter", Justification = "Names match Win32 api")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal readonly struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
internal readonly DWORD nLength;
|
||||
internal readonly LPVOID lpSecurityDescriptor;
|
||||
internal readonly BOOL bInheritHandle;
|
||||
|
||||
internal SECURITY_ATTRIBUTES(
|
||||
DWORD nLength, LPVOID lpSecurityDescriptor, BOOL bInheritHandle)
|
||||
{
|
||||
this.nLength = nLength;
|
||||
this.lpSecurityDescriptor = lpSecurityDescriptor;
|
||||
this.bInheritHandle = bInheritHandle;
|
||||
}
|
||||
|
||||
public static int Size =>
|
||||
Marshal.SizeOf<SECURITY_ATTRIBUTES>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
using static MouseJump.Kicker.NativeMethods.Core;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Kernel32
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates or opens a named or unnamed event object.
|
||||
/// To specify an access mask for the object, use the CreateEventEx function.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is a handle to the event object.
|
||||
/// If the named event object existed before the function call, the function returns
|
||||
/// a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.
|
||||
/// If the function fails, the return value is NULL.
|
||||
/// To get extended error information, call GetLastError.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaymonitors
|
||||
/// </remarks>
|
||||
[LibraryImport(Libraries.Kernel32, StringMarshalling = StringMarshalling.Utf16, SetLastError = true)]
|
||||
internal static partial HANDLE CreateEventW(
|
||||
LPSECURITY_ATTRIBUTES lpEventAttributes,
|
||||
BOOL bManualReset,
|
||||
BOOL bInitialState,
|
||||
LPCWSTR lpName);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
using static MouseJump.Kicker.NativeMethods.Core;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class Kernel32
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the specified event object to the signaled state.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is nonzero.
|
||||
/// If the function fails, the return value is zero.
|
||||
/// To get extended error information, call GetLastError.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaymonitors
|
||||
/// </remarks>
|
||||
[LibraryImport(Libraries.Kernel32, SetLastError = true)]
|
||||
internal static partial Core.BOOL SetEvent(
|
||||
HANDLE hEvent);
|
||||
}
|
||||
13
tools/MouseJump.Kicker/NativeMethods/Libraries.cs
Normal file
13
tools/MouseJump.Kicker/NativeMethods/Libraries.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
// 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.
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static class Libraries
|
||||
{
|
||||
public const string Gdi32 = "gdi32";
|
||||
public const string Kernel32 = "kernel32";
|
||||
public const string Shell32 = "shell32";
|
||||
public const string User32 = "user32";
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
using static MouseJump.Kicker.NativeMethods.Core;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class User32
|
||||
{
|
||||
/// <summary>
|
||||
/// An application-defined callback function for use with EnumWindows.
|
||||
/// Return TRUE to continue enumeration, FALSE to stop.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms633498(v=vs.85)
|
||||
/// </remarks>
|
||||
internal delegate BOOL EnumWindowsProc(HWND hwnd, LPARAM lParam);
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all top-level windows on the screen, including hidden windows,
|
||||
/// by passing the handle to each window in turn to an application-defined callback function.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is nonzero.
|
||||
/// If the function fails, the return value is zero.
|
||||
/// To get extended error information, call GetLastError.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows
|
||||
/// </remarks>
|
||||
[DllImport(Libraries.User32, SetLastError = true)]
|
||||
internal static extern BOOL EnumWindows(
|
||||
EnumWindowsProc lpEnumFunc,
|
||||
LPARAM lParam);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
using static MouseJump.Kicker.NativeMethods.Core;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class User32
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves the identifier of the thread that created the specified window and,
|
||||
/// optionally, the identifier of the process that created the window.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The return value is the identifier of the thread that created the window.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowthreadprocessid
|
||||
/// </remarks>
|
||||
[LibraryImport(Libraries.User32, SetLastError = true)]
|
||||
internal static partial uint GetWindowThreadProcessId(
|
||||
HWND hWnd,
|
||||
out uint lpdwProcessId);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
using static MouseJump.Kicker.NativeMethods.Core;
|
||||
|
||||
namespace MouseJump.Kicker.NativeMethods;
|
||||
|
||||
internal static partial class User32
|
||||
{
|
||||
/// <summary>
|
||||
/// Brings the thread that created the specified window into the foreground and
|
||||
/// activates the window.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// If the window was brought to the foreground, the return value is nonzero.
|
||||
/// If the window was not brought to the foreground, the return value is zero.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
|
||||
/// </remarks>
|
||||
[LibraryImport(Libraries.User32, SetLastError = true)]
|
||||
internal static partial BOOL SetForegroundWindow(
|
||||
HWND hWnd);
|
||||
}
|
||||
23
tools/MouseJump.Kicker/Program.cs
Normal file
23
tools/MouseJump.Kicker/Program.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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.Windows.Forms;
|
||||
|
||||
namespace MouseJump.Kicker;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
public static void Main()
|
||||
{
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new KickerForm());
|
||||
}
|
||||
}
|
||||
11
tools/MouseJump.Kicker/readme.md
Normal file
11
tools/MouseJump.Kicker/readme.md
Normal file
@@ -0,0 +1,11 @@
|
||||
## MouseJump.Kicker
|
||||
|
||||
This is a simple "kicker" app that can be used to launch the Mouse Jump background process
|
||||
and activate the hotkey without needing to build and run the entire "runner" app.
|
||||
|
||||
It's intended to be used for testing and development purposes, and is not meant to be
|
||||
included in the main PowerToys release footprint.
|
||||
|
||||
When launching Mouse Jump via the kicker, it will look in the build output folder and
|
||||
launch the last successful build. Make sure to build the Mouse Jump project before
|
||||
launching the kicker - otherwise it won't run the latest version of the code.
|
||||
Reference in New Issue
Block a user