Repository: ZetaSp/PowerToys-Chinese-TransMOD
Branch: master
Commit: 4a41565ba980
Files: 183
Total size: 2.4 MB
Directory structure:
gitextract_lcydtlch/
├── LICENSE
├── Patcher/
│ ├── 安装.CMD
│ └── 安装组策略.cmd
├── PowerToys/
│ ├── global.json
│ └── src/
│ ├── ActionRunner/
│ │ └── Resources.resx
│ ├── Monaco/
│ │ └── index.html
│ ├── Update/
│ │ └── Resources.resx
│ ├── Version.props
│ ├── common/
│ │ ├── interop/
│ │ │ └── keyboard_layout.cpp
│ │ └── sysinternals/
│ │ └── Eula/
│ │ └── eula.c
│ ├── gpo/
│ │ └── assets/
│ │ └── zh-CN/
│ │ └── PowerToys.adml
│ ├── modules/
│ │ ├── AdvancedPaste/
│ │ │ └── AdvancedPaste/
│ │ │ └── Strings/
│ │ │ └── en-us/
│ │ │ └── Resources.resw
│ │ ├── CropAndLock/
│ │ │ └── CropAndLock/
│ │ │ └── main.cpp
│ │ ├── EnvironmentVariables/
│ │ │ └── EnvironmentVariablesUILib/
│ │ │ └── Strings/
│ │ │ └── en-us/
│ │ │ └── Resources.resw
│ │ ├── FileLocksmith/
│ │ │ ├── FileLocksmithContextMenu/
│ │ │ │ ├── Resources.resx
│ │ │ │ └── dllmain.cpp
│ │ │ ├── FileLocksmithExt/
│ │ │ │ └── Resources.resx
│ │ │ └── FileLocksmithUI/
│ │ │ └── Strings/
│ │ │ └── en-us/
│ │ │ └── Resources.resw
│ │ ├── Hosts/
│ │ │ └── HostsUILib/
│ │ │ └── Strings/
│ │ │ └── en-us/
│ │ │ └── Resources.resw
│ │ ├── MeasureTool/
│ │ │ └── MeasureToolUI/
│ │ │ └── Strings/
│ │ │ └── en-us/
│ │ │ └── Resources.resw
│ │ ├── MouseWithoutBorders/
│ │ │ ├── App/
│ │ │ │ ├── Class/
│ │ │ │ │ ├── Common.Clipboard.cs
│ │ │ │ │ ├── Common.Encryption.cs
│ │ │ │ │ ├── Common.Event.cs
│ │ │ │ │ ├── Common.Helper.cs
│ │ │ │ │ ├── Common.MachineStuff.cs
│ │ │ │ │ ├── Common.Service.cs
│ │ │ │ │ ├── EasyMouseOption.cs
│ │ │ │ │ ├── Extensions.cs
│ │ │ │ │ ├── IClipboardHelper.cs
│ │ │ │ │ ├── InputHook.cs
│ │ │ │ │ ├── Program.cs
│ │ │ │ │ └── SocketStuff.cs
│ │ │ │ ├── Control/
│ │ │ │ │ ├── Machine.cs
│ │ │ │ │ └── Machine.designer.cs
│ │ │ │ ├── Core/
│ │ │ │ │ └── Receiver.cs
│ │ │ │ ├── Form/
│ │ │ │ │ ├── Settings/
│ │ │ │ │ │ ├── SettingsFormPage.Designer.cs
│ │ │ │ │ │ ├── SettingsFormPage.cs
│ │ │ │ │ │ ├── SetupPage1.Designer.cs
│ │ │ │ │ │ ├── SetupPage2a.Designer.cs
│ │ │ │ │ │ ├── SetupPage2aa.Designer.cs
│ │ │ │ │ │ ├── SetupPage2ab.Designer.cs
│ │ │ │ │ │ ├── SetupPage2b.Designer.cs
│ │ │ │ │ │ ├── SetupPage3a.Designer.cs
│ │ │ │ │ │ ├── SetupPage3a.cs
│ │ │ │ │ │ ├── SetupPage4.Designer.cs
│ │ │ │ │ │ └── SetupPage5.Designer.cs
│ │ │ │ │ ├── frmAbout.Designer.cs
│ │ │ │ │ ├── frmAbout.cs
│ │ │ │ │ ├── frmInputCallback.cs
│ │ │ │ │ ├── frmLogon.Designer.cs
│ │ │ │ │ ├── frmMatrix.Designer.cs
│ │ │ │ │ ├── frmMatrix.cs
│ │ │ │ │ ├── frmMatrix.resx
│ │ │ │ │ ├── frmMessage.Designer.cs
│ │ │ │ │ ├── frmScreen.Designer.cs
│ │ │ │ │ └── frmScreen.cs
│ │ │ │ └── Helper/
│ │ │ │ └── FormHelper.cs
│ │ │ └── ModuleInterface/
│ │ │ └── dllmain.cpp
│ │ ├── NewPlus/
│ │ │ ├── NewShellExtensionContextMenu/
│ │ │ │ ├── NewShellExtensionContextMenu.vcxproj
│ │ │ │ ├── NewShellExtensionContextMenu.vcxproj.filters
│ │ │ │ ├── TemplateExamples/
│ │ │ │ │ ├── 模板文件夹里的一切都会出现在新建+菜单中.txt
│ │ │ │ │ └── 示例文件夹/
│ │ │ │ │ ├── 另一个示例文本文件.txt
│ │ │ │ │ └── 示例文本文件.txt
│ │ │ │ └── resources.resx
│ │ │ └── NewShellExtensionContextMenu.win10/
│ │ │ └── resources.resx
│ │ ├── PowerOCR/
│ │ │ └── PowerOCR/
│ │ │ └── Properties/
│ │ │ └── Resources.resx
│ │ ├── ShortcutGuide/
│ │ │ └── ShortcutGuide/
│ │ │ └── Resources.resx
│ │ ├── Workspaces/
│ │ │ ├── WorkspacesEditor/
│ │ │ │ ├── Models/
│ │ │ │ │ └── Project.cs
│ │ │ │ └── Properties/
│ │ │ │ └── Resources.resx
│ │ │ ├── WorkspacesLauncher/
│ │ │ │ └── Resource.resx
│ │ │ ├── WorkspacesLauncherUI/
│ │ │ │ └── Properties/
│ │ │ │ └── Resources.resx
│ │ │ └── WorkspacesSnapshotTool/
│ │ │ └── Resource.resx
│ │ ├── ZoomIt/
│ │ │ └── ZoomIt/
│ │ │ ├── ZoomIt.rc
│ │ │ └── Zoomit.cpp
│ │ ├── alwaysontop/
│ │ │ └── AlwaysOnTop/
│ │ │ └── Resources.resx
│ │ ├── awake/
│ │ │ └── Awake/
│ │ │ ├── Core/
│ │ │ │ └── Constants.cs
│ │ │ └── Properties/
│ │ │ └── Resources.resx
│ │ ├── colorPicker/
│ │ │ └── ColorPickerUI/
│ │ │ ├── Properties/
│ │ │ │ └── Resources.resx
│ │ │ └── ViewModels/
│ │ │ └── ColorEditorViewModel.cs
│ │ ├── fancyzones/
│ │ │ ├── FancyZonesLib/
│ │ │ │ └── Resources.resx
│ │ │ └── editor/
│ │ │ └── FancyZonesEditor/
│ │ │ └── Properties/
│ │ │ └── Resources.resx
│ │ ├── imageresizer/
│ │ │ ├── ImageResizerContextMenu/
│ │ │ │ └── Resources.resx
│ │ │ ├── dll/
│ │ │ │ └── Resources.resx
│ │ │ └── ui/
│ │ │ ├── Properties/
│ │ │ │ └── Resources.resx
│ │ │ └── Views/
│ │ │ ├── EnumValueConverter.cs
│ │ │ └── InputPage.xaml
│ │ ├── keyboardmanager/
│ │ │ ├── KeyboardManagerEditor/
│ │ │ │ └── Resources.resx
│ │ │ └── KeyboardManagerEngineLibrary/
│ │ │ └── KeyboardEventHandlers.cpp
│ │ ├── launcher/
│ │ │ ├── Plugins/
│ │ │ │ ├── Community.PowerToys.Run.Plugin.UnitConverter/
│ │ │ │ │ ├── InputInterpreter.cs
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Community.PowerToys.Run.Plugin.VSCodeWorkspaces/
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Community.PowerToys.Run.Plugin.ValueGenerator/
│ │ │ │ │ ├── Generators/
│ │ │ │ │ │ ├── Base64/
│ │ │ │ │ │ │ ├── Base64DecodeRequest.cs
│ │ │ │ │ │ │ └── Base64Request.cs
│ │ │ │ │ │ ├── GUID/
│ │ │ │ │ │ │ └── GUIDRequest.cs
│ │ │ │ │ │ └── Uri/
│ │ │ │ │ │ ├── DataEscapeRequest.cs
│ │ │ │ │ │ ├── DataUnescapeRequest.cs
│ │ │ │ │ │ ├── HexEscapeRequest.cs
│ │ │ │ │ │ ├── HexUnescapeRequest.cs
│ │ │ │ │ │ ├── UrlDecodeRequest.cs
│ │ │ │ │ │ └── UrlEncodeRequest.cs
│ │ │ │ │ ├── InputParser.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Community.PowerToys.Run.Plugin.WebSearch/
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.Plugin.Folder/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.Plugin.Indexer/
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.Plugin.Program/
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ ├── Programs/
│ │ │ │ │ │ └── UWPApplication.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.Plugin.Shell/
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.Plugin.Uri/
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.Plugin.WindowWalker/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.Calculator/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.History/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.OneNote/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.PowerToys/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.Registry/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.Service/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.System/
│ │ │ │ │ ├── Components/
│ │ │ │ │ │ └── ResultHelper.cs
│ │ │ │ │ ├── Main.cs
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.TimeDate/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ ├── Microsoft.PowerToys.Run.Plugin.WindowsSettings/
│ │ │ │ │ └── Properties/
│ │ │ │ │ └── Resources.resx
│ │ │ │ └── Microsoft.PowerToys.Run.Plugin.WindowsTerminal/
│ │ │ │ ├── Main.cs
│ │ │ │ └── Properties/
│ │ │ │ └── Resources.resx
│ │ │ └── PowerLauncher/
│ │ │ └── Properties/
│ │ │ └── Resources.resx
│ │ ├── peek/
│ │ │ └── Peek.UI/
│ │ │ └── Strings/
│ │ │ └── en-us/
│ │ │ └── Resources.resw
│ │ ├── powerrename/
│ │ │ ├── PowerRenameContextMenu/
│ │ │ │ └── Resources.resx
│ │ │ ├── PowerRenameUILib/
│ │ │ │ ├── PowerRenameXAML/
│ │ │ │ │ └── MainWindow.xaml.cpp
│ │ │ │ └── Strings/
│ │ │ │ └── en-us/
│ │ │ │ └── Resources.resw
│ │ │ └── dll/
│ │ │ └── Resources.resx
│ │ ├── previewpane/
│ │ │ ├── GcodePreviewHandler/
│ │ │ │ └── Properties/
│ │ │ │ └── Resource.resx
│ │ │ ├── MarkdownPreviewHandler/
│ │ │ │ └── Properties/
│ │ │ │ └── Resources.resx
│ │ │ ├── MonacoPreviewHandler/
│ │ │ │ └── Properties/
│ │ │ │ └── Resources.resx
│ │ │ ├── PdfPreviewHandler/
│ │ │ │ └── Properties/
│ │ │ │ └── Resources.resx
│ │ │ ├── QoiPreviewHandler/
│ │ │ │ └── Properties/
│ │ │ │ └── Resource.resx
│ │ │ ├── SvgPreviewHandler/
│ │ │ │ └── Properties/
│ │ │ │ └── Resource.resx
│ │ │ └── powerpreview/
│ │ │ └── Resources.resx
│ │ └── registrypreview/
│ │ ├── RegistryPreview/
│ │ │ └── RegistryPreviewXAML/
│ │ │ └── MainWindow.xaml.cs
│ │ └── RegistryPreviewUILib/
│ │ └── Strings/
│ │ └── en-US/
│ │ └── Resources.resw
│ ├── runner/
│ │ ├── Resources.resx
│ │ └── main.cpp
│ └── settings-ui/
│ ├── Settings.UI/
│ │ ├── Assets/
│ │ │ └── Settings/
│ │ │ └── Scripts/
│ │ │ ├── CheckCmdNotFoundRequirements.ps1
│ │ │ ├── DisableModule.ps1
│ │ │ ├── EnableModule.ps1
│ │ │ ├── InstallPowerShell7.ps1
│ │ │ └── InstallWinGetClientModule.ps1
│ │ ├── Converters/
│ │ │ └── ZoomItTypeSpeedSliderConverter.cs
│ │ ├── SettingsXAML/
│ │ │ ├── App.xaml.cs
│ │ │ ├── OOBE/
│ │ │ │ └── Views/
│ │ │ │ ├── OobeShellPage.xaml
│ │ │ │ └── OobeShellPage.xaml.cs
│ │ │ └── Views/
│ │ │ ├── ColorPickerPage.xaml
│ │ │ ├── ImageResizerPage.xaml
│ │ │ ├── MouseUtilsPage.xaml
│ │ │ ├── MouseWithoutBordersPage.xaml
│ │ │ ├── PowerLauncherPage.xaml
│ │ │ ├── PowerOcrPage.xaml
│ │ │ ├── PowerPreviewPage.xaml
│ │ │ ├── PowerRenamePage.xaml
│ │ │ └── ZoomItPage.xaml
│ │ ├── Strings/
│ │ │ └── en-us/
│ │ │ └── Resources.resw
│ │ └── ViewModels/
│ │ ├── CmdNotFoundViewModel.cs
│ │ ├── DashboardViewModel.cs
│ │ └── PowerAccentViewModel.cs
│ └── Settings.UI.Library/
│ └── ColorFormatModel.cs
├── README.md
└── Tools/
├── README.md
├── autosort.py
├── autosort_newgptbroken.py
├── autosort_old.py
├── blank
├── clean.cmd
├── clean.txt
├── modify.cmd
├── modify_arm64.cmd
├── zhcn_modify_list.txt
├── zhcn_modify_list2.txt
└── zhcn_modify_list2.txt.bak
================================================
FILE CONTENTS
================================================
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022 Zetaspace
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Patcher/安装.CMD
================================================
@echo off
chcp 65001>nul
color f0
if not exist "%~dp0组策略文件\安装组策略.cmd" echo 检测到文件缺失,请解压后运行!&pause&exit
echo 请允许管理员权限以便安装,谢谢。
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
cd /d %~dp0
mode con cols=20 lines=10
for /f "tokens=2 delims= " %%i in ('dir /b^|findstr PowerToys') do set modver=%%i
set modfulver=%modver%
set softname=PowerToys
title 修改 %softname%
for /l %%i in (1,20,40) do mode con cols=20 lines=%%i
for /l %%i in (20,40,160) do mode con cols=%%i lines=40
:start
color f0
msg %username% /time:1 /v /w 欢迎使用 Zetaloop 的 %softname% 修改!>nul
color 07
for /f "skip=2 tokens=2,*" %%a in ('reg query "HKCR\powertoys\shell\open\command"') do set ptpath=%%b
if %errorlevel%==1 echo 警告:找不到注册表信息!你可能未安装 %softname%&set /p =请按任意键退出. . . &exit
set ptpath=%ptpath:~1,-6%
for /f "delims=" %%a in ('echo %ptpath%') do set installpath=%%~dpa
for /f "usebackq delims=" %%a in (`mshta vbscript:CreateObject("Scripting.FileSystemObject"^).GetStandardStream(1^).WriteLine(CStr(CreateObject("Scripting.FileSystemObject"^).GetFileVersion("%ptpath%"^)^)^)(window.close^)`) do set installver=%%a
for /f "tokens=1,2,3 delims=." %%a in ('echo %installver%') do set installver=%%a.%%b.%%c
echo.
echo 修改包版本 %modfulver%
echo %softname% 版本 %installver%
if not "%modfulver%"=="%installver%" echo ·警告:汉化包版本不对应!&msg %username% /v /w 警告:汉化包版本不对应,强行安装可能导致报错闪退!>nul
echo.
echo 安装目录 %installpath%
if not exist "%installpath%PowerToys.exe" echo 警告:安装目录检测失败! %&set /p =请按任意键退出. . . &exi
echo.
echo 安装过程:
::
echo ·解除安装目录的占用
::
echo ·复制汉化文件到软件目录
echo.
echo 为解除文件占用,将会重启 Windows 资源管理器
echo ---------------------------------------------------
choice /c thequickbrownfxjmpsvlazydg /n /m "确认无误后,按下 Y 开始:"
if %errorlevel%==24 goto install
::if %errorlevel%==22 goto installarm64
echo 取消安装。退出安装器...
choice /t 1 /d n >nul
exit
:installarm64
set modver=%modver% ARM64
:install
echo 开始安装!
if exist "%tmp%\PowerToys.NewPlus.ShellExtension.dll_*" del "%tmp%\PowerToys.NewPlus.ShellExtension.dll_*"
if exist "%tmp%\PowerToys.FileLocksmithExt.dll_*" del "%tmp%\PowerToys.FileLocksmithExt.dll_*"
if exist "%tmp%\PowerToys.FileLocksmithContextMenu.dll_*" del "%tmp%\PowerToys.FileLocksmithContextMenu.dll_*"
if exist "%tmp%\PowerToys.PowerRenameExt.dll_*" del "%tmp%\PowerToys.PowerRenameExt.dll_*"
if exist "%tmp%\PowerToys.PowerRenameContextMenu.dll_*" del "%tmp%\PowerToys.PowerRenameContextMenu.dll_*"
if exist "%tmp%\PowerToys.RegistryPreviewExt.dll_*" del "%tmp%\PowerToys.RegistryPreviewExt.dll_*"
if exist "%tmp%\PowerToys.ImageResizerExt.dll_*" del "%tmp%\PowerToys.ImageResizerExt.dll_*"
:chcp 936>nul
call :killpt
rmdir /s /q %installpath%WinUI3Apps\Assets\NewPlus\Templates
xcopy ".\%softname% %modver%\*" "%installpath%" /e /y
if %errorlevel%==0 goto success
echo 尝试解锁...
taskkill /f /im explorer.exe
rmdir /s /q %installpath%WinUI3Apps\Assets\NewPlus\Templates
xcopy ".\%softname% %modver%\*" "%installpath%" /e /y
if %errorlevel%==0 start explorer&goto success
start explorer
echo 尝试移走一些文件...
echo 这些文件放到了系统临时文件夹。
::
echo 你可能需要重启电脑来使汉化生效。
::
if exist "%tmp%\PowerToys.NewPlus.ShellExtension.dll_*" del "%tmp%\PowerToys.NewPlus.ShellExtension.dll_*"
if exist "%installpath%WinUI3Apps\PowerToys.NewPlus.ShellExtension.dll" move "%installpath%WinUI3Apps\PowerToys.NewPlus.ShellExtension.dll" "%tmp%\PowerToys.NewPlus.ShellExtension.dll_%random%.tmp"
if exist "%tmp%\PowerToys.FileLocksmithExt.dll_*" del "%tmp%\PowerToys.FileLocksmithExt.dll_*"
if exist "%installpath%WinUI3Apps\PowerToys.FileLocksmithExt.dll" move "%installpath%WinUI3Apps\PowerToys.FileLocksmithExt.dll" "%tmp%\PowerToys.FileLocksmithExt.dll_%random%.tmp"
if exist "%tmp%\PowerToys.FileLocksmithContextMenu.dll_*" del "%tmp%\PowerToys.FileLocksmithContextMenu.dll_*"
if exist "%installpath%WinUI3Apps\PowerToys.FileLocksmithContextMenu.dll" move "%installpath%WinUI3Apps\PowerToys.FileLocksmithContextMenu.dll" "%tmp%\PowerToys.FileLocksmithContextMenu.dll_%random%.tmp"
if exist "%tmp%\PowerToys.PowerRenameExt.dll_*" del "%tmp%\PowerToys.PowerRenameExt.dll_*"
if exist "%installpath%WinUI3Apps\PowerToys.PowerRenameExt.dll" move "%installpath%WinUI3Apps\PowerToys.PowerRenameExt.dll" "%tmp%\PowerToys.PowerRenameExt.dll_%random%.tmp"
if exist "%tmp%\PowerToys.PowerRenameContextMenu.dll_*" del "%tmp%\PowerToys.PowerRenameContextMenu.dll_*"
if exist "%installpath%WinUI3Apps\PowerToys.PowerRenameContextMenu.dll" move "%installpath%WinUI3Apps\PowerToys.PowerRenameContextMenu.dll" "%tmp%\PowerToys.PowerRenameContextMenu.dll_%random%.tmp"
if exist "%tmp%\PowerToys.RegistryPreviewExt.dll_*" del "%tmp%\PowerToys.RegistryPreviewExt.dll_*"
if exist "%installpath%WinUI3Apps\PowerToys.RegistryPreviewExt.dll" move "%installpath%WinUI3Apps\PowerToys.RegistryPreviewExt.dll" "%tmp%\PowerToys.RegistryPreviewExt.dll_%random%.tmp"
if exist "%tmp%\PowerToys.ImageResizerExt.dll_*" del "%tmp%\PowerToys.ImageResizerExt.dll_*"
if exist "%installpath%PowerToys.ImageResizerExt.dll" move "%installpath%PowerToys.ImageResizerExt.dll" "%tmp%\PowerToys.ImageResizerExt.dll_%random%.tmp"
echo 再试一次...
echo.
echo.
call :killpt
rmdir /s /q %installpath%WinUI3Apps\Assets\NewPlus\Templates
xcopy ".\%softname% %modver%\*" "%installpath%" /e /y
if %errorlevel%==0 goto success
echo 尝试解锁...
taskkill /f /im explorer.exe
rmdir /s /q %installpath%WinUI3Apps\Assets\NewPlus\Templates
xcopy ".\%softname% %modver%\*" "%installpath%" /e /y
if %errorlevel%==0 start explorer&goto success
start explorer
echo 安装失败!未能解除文件占用,请尝试手动复制,或重启后再试。
::
msg %username% /time:2 /v /w 安装失败!未能解除文件占用,请尝试手动复制,或重启后再试。>nul
set /p =请按任意键退出. . . &exit
goto :eof
:success
echo 重启文件资源管理器以加载汉化右键菜单
::
powershell exit
taskkill /f /im explorer.exe>nul 2>nul
taskkill /f /im explorer.exe>nul 2>nul
taskkill /f /im explorer.exe>nul 2>nul
powershell exit
start explorer
powershell exit
echo 启动 PowerToys
mshta vbscript:CreateObject("Shell.Application").ShellExecute("%installpath%PowerToys.exe","","","runas",1)(window.close)
powershell exit
echo 打开 PowerToys 设置
mshta vbscript:CreateObject("Shell.Application").ShellExecute("%installpath%PowerToys.exe","","","runas",1)(window.close)
powershell exit
echo 安装完成
:: Powershell 用于提供一个恰当的启动延迟
::
msg %username% /time:2 /v /w 安装完成!>nul
goto :eof
:killpt
taskkill /F /IM "PowerToys*"
taskkill /F /IM "PowerToys*"
goto :eof
================================================
FILE: Patcher/安装组策略.cmd
================================================
chcp 65001>nul
@echo off
echo 正在安装 PowerToys 组策略...
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&goto :eOF
cd /d %~dp0
xcopy /Y /I /E ".\PowerToys.admx" "%systemroot%\PolicyDefinitions\"
xcopy /Y /I /E ".\zh-CN\PowerToys.adml" "%systemroot%\PolicyDefinitions\zh-CN\"
xcopy /Y /I /E ".\en-US\PowerToys.adml" "%systemroot%\PolicyDefinitions\en-US\"
msg %username% 安装完成
================================================
FILE: PowerToys/global.json
================================================
{
"sdk": {
"allowPrerelease": false
}
}
================================================
FILE: PowerToys/src/ActionRunner/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
无法下载 .NET Core Desktop Runtime 3.1,请自行安装。
PowerToys 安装错误
PowerToys 有版本更新。请访问 GitHub 页面下载。
================================================
FILE: PowerToys/src/Monaco/index.html
================================================
Previewer for developer Files
================================================
FILE: PowerToys/src/Update/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
无法下载 .NET Core Desktop Runtime 3.1,请自行安装。
PowerToys 安装错误
PowerToys 有版本更新。
立刻更新
PowerToys 有版本更新。请访问 GitHub 页面下载。
更多信息
PowerToys 更新
================================================
FILE: PowerToys/src/Version.props
================================================
0.88.0
SHA256
================================================
FILE: PowerToys/src/common/interop/keyboard_layout.cpp
================================================
#include "pch.h"
#include
#include
#include "keyboard_layout_impl.h"
#include "shared_constants.h"
constexpr DWORD numpadOriginBit = 1ull << 31;
LayoutMap::LayoutMap() :
impl(new LayoutMap::LayoutMapImpl())
{
}
LayoutMap::~LayoutMap()
{
delete impl;
}
void LayoutMap::UpdateLayout()
{
impl->UpdateLayout();
}
std::wstring LayoutMap::GetKeyName(DWORD key)
{
return impl->GetKeyName(key);
}
DWORD LayoutMap::GetKeyFromName(const std::wstring& name)
{
auto list = impl->GetKeyNameList(false);
for (const auto& [value, key] : list)
{
if (key == name)
return value;
}
return {};
}
std::vector LayoutMap::GetKeyCodeList(const bool isShortcut)
{
return impl->GetKeyCodeList(isShortcut);
}
std::vector> LayoutMap::GetKeyNameList(const bool isShortcut)
{
return impl->GetKeyNameList(isShortcut);
}
// Function to return the unicode string name of the key
std::wstring LayoutMap::LayoutMapImpl::GetKeyName(DWORD key)
{
std::wstring result = L"未定义";
std::lock_guard lock(keyboardLayoutMap_mutex);
UpdateLayout();
auto it = keyboardLayoutMap.find(key);
if (it != keyboardLayoutMap.end())
{
result = it->second;
}
return result;
}
bool mapKeycodeToUnicode(const int vCode, HKL layout, const BYTE* keyState, std::array& outBuffer)
{
// Get the scan code from the virtual key code
const UINT scanCode = MapVirtualKeyExW(vCode, MAPVK_VK_TO_VSC, layout);
// Get the unicode representation from the virtual key code and scan code pair
const UINT wFlags = 1 << 2; // If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer)
const int result = ToUnicodeEx(vCode, scanCode, keyState, outBuffer.data(), static_cast(outBuffer.size()), wFlags, layout);
return result != 0;
}
// Update Keyboard layout according to input locale identifier
void LayoutMap::LayoutMapImpl::UpdateLayout()
{
// Get keyboard layout for current thread
const HKL layout = GetKeyboardLayout(0);
if (layout == previousLayout)
{
return;
}
previousLayout = layout;
if (!isKeyCodeListGenerated)
{
unicodeKeys.clear();
unknownKeys.clear();
}
std::array btKeys = { 0 };
// Only set the Caps Lock key to on for the key names in uppercase
btKeys[VK_CAPITAL] = 1;
// Iterate over all the virtual key codes. virtual key 0 is not used
for (int i = 1; i < 256; i++)
{
std::array szBuffer = { 0 };
if (mapKeycodeToUnicode(i, layout, btKeys.data(), szBuffer))
{
keyboardLayoutMap[i] = szBuffer.data();
if (!isKeyCodeListGenerated)
{
unicodeKeys[i] = szBuffer.data();
}
continue;
}
// Store the virtual key code as string
std::wstring vk = L"虚拟键值 ";
vk += std::to_wstring(i);
keyboardLayoutMap[i] = vk;
if (!isKeyCodeListGenerated)
{
unknownKeys[i] = vk;
}
}
// Override special key names like Shift, Ctrl etc because they don't have unicode mappings and key names like Enter, Space as they appear as "\r", " "
// To do: localization
keyboardLayoutMap[VK_CANCEL] = L"Break";
keyboardLayoutMap[VK_BACK] = L"Backspace";
keyboardLayoutMap[VK_TAB] = L"Tab";
keyboardLayoutMap[VK_CLEAR] = L"Clear";
keyboardLayoutMap[VK_SHIFT] = L"Shift";
keyboardLayoutMap[VK_CONTROL] = L"Ctrl";
keyboardLayoutMap[VK_MENU] = L"Alt";
keyboardLayoutMap[VK_PAUSE] = L"Pause";
keyboardLayoutMap[VK_CAPITAL] = L"Caps Lock";
keyboardLayoutMap[VK_ESCAPE] = L"Esc";
keyboardLayoutMap[VK_SPACE] = L"Space";
keyboardLayoutMap[VK_LEFT] = L"Left";
keyboardLayoutMap[VK_RIGHT] = L"Right";
keyboardLayoutMap[VK_UP] = L"Up";
keyboardLayoutMap[VK_DOWN] = L"Down";
keyboardLayoutMap[VK_INSERT] = L"Insert";
keyboardLayoutMap[VK_DELETE] = L"Delete";
keyboardLayoutMap[VK_PRIOR] = L"PgUp";
keyboardLayoutMap[VK_NEXT] = L"PgDn";
keyboardLayoutMap[VK_HOME] = L"Home";
keyboardLayoutMap[VK_END] = L"End";
keyboardLayoutMap[VK_RETURN] = L"Enter";
keyboardLayoutMap[VK_LEFT | numpadOriginBit] = L"Left (小键盘)";
keyboardLayoutMap[VK_RIGHT | numpadOriginBit] = L"Right (小键盘)";
keyboardLayoutMap[VK_UP | numpadOriginBit] = L"Up (小键盘)";
keyboardLayoutMap[VK_DOWN | numpadOriginBit] = L"Down (小键盘)";
keyboardLayoutMap[VK_INSERT | numpadOriginBit] = L"Insert (小键盘)";
keyboardLayoutMap[VK_DELETE | numpadOriginBit] = L"Delete (小键盘)";
keyboardLayoutMap[VK_PRIOR | numpadOriginBit] = L"PgUp (小键盘)";
keyboardLayoutMap[VK_NEXT | numpadOriginBit] = L"PgDn (小键盘)";
keyboardLayoutMap[VK_HOME | numpadOriginBit] = L"Home (小键盘)";
keyboardLayoutMap[VK_END | numpadOriginBit] = L"End (小键盘)";
keyboardLayoutMap[VK_RETURN | numpadOriginBit] = L"Enter (小键盘)";
keyboardLayoutMap[VK_DIVIDE | numpadOriginBit] = L"/ (小键盘)";
keyboardLayoutMap[VK_SUBTRACT] = L"- (小键盘)";
keyboardLayoutMap[VK_SELECT] = L"Select";
keyboardLayoutMap[VK_PRINT] = L"Print";
keyboardLayoutMap[VK_EXECUTE] = L"Execute";
keyboardLayoutMap[VK_SNAPSHOT] = L"Print Screen";
keyboardLayoutMap[VK_HELP] = L"Help";
keyboardLayoutMap[VK_LWIN] = L"Win (左)";
keyboardLayoutMap[VK_RWIN] = L"Win (右)";
keyboardLayoutMap[VK_APPS] = L"Apps/Menu";
keyboardLayoutMap[VK_SLEEP] = L"Sleep";
keyboardLayoutMap[VK_NUMPAD0] = L"0 (小键盘)";
keyboardLayoutMap[VK_NUMPAD1] = L"1 (小键盘)";
keyboardLayoutMap[VK_NUMPAD2] = L"2 (小键盘)";
keyboardLayoutMap[VK_NUMPAD3] = L"3 (小键盘)";
keyboardLayoutMap[VK_NUMPAD4] = L"4 (小键盘)";
keyboardLayoutMap[VK_NUMPAD5] = L"5 (小键盘)";
keyboardLayoutMap[VK_NUMPAD6] = L"6 (小键盘)";
keyboardLayoutMap[VK_NUMPAD7] = L"7 (小键盘)";
keyboardLayoutMap[VK_NUMPAD8] = L"8 (小键盘)";
keyboardLayoutMap[VK_NUMPAD9] = L"9 (小键盘)";
keyboardLayoutMap[VK_SEPARATOR] = L"Separator";
keyboardLayoutMap[VK_F1] = L"F1";
keyboardLayoutMap[VK_F2] = L"F2";
keyboardLayoutMap[VK_F3] = L"F3";
keyboardLayoutMap[VK_F4] = L"F4";
keyboardLayoutMap[VK_F5] = L"F5";
keyboardLayoutMap[VK_F6] = L"F6";
keyboardLayoutMap[VK_F7] = L"F7";
keyboardLayoutMap[VK_F8] = L"F8";
keyboardLayoutMap[VK_F9] = L"F9";
keyboardLayoutMap[VK_F10] = L"F10";
keyboardLayoutMap[VK_F11] = L"F11";
keyboardLayoutMap[VK_F12] = L"F12";
keyboardLayoutMap[VK_F13] = L"F13";
keyboardLayoutMap[VK_F14] = L"F14";
keyboardLayoutMap[VK_F15] = L"F15";
keyboardLayoutMap[VK_F16] = L"F16";
keyboardLayoutMap[VK_F17] = L"F17";
keyboardLayoutMap[VK_F18] = L"F18";
keyboardLayoutMap[VK_F19] = L"F19";
keyboardLayoutMap[VK_F20] = L"F20";
keyboardLayoutMap[VK_F21] = L"F21";
keyboardLayoutMap[VK_F22] = L"F22";
keyboardLayoutMap[VK_F23] = L"F23";
keyboardLayoutMap[VK_F24] = L"F24";
keyboardLayoutMap[VK_NUMLOCK] = L"Num Lock";
keyboardLayoutMap[VK_SCROLL] = L"Scroll Lock";
keyboardLayoutMap[VK_LSHIFT] = L"Shift (左)";
keyboardLayoutMap[VK_RSHIFT] = L"Shift (右)";
keyboardLayoutMap[VK_LCONTROL] = L"Ctrl (左)";
keyboardLayoutMap[VK_RCONTROL] = L"Ctrl (右)";
keyboardLayoutMap[VK_LMENU] = L"Alt (左)";
keyboardLayoutMap[VK_RMENU] = L"Alt (右)";
keyboardLayoutMap[VK_BROWSER_BACK] = L"Browser Back";
keyboardLayoutMap[VK_BROWSER_FORWARD] = L"Browser Forward";
keyboardLayoutMap[VK_BROWSER_REFRESH] = L"Browser Refresh";
keyboardLayoutMap[VK_BROWSER_STOP] = L"Browser Stop";
keyboardLayoutMap[VK_BROWSER_SEARCH] = L"Browser Search";
keyboardLayoutMap[VK_BROWSER_FAVORITES] = L"Browser Favorites";
keyboardLayoutMap[VK_BROWSER_HOME] = L"Browser Home";
keyboardLayoutMap[VK_VOLUME_MUTE] = L"Volume Mute";
keyboardLayoutMap[VK_VOLUME_DOWN] = L"Volume Down";
keyboardLayoutMap[VK_VOLUME_UP] = L"Volume Up";
keyboardLayoutMap[VK_MEDIA_NEXT_TRACK] = L"Next Track";
keyboardLayoutMap[VK_MEDIA_PREV_TRACK] = L"Previous Track";
keyboardLayoutMap[VK_MEDIA_STOP] = L"Stop Media";
keyboardLayoutMap[VK_MEDIA_PLAY_PAUSE] = L"Play/Pause Media";
keyboardLayoutMap[VK_LAUNCH_MAIL] = L"Start Mail";
keyboardLayoutMap[VK_LAUNCH_MEDIA_SELECT] = L"Select Media";
keyboardLayoutMap[VK_LAUNCH_APP1] = L"Start App 1";
keyboardLayoutMap[VK_LAUNCH_APP2] = L"Start App 2";
keyboardLayoutMap[VK_PACKET] = L"Packet";
keyboardLayoutMap[VK_ATTN] = L"Attn";
keyboardLayoutMap[VK_CRSEL] = L"CrSel";
keyboardLayoutMap[VK_EXSEL] = L"ExSel";
keyboardLayoutMap[VK_EREOF] = L"Erase EOF";
keyboardLayoutMap[VK_PLAY] = L"Play";
keyboardLayoutMap[VK_ZOOM] = L"Zoom";
keyboardLayoutMap[VK_PA1] = L"PA1";
keyboardLayoutMap[VK_OEM_CLEAR] = L"Clear";
keyboardLayoutMap[0xFF] = L"未定义";
keyboardLayoutMap[CommonSharedConstants::VK_WIN_BOTH] = L"Win";
keyboardLayoutMap[VK_KANA] = L"IME Kana";
keyboardLayoutMap[VK_HANGEUL] = L"IME Hangeul";
keyboardLayoutMap[VK_HANGUL] = L"IME Hangul";
keyboardLayoutMap[VK_IME_ON] = L"IME On";
keyboardLayoutMap[VK_JUNJA] = L"IME Junja";
keyboardLayoutMap[VK_FINAL] = L"IME Final";
keyboardLayoutMap[VK_HANJA] = L"IME Hanja";
keyboardLayoutMap[VK_KANJI] = L"IME Kanji";
keyboardLayoutMap[VK_IME_OFF] = L"IME Off";
keyboardLayoutMap[VK_CONVERT] = L"IME Convert";
keyboardLayoutMap[VK_NONCONVERT] = L"IME Non-Convert";
keyboardLayoutMap[VK_ACCEPT] = L"IME Kana";
keyboardLayoutMap[VK_MODECHANGE] = L"IME Mode Change";
keyboardLayoutMap[VK_DECIMAL] = L". (小键盘)";
keyboardLayoutMap[CommonSharedConstants::VK_DISABLED] = L"禁用";
}
// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist
std::vector LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcut)
{
std::lock_guard lock(keyboardLayoutMap_mutex);
UpdateLayout();
std::vector keyCodes;
if (!isKeyCodeListGenerated)
{
// Add character keys
for (auto& it : unicodeKeys)
{
// If it was not renamed with a special name
if (it.second == keyboardLayoutMap[it.first])
{
keyCodes.push_back(it.first);
}
}
// Add modifier keys in alphabetical order
keyCodes.push_back(VK_MENU);
keyCodes.push_back(VK_LMENU);
keyCodes.push_back(VK_RMENU);
keyCodes.push_back(VK_CONTROL);
keyCodes.push_back(VK_LCONTROL);
keyCodes.push_back(VK_RCONTROL);
keyCodes.push_back(VK_SHIFT);
keyCodes.push_back(VK_LSHIFT);
keyCodes.push_back(VK_RSHIFT);
keyCodes.push_back(CommonSharedConstants::VK_WIN_BOTH);
keyCodes.push_back(VK_LWIN);
keyCodes.push_back(VK_RWIN);
// Add all other special keys
std::vector specialKeys;
for (int i = 1; i < 256; i++)
{
// If it is not already been added (i.e. it was either a modifier or had a unicode representation)
if (std::find(keyCodes.begin(), keyCodes.end(), i) == keyCodes.end())
{
// If it is any other key but it is not named as VK #
auto it = unknownKeys.find(i);
if (it == unknownKeys.end())
{
specialKeys.push_back(i);
}
else if (unknownKeys[i] != keyboardLayoutMap[i])
{
specialKeys.push_back(i);
}
}
}
// Add numpad keys
for (auto it = keyboardLayoutMap.rbegin(); it->first & numpadOriginBit; ++it)
{
keyCodes.push_back(it->first);
}
// Sort the special keys in alphabetical order
std::sort(specialKeys.begin(), specialKeys.end(), [&](const DWORD& lhs, const DWORD& rhs) {
return keyboardLayoutMap[lhs] < keyboardLayoutMap[rhs];
});
for (int i = 0; i < specialKeys.size(); i++)
{
keyCodes.push_back(specialKeys[i]);
}
// Add unknown keys
for (auto& it : unknownKeys)
{
// If it was not renamed with a special name
if (it.second == keyboardLayoutMap[it.first])
{
keyCodes.push_back(it.first);
}
}
keyCodeList = keyCodes;
isKeyCodeListGenerated = true;
}
else
{
keyCodes = keyCodeList;
}
// If it is a key list for the shortcut control then we add a "None" key at the start
if (isShortcut)
{
keyCodes.insert(keyCodes.begin(), 0);
}
return keyCodes;
}
std::vector> LayoutMap::LayoutMapImpl::GetKeyNameList(const bool isShortcut)
{
std::vector> keyNames;
std::vector keyCodes = GetKeyCodeList(isShortcut);
std::lock_guard lock(keyboardLayoutMap_mutex);
// If it is a key list for the shortcut control then we add a "None" key at the start
if (isShortcut)
{
keyNames.push_back({ 0, L"无" });
for (int i = 1; i < keyCodes.size(); i++)
{
keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] });
}
}
else
{
for (int i = 0; i < keyCodes.size(); i++)
{
keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] });
}
}
return keyNames;
}
================================================
FILE: PowerToys/src/common/sysinternals/Eula/eula.c
================================================
#pragma once
#pragma warning( disable: 4996)
#include
#include
#include
#include
#include
#include
#include
#include "Eula.h"
#include "dll.h"
#define IDC_TEXT 500
#define IDC_PRINT 501
#define IDC_TEXT1 502
static const char * EulaText[] = {
"{\\rtf1\\ansi\\ansicpg1252\\deff0\\nouicompat\\deflang1033{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Tahoma;}{\\f1\\fnil\\fcharset0 Calibri;}}",
"{\\colortbl ;\\red0\\green0\\blue255;\\red0\\green0\\blue0;}",
"{\\*\\generator Riched20 10.0.10240}\\viewkind4\\uc1 ",
"\\pard\\brdrb\\brdrs\\brdrw10\\brsp20 \\sb120\\sa120\\b\\f0\\fs24 SYSINTERNALS SOFTWARE LICENSE TERMS\\fs28\\par",
"\\pard\\sb120\\sa120\\b0\\fs19 These license terms are an agreement between Sysinternals (a wholly owned subsidiary of Microsoft Corporation) and you. Please read them. They apply to the software you are downloading from Sysinternals.com, which includes the media on which you received it, if any. The terms also apply to any Sysinternals\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\'b7\\tab updates,\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\'b7\\tab supplements,\\par",
"\\'b7\\tab Internet-based services, and \\par",
"\\'b7\\tab support services\\par",
"\\pard\\sb120\\sa120 for this software, unless other terms accompany those items. If so, those terms apply.\\par",
"\\b BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\\par",
"\\pard\\brdrt\\brdrs\\brdrw10\\brsp20 \\sb120\\sa120 If you comply with these license terms, you have the rights below.\\par",
"\\pard\\fi-357\\li357\\sb120\\sa120\\tx360\\fs20 1.\\tab\\fs19 INSTALLATION AND USE RIGHTS. \\b0 You may install and use any number of copies of the software on your devices.\\b\\par",
"\\caps\\fs20 2.\\tab\\fs19 Scope of License\\caps0 .\\b0 The software is licensed, not sold. This agreement only gives you some rights to use the software. Sysinternals reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways. You may not\\b\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\b0\\'b7\\tab work around any technical limitations in the binary versions of the software;\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\'b7\\tab reverse engineer, decompile or disassemble the binary versions of the software, except and only to the extent that applicable law expressly permits, despite this limitation;\\par",
"\\'b7\\tab make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\\par",
"\\'b7\\tab publish the software for others to copy;\\par",
"\\'b7\\tab rent, lease or lend the software;\\par",
"\\'b7\\tab transfer the software or this agreement to any third party; or\\par",
"\\'b7\\tab use the software for commercial software hosting services.\\par",
"\\pard\\fi-357\\li357\\sb120\\sa120\\tx360\\b\\fs20 3.\\tab SENSITIVE INFORMATION. \\b0 Please be aware that, similar to other debug tools that capture \\ldblquote process state\\rdblquote information, files saved by Sysinternals tools may include personally identifiable or other sensitive information (such as usernames, passwords, paths to files accessed, and paths to registry accessed). By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software.\\b\\par",
"5. \\tab\\fs19 DOCUMENTATION.\\b0 Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\\b\\par",
"\\caps\\fs20 6.\\tab\\fs19 Export Restrictions\\caps0 .\\b0 The software is subject to United States export laws and regulations. You must comply with all domestic and international export laws and regulations that apply to the software. These laws include restrictions on destinations, end users and end use. For additional information, see {\\cf1\\ul{\\field{\\*\\fldinst{HYPERLINK www.microsoft.com/exporting }}{\\fldrslt{www.microsoft.com/exporting}}}}\\cf1\\ul\\f0\\fs19 <{{\\field{\\*\\fldinst{HYPERLINK \"http://www.microsoft.com/exporting\"}}{\\fldrslt{http://www.microsoft.com/exporting}}}}\\f0\\fs19 >\\cf0\\ulnone .\\b\\par",
"\\caps\\fs20 7.\\tab\\fs19 SUPPORT SERVICES.\\caps0 \\b0 Because this software is \"as is, \" we may not provide support services for it.\\b\\par",
"\\caps\\fs20 8.\\tab\\fs19 Entire Agreement.\\b0\\caps0 This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\\par",
"\\pard\\keepn\\fi-360\\li360\\sb120\\sa120\\tx360\\cf2\\b\\caps\\fs20 9.\\tab\\fs19 Applicable Law\\caps0 .\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\cf0\\fs20 a.\\tab\\fs19 United States.\\b0 If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles. The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\\b\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\fs20 b.\\tab\\fs19 Outside the United States.\\b0 If you acquired the software in any other country, the laws of that country apply.\\b\\par",
"\\pard\\fi-357\\li357\\sb120\\sa120\\tx360\\caps\\fs20 10.\\tab\\fs19 Legal Effect.\\b0\\caps0 This agreement describes certain legal rights. You may have other rights under the laws of your country. You may also have rights with respect to the party from whom you acquired the software. This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\\b\\caps\\par",
"\\fs20 11.\\tab\\fs19 Disclaimer of Warranty.\\caps0 \\caps The software is licensed \"as - is.\" You bear the risk of using it. SYSINTERNALS gives no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this agreement cannot change. To the extent permitted under your local laws, SYSINTERNALS excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement.\\par",
"\\pard\\fi-360\\li360\\sb120\\sa120\\tx360\\fs20 12.\\tab\\fs19 Limitation on and Exclusion of Remedies and Damages. You can recover from SYSINTERNALS and its suppliers only direct damages up to U.S. $5.00. You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\\par",
"\\pard\\li357\\sb120\\sa120\\b0\\caps0 This limitation applies to\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\'b7\\tab anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\'b7\\tab claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\\par",
"\\pard\\li360\\sb120\\sa120 It also applies even if Sysinternals knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\\par",
"\\pard\\b Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\\par",
"\\pard\\sb240\\lang1036 Remarque : Ce logiciel \\'e9tant distribu\\'e9 au Qu\\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\\'e7ais.\\par",
"\\pard\\sb120\\sa120 EXON\\'c9RATION DE GARANTIE.\\b0 Le logiciel vis\\'e9 par une licence est offert \\'ab tel quel \\'bb. Toute utilisation de ce logiciel est \\'e0 votre seule risque et p\\'e9ril. Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez b\\'e9n\\'e9ficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\\'e9 marchande, d'ad\\'e9quation \\'e0 un usage particulier et d'absence de contrefa\\'e7on sont exclues.\\par",
"\\pard\\keepn\\sb120\\sa120\\b LIMITATION DES DOMMAGES-INT\\'c9R\\'caTS ET EXCLUSION DE RESPONSABILIT\\'c9 POUR LES DOMMAGES.\\b0 Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \\'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\\'e9tendre \\'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\\'e9ciaux, indirects ou accessoires et pertes de b\\'e9n\\'e9fices.\\par",
"\\lang1033 Cette limitation concerne :\\par",
"\\pard\\keepn\\fi-360\\li720\\sb120\\sa120\\tx720\\lang1036\\'b7\\tab tout ce qui est reli\\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\\par",
"\\pard\\fi-363\\li720\\sb120\\sa120\\tx720\\'b7\\tab les r\\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\\'e9 stricte, de n\\'e9gligence ou d'une autre faute dans la limite autoris\\'e9e par la loi en vigueur.\\par",
"\\pard\\sb120\\sa120 Elle s'applique \\'e9galement, m\\'eame si Sysinternals connaissait ou devrait conna\\'eetre l'\\'e9ventualit\\'e9 d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilit\\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci-dessus ne s'appliquera pas \\'e0 votre \\'e9gard.\\par",
"\\b EFFET JURIDIQUE.\\b0 Le pr\\'e9sent contrat d\\'e9crit certains droits juridiques. Vous pourriez avoir d'autres droits pr\\'e9vus par les lois de votre pays. Le pr\\'e9sent contrat ne modifie pas les droits que vous conf\\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\\b\\par",
"\\pard\\b0\\fs20\\lang1033\\par",
"\\pard\\sa200\\sl276\\slmult1\\f1\\fs22\\lang9\\par",
"}",
NULL
};
static const wchar_t *Raw_EulaText = L"SYSINTERNALS SOFTWARE LICENSE TERMS\nThese license terms are an agreement between Sysinternals(a wholly owned subsidiary of Microsoft Corporation) and you.Please read them.They apply to the software you are downloading from technet.microsoft.com / sysinternals, which includes the media on which you received it, if any.The terms also apply to any Sysinternals\n* updates,\n*supplements,\n*Internet - based services,\n*and support services\nfor this software, unless other terms accompany those items.If so, those terms apply.\nBY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\n\nIf you comply with these license terms, you have the rights below.\nINSTALLATION AND USER RIGHTS\nYou may install and use any number of copies of the software on your devices.\n\nSCOPE OF LICENSE\nThe software is licensed, not sold.This agreement only gives you some rights to use the software.Sysinternals reserves all other rights.Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement.In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways.You may not\n* work around any technical limitations in the software;\n*reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\n*make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\n*publish the software for others to copy;\n*rent, lease or lend the software;\n*transfer the software or this agreement to any third party; or\n* use the software for commercial software hosting services.\n\nSENSITIVE INFORMATION\nPlease be aware that, similar to other debug tools that capture “process state” information, files saved by Sysinternals tools may include personally identifiable or other sensitive information(such as usernames, passwords, paths to files accessed, and paths to registry accessed).By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software.\n\nDOCUMENTATION\nAny person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\n\nEXPORT RESTRICTIONS\nThe software is subject to United States export laws and regulations.You must comply with all domestic and international export laws and regulations that apply to the software.These laws include restrictions on destinations, end users and end use.For additional information, see www.microsoft.com / exporting .\n\nSUPPORT SERVICES\nBecause this software is \"as is, \" we may not provide support services for it.\n\nENTIRE AGREEMENT\nThis agreement, and the terms for supplements, updates, Internet - based services and support services that you use, are the entire agreement for the software and support services.\n\nAPPLICABLE LAW\nUnited States.If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles.The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\nOutside the United States.If you acquired the software in any other country, the laws of that country apply.\n\nLEGAL EFFECT\nThis agreement describes certain legal rights.You may have other rights under the laws of your country.You may also have rights with respect to the party from whom you acquired the software.This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\n\nDISCLAIMER OF WARRANTY\nThe software is licensed \"as - is.\" You bear the risk of using it.Sysinternals gives no express warranties, guarantees or conditions.You may have additional consumer rights under your local laws which this agreement cannot change.To the extent permitted under your local laws, sysinternals excludes the implied warranties of merchantability, fitness for a particular purpose and non - infringement.\n\nLIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES\nYou can recover from sysinternals and its suppliers only direct damages up to U.S.$5.00.You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\nThis limitation applies to\n* anything related to the software, services, content(including code) on third party Internet sites, or third party programs; and\n* claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\nIt also applies even if Sysinternals knew or should have known about the possibility of the damages.The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\nPlease note : As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\nRemarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci - dessous en français.\n EXONÉRATION DE GARANTIE.Le logiciel visé par une licence est offert « tel quel ».Toute utilisation de ce logiciel est à votre seule risque et péril.Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d'adéquation à un usage particulier et d'absence de contrefaçon sont exclues.\n LIMITATION DES DOMMAGES - INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES.Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5, 00 $ US.Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.\n\n Cette limitation concerne :\ntout ce qui est relié au logiciel, aux services ou au contenu(y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et\nles réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d'une autre faute dans la limite autorisée par la loi en vigueur.\n\nElle s'applique également, même si Sysinternals connaissait ou devrait connaître l'éventualité d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci - dessus ne s'appliquera pas à votre égard.\nEFFET JURIDIQUE.Le présent contrat décrit certains droits juridiques.Vous pourriez avoir d'autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.\n\n";
BOOL IsEulaRegkeyAdded(const TCHAR * ToolName);
static BOOL EulaCenter( HWND hwndChild, HWND hwndParent )
{
RECT rcChild, rcParent;
int cxChild, cyChild, cxParent, cyParent;
int cxScreen, cyScreen, xNew, yNew;
HDC hdc;
// Get the Height and Width of the child window
GetWindowRect(hwndChild, &rcChild);
cxChild = rcChild.right - rcChild.left;
cyChild = rcChild.bottom - rcChild.top;
// Get the Height and Width of the parent window
GetWindowRect(hwndParent, &rcParent);
cxParent = rcParent.right - rcParent.left;
cyParent = rcParent.bottom - rcParent.top;
// Get the display limits
hdc = GetDC(hwndChild);
cxScreen = GetDeviceCaps(hdc, HORZRES);
cyScreen = GetDeviceCaps(hdc, VERTRES);
ReleaseDC(hwndChild, hdc);
// Calculate new X position, then adjust for screen
xNew = rcParent.left + ((cxParent - cxChild) / 2);
if (xNew < 0)
{
xNew = 0;
}
else if ((xNew + cxChild) > cxScreen)
{
xNew = cxScreen - cxChild;
}
// Calculate new Y position, then adjust for screen
yNew = rcParent.top + ((cyParent - cyChild) / 2);
if (yNew < 0)
{
yNew = 0;
}
else if ((yNew + cyChild) > cyScreen)
{
yNew = cyScreen - cyChild;
}
// Set it, and return
return SetWindowPos(hwndChild,
NULL,
xNew, yNew,
0, 0,
SWP_NOSIZE | SWP_NOZORDER);
}
static BOOL PrintRichedit( HWND hRichedit )
{
// Get the printer.
PRINTDLG pd = { 0 };
pd.lStructSize = sizeof pd;
pd.hwndOwner = hRichedit;
pd.hInstance = GetModuleHandle(NULL);
pd.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION | PD_PRINTSETUP;
if ( !PrintDlg( &pd ) )
return FALSE;
{
HCURSOR oldCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
int nHorzRes = GetDeviceCaps( pd.hDC, HORZRES );
int nVertRes = GetDeviceCaps( pd.hDC, VERTRES );
int nLogPixelsX = GetDeviceCaps( pd.hDC, LOGPIXELSX );
int nLogPixelsY = GetDeviceCaps( pd.hDC, LOGPIXELSY );
FORMATRANGE fr = { 0 };
DOCINFO di = { 0 };
int TotalLength;
// Ensure the printer DC is in MM_TEXT mode.
SetMapMode( pd.hDC, MM_TEXT );
// Rendering to the same DC we are measuring.
fr.hdc = pd.hDC;
fr.hdcTarget = pd.hDC;
// Set up the page.
fr.rcPage.top = 0;
fr.rcPage.left = 0;
fr.rcPage.bottom = (nVertRes/nLogPixelsY) * 1440;
fr.rcPage.right = (nHorzRes/nLogPixelsX) * 1440;
// Set up 1" margins all around.
fr.rc = fr.rcPage;
InflateRect( &fr.rc, -1440, -1440 );
// Default the range of text to print as the entire document.
fr.chrg.cpMin = 0;
fr.chrg.cpMax = -1;
// Set up the print job (standard printing stuff here).
di.cbSize = sizeof di;
di.lpszDocName = _T("Sysinternals License");
// Start the document.
StartDoc( pd.hDC, &di );
// Find out real size of document in characters.
TotalLength = (int) SendMessage ( hRichedit, WM_GETTEXTLENGTH, 0, 0 );
for (;;) {
int NextPage;
// Start the page.
StartPage( pd.hDC );
// Print as much text as can fit on a page. The return value is
// the index of the first character on the next page.
NextPage = (int) SendMessage( hRichedit, EM_FORMATRANGE, TRUE, (LPARAM)&fr );
// Print last page.
EndPage( pd.hDC );
if ( NextPage >= TotalLength )
break;
// Adjust the range of characters to start printing at the first character of the next page.
fr.chrg.cpMin = NextPage;
fr.chrg.cpMax = -1;
}
// Tell the control to release cached information.
SendMessage( hRichedit, EM_FORMATRANGE, 0, (LPARAM)NULL );
EndDoc( pd.hDC );
SetCursor( oldCursor );
}
return TRUE;
}
// combine all text strings into a single string
char * GetEulaText()
{
char * text;
DWORD len = 1;
int i;
for ( i = 0; EulaText[i]; ++i )
len += (DWORD) strlen( EulaText[i] );
text = (char *) malloc( len );
len = 0;
for ( i = 0; EulaText[i]; ++i ) {
strcpy( text+len, EulaText[i] );
len += (DWORD) strlen( EulaText[i] );
}
text[len] = 0;
return text;
}
DWORD CALLBACK StreamCallback( DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb )
{
const char ** ptr = (const char **) dwCookie;
LONG_PTR len = strlen(*ptr);
if ( cb > len )
cb = (int) len;
memcpy( pbBuff, *ptr, cb );
*pcb = cb;
*ptr += cb;
return 0;
}
static INT_PTR CALLBACK EulaProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg ) {
case WM_INITDIALOG:
{
TCHAR title[MAX_PATH];
char * text = GetEulaText();
char * textptr = text;
EDITSTREAM stream = { 0, 0, StreamCallback };
stream.dwCookie = (DWORD_PTR) &textptr;
_stprintf_s( title, MAX_PATH, _T("%s 许可协议"), (TCHAR *) lParam );
SetWindowText( hwndDlg, title );
// enter RTF into edit box
SendMessage( GetDlgItem(hwndDlg,IDC_TEXT), EM_EXLIMITTEXT, 0, 1024*1024 );
SendMessage( GetDlgItem(hwndDlg,IDC_TEXT), EM_STREAMIN, SF_RTF, (LPARAM)&stream );
free( text );
}
return TRUE;
case WM_CTLCOLORSTATIC:
// force background of read-only text window to be white
if ( (HWND)lParam == GetDlgItem( hwndDlg, IDC_TEXT) ) {
return (INT_PTR)GetSysColorBrush( COLOR_WINDOW );
}
break;
case WM_COMMAND:
switch( LOWORD( wParam )) {
case IDOK:
EndDialog( hwndDlg, TRUE );
return TRUE;
case IDCANCEL:
EndDialog( hwndDlg, FALSE );
return TRUE;
case IDC_PRINT:
PrintRichedit( GetDlgItem(hwndDlg,IDC_TEXT) );
return TRUE;
}
break;
}
return FALSE;
}
static WORD * Align2( WORD * pos )
{
return (WORD *)(((DWORD_PTR)pos + 1) & ~((DWORD_PTR) 1));
}
static WORD * Align4( WORD * pos )
{
return (WORD *)(((DWORD_PTR)pos + 3) & ~((DWORD_PTR) 3));
}
static int CopyText( WORD * pos, const WCHAR * text )
{
int len = (int) wcslen( text ) + 1;
wcscpy( (PWCHAR) pos, text );
return len;
}
BOOL ShowEulaInternal( const TCHAR * ToolName, DWORD eulaAccepted )
{
#if !defined(SYSMON_SHARED)
HKEY hKey = NULL;
TCHAR keyName[MAX_PATH];
_stprintf_s( keyName, MAX_PATH, _T("Software\\Sysinternals\\%s"), ToolName );
//
// check the regkey value if no -accepteula switch append
//
if (!eulaAccepted)
{
eulaAccepted = IsEulaRegkeyAdded(ToolName);
}
#endif
if( !eulaAccepted ) {
if (IsIoTEdition())
{
eulaAccepted = ShowEulaConsole(); // display Eula to console and prompt for Eula Accepted.
{
}
}
else if (IsRemoteOnlyEdition() || IsRunningRemotely()) // Nano and in remote session will not be able to accept eula from prompt
{
ShowEulaConsoleNoPrompt();
}
else
{
DLGTEMPLATE * dlg = (DLGTEMPLATE *)LocalAlloc(LPTR, 1000);
WORD * extra = (WORD *)(dlg + 1);
DLGITEMTEMPLATE * item;
#if defined(SYSMON_SHARED)
printf( "正在打开 EULA 许可协议对话框 ... (使用 -accepteula 可跳过)。\n" );
#endif
LoadLibrarySafe(_T("Riched32.dll"), DLL_LOAD_LOCATION_SYSTEM ); // Richedit 1.0 library
// header
dlg->style = DS_MODALFRAME | DS_CENTER | DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_NOFAILCREATE;
dlg->x = 0;
dlg->y = 0;
dlg->cx = 312;
dlg->cy = 180;
dlg->cdit = 0; // number of controls
*extra++ = 0; // menu
*extra++ = 0; // class
extra += CopyText(extra, L"许可协议");
*extra++ = 8; // font size
extra += CopyText(extra, L"MS Shell Dlg");
// Command-line message
item = (DLGITEMTEMPLATE *)Align4(extra);
item->x = 7;
item->y = 3;
item->cx = 298;
item->cy = 14;
item->id = IDC_TEXT1;
item->style = WS_CHILD | WS_VISIBLE;
extra = (WORD *)(item + 1);
*extra++ = 0xFFFF; // class is ordinal
*extra++ = 0x0082; // class is static
extra += CopyText(extra, L"您也可使用 /accepteula 命令行开关来同意 EULA。");
*extra++ = 0; // creation data
dlg->cdit++;
// Agree button
item = (DLGITEMTEMPLATE *)Align4(extra);
item->x = 201;
item->y = 159;
item->cx = 50;
item->cy = 14;
item->id = IDOK;
item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP; // | WS_DEFAULT;
extra = (WORD *)(item + 1);
*extra++ = 0xFFFF; // class is ordinal
*extra++ = 0x0080; // class is button
extra += CopyText(extra, L"同意(&A)");
*extra++ = 0; // creation data
dlg->cdit++;
// Decline button
item = (DLGITEMTEMPLATE *)Align4(extra);
item->x = 255;
item->y = 159;
item->cx = 50;
item->cy = 14;
item->id = IDCANCEL;
item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
extra = (WORD *)(item + 1);
*extra++ = 0xFFFF; // class is ordinal
*extra++ = 0x0080; // class is button
extra += CopyText(extra, L"拒绝(&D)");
*extra++ = 0; // creation data
dlg->cdit++;
// Print button
item = (DLGITEMTEMPLATE *)Align4(extra);
item->x = 7;
item->y = 159;
item->cx = 50;
item->cy = 14;
item->id = IDC_PRINT;
item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
extra = (WORD *)(item + 1);
*extra++ = 0xFFFF; // class is ordinal
*extra++ = 0x0080; // class is button
extra += CopyText(extra, L"打印(&P)");
*extra++ = 0; // creation data
dlg->cdit++;
// Edit box
item = (DLGITEMTEMPLATE *)Align4(extra);
item->x = 7;
item->y = 14;
item->cx = 298;
item->cy = 140;
item->id = IDC_TEXT;
item->style = WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
extra = (WORD *)(item + 1);
extra += CopyText(extra, L"RICHEDIT");
extra += CopyText(extra, L"拒绝(&D)");
*extra++ = 0; // creation data
dlg->cdit++;
eulaAccepted = (DWORD)DialogBoxIndirectParam(NULL, dlg, NULL, EulaProc, (LPARAM)ToolName);
LocalFree(dlg);
}
}
#if !defined(SYSMON_SHARED)
if ( eulaAccepted ) {
if (RegCreateKey(HKEY_CURRENT_USER, keyName, &hKey) == ERROR_SUCCESS) {
RegSetValueEx(hKey, _T("EulaAccepted"), 0, REG_DWORD, (BYTE *)&eulaAccepted, sizeof(eulaAccepted));
RegCloseKey(hKey);
}
}
#endif
return eulaAccepted != 0;
}
BOOL ShowEulaW( const TCHAR * ToolName, int *argc, PWCHAR argv[] )
{
DWORD eulaAccepted = 0;
int i;
if ( argc == NULL || argv == NULL ) {
typedef LPWSTR * (WINAPI * type_CommandLineToArgvW)( LPCWSTR lpCmdLine, int *pNumArgs );
type_CommandLineToArgvW pCommandLineToArgvW = (type_CommandLineToArgvW) GetProcAddress( LoadLibrarySafe(_T("Shell32.dll"), DLL_LOAD_LOCATION_SYSTEM), "CommandLineToArgvW" );
if ( pCommandLineToArgvW ) {
static int argc2;
argc = &argc2;
argv = (*pCommandLineToArgvW)( GetCommandLineW(), argc );
} else {
argc = NULL;
}
}
//
// See if its accepted via command line switch
//
if( argc ) {
for( i = 0; i < *argc; i++ ) {
eulaAccepted = (!_wcsicmp( argv[i], L"/accepteula") ||
!_wcsicmp( argv[i], L"-accepteula"));
if( eulaAccepted ) {
for( ; i < *argc - 1; i++ ) {
argv[i] = argv[i+1];
}
(*argc)--;
break;
}
}
}
if( ShowEulaInternal( ToolName, eulaAccepted )) {
eulaAccepted = 1;
}
return eulaAccepted != 0;
}
BOOL ShowEula( const TCHAR * ToolName, int *argc, PTCHAR argv[] )
{
DWORD eulaAccepted = 0;
int i;
if ( argc == NULL || argv == NULL ) {
return ShowEulaW( ToolName, NULL, NULL );
}
//
// See if its accepted via command line switch
//
if( argc ) {
for( i = 0; i < *argc; i++ ) {
eulaAccepted = (!_tcsicmp( argv[i], _T("/accepteula")) ||
!_tcsicmp( argv[i], _T("-accepteula")));
if( eulaAccepted ) {
for( ; i < *argc - 1; i++ ) {
argv[i] = argv[i+1];
}
(*argc)--;
break;
}
}
}
if( ShowEulaInternal( ToolName, eulaAccepted )) {
eulaAccepted = 1;
}
return eulaAccepted != 0;
}
// Determine whether we are on the IoT SKU by looking at the ProductName.
BOOL IsIoTEdition()
{
HKEY hKey = NULL;
wchar_t ProductName[MAX_PATH];
BOOL bRet = FALSE; // assume "not" IoT Edition
DWORD dwSize = sizeof(ProductName);
DWORD type = 0;
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\windows nt\\currentversion"), &hKey))
{
if (ERROR_SUCCESS == RegQueryValueExW(hKey, L"ProductName", 0, &type, (LPBYTE)ProductName, &dwSize))
{
if (!_wcsicmp(L"iotuap", ProductName))
bRet = TRUE;
}
RegCloseKey(hKey);
}
return bRet;
}
// Determine whether we are on the remote only edition, where we cannot prompt for user input.
BOOL IsRemoteOnlyEdition()
{
HKEY hKey = NULL;
DWORD dwNanoServer = 0;
BOOL bRet = FALSE;
DWORD dwSize = sizeof(dwNanoServer);
DWORD type = 0;
// Currently Nano is the only remote only edtion.
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Server\\ServerLevels"), &hKey))
{
if (ERROR_SUCCESS == RegQueryValueEx(hKey, _T("NanoServer"), 0, &type, (LPBYTE)&dwNanoServer, &dwSize))
{
if (type == REG_DWORD && dwNanoServer == 1)
bRet = TRUE;
}
RegCloseKey(hKey);
}
return bRet;
}
BOOL IsRunningRemotely()
{
// running from a remote session will not support input interaction
DWORD fileType = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));
return fileType == FILE_TYPE_PIPE;
}
DWORD ShowEulaConsole()
{
DWORD dwRet = 0;
char ch;
BOOLEAN eulaAcknowledged = FALSE;
wprintf(Raw_EulaText);
while( eulaAcknowledged != TRUE )
{
printf("是否接受 EULA (Y/N)?");
ch = (char) _getch();
printf("%c\n", ch);
if ('y' == ch || 'Y' == ch)
{
dwRet = 1; // EULA Accepted.
eulaAcknowledged = TRUE;
}
if ('n' == ch || 'N' == ch)
{
// EULA not accepted.
eulaAcknowledged = TRUE;
}
}
return dwRet;
}
void ShowEulaConsoleNoPrompt()
{
wprintf_s(L"%ls", Raw_EulaText);
wprintf_s(L"这是您首次运行此程序,需要同意 EULA 才能继续。\n");
wprintf_s(L"可使用 -accepteula 来同意 EULA。\n\n");
// exit here to avoid printing the misleading "Eula declined".
exit(1);
}
BOOL IsEulaAcceptedValueExist(HKEY hKeyRoot, LPCTSTR lpSubKey)
{
HKEY hKey = NULL;
DWORD length;
DWORD eulaAccepted = 0;
DWORD ret;
//
// check if it is set by external channel for all tools
// assuming external channel do not set to WOW6432Node
//
if (RegOpenKeyEx(hKeyRoot, lpSubKey, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
{
length = sizeof(eulaAccepted);
ret = RegQueryValueEx(hKey, _T("EulaAccepted"), NULL, NULL, (LPBYTE)&eulaAccepted, &length);
RegCloseKey(hKey);
if (ret == ERROR_SUCCESS && eulaAccepted)
{
return TRUE;
}
}
return FALSE;
}
BOOL IsEulaRegkeyAdded(const TCHAR * ToolName)
{
TCHAR perToolRegKey[MAX_PATH];
PTCHAR suiteRegKey = _T("Software\\Sysinternals");
_stprintf_s(perToolRegKey, MAX_PATH, _T("%s\\%s"), suiteRegKey, ToolName);
//
// check if it is set by external channel for all tools
// assuming external channel do not set to WOW6432Node
//
if (IsEulaAcceptedValueExist(HKEY_LOCAL_MACHINE, suiteRegKey) ||
IsEulaAcceptedValueExist(HKEY_CURRENT_USER, suiteRegKey))
{
return TRUE;
}
//
// per tool check
//
if (IsEulaAcceptedValueExist(HKEY_CURRENT_USER, perToolRegKey))
{
return TRUE;
}
return FALSE;
}
BOOL IsEulaSwitchAppended(int *argc, PTCHAR argv[])
{
DWORD eulaAccepted = 0;
int i;
//
// See if its accepted via command line switch
//
if (*argc > 1) {
for (i = 1; i < *argc; i++) {
eulaAccepted = (!_tcsicmp(argv[i], _T("/accepteula")) ||
!_tcsicmp(argv[i], _T("-accepteula")));
if (eulaAccepted) {
break;
}
}
}
return eulaAccepted;
}
//
// Determine if Eula is accepted, either already have regkey added
// or have -accepteula switch appended
//
BOOL IsEulaAccepted(const TCHAR * ToolName, int *argc, PTCHAR argv[])
{
return IsEulaRegkeyAdded(ToolName) || IsEulaSwitchAppended(argc, argv);
}
================================================
FILE: PowerToys/src/gpo/assets/zh-CN/PowerToys.adml
================================================
PowerToys
PowerToys
Microsoft PowerToys
安装与更新
快捷启动器
高级粘贴
无界鼠标
常规设置
新建+
已弃用
PowerToys 版本 0.64.0 或更高版本
PowerToys 版本 0.68.0 或更高版本
PowerToys 版本 0.69.0 或更高版本
PowerToys 版本 0.70.0 或更高版本
PowerToys 版本 0.73.0 或更高版本
PowerToys 版本 0.75.0 或更高版本
PowerToys 版本 0.76.0 或更高版本
PowerToys 版本 0.77.0 或更高版本
PowerToys 版本 0.78.0 或更高版本
PowerToys 版本 0.81.0 或更高版本
PowerToys 版本 0.81.1 或更高版本
PowerToys 版本 0.83.0 或更高版本
PowerToys 版本 0.84.0 或更高版本
PowerToys 版本 0.85.0 或更高版本
PowerToys 版本 0.86.0 或更高版本
PowerToys 版本 0.88.0 或更高版本
PowerToys 版本 0.64.0 至 0.87.1
此策略控制所有 PowerToys 功能的启用状态。
如果策略设置为“已启用”,所有功能将始终启用,用户不可以禁用任何功能。
如果策略设置为“已禁用”,所有功能将始终禁用,用户不可以启用任何功能。
如果策略设置为“未配置”,用户可以自由地启用和禁用功能。
特定某个功能的启用状态策略将会覆盖此策略。
此策略控制一个 PowerToys 功能的启用状态。
如果策略设置为“已启用”,该功能将始终启用,用户不可以禁用这个功能。
如果策略设置为“已禁用”,该功能将始终禁用,用户不可以启用这个功能。
如果策略设置为“未配置”,用户可以自由地启用和禁用这个功能。
该策略比“配置所有功能的启用状态”策略优先级更高,将会覆盖其设置。
(注意:有用户反馈 PDF 预览与 Outlook 不兼容)
此策略控制一个 PowerToys 功能的启用状态。
如果策略设置为“已启用”,该功能将始终启用,用户不可以禁用这个功能。
如果策略设置为“已禁用”,该功能将始终禁用,用户不可以启用这个功能。
如果策略设置为“未配置”,用户可以自由地启用和禁用这个功能。
该策略比“配置所有功能的启用状态”策略优先级更高,将会覆盖其设置。
此策略控制是否允许单用户安装。
如果策略设置为“已启用”,禁用单用户安装。
如果策略设置为“已禁用”或“未配置”,用户可以选择仅为单用户安装 PowerToys。
此策略控制是否禁用自动下载和安装更新。(不过,在按流量计费的网络上,永远不会自动下载更新。)
如果策略设置为“已启用”,禁用自动下载和安装更新。
如果策略设置为“已禁用”或“未配置”,用户可以在设置中自行选择。
此策略控制是否在两次小版本更新内,不显示更新通知。(比如:如果安装的版本为 v0.60.0,则下一次显示更新提示将会是版本 v0.63.*)
如果策略设置为“已启用”,减少更新通知。
如果策略设置为“已禁用”或“未配置”,正常显示所有更新通知。
注意:大版本更新通知始终会显示。
如果启用“禁用新版本更新消息推送”策略或者在软件设置中关闭了自动更新,则该策略无效。
此策略控制是否禁用更新通知。
如果策略设置为“已启用”,不显示更新通知。
如果策略设置为“已禁用”或“未配置”,用户可以选择是否显示更新通知。
此策略控制更新完成后是否显示更新日志窗口。
如果策略设置为“已启用”,更新完成后不会自动打开更新日志。
如果策略设置为“已禁用”或“未配置”,用户可以在设置中自行选择。
此策略控制是否允许进行 PowerToys 功能测试。如果允许测试,当用户被选中为测试组时,可以用到实验性的新功能。(功能测试只会在 Windows Insider 版本上进行。)
如果策略设置为“已启用”,用户可以在 PowerToys 设置里选择是否参与功能测试。
如果策略设置为“已禁用”或“未配置”,不允许参与功能测试。
此策略控制是否允许发送 PowerToys 诊断数据。发送诊断数据可以帮助修复错误和优化性能。
如果策略设置为“已启用”或“未配置”,用户可以在 PowerToys 设置里选择是否发送诊断数据。
如果策略设置为“已禁用”或“未配置”,不允许发送诊断数据。
此策略控制所有快捷启动器插件的启用状态。所有插件将会拥有相同的启用状态。
如果策略设置为“已启用”,所有插件将始终启用,用户不可以禁用任何插件。
如果策略设置为“已禁用”,所有插件将始终禁用,用户不可以启用任何插件。
如果策略设置为“未配置”,用户可以自由地启用和禁用插件。
可以通过“配置特定插件的启用状态”策略来为特定插件配置启用状态覆盖此设置。特定某个功能的启用状态策略将会覆盖此策略。
注意:更改需要重新启动快捷启动器才能应用。
此策略控制列表中每个快捷启动器插件的启用状态。
如果策略设置为“已启用”,你可以在列表中定义某个插件和其启用状态:
- 值名称(第一列)填入插件 ID,可以在插件文件夹内 plugin.json 文件中找到对应 ID。
- 值(第二列)填入数字,0 代表禁用,1 代表启用,2 代表由用户控制。
- 这是禁用“应用程序”插件的例子: 791FC278BA414111B8D1886DFE447410 | 0
如果策略设置为“已禁用”或“未配置”,用户或“配置所有插件的启用状态”可以控制插件的启用状态。
启用该策略后,你可以通过“配置所有插件的启用状态”策略,来控制列表外的其他插件的启用状态。
注意:更改需要重新启动快捷启动器才能应用。
此策略可以禁用高级粘贴的在线 AI 模型。
如果策略设置为“已启用”或“未配置”,用户可以设置是否启用 AI 粘贴功能。
如果策略设置为“已禁用”,用户不可以启用 AI 粘贴功能,不可以在粘贴面板中输入 AI 提示词,也不能配置 OpenAI 密钥。
此策略控制是否允许在多台设备之间同步剪贴板。
如果策略设置为“已启用”或“未配置”,用户可以自由地启用共享剪贴板功能。
如果策略设置为“已禁用”,该功能将始终禁用,用户不可以启用这个功能。
此策略控制是否允许在多台设备间传输剪贴板文件。
如果策略设置为“已启用”或“未配置”,用户可以自由地启用共享文件功能。
如果策略设置为“已禁用”,该功能将始终禁用,用户不可以启用这个功能。
注意:共享文件需要开启共享剪贴板。如果禁用共享剪贴板,共享文件也将自动禁用。
此策略控制是否允许使用旧版无界鼠标界面。
如果策略设置为“已启用”或“未配置”,用户可以自由地启用旧版界面。
如果策略设置为“已禁用”,用户不可以启用旧版界面。
此策略控制是否允许关闭被控电脑上的屏幕保护程序。
如果策略设置为“已启用”,用户无法启用阻止屏保功能,被控电脑的屏幕保护程序不会受到影响。
如果策略设置为“已禁用”或“未配置”,用户可以自由地启用阻止屏保。
此策略控制是否仅允许同一内网的连接。
如果策略设置为“已启用”,该功能将始终启用,只允许连接到同一内网的电脑。
如果策略设置为“已禁用”,该功能将始终禁用,允许所有连接。
如果策略设置为“未配置”,用户可以自由地启用和禁用这个功能。
此策略控制是否通过反向 DNS 查找来验证被控设备 IP 地址。
如果策略设置为“已启用”,该功能将始终启用,验证 IP 地址。
如果策略设置为“已禁用”,该功能将始终禁用,不验证 IP 地址。
如果策略设置为“未配置”,用户可以自由地启用和禁用这个功能。
此策略控制是否允许用户设定 IP 地址映射。
如果策略设置为“已启用”,该功能将始终禁用,用户无法设定和使用 IP 地址映射规则。
如果策略设置为“已禁用”或“未配置”,用户可以自由地启用和禁用这个功能。
注意:启用该策略并不会影响组策略的预设 IP 地址映射生效。
此策略可以设定 IP 地址映射规则。
如果策略设置为“已启用”,可以设定强制的 IP 地址映射规则,用户无法改动或禁用。
请按此格式输入,每行一个:"hostname IP"
如果策略设置为“已禁用”或“未配置”,不使用预设规则。
此策略控制是否显示模板文件的扩展名。
如果策略设置为“已启用”,该功能将始终启用,隐藏模板文件扩展名。
如果策略设置为“已禁用”,该功能将始终禁用,显示模板文件扩展名。
如果策略设置为“未配置”,用户可以自由地启用和禁用这个功能。
配置所有功能的启用状态
高级粘贴: 启用该功能
窗口置顶: 启用该功能
阻止睡眠: 启用该功能
取色器: 启用该功能
未找到命令: 启用该功能
窗口镜像: 启用该功能
环境变量: 启用该功能
窗口布局: 启用该功能
文件开锁匠: 启用该功能
预览增强 - SVG 文件预览: 启用该功能
预览增强 - Markdown 文件预览: 启用该功能
预览增强 - 代码文件预览: 启用该功能
预览增强 - PDF 文件预览: 启用该功能
预览增强 - Gcode 文件预览: 启用该功能
预览增强 - SVG 文件缩略图: 启用该功能
预览增强 - PDF 文件缩略图: 启用该功能
预览增强 - Gcode 文件缩略图: 启用该功能
预览增强 - STL 文件缩略图: 启用该功能
域名表: 启用该功能
图像裁剪器: 启用该功能
键盘修改器: 启用该功能
鼠标工具箱 - 鼠标定位: 启用该功能
鼠标工具箱 - 鼠标高亮: 启用该功能
鼠标工具箱 - 鼠标跳转: 启用该功能
鼠标工具箱 - 鼠标准心: 启用该功能
无界鼠标: 启用该功能
新建+: 启用该功能
快速查看: 启用该功能
批量重命名: 启用该功能
快捷启动器: 启用该功能
工作区: 启用该功能
字母助手: 启用该功能
注册表预览: 启用该功能
屏幕标尺: 启用该功能
快捷键指南: 启用该功能
直播工具: 启用该功能
演示工具:启用该功能
禁用单用户安装
禁用自动下载更新
禁用更新日志弹窗
减少新版本更新消息推送
禁用新版本更新消息推送
允许功能测试
配置所有插件的启用状态
配置特定插件的启用状态
预览增强 - QOI 文件预览: 启用该功能
预览增强 - QOI 文件缩略图: 启用该功能
允许使用在线 AI 模型
启用共享剪贴板
启用文件传输
启用原版界面
禁用阻止屏保
仅允许内网控制
验证远程设备 IP 地址
禁用自定义 IP 地址映射
预设 IP 地址映射规则
隐藏模板文件扩展名
允许发送诊断数据
插件管理列表:
IP 地址映射列表:
================================================
FILE: PowerToys/src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
注意 AI 也可能会犯错
剪贴板为空
未启用 AI 粘贴功能
API 密钥或接入点无效
API 密钥额度已用尽
OpenAI 请求失败,返回状态码:
粘贴时出现问题
内容包含敏感信息,无法处理。请试试其他内容。
剪贴板历史记录
剪贴板历史记录
图片数据
更多选项
删除
告诉我你想要什么格式..
告诉我你想要什么格式..
隐私政策
正在生成结果..
粘贴为 JSON
粘贴为 Markdown
粘贴为纯文本
图像转文本
粘贴为 .txt 文件
粘贴为 .png 文件
粘贴为 .html 文件
粘贴
粘贴
结果
回到上一次的提示词与剪贴板数据
回到上一次的提示词与剪贴板数据
生成并粘贴数据
重新生成
重新生成
生成并粘贴数据
打开设置
打开设置
AI 助手给出了如下消息:
差评
好评
高级粘贴
上一条
上一条
下一条
下一条
OpenAI 隐私政策
OpenAI 使用条款
组策略已禁止 AI 功能
Ctrl
PowerToys_Paste_
================================================
FILE: PowerToys/src/modules/CropAndLock/CropAndLock/main.cpp
================================================
#include "pch.h"
#include "SettingsWindow.h"
#include "OverlayWindow.h"
#include "CropAndLockWindow.h"
#include "ThumbnailCropAndLockWindow.h"
#include "ReparentCropAndLockWindow.h"
#include "ModuleConstants.h"
#include "trace.h"
#include
#include
#include
#include
#include
#include
#include
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
namespace winrt
{
using namespace Windows::Foundation;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Composition;
}
namespace util
{
using namespace robmikh::common::desktop;
}
const std::wstring instanceMutexName = L"Local\\PowerToys_CropAndLock_InstanceMutex";
bool m_running = true;
int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _In_ int)
{
// Initialize COM
winrt::init_apartment(winrt::apartment_type::single_threaded);
Trace::CropAndLock::RegisterProvider();
Shared::Trace::ETWTrace trace;
trace.UpdateState(true);
// Initialize logger automatic logging of exceptions.
LoggerHelpers::init_logger(NonLocalizable::ModuleKey, L"", LogSettings::cropAndLockLoggerName);
InitUnhandledExceptionHandler();
if (powertoys_gpo::getConfiguredCropAndLockEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled)
{
Logger::warn(L"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.");
return 0;
}
// Before we do anything, check to see if we're already running. If we are,
// the hotkey won't register and we'll fail. Instead, we should tell the user
// to kill the other instance and exit this one.
auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str());
if (mutex == nullptr)
{
Logger::error(L"Failed to create mutex. {}", get_last_error_or_default(GetLastError()));
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// CropAndLock is already open.
return 1;
}
std::wstring pid = std::wstring(lpCmdLine);
if (pid.empty())
{
Logger::warn(L"Tried to run Crop And Lock as a standalone.");
MessageBoxW(nullptr, L"窗口镜像功能不能独立使用,请从 PowerToys 启动。", L"CropAndLock", MB_ICONERROR);
return 1;
}
auto mainThreadId = GetCurrentThreadId();
ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) {
if (err != ERROR_SUCCESS)
{
Logger::error(L"Failed to wait for parent process exit. {}", get_last_error_or_default(err));
}
else
{
Logger::trace(L"PowerToys runner exited.");
}
Logger::trace(L"Exiting CropAndLock");
PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);
});
// NOTE: reparenting a window with a different DPI context has consequences.
// See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setparent#remarks
// for more info.
winrt::check_bool(SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2));
// Create the DispatcherQueue that the compositor needs to run
auto controller = util::CreateDispatcherQueueControllerForCurrentThread();
// Setup Composition
auto compositor = winrt::Compositor();
// Create our overlay window
std::unique_ptr overlayWindow;
// Keep a list of our cropped windows
std::vector> croppedWindows;
// Handles and thread for the events sent from runner
HANDLE m_reparent_event_handle;
HANDLE m_thumbnail_event_handle;
HANDLE m_exit_event_handle;
std::thread m_event_triggers_thread;
std::function removeWindowCallback = [&](HWND windowHandle) {
if (!m_running)
{
// If we're not running, the reference to croppedWindows might no longer be valid and cause a crash at exit time, due to being called by destructors after wWinMain returns.
return;
}
auto pos = std::find_if(croppedWindows.begin(), croppedWindows.end(), [windowHandle](auto window) { return window->Handle() == windowHandle; });
if (pos != croppedWindows.end())
{
croppedWindows.erase(pos);
}
};
std::function ProcessCommand = [&](CropAndLockType mode) {
std::function windowCroppedCallback = [&, mode](HWND targetWindow, RECT cropRect) {
auto targetInfo = util::WindowInfo(targetWindow);
// TODO: Fix WindowInfo.h to not contain the null char at the end.
auto nullCharIndex = std::wstring::npos;
do
{
nullCharIndex = targetInfo.Title.rfind(L'\0');
if (nullCharIndex != std::wstring::npos)
{
targetInfo.Title.erase(nullCharIndex);
}
} while (nullCharIndex != std::wstring::npos);
std::wstringstream titleStream;
titleStream << targetInfo.Title << L" (镜像)";
auto title = titleStream.str();
std::shared_ptr croppedWindow;
switch (mode)
{
case CropAndLockType::Reparent:
croppedWindow = std::make_shared(title, 800, 600);
Logger::trace(L"Creating a reparent window");
Trace::CropAndLock::CreateReparentWindow();
break;
case CropAndLockType::Thumbnail:
croppedWindow = std::make_shared(title, 800, 600);
Logger::trace(L"Creating a thumbnail window");
Trace::CropAndLock::CreateThumbnailWindow();
break;
default:
return;
}
croppedWindow->CropAndLock(targetWindow, cropRect);
croppedWindow->OnClosed(removeWindowCallback);
croppedWindows.push_back(croppedWindow);
};
overlayWindow.reset();
// Get the current window with focus
auto foregroundWindow = GetForegroundWindow();
if (foregroundWindow != nullptr)
{
bool match = false;
for (auto&& croppedWindow : croppedWindows)
{
if (foregroundWindow == croppedWindow->Handle())
{
match = true;
break;
}
}
if (!match)
{
overlayWindow = std::make_unique(compositor, foregroundWindow, windowCroppedCallback);
}
}
};
// Start a thread to listen on the events.
m_reparent_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::CROP_AND_LOCK_REPARENT_EVENT);
m_thumbnail_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::CROP_AND_LOCK_THUMBNAIL_EVENT);
m_exit_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::CROP_AND_LOCK_EXIT_EVENT);
if (!m_reparent_event_handle || !m_thumbnail_event_handle || !m_exit_event_handle)
{
Logger::warn(L"Failed to create events. {}", get_last_error_or_default(GetLastError()));
return 1;
}
m_event_triggers_thread = std::thread([&]() {
MSG msg;
HANDLE event_handles[3] = { m_reparent_event_handle, m_thumbnail_event_handle, m_exit_event_handle };
while (m_running)
{
DWORD dwEvt = MsgWaitForMultipleObjects(3, event_handles, false, INFINITE, QS_ALLINPUT);
if (!m_running)
{
break;
}
switch (dwEvt)
{
case WAIT_OBJECT_0:
{
// Reparent Event
bool enqueueSucceeded = controller.DispatcherQueue().TryEnqueue([&]() {
ProcessCommand(CropAndLockType::Reparent);
});
if (!enqueueSucceeded)
{
Logger::error("Couldn't enqueue message to reparent a window.");
}
break;
}
case WAIT_OBJECT_0 + 1:
{
// Thumbnail Event
bool enqueueSucceeded = controller.DispatcherQueue().TryEnqueue([&]() {
ProcessCommand(CropAndLockType::Thumbnail);
});
if (!enqueueSucceeded)
{
Logger::error("Couldn't enqueue message to thumbnail a window.");
}
break;
}
case WAIT_OBJECT_0 + 2:
{
// Exit Event
Logger::trace(L"Received an exit event.");
PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);
break;
}
case WAIT_OBJECT_0 + 3:
if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
break;
default:
break;
}
}
});
// Message pump
MSG msg = {};
while (GetMessageW(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
trace.Flush();
Trace::CropAndLock::UnregisterProvider();
m_running = false;
// Needed to unblock MsgWaitForMultipleObjects one last time
SetEvent(m_reparent_event_handle);
CloseHandle(m_reparent_event_handle);
CloseHandle(m_thumbnail_event_handle);
CloseHandle(m_exit_event_handle);
m_event_triggers_thread.join();
return util::ShutdownDispatcherQueueControllerAndWait(controller, static_cast(msg.wParam));
}
================================================
FILE: PowerToys/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Strings/en-us/Resources.resw
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
默认变量
默认变量
新建模板
通过模板来快速设定一组环境变量预设,模板变量优先于用户和系统变量。
模板
系统
用户
环境变量编辑器
Title of the window when running as user
取消
编辑变量
名称
保存
值
保存
新建模板
立即应用
添加变量
名称
Name as in Environment variable name
值
Value as in Environment variable value
已有变量
新建变量
管理员权限: 环境变量编辑器
Title of the window when running as administrator
取消
添加
当前所有环境变量,包括模板、用户和系统所设置的变量。
当前变量
变量
删除
确定删除此模板?如果该模板已启用,它添加的变量也将被删除。
编辑系统环境变量需要管理员权限
否
是
变量发生改动
由模板添加的变量已被修改,在重新启用模板前,请检查改动情况
取消
变量已被其他程序修改,刷新获取最新值
添加变量
确定删除这个变量吗?
编辑模板
添加变量
修改用户和系统的环境变量。
编辑
更多选项
下移
上移
在前面插入
在后面插入
应用到系统?
删除
删除
添加变量
无法应用模板。
变量或备份变量无效。
该变量由已启用的模板写入
================================================
FILE: PowerToys/src/modules/FileLocksmith/FileLocksmithContextMenu/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
查看文件占用
This text will be shown when the user opens the context menu (right clicks) a file. File Locksmith is the product name, do not loc.
文件开锁匠
================================================
FILE: PowerToys/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp
================================================
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include
#include
#include
#include
#include "FileLocksmithLib/IPC.h"
#include "FileLocksmithLib/Settings.h"
#include "FileLocksmithLib/Trace.h"
#include
#include
#include
#include
#include "Generated Files/resource.h"
using namespace Microsoft::WRL;
HINSTANCE g_hInst = 0;
Shared::Trace::ETWTrace trace(L"FileLocksmithContextMenu");
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = hModule;
Trace::RegisterProvider();
break;
case DLL_PROCESS_DETACH:
Trace::UnregisterProvider();
break;
}
return TRUE;
}
class __declspec(uuid("AAF1E27D-4976-49C2-8895-AAFA743C0A7E")) FileLocksmithContextMenuCommand final : public RuntimeClass, IExplorerCommand, IObjectWithSite>
{
public:
virtual const wchar_t* Title() { return L"File Locksmith"; }
virtual const EXPCMDFLAGS Flags() { return ECF_DEFAULT; }
virtual const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) { return ECS_ENABLED; }
// IExplorerCommand
IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
{
return SHStrDup(context_menu_caption.c_str(), name);
}
IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon)
{
std::wstring iconResourcePath = get_module_folderpath(g_hInst);
iconResourcePath += L"\\Assets\\FileLocksmith\\";
iconResourcePath += L"FileLocksmith.ico";
return SHStrDup(iconResourcePath.c_str(), icon);
}
IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip)
{
*infoTip = nullptr;
return E_NOTIMPL;
}
IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName)
{
*guidCommandName = __uuidof(this);
return S_OK;
}
IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState)
{
*cmdState = ECS_ENABLED;
if (!FileLocksmithSettingsInstance().GetEnabled())
{
*cmdState = ECS_HIDDEN;
}
if (FileLocksmithSettingsInstance().GetShowInExtendedContextMenu())
{
*cmdState = ECS_HIDDEN;
}
return S_OK;
}
IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept
{
trace.UpdateState(true);
Trace::Invoked();
ipc::Writer writer;
if (selection == nullptr)
{
return S_OK;
}
if (HRESULT result = writer.start(); FAILED(result))
{
Trace::InvokedRet(result);
trace.Flush();
trace.UpdateState(false);
return result;
}
std::wstring path = get_module_folderpath(g_hInst);
path = path + L"\\PowerToys.FileLocksmithUI.exe";
HRESULT result;
if (!RunNonElevatedEx(path.c_str(), L"", get_module_folderpath(g_hInst)))
{
result = E_FAIL;
Trace::InvokedRet(result);
trace.Flush();
trace.UpdateState(false);
return result;
}
DWORD num_items;
selection->GetCount(&num_items);
for (DWORD i = 0; i < num_items; i++)
{
IShellItem* item;
result = selection->GetItemAt(i, &item);
if (SUCCEEDED(result))
{
LPWSTR file_path;
result = item->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
if (SUCCEEDED(result))
{
// TODO Aggregate items and send to UI
writer.add_path(file_path);
CoTaskMemFree(file_path);
}
item->Release();
}
}
Trace::InvokedRet(S_OK);
trace.Flush();
trace.UpdateState(false);
return S_OK;
}
IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags)
{
*flags = Flags();
return S_OK;
}
IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands)
{
*enumCommands = nullptr;
return E_NOTIMPL;
}
// IObjectWithSite
IFACEMETHODIMP SetSite(_In_ IUnknown* site) noexcept
{
m_site = site;
return S_OK;
}
IFACEMETHODIMP GetSite(_In_ REFIID riid, _COM_Outptr_ void** site) noexcept { return m_site.CopyTo(riid, site); }
protected:
ComPtr m_site;
private:
std::wstring context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_FILE_LOCKSMITH_CONTEXT_MENU_ENTRY, L"鿴ļռ"); // ANSI PLZ
};
CoCreatableClass(FileLocksmithContextMenuCommand)
CoCreatableClassWrlCreatorMapInclude(FileLocksmithContextMenuCommand)
STDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory)
{
return Module::GetModule().GetActivationFactory(activatableClassId, factory);
}
STDAPI DllCanUnloadNow()
{
return Module::GetModule().GetObjectCount() == 0 ? S_OK : S_FALSE;
}
STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _COM_Outptr_ void** instance)
{
return Module::GetModule().GetClassObject(rclsid, riid, instance);
}
================================================
FILE: PowerToys/src/modules/FileLocksmith/FileLocksmithExt/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
查看文件占用
This text will be shown when the user opens the context menu (right clicks) a file. File Locksmith is the product name, do not loc.
文件开锁匠
Localized name of the PowerToy.
================================================
FILE: PowerToys/src/modules/FileLocksmith/FileLocksmithUI/Strings/en-us/Resources.resw
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
文件开锁匠
Title of the window when running as user.
无占用
结束任务
占用文件
占用文件
关闭
As in, close a dialog prompt.
点击查看所有选中文件
Paths as in file paths that were selected for the utility to check.
此为系统程序,结束它可能导致系统故障。
选中文件列表
Paths as in file paths that were selected for the utility to check.
关闭
As in, close a dialog prompt.
未选择文件
进程 ID
刷新
以管理员身份重启
用户
管理员权限: 文件开锁匠
Title of the window when running as administrator.
查看
Show files for the selected process
================================================
FILE: PowerToys/src/modules/Hosts/HostsUILib/Strings/en-us/Resources.resw
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
启用
启用
添加
添加条目
添加条目
添加条目 (Ctrl+N)
添加一个条目
注释
注释
取消
保存
注释
添加条目
地址
"Address" refers to the IP address of the entry
地址
"Address" refers to the IP address of the entry
清除筛选
清除筛选
清除筛选
备注
"Comment" refers to the comment of the entry
备注
"Comment" refers to the comment of the entry
删除
否
是
确定删除此条目?
删除
删除 (Delete)
"Delete" between parentheses refers to the Delete keyboard key
复制
Refers to the action of duplicate an existing entry
地址重复
编辑
无筛选结果
未储存任何条目
"Hosts" refers to the system hosts file, do not loc
条目
取消
域名表文件被其他软件改动。
"Hosts" refers to the system hosts file, do not loc
无法保存域名表文件,因为文件被其他软件所占用。
"Hosts" refers to the system hosts file, do not loc
无法保存域名表文件。
"Hosts" refers to the system hosts file, do not loc
无法保存域名表文件,需要管理员权限。
"Hosts" refers to the system hosts file, do not loc
无法保存域名表文件,文件不允许写入。
"Hosts" refers to the system hosts file, do not loc
筛选
筛选
域名
"Hosts" refers to the system hosts file, do not loc // 并不是
空格分隔多个域名(比如:server server.local),一次最多九个
Do not localize "server" and "server.local"
域名
"Hosts" refers to the system hosts file, do not loc // 并不是
获取写入权限
下移
上移
打开文本编辑器
"Hosts" refers to the system hosts file, do not loc
打开文本编辑器
"Hosts" refers to the system hosts file, do not loc
Ping 测试
"Ping" refers to the command-line utility, do not loc
Ping 结果
"Ping" refers to the command-line utility, do not loc
重新加载
设置
设置
仅显示地址重复的条目
每条最多填写九个域名,太长的条目已被拆分,保存后生效。
"Hosts" refers to the system hosts file, do not loc
域名数量过多
"Hosts" refers to the system hosts file, do not loc
地址不符合 IPv4 或 IPv6 格式
域名列表不符合格式
更新
更新条目
继续
退出
这是 Hosts 域名表文件编辑器。
错误修改域名表可能会导致无法解析域名、访问网站,因此请谨慎使用。
"Hosts" refers to the system hosts file, do not loc
警告
管理员权限: 域名表编辑器
Title of the window when running as administrator. "Hosts File Editor" is the name of the utility. "Hosts" refers to the system hosts file, do not loc
域名表编辑器
Title of the window when running as user. "Hosts File Editor" is the name of the utility. "Hosts" refers to the system hosts file, do not loc
================================================
FILE: PowerToys/src/modules/MeasureTool/MeasureToolUI/Strings/en-us/Resources.resw
================================================
text/microsoft-resx
1.3
System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
框选 (Ctrl+1)
框选 (Ctrl+1)
间距 (Ctrl+2)
间距 (Ctrl+2)
水平间距 (Ctrl+3)
水平间距 (Ctrl+3)
垂直间距 (Ctrl+4)
垂直间距 (Ctrl+4)
关闭 (Esc)
像素
英寸
厘米
毫米
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs
================================================
// 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.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.PowerToys.Telemetry;
//
// Clipboard related routines.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
using MouseWithoutBorders.Exceptions;
using SystemClipboard = System.Windows.Forms.Clipboard;
using Thread = MouseWithoutBorders.Core.Thread;
namespace MouseWithoutBorders
{
internal partial class Common
{
internal static readonly char[] Comma = new char[] { ',' };
internal static readonly char[] Star = new char[] { '*' };
internal static readonly char[] NullSeparator = new char[] { '\0' };
internal const uint BIG_CLIPBOARD_DATA_TIMEOUT = 60000; // [CN] 30s -> 60s
private const uint MAX_CLIPBOARD_DATA_SIZE_CAN_BE_SENT_INSTANTLY_TCP = 1024 * 1024; // 1MB
private const uint MAX_CLIPBOARD_FILE_SIZE_CAN_BE_SENT = 500 * 1024 * 1024; // 100MB [CN]-> 500MB
private const int TEXT_HEADER_SIZE = 12;
private const int DATA_SIZE = 48;
private const string TEXT_TYPE_SEP = "{4CFF57F7-BEDD-43d5-AE8F-27A61E886F2F}";
private static long lastClipboardEventTime;
private static string lastMachineWithClipboardData;
private static string lastDragDropFile;
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
internal static long clipboardCopiedTime;
#pragma warning restore SA1307
internal static ID LastIDWithClipboardData { get; set; }
internal static string LastDragDropFile
{
get => Common.lastDragDropFile;
set => Common.lastDragDropFile = value;
}
internal static string LastMachineWithClipboardData
{
get => Common.lastMachineWithClipboardData;
set => Common.lastMachineWithClipboardData = value;
}
internal static long LastClipboardEventTime
{
get => Common.lastClipboardEventTime;
set => Common.lastClipboardEventTime = value;
}
internal static IntPtr NextClipboardViewer { get; set; }
internal static bool IsClipboardDataImage { get; private set; }
internal static byte[] LastClipboardData { get; private set; }
private static object lastClipboardObject = string.Empty;
internal static bool HasSwitchedMachineSinceLastCopy { get; set; }
internal static bool CheckClipboardEx(ByteArrayOrString data, bool isFilePath)
{
Logger.LogDebug($"{nameof(CheckClipboardEx)}: ShareClipboard = {Setting.Values.ShareClipboard}, TransferFile = {Setting.Values.TransferFile}, data = {data}.");
Logger.LogDebug($"{nameof(CheckClipboardEx)}: {nameof(Setting.Values.OneWayClipboardMode)} = {Setting.Values.OneWayClipboardMode}.");
if (!Setting.Values.ShareClipboard)
{
return false;
}
if (Common.RunWithNoAdminRight && Setting.Values.OneWayClipboardMode)
{
return false;
}
if (GetTick() - LastClipboardEventTime < 1000)
{
Logger.LogDebug("GetTick() - lastClipboardEventTime < 1000");
LastClipboardEventTime = GetTick();
return false;
}
LastClipboardEventTime = GetTick();
try
{
IsClipboardDataImage = false;
LastClipboardData = null;
LastDragDropFile = null;
GC.Collect();
string stringData = null;
byte[] byteData = null;
if (data.IsByteArray)
{
byteData = data.GetByteArray();
}
else
{
stringData = data.GetString();
}
if (stringData != null)
{
if (!HasSwitchedMachineSinceLastCopy)
{
if (lastClipboardObject is string lastStringData && lastStringData.Equals(stringData, StringComparison.OrdinalIgnoreCase))
{
Logger.LogDebug("CheckClipboardEx: Same string data.");
return false;
}
}
HasSwitchedMachineSinceLastCopy = false;
if (isFilePath)
{
Logger.LogDebug("Clipboard contains FileDropList");
if (!Setting.Values.TransferFile)
{
Logger.LogDebug("TransferFile option is unchecked.");
return false;
}
string filePath = stringData;
_ = Common.ImpersonateLoggedOnUserAndDoSomething(() =>
{
if (File.Exists(filePath) || Directory.Exists(filePath))
{
if (File.Exists(filePath) && new FileInfo(filePath).Length <= MAX_CLIPBOARD_FILE_SIZE_CAN_BE_SENT)
{
Logger.LogDebug("Clipboard contains: " + filePath);
LastDragDropFile = filePath;
SendClipboardBeat();
SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_BIG_CLIPBOARD, -1, ICON_BIG_CLIPBOARD, -1 });
}
else
{
if (Directory.Exists(filePath))
{
Logger.LogDebug("Clipboard contains a directory: " + filePath);
LastDragDropFile = filePath;
SendClipboardBeat();
}
else
{
LastDragDropFile = filePath + " - 文件过大无法粘贴,请改为拖放文件!";
SendClipboardBeat();
Logger.Log("Clipboard: File too big: " + filePath);
}
SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_ERROR, -1, ICON_ERROR, -1 });
}
}
else
{
Logger.Log("CheckClipboardEx: File not found: " + filePath);
}
});
}
else
{
byte[] texts = Common.GetBytesU(stringData);
using MemoryStream ms = new();
using (DeflateStream s = new(ms, CompressionMode.Compress, true))
{
s.Write(texts, 0, texts.Length);
}
Logger.LogDebug("Plain/Zip = " + texts.Length.ToString(CultureInfo.CurrentCulture) + "/" +
ms.Length.ToString(CultureInfo.CurrentCulture));
LastClipboardData = ms.GetBuffer();
}
}
else if (byteData != null)
{
if (!HasSwitchedMachineSinceLastCopy)
{
if (lastClipboardObject is byte[] lastByteData && Enumerable.SequenceEqual(lastByteData, byteData))
{
Logger.LogDebug("CheckClipboardEx: Same byte[] data.");
return false;
}
}
HasSwitchedMachineSinceLastCopy = false;
Logger.LogDebug("Clipboard contains image");
IsClipboardDataImage = true;
LastClipboardData = byteData;
}
else
{
Logger.LogDebug("*** Clipboard contains something else!");
return false;
}
lastClipboardObject = data;
if (LastClipboardData != null && LastClipboardData.Length > 0)
{
if (LastClipboardData.Length > MAX_CLIPBOARD_DATA_SIZE_CAN_BE_SENT_INSTANTLY_TCP)
{
SendClipboardBeat();
SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_BIG_CLIPBOARD, -1, ICON_BIG_CLIPBOARD, -1 });
}
else
{
SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_SMALL_CLIPBOARD, -1, -1, -1 });
SendClipboardDataUsingTCP(LastClipboardData, IsClipboardDataImage);
}
return true;
}
}
catch (Exception e)
{
Logger.Log(e);
}
return false;
}
private static void SendClipboardDataUsingTCP(byte[] bytes, bool image)
{
if (Sk == null)
{
return;
}
new Task(() =>
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
System.Threading.Thread thread = Thread.CurrentThread;
thread.Name = $"{nameof(SendClipboardDataUsingTCP)}.{thread.ManagedThreadId}";
Thread.UpdateThreads(thread);
int l = bytes.Length;
int index = 0;
int len;
DATA package = new();
byte[] buf = new byte[PACKAGE_SIZE_EX];
int dataStart = PACKAGE_SIZE_EX - DATA_SIZE;
while (true)
{
if ((index + DATA_SIZE) > l)
{
len = l - index;
Array.Clear(buf, 0, PACKAGE_SIZE_EX);
}
else
{
len = DATA_SIZE;
}
Array.Copy(bytes, index, buf, dataStart, len);
package.Bytes = buf;
package.Type = image ? PackageType.ClipboardImage : PackageType.ClipboardText;
package.Des = ID.ALL;
SkSend(package, (uint)MachineID, false);
index += DATA_SIZE;
if (index >= l)
{
break;
}
}
package.Type = PackageType.ClipboardDataEnd;
package.Des = ID.ALL;
SkSend(package, (uint)MachineID, false);
}).Start();
}
internal static void ReceiveClipboardDataUsingTCP(DATA data, bool image, TcpSk tcp)
{
try
{
if (Sk == null || RunOnLogonDesktop || RunOnScrSaverDesktop)
{
return;
}
MemoryStream m = new();
int dataStart = PACKAGE_SIZE_EX - DATA_SIZE;
m.Write(data.Bytes, dataStart, DATA_SIZE);
int unexpectedCount = 0;
bool done = false;
do
{
data = SocketStuff.TcpReceiveData(tcp, out int err);
switch (data.Type)
{
case PackageType.ClipboardImage:
case PackageType.ClipboardText:
m.Write(data.Bytes, dataStart, DATA_SIZE);
break;
case PackageType.ClipboardDataEnd:
done = true;
break;
default:
Receiver.ProcessPackage(data, tcp);
if (++unexpectedCount > 100)
{
Logger.Log("ReceiveClipboardDataUsingTCP: unexpectedCount > 100!");
done = true;
}
break;
}
}
while (!done);
LastClipboardEventTime = GetTick();
if (image)
{
Image im = Image.FromStream(m);
Clipboard.SetImage(im);
LastClipboardEventTime = GetTick();
}
else
{
Common.SetClipboardData(m.GetBuffer());
LastClipboardEventTime = GetTick();
}
m.Dispose();
SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_SMALL_CLIPBOARD, -1, ICON_SMALL_CLIPBOARD, -1 });
}
catch (Exception e)
{
Logger.Log("ReceiveClipboardDataUsingTCP: " + e.Message);
}
}
private static readonly Lock ClipboardThreadOldLock = new();
private static System.Threading.Thread clipboardThreadOld;
internal static void GetRemoteClipboard(string postAction)
{
if (!RunOnLogonDesktop && !RunOnScrSaverDesktop)
{
if (Common.LastMachineWithClipboardData == null ||
Common.LastMachineWithClipboardData.Length < 1)
{
return;
}
new Task(() =>
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
System.Threading.Thread thread = Thread.CurrentThread;
thread.Name = $"{nameof(ConnectAndGetData)}.{thread.ManagedThreadId}";
Thread.UpdateThreads(thread);
ConnectAndGetData(postAction);
}).Start();
}
}
private static Stream m;
private static void ConnectAndGetData(object postAction)
{
if (Sk == null)
{
Logger.Log("ConnectAndGetData: Sk == null!");
return;
}
string remoteMachine;
TcpClient clipboardTcpClient = null;
string postAct = (string)postAction;
Logger.LogDebug("ConnectAndGetData.postAction: " + postAct);
ClipboardPostAction clipboardPostAct = postAct.Contains("mspaint,") ? ClipboardPostAction.Mspaint
: postAct.Equals("desktop", StringComparison.OrdinalIgnoreCase) ? ClipboardPostAction.Desktop
: ClipboardPostAction.Other;
try
{
remoteMachine = postAct.Contains("mspaint,") ? postAct.Split(Comma)[1] : Common.LastMachineWithClipboardData;
remoteMachine = remoteMachine.Trim();
if (!IsConnectedByAClientSocketTo(remoteMachine))
{
Logger.Log($"No potential inbound connection from {MachineName} to {remoteMachine}, ask for a push back instead.");
ID machineId = MachinePool.ResolveID(remoteMachine);
if (machineId != ID.NONE)
{
SkSend(
new DATA()
{
Type = PackageType.ClipboardAsk,
Des = machineId,
MachineName = MachineName,
PostAction = clipboardPostAct,
},
null,
false);
}
else
{
Logger.Log($"Unable to resolve {remoteMachine} to its long IP.");
}
return;
}
ShowToolTip("正在连接 " + remoteMachine, 2000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);
clipboardTcpClient = ConnectToRemoteClipboardSocket(remoteMachine);
}
catch (ThreadAbortException)
{
Logger.Log("The current thread is being aborted (1).");
if (clipboardTcpClient != null && clipboardTcpClient.Connected)
{
clipboardTcpClient.Client.Close();
}
return;
}
catch (Exception e)
{
Logger.Log(e);
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]
{
Common.ICON_BIG_CLIPBOARD,
-1, Common.ICON_BIG_CLIPBOARD, -1,
});
ShowToolTip(e.Message, 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
return;
}
bool clientPushData = false;
if (!ShakeHand(ref remoteMachine, clipboardTcpClient.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref clipboardPostAct))
{
return;
}
ReceiveAndProcessClipboardData(remoteMachine, clipboardTcpClient.Client, enStream, deStream, postAct);
}
internal static void ReceiveAndProcessClipboardData(string remoteMachine, Socket s, Stream enStream, Stream deStream, string postAct)
{
lock (ClipboardThreadOldLock)
{
// Do not enable two connections at the same time.
if (clipboardThreadOld != null && clipboardThreadOld.ThreadState != System.Threading.ThreadState.AbortRequested
&& clipboardThreadOld.ThreadState != System.Threading.ThreadState.Aborted && clipboardThreadOld.IsAlive
&& clipboardThreadOld.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)
{
if (clipboardThreadOld.Join(3000))
{
if (m != null)
{
m.Flush();
m.Close();
m = null;
}
}
}
clipboardThreadOld = Thread.CurrentThread;
}
try
{
byte[] header = new byte[1024];
byte[] buf = new byte[NETWORK_STREAM_BUF_SIZE];
string fileName = null;
string tempFile = "data", savingFolder = string.Empty;
Common.ToggleIconsIndex = 0;
int rv;
long receivedCount = 0;
if ((rv = deStream.ReadEx(header, 0, header.Length)) < header.Length)
{
Logger.Log("Reading header failed: " + rv.ToString(CultureInfo.CurrentCulture));
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]
{
Common.ICON_BIG_CLIPBOARD,
-1, -1, -1,
});
return;
}
fileName = Common.GetStringU(header).Replace("\0", string.Empty);
Logger.LogDebug("Header: " + fileName);
string[] headers = fileName.Split(Star);
if (headers.Length < 2 || !long.TryParse(headers[0], out long dataSize))
{
Logger.Log(string.Format(
CultureInfo.CurrentCulture,
"Reading header failed: {0}:{1}",
headers.Length,
fileName));
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]
{
Common.ICON_BIG_CLIPBOARD,
-1, -1, -1,
});
return;
}
fileName = headers[1];
Logger.LogDebug(string.Format(
CultureInfo.CurrentCulture,
"Receiving {0}:{1} from {2}...",
Path.GetFileName(fileName),
dataSize,
remoteMachine));
ShowToolTip(
string.Format(
CultureInfo.CurrentCulture,
"正在从 {1} 接收 {0} ...",
Path.GetFileName(fileName),
remoteMachine),
5000,
ToolTipIcon.Info,
Setting.Values.ShowClipNetStatus);
if (fileName.StartsWith("image", StringComparison.CurrentCultureIgnoreCase) ||
fileName.StartsWith("text", StringComparison.CurrentCultureIgnoreCase))
{
m = new MemoryStream();
}
else
{
if (postAct.Equals("desktop", StringComparison.OrdinalIgnoreCase))
{
_ = ImpersonateLoggedOnUserAndDoSomething(() =>
{
savingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\MouseWithoutBorders\\";
if (!Directory.Exists(savingFolder))
{
_ = Directory.CreateDirectory(savingFolder);
}
});
tempFile = savingFolder + Path.GetFileName(fileName);
m = new FileStream(tempFile, FileMode.Create);
}
else if (postAct.Contains("mspaint"))
{
tempFile = GetMyStorageDir() + @"ScreenCapture-" +
remoteMachine + ".png";
m = new FileStream(tempFile, FileMode.Create);
}
else
{
tempFile = GetMyStorageDir();
tempFile += Path.GetFileName(fileName);
m = new FileStream(tempFile, FileMode.Create);
}
Logger.Log("==> " + tempFile);
}
ShowToolTip(
string.Format(
CultureInfo.CurrentCulture,
"正在从 {1} 接收 {0} ...",
Path.GetFileName(fileName),
remoteMachine),
5000,
ToolTipIcon.Info,
Setting.Values.ShowClipNetStatus);
do
{
rv = deStream.ReadEx(buf, 0, buf.Length);
if (rv > 0)
{
receivedCount += rv;
if (receivedCount > dataSize)
{
rv -= (int)(receivedCount - dataSize);
}
m.Write(buf, 0, rv);
}
if (Common.ToggleIcons == null)
{
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]
{
Common.ICON_SMALL_CLIPBOARD,
-1, Common.ICON_SMALL_CLIPBOARD, -1,
});
}
string text = string.Format(CultureInfo.CurrentCulture, "{0}KB received: {1}", m.Length / 1024, Path.GetFileName(fileName));
DoSomethingInUIThread(() =>
{
MainForm.SetTrayIconText(text);
});
}
while (rv > 0);
if (m != null && fileName != null)
{
m.Flush();
Logger.LogDebug(m.Length.ToString(CultureInfo.CurrentCulture) + " bytes received.");
Common.LastClipboardEventTime = Common.GetTick();
string toolTipText = null;
string sizeText = m.Length >= 1024
? (m.Length / 1024).ToString(CultureInfo.CurrentCulture) + "KB"
: m.Length.ToString(CultureInfo.CurrentCulture) + "Bytes";
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersClipboardFileTransferEvent());
if (fileName.StartsWith("image", StringComparison.CurrentCultureIgnoreCase))
{
Clipboard.SetImage(Image.FromStream(m));
toolTipText = string.Format(
CultureInfo.CurrentCulture,
"{0} {1} 来自 {2} 已存入剪贴板.",
sizeText,
"image",
remoteMachine);
}
else if (fileName.StartsWith("text", StringComparison.CurrentCultureIgnoreCase))
{
byte[] data = (m as MemoryStream).GetBuffer();
toolTipText = string.Format(
CultureInfo.CurrentCulture,
"{0} {1} 来自 {2} 已存入剪贴板.",
sizeText,
"text",
remoteMachine);
Common.SetClipboardData(data);
}
else if (tempFile != null)
{
if (postAct.Equals("desktop", StringComparison.OrdinalIgnoreCase))
{
toolTipText = string.Format(
CultureInfo.CurrentCulture,
"{0} {1} 来自 {2}!",
sizeText,
Path.GetFileName(fileName),
remoteMachine);
_ = ImpersonateLoggedOnUserAndDoSomething(() =>
{
ProcessStartInfo startInfo = new();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = savingFolder;
startInfo.FileName = savingFolder;
startInfo.Verb = "open";
_ = Process.Start(startInfo);
});
}
else if (postAct.Contains("mspaint"))
{
m.Close();
m = null;
OpenImage(tempFile);
toolTipText = string.Format(
CultureInfo.CurrentCulture,
"{0} {1} 来自 {2} 已放入画图.",
sizeText,
Path.GetFileName(tempFile),
remoteMachine);
}
else
{
StringCollection filePaths = new()
{
tempFile,
};
Clipboard.SetFileDropList(filePaths);
toolTipText = string.Format(
CultureInfo.CurrentCulture,
"{0} {1} 来自 {2} 已存入剪贴板.",
sizeText,
Path.GetFileName(fileName),
remoteMachine);
}
}
if (!string.IsNullOrWhiteSpace(toolTipText))
{
Common.ShowToolTip(toolTipText, 5000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);
}
DoSomethingInUIThread(() =>
{
MainForm.UpdateNotifyIcon();
});
m?.Close();
m = null;
}
}
catch (ThreadAbortException)
{
Logger.Log("The current thread is being aborted (3).");
s.Close();
if (m != null)
{
m.Close();
m = null;
}
return;
}
catch (Exception e)
{
if (e is IOException)
{
string log = $"{nameof(ReceiveAndProcessClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
}
else
{
Logger.Log(e);
}
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]
{
Common.ICON_BIG_CLIPBOARD,
-1, Common.ICON_BIG_CLIPBOARD, -1,
});
ShowToolTip(e.Message, 1000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);
if (m != null)
{
m.Close();
m = null;
}
return;
}
s.Close();
}
internal static bool ShakeHand(ref string remoteName, Socket s, out Stream enStream, out Stream deStream, ref bool clientPushData, ref ClipboardPostAction postAction)
{
const int CLIPBOARD_HANDSHAKE_TIMEOUT = 30;
s.ReceiveTimeout = CLIPBOARD_HANDSHAKE_TIMEOUT * 1000;
s.NoDelay = true;
s.SendBufferSize = s.ReceiveBufferSize = 1024000;
bool handShaken = false;
enStream = deStream = null;
try
{
DATA package = new()
{
Type = clientPushData ? PackageType.ClipboardPush : PackageType.Clipboard,
PostAction = postAction,
Src = MachineID,
MachineName = MachineName,
};
byte[] buf = new byte[PACKAGE_SIZE_EX];
NetworkStream ns = new(s);
enStream = Common.GetEncryptedStream(ns);
Common.SendOrReceiveARandomDataBlockPerInitialIV(enStream);
Logger.LogDebug($"{nameof(ShakeHand)}: Writing header package.");
enStream.Write(package.Bytes, 0, PACKAGE_SIZE_EX);
Logger.LogDebug($"{nameof(ShakeHand)}: Sent: clientPush={clientPushData}, postAction={postAction}.");
deStream = Common.GetDecryptedStream(ns);
Common.SendOrReceiveARandomDataBlockPerInitialIV(deStream, false);
Logger.LogDebug($"{nameof(ShakeHand)}: Reading header package.");
int bytesReceived = deStream.ReadEx(buf, 0, Common.PACKAGE_SIZE_EX);
package.Bytes = buf;
string name = "Unknown";
if (bytesReceived == Common.PACKAGE_SIZE_EX)
{
if (package.Type is PackageType.Clipboard or PackageType.ClipboardPush)
{
name = remoteName = package.MachineName;
Logger.LogDebug($"{nameof(ShakeHand)}: Connection from {name}:{package.Src}");
if (Common.MachinePool.ResolveID(name) == package.Src && Common.IsConnectedTo(package.Src))
{
clientPushData = package.Type == PackageType.ClipboardPush;
postAction = package.PostAction;
handShaken = true;
Logger.LogDebug($"{nameof(ShakeHand)}: Received: clientPush={clientPushData}, postAction={postAction}.");
}
else
{
Logger.LogDebug($"{nameof(ShakeHand)}: No active connection to the machine: {name}.");
}
}
else
{
Logger.LogDebug($"{nameof(ShakeHand)}: Unexpected package type: {package.Type}.");
}
}
else
{
Logger.LogDebug($"{nameof(ShakeHand)}: BytesTransferred != PACKAGE_SIZE_EX: {bytesReceived}");
}
if (!handShaken)
{
string msg = $"剪贴板连接被拒绝: {name}:{remoteName}/{package.Src}\r\n\r\n请确保软件版本相同.";
Logger.Log(msg);
Common.ShowToolTip(msg, 3000, ToolTipIcon.Warning);
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE] { Common.ICON_BIG_CLIPBOARD, -1, -1, -1 });
}
}
catch (ThreadAbortException)
{
Logger.Log($"{nameof(ShakeHand)}: The current thread is being aborted.");
s.Close();
}
catch (Exception e)
{
if (e is IOException)
{
string log = $"{nameof(ShakeHand)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
}
else
{
Logger.Log(e);
}
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]
{
Common.ICON_BIG_CLIPBOARD,
-1, Common.ICON_BIG_CLIPBOARD, -1,
});
MainForm.UpdateNotifyIcon();
ShowToolTip(e.Message + "\r\n\r\n请确保软件版本相同.", 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
if (m != null)
{
m.Close();
m = null;
}
}
return handShaken;
}
internal static TcpClient ConnectToRemoteClipboardSocket(string remoteMachine)
{
TcpClient clipboardTcpClient;
clipboardTcpClient = new TcpClient(AddressFamily.InterNetworkV6);
clipboardTcpClient.Client.DualMode = true;
SocketStuff sk = Common.Sk;
if (sk != null)
{
Common.DoSomethingInUIThread(() => Common.MainForm.ChangeIcon(Common.ICON_SMALL_CLIPBOARD));
System.Net.IPAddress ip = GetConnectedClientSocketIPAddressFor(remoteMachine);
Logger.LogDebug($"{nameof(ConnectToRemoteClipboardSocket)}Connecting to {remoteMachine}:{ip}:{sk.TcpPort}...");
if (ip != null)
{
clipboardTcpClient.Connect(ip, sk.TcpPort);
}
else
{
clipboardTcpClient.Connect(remoteMachine, sk.TcpPort);
}
Logger.LogDebug($"Connected from {clipboardTcpClient.Client.LocalEndPoint}. Getting data...");
return clipboardTcpClient;
}
else
{
throw new ExpectedSocketException($"{nameof(ConnectToRemoteClipboardSocket)}: No longer connected.");
}
}
internal static void SetClipboardData(byte[] data)
{
if (data == null || data.Length <= 0)
{
Logger.Log("data is null or empty!");
return;
}
if (data.Length > 1024000)
{
ShowToolTip(
string.Format(
CultureInfo.CurrentCulture,
"正在解压 {0} 剪贴板数据 ...",
(data.Length / 1024).ToString(CultureInfo.CurrentCulture) + "KB"),
5000,
ToolTipIcon.Info,
Setting.Values.ShowClipNetStatus);
}
string st = string.Empty;
using (MemoryStream ms = new(data))
{
using DeflateStream s = new(ms, CompressionMode.Decompress, true);
const int BufferSize = 1024000; // Buffer size should be big enough, this is critical to performance!
int rv = 0;
do
{
byte[] buffer = new byte[BufferSize];
rv = s.ReadEx(buffer, 0, BufferSize);
if (rv > 0)
{
st += Common.GetStringU(buffer);
}
else
{
break;
}
}
while (true);
}
int textTypeCount = 0;
string[] texts = st.Split(new string[] { TEXT_TYPE_SEP }, StringSplitOptions.RemoveEmptyEntries);
string tmp;
DataObject data1 = new();
foreach (string txt in texts)
{
if (string.IsNullOrEmpty(txt.Trim(NullSeparator)))
{
continue;
}
tmp = txt[3..];
if (txt.StartsWith("RTF", StringComparison.CurrentCultureIgnoreCase))
{
Logger.LogDebug(((double)tmp.Length / 1024).ToString("0.00", CultureInfo.InvariantCulture) + "KB of RTF <-");
data1.SetData(DataFormats.Rtf, tmp);
}
else if (txt.StartsWith("HTM", StringComparison.CurrentCultureIgnoreCase))
{
Logger.LogDebug(((double)tmp.Length / 1024).ToString("0.00", CultureInfo.InvariantCulture) + "KB of HTM <-");
data1.SetData(DataFormats.Html, tmp);
}
else if (txt.StartsWith("TXT", StringComparison.CurrentCultureIgnoreCase))
{
Logger.LogDebug(((double)tmp.Length / 1024).ToString("0.00", CultureInfo.InvariantCulture) + "KB of TXT <-");
data1.SetData(DataFormats.UnicodeText, tmp);
}
else
{
if (textTypeCount == 0)
{
Logger.LogDebug(((double)txt.Length / 1024).ToString("0.00", CultureInfo.InvariantCulture) + "KB of UNI <-");
data1.SetData(DataFormats.UnicodeText, txt);
}
Logger.Log("Invalid clipboard format received!");
}
textTypeCount++;
}
if (textTypeCount > 0)
{
Clipboard.SetDataObject(data1);
}
}
}
internal static class Clipboard
{
public static void SetFileDropList(StringCollection filePaths)
{
Common.DoSomethingInUIThread(() =>
{
try
{
_ = Common.Retry(
nameof(SystemClipboard.SetFileDropList),
() =>
{
SystemClipboard.SetFileDropList(filePaths);
return true;
},
(log) => Logger.TelemetryLogTrace(
log,
SeverityLevel.Information),
() => Common.LastClipboardEventTime = Common.GetTick());
}
catch (ExternalException e)
{
Logger.Log(e);
}
catch (ThreadStateException e)
{
Logger.Log(e);
}
catch (ArgumentNullException e)
{
Logger.Log(e);
}
catch (ArgumentException e)
{
Logger.Log(e);
}
});
}
public static void SetImage(Image image)
{
Common.DoSomethingInUIThread(() =>
{
try
{
_ = Common.Retry(
nameof(SystemClipboard.SetImage),
() =>
{
SystemClipboard.SetImage(image);
return true;
},
(log) => Logger.TelemetryLogTrace(log, SeverityLevel.Information),
() => Common.LastClipboardEventTime = Common.GetTick());
}
catch (ExternalException e)
{
Logger.Log(e);
}
catch (ThreadStateException e)
{
Logger.Log(e);
}
catch (ArgumentNullException e)
{
Logger.Log(e);
}
});
}
public static void SetText(string text)
{
Common.DoSomethingInUIThread(() =>
{
try
{
_ = Common.Retry(
nameof(SystemClipboard.SetText),
() =>
{
SystemClipboard.SetText(text);
return true;
},
(log) => Logger.TelemetryLogTrace(log, SeverityLevel.Information),
() => Common.LastClipboardEventTime = Common.GetTick());
}
catch (ExternalException e)
{
Logger.Log(e);
}
catch (ThreadStateException e)
{
Logger.Log(e);
}
catch (ArgumentNullException e)
{
Logger.Log(e);
}
});
}
public static void SetDataObject(DataObject dataObject)
{
Common.DoSomethingInUIThread(() =>
{
try
{
SystemClipboard.SetDataObject(dataObject, true, 10, 200);
}
catch (ExternalException e)
{
string dataFormats = string.Join(",", dataObject.GetFormats());
Logger.Log($"{e.Message}: {dataFormats}");
}
catch (ThreadStateException e)
{
Logger.Log(e);
}
catch (ArgumentNullException e)
{
Logger.Log(e);
}
});
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Encryption.cs
================================================
// 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.
//
// Encrypt/decrypt implementation.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using System;
using System.Collections.Concurrent;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using MouseWithoutBorders.Core;
namespace MouseWithoutBorders
{
internal partial class Common
{
#pragma warning disable SYSLIB0021
private static AesCryptoServiceProvider symAl;
#pragma warning restore SYSLIB0021
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
internal static string myKey;
#pragma warning restore SA1307
private static uint magicNumber;
private static Random ran = new(); // Used for non encryption related functionality.
internal const int SymAlBlockSize = 16;
///
/// This is used for the first encryption block, the following blocks will be combined with the cipher text of the previous block.
/// Thus identical blocks in the socket stream would be encrypted to different cipher text blocks.
/// The first block is a handshake one containing random data.
/// Related Unit Test: TestEncryptDecrypt
///
internal static readonly string InitialIV = ulong.MaxValue.ToString(CultureInfo.InvariantCulture);
internal static Random Ran
{
get => Common.ran ??= new Random();
set => Common.ran = value;
}
internal static uint MagicNumber
{
get => Common.magicNumber;
set => Common.magicNumber = value;
}
internal static string MyKey
{
get => Common.myKey;
set
{
if (Common.myKey != value)
{
Common.myKey = value;
_ = Task.Factory.StartNew(
() => Common.GenLegalKey(),
System.Threading.CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.Default); // Cache the key to improve UX.
}
}
}
internal static string KeyDisplayedText(string key)
{
string displayedValue = string.Empty;
int i = 0;
do
{
int length = Math.Min(4, key.Length - i);
displayedValue += string.Concat(key.AsSpan(i, length), " ");
i += 4;
}
while (i < key.Length - 1);
return displayedValue.Trim();
}
internal static bool GeneratedKey { get; set; }
internal static bool KeyCorrupted { get; set; }
internal static void InitEncryption()
{
try
{
if (symAl == null)
{
#pragma warning disable SYSLIB0021 // No proper replacement for now
symAl = new AesCryptoServiceProvider();
#pragma warning restore SYSLIB0021
symAl.KeySize = 256;
symAl.BlockSize = SymAlBlockSize * 8;
symAl.Padding = PaddingMode.Zeros;
symAl.Mode = CipherMode.CBC;
symAl.GenerateIV();
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
private static readonly ConcurrentDictionary LegalKeyDictionary = new(StringComparer.OrdinalIgnoreCase);
internal static byte[] GenLegalKey()
{
byte[] rv;
string myKey = Common.MyKey;
if (!LegalKeyDictionary.TryGetValue(myKey, out byte[] value))
{
Rfc2898DeriveBytes key = new(
myKey,
Common.GetBytesU(InitialIV),
50000,
HashAlgorithmName.SHA512);
rv = key.GetBytes(32);
_ = LegalKeyDictionary.AddOrUpdate(myKey, rv, (k, v) => rv);
}
else
{
rv = value;
}
return rv;
}
private static byte[] GenLegalIV()
{
string st = InitialIV;
int ivLength = symAl.IV.Length;
if (st.Length > ivLength)
{
st = st[..ivLength];
}
else if (st.Length < ivLength)
{
st = st.PadRight(ivLength, ' ');
}
return GetBytes(st);
}
internal static Stream GetEncryptedStream(Stream encryptedStream)
{
ICryptoTransform encryptor;
encryptor = symAl.CreateEncryptor(GenLegalKey(), GenLegalIV());
return new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write);
}
internal static Stream GetDecryptedStream(Stream encryptedStream)
{
ICryptoTransform decryptor;
decryptor = symAl.CreateDecryptor(GenLegalKey(), GenLegalIV());
return new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);
}
internal static uint Get24BitHash(string st)
{
if (string.IsNullOrEmpty(st))
{
return 0;
}
byte[] bytes = new byte[PACKAGE_SIZE];
for (int i = 0; i < PACKAGE_SIZE; i++)
{
if (i < st.Length)
{
bytes[i] = (byte)st[i];
}
}
var hash = SHA512.Create();
byte[] hashValue = hash.ComputeHash(bytes);
for (int i = 0; i < 50000; i++)
{
hashValue = hash.ComputeHash(hashValue);
}
Logger.LogDebug(string.Format(CultureInfo.CurrentCulture, "magic: {0},{1},{2}", hashValue[0], hashValue[1], hashValue[^1]));
hash.Clear();
return (uint)((hashValue[0] << 23) + (hashValue[1] << 16) + (hashValue[^1] << 8) + hashValue[2]);
}
internal static string GetDebugInfo(string st)
{
return string.IsNullOrEmpty(st) ? st : ((byte)(Common.GetBytesU(st).Sum(value => value) % 256)).ToString(CultureInfo.InvariantCulture);
}
internal static string CreateDefaultKey()
{
return CreateRandomKey();
}
private const int PW_LENGTH = 16;
public static string CreateRandomKey()
{
// Not including characters like "'`O0& since they are confusing to users.
string[] chars = new[] { "abcdefghjkmnpqrstuvxyz", "ABCDEFGHJKMNPQRSTUVXYZ", "123456789", "~!@#$%^*()_-+=:;<,>.?/\\|[]" };
char[][] charactersUsedForKey = chars.Select(charset => Enumerable.Range(0, charset.Length - 1).Select(i => charset[i]).ToArray()).ToArray();
byte[] randomData = new byte[1];
string key = string.Empty;
do
{
foreach (string set in chars)
{
randomData = RandomNumberGenerator.GetBytes(1);
key += set[randomData[0] % set.Length];
if (key.Length >= PW_LENGTH)
{
break;
}
}
}
while (key.Length < PW_LENGTH);
return key;
}
internal static bool IsKeyValid(string key, out string error)
{
error = string.IsNullOrEmpty(key) || key.Length < 16
? "密码必须至少包含 16 个字符,空格不计,必须由程序自动生成。"
: null;
return error == null;
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Event.cs
================================================
// 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.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
//
// Keyboard/Mouse hook callback implementation.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
using MouseWithoutBorders.Form;
using Thread = MouseWithoutBorders.Core.Thread;
namespace MouseWithoutBorders
{
internal partial class Common
{
private static readonly DATA KeybdPackage = new();
private static readonly DATA MousePackage = new();
#pragma warning disable SA1307 // Accessible fields should begin with upper-case names
internal static ulong inputEventCount;
internal static ulong invalidPackageCount;
#pragma warning restore SA1307
internal static int MOVE_MOUSE_RELATIVE = 100000;
internal static int XY_BY_PIXEL = 300000;
static Common()
{
}
internal static ulong InvalidPackageCount
{
get => Common.invalidPackageCount;
set => Common.invalidPackageCount = value;
}
internal static ulong InputEventCount
{
get => Common.inputEventCount;
set => Common.inputEventCount = value;
}
internal static ulong RealInputEventCount
{
get;
set;
}
private static Point actualLastPos;
private static int myLastX;
private static int myLastY;
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Dotnet port with style preservation")]
internal static void MouseEvent(MOUSEDATA e, int dx, int dy)
{
try
{
PaintCount = 0;
bool switchByMouseEnabled = IsSwitchingByMouseEnabled();
if (switchByMouseEnabled && Sk != null && (DesMachineID == MachineID || !Setting.Values.MoveMouseRelatively) && e.dwFlags == WM_MOUSEMOVE)
{
Point p = MoveToMyNeighbourIfNeeded(e.X, e.Y, desMachineID);
if (!p.IsEmpty)
{
HasSwitchedMachineSinceLastCopy = true;
Logger.LogDebug(string.Format(
CultureInfo.CurrentCulture,
"***** Host Machine: newDesMachineIdEx set = [{0}]. Mouse is now at ({1},{2})",
newDesMachineIdEx,
e.X,
e.Y));
myLastX = e.X;
myLastY = e.Y;
PrepareToSwitchToMachine(newDesMachineIdEx, p);
}
}
if (desMachineID != MachineID && SwitchLocation.Count <= 0)
{
MousePackage.Des = desMachineID;
MousePackage.Type = PackageType.Mouse;
MousePackage.Md.dwFlags = e.dwFlags;
MousePackage.Md.WheelDelta = e.WheelDelta;
// Relative move
if (Setting.Values.MoveMouseRelatively && Math.Abs(dx) >= MOVE_MOUSE_RELATIVE && Math.Abs(dy) >= MOVE_MOUSE_RELATIVE)
{
MousePackage.Md.X = dx;
MousePackage.Md.Y = dy;
}
else
{
MousePackage.Md.X = (e.X - primaryScreenBounds.Left) * 65535 / screenWidth;
MousePackage.Md.Y = (e.Y - primaryScreenBounds.Top) * 65535 / screenHeight;
}
SkSend(MousePackage, null, false);
if (MousePackage.Md.dwFlags is WM_LBUTTONUP or WM_RBUTTONUP)
{
Thread.Sleep(10);
}
NativeMethods.GetCursorPos(ref actualLastPos);
if (actualLastPos != Common.LastPos)
{
Logger.LogDebug($"Mouse cursor has moved unexpectedly: Expected: {Common.LastPos}, actual: {actualLastPos}.");
Common.LastPos = actualLastPos;
}
}
#if SHOW_ON_WINLOGON_EX
if (RunOnLogonDesktop && e.dwFlags == WM_RBUTTONUP &&
desMachineID == machineID &&
e.x > 2 && e.x < 100 && e.y > 2 && e.y < 20)
{
DoSomethingInUIThread(delegate()
{
MainForm.HideMenuWhenRunOnLogonDesktop();
MainForm.MainMenu.Hide();
MainForm.MainMenu.Show(e.x - 5, e.y - 3);
});
}
#endif
}
catch (Exception ex)
{
Logger.Log(ex);
}
}
internal static bool IsSwitchingByMouseEnabled()
{
return (EasyMouseOption)Setting.Values.EasyMouse == EasyMouseOption.开启 || InputHook.EasyMouseKeyDown;
}
internal static void PrepareToSwitchToMachine(ID newDesMachineID, Point desMachineXY)
{
Logger.LogDebug($"PrepareToSwitchToMachine: newDesMachineID = {newDesMachineID}, desMachineXY = {desMachineXY}");
if (((GetTick() - lastJump < 100) && (GetTick() - lastJump > 0)) || desMachineID == ID.ALL)
{
Logger.LogDebug("PrepareToSwitchToMachine: lastJump");
return;
}
lastJump = GetTick();
string newDesMachineName = NameFromID(newDesMachineID);
if (!IsConnectedTo(newDesMachineID))
{// Connection lost, cancel switching
Logger.LogDebug("No active connection found for " + newDesMachineName);
// ShowToolTip("No active connection found for [" + newDesMachineName + "]!", 500);
}
else
{
Common.newDesMachineID = newDesMachineID;
SwitchLocation.X = desMachineXY.X;
SwitchLocation.Y = desMachineXY.Y;
SwitchLocation.ResetCount();
_ = EvSwitch.Set();
// PostMessage(mainForm.Handle, WM_SWITCH, IntPtr.Zero, IntPtr.Zero);
if (newDesMachineID != DragMachine)
{
if (!IsDragging && !IsDropping)
{
if (MouseDown && !RunOnLogonDesktop && !RunOnScrSaverDesktop)
{
DragDropStep02();
}
}
else if (DragMachine != (ID)1)
{
ChangeDropMachine();
}
}
else
{
DragDropStep11();
}
// Change des machine
if (desMachineID != newDesMachineID)
{
Logger.LogDebug("MouseEvent: Switching to new machine:" + newDesMachineName);
// Ask current machine to hide the Mouse cursor
if (newDesMachineID != ID.ALL && desMachineID != MachineID)
{
SendPackage(desMachineID, PackageType.HideMouse);
}
DesMachineID = newDesMachineID;
if (desMachineID == MachineID)
{
if (GetTick() - clipboardCopiedTime < BIG_CLIPBOARD_DATA_TIMEOUT)
{
clipboardCopiedTime = 0;
Common.GetRemoteClipboard("PrepareToSwitchToMachine");
}
}
else
{
// Ask the new active machine to get clipboard data (if the data is too big)
SendPackage(desMachineID, PackageType.MachineSwitched);
}
_ = Interlocked.Increment(ref switchCount);
}
}
}
internal static void SaveSwitchCount()
{
if (SwitchCount > 0)
{
_ = Task.Run(() =>
{
Setting.Values.SwitchCount += SwitchCount;
_ = Interlocked.Exchange(ref switchCount, 0);
});
}
}
internal static void KeybdEvent(KEYBDDATA e)
{
try
{
PaintCount = 0;
if (desMachineID != newDesMachineID)
{
Logger.LogDebug("KeybdEvent: Switching to new machine...");
DesMachineID = newDesMachineID;
}
if (desMachineID != MachineID)
{
KeybdPackage.Des = desMachineID;
KeybdPackage.Type = PackageType.Keyboard;
KeybdPackage.Kd = e;
KeybdPackage.DateTime = GetTick();
SkSend(KeybdPackage, null, false);
if (KeybdPackage.Kd.dwFlags is WM_KEYUP or WM_SYSKEYUP)
{
Thread.Sleep(10);
}
}
}
catch (Exception ex)
{
Logger.Log(ex);
}
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Helper.cs
================================================
// 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.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Principal;
using System.Windows.Forms;
//
// Some other helper methods.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using Microsoft.Win32;
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
using static System.Windows.Forms.Control;
namespace MouseWithoutBorders
{
internal partial class Common
{
internal const string HELPER_FORM_TEXT = "Mouse without Borders Helper";
internal const string HelperProcessName = "PowerToys.MouseWithoutBordersHelper";
private static bool signalHelperToExit;
private static bool signalWatchDogToExit;
internal static long WndProcCounter;
private static void WatchDogThread()
{
long oldCounter = WndProcCounter;
do
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
if (signalWatchDogToExit)
{
break;
}
}
while (BlockingUI)
{
Thread.Sleep(1000);
}
if (WndProcCounter == oldCounter)
{
Process p = Process.GetCurrentProcess();
string procInfo = $"{p.PrivateMemorySize64 / 1024 / 1024}MB, {p.TotalProcessorTime}, {Environment.ProcessorCount}.";
string threadStacks = $"{procInfo} {Thread.DumpThreadsStack()}";
Logger.TelemetryLogTrace(threadStacks, SeverityLevel.Error);
break;
}
oldCounter = WndProcCounter;
}
while (true);
}
private static void HelperThread()
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = System.Threading.ExecutionContext.SuppressFlow();
try
{
while (true)
{
_ = EvSwitch.WaitOne(); // Switching to another machine?
if (signalHelperToExit)
{
break;
}
if (Common.NewDesMachineID != Common.MachineID && Common.NewDesMachineID != ID.ALL)
{
HideMouseCursor(false);
Common.MainFormDotEx(true);
}
else
{
if (Common.SwitchLocation.Count > 0)
{
Common.SwitchLocation.Count--;
// When we want to move mouse by pixels, we add 300k to x and y (search for XY_BY_PIXEL for other related code).
Logger.LogDebug($"+++++ Moving mouse to {Common.SwitchLocation.X}, {Common.SwitchLocation.Y}");
// MaxXY = 65535 so 100k is safe.
if (Common.SwitchLocation.X > XY_BY_PIXEL - 100000 || Common.SwitchLocation.Y > XY_BY_PIXEL - 100000)
{
InputSimulation.MoveMouse(Common.SwitchLocation.X - XY_BY_PIXEL, Common.SwitchLocation.Y - XY_BY_PIXEL);
}
else
{
InputSimulation.MoveMouseEx(Common.SwitchLocation.X, Common.SwitchLocation.Y);
}
Common.MainFormDot();
}
}
if (Common.NewDesMachineID == Common.MachineID)
{
ReleaseAllKeys();
}
}
}
catch (Exception e)
{
Logger.Log(e);
}
signalHelperToExit = false;
Logger.LogDebug("^^^Helper Thread exiting...^^^");
}
internal static void MainFormDotEx(bool bCheckTS)
{
Logger.LogDebug("***** MainFormDotEx:");
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
int left = Common.PrimaryScreenBounds.Left + ((Common.PrimaryScreenBounds.Right - Common.PrimaryScreenBounds.Left) / 2) - 1;
int top = Setting.Values.HideMouse ? 3 : Common.PrimaryScreenBounds.Top + ((Common.PrimaryScreenBounds.Bottom - Common.PrimaryScreenBounds.Top) / 2);
Common.MainFormVisible = true;
if (Setting.Values.HideMouse && Setting.Values.StealFocusWhenSwitchingMachine && Common.SendMessageToHelper(0x407, new IntPtr(left), new IntPtr(top), true) == 0)
{
try
{
/* When user just switches to the Logon desktop, user is actually on the "Windows Default Lock Screen" (LockApp).
* If a click is sent to this during switch, it actually triggers a desktop switch on the local machine causing a reconnection affecting the machine switch.
* We can detect and skip in this case.
* */
IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();
string foreGroundWindowText = GetText(foreGroundWindow);
bool mouseClick = true;
if (foreGroundWindowText.Equals("Windows Default Lock Screen", StringComparison.OrdinalIgnoreCase))
{
mouseClick = false;
}
// Window title may be localized, check process name:
if (mouseClick)
{
_ = NativeMethods.GetWindowThreadProcessId(foreGroundWindow, out uint pid);
if (pid > 0)
{
string foreGroundWindowProcess = Process.GetProcessById((int)pid)?.ProcessName;
if (foreGroundWindowProcess.Equals("LockApp", StringComparison.OrdinalIgnoreCase))
{
mouseClick = false;
}
}
}
if (mouseClick)
{
InputSimulation.MouseClickDotForm(left + 1, top + 1);
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
}
CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);
}
internal static void MainForm3Pixels()
{
Logger.LogDebug("***** MainFormDotLarge:");
DoSomethingInUIThread(
() =>
{
MainForm.Left = Common.PrimaryScreenBounds.Left + ((Common.PrimaryScreenBounds.Right - Common.PrimaryScreenBounds.Left) / 2) - 2;
MainForm.Top = Setting.Values.HideMouse ? 3 : Common.PrimaryScreenBounds.Top + ((Common.PrimaryScreenBounds.Bottom - Common.PrimaryScreenBounds.Top) / 2) - 1;
MainForm.Width = 3;
MainForm.Height = 3;
MainForm.Opacity = 0.11D;
MainForm.TopMost = true;
if (Setting.Values.HideMouse)
{
MainForm.BackColor = Color.Black;
MainForm.Show();
Common.MainFormVisible = true;
}
else
{
MainForm.BackColor = Color.White;
MainForm.Hide();
Common.MainFormVisible = false;
}
},
true);
CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);
}
internal static void MainFormDot()
{
DoSomethingInUIThread(
() =>
{
_ = Common.SendMessageToHelper(0x408, IntPtr.Zero, IntPtr.Zero, false);
MainForm.Left = Common.PrimaryScreenBounds.Left + ((Common.PrimaryScreenBounds.Right - Common.PrimaryScreenBounds.Left) / 2) - 1;
MainForm.Top = Setting.Values.HideMouse ? 3 : Common.PrimaryScreenBounds.Top + ((Common.PrimaryScreenBounds.Bottom - Common.PrimaryScreenBounds.Top) / 2);
MainForm.Width = 1;
MainForm.Height = 1;
MainForm.Opacity = 0.15;
MainForm.Hide();
Common.MainFormVisible = false;
},
true);
CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);
}
internal static void ToggleIcon()
{
try
{
if (toggleIconsIndex < TOGGLE_ICONS_SIZE)
{
Common.DoSomethingInUIThread(() => Common.MainForm.ChangeIcon(toggleIcons[toggleIconsIndex++]));
}
else
{
toggleIconsIndex = 0;
toggleIcons = null;
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
internal static void RunDDHelper(bool cleanUp = false)
{
if (Common.RunOnLogonDesktop || Common.RunOnScrSaverDesktop)
{
return;
}
if (cleanUp)
{
try
{
Process[] ps = Process.GetProcessesByName(HelperProcessName);
foreach (Process p in ps)
{
p.KillProcess();
}
}
catch (Exception e)
{
Logger.Log(e);
_ = Common.SendMessageToHelper(SharedConst.QUIT_CMD, IntPtr.Zero, IntPtr.Zero);
}
return;
}
if (!Common.IsMyDesktopActive())
{
return;
}
if (!Common.IpcChannelCreated)
{
Logger.TelemetryLogTrace($"{nameof(Common.IpcChannelCreated)} = {Common.IpcChannelCreated}. {Logger.GetStackTrace(new StackTrace())}", SeverityLevel.Warning);
return;
}
if (!MainForm.IsDisposed)
{
MainForm.NotifyIcon.Visible = false;
MainForm.NotifyIcon.Visible = Setting.Values.ShowOriginalUI;
}
IntPtr h = (IntPtr)NativeMethods.FindWindow(null, Common.HELPER_FORM_TEXT);
if (h.ToInt32() <= 0)
{
_ = Common.CreateProcessInInputDesktopSession(
$"\"{Path.GetDirectoryName(Application.ExecutablePath)}\\{HelperProcessName}.exe\"",
string.Empty,
Common.GetInputDesktop(),
0);
HasSwitchedMachineSinceLastCopy = true;
// Common.CreateLowIntegrityProcess("\"" + Path.GetDirectoryName(Application.ExecutablePath) + "\\MouseWithoutBordersHelper.exe\"", string.Empty, 0, false, 0);
var processes = Process.GetProcessesByName(HelperProcessName);
if (processes?.Length == 0)
{
Logger.Log("Unable to start helper process.");
Common.ShowToolTip("无法启动无界鼠标帮助模块,剪贴板共享功能失效!", 5000, ToolTipIcon.Error);
}
else
{
Logger.Log("Helper process started.");
}
}
else
{
var processes = Process.GetProcessesByName(HelperProcessName);
if (processes?.Length > 0)
{
Logger.Log("Helper process found running.");
}
else
{
Logger.Log("Invalid helper process found running.");
Common.ShowToolTip("找不到无界鼠标帮助模块,剪贴板共享功能失效!", 5000, ToolTipIcon.Error);
}
}
}
internal static int SendMessageToHelper(int msg, IntPtr wparam, IntPtr lparam, bool wait = true, bool log = true)
{
int h = NativeMethods.FindWindow(null, Common.HELPER_FORM_TEXT);
int rv = -1;
if (h > 0)
{
rv = wait
? (int)NativeMethods.SendMessage((IntPtr)h, msg, wparam, lparam)
: NativeMethods.PostMessage((IntPtr)h, msg, wparam, lparam) ? 1 : 0;
}
if (log)
{
Logger.LogDebug($"SendMessageToHelper: HelperWindow={h}, Return={rv}, msg={msg}, w={wparam.ToInt32()}, l={lparam.ToInt32()}, Post={!wait}");
}
return rv;
}
internal static bool IsWindows8AndUp()
{
return (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2)
|| Environment.OSVersion.Version.Major > 6;
}
internal static string GetMiniLog(IEnumerable optionControls)
{
string log = string.Empty;
log += "=============================================================================================================================\r\n";
log += $"{Application.ProductName} version {Application.ProductVersion}\r\n";
log += $"{Setting.Values.Username}/{GetDebugInfo(MyKey)}\r\n";
log += $"{MachineName}/{MachineID}/{DesMachineID}\r\n";
log += $"Id: {Setting.Values.DeviceId}\r\n";
log += $"Matrix: {string.Join(",", MachineMatrix)}\r\n";
log += $"McPool: {Setting.Values.MachinePoolString}\r\n";
log += "\r\nOPTIONS:\r\n";
foreach (ControlCollection controlCollection in optionControls)
{
foreach (object c in controlCollection)
{
if (c is CheckBox checkBox)
{
log += $"({(checkBox.Checked ? 1 : 0)}) {checkBox.Text}\r\n";
continue;
}
if (c is RadioButton radioButton)
{
log += $"({(radioButton.Checked ? 1 : 0)}) {radioButton.Name}.[{radioButton.Text}]\r\n";
continue;
}
if (c is ComboBox comboBox)
{
log += $"{comboBox.Name} = {comboBox.Text}\r\n";
continue;
}
}
}
log += "\r\n";
SocketStuff sk = Sk;
if (sk?.TcpSockets != null)
{
foreach (TcpSk tcp in sk.TcpSockets)
{
log += $"{Common.MachineName}{(tcp.IsClient ? "=>" : "<=")}{tcp.MachineName}({tcp.MachineId}):{tcp.Status}\r\n";
}
}
log += string.Format(CultureInfo.CurrentCulture, "Helper:{0}\r\n", SendMessageToHelper(0x400, IntPtr.Zero, IntPtr.Zero));
log += Setting.Values.LastPersonalizeLogonScr + "\r\n";
log += "Name2IP =\r\n" + Setting.Values.Name2IP + "\r\n";
log += "Last 10 trace messages:\r\n";
log += string.Join(Environment.NewLine, Logger.LogCounter.Select(item => $"({item.Value}): {item.Key}").Take(10));
log += "\r\n=============================================================================================================================";
return log;
}
internal static bool GetUserName()
{
if (string.IsNullOrEmpty(Setting.Values.Username) && !Common.RunOnLogonDesktop)
{
if (Program.User.Contains("system", StringComparison.CurrentCultureIgnoreCase))
{
_ = Common.ImpersonateLoggedOnUserAndDoSomething(() =>
{
Setting.Values.Username = WindowsIdentity.GetCurrent(true).Name;
});
}
else
{
Setting.Values.Username = Program.User;
}
Logger.LogDebug("[Username] = " + Setting.Values.Username);
}
return !string.IsNullOrEmpty(Setting.Values.Username);
}
internal static void ShowOneWayModeMessage()
{
ToggleShowTopMostMessage(
@"
Due to Security Controls, a remote device cannot control a SAW device.
Please use the keyboard and Mouse from the SAW device.
(Press Esc to hide this message)
",
string.Empty,
10);
}
internal static void ApplyCADSetting()
{
try
{
if (Setting.Values.DisableCAD)
{
RegistryKey k = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System");
if (k != null)
{
k.SetValue("DisableCAD", 1, RegistryValueKind.DWord);
k.Close();
}
}
else
{
RegistryKey k = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System");
if (k != null)
{
k.SetValue("DisableCAD", 0, RegistryValueKind.DWord);
k.Close();
}
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.MachineStuff.cs
================================================
// 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.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Microsoft.PowerToys.Telemetry;
//
// Machine setup/switching implementation.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
namespace MouseWithoutBorders
{
internal struct MachineInf
{
internal string Name;
internal ID Id;
internal long Time;
}
internal class MyRectangle
{
internal int Left;
internal int Top;
internal int Right;
internal int Bottom;
}
internal partial class Common
{
private static readonly Lock McMatrixLock = new();
internal const byte MAX_MACHINE = 4;
internal const byte MAX_SOCKET = MAX_MACHINE * 2;
internal const long HEARTBEAT_TIMEOUT = 1500000; // 30 Mins
private const int SKIP_PIXELS = 1;
private const int JUMP_PIXELS = 2;
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
internal static ID desMachineID;
#pragma warning restore SA1307
internal static string DesMachineName = string.Empty;
private static ID newDesMachineID;
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
internal static ID newDesMachineIdEx;
#pragma warning restore SA1307
private static ID dropMachineID;
private static long lastJump = Common.GetTick();
private static MyRectangle desktopBounds = new();
private static MyRectangle primaryScreenBounds = new();
private static MachinePool _machinePool;
internal static MachinePool MachinePool
{
get
{
_machinePool ??= new MachinePool();
return _machinePool;
}
}
internal static MyRectangle PrimaryScreenBounds => Common.primaryScreenBounds;
internal static MouseLocation SwitchLocation = new();
internal static ID NewDesMachineID
{
get => Common.newDesMachineID;
set => Common.newDesMachineID = value;
}
internal static MyRectangle DesktopBounds => Common.desktopBounds;
#if OLD_VERSION
static bool MoveToMyNeighbourIfNeeded(int x, int y)
{
if (Math.Abs(x) > 10) LastX = x;
if (Math.Abs(y) > 10) LastY = y;
if (GetTick() - lastJump < 500 || desMachineID == IP.ALL) return false;
if (desMachineID == machineID)
{
if (x < desktopBounds.Left + skipPixels) return MoveLeft(x, y, x - desktopBounds.Left, 0);
}
else
{
if (x < primaryScreenBounds.Left + skipPixels)
{
if (MoveLeft(x, y, x - primaryScreenBounds.Left, 0))
{
return true;
}
else
{
if (desktopBounds.Left < primaryScreenBounds.Left)
{
RequestedX_Ex = primaryScreenBounds.Left;
RequestedY_Ex = y;
return true;
}
}
}
}
if (desMachineID == machineID)
{
if (x > desktopBounds.Right - skipPixels) return MoveRight(x, y, x - desktopBounds.Right, 0);
}
else
{
if (x > primaryScreenBounds.Right - skipPixels)
{
if (MoveRight(x, y, x - primaryScreenBounds.Right, 0))
{
return true;
}
else
{
if (desktopBounds.Right > primaryScreenBounds.Right)
{
RequestedX_Ex = primaryScreenBounds.Right;
RequestedY_Ex = y;
return true;
}
}
}
}
if (desMachineID == machineID)
{
if (y < desktopBounds.Top + skipPixels) return MoveUp(x, y, 0, y - desktopBounds.Top);
}
else
{
if (y < primaryScreenBounds.Top + skipPixels)
{
if (MoveUp(x, y, 0, y - primaryScreenBounds.Top))
{
return true;
}
else
{
if (desktopBounds.Top < primaryScreenBounds.Top)
{
RequestedX_Ex = x;
RequestedY_Ex = primaryScreenBounds.Top;
return true;
}
}
}
}
if (desMachineID == machineID)
{
if (y > desktopBounds.Bottom - skipPixels) return MoveDown(x, y, 0, y - desktopBounds.Bottom);
}
else
{
if (y > primaryScreenBounds.Bottom - skipPixels)
{
if (MoveDown(x, y, 0, y - primaryScreenBounds.Bottom))
{
return true;
}
else
{
if (desktopBounds.Bottom > primaryScreenBounds.Bottom)
{
RequestedX_Ex = x;
RequestedY_Ex = primaryScreenBounds.Bottom;
return true;
}
}
}
}
return false;
}
#else
private static Point ConvertToUniversalValue(Point p, MyRectangle r)
{
if (!p.IsEmpty)
{
p.X = (p.X - r.Left) * 65535 / (r.Right - r.Left);
p.Y = (p.Y - r.Top) * 65535 / (r.Bottom - r.Top);
}
return p;
}
/* Let's say we have 3 machines A, B, and C. A is the controller machine.
* (x, y) is the current Mouse position in pixel.
* If Setting.Values.MoveMouseRelatively then (x, y) can be from any machine having the value bounded by desktopBounds (can be negative)
* Else (x, y) is from the controller machine which is bounded by ONLY primaryScreenBounds (>=0);
*
* The return point is from 0 to 65535 which is then mapped to the desktop of the new controlled machine by the SendInput method.
* Let's say user is switching from machine B to machine C:
* If Setting.Values.MoveMouseRelatively the this method is called by B and the return point is calculated by B and sent back to A, A will use it to move Mouse to the right position when switching to C.
* Else this method is called by A and the return point is calculated by A.
* */
internal static Point MoveToMyNeighbourIfNeeded(int x, int y, ID desMachineID)
{
newDesMachineIdEx = desMachineID;
if (Math.Abs(x) > 10)
{
LastX = x;
}
if (Math.Abs(y) > 10)
{
LastY = y;
}
if ((GetTick() - lastJump < 100) || desMachineID == ID.ALL)
{
return Point.Empty;
}
if (Setting.Values.BlockMouseAtCorners)
{
lock (SensitivePoints)
{
foreach (Point p in SensitivePoints)
{
if (Math.Abs(p.X - x) < 100 && Math.Abs(p.Y - y) < 100)
{
return Point.Empty;
}
}
}
}
/* If Mouse is moving in the controller machine and this method is called by the controller machine.
* Or if Mouse is moving in the controlled machine and this method is called by the controlled machine and Setting.Values.MoveMouseRelative.
* */
if (desMachineID == MachineID)
{
if (x < desktopBounds.Left + SKIP_PIXELS)
{
return MoveLeft(x, y);
}
else if (x >= desktopBounds.Right - SKIP_PIXELS)
{
return MoveRight(x, y);
}
else if (y < desktopBounds.Top + SKIP_PIXELS)
{
return MoveUp(x, y);
}
else if (y >= desktopBounds.Bottom - SKIP_PIXELS)
{
return MoveDown(x, y);
}
}
/* If Mouse is moving in the controlled machine and this method is called by the controller machine and !Setting.Values.MoveMouseRelative.
* Mouse location is scaled from the primary screen bound of the controller machine regardless of how many monitors the controlled machine may have.
* */
else
{
if (x < primaryScreenBounds.Left + SKIP_PIXELS)
{
return MoveLeft(x, y);
}
else if (x >= primaryScreenBounds.Right - SKIP_PIXELS)
{
return MoveRight(x, y);
}
else if (y < primaryScreenBounds.Top + SKIP_PIXELS)
{
return MoveUp(x, y);
}
else if (y >= primaryScreenBounds.Bottom - SKIP_PIXELS)
{
return MoveDown(x, y);
}
}
return Point.Empty;
}
#endif
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Dotnet port with style preservation")]
private static Point MoveRight(int x, int y)
{
string[] mc = LiveMachineMatrix;
if (mc == null)
{
return Point.Empty;
}
bool oneRow = Setting.Values.MatrixOneRow;
string currentMachine = NameFromID(desMachineID);
if (currentMachine == null)
{
return Point.Empty;
}
ID newID;
if (oneRow)
{
bool found = false;
for (int i = 0; i < MAX_MACHINE; i++)
{
if (currentMachine.Trim().Equals(mc[i], StringComparison.OrdinalIgnoreCase))
{
for (int j = i; j < MAX_MACHINE - 1; j++)
{
if (mc[j + 1] != null && mc[j + 1].Length > 0)
{
if ((newID = IdFromName(mc[j + 1])) > 0)
{
newDesMachineIdEx = newID;
found = true;
break;
}
}
}
if (!found && Setting.Values.MatrixCircle)
{
for (int j = 0; j < i; j++)
{
if (mc[j] != null && mc[j].Length > 0)
{
if ((newID = IdFromName(mc[j])) > 0)
{
newDesMachineIdEx = newID;
break;
}
}
}
}
break;
}
}
}
else
{
if (currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)
&& (mc[1].Length > 0))
{
if ((newID = IdFromName(mc[1])) > 0)
{
newDesMachineIdEx = newID;
}
}
else if (currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)
&& (mc[3].Length > 0))
{
if ((newID = IdFromName(mc[3])) > 0)
{
newDesMachineIdEx = newID;
}
}
else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)
&& (mc[0].Length > 0))
{
if ((newID = IdFromName(mc[0])) > 0)
{
newDesMachineIdEx = newID;
}
}
else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)
&& (mc[2].Length > 0))
{
if ((newID = IdFromName(mc[2])) > 0)
{
newDesMachineIdEx = newID;
}
}
}
// THIS LOGIC IS THE SAME FOR Move*(int x, int y) METHODS.
if (newDesMachineIdEx != desMachineID)
{
Logger.LogDebug("Move Right");
if (!Setting.Values.MoveMouseRelatively)
{
if (newDesMachineIdEx == MachineID)
{
/* Switching back to the controller machine, we need to scale up to the desktopBounds from primaryScreenBounds (sine !Setting.Values.MoveMouseRelatively).
* primaryScreenBounds => 65535 => desktopBounds, so that the Mouse position is mapped to the right position when the controller machine has multiple monitors.
* */
return ConvertToUniversalValue(new Point(primaryScreenBounds.Left + JUMP_PIXELS, y), primaryScreenBounds);
}
else
{
if (desMachineID == MachineID)
{
/* Switching FROM the controller machine, since Mouse was not bounded/locked to the primary screen,
* Mouse position can just be mapped from desktopBounds to desktopBounds
* desktopBounds => 65535 => desktopBounds.
* */
return ConvertToUniversalValue(new Point(desktopBounds.Left + JUMP_PIXELS, y), desktopBounds);
}
else
{
/* Switching between two machines where non of them is the controller machine.
* Since the current Mouse position is "mapped" from the primary monitor of the controller machine,
* new Mouse position for the new controlled machine needs to be calculated from this as well.
* primaryScreenBounds => 65535 => desktopBounds
* */
return ConvertToUniversalValue(new Point(primaryScreenBounds.Left + JUMP_PIXELS, y), primaryScreenBounds);
}
}
}
else
{
/* In the case where Mouse is moved relatively, Mouse position is simply mapped from desktopBounds to desktopBounds.
* desktopBounds => 65535 => desktopBounds.
* */
return ConvertToUniversalValue(new Point(desktopBounds.Left + JUMP_PIXELS, y), desktopBounds);
}
}
return Point.Empty;
}
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Dotnet port with style preservation")]
private static Point MoveLeft(int x, int y)
{
string[] mc = LiveMachineMatrix;
if (mc == null)
{
return Point.Empty;
}
bool oneRow = Setting.Values.MatrixOneRow;
string currentMachine = NameFromID(desMachineID);
if (currentMachine == null)
{
return Point.Empty;
}
ID newID;
if (oneRow)
{
bool found = false;
for (int i = MAX_MACHINE - 1; i >= 0; i--)
{
if (currentMachine.Trim().Equals(mc[i], StringComparison.OrdinalIgnoreCase))
{
for (int j = i; j > 0; j--)
{
if (mc[j - 1] != null && mc[j - 1].Length > 0)
{
if ((newID = IdFromName(mc[j - 1])) != ID.NONE)
{
newDesMachineIdEx = newID;
found = true;
break;
}
}
}
if (!found && Setting.Values.MatrixCircle)
{
for (int j = MAX_MACHINE - 1; j > i; j--)
{
if (mc[j] != null && mc[j].Length > 0)
{
if ((newID = IdFromName(mc[j])) != ID.NONE)
{
newDesMachineIdEx = newID;
break;
}
}
}
}
break;
}
}
}
else
{
if (currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)
&& (mc[0].Length > 0))
{
if ((newID = IdFromName(mc[0])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)
&& (mc[2].Length > 0))
{
if ((newID = IdFromName(mc[2])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)
&& (mc[1].Length > 0))
{
if ((newID = IdFromName(mc[1])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)
&& (mc[3].Length > 0))
{
if ((newID = IdFromName(mc[3])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
}
if (newDesMachineIdEx != desMachineID)
{
Logger.LogDebug("Move Left");
return !Setting.Values.MoveMouseRelatively
? newDesMachineIdEx == MachineID
? ConvertToUniversalValue(new Point(primaryScreenBounds.Right - JUMP_PIXELS, y), primaryScreenBounds)
: desMachineID == MachineID
? ConvertToUniversalValue(new Point(desktopBounds.Right - JUMP_PIXELS, y), desktopBounds)
: ConvertToUniversalValue(new Point(primaryScreenBounds.Right - JUMP_PIXELS, y), primaryScreenBounds)
: ConvertToUniversalValue(new Point(desktopBounds.Right - JUMP_PIXELS, y), desktopBounds);
}
return Point.Empty;
}
private static Point MoveUp(int x, int y)
{
if (Setting.Values.MatrixOneRow)
{
return Point.Empty;
}
string[] mc = LiveMachineMatrix;
if (mc == null)
{
return Point.Empty;
}
string currentMachine = NameFromID(desMachineID);
if (currentMachine == null)
{
return Point.Empty;
}
ID newID;
if (currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)
&& (mc[0].Length > 0))
{
if ((newID = IdFromName(mc[0])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)
&& (mc[1].Length > 0))
{
if ((newID = IdFromName(mc[1])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)
&& (mc[2].Length > 0))
{
if ((newID = IdFromName(mc[2])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)
&& (mc[3].Length > 0))
{
if ((newID = IdFromName(mc[3])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
if (newDesMachineIdEx != desMachineID)
{
Logger.LogDebug("Move Up");
return !Setting.Values.MoveMouseRelatively
? newDesMachineIdEx == MachineID
? ConvertToUniversalValue(new Point(x, primaryScreenBounds.Bottom - JUMP_PIXELS), primaryScreenBounds)
: desMachineID == MachineID
? ConvertToUniversalValue(new Point(x, desktopBounds.Bottom - JUMP_PIXELS), desktopBounds)
: ConvertToUniversalValue(new Point(x, primaryScreenBounds.Bottom - JUMP_PIXELS), primaryScreenBounds)
: ConvertToUniversalValue(new Point(x, desktopBounds.Bottom - JUMP_PIXELS), desktopBounds);
}
return Point.Empty;
}
private static Point MoveDown(int x, int y)
{
if (Setting.Values.MatrixOneRow)
{
return Point.Empty;
}
string[] mc = LiveMachineMatrix;
if (mc == null)
{
return Point.Empty;
}
string currentMachine = NameFromID(desMachineID);
if (currentMachine == null)
{
return Point.Empty;
}
ID newID;
if (currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)
&& (mc[2].Length > 0))
{
if ((newID = IdFromName(mc[2])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)
&& (mc[3].Length > 0))
{
if ((newID = IdFromName(mc[3])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)
&& (mc[0].Length > 0))
{
if ((newID = IdFromName(mc[0])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)
&& (mc[1].Length > 0))
{
if ((newID = IdFromName(mc[1])) != ID.NONE)
{
newDesMachineIdEx = newID;
}
}
if (newDesMachineIdEx != desMachineID)
{
Logger.LogDebug("Move Down");
return !Setting.Values.MoveMouseRelatively
? newDesMachineIdEx == MachineID
? ConvertToUniversalValue(new Point(x, primaryScreenBounds.Top + JUMP_PIXELS), primaryScreenBounds)
: desMachineID == MachineID
? ConvertToUniversalValue(new Point(x, desktopBounds.Top + JUMP_PIXELS), desktopBounds)
: ConvertToUniversalValue(new Point(x, primaryScreenBounds.Top + JUMP_PIXELS), primaryScreenBounds)
: ConvertToUniversalValue(new Point(x, desktopBounds.Top + JUMP_PIXELS), desktopBounds);
}
return Point.Empty;
}
internal static bool RemoveDeadMachines(ID ip)
{
bool rv = false;
// Here we are removing a dead machine by IP.
foreach (MachineInf inf in Common.MachinePool.ListAllMachines())
{
if (inf.Id == ip)
{
if (MachinePool.SetMachineDisconnected(inf.Name))
{
rv = true;
}
Logger.LogDebug("<><><><><>>><><><<><><><><><><><><><><>><><><><><><><><><><><" + inf.Name);
}
}
return rv;
}
internal static void RemoveDeadMachines()
{
// list of live/dead machines is now automatically up-to-date
// if it changed we need to update the UI.
// for now assume it changed.
// Common.MachinePool.ResetIPAddressesForDeadMachines();
// DoSomethingInUIThread(UpdateMenu);
Common.UpdateMachinePoolStringSetting();
// Make sure MachinePool still holds this machine.
if (Common.MachinePool.LearnMachine(MachineName))
{
_ = Common.MachinePool.TryUpdateMachineID(MachineName, MachineID, false);
}
}
internal static string AddToMachinePool(DATA package)
{
// Log("********** AddToMachinePool called: " + package.src.ToString(CultureInfo.InvariantCulture));
// There should be no duplicates in machine pool.
string name = package.MachineName;
// a few things happening here:
// 1) find a matching machine (by name)
// 2) update its ID and time
// 3) logging
// 4) updating some variables - desMachineID/newDesMachineID
// 5) return the matched name (trimmed) - only in the event of a match
if (Common.MachinePool.TryFindMachineByName(name, out MachineInf machineInfo))
{
_ = Common.MachinePool.TryUpdateMachineID(machineInfo.Name, machineInfo.Id, true);
_ = Common.MachinePool.TryUpdateMachineID(machineInfo.Name, package.Src, true);
if (machineInfo.Name.Equals(DesMachineName, StringComparison.OrdinalIgnoreCase))
{
Logger.LogDebug("AddToMachinePool: Des ID updated: " + DesMachineID.ToString() + "/" + package.Src.ToString());
newDesMachineID = desMachineID = package.Src;
}
return machineInfo.Name;
}
else
{
if (Common.MachinePool.LearnMachine(name))
{
_ = Common.MachinePool.TryUpdateMachineID(name, package.Src, true);
}
else
{
Logger.LogDebug("AddToMachinePool: could not add a new machine: " + name);
return "The 5th machine";
}
}
// if (machineCount != saved)
{
// DoSomethingInUIThread(UpdateMenu);
Common.UpdateMachinePoolStringSetting();
}
// NOTE(yuyoyuppe): automatically active "bidirectional" control between the machines.
string[] st = new string[Common.MAX_MACHINE];
Array.Fill(st, string.Empty);
var machines = Common.MachinePool.ListAllMachines();
for (int i = 0; i < machines.Count; ++i)
{
if (machines[i].Id != ID.NONE && machines[i].Id != ID.ALL)
{
st[i] = machines[i].Name;
}
}
Common.MachineMatrix = st;
Common.ReopenSockets(true);
Common.SendMachineMatrix();
Logger.LogDebug("Machine added: " + name + "/" + package.Src.ToString());
UpdateClientSockets("AddToMachinePool");
return name;
}
internal static void UpdateClientSockets(string logHeader)
{
Logger.LogDebug("UpdateClientSockets: " + logHeader);
Sk?.UpdateTCPClients();
}
private static SettingsForm settings;
internal static SettingsForm Settings
{
get => Common.settings;
set => Common.settings = value;
}
internal static void ShowSetupForm(bool reopenSockets = false)
{
Logger.LogDebug("========== BEGIN THE SETUP EXPERIENCE ==========", true);
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
Common.GeneratedKey = true;
if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
{
Logger.Log("Not physical console session.");
_ = MessageBox.Show(
"请在物理终端会话中运行.\r\n本软件不支持在远程连接和虚拟机中使用.",
Application.ProductName,
MessageBoxButtons.OK,
MessageBoxIcon.Stop);
return;
}
if (settings == null)
{
settings = new SettingsForm();
settings.Show();
}
else
{
settings.Close();
Common.MMSleep(0.3);
settings = new SettingsForm();
settings.Show();
}
if (reopenSockets)
{
Common.ReopenSockets(true);
}
}
internal static void CloseSetupForm()
{
if (settings != null)
{
settings.Close();
settings = null;
}
}
internal static void ShowMachineMatrix()
{
if (!Setting.Values.ShowOriginalUI)
{
return;
}
if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
{
Common.ShowToolTip("本软件不支持在远程连接和虚拟机中使用.", 5000);
}
#if NEW_SETTINGS_FORM
Common.ShowSetupForm();
#else
if (Setting.Values.FirstRun && !Common.AtLeastOneSocketConnected())
{
Common.ShowSetupForm();
}
else
{
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIOpenedEvent());
if (MatrixForm == null)
{
MatrixForm = new FrmMatrix();
MatrixForm.Show();
if (MainForm != null)
{
MainForm.NotifyIcon.Visible = false;
MainForm.NotifyIcon.Visible = Setting.Values.ShowOriginalUI;
}
}
else
{
MatrixForm.WindowState = FormWindowState.Normal;
MatrixForm.Activate();
}
}
#endif
}
private static string[] mcMatrix;
internal static string[] MachineMatrix
{
get
{
lock (McMatrixLock)
{
if (mcMatrix == null)
{
string s = Setting.Values.MachineMatrixString;
if (!string.IsNullOrEmpty(s))
{
mcMatrix = s.Split(new char[] { ',' });
if (mcMatrix == null || mcMatrix.Length != MAX_MACHINE)
{
mcMatrix = new string[MAX_MACHINE] { string.Empty, string.Empty, string.Empty, string.Empty };
}
}
else
{
mcMatrix = new string[MAX_MACHINE] { string.Empty, string.Empty, string.Empty, string.Empty };
}
}
return mcMatrix;
}
}
set
{
lock (McMatrixLock)
{
if (value == null)
{
mcMatrix = null; // Force read from registry next time.
return;
}
else
{
Setting.Values.MachineMatrixString = string.Join(",", mcMatrix = value);
}
}
DoSomethingInUIThread(() =>
{
MainForm.ChangeIcon(-1);
MainForm.UpdateNotifyIcon();
});
}
}
private static string[] LiveMachineMatrix
{
get
{
bool twoRow = !Setting.Values.MatrixOneRow;
string[] connectedMachines = twoRow ? MachineMatrix : MachineMatrix.Select(m => IsConnectedTo(IdFromName(m)) ? m : string.Empty).ToArray();
Logger.LogDebug($"Matrix: {string.Join(",", MachineMatrix)}, Connected: {string.Join(",", connectedMachines)}");
return connectedMachines;
}
}
internal static void UpdateMachinePoolStringSetting()
{
Setting.Values.MachinePoolString = Common.MachinePool.SerializedAsString();
}
internal static void SendMachineMatrix()
{
if (MachineMatrix == null)
{
return;
}
DATA package = new();
for (int i = 0; i < MachineMatrix.Length; i++)
{
package.MachineName = MachineMatrix[i];
package.Type = PackageType.Matrix
| (Setting.Values.MatrixCircle ? PackageType.MatrixSwapFlag : 0)
| (Setting.Values.MatrixOneRow ? 0 : PackageType.MatrixTwoRowFlag);
package.Src = (ID)(i + 1);
package.Des = ID.ALL;
SkSend(package, null, false);
Logger.LogDebug($"matrixIncludedMachine sent: [{i + 1}]:[{MachineMatrix[i]}]");
}
}
internal static void UpdateMachineMatrix(DATA package)
{
uint i = (uint)package.Src;
string matrixIncludedMachine = package.MachineName;
if (i is > 0 and <= MAX_MACHINE)
{
Logger.LogDebug($"matrixIncludedMachine: [{i}]:[{matrixIncludedMachine}]");
MachineMatrix[i - 1] = matrixIncludedMachine;
if (i == MAX_MACHINE)
{
Setting.Values.MatrixCircle = (package.Type & PackageType.MatrixSwapFlag) == PackageType.MatrixSwapFlag;
Setting.Values.MatrixOneRow = !((package.Type & PackageType.MatrixTwoRowFlag) == PackageType.MatrixTwoRowFlag);
MachineMatrix = MachineMatrix; // Save
Common.ReopenSocketDueToReadError = true;
UpdateClientSockets("UpdateMachineMatrix");
Setting.Values.Changed = true;
}
}
else
{
Logger.LogDebug("Invalid machine Matrix package!");
}
}
internal static void SwitchToMachine(string name)
{
ID id = Common.MachinePool.ResolveID(name);
if (id != ID.NONE)
{
// Ask current machine to hide the Mouse cursor
if (desMachineID != MachineID)
{
SendPackage(desMachineID, PackageType.HideMouse);
}
NewDesMachineID = DesMachineID = id;
SwitchLocation.X = XY_BY_PIXEL + primaryScreenBounds.Left + ((primaryScreenBounds.Right - primaryScreenBounds.Left) / 2);
SwitchLocation.Y = XY_BY_PIXEL + primaryScreenBounds.Top + ((primaryScreenBounds.Bottom - primaryScreenBounds.Top) / 2);
SwitchLocation.ResetCount();
Common.UpdateMultipleModeIconAndMenu();
HideMouseCursor(false);
_ = EvSwitch.Set();
}
}
internal static void SwitchToMultipleMode(bool multipleMode, bool centerScreen)
{
if (multipleMode)
{
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersMultipleModeEvent());
NewDesMachineID = DesMachineID = ID.ALL;
}
else
{
NewDesMachineID = DesMachineID = MachineID;
}
if (centerScreen)
{
MoveMouseToCenter();
}
ReleaseAllKeys();
Common.UpdateMultipleModeIconAndMenu();
}
internal static bool CheckSecondInstance(bool sendMessage = false)
{
int h;
if ((h = NativeMethods.FindWindow(null, Setting.Values.MyID)) > 0)
{
return true;
}
return false;
}
private static EventWaitHandle oneInstanceCheck;
internal static void AssertOneInstancePerDesktopSession()
{
string eventName = $"Global\\{Application.ProductName}-{FrmAbout.AssemblyVersion}-{GetMyDesktop()}-{CurrentProcess.SessionId}";
oneInstanceCheck = new EventWaitHandle(false, EventResetMode.ManualReset, eventName, out bool created);
if (!created)
{
Logger.TelemetryLogTrace($"Second instance found: {eventName}.", SeverityLevel.Warning, true);
CurrentProcess.KillProcess(true);
}
}
internal static ID IdFromName(string name)
{
return Common.MachinePool.ResolveID(name);
}
internal static string NameFromID(ID id)
{
foreach (MachineInf inf in Common.MachinePool.TryFindMachineByID(id))
{
if (!string.IsNullOrEmpty(inf.Name))
{
return inf.Name;
}
}
return null;
}
internal static bool InMachineMatrix(string name)
{
if (MachineMatrix == null || string.IsNullOrWhiteSpace(name))
{
return false;
}
foreach (string st in MachineMatrix)
{
if (!string.IsNullOrWhiteSpace(st) && st.Trim().Equals(name.Trim(), StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
internal static void ClearComputerMatrix()
{
Common.MachineMatrix = new string[Common.MAX_MACHINE] { Common.MachineName.Trim(), string.Empty, string.Empty, string.Empty };
Common.MachinePool.Initialize(new string[] { Common.MachineName });
Common.UpdateMachinePoolStringSetting();
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Service.cs
================================================
// 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.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.ServiceProcess;
using System.Threading.Tasks;
using System.Windows.Forms;
//
// Service control code.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.Common.#StartMouseWithoutBordersService()", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders
{
internal partial class Common
{
private static bool shownErrMessage;
private static DateTime lastStartServiceTime = DateTime.UtcNow;
internal static void StartMouseWithoutBordersService(string desktopToRunMouseWithoutBordersOn = null, string startTag1 = "byapp", string startTag2 = null)
{
// NOTE(@yuyoyuppe): the new flow assumes we run both mwb processes directly from the svc.
if (Common.RunWithNoAdminRight || true)
{
return;
}
Logger.Log($"{nameof(StartMouseWithoutBordersService)}: {Logger.GetStackTrace(new StackTrace())}.");
Task task = Task.Run(() =>
{
Process[] ps = Process.GetProcessesByName("MouseWithoutBordersSvc");
if (ps.Length != 0)
{
if (DateTime.UtcNow - lastStartServiceTime < TimeSpan.FromSeconds(5))
{
Logger.Log($"{nameof(StartMouseWithoutBordersService)}: Aborted.");
return;
}
foreach (Process pp in ps)
{
Logger.Log(string.Format(CultureInfo.InvariantCulture, "Killing process MouseWithoutBordersSvc {0}.", pp.Id));
pp.KillProcess();
}
}
lastStartServiceTime = DateTime.UtcNow;
ServiceController service = new("MouseWithoutBordersSvc");
try
{
Logger.Log("Starting " + service.ServiceName);
}
catch (Exception)
{
if (!shownErrMessage)
{
shownErrMessage = true;
_ = MessageBox.Show(
Application.ProductName + " 尚未安装,请先运行 Setup.exe!",
Application.ProductName,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
return;
}
try
{
int c = 0;
while (service.Status != ServiceControllerStatus.Stopped && c++ < 5)
{
Thread.Sleep(1000);
service = new ServiceController("MouseWithoutBordersSvc");
}
if (string.IsNullOrWhiteSpace(desktopToRunMouseWithoutBordersOn))
{
startTag2 ??= Process.GetCurrentProcess().SessionId.ToString(CultureInfo.InvariantCulture);
service.Start(new string[] { startTag1, startTag2 });
}
else
{
service.Start(new string[] { desktopToRunMouseWithoutBordersOn });
}
}
catch (Exception e)
{
Logger.Log(e);
// ERROR_SERVICE_ALREADY_RUNNING
if (!(shownErrMessage || ((e?.InnerException as Win32Exception)?.NativeErrorCode == 1056)))
{
shownErrMessage = true;
_ = MessageBox.Show(
"无法启动服务 " + service.ServiceName + ": " + e.Message,
Common.BinaryName,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
return;
}
});
// Wait for the task while not blocking the UI thread.
do
{
MMSleep(1);
if (task.IsCanceled || task.IsCompleted || task.IsFaulted)
{
break;
}
}
while (true);
}
internal static void StartServiceAndSendLogoffSignal()
{
try
{
Process[] p = Process.GetProcessesByName("winlogon");
Process me = Process.GetCurrentProcess();
string myWinlogon = p?.FirstOrDefault(item => item.SessionId == me.SessionId)?.Id.ToString(CultureInfo.InvariantCulture) ?? null;
if (string.IsNullOrWhiteSpace(myWinlogon))
{
StartMouseWithoutBordersService(null, "logoff");
}
else
{
StartMouseWithoutBordersService(null, "logoff", myWinlogon);
}
}
catch (Exception e)
{
Logger.Log($"{nameof(StartServiceAndSendLogoffSignal)}: {e.Message}");
}
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/EasyMouseOption.cs
================================================
// 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 MouseWithoutBorders.Class
{
internal enum EasyMouseOption : int
{
关闭 = 0,
开启 = 1,
Ctrl = 2,
Shift = 3,
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Extensions.cs
================================================
// 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.ComponentModel;
using System.Diagnostics;
using System.IO;
using MouseWithoutBorders.Core;
// Disable the warning to preserve original code
#pragma warning disable CA1716
namespace MouseWithoutBorders.Class
#pragma warning restore CA1716
{
internal static class Extensions
{
internal static int ReadEx(this Stream st, byte[] buf, int bufIndex, int length)
{
int bytesReceived = st.Read(buf, bufIndex, length);
int receivedCount = bytesReceived;
while (receivedCount != 0 && bytesReceived < length)
{
bytesReceived += receivedCount = st.Read(buf, bufIndex + bytesReceived, length - bytesReceived);
}
return bytesReceived;
}
internal static void KillProcess(this Process process, bool keepTrying = false)
{
string processName = process.ProcessName;
int processId = process.Id;
do
{
try
{
process.Kill();
break;
}
catch (Win32Exception e)
{
string log = $"The process {processName} (PID={processId}) could not be terminated, error: {e.Message}";
string logcn = $"进程 {processName} (PID={processId}) 无法被终止,错误: {e.Message}";
Logger.TelemetryLogTrace(log, SeverityLevel.Error);
Common.ShowToolTip(logcn, 5000);
if (!keepTrying)
{
Thread.Sleep(1000);
break;
}
}
}
while (true);
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/IClipboardHelper.cs
================================================
// 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;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Pipes;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.VisualStudio.Threading;
using Newtonsoft.Json;
using StreamJsonRpc;
#if !MM_HELPER
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
#endif
using SystemClipboard = System.Windows.Forms.Clipboard;
#if !MM_HELPER
using Thread = MouseWithoutBorders.Core.Thread;
#endif
namespace MouseWithoutBorders
{
[JsonObject(MemberSerialization.OptIn)]
public struct ByteArrayOrString
{
private enum ValueType
{
ByteArray,
String,
}
[JsonProperty]
private ValueType _type;
private byte[] _byteArrayValue;
private string _stringValue;
public ByteArrayOrString(byte[] byteArray)
{
_type = ValueType.ByteArray;
_byteArrayValue = byteArray;
_stringValue = null;
}
public ByteArrayOrString(string str)
{
_type = ValueType.String;
_byteArrayValue = null;
_stringValue = str;
}
public bool IsByteArray => _type == ValueType.ByteArray;
public bool IsString => _type == ValueType.String;
[JsonProperty("byteArray")]
public byte[] ByteArray
{
get => _byteArrayValue;
set
{
_byteArrayValue = value;
_type = ValueType.ByteArray;
}
}
[JsonProperty("string")]
public string TheString
{
get => _stringValue;
set
{
_stringValue = value;
_type = ValueType.String;
}
}
public bool ShouldSerializeByteArray() => IsByteArray;
public bool ShouldSerializeString() => IsString;
public byte[] GetByteArray()
{
if (IsByteArray)
{
return _byteArrayValue;
}
throw new InvalidOperationException("The value is not a byte array.");
}
public string GetString()
{
if (IsString)
{
return _stringValue;
}
throw new InvalidOperationException("The value is not a string.");
}
public static implicit operator ByteArrayOrString(byte[] byteArray) => new ByteArrayOrString(byteArray);
public static implicit operator ByteArrayOrString(string str) => new ByteArrayOrString(str);
}
public interface IClipboardHelper
{
void SendLog(string log);
void SendDragFile(string fileName);
void SendClipboardData(ByteArrayOrString data, bool isFilePath);
}
#if !MM_HELPER
public class ClipboardHelper : IClipboardHelper
{
public void SendLog(string log)
{
Logger.LogDebug("FROM HELPER: " + log);
if (!string.IsNullOrEmpty(log))
{
if (log.StartsWith("Screen capture ended", StringComparison.InvariantCulture))
{
/* TODO: Telemetry for screen capture. */
if (Setting.Values.FirstCtrlShiftS)
{
Setting.Values.FirstCtrlShiftS = false;
Common.ShowToolTip("区块截屏被触发,您可以在设置中调整快捷键.", 10000);
}
}
else if (log.StartsWith("Trace:", StringComparison.InvariantCulture))
{
Logger.TelemetryLogTrace(log, SeverityLevel.Information);
}
}
}
public void SendDragFile(string fileName)
{
Common.DragDropStep05Ex(fileName);
}
public void SendClipboardData(ByteArrayOrString data, bool isFilePath)
{
_ = Common.CheckClipboardEx(data, isFilePath);
}
}
#endif
internal sealed class IpcChannel
where T : new()
{
public static T StartIpcServer(string pipeName, CancellationToken cancellationToken)
{
SecurityIdentifier securityIdentifier = new SecurityIdentifier(
WellKnownSidType.AuthenticatedUserSid, null);
PipeSecurity pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule(
securityIdentifier,
PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance,
AccessControlType.Allow));
_ = Task.Factory.StartNew(
async () =>
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
using (var serverChannel = NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, 0, pipeSecurity))
{
await serverChannel.WaitForConnectionAsync();
var taskRpc = JsonRpc.Attach(serverChannel, new T());
await taskRpc.Completion;
}
}
}
catch (OperationCanceledException)
{
}
catch (Exception e)
{
#if MM_HELPER
_ = e;
#else
Logger.Log(e);
#endif
}
},
cancellationToken,
TaskCreationOptions.None,
TaskScheduler.Default);
return default(T);
}
}
internal sealed class IpcHelper
{
private const string ChannelName = "MouseWithoutBorders";
private const string RemoteObjectName = "ClipboardHelper";
#if !MM_HELPER
private static void CleanupStream()
{
if (_serverTaskCancellationSource != null)
{
_serverTaskCancellationSource.Cancel();
_serverTaskCancellationSource.Dispose();
_serverTaskCancellationSource = null;
}
}
private static CancellationTokenSource _serverTaskCancellationSource;
internal static void CreateIpcServer(bool cleanup)
{
try
{
if (cleanup)
{
CleanupStream();
return;
}
_serverTaskCancellationSource = new CancellationTokenSource();
CancellationToken cancellationToken = _serverTaskCancellationSource.Token;
IpcChannel.StartIpcServer(ChannelName + "/" + RemoteObjectName, cancellationToken);
Common.IpcChannelCreated = true;
}
catch (Exception e)
{
Common.IpcChannelCreated = false;
Common.ShowToolTip("Error setting up clipboard sharing, clipboard sharing will not work!", 5000, ToolTipIcon.Error);
Logger.Log(e);
}
}
#else
internal static IClipboardHelper CreateIpcClient()
{
try
{
var stream = new NamedPipeClientStream(".", ChannelName + "/" + RemoteObjectName, PipeDirection.InOut, PipeOptions.Asynchronous);
stream.Connect();
return JsonRpc.Attach(stream);
}
catch (Exception e)
{
EventLogger.LogEvent(e.Message, EventLogEntryType.Error);
}
return null;
}
#endif
}
internal static class EventLogger
{
#if MM_HELPER
private const string EventSourceName = "MouseWithoutBordersHelper";
#else
private const string EventSourceName = "MouseWithoutBorders";
#endif
internal static void LogEvent(string message, EventLogEntryType logType = EventLogEntryType.Information)
{
try
{
if (!EventLog.SourceExists(EventSourceName))
{
EventLog.CreateEventSource(EventSourceName, "Application");
}
EventLog.WriteEntry(EventSourceName, message, logType);
}
catch (Exception e)
{
Debug.WriteLine(message + ": " + e.Message);
}
}
}
#if MM_HELPER
internal static class ClipboardMMHelper
{
internal static IntPtr NextClipboardViewer = IntPtr.Zero;
private static FormHelper helperForm;
private static bool addClipboardFormatListenerResult;
private static void Log(string log)
{
helperForm.SendLog(log);
}
private static void Log(Exception e)
{
Log($"Trace: {e}");
}
internal static void HookClipboard(FormHelper f)
{
helperForm = f;
try
{
addClipboardFormatListenerResult = NativeMethods.AddClipboardFormatListener(f.Handle);
int err = addClipboardFormatListenerResult ? 0 : Marshal.GetLastWin32Error();
if (err != 0)
{
Log($"Trace: {nameof(NativeMethods.AddClipboardFormatListener)}: GetLastError = {err}");
}
}
catch (EntryPointNotFoundException e)
{
Log($"{nameof(NativeMethods.AddClipboardFormatListener)} is unavailable in this version of Windows.");
Log(e);
}
catch (Exception e)
{
Log(e);
}
// Fallback
if (!addClipboardFormatListenerResult)
{
NextClipboardViewer = NativeMethods.SetClipboardViewer(f.Handle);
int err = NextClipboardViewer == IntPtr.Zero ? Marshal.GetLastWin32Error() : 0;
if (err != 0)
{
Log($"Trace: {nameof(NativeMethods.SetClipboardViewer)}: GetLastError = {err}");
}
}
Log($"Trace: Clipboard monitor method {(addClipboardFormatListenerResult ? nameof(NativeMethods.AddClipboardFormatListener) : NextClipboardViewer != IntPtr.Zero ? nameof(NativeMethods.SetClipboardViewer) : "(none)")} is used.");
}
internal static void UnhookClipboard()
{
if (addClipboardFormatListenerResult)
{
addClipboardFormatListenerResult = false;
_ = NativeMethods.RemoveClipboardFormatListener(helperForm.Handle);
}
else
{
_ = NativeMethods.ChangeClipboardChain(helperForm.Handle, NextClipboardViewer);
NextClipboardViewer = IntPtr.Zero;
}
}
private static void ReHookClipboard()
{
UnhookClipboard();
HookClipboard(helperForm);
}
internal static bool UpdateNextClipboardViewer(Message m)
{
if (m.WParam == NextClipboardViewer)
{
NextClipboardViewer = m.LParam;
return true;
}
return false;
}
internal static void PassMessageToTheNextViewer(Message m)
{
if (NextClipboardViewer != IntPtr.Zero && NextClipboardViewer != helperForm.Handle)
{
_ = NativeMethods.SendMessage(NextClipboardViewer, m.Msg, m.WParam, m.LParam);
}
}
public static bool ContainsFileDropList()
{
bool rv = false;
try
{
rv = Common.Retry(nameof(SystemClipboard.ContainsFileDropList), () => { return SystemClipboard.ContainsFileDropList(); }, (log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
return rv;
}
public static bool ContainsImage()
{
bool rv = false;
try
{
rv = Common.Retry(nameof(SystemClipboard.ContainsImage), () => { return SystemClipboard.ContainsImage(); }, (log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
return rv;
}
public static bool ContainsText()
{
bool rv = false;
try
{
rv = Common.Retry(nameof(SystemClipboard.ContainsText), () => { return SystemClipboard.ContainsText(); }, (log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
return rv;
}
public static StringCollection GetFileDropList()
{
StringCollection rv = null;
try
{
rv = Common.Retry(nameof(SystemClipboard.GetFileDropList), () => { return SystemClipboard.GetFileDropList(); }, (log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
return rv;
}
public static Image GetImage()
{
Image rv = null;
try
{
rv = Common.Retry(nameof(SystemClipboard.GetImage), () => { return SystemClipboard.GetImage(); }, (log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
return rv;
}
public static string GetText(TextDataFormat format)
{
string rv = null;
try
{
rv = Common.Retry(nameof(SystemClipboard.GetText), () => { return SystemClipboard.GetText(format); }, (log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
catch (System.ComponentModel.InvalidEnumArgumentException e)
{
Log(e);
}
return rv;
}
public static void SetImage(Image image)
{
try
{
_ = Common.Retry(
nameof(SystemClipboard.SetImage),
() =>
{
SystemClipboard.SetImage(image);
return true;
},
(log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
catch (ArgumentNullException e)
{
Log(e);
}
}
public static void SetText(string text)
{
try
{
_ = Common.Retry(
nameof(SystemClipboard.SetText),
() =>
{
SystemClipboard.SetText(text);
return true;
},
(log) => Log(log));
}
catch (ExternalException e)
{
Log(e);
ReHookClipboard();
}
catch (ThreadStateException e)
{
Log(e);
ReHookClipboard();
}
catch (ArgumentNullException e)
{
Log(e);
}
}
}
#endif
internal sealed class SharedConst
{
internal const int QUIT_CMD = 0x409;
}
internal sealed partial class Common
{
internal static bool IpcChannelCreated { get; set; }
internal static T Retry(string name, Func func, Action log, Action preRetry = null)
{
int count = 0;
do
{
try
{
T rv = func();
if (count > 0)
{
log($"Trace: {name} has been successful after {count} retry.");
}
return rv;
}
catch (Exception)
{
count++;
preRetry?.Invoke();
if (count > 10)
{
throw;
}
Application.DoEvents();
Thread.Sleep(200);
}
}
while (true);
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/InputHook.cs
================================================
// 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.
//
// Keyboard/Mouse hook callbacks, pre-process before calling to routines in Common.Event.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.PowerToys.Settings.UI.Library;
using MouseWithoutBorders.Core;
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.InputHook.#MouseHookProc(System.Int32,System.Int32,System.IntPtr)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "MouseWithoutBorders.InputHook.#ProcessKeyEx(System.Int32,System.Int32)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.InputHook.#Start()", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders.Class
{
internal class InputHook
{
internal delegate void MouseEvHandler(MOUSEDATA e, int dx, int dy);
internal delegate void KeybdEvHandler(KEYBDDATA e);
[StructLayout(LayoutKind.Sequential)]
private struct MouseHookStruct
{
internal NativeMethods.POINT Pt;
internal int Hwnd;
internal int WHitTestCode;
internal int DwExtraInfo;
}
// http://msdn.microsoft.com/en-us/library/ms644970(VS.85).aspx
[StructLayout(LayoutKind.Sequential)]
private struct MouseLLHookStruct
{
internal NativeMethods.POINT Pt;
internal int MouseData;
internal int Flags;
internal int Time;
internal int DwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
private struct KeyboardHookStruct
{
internal int VkCode;
internal int ScanCode;
internal int Flags;
internal int Time;
internal int DwExtraInfo;
}
internal event MouseEvHandler MouseEvent;
internal event KeybdEvHandler KeyboardEvent;
private int hMouseHook;
private int hKeyboardHook;
private static NativeMethods.HookProc mouseHookProcedure;
private static NativeMethods.HookProc keyboardHookProcedure;
private static MouseLLHookStruct mouseHookStruct;
private static KeyboardHookStruct keyboardHookStruct;
private static MOUSEDATA hookCallbackMouseData;
private static KEYBDDATA hookCallbackKeybdData;
private static bool winDown;
private static bool altDown;
private static bool shiftDown;
internal static bool RealData { get; set; } = true;
internal static int SkipMouseUpCount { get; set; }
internal static bool SkipMouseUpDown { get; set; }
internal static bool CtrlDown { get; private set; }
internal static bool EasyMouseKeyDown { get; set; }
internal InputHook()
{
Start();
}
~InputHook()
{
Stop();
}
internal void Start()
{
int le;
bool er = false;
// Install Mouse Hook
mouseHookProcedure = new NativeMethods.HookProc(MouseHookProc);
hMouseHook = NativeMethods.SetWindowsHookEx(
Common.WH_MOUSE_LL,
mouseHookProcedure,
Marshal.GetHINSTANCE(
Assembly.GetExecutingAssembly().GetModules()[0]),
0);
if (hMouseHook == 0)
{
le = Marshal.GetLastWin32Error();
Logger.Log("Error installing Mouse hook: " + le.ToString(CultureInfo.CurrentCulture));
er = true;
Stop();
}
// Install Keyboard Hook
keyboardHookProcedure = new NativeMethods.HookProc(KeyboardHookProc);
hKeyboardHook = NativeMethods.SetWindowsHookEx(
Common.WH_KEYBOARD_LL,
keyboardHookProcedure,
Marshal.GetHINSTANCE(
Assembly.GetExecutingAssembly().GetModules()[0]),
0);
if (hKeyboardHook == 0)
{
le = Marshal.GetLastWin32Error();
Logger.Log("Error installing keyboard hook: " + le.ToString(CultureInfo.CurrentCulture));
er = true;
Stop();
}
if (er)
{
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
_ = MessageBox.Show(
"安装键盘/鼠标侦听器失败!",
Application.ProductName,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
else
{
Common.InitLastInputEventCount();
}
}
internal void Stop()
{
if (hMouseHook != 0)
{
int retMouse = NativeMethods.UnhookWindowsHookEx(hMouseHook);
hMouseHook = 0;
if (retMouse == 0)
{
int errorCode = Marshal.GetLastWin32Error();
// throw new Win32Exception(errorCode);
Logger.Log("Exception uninstalling Mouse hook, error code: " + errorCode.ToString(CultureInfo.CurrentCulture));
}
}
if (hKeyboardHook != 0)
{
int retKeyboard = NativeMethods.UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
if (retKeyboard == 0)
{
int errorCode = Marshal.GetLastWin32Error();
// throw new Win32Exception(errorCode);
Logger.Log("Exception uninstalling keyboard hook, error code: " + errorCode.ToString(CultureInfo.CurrentCulture));
}
}
}
// Better performance, compared to Marshal.PtrToStructure.
private static MouseLLHookStruct LParamToMouseLLHookStruct(IntPtr lParam)
{
unsafe
{
return *(MouseLLHookStruct*)lParam;
}
}
private static KeyboardHookStruct LParamToKeyboardHookStruct(IntPtr lParam)
{
unsafe
{
return *(KeyboardHookStruct*)lParam;
}
}
private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
{
int rv = 1, dx = 0, dy = 0;
bool local = false;
Common.InputEventCount++;
try
{
if (!RealData)
{
RealData = true;
// Common.Log("MouseHookProc: Not real data!");
// return rv;
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
else
{
Common.RealInputEventCount++;
if (Common.NewDesMachineID == Common.MachineID || Common.NewDesMachineID == ID.ALL)
{
local = true;
if (Common.MainFormVisible && !Common.IsDropping)
{
Common.MainFormDot();
}
}
if (nCode >= 0 && MouseEvent != null)
{
if (wParam == Common.WM_LBUTTONUP && SkipMouseUpCount > 0)
{
Logger.LogDebug($"{nameof(SkipMouseUpCount)}: {SkipMouseUpCount}.");
SkipMouseUpCount--;
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
return rv;
}
if ((wParam == Common.WM_LBUTTONUP || wParam == Common.WM_LBUTTONDOWN) && SkipMouseUpDown)
{
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
return rv;
}
mouseHookStruct = LParamToMouseLLHookStruct(lParam);
hookCallbackMouseData.dwFlags = wParam;
// Use WheelDelta to store XBUTTON1/XBUTTON2 data.
hookCallbackMouseData.WheelDelta = (short)((mouseHookStruct.MouseData >> 16) & 0xffff);
if (local)
{
hookCallbackMouseData.X = mouseHookStruct.Pt.x;
hookCallbackMouseData.Y = mouseHookStruct.Pt.y;
if (Setting.Values.DrawMouse && Common.MouseCursorForm != null)
{
CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);
}
}
else
{
if (Common.SwitchLocation.Count > 0 && Common.NewDesMachineID != Common.MachineID && Common.NewDesMachineID != ID.ALL)
{
Common.SwitchLocation.Count--;
if (Common.SwitchLocation.X > Common.XY_BY_PIXEL - 100000 || Common.SwitchLocation.Y > Common.XY_BY_PIXEL - 100000)
{
hookCallbackMouseData.X = Common.SwitchLocation.X - Common.XY_BY_PIXEL;
hookCallbackMouseData.Y = Common.SwitchLocation.Y - Common.XY_BY_PIXEL;
}
else
{
hookCallbackMouseData.X = (Common.SwitchLocation.X * Common.ScreenWidth / 65535) + Common.PrimaryScreenBounds.Left;
hookCallbackMouseData.Y = (Common.SwitchLocation.Y * Common.ScreenHeight / 65535) + Common.PrimaryScreenBounds.Top;
}
Common.HideMouseCursor(false);
}
else
{
dx = mouseHookStruct.Pt.x - Common.LastPos.X;
dy = mouseHookStruct.Pt.y - Common.LastPos.Y;
hookCallbackMouseData.X += dx;
hookCallbackMouseData.Y += dy;
if (hookCallbackMouseData.X < Common.PrimaryScreenBounds.Left)
{
hookCallbackMouseData.X = Common.PrimaryScreenBounds.Left - 1;
}
else if (hookCallbackMouseData.X > Common.PrimaryScreenBounds.Right)
{
hookCallbackMouseData.X = Common.PrimaryScreenBounds.Right + 1;
}
if (hookCallbackMouseData.Y < Common.PrimaryScreenBounds.Top)
{
hookCallbackMouseData.Y = Common.PrimaryScreenBounds.Top - 1;
}
else if (hookCallbackMouseData.Y > Common.PrimaryScreenBounds.Bottom)
{
hookCallbackMouseData.Y = Common.PrimaryScreenBounds.Bottom + 1;
}
dx += dx < 0 ? -Common.MOVE_MOUSE_RELATIVE : Common.MOVE_MOUSE_RELATIVE;
dy += dy < 0 ? -Common.MOVE_MOUSE_RELATIVE : Common.MOVE_MOUSE_RELATIVE;
}
}
MouseEvent(hookCallbackMouseData, dx, dy);
Common.DragDropStep01(wParam);
Common.DragDropStep09(wParam);
}
if (local)
{
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
}
}
catch (Exception e)
{
Logger.Log(e);
rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
return rv;
}
private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam)
{
Common.InputEventCount++;
if (!RealData)
{
return NativeMethods.CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
Common.RealInputEventCount++;
keyboardHookStruct = LParamToKeyboardHookStruct(lParam);
hookCallbackKeybdData.dwFlags = keyboardHookStruct.Flags;
hookCallbackKeybdData.wVk = (short)keyboardHookStruct.VkCode;
if (nCode >= 0 && KeyboardEvent != null)
{
if (!ProcessKeyEx(keyboardHookStruct.VkCode, keyboardHookStruct.Flags, hookCallbackKeybdData))
{
return 1;
}
KeyboardEvent(hookCallbackKeybdData);
}
if (Common.DesMachineID == ID.NONE || Common.DesMachineID == ID.ALL || Common.DesMachineID == Common.MachineID)
{
return NativeMethods.CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
else
{
return 1;
}
}
private bool ProcessKeyEx(int vkCode, int flags, KEYBDDATA hookCallbackKeybdData)
{
if ((flags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)
{
EasyMouseKeyDown = false;
switch ((VK)vkCode)
{
case VK.LWIN:
case VK.RWIN:
winDown = false;
break;
case VK.LCONTROL:
case VK.RCONTROL:
CtrlDown = false;
break;
case VK.LMENU:
case VK.RMENU:
altDown = false;
break;
case VK.LSHIFT:
shiftDown = false;
break;
default:
break;
}
}
else
{
UpdateEasyMouseKeyDown((VK)vkCode);
switch ((VK)vkCode)
{
case VK.LWIN:
case VK.RWIN:
winDown = true;
break;
case VK.LCONTROL:
case VK.RCONTROL:
CtrlDown = true;
break;
case VK.LMENU:
case VK.RMENU:
altDown = true;
break;
case VK.LSHIFT:
shiftDown = true;
break;
case VK.DELETE:
if (CtrlDown && altDown)
{
CtrlDown = altDown = false;
KeyboardEvent(hookCallbackKeybdData);
if (Common.DesMachineID != ID.ALL)
{
Common.SwitchToMachine(Common.MachineName.Trim());
}
/*
#if CUSTOMIZE_LOGON_SCREEN
Common.DoSomethingInUIThread(delegate()
{
Common.MainForm.LoadNewLogonBackground();
});
#endif
* */
}
break;
case VK.ESCAPE:
if (Common.IsTopMostMessageNotNull())
{
Common.HideTopMostMessage();
}
break;
default:
Logger.LogDebug("X");
return ProcessHotKeys(vkCode, hookCallbackKeybdData);
}
}
return true;
}
private void UpdateEasyMouseKeyDown(VK vkCode)
{
EasyMouseOption easyMouseOption = (EasyMouseOption)Setting.Values.EasyMouse;
EasyMouseKeyDown = (easyMouseOption == EasyMouseOption.Ctrl && (vkCode == VK.LCONTROL || vkCode == VK.RCONTROL))
|| (easyMouseOption == EasyMouseOption.Shift && (vkCode == VK.LSHIFT || vkCode == VK.RSHIFT));
}
private static long lastHotKeyLockMachine;
private void ResetModifiersState(HotkeySettings matchingHotkey)
{
CtrlDown = CtrlDown && matchingHotkey.Ctrl;
altDown = altDown && matchingHotkey.Alt;
shiftDown = shiftDown && matchingHotkey.Shift;
winDown = winDown && matchingHotkey.Win;
}
private List GetVkCodesList(HotkeySettings hotkey)
{
var list = new List();
if (hotkey.Alt)
{
list.Add((short)VK.MENU);
}
if (hotkey.Shift)
{
list.Add((short)VK.SHIFT);
}
if (hotkey.Win)
{
list.Add((short)VK.LWIN);
}
if (hotkey.Ctrl)
{
list.Add((short)VK.CONTROL);
}
if (hotkey.Code != 0)
{
list.Add((short)hotkey.Code);
}
return list;
}
private bool ProcessHotKeys(int vkCode, KEYBDDATA hookCallbackKeybdData)
{
if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeySwitch2AllPC))
{
ResetLastSwitchKeys();
Common.SwitchToMultipleMode(Common.DesMachineID != ID.ALL, true);
}
if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeyToggleEasyMouse))
{
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
EasyMouseOption easyMouseOption = (EasyMouseOption)Setting.Values.EasyMouse;
if (easyMouseOption is EasyMouseOption.关闭 or EasyMouseOption.开启)
{
Setting.Values.EasyMouse = (int)(easyMouseOption == EasyMouseOption.关闭 ? EasyMouseOption.开启 : EasyMouseOption.关闭);
Common.ShowToolTip($"易动模式已通过快捷键切换为 [{(EasyMouseOption)Setting.Values.EasyMouse}]. 可以在设置中调整快捷键.", 5000);
return false;
}
}
}
else if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeyLockMachine))
{
if (!Common.RunOnLogonDesktop
&& !Common.RunOnScrSaverDesktop)
{
if (Common.GetTick() - lastHotKeyLockMachine < 500)
{
Common.SwitchToMultipleMode(true, true);
var codes = GetVkCodesList(Setting.Values.HotKeyLockMachine);
foreach (var code in codes)
{
hookCallbackKeybdData.wVk = code;
KeyboardEvent(hookCallbackKeybdData);
}
hookCallbackKeybdData.dwFlags |= (int)Common.LLKHF.UP;
foreach (var code in codes)
{
hookCallbackKeybdData.wVk = code;
KeyboardEvent(hookCallbackKeybdData);
}
Common.SwitchToMultipleMode(false, true);
_ = NativeMethods.LockWorkStation();
}
else
{
KeyboardEvent(hookCallbackKeybdData);
}
lastHotKeyLockMachine = Common.GetTick();
return false;
}
}
else if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeyReconnect))
{
Common.ShowToolTip("正在重新连接...", 2000);
Common.LastReconnectByHotKeyTime = Common.GetTick();
Common.PleaseReopenSocket = Common.REOPEN_WHEN_HOTKEY;
return false;
}
if (CtrlDown && altDown)
{
if (shiftDown && vkCode == Setting.Values.HotKeyExitMM &&
(Common.DesMachineID == Common.MachineID || Common.DesMachineID == ID.ALL))
{
Common.DoSomethingInUIThread(() =>
{
Common.MainForm.NotifyIcon.Visible = false;
for (int i = 1; i < 10; i++)
{
Application.DoEvents();
Thread.Sleep(20);
}
Common.MainForm.Quit(false, false);
});
}
else if (shiftDown || winDown)
{
// The following else cases should work if control and alt modifiers are pressed. The hotkeys should still be captured.
// But if any of the other 2 modifiers (shift or win) are pressed, they hotkeys should not be activated.
// Issue #26597
return true;
}
else if (vkCode == Setting.Values.HotKeySwitchMachine ||
vkCode == Setting.Values.HotKeySwitchMachine + 1 ||
vkCode == Setting.Values.HotKeySwitchMachine + 2 ||
vkCode == Setting.Values.HotKeySwitchMachine + 3)
{
if (Switch2(vkCode - Setting.Values.HotKeySwitchMachine))
{
return false;
}
}
}
return true;
}
private static bool Switch2(int index)
{
if (Common.MachineMatrix != null && Common.MachineMatrix.Length > index)
{
string mcName = Common.MachineMatrix[index].Trim();
if (!string.IsNullOrEmpty(mcName))
{
// Common.DoSomethingInUIThread(delegate()
{
Common.ReleaseAllKeys();
}
// );
Common.SwitchToMachine(mcName);
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Common.ShowToolTip(
string.Format(
CultureInfo.CurrentCulture,
"控制已通过快捷键 Ctrl+Alt+{1}{2} 切换到设备 {0}.",
mcName,
Setting.Values.HotKeySwitchMachine == (int)VK.F1 ? "F" : string.Empty,
index + 1),
3000);
}
return true;
}
}
return false;
}
internal void ResetLastSwitchKeys()
{
CtrlDown = winDown = altDown = false;
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/Program.cs
================================================
// 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.
//
// Application entry and pre-process/initialization.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Drawing.Printing;
using System.Globalization;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Security.Authentication.ExtendedProtection;
using System.Security.Principal;
using System.ServiceModel.Channels;
using System.ServiceProcess;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Telemetry;
using Newtonsoft.Json;
using StreamJsonRpc;
using Logger = MouseWithoutBorders.Core.Logger;
using Thread = MouseWithoutBorders.Core.Thread;
[module: SuppressMessage("Microsoft.MSInternal", "CA904:DeclareTypesInMicrosoftOrSystemNamespace", Scope = "namespace", Target = "MouseWithoutBorders", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1014:MarkAssembliesWithClsCompliant", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", Scope = "member", Target = "MouseWithoutBorders.Program.#Main()", MessageId = "System.String.ToLower", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.Program.#Main()", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders.Class
{
internal static class Program
{
private static readonly string ServiceName = "PowerToys.MWB.Service";
private static readonly string ServiceModeArg = "UseService";
public static bool ShowServiceModeErrorTooltip;
[STAThread]
private static void Main()
{
ManagedCommon.Logger.InitializeLogger("\\MouseWithoutBorders\\Logs");
Logger.Log(Application.ProductName + " Started!");
ETWTrace etwTrace = new ETWTrace();
if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
{
Logger.Log("Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.");
return;
}
Thread.CurrentThread.Name = Application.ProductName + " main thread";
Common.BinaryName = Path.GetFileNameWithoutExtension(Application.ExecutablePath);
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
SecurityIdentifier currentUserSID = currentUser.User;
SecurityIdentifier localSystemSID = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
bool runningAsSystem = currentUserSID.Equals(localSystemSID);
Common.RunWithNoAdminRight = !runningAsSystem;
try
{
string[] args = Environment.GetCommandLineArgs();
string firstArg = string.Empty;
if (args.Length > 1 && args[1] != null)
{
firstArg = args[1].Trim();
}
User = WindowsIdentity.GetCurrent().Name;
Logger.LogDebug("*** Started as " + User);
Logger.Log(Environment.CommandLine);
bool serviceMode = firstArg == ServiceModeArg;
// If we're started from the .dll module or from the service process, we should
// assume the service mode.
if (serviceMode && !runningAsSystem)
{
try
{
var sc = new ServiceController(ServiceName);
sc.Start();
return;
}
catch (Exception ex)
{
Logger.Log("Couldn't start the service. Will try to continue as not a service.");
Logger.Log(ex);
ShowServiceModeErrorTooltip = true;
serviceMode = false;
Setting.Values.UseService = false;
}
}
if (serviceMode || runningAsSystem)
{
if (args.Length > 2)
{
Helper.UserLocalAppDataPath = args[2].Trim();
}
}
ShutdownWithPowerToys.WaitForPowerToysRunner(etwTrace);
if (firstArg != string.Empty)
{
if (Common.CheckSecondInstance(Common.RunWithNoAdminRight))
{
Logger.Log("*** Second instance, exiting...");
return;
}
string myDesktop = Common.GetMyDesktop();
if (firstArg.Equals("winlogon", StringComparison.OrdinalIgnoreCase))
{
// Executed by service, running on logon desktop
Logger.Log("*** Running on " + firstArg + " desktop");
Common.RunOnLogonDesktop = true;
}
else if (args[1].Trim().Equals("default", StringComparison.OrdinalIgnoreCase))
{
Logger.Log("*** Running on " + firstArg + " desktop");
}
else if (args[1].Equals(myDesktop, StringComparison.OrdinalIgnoreCase))
{
Logger.Log("*** Running on " + myDesktop);
if (myDesktop.Equals("Screen-saver", StringComparison.OrdinalIgnoreCase))
{
Common.RunOnScrSaverDesktop = true;
Setting.Values.LastX = Common.JUST_GOT_BACK_FROM_SCREEN_SAVER;
}
}
}
else
{
if (Common.CheckSecondInstance(true))
{
Logger.Log("*** Second instance, exiting...");
return;
}
}
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersStartedEvent());
try
{
Common.CurrentProcess = Process.GetCurrentProcess();
Common.CurrentProcess.PriorityClass = ProcessPriorityClass.RealTime;
}
catch (Exception e)
{
Logger.Log(e);
}
Logger.Log(Environment.OSVersion.ToString());
// Environment.OSVersion is unreliable from 6.2 and up, so just forcefully call the APIs and log the exception unsupported by Windows:
int setProcessDpiAwarenessResult = -1;
try
{
setProcessDpiAwarenessResult = NativeMethods.SetProcessDpiAwareness(2);
Logger.Log(string.Format(CultureInfo.InvariantCulture, "SetProcessDpiAwareness: {0}.", setProcessDpiAwarenessResult));
}
catch (DllNotFoundException)
{
Logger.Log("SetProcessDpiAwareness is unsupported in Windows 7 and lower.");
}
catch (EntryPointNotFoundException)
{
Logger.Log("SetProcessDpiAwareness is unsupported in Windows 7 and lower.");
}
catch (Exception e)
{
Logger.Log(e);
}
try
{
if (setProcessDpiAwarenessResult != 0)
{
Logger.Log(string.Format(CultureInfo.InvariantCulture, "SetProcessDPIAware: {0}.", NativeMethods.SetProcessDPIAware()));
}
}
catch (Exception e)
{
Logger.Log(e);
}
System.Threading.Thread mainUIThread = Thread.CurrentThread;
Common.UIThreadID = mainUIThread.ManagedThreadId;
Thread.UpdateThreads(mainUIThread);
StartInputCallbackThread();
if (!Common.RunOnLogonDesktop)
{
StartSettingSyncThread();
}
Application.EnableVisualStyles();
_ = Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
Application.SetCompatibleTextRenderingDefault(false);
Common.Init();
Common.WndProcCounter++;
var formScreen = new FrmScreen();
Application.Run(formScreen);
etwTrace?.Dispose();
}
catch (Exception e)
{
Logger.Log(e);
}
}
private interface ISettingsSyncHelper
{
[JsonObject(MemberSerialization.OptIn)]
public struct MachineSocketState
{
// Disable false-positive warning due to IPC
#pragma warning disable CS0649
[JsonProperty]
public string Name;
[JsonProperty]
public SocketStatus Status;
#pragma warning restore CS0649
}
void Shutdown();
void Reconnect();
void GenerateNewKey();
void ConnectToMachine(string machineName, string securityKey);
Task RequestMachineSocketStateAsync();
}
private sealed class SettingsSyncHelper : ISettingsSyncHelper
{
public Task RequestMachineSocketStateAsync()
{
var machineStates = new Dictionary();
if (Common.Sk == null || Common.Sk.TcpSockets == null)
{
return Task.FromResult(Array.Empty());
}
foreach (var client in Common.Sk.TcpSockets
.Where(t => t != null && t.IsClient && !string.IsNullOrEmpty(t.MachineName)))
{
var exists = machineStates.TryGetValue(client.MachineName, out var existingStatus);
if (!exists || existingStatus == SocketStatus.NA)
{
machineStates[client.MachineName] = client.Status;
}
}
return Task.FromResult(machineStates.Select((state) => new ISettingsSyncHelper.MachineSocketState { Name = state.Key, Status = state.Value }).ToArray());
}
public void ConnectToMachine(string pcName, string securityKey)
{
Setting.Values.PauseInstantSaving = true;
Common.ClearComputerMatrix();
Setting.Values.MyKey = securityKey;
Common.MyKey = securityKey;
Common.MagicNumber = Common.Get24BitHash(Common.MyKey);
Common.MachineMatrix = new string[Common.MAX_MACHINE] { pcName.Trim().ToUpper(CultureInfo.CurrentCulture), Common.MachineName.Trim(), string.Empty, string.Empty };
string[] machines = Common.MachineMatrix;
Common.MachinePool.Initialize(machines);
Common.UpdateMachinePoolStringSetting();
SocketStuff.InvalidKeyFound = false;
Common.ReopenSocketDueToReadError = true;
Common.ReopenSockets(true);
Common.SendMachineMatrix();
Setting.Values.PauseInstantSaving = false;
Setting.Values.SaveSettings();
}
public void GenerateNewKey()
{
Setting.Values.PauseInstantSaving = true;
Setting.Values.EasyMouse = (int)EasyMouseOption.开启;
Common.ClearComputerMatrix();
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
Common.GeneratedKey = true;
Setting.Values.PauseInstantSaving = false;
Setting.Values.SaveSettings();
Reconnect();
}
public void Reconnect()
{
SocketStuff.InvalidKeyFound = false;
Common.ReopenSocketDueToReadError = true;
Common.ReopenSockets(true);
for (int i = 0; i < 10; i++)
{
if (Common.AtLeastOneSocketConnected())
{
Common.MMSleep(0.5);
break;
}
Common.MMSleep(0.2);
}
Common.SendMachineMatrix();
}
public void Shutdown()
{
Process[] ps = Process.GetProcessesByName("PowerToys.MouseWithoutBorders");
Process me = Process.GetCurrentProcess();
foreach (Process p in ps)
{
if (p.Id != me.Id)
{
p.Kill();
}
}
Common.MainForm.Quit(true, false);
}
}
internal static void StartSettingSyncThread()
{
var serverTaskCancellationSource = new CancellationTokenSource();
CancellationToken cancellationToken = serverTaskCancellationSource.Token;
IpcChannel.StartIpcServer("MouseWithoutBorders/SettingsSync", cancellationToken);
}
internal static void StartInputCallbackThread()
{
Thread inputCallback = new(new ThreadStart(InputCallbackThread), "InputCallback Thread");
inputCallback.SetApartmentState(ApartmentState.STA);
inputCallback.Priority = ThreadPriority.Highest;
inputCallback.Start();
}
private static void InputCallbackThread()
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
Common.InputCallbackThreadID = Thread.CurrentThread.ManagedThreadId;
while (!Common.InitDone)
{
Thread.Sleep(100);
}
Application.Run(new FrmInputCallback());
}
internal static void StartService()
{
if (Common.RunWithNoAdminRight)
{
return;
}
try
{
// Kill all but me
Process me = Process.GetCurrentProcess();
Process[] ps = Process.GetProcessesByName(Common.BinaryName);
foreach (Process pp in ps)
{
if (pp.Id != me.Id)
{
Logger.Log(string.Format(CultureInfo.InvariantCulture, "Killing process {0}.", pp.Id));
pp.KillProcess();
}
}
}
catch (Exception e)
{
Logger.Log(e);
}
Common.StartMouseWithoutBordersService();
}
internal static string User { get; set; }
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs
================================================
// 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.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using MouseWithoutBorders.Core;
//
// Socket code.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Exceptions;
using Thread = MouseWithoutBorders.Core.Thread;
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendData(System.Byte[])", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#Close()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#CreateSocket(System.Boolean)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendData(System.Byte[],MouseWithoutBorders.IP)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendData(System.Object)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendFile(System.Net.Sockets.Socket,System.String)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#MainTCPRoutine(System.Net.Sockets.Socket,System.String)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#TCPServerThread(System.Object)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendClipboardData(System.Object)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#StartNewTcpClient(MouseWithoutBorders.MachineInf)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#StartNewTcpServer(System.Net.Sockets.Socket,System.String)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#UpdateTCPClients()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#UpdateTcpSockets(System.Net.Sockets.Socket,MouseWithoutBorders.SocketStatus)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#.ctor(System.Int32,System.Boolean)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.SocketStuff.#SendData(System.Byte[],MouseWithoutBorders.IP,System.Int32)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Scope = "type", Target = "MouseWithoutBorders.SocketStuff", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders.Class
{
internal enum SocketStatus : int
{
NA = 0,
Resolving = 1,
Connecting = 2,
Handshaking = 3,
Error = 4,
ForceClosed = 5,
InvalidKey = 6,
Timeout = 7,
SendError = 8,
Connected = 9,
}
internal class TcpSk : IDisposable
{
public TcpSk(bool isClient, Socket s, SocketStatus status, string machineName, IPAddress address = null)
{
IsClient = isClient;
BackingSocket = s;
Status = status;
MachineName = machineName;
Address = address;
BirthTime = Common.GetTick();
}
public bool IsClient { get; set; }
public Socket BackingSocket { get; set; }
public SocketStatus Status { get; set; }
public string MachineName { get; set; }
public long BirthTime { get; set; }
public uint MachineId { get; set; }
public IPAddress Address { get; set; }
private Stream encryptedStream;
private Stream decryptedStream;
private Stream socketStream;
public Stream EncryptedStream
{
get
{
if (encryptedStream == null && BackingSocket.Connected)
{
encryptedStream = Common.GetEncryptedStream(new NetworkStream(BackingSocket));
Common.SendOrReceiveARandomDataBlockPerInitialIV(encryptedStream);
}
return encryptedStream;
}
}
public Stream DecryptedStream
{
get
{
if (decryptedStream == null && BackingSocket.Connected)
{
decryptedStream = Common.GetDecryptedStream(new NetworkStream(BackingSocket));
Common.SendOrReceiveARandomDataBlockPerInitialIV(decryptedStream, false);
}
return decryptedStream;
}
}
public Stream SocketStream
{
get
{
if (socketStream == null && BackingSocket.Connected)
{
socketStream = new NetworkStream(BackingSocket);
}
return socketStream;
}
}
public void Dispose()
{
encryptedStream?.Dispose();
decryptedStream?.Dispose();
socketStream?.Dispose();
}
}
internal class SocketStuff
{
private readonly int bASE_PORT;
private TcpServer skClipboardServer;
private TcpServer skMessageServer;
internal object TcpSocketsLock = new();
internal static bool InvalidKeyFound;
internal static bool InvalidKeyFoundOnClientSocket;
internal const int CONNECT_TIMEOUT = 60000;
private static readonly ConcurrentDictionary FailedAttempt = new();
internal List TcpSockets
{
get; private set;
// set { tcpSockets = value; }
}
internal int TcpPort
{
get;
// set { tcpPort = value; }
}
private static bool firstRun;
private readonly long connectTimeout;
private static int restartCount;
internal SocketStuff(int port, bool byUser)
{
Logger.LogDebug("SocketStuff started.");
bASE_PORT = port;
Common.Ran = new Random();
Logger.LogDebug("Validating session...");
if (Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
{
if (Common.DesMachineID != Common.MachineID)
{
Common.SwitchToMultipleMode(false, true);
}
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Common.MainForm.SetTrayIconText("Not physical console session.");
if (byUser)
{
Common.ShowToolTip("非物理控制台会话.", 5000);
}
}
Common.MMSleep(1);
Logger.Log("Not physical console session.");
throw new NotPhysicalConsoleException("Not physical console session.");
}
Logger.LogDebug("Creating socket list and mutex...");
try
{
lock (TcpSocketsLock)
{
TcpSockets = new List();
}
bool dummy1 = Setting.Values.MatrixOneRow; // Reading from reg to variable
dummy1 = Setting.Values.MatrixCircle;
if (Setting.Values.IsMyKeyRandom)
{
Setting.Values.MyKey = Common.MyKey;
}
Common.MagicNumber = Common.Get24BitHash(Common.MyKey);
Common.PackageID = Setting.Values.PackageID;
TcpPort = bASE_PORT;
if (Common.SocketMutex == null)
{
firstRun = true;
Common.SocketMutex = new Mutex(false, $"Global\\{Application.ProductName}-{FrmAbout.AssemblyVersion}-FF7CDABE-1015-0904-1103-24670FA5D16E");
}
Common.AcquireSocketMutex();
}
catch (AbandonedMutexException e)
{
Logger.TelemetryLogTrace($"{nameof(SocketStuff)}: {e.Message}", SeverityLevel.Warning);
}
Common.GetScreenConfig();
if (firstRun && Common.RunOnScrSaverDesktop)
{
firstRun = false;
}
// JUST_GOT_BACK_FROM_SCREEN_SAVER: For bug: monitor does not turn off after logon screen saver exits
else if (!Common.RunOnScrSaverDesktop)
{
if (Setting.Values.LastX == Common.JUST_GOT_BACK_FROM_SCREEN_SAVER)
{
Common.NewDesMachineID = Common.DesMachineID = Common.MachineID;
}
else
{
// Common.Log("Getting IP: " + Setting.Values.DesMachineID.ToString(CultureInfo.CurrentCulture));
Common.LastX = Setting.Values.LastX;
Common.LastY = Setting.Values.LastY;
if (Common.RunOnLogonDesktop && Setting.Values.DesMachineID == (uint)ID.ALL)
{
Common.SwitchToMultipleMode(true, false);
}
else
{
Common.SwitchToMultipleMode(false, false);
}
}
}
connectTimeout = Common.GetTick() + (CONNECT_TIMEOUT / 2);
Exception openSocketErr;
/*
* The machine might be getting a new IP address from its DHCP server
* for ex, when a laptop with a wireless connection just wakes up, might take long time:(
* */
Common.GetMachineName(); // IPs might have been changed
Common.UpdateMachineTimeAndID();
Logger.LogDebug("Creating sockets...");
openSocketErr = CreateSocket();
int sleepSecs = 0, errCode = 0;
if (openSocketErr != null)
{
if (openSocketErr is SocketException)
{
errCode = (openSocketErr as SocketException).ErrorCode;
switch (errCode)
{
case 0: // No error.
break;
case 10048: // WSAEADDRINUSE
sleepSecs = 10;
// It is reasonable to give a try on restarting MwB processes in other sessions.
if (restartCount++ < 5 && Common.IsMyDesktopActive() && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Logger.TelemetryLogTrace("Restarting the service dues to WSAEADDRINUSE.", SeverityLevel.Warning);
Program.StartService();
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
}
break;
case 10049: // WSAEADDRNOTAVAIL
sleepSecs = 1;
break;
default:
sleepSecs = 5;
break;
}
}
else
{
sleepSecs = 10;
}
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
if (byUser)
{
Common.ShowToolTip(errCode.ToString(CultureInfo.CurrentCulture) + ": " + openSocketErr.Message, 5000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
}
}
Common.MMSleep(sleepSecs);
Common.ReleaseSocketMutex();
throw new ExpectedSocketException(openSocketErr.Message);
}
else
{
restartCount = 0;
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
IpcHelper.CreateIpcServer(false);
}
Common.MainForm.UpdateNotifyIcon();
}
}
internal void Close(bool sentWait)
{
try
{
if (!Common.RunOnScrSaverDesktop)
{
Setting.Values.LastX = Common.LastX;
Setting.Values.LastY = Common.LastY;
Setting.Values.PackageID = Common.PackageID;
// Common.Log("Saving IP: " + Setting.Values.DesMachineID.ToString(CultureInfo.CurrentCulture));
Setting.Values.DesMachineID = (uint)Common.DesMachineID;
}
_ = Common.ExecuteAndTrace(
"Closing sockets",
() =>
{
Logger.LogDebug($"Closing socket [{skMessageServer?.Name}].");
skMessageServer?.Close(); // The original ones, not the socket instances produced by the accept() method.
skMessageServer = null;
Logger.LogDebug($"Closing socket [{skClipboardServer?.Name}].");
skClipboardServer?.Close();
skClipboardServer = null;
try
{
// If these sockets are failed to be closed then the tool would not function properly, more logs are added for debugging.
lock (TcpSocketsLock)
{
int c = 0;
if (TcpSockets != null)
{
Logger.LogDebug("********** Closing Sockets: " + TcpSockets.Count.ToString(CultureInfo.InvariantCulture));
List notClosedSockets = new();
foreach (TcpSk t in TcpSockets)
{
if (t != null && t.BackingSocket != null && t.Status != SocketStatus.Resolving)
{
try
{
t.MachineName = "$*NotUsed*$";
t.Status = t.Status >= 0 ? 0 : t.Status - 1;
if (sentWait)
{
t.BackingSocket.Close(1);
}
else
{
t.BackingSocket.Close();
}
c++;
continue;
}
catch (SocketException e)
{
string log = $"Socket.Close error: {e.GetType()}/{e.Message}. This is expected when the socket is already closed by remote host.";
Logger.Log(log);
}
catch (ObjectDisposedException e)
{
string log = $"Socket.Close error: {e.GetType()}/{e.Message}. This is expected when the socket is already disposed.";
Logger.Log(log);
}
catch (Exception e)
{
Logger.Log(e);
}
// If there was an error closing the socket:
if ((int)t.Status > -5)
{
notClosedSockets.Add(t); // Try to give a few times to close the socket later on.
}
}
}
TcpSockets = notClosedSockets;
}
Logger.LogDebug("********** Sockets Closed: " + c.ToString(CultureInfo.CurrentCulture));
}
}
catch (Exception e)
{
Logger.Log(e);
}
},
TimeSpan.FromSeconds(3),
true);
}
catch (Exception e)
{
Logger.Log(e);
}
finally
{
Common.ReleaseSocketMutex();
}
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
try
{
IpcHelper.CreateIpcServer(true);
}
catch (Exception e)
{
Logger.Log(e);
}
}
}
private Exception CreateSocket()
{
try
{
skMessageServer = new TcpServer(TcpPort + 1, new ParameterizedThreadStart(TCPServerThread));
skClipboardServer = new TcpServer(TcpPort, new ParameterizedThreadStart(AcceptConnectionAndSendClipboardData));
}
catch (SocketException e)
{
Logger.Log(e);
return e;
}
catch (Exception e)
{
Logger.Log(e);
return e;
}
Logger.LogDebug("==================================================");
return null;
}
private static int TcpSendData(TcpSk tcp, byte[] bytes)
{
Stream encryptedStream = tcp.EncryptedStream;
if (tcp.BackingSocket == null || !tcp.BackingSocket.Connected || encryptedStream == null)
{
string log = $"{nameof(TcpSendData)}: The socket is no longer connected, it could have been closed by the remote host.";
Logger.Log(log);
throw new ExpectedSocketException(log);
}
bytes[3] = (byte)((Common.MagicNumber >> 24) & 0xFF);
bytes[2] = (byte)((Common.MagicNumber >> 16) & 0xFF);
bytes[1] = 0;
for (int i = 2; i < Common.PACKAGE_SIZE; i++)
{
bytes[1] = (byte)(bytes[1] + bytes[i]);
}
try
{
encryptedStream.Write(bytes, 0, bytes.Length);
}
catch (IOException e)
{
string log = $"{nameof(TcpSendData)}: Exception writing to the socket: {tcp.MachineName}: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
throw e.InnerException is SocketException se ? new ExpectedSocketException(se) : new ExpectedSocketException(log);
}
return bytes.Length;
}
private static void ProcessReceivedDataEx(byte[] buf)
{
int magic;
byte checksum = 0;
magic = (buf[3] << 24) + (buf[2] << 16);
if (magic != (Common.MagicNumber & 0xFFFF0000))
{
Logger.Log("Magic number invalid!");
buf[0] = (byte)PackageType.Invalid;
}
for (int i = 2; i < Common.PACKAGE_SIZE; i++)
{
checksum = (byte)(checksum + buf[i]);
}
if (buf[1] != checksum)
{
Logger.Log("Checksum invalid!");
buf[0] = (byte)PackageType.Invalid;
}
buf[3] = buf[2] = buf[1] = 0;
}
internal static DATA TcpReceiveData(TcpSk tcp, out int bytesReceived)
{
byte[] buf = new byte[Common.PACKAGE_SIZE_EX];
Stream decryptedStream = tcp.DecryptedStream;
if (tcp.BackingSocket == null || !tcp.BackingSocket.Connected || decryptedStream == null)
{
string log = $"{nameof(TcpReceiveData)}: The socket is no longer connected, it could have been closed by the remote host.";
Logger.Log(log);
throw new ExpectedSocketException(log);
}
DATA package;
try
{
bytesReceived = decryptedStream.ReadEx(buf, 0, Common.PACKAGE_SIZE);
if (bytesReceived != Common.PACKAGE_SIZE)
{
buf[0] = bytesReceived == 0 ? (byte)PackageType.Error : (byte)PackageType.Invalid;
}
else
{
ProcessReceivedDataEx(buf);
}
package = new DATA(buf);
if (package.IsBigPackage)
{
bytesReceived = decryptedStream.ReadEx(buf, Common.PACKAGE_SIZE, Common.PACKAGE_SIZE);
if (bytesReceived != Common.PACKAGE_SIZE)
{
buf[0] = bytesReceived == 0 ? (byte)PackageType.Error : (byte)PackageType.Invalid;
}
else
{
package.Bytes = buf;
}
}
}
catch (IOException e)
{
string log = $"{nameof(TcpReceiveData)}: Exception reading from the socket: {tcp.MachineName}: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
throw e.InnerException is SocketException se ? new ExpectedSocketException(se) : new ExpectedSocketException(log);
}
return package;
}
private static void PreProcessData(PackageType type)
{
switch (type)
{
case PackageType.Keyboard:
Common.PackageSent.Keyboard++;
break;
case PackageType.Mouse:
Common.PackageSent.Mouse++;
break;
case PackageType.Heartbeat:
case PackageType.Heartbeat_ex:
Common.PackageSent.Heartbeat++;
break;
case PackageType.Hello:
Common.PackageSent.Hello++;
break;
case PackageType.ByeBye:
Common.PackageSent.ByeBye++;
break;
case PackageType.Matrix:
Common.PackageSent.Matrix++;
break;
default:
byte subtype = (byte)((uint)type & 0x000000FF);
switch (subtype)
{
case (byte)PackageType.ClipboardText:
Common.PackageSent.ClipboardText++;
break;
case (byte)PackageType.ClipboardImage:
Common.PackageSent.ClipboardImage++;
break;
default:
// Common.Log("Send: Other type (1-17)");
break;
}
break;
}
}
internal int TcpSend(TcpSk tcp, DATA data)
{
PreProcessData(data.Type);
if (data.Src == ID.NONE)
{
data.Src = Common.MachineID;
}
byte[] dataAsBytes = data.Bytes;
int rv = TcpSendData(tcp, dataAsBytes);
if (rv < dataAsBytes.Length)
{
Logger.Log("TcpSend error! Length of sent data is unexpected.");
UpdateTcpSockets(tcp, SocketStatus.SendError);
throw new SocketException((int)SocketStatus.SendError);
}
return rv;
}
private void TCPServerThread(object param)
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
try
{
TcpListener server = param as TcpListener;
do
{
Logger.LogDebug("TCPServerThread: Waiting for request...");
Socket s = server.AcceptSocket();
_ = Task.Run(() =>
{
try
{
AddSocket(s);
}
catch (Exception e)
{
Logger.Log(e);
}
});
}
while (true);
}
catch (InvalidOperationException e)
{
string log = $"TCPServerThread.AcceptSocket: The server socket could have been closed. {e.Message}";
Logger.Log(log);
}
catch (SocketException e)
{
if (e.ErrorCode == (int)SocketError.Interrupted)
{
Logger.Log("TCPServerThread.AcceptSocket: A blocking socket call was canceled.");
}
else
{
Logger.Log(e);
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
private static string GetMachineNameFromSocket(Socket socket)
{
string stringIP = socket.RemoteEndPoint.ToString();
string name = null;
try
{
// Remote machine has IP changed, update it.
name = Dns.GetHostEntry((socket.RemoteEndPoint as IPEndPoint).Address).HostName;
}
catch (SocketException e)
{
Logger.Log($"{nameof(GetMachineNameFromSocket)}: {e.Message}");
return stringIP;
}
// Remove the domain part.
if (!string.IsNullOrEmpty(name))
{
int dotPos = name.IndexOf('.');
if (dotPos > 0)
{
Logger.LogDebug("Removing domain part from the full machine name: {0}.", name);
name = name[..dotPos];
}
}
return string.IsNullOrEmpty(name) ? stringIP : name;
}
private void AddSocket(Socket s)
{
string machineName = GetMachineNameFromSocket(s);
Logger.Log($"New connection from client: [{machineName}].");
TcpSk tcp = AddTcpSocket(false, s, SocketStatus.Connecting, machineName);
StartNewTcpServer(tcp, machineName);
}
private void StartNewTcpServer(TcpSk tcp, string machineName)
{
void ServerThread()
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
try
{
// Receiving packages
MainTCPRoutine(tcp, machineName, false);
}
catch (Exception e)
{
Logger.Log(e);
}
}
Thread t = new(ServerThread, "TCP Server Thread " + tcp.BackingSocket.LocalEndPoint.ToString() + " : " + machineName);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
internal void UpdateTCPClients()
{
if (InvalidKeyFound)
{
return;
}
Logger.LogDebug("!!!!! UpdateTCPClients !!!!!");
try
{
if (Common.MachineMatrix != null)
{
Logger.LogDebug("MachineMatrix = " + string.Join(", ", Common.MachineMatrix));
foreach (string st in Common.MachineMatrix)
{
string machineName = st.Trim();
if (!string.IsNullOrEmpty(machineName) &&
!machineName.Equals(Common.MachineName.Trim(), StringComparison.OrdinalIgnoreCase))
{
bool found = false;
found = Common.IsConnectedByAClientSocketTo(machineName);
if (found)
{
Logger.LogDebug(machineName + " is already connected! ^^^^^^^^^^^^^^^^^^^^^");
continue;
}
StartNewTcpClient(machineName);
}
}
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
private static readonly Dictionary> BadIPs = new();
private static readonly Lock BadIPsLock = new();
private static bool IsBadIP(string machineName, IPAddress ip)
{
lock (BadIPsLock)
{
return BadIPs.ContainsKey(machineName) && BadIPs.TryGetValue(machineName, out List ips) && ips.Contains(ip);
}
}
private static void AddBadIP(string machineName, IPAddress ip)
{
if (!IsBadIP(machineName, ip))
{
lock (BadIPsLock)
{
List ips;
if (BadIPs.ContainsKey(machineName))
{
_ = BadIPs.TryGetValue(machineName, out ips);
}
else
{
ips = new List();
BadIPs.Add(machineName, ips);
}
ips.Add(ip);
}
}
}
internal static void ClearBadIPs()
{
lock (BadIPsLock)
{
if (BadIPs.Count > 0)
{
BadIPs.Clear();
}
}
}
internal void StartNewTcpClient(string machineName)
{
void ClientThread(object obj)
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
IPHostEntry host;
bool useName2IP = false;
List validAddresses = new();
List validatedAddresses = new();
string validAddressesSt = string.Empty;
// Add a dummy socket to show the status.
Socket dummySocket = new(AddressFamily.Unspecified, SocketType.Stream, ProtocolType.Tcp);
TcpSk dummyTcp = AddTcpSocket(true, dummySocket, SocketStatus.Resolving, machineName);
Logger.LogDebug("Connecting to: " + machineName);
if (!string.IsNullOrEmpty(Setting.Values.Name2IP))
{
string combinedName2ipList = Setting.Values.Name2IpPolicyList + Separator + Setting.Values.Name2IP;
string[] name2ip = combinedName2ipList.Split(Separator, StringSplitOptions.RemoveEmptyEntries);
string[] nameNip;
if (name2ip != null)
{
foreach (string st in name2ip)
{
nameNip = st.Split(BlankSeparator, StringSplitOptions.RemoveEmptyEntries);
if (nameNip != null && nameNip.Length >= 2 && nameNip[0].Trim().Equals(machineName, StringComparison.OrdinalIgnoreCase)
&& IPAddress.TryParse(nameNip[1].Trim(), out IPAddress ip) && !validAddressesSt.Contains("[" + ip.ToString() + "]")
)
{
validatedAddresses.Add(ip);
validAddressesSt += "[" + ip.ToString() + "]";
}
}
}
if (validatedAddresses.Count > 0)
{
useName2IP = true;
Logger.LogDebug("Using both user-defined Name-to-IP mappings and DNS result for " + machineName);
Common.ShowToolTip("为 " + machineName + " 同时使用用户自定义 IP 映射和 DNS 结果", 3000, ToolTipIcon.Info, false);
if (!CheckForSameSubNet(validatedAddresses, machineName))
{
return;
}
foreach (IPAddress vip in validatedAddresses)
{
StartNewTcpClientThread(machineName, vip);
}
validatedAddresses.Clear();
}
}
try
{
host = Dns.GetHostEntry(machineName);
}
catch (SocketException e)
{
host = null;
UpdateTcpSockets(dummyTcp, SocketStatus.Timeout);
Common.ShowToolTip(e.Message + ": " + machineName, 10000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
Logger.Log($"{nameof(StartNewTcpClient)}.{nameof(Dns.GetHostEntry)}: {e.Message}");
}
UpdateTcpSockets(dummyTcp, SocketStatus.NA);
if (!Common.InMachineMatrix(machineName))
{
// While Resolving from name to IP, user may have changed the machine name and clicked on Apply.
return;
}
if (host != null)
{
string ipLog = string.Empty;
foreach (IPAddress ip in host.AddressList)
{
ipLog += "<" + ip.ToString() + ">";
if ((ip.AddressFamily == AddressFamily.InterNetwork || ip.AddressFamily == AddressFamily.InterNetworkV6) && !validAddressesSt.Contains("[" + ip.ToString() + "]"))
{
validAddresses.Add(ip);
validAddressesSt += "[" + ip.ToString() + "]";
}
}
Logger.LogDebug(machineName + ipLog);
}
if (validAddresses.Count > 0)
{
if (!Setting.Values.ReverseLookup)
{
validatedAddresses = validAddresses;
ClearBadIPs();
}
else
{
foreach (IPAddress ip in validAddresses)
{
if (IsBadIP(machineName, ip))
{
Logger.Log($"Skip bad IP address: {ip}");
continue;
}
try
{
// Reverse lookup to validate the IP Address.
string hn = Dns.GetHostEntry(ip).HostName;
if (hn.StartsWith(machineName, StringComparison.CurrentCultureIgnoreCase) || hn.Equals(ip.ToString(), StringComparison.OrdinalIgnoreCase))
{
validatedAddresses.Add(ip);
}
else
{
Logger.Log($"DNS information of machine not matched: {machineName} => {ip} => {hn}.");
AddBadIP(machineName, ip);
}
}
catch (SocketException se)
{
Logger.Log($"{nameof(StartNewTcpClient)}: DNS information of machine not matched: {machineName} => {ip} => {se.Message}.");
AddBadIP(machineName, ip);
}
catch (ArgumentException ae)
{
Logger.Log($"{nameof(StartNewTcpClient)}: DNS information of machine not matched: {machineName} => {ip} => {ae.Message}.");
AddBadIP(machineName, ip);
}
}
}
}
if (validatedAddresses.Count > 0)
{
if (!CheckForSameSubNet(validatedAddresses, machineName))
{
return;
}
foreach (IPAddress ip in validatedAddresses)
{
StartNewTcpClientThread(machineName, ip);
}
}
else
{
Logger.Log("Cannot resolve IPv4 Addresses of machine: " + machineName);
if (!useName2IP)
{
Common.ShowToolTip($"无法解析对方电脑的 IP 地址: {machineName}.\r\n请解决 DNS 问题,或者手动设置 IP 地址映射.", 10000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
}
}
}
Thread t = new(
ClientThread, "StartNewTcpClient." + machineName);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private bool CheckForSameSubNet(List validatedAddresses, string machineName)
{
if (!Setting.Values.SameSubNetOnly)
{
return true;
}
// Only support if IPv4 addresses found in both.
IEnumerable remoteIPv4Addresses = validatedAddresses.Where(addr => addr?.AddressFamily == AddressFamily.InterNetwork);
if (!remoteIPv4Addresses.Any())
{
Logger.Log($"No IPv4 resolved from the remote machine: {machineName}.");
return true;
}
List localIPv4Addresses = GetMyIPv4Addresses().ToList();
if (localIPv4Addresses.Count == 0)
{
Logger.Log($"No IPv4 resolved from the local machine: {Common.MachineName}");
return true;
}
foreach (IPAddress remote in remoteIPv4Addresses)
{
foreach (IPAddress local in localIPv4Addresses)
{
byte[] myIPAddressBytes = local.GetAddressBytes();
byte[] yourIPAddressBytes = remote.GetAddressBytes();
// Same WAN?
if (myIPAddressBytes[0] == yourIPAddressBytes[0] && myIPAddressBytes[1] == yourIPAddressBytes[1])
{
return true;
}
}
}
Logger.Log($"Skip machine not in the same network: {machineName}.");
return false;
}
private IEnumerable GetMyIPv4Addresses()
{
try
{
IEnumerable ip4addresses = NetworkInterface.GetAllNetworkInterfaces()?
.Where(networkInterface =>
(networkInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet || networkInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
&& networkInterface.OperationalStatus == OperationalStatus.Up)
.SelectMany(ni => ni?.GetIPProperties()?.UnicastAddresses.Select(uni => uni?.Address))
.Where(addr => addr?.AddressFamily == AddressFamily.InterNetwork);
return ip4addresses;
}
catch (Exception e)
{
Logger.Log(e);
return Enumerable.Empty();
}
}
private void StartNewTcpClientThread(string machineName, IPAddress ip)
{
void NewTcpClient()
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
TcpClient tcpClient = null;
try
{
tcpClient = new TcpClient(AddressFamily.InterNetworkV6);
tcpClient.Client.DualMode = true;
if (Common.IsConnectedByAClientSocketTo(machineName))
{
Logger.LogDebug(machineName + " is already connected by another client socket.");
return;
}
if (Common.IsConnectingByAClientSocketTo(machineName, ip))
{
Logger.LogDebug($"{machineName}:{ip} is already being connected by another client socket.");
return;
}
TcpSk tcp = AddTcpSocket(true, tcpClient.Client, SocketStatus.Connecting, machineName, ip);
// Update the other server socket's machine name based on this corresponding client socket.
UpdateTcpSockets(tcp, SocketStatus.Connecting);
Logger.LogDebug(string.Format(CultureInfo.CurrentCulture, "=====> Connecting to: {0}:{1}", machineName, ip.ToString()));
long timeoutLeft;
do
{
try
{
tcpClient.Connect(ip, TcpPort + 1);
}
catch (ObjectDisposedException)
{
// When user reconnects.
Logger.LogDebug($"tcpClient.Connect: The socket has already been disposed: {machineName}:{ip}");
return;
}
catch (SocketException e)
{
timeoutLeft = connectTimeout - Common.GetTick();
if (timeoutLeft > 0)
{
Logger.LogDebug($"tcpClient.Connect: {timeoutLeft}: {e.Message}");
Thread.Sleep(1000);
continue;
}
else
{
Logger.Log($"tcpClient.Connect: Unable to connect after a timeout: {machineName}:{ip} : {e.Message}");
string message = $"连接超时: {machineName}:{ip}";
Common.ShowToolTip(message, 5000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
UpdateTcpSockets(tcp, SocketStatus.Timeout);
return;
}
}
break;
}
while (true);
Logger.LogDebug($"=====> Connected: {tcpClient.Client.LocalEndPoint} => {machineName}: {ip}");
// Sending/Receiving packages
MainTCPRoutine(tcp, machineName, true);
}
catch (ObjectDisposedException e)
{
Logger.Log($"{nameof(StartNewTcpClientThread)}: The socket could have been closed/disposed due to machine switch: {e.Message}");
}
catch (SocketException e)
{
// DHCP error, etc.
string localIP = tcpClient?.Client?.LocalEndPoint?.ToString();
if (localIP != null && (localIP.StartsWith("169.254", StringComparison.InvariantCulture) || localIP.ToString().StartsWith("0.0", StringComparison.InvariantCulture)))
{
Common.ShowToolTip($"错误: 该机器对于 [{localIP}] 的连接性有限.", 5000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
}
else
{
Logger.TelemetryLogTrace($"{nameof(StartNewTcpClientThread)}: Error: {e.Message} on the IP Address: {localIP}", SeverityLevel.Error);
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
Thread t = new(NewTcpClient, "TCP Client Thread " + machineName + " " + ip.ToString());
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
private void FlagReopenSocketIfNeeded(Exception e)
{
/* SCENARIO: MachineA has MM blocked by firewall but MachineA can connect to MachineB so the tool would work normally (MM is not blocked by firewall in MachineB).
* 1. a connection from A to B is working. Mouse/Keyboard is connected to A.
* 2. User moves Mouse to B and lock B by Ctrl+Alt+L.
* 3. B closes all sockets before switches to logon desktop. The client socket in A gets reset by B (the only connection between A and B).
* 4. B is now on the logon desktop and tries to connect to A, connection fails since it is block by firewall in A.
* 5. When the client socket gets reset in A, it should retry to connect to B => this is the fix implemented by few lines of code below.
* */
// WSAECONNRESET
if (e is ExpectedSocketException se && se.ShouldReconnect)
{
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
Logger.Log($"MainTCPRoutine: {nameof(FlagReopenSocketIfNeeded)}");
}
}
private long lastRemoteMachineID;
internal static readonly string[] Separator = new string[] { "\r\n" };
internal static readonly char[] BlankSeparator = new char[] { ' ' };
private void MainTCPRoutine(TcpSk tcp, string machineName, bool isClient)
{
int packageCount = 0;
DATA d;
string remoteMachine = string.Empty;
string strIP = string.Empty;
ID remoteID = ID.NONE;
byte[] buf = RandomNumberGenerator.GetBytes(Common.PACKAGE_SIZE_EX);
d = new DATA(buf);
TcpSk currentTcp = tcp;
Socket currentSocket = currentTcp.BackingSocket;
if (currentSocket == null)
{
Logger.LogDebug($"{nameof(MainTCPRoutine)}: The socket could have been closed/disposed by other threads.");
return;
}
try
{
currentSocket.SendBufferSize = Common.PACKAGE_SIZE * 10000;
currentSocket.ReceiveBufferSize = Common.PACKAGE_SIZE * 10000;
currentSocket.NoDelay = true; // This is very interesting to know:(
currentSocket.SendTimeout = 500;
d.MachineName = Common.MachineName;
d.Type = PackageType.Handshake;
for (int i = 0; i < 10; i++)
{
_ = TcpSend(currentTcp, d);
}
d.Machine1 = ~d.Machine1;
d.Machine2 = ~d.Machine2;
d.Machine3 = ~d.Machine3;
d.Machine4 = ~d.Machine4;
UpdateTcpSockets(currentTcp, SocketStatus.Handshaking);
strIP = Common.GetRemoteStringIP(currentSocket, true);
remoteMachine = string.IsNullOrEmpty(machineName) ? GetMachineNameFromSocket(currentSocket) : machineName;
Logger.LogDebug($"MainTCPRoutine: Remote machineName/IP = {remoteMachine}/{strIP}");
}
catch (ObjectDisposedException e)
{
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
UpdateTcpSockets(currentTcp, SocketStatus.ForceClosed);
currentSocket.Close();
Logger.Log($"{nameof(MainTCPRoutine)}: The socket could have been closed/disposed by other threads: {e.Message}");
}
catch (Exception e)
{
UpdateTcpSockets(currentTcp, SocketStatus.ForceClosed);
FlagReopenSocketIfNeeded(e);
currentSocket.Close();
Logger.Log(e);
}
int errCount = 0;
while (true)
{
try
{
DATA package = TcpReceiveData(currentTcp, out int receivedCount);
remoteID = package.Src;
if (package.Type == PackageType.Error)
{
errCount++;
string log = $"{nameof(MainTCPRoutine)}.TcpReceive error, invalid package from {remoteMachine}: {receivedCount}";
Logger.Log(log);
if (receivedCount > 0)
{
Common.ShowToolTip($"来自 {remoteMachine} 的数据包无效. 请确保连接密码一致.", 5000, ToolTipIcon.Warning, false);
}
if (errCount > 5)
{
Common.MMSleep(1);
UpdateTcpSockets(currentTcp, SocketStatus.Error);
currentSocket.Close();
/*
* Sometimes when the peer machine closes the connection, we do not actually get an exception.
* Socket status is still connected and a read on the socket stream returns 0 byte.
* In this case, we should give ONE try to reconnect.
*/
if (Common.ReopenSocketDueToReadError)
{
Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;
Common.ReopenSocketDueToReadError = false;
}
break;
}
}
else
{
errCount = 0;
}
if (package.Type == PackageType.Handshake)
{
// Common.Log("Got a Handshake signal!");
package.Type = PackageType.HandshakeAck;
package.Src = ID.NONE;
package.MachineName = Common.MachineName;
package.Machine1 = ~package.Machine1;
package.Machine2 = ~package.Machine2;
package.Machine3 = ~package.Machine3;
package.Machine4 = ~package.Machine4;
_ = TcpSend(currentTcp, package);
}
else
{
if (packageCount >= 0)
{
if (++packageCount >= 10)
{
// Common.ShowToolTip("Invalid Security Key from " + remoteMachine, 5000);
Logger.Log("More than 10 invalid packages received!");
package.Type = PackageType.Invalid;
for (int i = 0; i < 10; i++)
{
_ = TcpSend(currentTcp, package);
}
Common.MMSleep(2);
UpdateTcpSockets(currentTcp, SocketStatus.InvalidKey);
currentSocket.Close();
break;
}
else if (package.Type == PackageType.HandshakeAck)
{
if (package.Machine1 == d.Machine1 && package.Machine2 == d.Machine2 &&
package.Machine3 == d.Machine3 && package.Machine4 == d.Machine4)
{
string claimedMachineName = package.MachineName;
if (!remoteMachine.Equals(claimedMachineName, StringComparison.Ordinal))
{
Logger.LogDebug($"DNS.RemoteMachineName({remoteMachine}) <> Claimed.MachineName({claimedMachineName}), using the claimed machine name.");
remoteMachine = claimedMachineName;
currentTcp.MachineName = remoteMachine;
}
// Double check to avoid a redundant client socket.
if (isClient && Common.IsConnectedByAClientSocketTo(remoteMachine))
{
Logger.LogDebug("=====> Duplicate connected client socket for: " + remoteMachine + ":" + strIP + " is being removed.");
UpdateTcpSockets(currentTcp, SocketStatus.ForceClosed);
currentSocket.Close();
return;
}
if (remoteMachine.Equals(Common.MachineName, StringComparison.OrdinalIgnoreCase))
{
Logger.LogDebug("Connected to/from local socket: " + strIP + (isClient ? "-Client" : "-Server"));
UpdateTcpSockets(currentTcp, SocketStatus.NA);
Common.MMSleep(1);
currentSocket.Close();
return;
}
packageCount = -1; // Trusted
InvalidKeyFound = false;
currentTcp.MachineId = (uint)remoteID;
currentTcp.Status = SocketStatus.Connected;
UpdateTcpSockets(currentTcp, SocketStatus.Connected);
Logger.LogDebug("))))))))))))))) Machine got trusted: " + remoteMachine + ":" + strIP + ", Is client: " + isClient);
if (Math.Abs(Common.GetTick() - Common.LastReconnectByHotKeyTime) < 5000)
{
Common.ShowToolTip("已连接 " + remoteMachine, 1000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);
}
Common.SendHeartBeat(initial: true);
if (Common.MachinePool.TryFindMachineByName(remoteMachine, out MachineInf machineInfo))
{
Logger.LogDebug("Machine updated: " + remoteMachine + "/" + remoteID.ToString());
if (machineInfo.Name.Equals(Common.DesMachineName, StringComparison.OrdinalIgnoreCase))
{
Logger.LogDebug("Des ID updated: " + Common.DesMachineID.ToString() +
"/" + remoteID.ToString());
Common.NewDesMachineID = Common.DesMachineID = remoteID;
}
_ = Common.MachinePool.TryUpdateMachineID(remoteMachine, remoteID, true);
Common.UpdateMachinePoolStringSetting();
}
else
{
Logger.LogDebug("New machine connected: {0}.", remoteMachine);
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Common.ShowToolTip("已建立新连接 " + remoteMachine, 1000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);
}
}
if (!isClient)
{
Common.UpdateClientSockets("MainTCPRoutine");
}
}
else
{
Logger.LogDebug("Invalid ACK from " + remoteMachine);
UpdateTcpSockets(currentTcp, SocketStatus.InvalidKey);
string remoteEP = currentSocket.RemoteEndPoint.ToString();
if (FailedAttempt.AddOrUpdate(remoteEP, 1, (key, value) => value + 1) > 10)
{
_ = FailedAttempt.AddOrUpdate(remoteEP, 0, (key, value) => 0);
_ = MessageBox.Show($"来自 [{remoteEP}] 的连接尝试次数过多!\r\n重启软件后再试.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
Common.MainForm.Quit(true, false);
}
currentSocket.Close();
break;
}
}
else if (package.Type == PackageType.Mouse)
{
if (packageCount > 5)
{
packageCount--;
}
}
else if (package.Type is PackageType.Heartbeat or PackageType.Heartbeat_ex)
{
if (packageCount > 5)
{
packageCount--;
}
}
else
{
if (packageCount > 5)
{
UpdateTcpSockets(currentTcp, SocketStatus.InvalidKey);
}
else
{
Logger.Log(string.Format(
CultureInfo.CurrentCulture,
"Unexpected package, size = {0}, type = {1}",
receivedCount,
package.Type));
}
}
}
else if (receivedCount > 0)
{
// Add some log when remote machine switches.
if (lastRemoteMachineID != (long)remoteID)
{
_ = Interlocked.Exchange(ref lastRemoteMachineID, (long)remoteID);
Logger.LogDebug($"MainTCPRoutine: Remote machine = {strIP}/{lastRemoteMachineID}");
}
if (package.Type == PackageType.HandshakeAck)
{
Logger.LogDebug("Skipping the rest of the Handshake packages.");
}
else
{
Receiver.ProcessPackage(package, currentTcp);
}
}
}
}
catch (Exception e)
{
UpdateTcpSockets(currentTcp, SocketStatus.Error);
FlagReopenSocketIfNeeded(e);
currentSocket.Close();
Logger.Log(e);
break;
}
}
if (remoteID != ID.NONE)
{
_ = Common.RemoveDeadMachines(remoteID);
}
}
private static void AcceptConnectionAndSendClipboardData(object param)
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
TcpListener server = param as TcpListener;
do
{
Logger.LogDebug("SendClipboardData: Waiting for request...");
Socket s = null;
try
{
s = server.AcceptSocket();
}
catch (InvalidOperationException e)
{
Logger.Log($"The clipboard socket could have been closed. {e.Message}");
break;
}
catch (SocketException e)
{
if (e.ErrorCode == (int)SocketError.Interrupted)
{
Logger.Log("server.AcceptSocket: A blocking socket call was canceled.");
continue;
}
else
{
Logger.Log(e);
break;
}
}
catch (Exception e)
{
Logger.Log(e);
break;
}
if (s != null)
{
try
{
new Task(() =>
{
// SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.
// More details can be found on: https://github.com/microsoft/PowerToys/pull/36892
using var asyncFlowControl = ExecutionContext.SuppressFlow();
System.Threading.Thread thread = Thread.CurrentThread;
thread.Name = $"{nameof(SendOrReceiveClipboardData)}.{thread.ManagedThreadId}";
Thread.UpdateThreads(thread);
SendOrReceiveClipboardData(s);
}).Start();
}
catch (Exception e)
{
Logger.Log(e);
}
}
}
while (true);
}
internal static void SendOrReceiveClipboardData(Socket s)
{
try
{
string remoteEndPoint = s.RemoteEndPoint.ToString();
Logger.LogDebug("SendClipboardData: Request accepted: " + s.LocalEndPoint.ToString() + "/" + remoteEndPoint);
Common.IsDropping = false;
Common.IsDragging = false;
Common.DragMachine = (ID)1;
bool clientPushData = true;
ClipboardPostAction postAction = ClipboardPostAction.Other;
bool handShaken = Common.ShakeHand(ref remoteEndPoint, s, out Stream enStream, out Stream deStream, ref clientPushData, ref postAction);
if (!handShaken)
{
s.Close();
return;
}
else
{
Logger.LogDebug($"{nameof(SendOrReceiveClipboardData)}: Clipboard connection accepted: " + remoteEndPoint);
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE] { Common.ICON_SMALL_CLIPBOARD, -1, -1, -1 });
}
if (clientPushData)
{
Common.ReceiveAndProcessClipboardData(remoteEndPoint, s, enStream, deStream, $"{postAction}");
}
else
{
SendClipboardData(s, enStream);
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
internal static void SendClipboardData(Socket s, Stream ecStream)
{
if (Common.RunWithNoAdminRight && Setting.Values.OneWayClipboardMode)
{
s?.Close();
return;
}
const int CLOSE_TIMEOUT = 10;
byte[] header = new byte[1024];
string headerString = string.Empty;
if (Common.LastDragDropFile != null)
{
string fileName = null;
if (!Common.ImpersonateLoggedOnUserAndDoSomething(() =>
{
if (!File.Exists(Common.LastDragDropFile))
{
headerString = Directory.Exists(Common.LastDragDropFile)
? $"{0}*{Common.LastDragDropFile} - Folder is not supported, zip it first!"
: Common.LastDragDropFile.Contains("- File too big")
? $"{0}*{Common.LastDragDropFile}"
: $"{0}*{Common.LastDragDropFile} not found!";
}
else
{
fileName = Common.LastDragDropFile;
headerString = $"{new FileInfo(fileName).Length}*{fileName}";
}
}))
{
s?.Close();
return;
}
Common.GetBytesU(headerString).CopyTo(header, 0);
try
{
ecStream.Write(header, 0, header.Length);
if (!string.IsNullOrEmpty(fileName))
{
if (SendFile(s, ecStream, fileName))
{
s.Close(CLOSE_TIMEOUT);
}
}
else
{
s.Close(CLOSE_TIMEOUT);
}
}
catch (IOException e)
{
string log = $"{nameof(SendClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
}
catch (SocketException e)
{
string log = $"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.";
Logger.Log(log);
}
catch (ObjectDisposedException e)
{
string log = $"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..";
Logger.Log(log);
}
}
else if (!Common.IsClipboardDataImage && Common.LastClipboardData != null)
{
try
{
byte[] data = Common.LastClipboardData;
headerString = $"{data.Length}*{"text"}";
Common.GetBytesU(headerString).CopyTo(header, 0);
if (data != null)
{
ecStream.Write(header, 0, header.Length);
_ = SendData(s, ecStream, data);
Logger.LogDebug("Text sent: " + data.Length.ToString(CultureInfo.CurrentCulture));
}
s.Close(CLOSE_TIMEOUT);
}
catch (IOException e)
{
string log = $"{nameof(SendClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
}
catch (SocketException e)
{
string log = $"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.";
Logger.Log(log);
}
catch (ObjectDisposedException e)
{
string log = $"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..";
Logger.Log(log);
}
}
else if (Common.LastClipboardData != null && Common.LastClipboardData.Length > 0)
{
byte[] data = Common.LastClipboardData;
headerString = $"{data.Length}*{"image"}";
Common.GetBytesU(headerString).CopyTo(header, 0);
try
{
ecStream.Write(header, 0, header.Length);
_ = SendData(s, ecStream, data);
Logger.LogDebug("Image sent: " + data.Length.ToString(CultureInfo.CurrentCulture));
s.Close(CLOSE_TIMEOUT);
}
catch (IOException e)
{
string log = $"{nameof(SendClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
}
catch (SocketException e)
{
string log = $"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.";
Logger.Log(log);
}
catch (ObjectDisposedException e)
{
string log = $"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..";
Logger.Log(log);
}
}
else
{
Logger.Log("No data available in clipboard or LastDragDropFile!");
s.Close();
}
}
private static bool SendFileEx(Socket s, Stream ecStream, string fileName)
{
try
{
using (FileStream f = File.OpenRead(fileName))
{
byte[] buf = new byte[Common.NETWORK_STREAM_BUF_SIZE];
int rv, sentCount = 0;
do
{
if ((rv = f.Read(buf, 0, Common.NETWORK_STREAM_BUF_SIZE)) > 0)
{
ecStream.Write(buf, 0, rv);
sentCount += rv;
}
}
while (rv > 0);
if ((rv = Common.PACKAGE_SIZE - (sentCount % Common.PACKAGE_SIZE)) > 0)
{
Array.Clear(buf, 0, buf.Length);
ecStream.Write(buf, 0, rv);
}
ecStream.Flush();
Logger.LogDebug("File sent: " + fileName);
}
return true;
}
catch (Exception e)
{
if (e is IOException)
{
string log = $"{nameof(SendFileEx)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
}
else
{
Logger.Log(e);
}
Common.ShowToolTip(e.Message, 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
s.Close();
}
return false;
}
private static bool SendFile(Socket s, Stream ecStream, string fileName)
{
bool r = false;
if (Common.RunOnLogonDesktop || Common.RunOnScrSaverDesktop)
{
if (fileName.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\" + Common.BinaryName + @"\ScreenCaptures\", StringComparison.CurrentCultureIgnoreCase))
{
r = SendFileEx(s, ecStream, fileName);
}
}
else
{
_ = Common.ImpersonateLoggedOnUserAndDoSomething(() => { r = SendFileEx(s, ecStream, fileName); });
}
return r;
}
private static bool SendData(Socket s, Stream ecStream, byte[] data)
{
bool r = false;
try
{
using MemoryStream f = new(data);
byte[] buf = new byte[Common.NETWORK_STREAM_BUF_SIZE];
int rv, sentCount = 0;
do
{
if ((rv = f.Read(buf, 0, Common.NETWORK_STREAM_BUF_SIZE)) > 0)
{
ecStream.Write(buf, 0, rv);
sentCount += rv;
}
}
while (rv > 0);
if ((rv = sentCount % Common.PACKAGE_SIZE) > 0)
{
Array.Clear(buf, 0, buf.Length);
ecStream.Write(buf, 0, rv);
}
ecStream.Flush();
Logger.LogDebug("Data sent: " + data.Length.ToString(CultureInfo.InvariantCulture));
r = true;
}
catch (Exception e)
{
if (e is IOException)
{
string log = $"{nameof(SendData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)";
Logger.Log(log);
}
else
{
Logger.Log(e);
}
Common.ShowToolTip(e.Message, 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);
ecStream.Close();
s.Close();
}
return r;
}
private TcpSk AddTcpSocket(bool isClient, Socket s, SocketStatus status, string machineName)
{
Common.CloseAnUnusedSocket();
TcpSk tcp = new(isClient, s, status, machineName);
lock (TcpSocketsLock)
{
#if ENABLE_LEGACY_DOS_PROTECTION
PreventDoS(TcpSockets);
#endif
TcpSockets.Add(tcp);
}
return tcp;
}
private TcpSk AddTcpSocket(bool isClient, Socket s, SocketStatus status, string machineName, IPAddress ip)
{
Common.CloseAnUnusedSocket();
TcpSk tcp = new(isClient, s, status, machineName, ip);
lock (TcpSocketsLock)
{
#if ENABLE_LEGACY_DOS_PROTECTION
PreventDoS(TcpSockets);
#endif
TcpSockets.Add(tcp);
}
return tcp;
}
private void UpdateTcpSockets(TcpSk tcp, SocketStatus status)
{
if (status == SocketStatus.InvalidKey)
{
InvalidKeyFound = true;
}
InvalidKeyFoundOnClientSocket = tcp.IsClient && InvalidKeyFound;
try
{
lock (TcpSocketsLock)
{
if (TcpSockets != null)
{
if (status == SocketStatus.Connected && tcp.IsClient)
{
List tobeRemovedSockets = TcpSockets;
if (tcp.MachineId == Setting.Values.MachineId)
{
tcp = null;
Setting.Values.MachineId = Common.Ran.Next();
Common.UpdateMachineTimeAndID();
Common.PleaseReopenSocket = Common.REOPEN_WHEN_HOTKEY;
Logger.TelemetryLogTrace("MachineID conflict.", SeverityLevel.Information);
}
else
{
// Keep the first connected one.
tobeRemovedSockets = TcpSockets.Where(item => item.IsClient && !ReferenceEquals(item, tcp) && item.MachineName.Equals(tcp.MachineName, StringComparison.OrdinalIgnoreCase)).ToList();
}
foreach (TcpSk t in tobeRemovedSockets)
{
t.Status = SocketStatus.ForceClosed;
Logger.LogDebug($"Closing duplicated socket {t.MachineName}: {t.Address}");
}
}
List toBeRemoved = new();
foreach (TcpSk t in TcpSockets)
{
if (t.Status is SocketStatus.Error or
SocketStatus.ForceClosed or
// SocketStatus.InvalidKey or
SocketStatus.NA or
SocketStatus.Timeout or
SocketStatus.SendError)
{
try
{
if (t.BackingSocket != null)
{
t.MachineName = "$*NotUsed*$";
t.Status = t.Status >= 0 ? 0 : t.Status - 1; // If error closing, the socket will be closed again at SocketStuff.Close().
t.BackingSocket.Close();
}
toBeRemoved.Add(t);
}
catch (SocketException e)
{
string log = $"{nameof(UpdateTcpSockets)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.";
Logger.Log(log);
}
catch (ObjectDisposedException e)
{
string log = $"{nameof(UpdateTcpSockets)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..";
Logger.Log(log);
}
}
}
if (tcp != null)
{
tcp.Status = status;
if (status == SocketStatus.Connected)
{
// Update the socket's machine name based on its corresponding client/server socket.
foreach (TcpSk t in TcpSockets)
{
if (t.MachineId == tcp.MachineId && t.IsClient != tcp.IsClient)
{
if ((string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':'))
&& !(string.IsNullOrEmpty(t.MachineName) || t.MachineName.Contains('.') || t.MachineName.Contains(':')))
{
tcp.MachineName = t.MachineName;
}
else if ((string.IsNullOrEmpty(t.MachineName) || t.MachineName.Contains('.') || t.MachineName.Contains(':'))
&& !(string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':')))
{
t.MachineName = tcp.MachineName;
}
}
}
if (string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':'))
{
tcp.MachineName = Common.NameFromID((ID)tcp.MachineId);
}
if (string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':'))
{
tcp.MachineName = Common.GetRemoteStringIP(tcp.BackingSocket);
}
}
}
else
{
Logger.Log("UpdateTcpSockets.Exception: Socket not found!");
}
foreach (TcpSk t in toBeRemoved)
{
_ = TcpSockets.Remove(t);
}
}
}
}
catch (Exception e)
{
Logger.Log(e);
}
}
private void PreventDoS(List sockets)
{
if (sockets.Count > 100)
{
TcpSk tcp;
try
{
string msg = Application.ProductName + " has been terminated, too many connections.";
for (int i = 0; i < 10; i++)
{
tcp = sockets[i * 10];
if (tcp != null)
{
msg += $"\r\n{Common.MachineName}{(tcp.IsClient ? "=>" : "<=")}{tcp.MachineName}:{tcp.Status}";
}
}
_ = Common.CreateLowIntegrityProcess(
"\"" + Path.GetDirectoryName(Application.ExecutablePath) + "\\MouseWithoutBordersHelper.exe\"",
"InternalError" + " \"" + msg + "\"",
0,
false,
0,
(short)ProcessWindowStyle.Hidden);
}
finally
{
Common.MainForm.Quit(true, false);
}
}
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Control/Machine.cs
================================================
// 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.ComponentModel;
using System.Windows.Forms;
//
// User control, used in the Matrix form.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Properties;
namespace MouseWithoutBorders
{
internal partial class Machine : UserControl
{
// private int ip;
// private Point mouseDownPos;
private SocketStatus statusClient;
private SocketStatus statusServer;
private bool localhost;
internal Machine()
{
InitializeComponent();
Visible = false;
MachineEnabled = false;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal string MachineName
{
get => textBoxName.Text;
set => textBoxName.Text = value;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal bool MachineEnabled
{
get => checkBoxEnabled.Checked;
set
{
checkBoxEnabled.Checked = value;
Editable = value;
pictureBoxLogo.Image = value ? Images.MachineEnabled : (System.Drawing.Image)Images.MachineDisabled;
OnEnabledChanged(EventArgs.Empty); // Borrow this event since we do not use it for any other purpose:) (we can create one but l...:))
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
internal bool Editable
{
set => textBoxName.Enabled = value;
// get { return textBoxName.Enabled; }
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
internal bool CheckAble
{
set
{
if (!value)
{
checkBoxEnabled.Checked = true;
Editable = false;
}
checkBoxEnabled.Enabled = value;
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
internal bool LocalHost
{
// get { return localhost; }
set
{
localhost = value;
if (localhost)
{
labelStatusClient.Text = "此电脑";
labelStatusServer.Text = "...";
CheckAble = false;
}
else
{
labelStatusClient.Text = "...";
labelStatusServer.Text = "...";
CheckAble = true;
}
}
}
private void PictureBoxLogo_MouseDown(object sender, MouseEventArgs e)
{
// mouseDownPos = e.Location;
OnMouseDown(e);
}
/*
internal Point MouseDownPos
{
get { return mouseDownPos; }
}
*/
private void CheckBoxEnabled_CheckedChanged(object sender, EventArgs e)
{
MachineEnabled = checkBoxEnabled.Checked;
}
private static string StatusString(SocketStatus status)
{
string rv = string.Empty;
switch (status)
{
case SocketStatus.Resolving:
rv = "正在查找地址";
break;
case SocketStatus.Connected:
rv = "已连接";
break;
case SocketStatus.Connecting:
rv = "正在连接";
break;
case SocketStatus.Error:
rv = "出错";
break;
case SocketStatus.ForceClosed:
rv = "已关闭";
break;
case SocketStatus.Handshaking:
rv = "正在握手";
break;
case SocketStatus.SendError:
rv = "发送错误";
break;
case SocketStatus.InvalidKey:
rv = "密码错误";
break;
case SocketStatus.Timeout:
rv = "连接超时";
break;
case SocketStatus.NA:
rv = "...";
break;
default:
break;
}
return rv;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal SocketStatus StatusClient
{
get => statusClient;
set
{
statusClient = value;
if (statusClient is SocketStatus.Connected or
SocketStatus.Handshaking)
{
Editable = false;
}
labelStatusClient.Text = StatusString(statusClient) + " -->";
}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal SocketStatus StatusServer
{
get => statusServer;
set
{
statusServer = value;
if (statusServer is SocketStatus.Connected or
SocketStatus.Handshaking)
{
Editable = false;
}
labelStatusServer.Text = StatusString(statusServer) + " <--";
}
}
private void PictureBoxLogo_Paint(object sender, PaintEventArgs e)
{
// e.Graphics.DrawString("(Draggable)", this.Font, Brushes.WhiteSmoke, 20, 15);
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Control/Machine.designer.cs
================================================
namespace MouseWithoutBorders
{
partial class Machine
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.labelStatusServer = new System.Windows.Forms.Label();
this.textBoxName = new System.Windows.Forms.TextBox();
this.checkBoxEnabled = new System.Windows.Forms.CheckBox();
this.pictureBoxLogo = new System.Windows.Forms.PictureBox();
this.labelStatusClient = new System.Windows.Forms.Label();
this.toolTipHelp = new System.Windows.Forms.ToolTip(this.components);
((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).BeginInit();
this.SuspendLayout();
//
// labelStatusServer
//
this.labelStatusServer.Dock = System.Windows.Forms.DockStyle.Bottom;
this.labelStatusServer.Location = new System.Drawing.Point(0, 90);
this.labelStatusServer.Name = "labelStatusServer";
this.labelStatusServer.Size = new System.Drawing.Size(106, 16);
this.labelStatusServer.TabIndex = 0;
this.labelStatusServer.Text = "...";
this.labelStatusServer.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// textBoxName
//
this.textBoxName.Dock = System.Windows.Forms.DockStyle.Bottom;
this.textBoxName.Location = new System.Drawing.Point(0, 54);
this.textBoxName.Name = "textBoxName";
this.textBoxName.Size = new System.Drawing.Size(106, 20);
this.textBoxName.TabIndex = 1;
this.textBoxName.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// checkBoxEnabled
//
this.checkBoxEnabled.AutoSize = true;
this.checkBoxEnabled.Checked = true;
this.checkBoxEnabled.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxEnabled.Location = new System.Drawing.Point(91, 40);
this.checkBoxEnabled.Name = "checkBoxEnabled";
this.checkBoxEnabled.Size = new System.Drawing.Size(15, 14);
this.checkBoxEnabled.TabIndex = 3;
this.checkBoxEnabled.UseVisualStyleBackColor = true;
this.checkBoxEnabled.CheckedChanged += new System.EventHandler(this.CheckBoxEnabled_CheckedChanged);
//
// pictureBoxLogo
//
this.pictureBoxLogo.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBoxLogo.ErrorImage = null;
this.pictureBoxLogo.InitialImage = null;
this.pictureBoxLogo.Location = new System.Drawing.Point(0, 0);
this.pictureBoxLogo.Name = "pictureBoxLogo";
this.pictureBoxLogo.Size = new System.Drawing.Size(106, 54);
this.pictureBoxLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBoxLogo.TabIndex = 2;
this.pictureBoxLogo.TabStop = false;
this.toolTipHelp.SetToolTip(this.pictureBoxLogo, "拖放改变设备布局,选中输入设备名称。");
this.pictureBoxLogo.Paint += new System.Windows.Forms.PaintEventHandler(this.PictureBoxLogo_Paint);
this.pictureBoxLogo.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PictureBoxLogo_MouseDown);
//
// labelStatusClient
//
this.labelStatusClient.Dock = System.Windows.Forms.DockStyle.Bottom;
this.labelStatusClient.Location = new System.Drawing.Point(0, 74);
this.labelStatusClient.Name = "labelStatusClient";
this.labelStatusClient.Size = new System.Drawing.Size(106, 16);
this.labelStatusClient.TabIndex = 4;
this.labelStatusClient.Text = "...";
this.labelStatusClient.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// Machine
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Transparent;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.Controls.Add(this.checkBoxEnabled);
this.Controls.Add(this.pictureBoxLogo);
this.Controls.Add(this.textBoxName);
this.Controls.Add(this.labelStatusClient);
this.Controls.Add(this.labelStatusServer);
this.Name = "Machine";
this.Size = new System.Drawing.Size(106, 106);
((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label labelStatusServer;
private System.Windows.Forms.TextBox textBoxName;
private System.Windows.Forms.PictureBox pictureBoxLogo;
private System.Windows.Forms.CheckBox checkBoxEnabled;
private System.Windows.Forms.Label labelStatusClient;
private System.Windows.Forms.ToolTip toolTipHelp;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Core/Receiver.cs
================================================
// 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.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using MouseWithoutBorders.Class;
[module: SuppressMessage("Microsoft.Reliability", "CA2002:DoNotLockOnObjectsWithWeakIdentity", Scope = "member", Target = "MouseWithoutBorders.Common.#PreProcess(MouseWithoutBorders.DATA)", Justification = "Dotnet port with style preservation")]
//
// Back-end thread for the socket.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
namespace MouseWithoutBorders.Core;
internal static class Receiver
{
private static readonly uint QUEUE_SIZE = 50;
private static readonly int[] RecentProcessedPackageIDs = new int[QUEUE_SIZE];
private static int recentProcessedPackageIndex;
#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter
internal static long processedPackageCount;
internal static long skippedPackageCount;
#pragma warning restore SA1307
private static long JustGotAKey { get; set; }
private static bool PreProcess(DATA package)
{
if (package.Type == PackageType.Invalid)
{
if ((Common.InvalidPackageCount % 100) == 0)
{
Common.ShowToolTip("收到无效数据包!", 1000, ToolTipIcon.Warning, false);
}
Common.InvalidPackageCount++;
Logger.Log("Invalid packages received!");
return false;
}
else if (package.Type == 0)
{
Logger.Log("Got an unknown package!");
return false;
}
else if (package.Type is not PackageType.ClipboardText and not PackageType.ClipboardImage
// BEGIN: These package types are sent by TcpSend which is single direction.
and not PackageType.Handshake and not PackageType.HandshakeAck)
{
// END
lock (RecentProcessedPackageIDs)
{
for (int i = 0; i < QUEUE_SIZE; i++)
{
if (RecentProcessedPackageIDs[i] == package.Id)
{
skippedPackageCount++;
return false;
}
}
processedPackageCount++;
recentProcessedPackageIndex = (int)((recentProcessedPackageIndex + 1) % QUEUE_SIZE);
RecentProcessedPackageIDs[recentProcessedPackageIndex] = package.Id;
}
}
return true;
}
private static System.Drawing.Point lastXY;
internal static void ProcessPackage(DATA package, TcpSk tcp)
{
if (!PreProcess(package))
{
return;
}
switch (package.Type)
{
case PackageType.Keyboard:
Common.PackageReceived.Keyboard++;
if (package.Des == Common.MachineID || package.Des == ID.ALL)
{
JustGotAKey = Common.GetTick();
// NOTE(@yuyoyuppe): disabled to drop elevation requirement
bool nonElevated = Common.RunWithNoAdminRight && false;
if (nonElevated && Setting.Values.OneWayControlMode)
{
if ((package.Kd.dwFlags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)
{
Common.ShowOneWayModeMessage();
}
return;
}
InputSimulation.SendKey(package.Kd);
}
break;
case PackageType.Mouse:
Common.PackageReceived.Mouse++;
if (package.Des == Common.MachineID || package.Des == ID.ALL)
{
if (Common.desMachineID != Common.MachineID)
{
Common.NewDesMachineID = Common.DesMachineID = Common.MachineID;
}
// NOTE(@yuyoyuppe): disabled to drop elevation requirement
bool nonElevated = Common.RunWithNoAdminRight && false;
if (nonElevated && Setting.Values.OneWayControlMode && package.Md.dwFlags != Common.WM_MOUSEMOVE)
{
if (!Common.IsDropping)
{
if (package.Md.dwFlags is Common.WM_LBUTTONDOWN or Common.WM_RBUTTONDOWN)
{
Common.ShowOneWayModeMessage();
}
}
else if (package.Md.dwFlags is Common.WM_LBUTTONUP or Common.WM_RBUTTONUP)
{
Common.IsDropping = false;
}
return;
}
if (Math.Abs(package.Md.X) >= Common.MOVE_MOUSE_RELATIVE && Math.Abs(package.Md.Y) >= Common.MOVE_MOUSE_RELATIVE)
{
if (package.Md.dwFlags == Common.WM_MOUSEMOVE)
{
InputSimulation.MoveMouseRelative(
package.Md.X < 0 ? package.Md.X + Common.MOVE_MOUSE_RELATIVE : package.Md.X - Common.MOVE_MOUSE_RELATIVE,
package.Md.Y < 0 ? package.Md.Y + Common.MOVE_MOUSE_RELATIVE : package.Md.Y - Common.MOVE_MOUSE_RELATIVE);
_ = NativeMethods.GetCursorPos(ref lastXY);
Point p = Common.MoveToMyNeighbourIfNeeded(lastXY.X, lastXY.Y, Common.MachineID);
if (!p.IsEmpty)
{
Common.HasSwitchedMachineSinceLastCopy = true;
Logger.LogDebug(string.Format(
CultureInfo.CurrentCulture,
"***** Controlled Machine: newDesMachineIdEx set = [{0}]. Mouse is now at ({1},{2})",
Common.newDesMachineIdEx,
lastXY.X,
lastXY.Y));
Common.SendNextMachine(package.Src, Common.newDesMachineIdEx, p);
}
}
else
{
_ = NativeMethods.GetCursorPos(ref lastXY);
package.Md.X = lastXY.X * 65535 / Common.screenWidth;
package.Md.Y = lastXY.Y * 65535 / Common.screenHeight;
_ = InputSimulation.SendMouse(package.Md);
}
}
else
{
_ = InputSimulation.SendMouse(package.Md);
_ = NativeMethods.GetCursorPos(ref lastXY);
}
Common.LastX = lastXY.X;
Common.LastY = lastXY.Y;
CustomCursor.ShowFakeMouseCursor(Common.LastX, Common.LastY);
}
Common.DragDropStep01(package.Md.dwFlags);
Common.DragDropStep09(package.Md.dwFlags);
break;
case PackageType.NextMachine:
Logger.LogDebug("PackageType.NextMachine received!");
if (Common.IsSwitchingByMouseEnabled())
{
Common.PrepareToSwitchToMachine((ID)package.Md.WheelDelta, new Point(package.Md.X, package.Md.Y));
}
break;
case PackageType.ExplorerDragDrop:
Common.PackageReceived.ExplorerDragDrop++;
Common.DragDropStep03(package);
break;
case PackageType.Heartbeat:
case PackageType.Heartbeat_ex:
Common.PackageReceived.Heartbeat++;
Common.GeneratedKey = Common.GeneratedKey || package.Type == PackageType.Heartbeat_ex;
if (Common.GeneratedKey)
{
Setting.Values.MyKey = Common.MyKey;
Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l2);
}
string desMachine = Common.AddToMachinePool(package);
if (Setting.Values.FirstRun && !string.IsNullOrEmpty(desMachine))
{
Common.UpdateSetupMachineMatrix(desMachine);
Common.UpdateClientSockets("UpdateSetupMachineMatrix");
}
break;
case PackageType.Heartbeat_ex_l2:
Common.GeneratedKey = true;
Setting.Values.MyKey = Common.MyKey;
Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l3);
break;
case PackageType.Heartbeat_ex_l3:
Common.GeneratedKey = true;
Setting.Values.MyKey = Common.MyKey;
break;
case PackageType.Awake:
Common.PackageReceived.Heartbeat++;
_ = Common.AddToMachinePool(package);
Common.HumanBeingDetected();
break;
case PackageType.Hello:
Common.PackageReceived.Hello++;
Common.SendHeartBeat();
string newMachine = Common.AddToMachinePool(package);
if (Setting.Values.MachineMatrixString == null)
{
string tip = newMachine + " 报到!";
tip += "\r\n 右键打开设备布局";
Common.ShowToolTip(tip);
}
break;
case PackageType.Hi:
Common.PackageReceived.Hello++;
break;
case PackageType.ByeBye:
Common.PackageReceived.ByeBye++;
Common.ProcessByeByeMessage(package);
break;
case PackageType.Clipboard:
Common.PackageReceived.Clipboard++;
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Common.clipboardCopiedTime = Common.GetTick();
GetNameOfMachineWithClipboardData(package);
SignalBigClipboardData();
}
break;
case PackageType.MachineSwitched:
if (Common.GetTick() - Common.clipboardCopiedTime < Common.BIG_CLIPBOARD_DATA_TIMEOUT && (package.Des == Common.MachineID))
{
Common.clipboardCopiedTime = 0;
Common.GetRemoteClipboard("PackageType.MachineSwitched");
}
break;
case PackageType.ClipboardCapture:
Common.PackageReceived.Clipboard++;
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
if (package.Des == Common.MachineID || package.Des == ID.ALL)
{
GetNameOfMachineWithClipboardData(package);
Common.GetRemoteClipboard("mspaint," + Common.LastMachineWithClipboardData);
}
}
break;
case PackageType.CaptureScreenCommand:
Common.PackageReceived.Clipboard++;
if (package.Des == Common.MachineID || package.Des == ID.ALL)
{
Common.SendImage(package.Src, Common.CaptureScreen());
}
break;
case PackageType.ClipboardAsk:
Common.PackageReceived.ClipboardAsk++;
if (package.Des == Common.MachineID)
{
_ = Task.Run(() =>
{
try
{
System.Threading.Thread thread = Thread.CurrentThread;
thread.Name = $"{nameof(PackageType.ClipboardAsk)}.{thread.ManagedThreadId}";
Thread.UpdateThreads(thread);
string remoteMachine = package.MachineName;
System.Net.Sockets.TcpClient client = Common.ConnectToRemoteClipboardSocket(remoteMachine);
bool clientPushData = true;
if (Common.ShakeHand(ref remoteMachine, client.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref package.PostAction))
{
SocketStuff.SendClipboardData(client.Client, enStream);
}
}
catch (Exception e)
{
Logger.Log(e);
}
});
}
break;
case PackageType.ClipboardDragDrop:
Common.PackageReceived.ClipboardDragDrop++;
Common.DragDropStep08(package);
break;
case PackageType.ClipboardDragDropOperation:
Common.PackageReceived.ClipboardDragDrop++;
Common.DragDropStep08_2(package);
break;
case PackageType.ClipboardDragDropEnd:
Common.PackageReceived.ClipboardDragDropEnd++;
Common.DragDropStep12();
break;
case PackageType.ClipboardText:
case PackageType.ClipboardImage:
Common.clipboardCopiedTime = 0;
if (package.Type == PackageType.ClipboardImage)
{
Common.PackageReceived.ClipboardImage++;
}
else
{
Common.PackageReceived.ClipboardText++;
}
if (tcp != null)
{
Common.ReceiveClipboardDataUsingTCP(
package,
package.Type == PackageType.ClipboardImage,
tcp);
}
break;
case PackageType.HideMouse:
Common.HasSwitchedMachineSinceLastCopy = true;
Common.HideMouseCursor(true);
Common.MainFormDotEx(false);
Common.ReleaseAllKeys();
break;
default:
if ((package.Type & PackageType.Matrix) == PackageType.Matrix)
{
Common.PackageReceived.Matrix++;
Common.UpdateMachineMatrix(package);
break;
}
else
{
// We should never get to this point!
Logger.Log("Invalid package received!");
return;
}
}
}
internal static void GetNameOfMachineWithClipboardData(DATA package)
{
Common.LastIDWithClipboardData = package.Src;
List matchingMachines = Common.MachinePool.TryFindMachineByID(Common.LastIDWithClipboardData);
if (matchingMachines.Count >= 1)
{
Common.LastMachineWithClipboardData = matchingMachines[0].Name.Trim();
}
/*
lastMachineWithClipboardData =
Common.GetString(BitConverter.GetBytes(package.machineNameHead));
lastMachineWithClipboardData +=
Common.GetString(BitConverter.GetBytes(package.machineNameTail));
lastMachineWithClipboardData = lastMachineWithClipboardData.Trim();
* */
}
private static void SignalBigClipboardData()
{
Logger.LogDebug("SignalBigClipboardData");
Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE] { Common.ICON_BIG_CLIPBOARD, -1, Common.ICON_BIG_CLIPBOARD, -1 });
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsFormPage.Designer.cs
================================================
namespace MouseWithoutBorders
{
partial class SettingsFormPage
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.buttonSkip = new System.Windows.Forms.Button();
this.BackButton = new MouseWithoutBorders.ImageButton();
((System.ComponentModel.ISupportInitialize)(this.BackButton)).BeginInit();
this.SuspendLayout();
//
// buttonSkip
//
this.buttonSkip.FlatAppearance.BorderSize = 0;
this.buttonSkip.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128)))));
this.buttonSkip.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(0)))));
this.buttonSkip.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.buttonSkip.ForeColor = System.Drawing.Color.White;
this.buttonSkip.Location = new System.Drawing.Point(0, 36);
this.buttonSkip.Name = "buttonSkip";
this.buttonSkip.Size = new System.Drawing.Size(40, 23);
this.buttonSkip.TabIndex = 1;
this.buttonSkip.Text = "跳过(&S)";
this.buttonSkip.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.buttonSkip.UseVisualStyleBackColor = true;
this.buttonSkip.Click += new System.EventHandler(this.ButtonSkip_Click);
//
// BackButton
//
this.BackButton.DisabledImage = null;
this.BackButton.DownImage = global::MouseWithoutBorders.Properties.Images.back_button_click;
this.BackButton.HoverImage = global::MouseWithoutBorders.Properties.Images.back_button_hover;
this.BackButton.Image = global::MouseWithoutBorders.Properties.Images.back_button_normal;
this.BackButton.Location = new System.Drawing.Point(6, 6);
this.BackButton.Name = "BackButton";
this.BackButton.NormalImage = global::MouseWithoutBorders.Properties.Images.back_button_normal;
this.BackButton.Size = new System.Drawing.Size(24, 24);
this.BackButton.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.BackButton.TabIndex = 0;
this.BackButton.TabStop = false;
this.BackButton.Visible = false;
this.BackButton.Click += new System.EventHandler(this.BackButton_Click);
//
// SettingsFormPage
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DeepSkyBlue;
this.Controls.Add(this.buttonSkip);
this.Controls.Add(this.BackButton);
this.Name = "SettingsFormPage";
this.Size = new System.Drawing.Size(396, 345);
((System.ComponentModel.ISupportInitialize)(this.BackButton)).EndInit();
this.ResumeLayout(false);
}
#endregion
private ImageButton BackButton;
private System.Windows.Forms.Button buttonSkip;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsFormPage.cs
================================================
// 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;
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Form.Settings;
namespace MouseWithoutBorders
{
public partial class SettingsFormPage : UserControl
{
public event EventHandler NextPage;
protected bool BackButtonVisible
{
get => BackButton.Visible;
set => BackButton.Visible = value;
}
public SettingsFormPage()
{
InitializeComponent();
}
public virtual void OnPageClosing()
{
}
protected void SendNextPage(SettingsFormPage page)
{
NextPage?.Invoke(this, new PageEventArgs(page));
}
protected virtual SettingsFormPage CreateBackPage()
{
return null;
}
protected string GetSecureKey()
{
return Common.MyKey;
}
private void BackButton_Click(object sender, EventArgs e)
{
SendNextPage(CreateBackPage());
}
private void ButtonSkip_Click(object sender, EventArgs e)
{
if (MessageBox.Show(
"强烈推荐您先完成初始配置!确定需要跳过这些步骤吗?",
Application.ProductName,
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
Setting.Values.FirstRun = false;
Common.CloseSetupForm();
Common.ShowMachineMatrix();
}
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage1.Designer.cs
================================================
using System.Windows.Forms;
namespace MouseWithoutBorders
{
partial class SetupPage1
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.NoButton = new MouseWithoutBorders.ImageButton();
this.YesButton = new MouseWithoutBorders.ImageButton();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.NoButton)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.YesButton)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.Location = new System.Drawing.Point(41, 96);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(370, 1);
this.panel1.TabIndex = 1;
//
// label1
//
this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(61, 102);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(330, 52);
this.label1.TabIndex = 2;
this.label1.Text = "让我们开始吧";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel2
//
this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Location = new System.Drawing.Point(41, 166);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(370, 1);
this.panel2.TabIndex = 2;
//
// label2
//
this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(61, 185);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(310, 40);
this.label2.TabIndex = 3;
this.label2.Text = "我们需要知道您是否已经在要连接的电脑上完成了配置。";
//
// label3
//
this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.ForeColor = System.Drawing.Color.White;
this.label3.Location = new System.Drawing.Point(61, 240);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(310, 60);
this.label3.TabIndex = 4;
this.label3.Text = "您是否已经在另一台电脑上安装了无界鼠标?";
//
// label4
//
this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label4.ForeColor = System.Drawing.Color.White;
this.label4.Location = new System.Drawing.Point(61, 278);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(310, 20);
this.label4.TabIndex = 5;
this.label4.Text = "";
//
// NoButton
//
this.NoButton.BackColor = System.Drawing.Color.Transparent;
this.NoButton.DisabledImage = null;
this.NoButton.DownImage = global::MouseWithoutBorders.Properties.Images.no_button_click;
this.NoButton.HoverImage = global::MouseWithoutBorders.Properties.Images.no_button_hover;
this.NoButton.Image = global::MouseWithoutBorders.Properties.Images.no_button_normal;
this.NoButton.InitialImage = global::MouseWithoutBorders.Properties.Images.yes_button_normal;
this.NoButton.Location = new System.Drawing.Point(234, 366);
this.NoButton.Name = "NoButton";
this.NoButton.NormalImage = global::MouseWithoutBorders.Properties.Images.no_button_normal;
this.NoButton.Size = new System.Drawing.Size(55, 55);
this.NoButton.TabIndex = 7;
this.NoButton.TabStop = false;
this.NoButton.Click += new System.EventHandler(this.NoButtonClick);
//
// YesButton
//
this.YesButton.BackColor = System.Drawing.Color.Transparent;
this.YesButton.DisabledImage = null;
this.YesButton.DownImage = global::MouseWithoutBorders.Properties.Images.yes_button_click;
this.YesButton.HoverImage = global::MouseWithoutBorders.Properties.Images.yes_button_hover;
this.YesButton.Image = global::MouseWithoutBorders.Properties.Images.yes_button_normal;
this.YesButton.InitialImage = global::MouseWithoutBorders.Properties.Images.yes_button_normal;
this.YesButton.Location = new System.Drawing.Point(164, 366);
this.YesButton.Name = "YesButton";
this.YesButton.NormalImage = global::MouseWithoutBorders.Properties.Images.yes_button_normal;
this.YesButton.Size = new System.Drawing.Size(55, 55);
this.YesButton.TabIndex = 6;
this.YesButton.TabStop = false;
this.YesButton.Click += new System.EventHandler(this.YesButtonClick);
//
// pictureBox1
//
this.pictureBox1.Image = global::MouseWithoutBorders.Properties.Images.Mouse;
this.pictureBox1.Location = new System.Drawing.Point(206, 40);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(41, 36);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// SetupPage1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.NoButton);
this.Controls.Add(this.YesButton);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.panel2);
this.Controls.Add(this.label1);
this.Controls.Add(this.panel1);
this.Controls.Add(this.pictureBox1);
this.DoubleBuffered = true;
this.Name = "SetupPage1";
this.Size = new System.Drawing.Size(453, 438);
this.Controls.SetChildIndex(this.pictureBox1, 0);
this.Controls.SetChildIndex(this.panel1, 0);
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.panel2, 0);
this.Controls.SetChildIndex(this.label2, 0);
this.Controls.SetChildIndex(this.label3, 0);
this.Controls.SetChildIndex(this.label4, 0);
this.Controls.SetChildIndex(this.YesButton, 0);
this.Controls.SetChildIndex(this.NoButton, 0);
((System.ComponentModel.ISupportInitialize)(this.NoButton)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.YesButton)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private ImageButton YesButton;
private ImageButton NoButton;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2a.Designer.cs
================================================
namespace MouseWithoutBorders
{
using System.Windows.Forms;
partial class SetupPage2a
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label6 = new System.Windows.Forms.Label();
this.SecurityCodeField = new MouseWithoutBorders.ColorBorderField();
this.ComputerNameField = new MouseWithoutBorders.ColorBorderField();
this.label3 = new System.Windows.Forms.Label();
this.LinkButton = new MouseWithoutBorders.ImageButton();
this.label2 = new System.Windows.Forms.Label();
this.ExpandHelpButton = new MouseWithoutBorders.ImageButton();
this.CollapseHelpButton = new MouseWithoutBorders.ImageButton();
this.HelpLabel = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.LinkButton)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).BeginInit();
this.SuspendLayout();
//
// label6
//
this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.label6.Location = new System.Drawing.Point(98, 208);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(130, 18);
this.label6.TabIndex = 7;
this.label6.Text = "";
this.label6.TextAlign = System.Drawing.ContentAlignment.BottomLeft;
//
// SecurityCodeField
//
this.SecurityCodeField.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.SecurityCodeField.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.SecurityCodeField.BorderSize = 2;
this.SecurityCodeField.FocusColor = System.Drawing.Color.FromArgb(((int)(((byte)(251)))), ((int)(((byte)(176)))), ((int)(((byte)(64)))));
this.SecurityCodeField.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.SecurityCodeField.Location = new System.Drawing.Point(80, 226);
this.SecurityCodeField.Margin = new System.Windows.Forms.Padding(0);
this.SecurityCodeField.MaximumLength = 22;
this.SecurityCodeField.Name = "SecurityCodeField";
this.SecurityCodeField.Size = new System.Drawing.Size(300, 30);
this.SecurityCodeField.TabIndex = 0;
this.SecurityCodeField.FieldTextChanged += new System.EventHandler(this.SecurityCodeFieldFieldTextChanged);
//
// ComputerNameField
//
this.ComputerNameField.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.ComputerNameField.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.ComputerNameField.BorderSize = 2;
this.ComputerNameField.FocusColor = System.Drawing.Color.FromArgb(((int)(((byte)(251)))), ((int)(((byte)(176)))), ((int)(((byte)(64)))));
this.ComputerNameField.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F);
this.ComputerNameField.Location = new System.Drawing.Point(80, 280);
this.ComputerNameField.Margin = new System.Windows.Forms.Padding(0);
this.ComputerNameField.MaximumLength = 126;
this.ComputerNameField.Name = "ComputerNameField";
this.ComputerNameField.Size = new System.Drawing.Size(300, 30);
this.ComputerNameField.TabIndex = 1;
this.ComputerNameField.FieldTextChanged += new System.EventHandler(this.ComputerNameFieldFieldTextChanged);
//
// label3
//
this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.label3.Location = new System.Drawing.Point(98, 262);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(262, 18);
this.label3.TabIndex = 13;
this.label3.Text = "豸";
this.label3.TextAlign = System.Drawing.ContentAlignment.BottomLeft;
//
// LinkButton
//
this.LinkButton.DisabledImage = global::MouseWithoutBorders.Properties.Images.link_button_disabled;
this.LinkButton.DownImage = global::MouseWithoutBorders.Properties.Images.link_button_click;
this.LinkButton.Enabled = false;
this.LinkButton.HoverImage = global::MouseWithoutBorders.Properties.Images.link_button_hover;
this.LinkButton.Image = global::MouseWithoutBorders.Properties.Images.link_button_normal;
this.LinkButton.Location = new System.Drawing.Point(199, 366);
this.LinkButton.Name = "LinkButton";
this.LinkButton.NormalImage = global::MouseWithoutBorders.Properties.Images.link_button_normal;
this.LinkButton.Size = new System.Drawing.Size(55, 55);
this.LinkButton.TabIndex = 15;
this.LinkButton.TabStop = false;
this.LinkButton.Click += new System.EventHandler(this.LinkButtonClick);
//
// label2
//
this.label2.AutoSize = true;
this.label2.BackColor = System.Drawing.Color.Transparent;
this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(213, 208);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(128, 16);
this.label2.TabIndex = 23;
this.label2.Text = "ȥ룿";
//
// ExpandHelpButton
//
this.ExpandHelpButton.DisabledImage = null;
this.ExpandHelpButton.DownImage = global::MouseWithoutBorders.Properties.Images.expand_button_click;
this.ExpandHelpButton.HoverImage = global::MouseWithoutBorders.Properties.Images.expand_button_highlight;
this.ExpandHelpButton.Image = global::MouseWithoutBorders.Properties.Images.expand_button_normal;
this.ExpandHelpButton.Location = new System.Drawing.Point(360, 211);
this.ExpandHelpButton.Name = "ExpandHelpButton";
this.ExpandHelpButton.NormalImage = global::MouseWithoutBorders.Properties.Images.expand_button_normal;
this.ExpandHelpButton.Size = new System.Drawing.Size(11, 11);
this.ExpandHelpButton.TabIndex = 24;
this.ExpandHelpButton.TabStop = false;
this.ExpandHelpButton.Click += new System.EventHandler(this.ExpandHelpButtonClick);
//
// CollapseHelpButton
//
this.CollapseHelpButton.DisabledImage = null;
this.CollapseHelpButton.DownImage = global::MouseWithoutBorders.Properties.Images.collapse_button_click;
this.CollapseHelpButton.HoverImage = global::MouseWithoutBorders.Properties.Images.collapse_button_hover;
this.CollapseHelpButton.Image = global::MouseWithoutBorders.Properties.Images.collapse_button_normal;
this.CollapseHelpButton.Location = new System.Drawing.Point(360, 211);
this.CollapseHelpButton.Name = "CollapseHelpButton";
this.CollapseHelpButton.NormalImage = global::MouseWithoutBorders.Properties.Images.collapse_button_normal;
this.CollapseHelpButton.Size = new System.Drawing.Size(11, 11);
this.CollapseHelpButton.TabIndex = 25;
this.CollapseHelpButton.TabStop = false;
this.CollapseHelpButton.Visible = false;
this.CollapseHelpButton.Click += new System.EventHandler(this.CollapseHelpButtonClick);
//
// HelpLabel
//
this.HelpLabel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(49)))), ((int)(((byte)(159)))), ((int)(((byte)(217)))));
this.HelpLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.HelpLabel.ForeColor = System.Drawing.Color.White;
this.HelpLabel.Location = new System.Drawing.Point(101, 226);
this.HelpLabel.Name = "HelpLabel";
this.HelpLabel.Size = new System.Drawing.Size(250, 94);
this.HelpLabel.TabIndex = 26;
this.HelpLabel.Text = "ҪӵĵϣҼͼ꣬ý棬нչʾ롣豸һ̨Եơ";
this.HelpLabel.Visible = false;
//
// SetupPage2a
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.HelpLabel);
this.Controls.Add(this.LinkButton);
this.Controls.Add(this.ComputerNameField);
this.Controls.Add(this.label3);
this.Controls.Add(this.SecurityCodeField);
this.Controls.Add(this.CollapseHelpButton);
this.Controls.Add(this.ExpandHelpButton);
this.Controls.Add(this.label2);
this.Controls.Add(this.label6);
this.DoubleBuffered = true;
this.Name = "SetupPage2a";
this.Size = new System.Drawing.Size(453, 438);
this.Controls.SetChildIndex(this.label6, 0);
this.Controls.SetChildIndex(this.label2, 0);
this.Controls.SetChildIndex(this.ExpandHelpButton, 0);
this.Controls.SetChildIndex(this.CollapseHelpButton, 0);
this.Controls.SetChildIndex(this.SecurityCodeField, 0);
this.Controls.SetChildIndex(this.label3, 0);
this.Controls.SetChildIndex(this.ComputerNameField, 0);
this.Controls.SetChildIndex(this.LinkButton, 0);
this.Controls.SetChildIndex(this.HelpLabel, 0);
((System.ComponentModel.ISupportInitialize)(this.LinkButton)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label6;
private ColorBorderField SecurityCodeField;
private ColorBorderField ComputerNameField;
private System.Windows.Forms.Label label3;
private ImageButton LinkButton;
private System.Windows.Forms.Label label2;
private ImageButton ExpandHelpButton;
private ImageButton CollapseHelpButton;
private System.Windows.Forms.Label HelpLabel;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2aa.Designer.cs
================================================
using System.Windows.Forms;
namespace MouseWithoutBorders
{
partial class SetupPage2aa
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// label1
//
this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(49, 30);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(356, 150);
this.label1.TabIndex = 2;
this.label1.Text = "ֻһӣ";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label6
//
this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.label6.Location = new System.Drawing.Point(98, 185);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(130, 18);
this.label6.TabIndex = 7;
this.label6.Text = "";
this.label6.TextAlign = System.Drawing.ContentAlignment.BottomLeft;
//
// label2
//
this.label2.AutoSize = true;
this.label2.BackColor = System.Drawing.Color.Transparent;
this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(213, 185);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(128, 16);
this.label2.TabIndex = 23;
this.label2.Text = "ȥ룿";
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.Location = new System.Drawing.Point(41, 170);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(370, 1);
this.panel1.TabIndex = 1;
//
// SetupPage2aa
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.panel1);
this.Controls.Add(this.label1);
this.Name = "SetupPage2aa";
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.panel1, 0);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel panel1;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2ab.Designer.cs
================================================
using System.Windows.Forms;
namespace MouseWithoutBorders
{
partial class SetupPage2ab
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.ExpandHelpButton = new MouseWithoutBorders.ImageButton();
this.CollapseHelpButton = new MouseWithoutBorders.ImageButton();
this.panel1 = new System.Windows.Forms.Panel();
this.panel2 = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(49, 30);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(356, 53);
this.label1.TabIndex = 2;
this.label1.Text = "Ǹ";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label6
//
this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.label6.Location = new System.Drawing.Point(98, 208);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(130, 18);
this.label6.TabIndex = 7;
this.label6.Text = "";
this.label6.TextAlign = System.Drawing.ContentAlignment.BottomLeft;
//
// label4
//
this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label4.ForeColor = System.Drawing.Color.White;
this.label4.Location = new System.Drawing.Point(61, 95);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(332, 79);
this.label4.TabIndex = 27;
this.label4.Text = "ƺϱĵԡȷеԶͬһ£û豸";
//
// label2
//
this.label2.AutoSize = true;
this.label2.BackColor = System.Drawing.Color.Transparent;
this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(213, 208);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(128, 16);
this.label2.TabIndex = 23;
this.label2.Text = "ȥ룿";
//
// ExpandHelpButton
//
this.ExpandHelpButton.DisabledImage = null;
this.ExpandHelpButton.DownImage = null;
this.ExpandHelpButton.HoverImage = null;
this.ExpandHelpButton.Location = new System.Drawing.Point(0, 0);
this.ExpandHelpButton.Name = "ExpandHelpButton";
this.ExpandHelpButton.NormalImage = null;
this.ExpandHelpButton.Size = new System.Drawing.Size(80, 78);
this.ExpandHelpButton.TabIndex = 0;
this.ExpandHelpButton.TabStop = false;
//
// CollapseHelpButton
//
this.CollapseHelpButton.DisabledImage = null;
this.CollapseHelpButton.DownImage = null;
this.CollapseHelpButton.HoverImage = null;
this.CollapseHelpButton.Location = new System.Drawing.Point(0, 0);
this.CollapseHelpButton.Name = "CollapseHelpButton";
this.CollapseHelpButton.NormalImage = null;
this.CollapseHelpButton.Size = new System.Drawing.Size(80, 78);
this.CollapseHelpButton.TabIndex = 0;
this.CollapseHelpButton.TabStop = false;
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.Location = new System.Drawing.Point(41, 80);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(370, 1);
this.panel1.TabIndex = 1;
//
// panel2
//
this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Location = new System.Drawing.Point(41, 170);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(370, 1);
this.panel2.TabIndex = 28;
//
// SetupPage2ab
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.panel2);
this.Controls.Add(this.label4);
this.Controls.Add(this.panel1);
this.Controls.Add(this.label1);
this.Name = "SetupPage2ab";
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.panel1, 0);
this.Controls.SetChildIndex(this.label4, 0);
this.Controls.SetChildIndex(this.panel2, 0);
((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label2;
private ImageButton ExpandHelpButton;
private ImageButton CollapseHelpButton;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Panel panel2;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2b.Designer.cs
================================================
using System.Windows.Forms;
namespace MouseWithoutBorders
{
partial class SetupPage2b
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.label2 = new System.Windows.Forms.Label();
this.SecurityCodeLabel = new System.Windows.Forms.Label();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.MachineNameLabel = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.Location = new System.Drawing.Point(41, 326);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(370, 1);
this.panel1.TabIndex = 1;
//
// label1
//
this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 28F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(61, 28);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(330, 56);
this.label1.TabIndex = 2;
this.label1.Text = "Ͼͺ...";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel2
//
this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Location = new System.Drawing.Point(41, 87);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(370, 1);
this.panel2.TabIndex = 2;
//
// label2
//
this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(61, 103);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(338, 80);
this.label2.TabIndex = 3;
this.label2.Text = "ֻϢ߿ڣȻڱĵϰװ꣬ʼ̳üɡ";
//
// SecurityCodeLabel
//
this.SecurityCodeLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.SecurityCodeLabel.ForeColor = System.Drawing.Color.White;
this.SecurityCodeLabel.Location = new System.Drawing.Point(68, 207);
this.SecurityCodeLabel.Name = "SecurityCodeLabel";
this.SecurityCodeLabel.Size = new System.Drawing.Size(310, 40);
this.SecurityCodeLabel.TabIndex = 4;
this.SecurityCodeLabel.Text = "IlIlIlIlIl";
this.SecurityCodeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// pictureBox1
//
this.pictureBox1.Image = global::MouseWithoutBorders.Properties.Images.Mouse;
this.pictureBox1.Location = new System.Drawing.Point(206, 365);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(44, 35);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// label5
//
this.label5.Font = new System.Drawing.Font(Control.DefaultFont.Name, 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label5.ForeColor = System.Drawing.Color.White;
this.label5.Location = new System.Drawing.Point(61, 170);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(310, 24);
this.label5.TabIndex = 6;
this.label5.Text = "ȻǾú!";
//
// label6
//
this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.label6.Location = new System.Drawing.Point(71, 199);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(310, 15);
this.label6.TabIndex = 7;
this.label6.Text = "";
this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label4
//
this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));
this.label4.Location = new System.Drawing.Point(71, 258);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(310, 15);
this.label4.TabIndex = 9;
this.label4.Text = "豸";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// MachineNameLabel
//
this.MachineNameLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.MachineNameLabel.ForeColor = System.Drawing.Color.White;
this.MachineNameLabel.Location = new System.Drawing.Point(50, 266);
this.MachineNameLabel.Name = "MachineNameLabel";
this.MachineNameLabel.Size = new System.Drawing.Size(340, 40);
this.MachineNameLabel.TabIndex = 8;
this.MachineNameLabel.Text = "Сĵ";
this.MachineNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// SetupPage2b
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.label4);
this.Controls.Add(this.MachineNameLabel);
this.Controls.Add(this.label6);
this.Controls.Add(this.label5);
this.Controls.Add(this.SecurityCodeLabel);
this.Controls.Add(this.label2);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panel1);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.label1);
this.DoubleBuffered = true;
this.Name = "SetupPage2b";
this.Size = new System.Drawing.Size(453, 438);
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.pictureBox1, 0);
this.Controls.SetChildIndex(this.panel1, 0);
this.Controls.SetChildIndex(this.panel2, 0);
this.Controls.SetChildIndex(this.label2, 0);
this.Controls.SetChildIndex(this.SecurityCodeLabel, 0);
this.Controls.SetChildIndex(this.label5, 0);
this.Controls.SetChildIndex(this.label6, 0);
this.Controls.SetChildIndex(this.MachineNameLabel, 0);
this.Controls.SetChildIndex(this.label4, 0);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label SecurityCodeLabel;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label MachineNameLabel;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage3a.Designer.cs
================================================
using System.Windows.Forms;
namespace MouseWithoutBorders
{
partial class SetupPage3a
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.MessageLabel = new System.Windows.Forms.Label();
this.ExamplePicture = new System.Windows.Forms.PictureBox();
this.labelStatus = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(65, 56);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(330, 116);
this.label1.TabIndex = 2;
this.label1.Text = "ӣܿͿ...\r\n";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel2
//
this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Location = new System.Drawing.Point(41, 178);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(370, 1);
this.panel2.TabIndex = 2;
//
// MessageLabel
//
this.MessageLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.MessageLabel.ForeColor = System.Drawing.Color.White;
this.MessageLabel.Location = new System.Drawing.Point(71, 197);
this.MessageLabel.Name = "MessageLabel";
this.MessageLabel.Size = new System.Drawing.Size(310, 24);
this.MessageLabel.TabIndex = 4;
this.MessageLabel.Text = "Ըճ";
this.MessageLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// ExamplePicture
//
this.ExamplePicture.Image = global::MouseWithoutBorders.Properties.Images.copy_paste_example;
this.ExamplePicture.Location = new System.Drawing.Point(101, 251);
this.ExamplePicture.Name = "ExamplePicture";
this.ExamplePicture.Size = new System.Drawing.Size(251, 79);
this.ExamplePicture.TabIndex = 7;
this.ExamplePicture.TabStop = false;
//
// labelStatus
//
this.labelStatus.Dock = System.Windows.Forms.DockStyle.Bottom;
this.labelStatus.Font = new System.Drawing.Font(Control.DefaultFont.Name, 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelStatus.ForeColor = System.Drawing.Color.White;
this.labelStatus.Location = new System.Drawing.Point(0, 418);
this.labelStatus.Name = "labelStatus";
this.labelStatus.Size = new System.Drawing.Size(453, 20);
this.labelStatus.TabIndex = 8;
this.labelStatus.Text = "...";
this.labelStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// SetupPage3a
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.labelStatus);
this.Controls.Add(this.ExamplePicture);
this.Controls.Add(this.MessageLabel);
this.Controls.Add(this.panel2);
this.Controls.Add(this.label1);
this.DoubleBuffered = true;
this.Name = "SetupPage3a";
this.Size = new System.Drawing.Size(453, 438);
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.panel2, 0);
this.Controls.SetChildIndex(this.MessageLabel, 0);
this.Controls.SetChildIndex(this.ExamplePicture, 0);
this.Controls.SetChildIndex(this.labelStatus, 0);
((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label MessageLabel;
private System.Windows.Forms.PictureBox ExamplePicture;
private System.Windows.Forms.Label labelStatus;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage3a.cs
================================================
// 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.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
using MouseWithoutBorders.Properties;
namespace MouseWithoutBorders
{
public partial class SetupPage3a : SettingsFormPage
{
private readonly Image[] _frames = { Images.copy_paste_example, Images.drag_example, Images.keyboard_example };
private readonly string[] _messages =
{
"跨电脑复制粘贴",
"跨电脑拖拽文件",
"共享一套鼠标键盘",
};
private readonly int[] _timing = { 1000, 1000, 2000 };
#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager
private readonly System.Timers.Timer _animationTimer;
#pragma warning restore CA2213
private bool connected;
private bool done;
private bool invalidKey;
private int _animationFrame;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ReturnToSettings { get; set; }
public SetupPage3a()
{
InitializeComponent();
_animationTimer = new System.Timers.Timer { Interval = 1000 };
}
private void ShowStatus(string status)
{
labelStatus.Text = status;
Logger.Log(status);
}
public override void OnPageClosing()
{
_animationTimer.Stop();
base.OnPageClosing();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
_animationTimer.Elapsed += AnimationTimerTick;
Common.GetMachineName();
invalidKey = false;
UpdateAnimation();
_animationTimer.Start();
SocketStuff.InvalidKeyFound = false;
SocketStuff.InvalidKeyFoundOnClientSocket = false;
ShowStatus($"正在连接中...");
Common.SwitchToMultipleMode(false, false);
Common.ReopenSockets(true);
int timeOut = 0;
TcpSk connectedClientSocket;
// Client sockets run in different threads.
while (timeOut < 10)
{
Common.MMSleep(1);
if ((connectedClientSocket = Common.GetConnectedClientSocket()) != null)
{
ShowStatus($"已连接本地 IP 地址: {connectedClientSocket.Address}.");
Common.UpdateMachineTimeAndID();
Common.MMSleep(1);
connected = true;
return;
}
else if (SocketStuff.InvalidKeyFoundOnClientSocket)
{
invalidKey = true;
ShowStatus("状态: 密码无效.");
Common.MMSleep(3);
break;
}
timeOut++;
}
done = true;
}
private void AnimationTimerTick(object sender, EventArgs e)
{
_ = Invoke(new MethodInvoker(UpdateAnimation));
}
private void UpdateAnimation()
{
if ((ModifierKeys & Keys.Control) != 0)
{
_animationTimer.Stop();
SendNextPage(new SetupPage2ab());
return;
}
ExamplePicture.Image = _frames[_animationFrame];
MessageLabel.Text = _messages[_animationFrame];
_animationTimer.Interval = _timing[_animationFrame];
_animationFrame = (_animationFrame + 1) % _frames.Length;
if (connected)
{
_animationTimer.Stop();
SendNextPage(new SetupPage4());
}
else if (done)
{
_animationTimer.Stop();
SendNextPage(new SetupPage2ab());
if (invalidKey)
{
Common.ShowToolTip(
"密码不正确。\r\n请检查是否在所有电脑上都输入了同一个密码。\r\n并检查您运行的是否都是同一版本的 "
+ Application.ProductName + "。\r\n本软件版本: " + FrmAbout.AssemblyVersion,
20000);
}
else
{
string helpText = "连接出错!";
helpText += "\r\n请检查您的电脑是否连接到同一个网络,一般推荐插网线更稳定。";
helpText += "\r\n再三检查 " + Application.ProductName + " 是不是被系统防火墙阻拦了。";
Common.ShowToolTip(helpText, 30000);
}
}
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage4.Designer.cs
================================================
using System.Windows.Forms;
namespace MouseWithoutBorders
{
partial class SetupPage4
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.label5 = new System.Windows.Forms.Label();
this.ExamplePicture = new System.Windows.Forms.PictureBox();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.NextButton = new MouseWithoutBorders.ImageButton();
this.label4 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.NextButton)).BeginInit();
this.SuspendLayout();
//
// label1
//
this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(65, 58);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(330, 52);
this.label1.TabIndex = 2;
this.label1.Text = "ɹ";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel2
//
this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Location = new System.Drawing.Point(41, 175);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(370, 1);
this.panel2.TabIndex = 2;
//
// label5
//
this.label5.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label5.ForeColor = System.Drawing.Color.White;
this.label5.Location = new System.Drawing.Point(57, 108);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(344, 52);
this.label5.TabIndex = 6;
this.label5.Text = "Ͳһ...";
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// ExamplePicture
//
this.ExamplePicture.Image = global::MouseWithoutBorders.Properties.Images.combined_example;
this.ExamplePicture.Location = new System.Drawing.Point(75, 283);
this.ExamplePicture.Name = "ExamplePicture";
this.ExamplePicture.Size = new System.Drawing.Size(307, 25);
this.ExamplePicture.TabIndex = 7;
this.ExamplePicture.TabStop = false;
//
// label2
//
this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(61, 200);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(310, 25);
this.label2.TabIndex = 8;
this.label2.Text = "ͨʵЩ¡";
//
// label3
//
this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label3.ForeColor = System.Drawing.Color.White;
this.label3.Location = new System.Drawing.Point(71, 242);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(88, 38);
this.label3.TabIndex = 9;
this.label3.Text = "Ըճ";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.Location = new System.Drawing.Point(41, 345);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(370, 1);
this.panel1.TabIndex = 3;
//
// NextButton
//
this.NextButton.DisabledImage = null;
this.NextButton.DownImage = global::MouseWithoutBorders.Properties.Images.next_button_click;
this.NextButton.HoverImage = global::MouseWithoutBorders.Properties.Images.next_button_hover;
this.NextButton.Image = global::MouseWithoutBorders.Properties.Images.next_button_normal;
this.NextButton.Location = new System.Drawing.Point(199, 366);
this.NextButton.Name = "NextButton";
this.NextButton.NormalImage = global::MouseWithoutBorders.Properties.Images.next_button_normal;
this.NextButton.Size = new System.Drawing.Size(55, 55);
this.NextButton.TabIndex = 16;
this.NextButton.TabStop = false;
this.NextButton.Click += new System.EventHandler(this.NextButtonClick);
//
// label4
//
this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label4.ForeColor = System.Drawing.Color.White;
this.label4.Location = new System.Drawing.Point(185, 242);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(88, 38);
this.label4.TabIndex = 17;
this.label4.Text = "קļ";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label6
//
this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label6.ForeColor = System.Drawing.Color.White;
this.label6.Location = new System.Drawing.Point(294, 242);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(97, 38);
this.label6.TabIndex = 18;
this.label6.Text = "һ";
this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// SetupPage4
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.label6);
this.Controls.Add(this.label4);
this.Controls.Add(this.NextButton);
this.Controls.Add(this.panel1);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.ExamplePicture);
this.Controls.Add(this.label5);
this.Controls.Add(this.panel2);
this.Controls.Add(this.label1);
this.DoubleBuffered = true;
this.Name = "SetupPage4";
this.Size = new System.Drawing.Size(453, 438);
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.panel2, 0);
this.Controls.SetChildIndex(this.label5, 0);
this.Controls.SetChildIndex(this.ExamplePicture, 0);
this.Controls.SetChildIndex(this.label2, 0);
this.Controls.SetChildIndex(this.label3, 0);
this.Controls.SetChildIndex(this.panel1, 0);
this.Controls.SetChildIndex(this.NextButton, 0);
this.Controls.SetChildIndex(this.label4, 0);
this.Controls.SetChildIndex(this.label6, 0);
((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.NextButton)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.PictureBox ExamplePicture;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Panel panel1;
private ImageButton NextButton;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label6;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage5.Designer.cs
================================================
using System.Windows.Forms;
namespace MouseWithoutBorders
{
partial class SetupPage5
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.label3 = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.label2 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.DoneButton = new MouseWithoutBorders.ImageButton();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.DoneButton)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Image = global::MouseWithoutBorders.Properties.Images.Mouse;
this.pictureBox1.Location = new System.Drawing.Point(206, 40);
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(41, 36);
this.pictureBox1.TabIndex = 25;
this.pictureBox1.TabStop = false;
//
// label3
//
this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Bold);
this.label3.ForeColor = System.Drawing.Color.White;
this.label3.Location = new System.Drawing.Point(61, 271);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(310, 25);
this.label3.TabIndex = 24;
this.label3.Text = "ףÿģ";
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.Location = new System.Drawing.Point(41, 96);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(370, 1);
this.panel1.TabIndex = 20;
//
// label2
//
this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);
this.label2.ForeColor = System.Drawing.Color.White;
this.label2.Location = new System.Drawing.Point(61, 226);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(310, 40);
this.label2.TabIndex = 22;
this.label2.Text = "ʱͨͼá";
//
// panel2
//
this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel2.BackColor = System.Drawing.Color.White;
this.panel2.Location = new System.Drawing.Point(41, 208);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(370, 1);
this.panel2.TabIndex = 18;
//
// label1
//
this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.Color.White;
this.label1.Location = new System.Drawing.Point(62, 99);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(330, 109);
this.label1.TabIndex = 19;
this.label1.Text = "ɡ\r\nɵƯ";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// DoneButton
//
this.DoneButton.DisabledImage = null;
this.DoneButton.DownImage = global::MouseWithoutBorders.Properties.Images.done_button_click;
this.DoneButton.HoverImage = global::MouseWithoutBorders.Properties.Images.done_button_hover;
this.DoneButton.Image = global::MouseWithoutBorders.Properties.Images.done_button_normal;
this.DoneButton.Location = new System.Drawing.Point(199, 366);
this.DoneButton.Name = "DoneButton";
this.DoneButton.NormalImage = global::MouseWithoutBorders.Properties.Images.done_button_normal;
this.DoneButton.Size = new System.Drawing.Size(55, 56);
this.DoneButton.TabIndex = 26;
this.DoneButton.TabStop = false;
this.DoneButton.Click += new System.EventHandler(this.DoneButtonClick);
//
// SetupPage5
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DodgerBlue;
this.Controls.Add(this.DoneButton);
this.Controls.Add(this.panel1);
this.Controls.Add(this.label1);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.panel2);
this.DoubleBuffered = true;
this.Name = "SetupPage5";
this.Size = new System.Drawing.Size(453, 438);
this.Controls.SetChildIndex(this.panel2, 0);
this.Controls.SetChildIndex(this.label2, 0);
this.Controls.SetChildIndex(this.label3, 0);
this.Controls.SetChildIndex(this.pictureBox1, 0);
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.panel1, 0);
this.Controls.SetChildIndex(this.DoneButton, 0);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.DoneButton)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label1;
private ImageButton DoneButton;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmAbout.Designer.cs
================================================
namespace MouseWithoutBorders
{
partial class FrmAbout
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmAbout));
this.logoPictureBox = new System.Windows.Forms.PictureBox();
this.labelProductName = new System.Windows.Forms.Label();
this.labelCopyright = new System.Windows.Forms.Label();
this.labelCompanyName = new System.Windows.Forms.Label();
this.groupBoxContributors = new System.Windows.Forms.GroupBox();
this.textBoxContributors = new System.Windows.Forms.TextBox();
this.okButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
this.groupBoxContributors.SuspendLayout();
this.SuspendLayout();
//
// logoPictureBox
//
this.logoPictureBox.ErrorImage = null;
this.logoPictureBox.Image = global::MouseWithoutBorders.Properties.Images.Logo;
this.logoPictureBox.Location = new System.Drawing.Point(12, 12);
this.logoPictureBox.Name = "logoPictureBox";
this.logoPictureBox.Size = new System.Drawing.Size(131, 136);
this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.logoPictureBox.TabIndex = 12;
this.logoPictureBox.TabStop = false;
//
// labelProductName
//
this.labelProductName.AutoSize = true;
this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelProductName.Location = new System.Drawing.Point(152, 12);
this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelProductName.MaximumSize = new System.Drawing.Size(0, 17);
this.labelProductName.Name = "labelProductName";
this.labelProductName.Size = new System.Drawing.Size(87, 13);
this.labelProductName.TabIndex = 27;
this.labelProductName.Text = "Product Name";
this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// labelCopyright
//
this.labelCopyright.AutoSize = true;
this.labelCopyright.Location = new System.Drawing.Point(152, 31);
this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 17);
this.labelCopyright.Name = "labelCopyright";
this.labelCopyright.Size = new System.Drawing.Size(51, 13);
this.labelCopyright.TabIndex = 28;
this.labelCopyright.Text = "Copyright";
this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// labelCompanyName
//
this.labelCompanyName.AutoSize = true;
this.labelCompanyName.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelCompanyName.Location = new System.Drawing.Point(9, 162);
this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelCompanyName.MaximumSize = new System.Drawing.Size(0, 17);
this.labelCompanyName.Name = "labelCompanyName";
this.labelCompanyName.Size = new System.Drawing.Size(94, 13);
this.labelCompanyName.TabIndex = 29;
this.labelCompanyName.Text = "Company Name";
this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// groupBoxContributors
//
this.groupBoxContributors.Controls.Add(this.textBoxContributors);
this.groupBoxContributors.Location = new System.Drawing.Point(12, 178);
this.groupBoxContributors.Name = "groupBoxContributors";
this.groupBoxContributors.Size = new System.Drawing.Size(466, 350);
this.groupBoxContributors.TabIndex = 30;
this.groupBoxContributors.TabStop = false;
this.groupBoxContributors.Text = " 贡献者 ";
//
// textBoxContributors
//
this.textBoxContributors.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxContributors.Location = new System.Drawing.Point(3, 16);
this.textBoxContributors.Multiline = true;
this.textBoxContributors.Name = "textBoxContributors";
this.textBoxContributors.ReadOnly = true;
this.textBoxContributors.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.textBoxContributors.Size = new System.Drawing.Size(460, 331);
this.textBoxContributors.TabIndex = 31;
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.okButton.Location = new System.Drawing.Point(403, 534);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 24;
this.okButton.Text = "确定";
//
// frmAbout
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(487, 561);
this.Controls.Add(this.okButton);
this.Controls.Add(this.logoPictureBox);
this.Controls.Add(this.labelProductName);
this.Controls.Add(this.labelCopyright);
this.Controls.Add(this.labelCompanyName);
this.Controls.Add(this.groupBoxContributors);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "frmAbout";
this.Opacity = 0.9D;
this.Padding = new System.Windows.Forms.Padding(9);
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "frmAbout";
this.TopMost = true;
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FrmAbout_FormClosed);
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.groupBoxContributors.ResumeLayout(false);
this.groupBoxContributors.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.PictureBox logoPictureBox;
private System.Windows.Forms.Label labelProductName;
private System.Windows.Forms.Label labelCopyright;
private System.Windows.Forms.Label labelCompanyName;
private System.Windows.Forms.GroupBox groupBoxContributors;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.TextBox textBoxContributors;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmAbout.cs
================================================
// 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.
//
// About box.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using System;
using System.Globalization;
using System.Reflection;
using System.Windows.Forms;
namespace MouseWithoutBorders
{
internal partial class FrmAbout : System.Windows.Forms.Form, IDisposable
{
internal FrmAbout()
{
InitializeComponent();
Text = string.Format(CultureInfo.CurrentCulture, "关于 {0}", AssemblyTitle);
labelProductName.Text = string.Format(CultureInfo.CurrentCulture, "{0} {1}", AssemblyProduct, AssemblyVersion);
labelCopyright.Text = AssemblyCopyright;
labelCompanyName.Text = "项目创建者: Truong Do (Đỗ Đức Trường)";
textBoxContributors.Text += "* 微软车库: Quinn Hawkins, Michael Low, Joe Coplen, Nino Yuniardi, Gwyneth Marshall, David Andrews, Karen Luecking";
textBoxContributors.Text += "\r\n* Peter Hauge\t\t- Visual Studio";
textBoxContributors.Text += "\r\n* Bruce Dawson\t\t- Windows Fundamentals";
textBoxContributors.Text += "\r\n* Alan Myrvold\t\t- Office Security";
textBoxContributors.Text += "\r\n* Adrian Garside\t\t- WEX";
textBoxContributors.Text += "\r\n* Scott Bradner\t\t- Surface";
textBoxContributors.Text += "\r\n* Aleks Gershaft\t\t- Windows Azure";
textBoxContributors.Text += "\r\n* Chinh Huynh\t\t- Windows Azure";
textBoxContributors.Text += "\r\n* Long Nguyen\t\t- Data Center";
textBoxContributors.Text += "\r\n* Triet Le\t\t\t- Cloud Engineering";
textBoxContributors.Text += "\r\n* Luke Schoen\t\t- Excel";
textBoxContributors.Text += "\r\n* Bao Nguyen\t\t- Bing";
textBoxContributors.Text += "\r\n* Ross Nichols\t\t- Windows";
textBoxContributors.Text += "\r\n* Ryan Baltazar\t\t- Windows";
textBoxContributors.Text += "\r\n* Ed Essey\t\t\t- The Garage";
textBoxContributors.Text += "\r\n* Mario Madden\t\t- The Garage";
textBoxContributors.Text += "\r\n* Karthick Mahalingam\t- ACE";
textBoxContributors.Text += "\r\n* Pooja Kamra\t\t- ACE";
textBoxContributors.Text += "\r\n* Justin White\t\t- SA";
textBoxContributors.Text += "\r\n* Chris Ransom\t\t- SA";
textBoxContributors.Text += "\r\n* Mike Ricks\t\t- Red Team";
textBoxContributors.Text += "\r\n* Randy Santossio\t\t- Surface";
textBoxContributors.Text += "\r\n* Ashish Sen Jaswal\t\t- Device Health";
textBoxContributors.Text += "\r\n* Zoltan Harmath\t\t- Security Tools";
textBoxContributors.Text += "\r\n* Luciano Krigun\t\t- Security Products";
textBoxContributors.Text += "\r\n* Jo Hemmerlein\t\t- Red Team";
textBoxContributors.Text += "\r\n* Chris Johnson\t\t- Surface Hub";
textBoxContributors.Text += "\r\n* Loren Ponten\t\t- Surface Hub";
textBoxContributors.Text += "\r\n* Paul Schmitt\t\t- WWL";
textBoxContributors.Text += "\r\n\r\n* 还有我们的众多用户!";
}
internal static string AssemblyTitle
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
if (attributes.Length > 0)
{
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
if (titleAttribute.Title != null && titleAttribute.Title.Length > 0)
{
return titleAttribute.Title;
}
}
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location);
}
}
internal static string AssemblyVersion => Assembly.GetExecutingAssembly().GetName().Version.ToString();
internal static string AssemblyDescription
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
return attributes.Length == 0 ? string.Empty : ((AssemblyDescriptionAttribute)attributes[0]).Description;
}
}
internal static string AssemblyProduct
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
return attributes.Length == 0 ? string.Empty : ((AssemblyProductAttribute)attributes[0]).Product;
}
}
internal static string AssemblyCopyright
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
return attributes.Length == 0 ? string.Empty : ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
}
}
internal static string AssemblyCompany
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
return attributes.Length == 0 ? string.Empty : ((AssemblyCompanyAttribute)attributes[0]).Company;
}
}
private void FrmAbout_FormClosed(object sender, FormClosedEventArgs e)
{
Common.AboutForm = null;
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmInputCallback.cs
================================================
// 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.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Windows.Forms;
//
// Keyboard/Mouse hook callbacks are handled in the message loop of this form.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.frmInputCallback.#InstallKeyboardAndMouseHook()", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders
{
internal partial class FrmInputCallback : System.Windows.Forms.Form
{
internal FrmInputCallback()
{
InitializeComponent();
}
private void FrmInputCallback_Load(object sender, EventArgs e)
{
InstallKeyboardAndMouseHook();
Left = 0;
Top = 0;
Width = 0;
Height = 0;
}
private void FrmInputCallback_Shown(object sender, EventArgs e)
{
Common.InputCallbackForm = this;
Visible = false;
}
private void FrmInputCallback_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason != CloseReason.WindowsShutDown)
{
// e.Cancel = true;
}
}
internal void InstallKeyboardAndMouseHook()
{
/*
* Install hooks:
* According to http://msdn.microsoft.com/en-us/library/ms644986(VS.85).aspx
* we need to process the hook callback message fast enough so make the message loop thread a
* high priority thread. (Mouse/Keyboard event is important)
* */
try
{
Common.Hook = new InputHook();
Common.Hook.MouseEvent += new InputHook.MouseEvHandler(Common.MouseEvent);
Common.Hook.KeyboardEvent += new InputHook.KeybdEvHandler(Common.KeybdEvent);
Logger.Log("(((((Keyboard/Mouse hooks installed/reinstalled!)))))");
/* The hook is called in the context of the thread that installed it.
* The call is made by sending a message to the thread that installed the hook.
* Therefore, the thread that installed the hook must have a message loop!!!
* */
}
catch (Win32Exception e)
{
_ = MessageBox.Show(
"安装鼠标/键盘侦听器失败,错误代码: " + e.ErrorCode,
Application.ProductName,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
Common.MainForm.Quit(false, false); // we are [STAThread] :)
}
// Thread.CurrentThread.Priority = ThreadPriority.Highest;
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmLogon.Designer.cs
================================================
namespace MouseWithoutBorders
{
partial class frmLogon
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmLogon));
this.labelDesktop = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// labelDesktop
//
this.labelDesktop.AutoSize = true;
this.labelDesktop.BackColor = System.Drawing.Color.White;
this.labelDesktop.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.labelDesktop.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelDesktop.ForeColor = System.Drawing.Color.LimeGreen;
this.labelDesktop.Location = new System.Drawing.Point(1, 1);
this.labelDesktop.Name = "labelDesktop";
this.labelDesktop.Size = new System.Drawing.Size(80, 15);
this.labelDesktop.TabIndex = 0;
this.labelDesktop.Text = "微软无界鼠标";
//
// frmLogon
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(83, 17);
this.ControlBox = false;
this.Controls.Add(this.labelDesktop);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "frmLogon";
this.Opacity = 0.5;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "微软无界鼠标";
this.TopMost = true;
this.Load += new System.EventHandler(this.frmLogon_Load);
this.Shown += new System.EventHandler(this.frmLogon_Shown);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmLogon_FormClosing);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label labelDesktop;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMatrix.Designer.cs
================================================
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;
using Windows.UI.Notifications;
namespace MouseWithoutBorders
{
partial class FrmMatrix
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMatrix));
this.pictureBoxMouseWithoutBorders0 = new System.Windows.Forms.PictureBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.comboBoxLockMachine = new System.Windows.Forms.ComboBox();
this.comboBoxSwitchToAllPC = new System.Windows.Forms.ComboBox();
this.comboBoxReconnect = new System.Windows.Forms.ComboBox();
this.checkBoxTwoRow = new System.Windows.Forms.CheckBox();
this.comboBoxEasyMouse = new System.Windows.Forms.ComboBox();
this.checkBoxDrawMouse = new System.Windows.Forms.CheckBox();
this.checkBoxMouseMoveRelatively = new System.Windows.Forms.CheckBox();
this.checkBoxHideMouse = new System.Windows.Forms.CheckBox();
this.checkBoxBlockMouseAtCorners = new System.Windows.Forms.CheckBox();
this.checkBoxCircle = new System.Windows.Forms.CheckBox();
this.checkBoxBlockScreenSaver = new System.Windows.Forms.CheckBox();
this.checkBoxHideLogo = new System.Windows.Forms.CheckBox();
this.checkBoxShareClipboard = new System.Windows.Forms.CheckBox();
this.checkBoxDisableCAD = new System.Windows.Forms.CheckBox();
this.buttonOK = new System.Windows.Forms.Button();
this.checkBoxReverseLookup = new System.Windows.Forms.CheckBox();
this.checkBoxVKMap = new System.Windows.Forms.CheckBox();
this.comboBoxScreenCapture = new System.Windows.Forms.ComboBox();
this.checkBoxSameSubNet = new System.Windows.Forms.CheckBox();
this.checkBoxClipNetStatus = new System.Windows.Forms.CheckBox();
this.checkBoxSendLog = new System.Windows.Forms.CheckBox();
this.groupBoxKeySetup = new System.Windows.Forms.GroupBox();
this.buttonNewKey = new System.Windows.Forms.Button();
this.textBoxEnc = new System.Windows.Forms.TextBox();
this.LabelEnc = new System.Windows.Forms.Label();
this.checkBoxShowKey = new System.Windows.Forms.CheckBox();
this.labelEasyMouse = new System.Windows.Forms.Label();
this.comboBoxEasyMouseOption = new System.Windows.Forms.ComboBox();
this.checkBoxTransferFile = new System.Windows.Forms.CheckBox();
this.toolTipManual = new System.Windows.Forms.ToolTip(this.components);
this.tabPageOther = new System.Windows.Forms.TabPage();
this.groupBoxOtherOptions = new System.Windows.Forms.GroupBox();
this.groupBoxShortcuts = new System.Windows.Forms.GroupBox();
this.labelScreenCapture = new System.Windows.Forms.Label();
this.LabelToggleEasyMouse = new System.Windows.Forms.Label();
this.comboBoxExitMM = new System.Windows.Forms.ComboBox();
this.comboBoxShowSettings = new System.Windows.Forms.ComboBox();
this.labelReconnect = new System.Windows.Forms.Label();
this.labelSwitch2AllPCMode = new System.Windows.Forms.Label();
this.radioButtonDisable = new System.Windows.Forms.RadioButton();
this.radioButtonNum = new System.Windows.Forms.RadioButton();
this.radioButtonF1 = new System.Windows.Forms.RadioButton();
this.labelLockMachine = new System.Windows.Forms.Label();
this.labelExitMM = new System.Windows.Forms.Label();
this.labelShowSettings = new System.Windows.Forms.Label();
this.labelSwitchBetweenMachine = new System.Windows.Forms.Label();
this.tabPageMain = new System.Windows.Forms.TabPage();
this.buttonCancel = new System.Windows.Forms.Button();
this.groupBoxMachineMatrix = new System.Windows.Forms.GroupBox();
this.linkLabelReConfigure = new System.Windows.Forms.LinkLabel();
this.tabControlSetting = new System.Windows.Forms.TabControl();
this.tabPageAdvancedSettings = new System.Windows.Forms.TabPage();
this.groupBoxName2IPPolicyList = new System.Windows.Forms.GroupBox();
this.textBoxMachineName2IPPolicyList = new System.Windows.Forms.TextBox();
this.pictureBoxMouseWithoutBorders = new System.Windows.Forms.PictureBox();
this.groupBoxDNS = new System.Windows.Forms.GroupBox();
this.textBoxMachineName2IP = new System.Windows.Forms.TextBox();
this.textBoxDNS = new System.Windows.Forms.TextBox();
this.linkLabelHelp = new System.Windows.Forms.LinkLabel();
this.linkLabelMiniLog = new System.Windows.Forms.LinkLabel();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders0)).BeginInit();
this.groupBoxKeySetup.SuspendLayout();
this.tabPageOther.SuspendLayout();
this.groupBoxOtherOptions.SuspendLayout();
this.groupBoxShortcuts.SuspendLayout();
this.tabPageMain.SuspendLayout();
this.groupBoxMachineMatrix.SuspendLayout();
this.tabControlSetting.SuspendLayout();
this.tabPageAdvancedSettings.SuspendLayout();
this.groupBoxName2IPPolicyList.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders)).BeginInit();
this.groupBoxDNS.SuspendLayout();
this.SuspendLayout();
//
// pictureBoxMouseWithoutBorders0
//
this.pictureBoxMouseWithoutBorders0.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxMouseWithoutBorders0.BackgroundImage")));
this.pictureBoxMouseWithoutBorders0.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.pictureBoxMouseWithoutBorders0.Location = new System.Drawing.Point(590, 271);
this.pictureBoxMouseWithoutBorders0.Name = "pictureBoxMouseWithoutBorders0";
this.pictureBoxMouseWithoutBorders0.Size = new System.Drawing.Size(190, 54);
this.pictureBoxMouseWithoutBorders0.TabIndex = 16;
this.pictureBoxMouseWithoutBorders0.TabStop = false;
this.pictureBoxMouseWithoutBorders0.Visible = false;
//
// toolTip
//
this.toolTip.AutomaticDelay = 100;
this.toolTip.AutoPopDelay = 5000;
this.toolTip.InitialDelay = 100;
this.toolTip.ReshowDelay = 20;
this.toolTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info;
this.toolTip.ToolTipTitle = "Microsoft® Visual Studio® 2010";
//
// comboBoxLockMachine
//
this.comboBoxLockMachine.Enabled = true;
this.comboBoxLockMachine.FormattingEnabled = true;
this.comboBoxLockMachine.Items.AddRange(new object[] {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"关闭"});
this.comboBoxLockMachine.Location = new System.Drawing.Point(230, 68);
this.comboBoxLockMachine.Name = "comboBoxLockMachine";
this.comboBoxLockMachine.Size = new System.Drawing.Size(54, 21);
this.comboBoxLockMachine.TabIndex = 205;
this.comboBoxLockMachine.Text = "L";
this.toolTip.SetToolTip(this.comboBoxLockMachine, "双击锁定所有电脑。");
this.comboBoxLockMachine.TextChanged += new System.EventHandler(this.ComboBoxLockMachine_TextChanged);
//
// comboBoxSwitchToAllPC
//
this.comboBoxSwitchToAllPC.Enabled = true;
this.comboBoxSwitchToAllPC.FormattingEnabled = true;
this.comboBoxSwitchToAllPC.Items.AddRange(new object[] {
"Ctrl*3",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"关闭"});
this.comboBoxSwitchToAllPC.Location = new System.Drawing.Point(490, 68);
this.comboBoxSwitchToAllPC.Name = "comboBoxSwitchToAllPC";
this.comboBoxSwitchToAllPC.Size = new System.Drawing.Size(56, 21);
this.comboBoxSwitchToAllPC.TabIndex = 206;
this.comboBoxSwitchToAllPC.Text = "关闭";
this.toolTip.SetToolTip(this.comboBoxSwitchToAllPC, "按三次 Ctrl 或者 Ctrl+Alt+[?]");
this.comboBoxSwitchToAllPC.TextChanged += new System.EventHandler(this.ComboBoxSwitchToAllPC_TextChanged);
//
// comboBoxReconnect
//
this.comboBoxReconnect.Enabled = true;
this.comboBoxReconnect.FormattingEnabled = true;
this.comboBoxReconnect.Items.AddRange(new object[] {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"关闭"});
this.comboBoxReconnect.Location = new System.Drawing.Point(230, 95);
this.comboBoxReconnect.Name = "comboBoxReconnect";
this.comboBoxReconnect.Size = new System.Drawing.Size(54, 21);
this.comboBoxReconnect.TabIndex = 207;
this.comboBoxReconnect.Text = "R";
this.toolTip.SetToolTip(this.comboBoxReconnect, "防止连接丢失。");
this.comboBoxReconnect.TextChanged += new System.EventHandler(this.ComboBoxReconnect_TextChanged);
//
// checkBoxTwoRow
//
this.checkBoxTwoRow.AutoSize = true;
this.checkBoxTwoRow.Location = new System.Drawing.Point(9, 205);
this.checkBoxTwoRow.Name = "checkBoxTwoRow";
this.checkBoxTwoRow.Size = new System.Drawing.Size(72, 17);
this.checkBoxTwoRow.TabIndex = 6;
this.checkBoxTwoRow.Text = "双行排列(&R)";
this.toolTip.SetToolTip(this.checkBoxTwoRow, "选中改为上下两行,可上下移动鼠标来切换设备。");
this.checkBoxTwoRow.UseVisualStyleBackColor = true;
this.checkBoxTwoRow.CheckedChanged += new System.EventHandler(this.CheckBoxTwoRow_CheckedChanged);
//
// comboBoxEasyMouse
//
this.comboBoxEasyMouse.Enabled = true;
this.comboBoxEasyMouse.FormattingEnabled = true;
this.comboBoxEasyMouse.Items.AddRange(new object[] {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"关闭"});
this.comboBoxEasyMouse.Location = new System.Drawing.Point(490, 122);
this.comboBoxEasyMouse.Name = "comboBoxEasyMouse";
this.comboBoxEasyMouse.Size = new System.Drawing.Size(56, 21);
this.comboBoxEasyMouse.TabIndex = 208;
this.comboBoxEasyMouse.Text = "E";
this.toolTip.SetToolTip(this.comboBoxEasyMouse, "切换易动功能的开关,易动设置为按住按键开启时该切换无效。");
this.comboBoxEasyMouse.TextChanged += new System.EventHandler(this.ComboBoxEasyMouse_TextChanged);
//
// checkBoxDrawMouse
//
this.checkBoxDrawMouse.AutoSize = true;
this.checkBoxDrawMouse.Checked = true;
this.checkBoxDrawMouse.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxDrawMouse.Location = new System.Drawing.Point(9, 118);
this.checkBoxDrawMouse.Name = "checkBoxDrawMouse";
this.checkBoxDrawMouse.Size = new System.Drawing.Size(117, 17);
this.checkBoxDrawMouse.TabIndex = 171;
this.checkBoxDrawMouse.Text = "绘制鼠标光标(&D)";
this.toolTip.SetToolTip(this.checkBoxDrawMouse, "在 Win10 以上,如果电脑没插鼠标,那么默认不会显示鼠标光标,需要单独绘制。");
this.checkBoxDrawMouse.UseVisualStyleBackColor = true;
this.checkBoxDrawMouse.CheckedChanged += new System.EventHandler(this.CheckBoxDrawMouse_CheckedChanged);
//
// checkBoxMouseMoveRelatively
//
this.checkBoxMouseMoveRelatively.AutoSize = true;
this.checkBoxMouseMoveRelatively.Checked = true;
this.checkBoxMouseMoveRelatively.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxMouseMoveRelatively.Location = new System.Drawing.Point(268, 53);
this.checkBoxMouseMoveRelatively.Name = "checkBoxMouseMoveRelatively";
this.checkBoxMouseMoveRelatively.Size = new System.Drawing.Size(131, 17);
this.checkBoxMouseMoveRelatively.TabIndex = 170;
this.checkBoxMouseMoveRelatively.Text = "鼠标相对移动(&M)";
this.toolTip.SetToolTip(this.checkBoxMouseMoveRelatively, "提供不同屏幕配置和多屏使用的支持。");
this.checkBoxMouseMoveRelatively.UseVisualStyleBackColor = true;
this.checkBoxMouseMoveRelatively.CheckedChanged += new System.EventHandler(this.CheckBoxMouseMoveRelatively_CheckedChanged);
//
// checkBoxHideMouse
//
this.checkBoxHideMouse.AutoSize = true;
this.checkBoxHideMouse.Checked = true;
this.checkBoxHideMouse.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxHideMouse.Location = new System.Drawing.Point(9, 96);
this.checkBoxHideMouse.Name = "checkBoxHideMouse";
this.checkBoxHideMouse.Size = new System.Drawing.Size(156, 17);
this.checkBoxHideMouse.TabIndex = 169;
this.checkBoxHideMouse.Text = "移出屏幕隐藏鼠标(&H)";
this.toolTip.SetToolTip(this.checkBoxHideMouse, "鼠标移出屏幕后,把本设备光标隐藏在屏幕顶部,消除当前窗口焦点,使键盘输入转移到被控电脑。");
this.checkBoxHideMouse.UseVisualStyleBackColor = true;
this.checkBoxHideMouse.CheckedChanged += new System.EventHandler(this.CheckBoxHideMouse_CheckedChanged);
//
// checkBoxBlockMouseAtCorners
//
this.checkBoxBlockMouseAtCorners.AutoSize = true;
this.checkBoxBlockMouseAtCorners.Location = new System.Drawing.Point(268, 75);
this.checkBoxBlockMouseAtCorners.Name = "checkBoxBlockMouseAtCorners";
this.checkBoxBlockMouseAtCorners.Size = new System.Drawing.Size(172, 17);
this.checkBoxBlockMouseAtCorners.TabIndex = 172;
this.checkBoxBlockMouseAtCorners.Text = "屏幕四角阻挡";
this.toolTip.SetToolTip(this.checkBoxBlockMouseAtCorners, "在屏幕四角处阻挡跨界,防止误触。");
this.checkBoxBlockMouseAtCorners.UseVisualStyleBackColor = true;
this.checkBoxBlockMouseAtCorners.CheckedChanged += new System.EventHandler(this.CheckBoxBlockMouseAtCorners_CheckedChanged);
//
// checkBoxCircle
//
this.checkBoxCircle.AutoSize = true;
this.checkBoxCircle.Location = new System.Drawing.Point(9, 11);
this.checkBoxCircle.Name = "checkBoxCircle";
this.checkBoxCircle.Size = new System.Drawing.Size(87, 17);
this.checkBoxCircle.TabIndex = 163;
this.checkBoxCircle.Text = "循环移动(&W)";
this.toolTip.SetToolTip(this.checkBoxCircle, "鼠标移动超过最后一台电脑屏幕后,回到第一台电脑上。");
this.checkBoxCircle.UseVisualStyleBackColor = true;
this.checkBoxCircle.CheckedChanged += new System.EventHandler(this.CheckBoxCircle_CheckedChanged);
//
// checkBoxBlockScreenSaver
//
this.checkBoxBlockScreenSaver.AutoSize = true;
this.checkBoxBlockScreenSaver.Checked = true;
this.checkBoxBlockScreenSaver.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxBlockScreenSaver.Location = new System.Drawing.Point(268, 32);
this.checkBoxBlockScreenSaver.Name = "checkBoxBlockScreenSaver";
this.checkBoxBlockScreenSaver.Size = new System.Drawing.Size(211, 17);
this.checkBoxBlockScreenSaver.TabIndex = 168;
this.checkBoxBlockScreenSaver.Text = "阻止屏保(&B)";
this.toolTip.SetToolTip(this.checkBoxBlockScreenSaver, "阻止被控电脑启动屏幕保护程序。");
this.checkBoxBlockScreenSaver.UseVisualStyleBackColor = true;
this.checkBoxBlockScreenSaver.CheckedChanged += new System.EventHandler(this.CheckBoxBlockScreenSaver_CheckedChanged);
//
// checkBoxHideLogo
//
this.checkBoxHideLogo.AutoSize = true;
this.checkBoxHideLogo.Location = new System.Drawing.Point(9, 75);
this.checkBoxHideLogo.Name = "checkBoxHideLogo";
this.checkBoxHideLogo.Size = new System.Drawing.Size(164, 17);
this.checkBoxHideLogo.TabIndex = 167;
this.checkBoxHideLogo.Text = "登录时不显示 &Logo";
this.toolTip.SetToolTip(this.checkBoxHideLogo, "隐藏登录桌面上的“微软无界鼠标”字样。");
this.checkBoxHideLogo.UseVisualStyleBackColor = true;
this.checkBoxHideLogo.CheckedChanged += new System.EventHandler(this.CheckBoxHideLogo_CheckedChanged);
//
// checkBoxShareClipboard
//
this.checkBoxShareClipboard.AutoSize = true;
this.checkBoxShareClipboard.Checked = true;
this.checkBoxShareClipboard.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxShareClipboard.Location = new System.Drawing.Point(9, 32);
this.checkBoxShareClipboard.Name = "checkBoxShareClipboard";
this.checkBoxShareClipboard.Size = new System.Drawing.Size(101, 17);
this.checkBoxShareClipboard.TabIndex = 165;
this.checkBoxShareClipboard.Text = "共享剪贴板(&S)";
this.toolTip.SetToolTip(this.checkBoxShareClipboard, "共享复制的内容,如果功能突然失效,按 Ctrl + Alt + Del 然后按 Esc 也许可以解决问题。");
this.checkBoxShareClipboard.UseVisualStyleBackColor = true;
this.checkBoxShareClipboard.CheckedChanged += new System.EventHandler(this.CheckBoxShareClipboard_CheckedChanged);
//
// checkBoxDisableCAD
//
this.checkBoxDisableCAD.AutoSize = true;
this.checkBoxDisableCAD.Checked = true;
this.checkBoxDisableCAD.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxDisableCAD.Location = new System.Drawing.Point(268, 11);
this.checkBoxDisableCAD.Name = "checkBoxDisableCAD";
this.checkBoxDisableCAD.Size = new System.Drawing.Size(86, 17);
this.checkBoxDisableCAD.TabIndex = 166;
this.checkBoxDisableCAD.Text = "禁用 Ctrl+Alt+Del 登录(&C)";
this.toolTip.SetToolTip(this.checkBoxDisableCAD, "不需要按 Ctrl+Alt+Del 登录");
this.checkBoxDisableCAD.UseVisualStyleBackColor = true;
this.checkBoxDisableCAD.CheckedChanged += new System.EventHandler(this.CheckBoxDisableCAD_CheckedChanged);
//
// buttonOK
//
this.buttonOK.Location = new System.Drawing.Point(187, 328);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.TabIndex = 20;
this.buttonOK.Text = "应用(&A)";
this.toolTip.SetToolTip(this.buttonOK, "保存设置,刷新连接。");
this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
//
// checkBoxReverseLookup
//
this.checkBoxReverseLookup.AutoSize = true;
this.checkBoxReverseLookup.Location = new System.Drawing.Point(9, 141);
this.checkBoxReverseLookup.Name = "checkBoxReverseLookup";
this.checkBoxReverseLookup.Size = new System.Drawing.Size(196, 17);
this.checkBoxReverseLookup.TabIndex = 173;
this.checkBoxReverseLookup.Text = "验证远程设备地址(&V)";
this.toolTip.SetToolTip(this.checkBoxReverseLookup, "通过反向 DNS 查找来验证远程电脑的 IP 地址(高级功能,如有疑问查看在线帮助)");
this.checkBoxReverseLookup.UseVisualStyleBackColor = true;
this.checkBoxReverseLookup.CheckedChanged += new System.EventHandler(this.CheckBoxReverseLookup_CheckedChanged);
//
// checkBoxVKMap
//
this.checkBoxVKMap.Enabled = false;
this.checkBoxVKMap.AutoSize = true;
this.checkBoxVKMap.Location = new System.Drawing.Point(268, 98);
this.checkBoxVKMap.Name = "checkBoxVKMap";
this.checkBoxVKMap.Size = new System.Drawing.Size(115, 17);
this.checkBoxVKMap.TabIndex = 174;
this.checkBoxVKMap.Text = "启用按键映射(&U)";
this.toolTip.SetToolTip(this.checkBoxVKMap, "使用按键映射来改变快捷键,详情参阅在线帮助。");
this.checkBoxVKMap.UseVisualStyleBackColor = true;
this.checkBoxVKMap.CheckedChanged += new System.EventHandler(this.CheckBoxVKMap_CheckedChanged);
//
// comboBoxScreenCapture
//
this.comboBoxScreenCapture.Enabled = false;
this.comboBoxScreenCapture.FormattingEnabled = true;
this.comboBoxScreenCapture.Items.AddRange(new object[] {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"关闭"});
this.comboBoxScreenCapture.Location = new System.Drawing.Point(230, 121);
this.comboBoxScreenCapture.Name = "comboBoxScreenCapture";
this.comboBoxScreenCapture.Size = new System.Drawing.Size(54, 21);
this.comboBoxScreenCapture.TabIndex = 210;
this.comboBoxScreenCapture.Text = "S";
this.toolTip.SetToolTip(this.comboBoxScreenCapture, "按下快捷键,按住鼠标左键拖动选择屏幕区域,松手完成截屏。");
this.comboBoxScreenCapture.TextChanged += new System.EventHandler(this.ComboBoxScreenCapture_TextChanged);
//
// checkBoxSameSubNet
//
this.checkBoxSameSubNet.AutoSize = true;
this.checkBoxSameSubNet.Location = new System.Drawing.Point(9, 162);
this.checkBoxSameSubNet.Name = "checkBoxSameSubNet";
this.checkBoxSameSubNet.Size = new System.Drawing.Size(114, 18);
this.checkBoxSameSubNet.TabIndex = 175;
this.checkBoxSameSubNet.Text = "仅限内网控制";
this.toolTip.SetToolTip(this.checkBoxSameSubNet, "仅允许连接到同一内网 NNN.NNN.*.* 下的电脑,只支持 IPv4。");
this.checkBoxSameSubNet.UseCompatibleTextRendering = true;
this.checkBoxSameSubNet.UseVisualStyleBackColor = true;
this.checkBoxSameSubNet.CheckedChanged += new System.EventHandler(this.CheckBoxSameSubNet_CheckedChanged);
//
// checkBoxClipNetStatus
//
this.checkBoxClipNetStatus.AutoSize = true;
this.checkBoxClipNetStatus.Location = new System.Drawing.Point(268, 119);
this.checkBoxClipNetStatus.Name = "checkBoxClipNetStatus";
this.checkBoxClipNetStatus.Size = new System.Drawing.Size(231, 18);
this.checkBoxClipNetStatus.TabIndex = 176;
this.checkBoxClipNetStatus.Text = "显示剪贴板/网络活动通知(&N)";
this.toolTip.SetToolTip(this.checkBoxClipNetStatus, "剪贴板和网络状态发生变化时,发送系统通知。");
this.checkBoxClipNetStatus.UseCompatibleTextRendering = true;
this.checkBoxClipNetStatus.UseVisualStyleBackColor = true;
this.checkBoxClipNetStatus.CheckedChanged += new System.EventHandler(this.CheckBoxClipNetStatus_CheckedChanged);
//
// checkBoxSendLog
//
this.checkBoxSendLog.AutoSize = true;
this.checkBoxSendLog.Location = new System.Drawing.Point(268, 142);
this.checkBoxSendLog.Name = "checkBoxSendLog";
this.checkBoxSendLog.Size = new System.Drawing.Size(95, 18);
this.checkBoxSendLog.TabIndex = 177;
this.checkBoxSendLog.Text = "发送错误日志(&E)";
this.toolTip.SetToolTip(this.checkBoxSendLog, "发送匿名错误日志到微软车库来帮助改进本软件。");
this.checkBoxSendLog.UseCompatibleTextRendering = true;
this.checkBoxSendLog.UseVisualStyleBackColor = true;
this.checkBoxSendLog.Visible = false;
this.checkBoxSendLog.CheckedChanged += new System.EventHandler(this.CheckBoxSendLog_CheckedChanged);
//
// groupBoxKeySetup
//
this.groupBoxKeySetup.Controls.Add(this.buttonNewKey);
this.groupBoxKeySetup.Controls.Add(this.textBoxEnc);
this.groupBoxKeySetup.Controls.Add(this.LabelEnc);
this.groupBoxKeySetup.Controls.Add(this.checkBoxShowKey);
this.groupBoxKeySetup.Location = new System.Drawing.Point(3, 6);
this.groupBoxKeySetup.Name = "groupBoxKeySetup";
this.groupBoxKeySetup.Size = new System.Drawing.Size(558, 66);
this.groupBoxKeySetup.TabIndex = 0;
this.groupBoxKeySetup.TabStop = false;
this.groupBoxKeySetup.Text = " 连接(&S)";
this.toolTip.SetToolTip(this.groupBoxKeySetup, "数据通信使用该密码加密。");
//
// buttonNewKey
//
this.buttonNewKey.Location = new System.Drawing.Point(471, 19);
this.buttonNewKey.Name = "buttonNewKey";
this.buttonNewKey.Size = new System.Drawing.Size(75, 23);
this.buttonNewKey.TabIndex = 22;
this.buttonNewKey.Text = "生成(&K)";
this.buttonNewKey.UseVisualStyleBackColor = true;
this.buttonNewKey.Click += new System.EventHandler(this.ButtonNewKey_Click);
//
// textBoxEnc
//
this.textBoxEnc.Location = new System.Drawing.Point(86, 19);
this.textBoxEnc.MaxLength = 22;
this.textBoxEnc.Name = "textBoxEnc";
this.textBoxEnc.PasswordChar = '*';
this.textBoxEnc.Size = new System.Drawing.Size(304, 20);
this.textBoxEnc.TabIndex = 3;
this.toolTip.SetToolTip(this.textBoxEnc, "密码必须自动生成,不可以手动输入。将密码输入到其他设备建立连接。");
//
// LabelEnc
//
this.LabelEnc.AutoSize = true;
this.LabelEnc.Location = new System.Drawing.Point(7, 25);
this.LabelEnc.Name = "LabelEnc";
this.LabelEnc.Size = new System.Drawing.Size(69, 13);
this.LabelEnc.TabIndex = 19;
this.LabelEnc.Text = "密码:";
//
// checkBoxShowKey
//
this.checkBoxShowKey.AutoSize = true;
this.checkBoxShowKey.Location = new System.Drawing.Point(396, 21);
this.checkBoxShowKey.Name = "checkBoxShowKey";
this.checkBoxShowKey.Size = new System.Drawing.Size(73, 17);
this.checkBoxShowKey.TabIndex = 4;
this.checkBoxShowKey.Text = "显示(&S)";
this.checkBoxShowKey.UseVisualStyleBackColor = true;
this.checkBoxShowKey.CheckedChanged += new System.EventHandler(this.CheckBoxShowKey_CheckedChanged);
//
// labelEasyMouse
//
this.labelEasyMouse.AutoSize = true;
this.labelEasyMouse.Location = new System.Drawing.Point(309, 98);
this.labelEasyMouse.Name = "labelEasyMouse";
this.labelEasyMouse.Size = new System.Drawing.Size(68, 13);
this.labelEasyMouse.TabIndex = 211;
this.labelEasyMouse.Text = "易动模式:";
this.toolTip.SetToolTip(this.labelEasyMouse, "如果易动不选择常开,你也可以选择按住 Ctrl 或 Shift 来快速移动到其他电脑。");
//
// comboBoxEasyMouseOption
//
this.comboBoxEasyMouseOption.Enabled = true;
this.comboBoxEasyMouseOption.FormattingEnabled = true;
this.comboBoxEasyMouseOption.Items.AddRange(new object[] {
"开启",
"Ctrl",
"Shift",
"关闭"});
this.comboBoxEasyMouseOption.Location = new System.Drawing.Point(490, 94);
this.comboBoxEasyMouseOption.Name = "comboBoxEasyMouseOption";
this.comboBoxEasyMouseOption.Size = new System.Drawing.Size(56, 21);
this.comboBoxEasyMouseOption.TabIndex = 212;
this.comboBoxEasyMouseOption.Text = "开启";
this.toolTip.SetToolTip(this.comboBoxEasyMouseOption, "移动鼠标到屏幕边缘即可跨电脑移动。");
this.comboBoxEasyMouseOption.TextChanged += new System.EventHandler(this.ComboBoxEasyMouseOption_TextChanged);
//
// checkBoxTransferFile
//
this.checkBoxTransferFile.AutoSize = true;
this.checkBoxTransferFile.Checked = true;
this.checkBoxTransferFile.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBoxTransferFile.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.checkBoxTransferFile.Location = new System.Drawing.Point(26, 51);
this.checkBoxTransferFile.Name = "checkBoxTransferFile";
this.checkBoxTransferFile.Size = new System.Drawing.Size(81, 17);
this.checkBoxTransferFile.TabIndex = 178;
this.checkBoxTransferFile.Text = "自动传输文件(&T)";
this.toolTip.SetToolTip(this.checkBoxTransferFile, "共享复制的文件,复制文件小于 100MB 时,自动传输到别的电脑的剪贴板。");
this.checkBoxTransferFile.UseVisualStyleBackColor = true;
this.checkBoxTransferFile.CheckedChanged += new System.EventHandler(this.CheckBoxTransferFile_CheckedChanged);
//
// toolTipManual
//
this.toolTipManual.ToolTipTitle = "Microsoft® Visual Studio® 2010";
//
// tabPageOther
//
this.tabPageOther.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));
this.tabPageOther.Controls.Add(this.groupBoxOtherOptions);
this.tabPageOther.Controls.Add(this.groupBoxShortcuts);
this.tabPageOther.Location = new System.Drawing.Point(4, 25);
this.tabPageOther.Name = "tabPageOther";
this.tabPageOther.Padding = new System.Windows.Forms.Padding(3);
this.tabPageOther.Size = new System.Drawing.Size(563, 362);
this.tabPageOther.TabIndex = 1;
this.tabPageOther.Text = "配置";
//
// groupBoxOtherOptions
//
this.groupBoxOtherOptions.Controls.Add(this.checkBoxTransferFile);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxSendLog);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxClipNetStatus);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxSameSubNet);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxVKMap);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxReverseLookup);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxDrawMouse);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxMouseMoveRelatively);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxHideMouse);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxBlockMouseAtCorners);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxCircle);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxBlockScreenSaver);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxHideLogo);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxShareClipboard);
this.groupBoxOtherOptions.Controls.Add(this.checkBoxDisableCAD);
this.groupBoxOtherOptions.Dock = System.Windows.Forms.DockStyle.Top;
this.groupBoxOtherOptions.Location = new System.Drawing.Point(3, 3);
this.groupBoxOtherOptions.Name = "groupBoxOtherOptions";
this.groupBoxOtherOptions.Size = new System.Drawing.Size(557, 189);
this.groupBoxOtherOptions.TabIndex = 163;
this.groupBoxOtherOptions.TabStop = false;
//
// groupBoxShortcuts
//
this.groupBoxShortcuts.Controls.Add(this.comboBoxEasyMouseOption);
this.groupBoxShortcuts.Controls.Add(this.labelEasyMouse);
this.groupBoxShortcuts.Controls.Add(this.comboBoxScreenCapture);
this.groupBoxShortcuts.Controls.Add(this.labelScreenCapture);
this.groupBoxShortcuts.Controls.Add(this.comboBoxEasyMouse);
this.groupBoxShortcuts.Controls.Add(this.LabelToggleEasyMouse);
this.groupBoxShortcuts.Controls.Add(this.comboBoxReconnect);
this.groupBoxShortcuts.Controls.Add(this.comboBoxSwitchToAllPC);
this.groupBoxShortcuts.Controls.Add(this.comboBoxExitMM);
this.groupBoxShortcuts.Controls.Add(this.comboBoxLockMachine);
this.groupBoxShortcuts.Controls.Add(this.comboBoxShowSettings);
this.groupBoxShortcuts.Controls.Add(this.labelReconnect);
this.groupBoxShortcuts.Controls.Add(this.labelSwitch2AllPCMode);
this.groupBoxShortcuts.Controls.Add(this.radioButtonDisable);
this.groupBoxShortcuts.Controls.Add(this.radioButtonNum);
this.groupBoxShortcuts.Controls.Add(this.radioButtonF1);
this.groupBoxShortcuts.Controls.Add(this.labelLockMachine);
this.groupBoxShortcuts.Controls.Add(this.labelExitMM);
this.groupBoxShortcuts.Controls.Add(this.labelShowSettings);
this.groupBoxShortcuts.Controls.Add(this.labelSwitchBetweenMachine);
this.groupBoxShortcuts.Dock = System.Windows.Forms.DockStyle.Bottom;
this.groupBoxShortcuts.Location = new System.Drawing.Point(3, 198);
this.groupBoxShortcuts.Name = "groupBoxShortcuts";
this.groupBoxShortcuts.Size = new System.Drawing.Size(557, 161);
this.groupBoxShortcuts.TabIndex = 200;
this.groupBoxShortcuts.TabStop = false;
this.groupBoxShortcuts.Text = " 快捷键(&K) ";
ToolTip groupBoxToolTip = new ToolTip();
groupBoxToolTip.SetToolTip(this.groupBoxShortcuts, "以下设置由 PowerToys 设置界面控制.");
foreach (Control control in this.groupBoxShortcuts.Controls)
{
control.Enabled = false;
}
//
// labelScreenCapture
//
this.labelScreenCapture.AutoSize = true;
this.labelScreenCapture.Location = new System.Drawing.Point(6, 124);
this.labelScreenCapture.Name = "labelScreenCapture";
this.labelScreenCapture.Size = new System.Drawing.Size(173, 13);
this.labelScreenCapture.TabIndex = 209;
this.labelScreenCapture.Text = "区块截屏 Ctrl+Shift+:";
//
// LabelToggleEasyMouse
//
this.LabelToggleEasyMouse.AutoSize = true;
this.LabelToggleEasyMouse.Location = new System.Drawing.Point(309, 125);
this.LabelToggleEasyMouse.Name = "LabelToggleEasyMouse";
this.LabelToggleEasyMouse.Size = new System.Drawing.Size(149, 13);
this.LabelToggleEasyMouse.TabIndex = 114;
this.LabelToggleEasyMouse.Text = "切换易动 Ctrl+Alt+:";
//
// comboBoxExitMM
//
this.comboBoxExitMM.Enabled = false;
this.comboBoxExitMM.FormattingEnabled = true;
this.comboBoxExitMM.Items.AddRange(new object[] {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"关闭"});
this.comboBoxExitMM.Location = new System.Drawing.Point(490, 41);
this.comboBoxExitMM.Name = "comboBoxExitMM";
this.comboBoxExitMM.Size = new System.Drawing.Size(56, 21);
this.comboBoxExitMM.TabIndex = 204;
this.comboBoxExitMM.Text = "Q";
this.comboBoxExitMM.TextChanged += new System.EventHandler(this.ComboBoxExitMM_TextChanged);
//
// comboBoxShowSettings
//
this.comboBoxShowSettings.Enabled = false;
this.comboBoxShowSettings.FormattingEnabled = true;
this.comboBoxShowSettings.Items.AddRange(new object[] {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"关闭"});
this.comboBoxShowSettings.Location = new System.Drawing.Point(230, 41);
this.comboBoxShowSettings.Name = "comboBoxShowSettings";
this.comboBoxShowSettings.Size = new System.Drawing.Size(54, 21);
this.comboBoxShowSettings.TabIndex = 203;
this.comboBoxShowSettings.Text = "M";
this.comboBoxShowSettings.TextChanged += new System.EventHandler(this.ComboBoxShowSettings_TextChanged);
//
// labelReconnect
//
this.labelReconnect.AutoSize = true;
this.labelReconnect.Location = new System.Drawing.Point(6, 98);
this.labelReconnect.Name = "labelReconnect";
this.labelReconnect.Size = new System.Drawing.Size(195, 13);
this.labelReconnect.TabIndex = 59;
this.labelReconnect.Text = "刷新连接 Ctrl+Alt+:";
//
// labelSwitch2AllPCMode
//
this.labelSwitch2AllPCMode.AutoSize = true;
this.labelSwitch2AllPCMode.Location = new System.Drawing.Point(309, 71);
this.labelSwitch2AllPCMode.Name = "labelSwitch2AllPCMode";
this.labelSwitch2AllPCMode.Size = new System.Drawing.Size(122, 13);
this.labelSwitch2AllPCMode.TabIndex = 33;
this.labelSwitch2AllPCMode.Text = "同步模式:";
//
// radioButtonDisable
//
this.radioButtonDisable.AutoSize = true;
this.radioButtonDisable.Location = new System.Drawing.Point(434, 14);
this.radioButtonDisable.Name = "radioButtonDisable";
this.radioButtonDisable.Size = new System.Drawing.Size(60, 17);
this.radioButtonDisable.TabIndex = 202;
this.radioButtonDisable.TabStop = true;
this.radioButtonDisable.Text = "关闭(&D)";
this.radioButtonDisable.UseVisualStyleBackColor = true;
this.radioButtonDisable.CheckedChanged += new System.EventHandler(this.RadioButton_CheckedChanged);
//
// radioButtonNum
//
this.radioButtonNum.AutoSize = true;
this.radioButtonNum.Location = new System.Drawing.Point(346, 15);
this.radioButtonNum.Name = "radioButtonNum";
this.radioButtonNum.Size = new System.Drawing.Size(67, 17);
this.radioButtonNum.TabIndex = 201;
this.radioButtonNum.TabStop = true;
this.radioButtonNum.Text = "&1, 2, 3, 4";
this.radioButtonNum.UseVisualStyleBackColor = true;
this.radioButtonNum.CheckedChanged += new System.EventHandler(this.RadioButton_CheckedChanged);
//
// radioButtonF1
//
this.radioButtonF1.AutoSize = true;
this.radioButtonF1.Location = new System.Drawing.Point(230, 14);
this.radioButtonF1.Name = "radioButtonF1";
this.radioButtonF1.Size = new System.Drawing.Size(91, 17);
this.radioButtonF1.TabIndex = 200;
this.radioButtonF1.TabStop = true;
this.radioButtonF1.Text = "&F1, F2, F3, F4";
this.radioButtonF1.UseVisualStyleBackColor = true;
this.radioButtonF1.CheckedChanged += new System.EventHandler(this.RadioButton_CheckedChanged);
//
// labelLockMachine
//
this.labelLockMachine.AutoSize = true;
this.labelLockMachine.Location = new System.Drawing.Point(6, 71);
this.labelLockMachine.Name = "labelLockMachine";
this.labelLockMachine.Size = new System.Drawing.Size(133, 13);
this.labelLockMachine.TabIndex = 31;
this.labelLockMachine.Text = "全部锁屏 Ctrl+Alt+:";
//
// labelExitMM
//
this.labelExitMM.AutoSize = true;
this.labelExitMM.Location = new System.Drawing.Point(309, 44);
this.labelExitMM.Name = "labelExitMM";
this.labelExitMM.Size = new System.Drawing.Size(138, 13);
this.labelExitMM.TabIndex = 29;
this.labelExitMM.Text = "退出软件 Ctrl+Alt+Shift+:";
//
// labelShowSettings
//
this.labelShowSettings.AutoSize = true;
this.labelShowSettings.Location = new System.Drawing.Point(6, 44);
this.labelShowSettings.Name = "labelShowSettings";
this.labelShowSettings.Size = new System.Drawing.Size(149, 13);
this.labelShowSettings.TabIndex = 27;
this.labelShowSettings.Text = "打开设置 Ctrl+Alt+:";
//
// labelSwitchBetweenMachine
//
this.labelSwitchBetweenMachine.AutoSize = true;
this.labelSwitchBetweenMachine.Location = new System.Drawing.Point(6, 18);
this.labelSwitchBetweenMachine.Name = "labelSwitchBetweenMachine";
this.labelSwitchBetweenMachine.Size = new System.Drawing.Size(179, 13);
this.labelSwitchBetweenMachine.TabIndex = 24;
this.labelSwitchBetweenMachine.Text = "切换设备 Ctrl+Alt+:";
//
// tabPageMain
//
this.tabPageMain.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));
this.tabPageMain.Controls.Add(this.buttonCancel);
this.tabPageMain.Controls.Add(this.groupBoxMachineMatrix);
this.tabPageMain.Controls.Add(this.groupBoxKeySetup);
this.tabPageMain.Controls.Add(this.buttonOK);
this.tabPageMain.Location = new System.Drawing.Point(4, 25);
this.tabPageMain.Name = "tabPageMain";
this.tabPageMain.Padding = new System.Windows.Forms.Padding(3);
this.tabPageMain.Size = new System.Drawing.Size(563, 362);
this.tabPageMain.TabIndex = 0;
this.tabPageMain.Text = "设备";
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(290, 328);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 21;
this.buttonCancel.Text = "关闭(&C)";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);
//
// groupBoxMachineMatrix
//
this.groupBoxMachineMatrix.BackColor = System.Drawing.Color.Transparent;
this.groupBoxMachineMatrix.Controls.Add(this.checkBoxTwoRow);
this.groupBoxMachineMatrix.Controls.Add(this.linkLabelReConfigure);
this.groupBoxMachineMatrix.Location = new System.Drawing.Point(3, 78);
this.groupBoxMachineMatrix.Name = "groupBoxMachineMatrix";
this.groupBoxMachineMatrix.Size = new System.Drawing.Size(558, 244);
this.groupBoxMachineMatrix.TabIndex = 5;
this.groupBoxMachineMatrix.TabStop = false;
this.groupBoxMachineMatrix.Text = " 设备布局(&M) - 拖动设备图标排序,选中图标旁边的勾选框以输入设备名称。 ";
//
// linkLabelReConfigure
//
this.linkLabelReConfigure.Dock = System.Windows.Forms.DockStyle.Bottom;
this.linkLabelReConfigure.Location = new System.Drawing.Point(3, 221);
this.linkLabelReConfigure.Name = "linkLabelReConfigure";
this.linkLabelReConfigure.Size = new System.Drawing.Size(552, 20);
this.linkLabelReConfigure.TabIndex = 304;
this.linkLabelReConfigure.TabStop = true;
this.linkLabelReConfigure.Text = "重新执行软件初始化";
this.linkLabelReConfigure.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.linkLabelReConfigure.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelReConfigure_LinkClicked);
//
// tabControlSetting
//
this.tabControlSetting.Appearance = System.Windows.Forms.TabAppearance.FlatButtons;
this.tabControlSetting.Controls.Add(this.tabPageMain);
this.tabControlSetting.Controls.Add(this.tabPageOther);
this.tabControlSetting.Controls.Add(this.tabPageAdvancedSettings);
this.tabControlSetting.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControlSetting.Location = new System.Drawing.Point(0, 0);
this.tabControlSetting.Name = "tabControlSetting";
this.tabControlSetting.SelectedIndex = 0;
this.tabControlSetting.Size = new System.Drawing.Size(571, 391);
this.tabControlSetting.TabIndex = 20;
//
// tabPageAdvancedSettings
//
this.tabPageAdvancedSettings.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));
this.tabPageAdvancedSettings.Controls.Add(this.groupBoxName2IPPolicyList);
this.tabPageAdvancedSettings.Controls.Add(this.pictureBoxMouseWithoutBorders);
this.tabPageAdvancedSettings.Controls.Add(this.groupBoxDNS);
this.tabPageAdvancedSettings.Controls.Add(this.textBoxDNS);
this.tabPageAdvancedSettings.Location = new System.Drawing.Point(4, 25);
this.tabPageAdvancedSettings.Name = "tabPageAdvancedSettings";
this.tabPageAdvancedSettings.Padding = new System.Windows.Forms.Padding(3);
this.tabPageAdvancedSettings.Size = new System.Drawing.Size(563, 362);
this.tabPageAdvancedSettings.TabIndex = 2;
this.tabPageAdvancedSettings.Text = "高级";
//
// groupBoxName2IPPolicyList
//
this.groupBoxName2IPPolicyList.Controls.Add(this.textBoxMachineName2IPPolicyList);
this.groupBoxName2IPPolicyList.Dock = System.Windows.Forms.DockStyle.Top;
this.groupBoxName2IPPolicyList.Location = new System.Drawing.Point(3, 241);
this.groupBoxName2IPPolicyList.Name = "groupBoxName2IPPolicyList";
this.groupBoxName2IPPolicyList.Size = new System.Drawing.Size(357, 150);
this.groupBoxName2IPPolicyList.TabIndex = 1;
this.groupBoxName2IPPolicyList.TabStop = false;
this.groupBoxName2IPPolicyList.Text = " 组策略设定的 IP 地址映射 [组策略控制]";
this.groupBoxName2IPPolicyList.ForeColor = Color.DimGray;
this.groupBoxName2IPPolicyList.Visible = false;
//
// textBoxMachineName2IPPolicyList
//
this.textBoxMachineName2IPPolicyList.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxMachineName2IPPolicyList.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxMachineName2IPPolicyList.Location = new System.Drawing.Point(3, 172); // 3,172
this.textBoxMachineName2IPPolicyList.MaxLength = 1024;
this.textBoxMachineName2IPPolicyList.Multiline = true;
this.textBoxMachineName2IPPolicyList.Name = "textBoxMachineName2IPPolicyList";
this.textBoxMachineName2IPPolicyList.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.textBoxMachineName2IPPolicyList.Size = new System.Drawing.Size(351, 131);
this.textBoxMachineName2IPPolicyList.TabIndex = 1;
this.textBoxMachineName2IPPolicyList.ReadOnly = true;
this.textBoxMachineName2IPPolicyList.Visible = false;
//
// pictureBoxMouseWithoutBorders
//
this.pictureBoxMouseWithoutBorders.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.pictureBoxMouseWithoutBorders.Dock = System.Windows.Forms.DockStyle.Bottom;
this.pictureBoxMouseWithoutBorders.Location = new System.Drawing.Point(3, 241);
this.pictureBoxMouseWithoutBorders.Name = "pictureBoxMouseWithoutBorders";
this.pictureBoxMouseWithoutBorders.Size = new System.Drawing.Size(557, 118);
this.pictureBoxMouseWithoutBorders.TabIndex = 16;
this.pictureBoxMouseWithoutBorders.TabStop = false;
//
// groupBoxDNS
//
this.groupBoxDNS.Controls.Add(this.textBoxMachineName2IP);
this.groupBoxDNS.Dock = System.Windows.Forms.DockStyle.Top;
this.groupBoxDNS.Location = new System.Drawing.Point(3, 85);
this.groupBoxDNS.Name = "groupBoxDNS";
this.groupBoxDNS.Size = new System.Drawing.Size(557, 150);
this.groupBoxDNS.TabIndex = 0;
this.groupBoxDNS.TabStop = false;
this.groupBoxDNS.Text = " IP 地址映射 ";
//
// textBoxMachineName2IP
//
this.textBoxMachineName2IP.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxMachineName2IP.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxMachineName2IP.Location = new System.Drawing.Point(3, 16);
this.textBoxMachineName2IP.MaxLength = 1024;
this.textBoxMachineName2IP.Multiline = true;
this.textBoxMachineName2IP.Name = "textBoxMachineName2IP";
this.textBoxMachineName2IP.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.textBoxMachineName2IP.Size = new System.Drawing.Size(551, 131);
this.textBoxMachineName2IP.TabIndex = 0;
//
// textBoxDNS
//
this.textBoxDNS.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));
this.textBoxDNS.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBoxDNS.Dock = System.Windows.Forms.DockStyle.Top;
this.textBoxDNS.Location = new System.Drawing.Point(3, 3);
this.textBoxDNS.Multiline = true;
this.textBoxDNS.Name = "textBoxDNS";
this.textBoxDNS.ReadOnly = true;
this.textBoxDNS.Size = new System.Drawing.Size(557, 82);
this.textBoxDNS.TabIndex = 0;
this.textBoxDNS.TabStop = false;
this.textBoxDNS.Text = resources.GetString("textBoxDNS.Text");
//
// linkLabelHelp
//
this.linkLabelHelp.AutoSize = true;
this.linkLabelHelp.Dock = System.Windows.Forms.DockStyle.Right;
this.linkLabelHelp.Location = new System.Drawing.Point(400, 0);
this.linkLabelHelp.Name = "linkLabelHelp";
this.linkLabelHelp.Size = new System.Drawing.Size(124, 13);
this.linkLabelHelp.TabIndex = 300;
this.linkLabelHelp.TabStop = true;
this.linkLabelHelp.Text = "在线帮助(&H)";
this.linkLabelHelp.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelHelp_LinkClicked);
//
// linkLabelMiniLog
//
this.linkLabelMiniLog.AutoSize = true;
this.linkLabelMiniLog.Dock = System.Windows.Forms.DockStyle.Right;
this.linkLabelMiniLog.Location = new System.Drawing.Point(524, 0);
this.linkLabelMiniLog.Name = "linkLabelMiniLog";
this.linkLabelMiniLog.Size = new System.Drawing.Size(47, 13);
this.linkLabelMiniLog.TabIndex = 301;
this.linkLabelMiniLog.TabStop = true;
this.linkLabelMiniLog.Text = "运行日志";
this.linkLabelMiniLog.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelMiniLog_LinkClicked);
//
// frmMatrix
//
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(571, 391);
this.Controls.Add(this.linkLabelHelp);
this.Controls.Add(this.linkLabelMiniLog);
this.Controls.Add(this.tabControlSetting);
this.Controls.Add(this.pictureBoxMouseWithoutBorders0);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "frmMatrix";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "无界鼠标 - 设置";
this.TopMost = true;
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FrmMatrix_FormClosed);
this.Load += new System.EventHandler(this.FrmMatrix_Load);
this.Shown += new System.EventHandler(this.FrmMatrix_Shown);
this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form_DragDrop);
this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form_DragEnter);
this.DragOver += new System.Windows.Forms.DragEventHandler(this.Form_DragOver);
this.DragLeave += new System.EventHandler(this.FrmMatrix_DragLeave);
this.Resize += new System.EventHandler(this.FrmMatrix_Resize);
((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders0)).EndInit();
this.groupBoxKeySetup.ResumeLayout(false);
this.groupBoxKeySetup.PerformLayout();
this.tabPageOther.ResumeLayout(false);
this.groupBoxOtherOptions.ResumeLayout(false);
this.groupBoxOtherOptions.PerformLayout();
this.groupBoxShortcuts.ResumeLayout(false);
this.groupBoxShortcuts.PerformLayout();
this.tabPageMain.ResumeLayout(false);
this.groupBoxMachineMatrix.ResumeLayout(false);
this.groupBoxMachineMatrix.PerformLayout();
this.tabControlSetting.ResumeLayout(false);
this.tabPageAdvancedSettings.ResumeLayout(false);
this.tabPageAdvancedSettings.PerformLayout();
this.groupBoxName2IPPolicyList.ResumeLayout(false);
this.groupBoxName2IPPolicyList.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders)).EndInit();
this.groupBoxDNS.ResumeLayout(false);
this.groupBoxDNS.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private PictureBox pictureBoxMouseWithoutBorders0;
private ToolTip toolTip;
private ToolTip toolTipManual;
private TabPage tabPageOther;
private GroupBox groupBoxShortcuts;
private ComboBox comboBoxReconnect;
private ComboBox comboBoxSwitchToAllPC;
private ComboBox comboBoxExitMM;
private ComboBox comboBoxLockMachine;
private ComboBox comboBoxShowSettings;
private Label labelReconnect;
private Label labelSwitch2AllPCMode;
private RadioButton radioButtonDisable;
private RadioButton radioButtonNum;
private RadioButton radioButtonF1;
private Label labelLockMachine;
private Label labelExitMM;
private Label labelShowSettings;
private Label labelSwitchBetweenMachine;
private TabPage tabPageMain;
private Button buttonCancel;
private GroupBox groupBoxMachineMatrix;
private CheckBox checkBoxTwoRow;
private Button buttonOK;
private TabControl tabControlSetting;
private ComboBox comboBoxEasyMouse;
private Label LabelToggleEasyMouse;
private LinkLabel linkLabelHelp;
private TabPage tabPageAdvancedSettings;
private GroupBox groupBoxDNS;
private TextBox textBoxDNS;
private TextBox textBoxMachineName2IP;
private GroupBox groupBoxName2IPPolicyList;
private TextBox textBoxMachineName2IPPolicyList;
private PictureBox pictureBoxMouseWithoutBorders;
private GroupBox groupBoxOtherOptions;
private CheckBox checkBoxDrawMouse;
private CheckBox checkBoxMouseMoveRelatively;
private CheckBox checkBoxHideMouse;
private CheckBox checkBoxBlockMouseAtCorners;
private CheckBox checkBoxCircle;
private CheckBox checkBoxBlockScreenSaver;
private CheckBox checkBoxHideLogo;
private CheckBox checkBoxShareClipboard;
private CheckBox checkBoxDisableCAD;
private CheckBox checkBoxReverseLookup;
private CheckBox checkBoxVKMap;
private LinkLabel linkLabelMiniLog;
private ComboBox comboBoxScreenCapture;
private Label labelScreenCapture;
private LinkLabel linkLabelReConfigure;
private CheckBox checkBoxSameSubNet;
private CheckBox checkBoxClipNetStatus;
private CheckBox checkBoxSendLog;
private GroupBox groupBoxKeySetup;
private Button buttonNewKey;
private TextBox textBoxEnc;
private Label LabelEnc;
private CheckBox checkBoxShowKey;
private ComboBox comboBoxEasyMouseOption;
private Label labelEasyMouse;
private CheckBox checkBoxTransferFile;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMatrix.cs
================================================
// 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.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Microsoft.PowerToys.Telemetry;
//
// Matrix/Settings form.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
using Timer = System.Windows.Forms.Timer;
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#buttonOK_Click(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#buttonSendHello_Click(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#frmMatrix_Load(System.Object,System.EventArgs)", MessageId = "System.String.ToLower", Justification = "Dotnet port with style preservation")]
// [module: SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#ChangeUI2OneRow(System.Boolean)")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#logoTimer_Tick(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Usage", "CA2213:DisposableFieldsShouldBeDisposed", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#Dispose(System.Boolean)", MessageId = "logoBitmap", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#frmMatrix_Shown(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmMatrix.#PaintMyLogo()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Style", "IDE1006:Naming Styles", Scope = "member", Target = "~M:MouseWithoutBorders.FrmMatrix.M_EnabledChanged(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders
{
internal partial class FrmMatrix : System.Windows.Forms.Form, IDisposable
{
#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager
private Timer helperTimer;
#pragma warning restore CA2213
private bool formShown;
private int formOrgHeight;
private bool matrixOneRow;
internal FrmMatrix()
{
InitializeComponent();
textBoxEnc.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0);
Text = Application.ProductName + " " + Application.ProductVersion + " - 设置";
toolTip.ToolTipTitle = Application.ProductName;
toolTipManual.ToolTipTitle = Application.ProductName;
labelExitMM.Text = "退出软件, Ctrl+Alt+Shift+:";
textBoxMachineName2IP.Text = Setting.Values.Name2IP;
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
buttonCancel.Enabled = false;
Close();
Common.MatrixForm = null;
}
private void ButtonOK_Click(object sender, EventArgs e)
{
buttonOK.Enabled = false;
if (!UpdateKey(Regex.Replace(textBoxEnc.Text, @"\s+", string.Empty)))
{
buttonOK.Enabled = true;
return;
}
string[] st = new string[Common.MAX_MACHINE];
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
if (machines[i].MachineEnabled)
{
for (int j = 0; j < i; j++)
{
if (st[j].Equals(machines[i].MachineName, StringComparison.OrdinalIgnoreCase))
{
machines[i].MachineName = string.Empty;
machines[i].MachineEnabled = false;
}
}
st[i] = machines[i].MachineName;
}
else
{
st[i] = string.Empty;
}
}
Common.MachineMatrix = st;
Setting.Values.MatrixOneRow = matrixOneRow = !checkBoxTwoRow.Checked;
if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
{
Program.StartService();
Common.ShowToolTip("新设置应用于物理控制台会话!", 3000, ToolTipIcon.Warning, false);
}
else
{
SocketStuff.InvalidKeyFound = false;
showInvalidKeyMessage = false;
Common.ReopenSocketDueToReadError = true;
Common.ReopenSockets(true);
for (int i = 0; i < 10; i++)
{
if (Common.AtLeastOneSocketConnected())
{
Common.MMSleep(0.5);
break;
}
Common.MMSleep(0.2);
}
Common.SendMachineMatrix();
}
buttonOK.Enabled = true;
}
internal void UpdateKeyTextBox()
{
_ = Common.GetUserName();
textBoxEnc.Text = Common.MyKey;
}
private void InitAll()
{
formOrgHeight = Height;
matrixOneRow = Setting.Values.MatrixOneRow;
CreateMachines();
LoadSettingsToUI();
UpdateKeyTextBox();
}
private void LoadMachines()
{
bool meAdded = false;
string machineName;
if (Common.MachineMatrix != null && Common.MachineMatrix.Length == Common.MAX_MACHINE)
{
Logger.LogDebug("LoadMachines: Machine Matrix: " + Setting.Values.MachineMatrixString);
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
machineName = Common.MachineMatrix[i].Trim();
machines[i].MachineName = machineName;
if (string.IsNullOrEmpty(machineName))
{
machines[i].CheckAble = true;
}
else
{
machines[i].MachineEnabled = true;
}
bool found = Common.MachinePool.TryFindMachineByName(machineName, out MachineInf machineInfo);
if (found)
{
if (machineInfo.Id == Common.MachineID)
{
machines[i].LocalHost = true;
meAdded = true;
}
}
}
}
if (!meAdded)
{
foreach (Machine m in machines)
{
if (string.IsNullOrEmpty(m.MachineName))
{
m.MachineName = Common.MachineName.Trim();
m.LocalHost = true;
meAdded = true;
break;
}
}
}
}
private void CheckBoxShowKey_CheckedChanged(object sender, EventArgs e)
{
textBoxEnc.PasswordChar = checkBoxShowKey.Checked ? (char)0 : '*';
}
private void FrmMatrix_Shown(object sender, EventArgs e)
{
if (Setting.Values.FirstRun)
{
Setting.Values.FirstRun = false;
Common.ReopenSockets(false);
/*
string fireWallLog = Path.GetDirectoryName(Application.ExecutablePath) + "\\FirewallError.log";
if (File.Exists(fireWallLog))
{
//@"http://bing.com/search?q=Allow+a+program+through+Windows+Firewall"
MessageBox.Show(Application.ProductName + " was unable to add itself to the Firewall exception list.\r\n" +
"The following application needs to be added to the Firewall exception list:\r\n\r\n" +
Application.ExecutablePath +
"\r\n\r\nYou can go to bing.com and do a search on" + "\r\n'Allow a program through Windows Firewall' to know how.",
Application.ProductName,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
linkLabelHelp_LinkClicked(null, null);
* */
}
InitAll();
if (Setting.Values.IsMyKeyRandom)
{
Setting.Values.IsMyKeyRandom = false;
checkBoxShowKey.Checked = true;
}
if (helperTimer == null)
{
helperTimer = new Timer();
helperTimer.Interval = 200;
helperTimer.Tick += new EventHandler(HelperTimer_Tick);
helperTimer.Start();
}
formShown = true;
}
private void FrmMatrix_FormClosed(object sender, FormClosedEventArgs e)
{
/*
if (logoTimer != null)
{
logoTimer.Stop();
logoTimer.Dispose();
logoTimer = null;
}
* */
if (helperTimer != null)
{
helperTimer.Stop();
helperTimer.Dispose();
helperTimer = null;
}
// if (logoBitmap != null) logoBitmap.Dispose();
Common.MatrixForm = null;
}
private int pivot;
private Bitmap logoBitmap;
private void PaintMyLogo()
{
if (!Visible || !(tabControlSetting.SelectedTab == tabPageAdvancedSettings))
{
return;
}
uint rv = 0;
try
{
Color c;
uint cl;
double dC;
logoBitmap ??= new Bitmap(pictureBoxMouseWithoutBorders0.BackgroundImage);
int bWidth = logoBitmap.Width;
int bHeight = logoBitmap.Height;
double dx = (double)pictureBoxMouseWithoutBorders.Width / bWidth;
double dy = (double)pictureBoxMouseWithoutBorders.Height / bHeight;
IntPtr hdc = NativeMethods.GetWindowDC(pictureBoxMouseWithoutBorders.Handle);
for (int i = 0; i < bWidth; i++)
{
for (int j = 0; j < bHeight; j++)
{
c = logoBitmap.GetPixel(i, j);
// c.G > 245
if (c.R < 240 && c.B < 240)
{
dC = Math.Abs(pivot - i);
if (bWidth - pivot + i < dC)
{
dC = bWidth - pivot + i;
}
if (bWidth - i + pivot < dC)
{
dC = bWidth - i + pivot;
}
dC /= bWidth;
// c = Color.FromArgb(80, (int)(255 - 255 * dC), 80);
cl = (160 << 16) | ((uint)(255 - (255 * dC)) << 8) | 160;
// Using GDI SetPixel so we dont have to assign the image later on
// b.SetPixel(i, j, c);
rv = NativeMethods.SetPixel(hdc, (int)(i * dx), (int)(j * dy), cl);
}
}
}
// Image im = pictureBoxMouseWithoutBorders.BackgroundImage;
// pictureBoxMouseWithoutBorders.BackgroundImage = b;
// if (im != null) im.Dispose();
rv = (uint)NativeMethods.ReleaseDC(pictureBoxMouseWithoutBorders.Handle, hdc);
pivot = (pivot + 5) % bWidth;
}
catch (Exception ee)
{
Logger.Log(ee);
Logger.Log(rv.ToString(CultureInfo.CurrentCulture));
}
}
private void AddNewMachine()
{
string newMachine;
Machine unUsedMachine;
foreach (MachineInf inf in Common.MachinePool.ListAllMachines())
{
bool found = false;
unUsedMachine = null;
newMachine = inf.Name.Trim();
foreach (Machine m in machines)
{
if (m.MachineName.Equals(
newMachine,
StringComparison.OrdinalIgnoreCase))
{
found = true;
}
else if (unUsedMachine == null && string.IsNullOrEmpty(m.MachineName.Trim()))
{
unUsedMachine = m;
}
}
if (!found && unUsedMachine != null)
{
unUsedMachine.MachineName = newMachine;
}
}
}
private int helperTimerCounter;
private bool showInvalidKeyMessage;
private void HelperTimer_Tick(object sender, EventArgs e)
{
string keyNotMatchedMachines = string.Empty;
if (Setting.Values.Changed)
{
Setting.Values.Changed = false;
matrixOneRow = Setting.Values.MatrixOneRow;
LoadSettingsToUI();
/*
if (!Common.InMachineMatrix(Common.MachineName))
{
foreach (Machine m in machines)
{
if (!m.LocalHost)
{
m.MachineEnabled = false;
}
}
}
* */
}
helperTimerCounter++;
// 1 sec
if (helperTimerCounter % 5 == 0)
{
comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString();
if (!textBoxMachineName2IP.Text.Equals(Setting.Values.Name2IP, StringComparison.OrdinalIgnoreCase))
{
Setting.Values.Name2IP = textBoxMachineName2IP.Text;
}
// 2 times
if (helperTimerCounter < 15)
{
Common.SendHello();
}
AddNewMachine();
}
// NOTE(@yuyoyuppe): this option is deprecated
// checkBoxVKMap.Checked = Setting.Values.UseVKMap;
foreach (Machine m in machines)
{
if (m.StatusClient != SocketStatus.NA)
{
m.StatusClient = SocketStatus.NA;
}
if (m.StatusServer != SocketStatus.NA)
{
m.StatusServer = SocketStatus.NA;
}
}
SocketStuff sk = Common.Sk;
if (sk != null)
{
lock (sk.TcpSocketsLock)
{
if (sk.TcpSockets != null)
{
foreach (TcpSk t in sk.TcpSockets)
{
if (t.Status == SocketStatus.InvalidKey)
{
keyNotMatchedMachines += string.Format(CultureInfo.CurrentCulture, "[{0}]", t.MachineName);
}
foreach (Machine m in machines)
{
if (m.MachineEnabled)
{
if (m.MachineName.Equals(t.MachineName, StringComparison.OrdinalIgnoreCase))
{
if (t.IsClient)
{
if (t.Status > m.StatusClient)
{
m.StatusClient = t.Status;
}
}
else
{
if (t.Status > m.StatusServer)
{
m.StatusServer = t.Status;
}
}
}
}
}
}
}
}
}
if (SocketStuff.InvalidKeyFound)
{
if (!showInvalidKeyMessage)
{
showInvalidKeyMessage = true;
Common.ShowToolTip(
"密码不正确。\r\n请检查是否在所有电脑上都输入了同一个密码。\r\n并检查您运行的是否都是同一版本的 "
+ Application.ProductName + "。\r\n" + keyNotMatchedMachines + "\r\n本软件版本: " + FrmAbout.AssemblyVersion,
20000,
ToolTipIcon.Warning,
Setting.Values.ShowClipNetStatus);
}
}
else
{
showInvalidKeyMessage = false;
}
PaintMyLogo();
}
private void ShowKeyErrorMsg(string msg)
{
Common.ShowToolTip(msg, 10000, ToolTipIcon.Error, false);
_ = textBoxEnc.Focus();
textBoxEnc.SelectAll();
}
private bool UpdateKey(string newKey)
{
if (!Common.IsKeyValid(newKey, out string rv))
{
ShowKeyErrorMsg(rv);
return false;
}
if (!newKey.Equals(Common.MyKey, StringComparison.OrdinalIgnoreCase))
{
Common.MyKey = newKey;
Common.GeneratedKey = false;
}
Common.MagicNumber = Common.Get24BitHash(Common.MyKey);
return true;
}
private readonly Machine[] machines = new Machine[Common.MAX_MACHINE];
private Machine dragDropMachine;
private Machine desMachine;
private Machine desMachineX;
private Machine desMachineY;
private Machine oldDesMachine;
private Point desMachinePos;
private Point oldDesMachinePos;
private void CreateMachines()
{
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
Machine m = new();
m.MouseDown += Machine_MouseDown;
m.EnabledChanged += new EventHandler(M_EnabledChanged);
m.Parent = groupBoxMachineMatrix;
m.MachineEnabled = false;
machines[i] = m;
}
FrmMatrix_Resize(this, EventArgs.Empty);
ArrangeMachines();
}
private void ArrangeMachines()
{
Height = matrixOneRow ? formOrgHeight : formOrgHeight + 60;
int dx = (groupBoxMachineMatrix.Width - 40) / 4;
int yOffset = groupBoxMachineMatrix.Height / 3;
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
machines[i].Left = matrixOneRow ? 22 + (i * dx) : 22 + dx + ((i % 2) * dx);
machines[i].Top = matrixOneRow ? yOffset : (yOffset / 2) + (i / 2 * (machines[i].Width + 2));
machines[i].Visible = true;
}
}
private void M_EnabledChanged(object sender, EventArgs e)
{
Machine m = sender as Machine;
SocketStuff sk = Common.Sk;
if (!m.MachineEnabled && sk != null)
{
lock (sk.TcpSocketsLock)
{
if (sk.TcpSockets != null)
{
foreach (TcpSk t in sk.TcpSockets)
{
if (t.MachineName != null && t.MachineName.Equals(m.MachineName.Trim(), StringComparison.OrdinalIgnoreCase))
{
t.Status = SocketStatus.NA;
}
}
}
}
}
}
private void Machine_MouseDown(object sender, MouseEventArgs e)
{
oldDesMachine = desMachine = dragDropMachine = sender as Machine;
desMachinePos.X = desMachine.Left;
desMachinePos.Y = desMachine.Top;
oldDesMachinePos.X = oldDesMachine.Left;
oldDesMachinePos.Y = oldDesMachine.Top;
dragDropMachineOrgX = dragDropMachine.Left;
dragDropMachineOrgY = dragDropMachine.Top;
dragDropMachine.BringToFront();
_ = DoDragDrop(dragDropMachine, DragDropEffects.Move);
}
private int startX;
private int startY;
private int dragDropMachineOrgX;
private int dragDropMachineOrgY;
private void Form_DragEnter(object sender, DragEventArgs e)
{
startX = e.X;
startY = e.Y;
e.Effect = DragDropEffects.Move;
}
private bool IsOnSameRow(Machine m1, Machine m2)
{
return matrixOneRow || (m1 == dragDropMachine ? desMachinePos.Y : m1.Top) == m2.Top;
}
private bool IsOnSameCol(Machine m1, Machine m2)
{
return !matrixOneRow && (m1 == dragDropMachine ? desMachinePos.X : m1.Left) == m2.Left;
}
private long lastMove;
private void Form_DragOver(object sender, DragEventArgs e)
{
if (dragDropMachine == null)
{
return;
}
e.Effect = DragDropEffects.Move;
dragDropMachine.Left = dragDropMachineOrgX + (e.X - startX);
dragDropMachine.Top = dragDropMachineOrgY + (e.Y - startY);
/*
dragDropMachine.Left = e.X - dragDropMachine.MouseDownPos.X - Left - 3
- groupBoxMachineMatrix.Left - tabControlSetting.Left;
dragDropMachine.Top = e.Y - dragDropMachine.MouseDownPos.Y - Top - 25
- groupBoxMachineMatrix.Top - tabControlSetting.Top;
* */
if (!matrixOneRow && Common.GetTick() - lastMove < 500)
{
return;
}
int minX = Math.Abs(dragDropMachine.Left - desMachinePos.X);
int minY = Math.Abs(dragDropMachine.Top - desMachinePos.Y);
desMachineX = desMachineY = desMachine;
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
if (machines[i] == dragDropMachine)
{
continue;
}
if (IsOnSameRow(oldDesMachine, machines[i]))
{
if (minX > Math.Abs(dragDropMachine.Left - machines[i].Left))
{
minX = Math.Abs(dragDropMachine.Left - machines[i].Left);
desMachineX = machines[i];
}
}
if (IsOnSameCol(oldDesMachine, machines[i]))
{
if (minY > Math.Abs(dragDropMachine.Top - machines[i].Top))
{
minY = Math.Abs(dragDropMachine.Top - machines[i].Top);
desMachineY = machines[i];
}
}
}
oldDesMachine = desMachine;
desMachine = desMachineY == oldDesMachine ? desMachineX : desMachineX == oldDesMachine ? desMachineY : minX < minY ? desMachineX : desMachineY;
if (desMachine != oldDesMachine)
{
oldDesMachinePos.X = desMachinePos.X;
desMachinePos.X = desMachine.Left;
oldDesMachinePos.Y = desMachinePos.Y;
desMachinePos.Y = desMachine.Top;
desMachine.Left = oldDesMachinePos.X;
desMachine.Top = oldDesMachinePos.Y;
desMachine = dragDropMachine;
lastMove = Common.GetTick();
}
}
private void Form_DragDrop(object sender, DragEventArgs e)
{
if (desMachine != null)
{
dragDropMachine.Left = desMachinePos.X;
dragDropMachine.Top = desMachinePos.Y;
Machine tmp;
for (int i = 0; i < Common.MAX_MACHINE - 1; i++)
{
for (int j = 0; j < Common.MAX_MACHINE - 1 - i; j++)
{
if (machines[j + 1].Top < machines[j].Top || (machines[j + 1].Top == machines[j].Top && machines[j + 1].Left < machines[j].Left))
{
tmp = machines[j];
machines[j] = machines[j + 1];
machines[j + 1] = tmp;
}
}
}
}
}
private void FrmMatrix_DragLeave(object sender, EventArgs e)
{
Form_DragDrop(sender, null);
InputSimulation.MouseUp();
}
private void LoadSettingsToUI()
{
checkBoxCircle.Checked = Setting.Values.MatrixCircle;
checkBoxTwoRow.Checked = !matrixOneRow;
checkBoxBlockMouseAtCorners.Checked = Setting.Values.BlockMouseAtCorners;
checkBoxDrawMouse.Checked = Setting.Values.DrawMouse;
checkBoxReverseLookup.Checked = Setting.Values.ReverseLookup;
checkBoxSameSubNet.Checked = Setting.Values.SameSubNetOnly;
// NOTE(@yuyoyuppe): this option is deprecated
// checkBoxVKMap.Checked = Setting.Values.UseVKMap;
foreach (Machine m in machines)
{
m.MachineName = string.Empty;
m.MachineEnabled = false;
m.LocalHost = false;
}
LoadMachines();
}
internal static readonly string[] Separator = new string[] { "\r\n" };
internal void ShowTip(ToolTipIcon icon, string text, int duration)
{
int x = 0;
text += "\r\n ";
int y = (-text.Split(Separator, StringSplitOptions.None).Length * 15) - 30;
toolTipManual.Hide(this);
toolTipManual.ToolTipIcon = icon;
toolTipManual.Show(text, this, x, y, duration);
}
private void LinkLabelHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
linkLabelHelp.Enabled = false;
linkLabelHelp.Enabled = true;
}
private void CheckBoxShareClipboard_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.ShareClipboard = checkBoxShareClipboard.Checked;
checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = Setting.Values.ShareClipboard;
ShowUpdateMessage();
}
private void CheckBoxTransferFile_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.TransferFile = checkBoxTransferFile.Checked;
ShowUpdateMessage();
Common.HasSwitchedMachineSinceLastCopy = true;
}
private void CheckBoxDisableCAD_CheckedChanged(object sender, EventArgs e)
{
if (!Common.RunWithNoAdminRight)
{
Common.ApplyCADSetting();
ShowUpdateMessage();
}
}
private void FrmMatrix_Load(object sender, EventArgs e)
{
if (Common.RunWithNoAdminRight)
{
checkBoxDisableCAD.Enabled = false;
checkBoxHideLogo.Enabled = false;
}
// Note(@htcfreek): Disable checkboxes of settings that we don't support in the PowerToys implementation
checkBoxDisableCAD.Enabled = false;
checkBoxDisableCAD.Text = checkBoxDisableCAD.Text + " [不支持!]";
checkBoxHideLogo.Enabled = false;
checkBoxHideLogo.Text = checkBoxHideLogo.Text + " [不支持!]";
checkBoxSendLog.Enabled = false;
checkBoxSendLog.Text = checkBoxSendLog.Text + " [不支持!]";
checkBoxShareClipboard.Checked = Setting.Values.ShareClipboard;
if (!Setting.Values.ShareClipboard)
{
checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = false;
}
else
{
checkBoxTransferFile.Checked = Setting.Values.TransferFile;
}
checkBoxDisableCAD.Checked = Setting.Values.DisableCAD;
checkBoxHideLogo.Checked = Setting.Values.HideLogonLogo;
checkBoxHideMouse.Checked = Setting.Values.HideMouse;
checkBoxBlockScreenSaver.Checked = Setting.Values.BlockScreenSaver;
checkBoxMouseMoveRelatively.Checked = Setting.Values.MoveMouseRelatively;
checkBoxClipNetStatus.Checked = Setting.Values.ShowClipNetStatus;
checkBoxSendLog.Checked = Setting.Values.SendErrorLogV2;
if (Setting.Values.HotKeySwitchMachine == (int)VK.F1)
{
radioButtonF1.Checked = true;
}
else if (Setting.Values.HotKeySwitchMachine == '1')
{
radioButtonNum.Checked = true;
}
else
{
radioButtonDisable.Checked = true;
}
comboBoxShowSettings.Text = "关闭";
comboBoxExitMM.Text = Setting.Values.HotKeyExitMM == 0 ? "关闭" : new string(new char[] { (char)Setting.Values.HotKeyExitMM });
#if OBSOLETE_SHORTCUTS
comboBoxLockMachine.Text = Setting.Values.HotKeyLockMachine == 0 ? "关闭" : new string(new char[] { (char)Setting.Values.HotKeyLockMachine });
comboBoxReconnect.Text = Setting.Values.HotKeyReconnect == 0 ? "关闭" : new string(new char[] { (char)Setting.Values.HotKeyReconnect });
comboBoxSwitchToAllPC.Text = Setting.Values.HotKeySwitch2AllPC == 1
? "Ctrl*3"
: Setting.Values.HotKeySwitch2AllPC == 0 ? "关闭" : new string(new char[] { (char)Setting.Values.HotKeySwitch2AllPC });
comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString();
comboBoxEasyMouse.Text = Setting.Values.HotKeyToggleEasyMouse == 0 ? "关闭" : new string(new char[] { (char)Setting.Values.HotKeyToggleEasyMouse });
#endif
// Apply policy configuration on UI elements
// Has to be the last action
if (Setting.Values.ShareClipboardIsGpoConfigured)
{
checkBoxShareClipboard.Enabled = false;
checkBoxShareClipboard.Text += " [组策略控制]";
// transfer file setting depends on clipboard sharing
checkBoxTransferFile.Enabled = false;
}
if (Setting.Values.TransferFileIsGpoConfigured)
{
checkBoxTransferFile.Enabled = false;
checkBoxTransferFile.Text += " [组策略控制]";
}
if (Setting.Values.BlockScreenSaverIsGpoConfigured)
{
checkBoxBlockScreenSaver.Enabled = false;
checkBoxBlockScreenSaver.Text += " [组策略控制]";
}
if (Setting.Values.SameSubNetOnlyIsGpoConfigured)
{
checkBoxSameSubNet.Enabled = false;
checkBoxSameSubNet.Text += " [组策略控制]";
}
if (Setting.Values.ReverseLookupIsGpoConfigured)
{
checkBoxReverseLookup.Enabled = false;
checkBoxReverseLookup.Text += " [组策略控制]";
}
if (Setting.Values.Name2IpIsGpoConfigured)
{
textBoxMachineName2IP.Enabled = false;
groupBoxDNS.ForeColor = Color.DimGray;
groupBoxDNS.Text += " [组策略控制]";
}
if (Setting.Values.Name2IpPolicyListIsGpoConfigured)
{
pictureBoxMouseWithoutBorders.Visible = false;
groupBoxName2IPPolicyList.Visible = true;
textBoxMachineName2IPPolicyList.Visible = true;
textBoxMachineName2IPPolicyList.Text = Setting.Values.Name2IpPolicyList;
}
}
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton r = sender as RadioButton;
if (r.Checked)
{
Setting.Values.HotKeySwitchMachine = sender.Equals(radioButtonF1) ? (int)VK.F1 : sender.Equals(radioButtonNum) ? '1' : 0;
ShowUpdateMessage();
}
}
private void ComboBoxShowSettings_TextChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void ComboBoxExitMM_TextChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void ComboBoxLockMachine_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxLockMachine.Text.Contains("关闭"))
{
Setting.Values.HotKeyLockMachine = 0;
}
else if (comboBoxLockMachine.Text.Length > 0)
{
Setting.Values.HotKeyLockMachine = comboBoxLockMachine.Text[0];
}
#endif
}
private void ComboBoxSwitchToAllPC_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxSwitchToAllPC.Text.Contains("关闭"))
{
Setting.Values.HotKeySwitch2AllPC = 0;
}
else if (comboBoxSwitchToAllPC.Text.Contains("Ctrl*3"))
{
Setting.Values.HotKeySwitch2AllPC = 1;
}
else if (comboBoxSwitchToAllPC.Text.Length > 0)
{
Setting.Values.HotKeySwitch2AllPC = comboBoxSwitchToAllPC.Text[0];
}
#endif
ShowUpdateMessage();
}
private void CheckBoxHideLogo_CheckedChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void ShowUpdateMessage()
{
if (!formShown)
{
return;
}
foreach (Control c in tabPageOther.Controls)
{
if (c != groupBoxShortcuts)
{
c.Enabled = false;
}
}
foreach (Control c in groupBoxShortcuts.Controls)
{
if (c != pictureBoxMouseWithoutBorders)
{
c.Enabled = false;
}
}
for (int i = 0; i < 3; i++)
{
Application.DoEvents();
Thread.Sleep(20);
}
foreach (Control c in tabPageOther.Controls)
{
if (c != groupBoxShortcuts)
{
c.Enabled = true;
}
}
foreach (Control c in groupBoxShortcuts.Controls)
{
if (c != pictureBoxMouseWithoutBorders && c != comboBoxExitMM && c != comboBoxShowSettings && c != comboBoxScreenCapture)
{
c.Enabled = true;
}
}
}
private void CheckBoxBlockScreenSaver_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.BlockScreenSaver = checkBoxBlockScreenSaver.Checked;
ShowUpdateMessage();
}
private void ComboBoxReconnect_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxReconnect.Text.Contains("关闭"))
{
Setting.Values.HotKeyReconnect = 0;
}
else if (comboBoxReconnect.Text.Length > 0)
{
Setting.Values.HotKeyReconnect = comboBoxReconnect.Text[0];
}
#endif
ShowUpdateMessage();
}
private void CheckBoxCircle_CheckedChanged(object sender, EventArgs e)
{
if (Setting.Values.MatrixCircle != checkBoxCircle.Checked)
{
Setting.Values.MatrixCircle = checkBoxCircle.Checked;
ShowUpdateMessage();
Common.SendMachineMatrix();
}
}
private void CheckBoxBlockMouseAtCorners_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.BlockMouseAtCorners = checkBoxBlockMouseAtCorners.Checked;
ShowUpdateMessage();
}
private void CheckBoxHideMouse_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.HideMouse = checkBoxHideMouse.Checked;
ShowUpdateMessage();
}
private void ComboBoxEasyMouseOption_TextChanged(object sender, EventArgs e)
{
string selectedOption = comboBoxEasyMouseOption.Text;
int oldEasyMouseOption = Setting.Values.EasyMouse;
Setting.Values.EasyMouse = Enum.TryParse(selectedOption, out EasyMouseOption easyMouseOption) ? (int)easyMouseOption : (int)EasyMouseOption.开启;
if (oldEasyMouseOption != Setting.Values.EasyMouse)
{
ShowUpdateMessage();
}
}
private void ComboBoxEasyMouse_TextChanged(object sender, EventArgs e)
{
#if OBSOLETE_SHORTCUTS
if (comboBoxEasyMouse.Text.Contains("关闭"))
{
Setting.Values.HotKeyToggleEasyMouse = 0;
}
else if (comboBoxEasyMouse.Text.Length > 0)
{
Setting.Values.HotKeyToggleEasyMouse = comboBoxEasyMouse.Text[0];
}
#endif
ShowUpdateMessage();
}
private void CheckBoxMouseMoveRelatively_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.MoveMouseRelatively = checkBoxMouseMoveRelatively.Checked;
ShowUpdateMessage();
}
private void CheckBoxDrawMouse_CheckedChanged(object sender, EventArgs e)
{
if (!(Setting.Values.DrawMouse = checkBoxDrawMouse.Checked))
{
CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);
}
ShowUpdateMessage();
}
private void CheckBoxTwoRow_CheckedChanged(object sender, EventArgs e)
{
matrixOneRow = !checkBoxTwoRow.Checked;
ArrangeMachines();
}
private void ButtonNewKey_Click(object sender, EventArgs e)
{
string message = "确定要生成新密码吗?\r\n" +
"所有现有的连接会被取消,您需要重新输入密码来建立所有连接。";
if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();
textBoxEnc.Text = Common.MyKey;
checkBoxShowKey.Checked = true;
Common.GeneratedKey = true;
ButtonOK_Click(null, null);
Common.ShowToolTip("新密码已生成,需要在其他电脑上输入新的密码来重新连接。", 10000, ToolTipIcon.Info, false);
}
}
private void CheckBoxClipNetStatus_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.ShowClipNetStatus = checkBoxClipNetStatus.Checked;
ShowUpdateMessage();
}
private void CheckBoxSendLog_CheckedChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void FrmMatrix_Resize(object sender, EventArgs e)
{
if (WindowState != FormWindowState.Minimized)
{
groupBoxMachineMatrix.Top = groupBoxKeySetup.Top + groupBoxKeySetup.Height + 10;
groupBoxMachineMatrix.Height = ClientSize.Height - groupBoxKeySetup.Height - (int)(buttonOK.Height * 3.5);
checkBoxTwoRow.Top = groupBoxMachineMatrix.Height - (int)(checkBoxTwoRow.Height * 1.4);
buttonOK.Top = groupBoxMachineMatrix.Bottom + (int)(buttonOK.Height * 0.3);
buttonCancel.Top = groupBoxMachineMatrix.Bottom + (int)(buttonCancel.Height * 0.3);
groupBoxShortcuts.Height = ClientSize.Height - groupBoxOtherOptions.Bottom - 40;
groupBoxDNS.Height = ClientSize.Height - pictureBoxMouseWithoutBorders.Height - textBoxDNS.Height - 70;
}
}
private void CheckBoxReverseLookup_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.ReverseLookup = checkBoxReverseLookup.Checked;
ShowUpdateMessage();
}
private void CheckBoxVKMap_CheckedChanged(object sender, EventArgs e)
{
// NOTE(@yuyoyuppe): this option is deprecated
// Setting.Values.UseVKMap = checkBoxVKMap.Checked;
ShowUpdateMessage();
}
private void LinkLabelMiniLog_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string miniLog = Common.GetMiniLog(new[] { groupBoxOtherOptions.Controls, groupBoxShortcuts.Controls });
Clipboard.SetText(miniLog);
Common.ShowToolTip("运行日志已复制到剪贴板", 30000, ToolTipIcon.Info, false);
}
private void ComboBoxScreenCapture_TextChanged(object sender, EventArgs e)
{
ShowUpdateMessage();
}
private void LinkLabelReConfigure_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string message = "警告:这将清除当前布局,重置所有设置,重新运行软件初始教程。对于 PowerToys 用户,请使用 PowerToys 设置,而不是这个初始化。\r\n";
message += "你将需要重新初始化所有要连接的电脑。在接下去的选择窗口中,对于第一台电脑请选“否”,剩下的选“是”。\r\n";
message += "接着按照步骤完成配置。\r\n\r\n";
message += "您确定要继续吗?";
if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
{
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIReconfigureEvent());
ButtonCancel_Click(this, new EventArgs());
Setting.Values.FirstRun = true;
Setting.Values.EasyMouse = (int)EasyMouseOption.开启;
Common.ClearComputerMatrix();
Common.ShowSetupForm(true);
}
}
private void CheckBoxSameSubNet_CheckedChanged(object sender, EventArgs e)
{
Setting.Values.SameSubNetOnly = checkBoxSameSubNet.Checked;
ShowUpdateMessage();
}
#if USE_TO_CREATE_LOGO_BITMAP
private void PaintMyLogo()
{
Graphics g = Graphics.FromHwnd(this.Handle);
Font font = new Font("Chiller", 40);
g.DrawString(Common.BinaryName, font, Brushes.Lime, comboBoxIPs.Right + 50, comboBoxIPs.Bottom - 5);
Bitmap b = new Bitmap(220, 100);
Graphics g2 = Graphics.FromImage(b);
g2.FillRectangle(Brushes.WhiteSmoke, 0, 0, 220, 100);
g2.DrawString(Common.BinaryName, font, Brushes.Lime, 0, 0);
b.Save("c:\\zzz.bmp");
string p = "";
Color c;
int l = 0;
for (int i = 0; i < b.Width; i++)
{
for (int j = 0; j < b.Height; j++)
{
c = b.GetPixel(i, j);
if (c.G > 0)
{
p += "{" + i + "," + j + "},";
l++;
}
}
p += "\r\n";
}
//File.WriteAllText("c:\\zzz.txt", l + ":" + p, Encoding.Unicode);
b.Dispose();
g2.Dispose();
}
#endif
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMatrix.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
iVBORw0KGgoAAAANSUhEUgAAAN4AAAAaCAYAAADYHuIVAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
vAAADrwBlbxySQAABjpJREFUeF7tmzF25DYQROeCvocPsUfwCXwB58433tSpQ4fOfAOZf96WWFtqkIA4
Inae+CtYTRMgGo1GExxpby8XFw/mj++6aNPceF++6+Li4vFcT7yLh/H3olunfl3036LPyvDG+7rIA/jv
oovjkIQe178WPRu/LPI5uH5bpFxh02H7fdHZaGzp26IZvNl4BEdO/bPIqSoawb44TibEM8bV/Zco1ImK
zIw5rp6tmsGbUXmvk0P5guzXXBfHyafFjKfBUdx/tPU0UZuzIac1Npr1PcYPM88nGlVY8PTza66Ll/tR
Cr0X+npMn/H9x/1HLZgbhWZe0q86smZH+CE6WnyvvjqX57ud62KFAvWe994/Fz1zTPMdFbUgRuTYrKe6
H+uro/AZvEbHA8eTj6Dws44LW99YfXZy07xnMb2wzXj3eQTyX2pB4jPHWU91f2XK7zHO4jU6vvCgjaZH
MclFsPi2Te2kz46fEFrxIMm2Es3j70f8Gez52iKPyxUkPfGa+W34no9n8DqykscXnc/YgYCh6l3vs+Mx
qd4ZdHpAFLCKLGiz6PG1Bacj9UWOjpfk18xNBy0fz+Q+sv8Kwc/dOhKQFPzMQlQbb9bj+lkgdh6viozr
LHp8bZFzIK/8WOca3dSPxP2YxX1kr1T+fuLVjwXh+OGbVLo23jZ+BCMRW6gNmkWvry3U10Xu6A8CfHOe
8UcCjI0cjY9mcR/ZN5j/7sW/UPFFkE068+jA5s/fxaCf5fhSfbGS7z4ur/xuT52RpNDrawtvX8UCPK8+
mmoc2dL+SPby9D5ydUFoIQiWoIKsPd4639qwvTAmcphIHmVcehcV1ZMZ9SawH5Fam1pjZDw0ZxLV7Yhr
rS8u9J7dkq8BHIlzxnjU1xbefwsV+9ycvXNyf7f+J4Riyroj5qN+yOnNma2xe/P0zcbrgQXzPr44OTHU
SlwCqzaanDud+JM55Unki8dEGT/77h2PfRPkUYXAI1W0rGyKh89P8kXEJyRyA+Mj7fXZ2/bGuTfGo75W
pE9baI08tiO5k0XKN4OSGzJXU2IkZ/bGzn4u5ektG/XgyZB93AlEMJVQmexrqzVYSoqq2vmEW8cY8Dlp
E+SiarwW1RxZDP8sfzyRUeLXWokEHjuvpNrY7nNvnNcWfTFeW2/7WuHxQXtku5HcyfWR3OcsiORFK3dH
cmZvbOUFauXpzRuhXrw6O15hlDzuqAcwq5ESgX+rpPD2XG8lhtpsiUDv4e3BF8c3G7hvTi7eFh4nKrAj
u+iN80iMR3ytIMm8vxcKzzN8An0WvXMSsqOcC/h1jdmao9ta8pxxe47t8+Balac3LqhRTzIKryaOB1iV
A/TNqR8t0kGNL1tFVrGqonhRcOEbfrhfW3hfFj1jpZ9FfobRZG61S3tvnEdiPOqrk32RNg9koVb71ubc
mpNQW+RfCkL6wwYWbhejOeNtcmzYy9Ox6BpeiRzZ0g5przavP0mywjl+Jkf+hPDKewRfDBKWRdC/squS
gmyJ7NW1hPv5PUX212e3CbePxlh2NIr3RWx0oc2D8InPXN/bEKKyy5Z20bpe2UdzRm332rfy9LUXSZYV
ZQ/dzBfPK6zbqRjc35OqOkYoUUjurBK8A3Dd0YL6IoPum+1HyHcO/Nc8ZPP5yJbIXl1L8LfyOfv3xnk0
xmqLRsj3O8nj4ycGxia+Tu+chNqiCj+V+P1ka92vJ2fUFiU9eToW3UCB8sXLBWCHEzg9JTKgasd1JQnO
Ve3VNqnsLT9QL14FkYLpG88DLFsie3UtIQaMm35m/944Y1ObkRijEXxTVWJcfKmO6GIkd0DtuN5CbRD3
93jkxhvJGbWpxta1xO1j0Q1wjBvpvUEwAU9OifYJk/JKRz9sCoJPzBeNCsL9tCitKpVPLUQS9KD5ZT/G
ks3nJFviSbmH5pTzqfr3xnkkxiO+OloHF/GqfMx8cUZyR9dyAzncr/INtfr15Izs1T168vTQxgOChM5C
j2xXHlkeiS8aiwgsgmw9T+RciC2qzSDbGXEe8dXxmFSb5CNQkRhdf9aMfh7jUfbG3svTp9t4Z6OnW1Y2
BdPRYmiDOp7QtNuC63ttPpIRX58Rnvaa3ywOj8z7iL/jXVw8AxQUnnhswvN5efkf+nnqL5jaAGcAAAAA
SUVORK5CYII=
17, 17
107, 17
一般可以直接用设备名连接到其他电脑。如果名称解析出错,可以手动指定 IP 地址映射。
注意:如果电脑使用动态 IP 地址,那么每次对方 IP 变动时都要手动更改。
58
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==
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMessage.Designer.cs
================================================
namespace MouseWithoutBorders
{
partial class FrmMessage
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMessage));
this.labelTitle = new System.Windows.Forms.Label();
this.textExtraInfo = new System.Windows.Forms.TextBox();
this.timerLife = new System.Windows.Forms.Timer(this.components);
this.labelLifeTime = new System.Windows.Forms.Label();
this.textBoxMessage = new System.Windows.Forms.TextBox();
this.pictureBoxIcon = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBoxIcon)).BeginInit();
this.SuspendLayout();
//
// labelTitle
//
this.labelTitle.AutoSize = true;
this.labelTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelTitle.Location = new System.Drawing.Point(21, 0);
this.labelTitle.Name = "labelTitle";
this.labelTitle.Size = new System.Drawing.Size(168, 16);
this.labelTitle.TabIndex = 0;
this.labelTitle.Text = "无界鼠标";
//
// textExtraInfo
//
this.textExtraInfo.BackColor = System.Drawing.SystemColors.Info;
this.textExtraInfo.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textExtraInfo.Dock = System.Windows.Forms.DockStyle.Bottom;
this.textExtraInfo.Enabled = false;
this.textExtraInfo.Font = new System.Drawing.Font("Microsoft Sans Serif", 63.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textExtraInfo.Location = new System.Drawing.Point(0, 161);
this.textExtraInfo.Margin = new System.Windows.Forms.Padding(20);
this.textExtraInfo.Multiline = true;
this.textExtraInfo.Name = "textExtraInfo";
this.textExtraInfo.ReadOnly = true;
this.textExtraInfo.Size = new System.Drawing.Size(720, 239);
this.textExtraInfo.TabIndex = 3;
this.textExtraInfo.Text = "???\r\nLLL";
this.textExtraInfo.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// timerLife
//
this.timerLife.Enabled = true;
this.timerLife.Interval = 1000;
this.timerLife.Tick += new System.EventHandler(this.TimerLife_Tick);
//
// labelLifeTime
//
this.labelLifeTime.AutoSize = true;
this.labelLifeTime.Dock = System.Windows.Forms.DockStyle.Right;
this.labelLifeTime.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelLifeTime.Location = new System.Drawing.Point(720, 0);
this.labelLifeTime.Name = "labelLifeTime";
this.labelLifeTime.Size = new System.Drawing.Size(0, 16);
this.labelLifeTime.TabIndex = 4;
//
// textBoxMessage
//
this.textBoxMessage.BackColor = System.Drawing.SystemColors.Info;
this.textBoxMessage.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBoxMessage.Dock = System.Windows.Forms.DockStyle.Fill;
this.textBoxMessage.Enabled = false;
this.textBoxMessage.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxMessage.Location = new System.Drawing.Point(0, 0);
this.textBoxMessage.Margin = new System.Windows.Forms.Padding(20);
this.textBoxMessage.Multiline = true;
this.textBoxMessage.Name = "textBoxMessage";
this.textBoxMessage.ReadOnly = true;
this.textBoxMessage.Size = new System.Drawing.Size(720, 400);
this.textBoxMessage.TabIndex = 2;
this.textBoxMessage.Text = "Message Text";
this.textBoxMessage.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// pictureBoxIcon
//
this.pictureBoxIcon.Image = ((System.Drawing.Image)(resources.GetObject("pictureBoxIcon.Image")));
this.pictureBoxIcon.Location = new System.Drawing.Point(0, 0);
this.pictureBoxIcon.Name = "pictureBoxIcon";
this.pictureBoxIcon.Size = new System.Drawing.Size(16, 16);
this.pictureBoxIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBoxIcon.TabIndex = 5;
this.pictureBoxIcon.TabStop = false;
//
// frmMessage
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(231)))));
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.ClientSize = new System.Drawing.Size(720, 400);
this.Controls.Add(this.pictureBoxIcon);
this.Controls.Add(this.labelLifeTime);
this.Controls.Add(this.textExtraInfo);
this.Controls.Add(this.labelTitle);
this.Controls.Add(this.textBoxMessage);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "frmMessage";
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "frmMessage";
this.TopMost = true;
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FrmMessage_FormClosed);
((System.ComponentModel.ISupportInitialize)(this.pictureBoxIcon)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label labelTitle;
private System.Windows.Forms.TextBox textExtraInfo;
private System.Windows.Forms.Timer timerLife;
private System.Windows.Forms.Label labelLifeTime;
private System.Windows.Forms.TextBox textBoxMessage;
private System.Windows.Forms.PictureBox pictureBoxIcon;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmScreen.Designer.cs
================================================
namespace MouseWithoutBorders
{
partial class FrmScreen
{
///
/// Required designer variable.
///
private System.ComponentModel.IContainer components = null;
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmScreen));
this.MainMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.menuExit = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.menuAbout = new System.Windows.Forms.ToolStripMenuItem();
this.menuHelp = new System.Windows.Forms.ToolStripMenuItem();
this.menuGenDumpFile = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.menuGetScreenCapture = new System.Windows.Forms.ToolStripMenuItem();
this.menuGetFromAll = new System.Windows.Forms.ToolStripMenuItem();
this.menuSendScreenCapture = new System.Windows.Forms.ToolStripMenuItem();
this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.menuSend2Myself = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.menuWindowsPhone = new System.Windows.Forms.ToolStripMenuItem();
this.menuWindowsPhoneEnable = new System.Windows.Forms.ToolStripMenuItem();
this.menuWindowsPhoneDownload = new System.Windows.Forms.ToolStripMenuItem();
this.menuWindowsPhoneInformation = new System.Windows.Forms.ToolStripMenuItem();
this.menuReinstallKeyboardAndMouseHook = new System.Windows.Forms.ToolStripMenuItem();
this.menuMachineMatrix = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.MenuAllPC = new System.Windows.Forms.ToolStripMenuItem();
this.dUCTDOToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.tRUONG2DToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.NotifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
this.picLogonLogo = new System.Windows.Forms.PictureBox();
this.MainMenu.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picLogonLogo)).BeginInit();
this.SuspendLayout();
//
// MainMenu
//
this.MainMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.menuExit,
this.toolStripSeparator2,
this.menuAbout,
this.menuHelp,
this.menuGenDumpFile,
this.toolStripSeparator1,
this.menuGetScreenCapture,
this.menuSendScreenCapture,
this.toolStripMenuItem1,
this.menuWindowsPhone,
this.menuReinstallKeyboardAndMouseHook,
this.menuMachineMatrix,
this.toolStripMenuItem2,
this.MenuAllPC,
this.dUCTDOToolStripMenuItem,
this.tRUONG2DToolStripMenuItem});
this.MainMenu.Name = "MainMenu";
this.MainMenu.Size = new System.Drawing.Size(197, 292);
this.MainMenu.Opening += new System.ComponentModel.CancelEventHandler(this.MainMenu_Opening);
this.MainMenu.MouseLeave += new System.EventHandler(this.MainMenu_MouseLeave);
//
// menuExit
//
this.menuExit.ForeColor = System.Drawing.Color.Black;
this.menuExit.Name = "menuExit";
this.menuExit.Size = new System.Drawing.Size(196, 22);
this.menuExit.Text = "退出(&E)";
this.menuExit.Click += new System.EventHandler(this.MenuExit_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(193, 6);
//
// menuAbout
//
this.menuAbout.ForeColor = System.Drawing.Color.Black;
this.menuAbout.Name = "menuAbout";
this.menuAbout.Size = new System.Drawing.Size(196, 22);
this.menuAbout.Text = "关于(&B)";
this.menuAbout.Click += new System.EventHandler(this.MenuAbout_Click);
//
// menuHelp
//
this.menuHelp.Name = "menuHelp";
this.menuHelp.Size = new System.Drawing.Size(196, 22);
this.menuHelp.Text = "帮助(&H)";
this.menuHelp.Click += new System.EventHandler(this.MenuHelp_Click);
//
// menuGenDumpFile
//
this.menuGenDumpFile.Name = "menuGenDumpFile";
this.menuGenDumpFile.Size = new System.Drawing.Size(196, 22);
this.menuGenDumpFile.Text = "运行日志(&G)";
this.menuGenDumpFile.ToolTipText = "创建用于分析问题的日志文件,日志文件将在程序目录下生成。";
this.menuGenDumpFile.Visible = false;
this.menuGenDumpFile.Click += new System.EventHandler(this.MenuGenDumpFile_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(193, 6);
//
// menuGetScreenCapture
//
this.menuGetScreenCapture.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.menuGetFromAll});
this.menuGetScreenCapture.ForeColor = System.Drawing.Color.Black;
this.menuGetScreenCapture.Name = "menuGetScreenCapture";
this.menuGetScreenCapture.Size = new System.Drawing.Size(196, 22);
this.menuGetScreenCapture.Text = "获取截屏自(&G)";
//
// menuGetFromAll
//
this.menuGetFromAll.Enabled = false;
this.menuGetFromAll.Name = "menuGetFromAll";
this.menuGetFromAll.Size = new System.Drawing.Size(85, 22);
this.menuGetFromAll.Text = "所有电脑";
this.menuGetFromAll.Click += new System.EventHandler(this.MenuGetScreenCaptureClick);
//
// menuSendScreenCapture
//
this.menuSendScreenCapture.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.allToolStripMenuItem,
this.menuSend2Myself});
this.menuSendScreenCapture.ForeColor = System.Drawing.Color.Black;
this.menuSendScreenCapture.Name = "menuSendScreenCapture";
this.menuSendScreenCapture.Size = new System.Drawing.Size(196, 22);
this.menuSendScreenCapture.Text = "发送截屏到(&C)";
//
// allToolStripMenuItem
//
this.allToolStripMenuItem.Name = "allToolStripMenuItem";
this.allToolStripMenuItem.Size = new System.Drawing.Size(105, 22);
this.allToolStripMenuItem.Text = "所有电脑";
this.allToolStripMenuItem.Click += new System.EventHandler(this.MenuSendScreenCaptureClick);
//
// menuSend2Myself
//
this.menuSend2Myself.Name = "menuSend2Myself";
this.menuSend2Myself.Size = new System.Drawing.Size(105, 22);
this.menuSend2Myself.Text = "此电脑";
this.menuSend2Myself.Click += new System.EventHandler(this.MenuSendScreenCaptureClick);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(193, 6);
//
// menuReinstallKeyboardAndMouseHook
//
this.menuReinstallKeyboardAndMouseHook.Name = "menuReinstallKeyboardAndMouseHook";
this.menuReinstallKeyboardAndMouseHook.Size = new System.Drawing.Size(196, 22);
this.menuReinstallKeyboardAndMouseHook.Text = "重新安装快捷键侦听器(&R)";
this.menuReinstallKeyboardAndMouseHook.ToolTipText = "This might help when keyboard/Mouse redirection stops working";
this.menuReinstallKeyboardAndMouseHook.Visible = false;
this.menuReinstallKeyboardAndMouseHook.Click += new System.EventHandler(this.MenuReinstallKeyboardAndMouseHook_Click);
//
// menuMachineMatrix
//
this.menuMachineMatrix.Font = new System.Drawing.Font(System.Windows.Forms.Control.DefaultFont.Name, System.Windows.Forms.Control.DefaultFont.Size, System.Drawing.FontStyle.Bold);
this.menuMachineMatrix.ForeColor = System.Drawing.Color.Black;
this.menuMachineMatrix.Name = "menuMachineMatrix";
this.menuMachineMatrix.Size = new System.Drawing.Size(196, 22);
this.menuMachineMatrix.Text = "设置(&S)";
this.menuMachineMatrix.Click += new System.EventHandler(this.MenuMachineMatrix_Click);
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(193, 6);
//
// menuAllPC
//
this.MenuAllPC.CheckOnClick = true;
this.MenuAllPC.Name = "menuAllPC";
this.MenuAllPC.Size = new System.Drawing.Size(196, 22);
this.MenuAllPC.Text = "所有电脑(&A)";
this.MenuAllPC.ToolTipText = "Repeat Mouse/keyboard in all machines.";
this.MenuAllPC.Click += new System.EventHandler(this.MenuAllPC_Click);
//
// dUCTDOToolStripMenuItem
//
this.dUCTDOToolStripMenuItem.Name = "dUCTDOToolStripMenuItem";
this.dUCTDOToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.dUCTDOToolStripMenuItem.Tag = "MACHINE: TEST1";
this.dUCTDOToolStripMenuItem.Text = "DUCTDO";
//
// tRUONG2DToolStripMenuItem
//
this.tRUONG2DToolStripMenuItem.Name = "tRUONG2DToolStripMenuItem";
this.tRUONG2DToolStripMenuItem.Size = new System.Drawing.Size(196, 22);
this.tRUONG2DToolStripMenuItem.Tag = "MACHINE: TEST2";
this.tRUONG2DToolStripMenuItem.Text = "TRUONG2D";
//
// notifyIcon
//
this.NotifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
this.NotifyIcon.BalloonTipText = "Microsoft® Visual Studio® 2010";
this.NotifyIcon.BalloonTipTitle = "Microsoft® Visual Studio® 2010";
this.NotifyIcon.ContextMenuStrip = this.MainMenu;
this.NotifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon")));
this.NotifyIcon.Text = "Microsoft® Visual Studio® 2010";
this.NotifyIcon.MouseDown += new System.Windows.Forms.MouseEventHandler(this.NotifyIcon_MouseDown);
//
// picLogonLogo
//
this.picLogonLogo.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.picLogonLogo.Image = global::MouseWithoutBorders.Properties.Images.MouseWithoutBorders;
this.picLogonLogo.Location = new System.Drawing.Point(99, 62);
this.picLogonLogo.Name = "picLogonLogo";
this.picLogonLogo.Size = new System.Drawing.Size(95, 17);
this.picLogonLogo.TabIndex = 1;
this.picLogonLogo.TabStop = false;
this.picLogonLogo.Visible = false;
//
// frmScreen
//
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.ClientSize = new System.Drawing.Size(10, 10);
this.ControlBox = false;
this.Controls.Add(this.picLogonLogo);
this.Cursor = System.Windows.Forms.Cursors.Default;
this.Enabled = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "frmScreen";
this.Opacity = 0.5D;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
this.Text = "Microsoft® Visual Studio® 2010 Application";
this.TopMost = true;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmScreen_FormClosing);
this.Load += new System.EventHandler(this.FrmScreen_Load);
this.Shown += new System.EventHandler(this.FrmScreen_Shown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FrmScreen_MouseMove);
this.MainMenu.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.picLogonLogo)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ToolStripMenuItem menuExit;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem menuMachineMatrix;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem dUCTDOToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem tRUONG2DToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem menuSendScreenCapture;
private System.Windows.Forms.ToolStripMenuItem menuSend2Myself;
private System.Windows.Forms.ToolStripMenuItem menuGetScreenCapture;
private System.Windows.Forms.ToolStripMenuItem menuGetFromAll;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem allToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem menuAbout;
private System.Windows.Forms.PictureBox picLogonLogo;
private System.Windows.Forms.ToolStripMenuItem menuHelp;
private System.Windows.Forms.ToolStripMenuItem menuReinstallKeyboardAndMouseHook;
private System.Windows.Forms.ToolStripMenuItem menuGenDumpFile;
private System.Windows.Forms.ToolStripMenuItem menuWindowsPhone;
private System.Windows.Forms.ToolStripMenuItem menuWindowsPhoneEnable;
private System.Windows.Forms.ToolStripMenuItem menuWindowsPhoneInformation;
private System.Windows.Forms.ToolStripMenuItem menuWindowsPhoneDownload;
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Form/frmScreen.cs
================================================
// 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.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
using Microsoft.PowerToys.Telemetry;
//
// Startup/main form + helper methods.
//
//
// 2008 created by Truong Do (ductdo).
// 2009-... modified by Truong Do (TruongDo).
// 2023- Included in PowerToys.
//
using MouseWithoutBorders.Class;
using MouseWithoutBorders.Core;
using MouseWithoutBorders.Properties;
using Timer = System.Windows.Forms.Timer;
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#ShowMouseWithoutBordersUiOnWinLogonDesktop(System.Boolean)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#ChangeIcon(System.Int32)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#UpdateMenu(MouseWithoutBorders.MachineInf[])", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#frmScreen_Load(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#MenuNewVersion(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#.ctor()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#LoadPlugins()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#menuPersonalizeLogonScrPluginClick(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)", MessageId = "System.String.ToLower", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#LogonLogo", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Performance", "CA1814:PreferJaggedArraysOverMultidimensional", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#frmScreen_Load(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#LoadNewLogonBackground()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#UncheckAllMenus()", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#WndProc(System.Windows.Forms.Message&)", MessageId = "MouseWithoutBorders.NativeMethods.SendMessage(System.IntPtr,System.Int32,System.IntPtr,System.IntPtr)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#Destroy()", MessageId = "MouseWithoutBorders.NativeMethods.SendMessage(System.IntPtr,System.Int32,System.IntPtr,System.IntPtr)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Usage", "CA1806:DoNotIgnoreMethodResults", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)", MessageId = "MouseWithoutBorders.NativeMethods.SendMessage(System.IntPtr,System.Int32,System.IntPtr,System.IntPtr)", Justification = "Dotnet port with style preservation")]
[module: SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions", Scope = "member", Target = "MouseWithoutBorders.frmScreen.#menuPersonalizeLogonScrPluginClick(System.Object,System.EventArgs)", Justification = "Dotnet port with style preservation")]
namespace MouseWithoutBorders
{
internal partial class FrmScreen : System.Windows.Forms.Form
{
#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager
private Cursor dotCur;
private Cursor dropCur;
private int[,] logonLogo;
private Timer helperTimer;
#pragma warning restore CA2213
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal int CurIcon { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal NotifyIcon NotifyIcon { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal System.Windows.Forms.ToolStripMenuItem MenuAllPC { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal System.Windows.Forms.ContextMenuStrip MainMenu { get; set; }
internal FrmScreen()
{
InitializeComponent();
Text = Setting.Values.MyID;
NotifyIcon.BalloonTipText = Application.ProductName;
NotifyIcon.BalloonTipTitle = Application.ProductName;
menuGenDumpFile.Visible = true;
Common.WndProcCounter++;
try
{
menuWindowsPhone.Visible = false; // No longer supported.
}
catch (Exception e)
{
Logger.Log(e);
}
}
private void FrmScreen_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason != CloseReason.WindowsShutDown)
{
if (Tag == null)
{
e.Cancel = true;
}
}
else
{
Common.StartServiceAndSendLogoffSignal();
Quit(true, true);
}
}
internal void Destroy()
{
if (helperTimer != null)
{
helperTimer.Stop();
helperTimer.Dispose();
helperTimer = null;
}
NotifyIcon.Visible = false;
NotifyIcon.Dispose();
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Common.RunDDHelper(true);
}
// Common.UnhookClipboard();
Tag = "此电脑";
Close();
}
internal void Quit(bool cleanup, bool isFormClosing)
{
Tag = "Quitting...";
Setting.Values.SwitchCount += Common.SwitchCount;
Process me = Process.GetCurrentProcess();
Common.WndProcCounter++;
try
{
if (cleanup)
{
Common.Cleanup();
}
Common.WndProcCounter++;
if (!Common.RunOnScrSaverDesktop)
{
Common.ReleaseAllKeys();
}
Common.RunDDHelper(true);
}
catch (Exception e)
{
_ = MessageBox.Show(e.ToString());
}
Common.MMSleep(1);
Application.Exit();
me.KillProcess();
}
private void MenuExit_Click(object sender, EventArgs e)
{
PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIQuitEvent());
Quit(true, false);
}
internal void MenuOnClick(object sender, EventArgs e)
{
string name = (sender as ToolStripMenuItem).Text;
Common.SwitchToMachine(name);
}
internal void UpdateMenu()
{
try
{
ChangeIcon(-1);
while (MainMenu.Items[MainMenu.Items.Count - 1].Tag != null &&
((string)MainMenu.Items[MainMenu.Items.Count - 1].Tag).StartsWith("MACHINE: ", StringComparison.CurrentCultureIgnoreCase))
{
MainMenu.Items.Remove(MainMenu.Items[MainMenu.Items.Count - 1]);
}
while (!menuSendScreenCapture.DropDown.Items[
menuSendScreenCapture.DropDown.Items.Count - 1].Text.Equals("此电脑", StringComparison.OrdinalIgnoreCase))
{
menuSendScreenCapture.DropDown.Items.Remove(menuSendScreenCapture.DropDown.Items[
menuSendScreenCapture.DropDown.Items.Count - 1]);
}
while (!menuGetScreenCapture.DropDown.Items[
menuGetScreenCapture.DropDown.Items.Count - 1].Text.Equals("所有电脑", StringComparison.OrdinalIgnoreCase))
{
menuGetScreenCapture.DropDown.Items.Remove(menuGetScreenCapture.DropDown.Items[
menuGetScreenCapture.DropDown.Items.Count - 1]);
}
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
string newMachine = Common.MachineMatrix[i].Trim();
if (Common.MachinePool.TryFindMachineByName(newMachine, out MachineInf inf) && MachinePool.IsAlive(inf))
{
ToolStripMenuItem newItem = new(
newMachine,
null,
new EventHandler(MenuOnClick));
newItem.Tag = "MACHINE: " + inf.Name;
newItem.ToolTipText = "Switch Mouse/keyboard to " + newMachine;
newItem.Visible = true;
_ = MainMenu.Items.Add(newItem);
if (!newMachine.Equals(Common.MachineName.Trim(), StringComparison.OrdinalIgnoreCase))
{
ToolStripMenuItem newItem2 = new(
inf.Name.Trim(),
null,
new EventHandler(MenuSendScreenCaptureClick));
newItem2.Visible = true;
_ = menuSendScreenCapture.DropDown.Items.Add(newItem2);
ToolStripMenuItem newItem3 = new(
inf.Name.Trim(),
null,
new EventHandler(MenuGetScreenCaptureClick));
newItem3.Visible = true;
_ = menuGetScreenCapture.DropDown.Items.Add(newItem3);
}
}
}
menuGetScreenCapture.DropDown.Items[0].Enabled = menuGetScreenCapture.DropDown.Items.Count > 1;
}
catch (Exception e)
{
Logger.Log(e);
}
}
// We dont do something heavy in our timer
private void FrmScreen_Load(object sender, EventArgs e)
{
try
{
// Common.UpdateMenu();
// Common.HookClipboard();
CurIcon = Common.ICON_ONE;
ChangeIcon(-1);
dotCur = CustomCursor.CreateDotCursor();
Cursor = dotCur;
dropCur = CustomCursor.CreateCursor(Icon.ToBitmap(), 0, 0);
BackColor = Color.White;
Opacity = 0.15;
UpdateNotifyIcon();
if (picLogonLogo.Image != null)
{
Bitmap b = new(picLogonLogo.Image);
logonLogo = new int[b.Width, b.Height];
for (int i = 0; i < b.Width; i++)
{
for (int j = 0; j < b.Height; j++)
{
Color c = b.GetPixel(i, j);
logonLogo[i, j] = !(c.G == 255 && c.R == 0 && c.B == 0) ? (c.B << 16) | (c.G << 8) | c.R : -1;
}
}
b.Dispose();
}
}
catch (Exception ex)
{
BackColor = Color.White;
Opacity = 0.15;
Logger.Log(ex);
}
helperTimer = new System.Windows.Forms.Timer();
helperTimer.Interval = 100;
helperTimer.Tick += new EventHandler(HelperTimer_Tick);
helperTimer.Start();
Common.WndProcCounter++;
if (Environment.OSVersion.Version.Major > 6 ||
(Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1))
{
// Win7 up
_ = NativeMethods.ChangeWindowMessageFilterEx(Handle, NativeMethods.WM_SHOW_SETTINGS_FORM, 1, IntPtr.Zero);
}
}
private long count = 21;
// private bool checkForNewVersion;
#if USING_FORM
private static frmLogon fLogon = null;
#endif
private bool busy;
private bool shownSetupFormOneTime;
private bool myDesktopNotActive;
private void HelperTimer_Tick(object sender, EventArgs e)
{
Common.WndProcCounter++;
if (busy)
{
return;
}
busy = true;
try
{
if (!Common.IsMyDesktopActive() || Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())
{
myDesktopNotActive = true;
SocketStuff sk = Common.Sk;
// We are not on application desktop
if (sk != null)
{
turnedOff = true;
Common.SecondOpenSocketTry = false;
sk.Close(false);
Common.Sk = null;
count = 21;
#if USING_FORM
if (fLogon != null) fLogon.Hide();
#endif
if (Common.MainFormVisible)
{
Common.MainFormDot();
}
InputSimulation.ResetSystemKeyFlags();
Common.DoSomethingInTheInputCallbackThread(() =>
{
Common.Hook?.ResetLastSwitchKeys();
});
Common.CheckForDesktopSwitchEvent(true);
}
}
else
{
if (Common.Sk == null)
{
if (!Common.SecondOpenSocketTry)
{
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && !Common.GetUserName())
{
// While Windows 8 is hybrid-shutting down, user name would be empty (as returned from the .Net API), we should not do anything in this case.
Logger.LogDebug("No active user.");
Thread.Sleep(1000);
busy = false;
return;
}
if (myDesktopNotActive)
{
myDesktopNotActive = false;
Common.MyKey = Setting.Values.MyKey;
}
Common.UpdateMachinePoolStringSetting();
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && (Setting.Values.FirstRun || Common.KeyCorrupted))
{
if (!shownSetupFormOneTime)
{
shownSetupFormOneTime = true;
Common.ShowMachineMatrix();
if (Common.KeyCorrupted && !Setting.Values.FirstRun)
{
Common.KeyCorrupted = false;
string msg = "连接密码意外损坏,请重新生成。";
MessageBox.Show(msg, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
Common.ReopenSockets(false);
Common.SecondOpenSocketTry = true;
if (Common.Sk != null)
{
Common.SendHello();
Common.SendHeartBeat();
if (!Common.RunOnScrSaverDesktop && !Common.RunOnLogonDesktop)
{
NotifyIcon.Visible = false;
NotifyIcon.Visible = Setting.Values.ShowOriginalUI;
// Common.ReHookClipboard();
}
Common.RunDDHelper();
}
count = 0;
Common.InitDone = true;
#if SHOW_ON_WINLOGON
if (Common.RunOnLogonDesktop)
{
ShowMouseWithoutBordersUiOnWinLogonDesktop(true);
}
#endif
}
if ((count % 2) == 0)
{
if (Common.PleaseReopenSocket == 10 || (Common.PleaseReopenSocket > 0 && count > 0 && count % 300 == 0))
{
if (!Common.AtLeastOneSocketEstablished() || Common.PleaseReopenSocket == 10)
{
Thread.Sleep(1000);
if (Common.PleaseReopenSocket > 0)
{
Common.PleaseReopenSocket--;
}
// Double check.
if (!Common.AtLeastOneSocketEstablished())
{
Common.GetMachineName();
Logger.LogDebug("Common.pleaseReopenSocket: " + Common.PleaseReopenSocket.ToString(CultureInfo.InvariantCulture));
Common.ReopenSockets(false);
Common.NewDesMachineID = Common.DesMachineID = Common.MachineID;
}
}
else
{
Common.PleaseReopenSocket = 0;
}
}
if (Common.PleaseReopenSocket == Common.REOPEN_WHEN_HOTKEY)
{
Common.PleaseReopenSocket = 0;
Common.ReopenSockets(true);
}
else if (Common.PleaseReopenSocket == Common.REOPEN_WHEN_WSAECONNRESET)
{
Common.PleaseReopenSocket = 0;
Thread.Sleep(1000);
Common.UpdateClientSockets("REOPEN_WHEN_WSAECONNRESET");
}
if (Common.RunOnLogonDesktop)
{
PaintMyNameOnDesktop();
}
/*
if (checkClipboard)
{
Common.CtrlC = -1;
checkClipboard = false;
Common.CheckClipboard();
}
else if (--Common.CtrlC == 0)//Giving some timeout from the time Ctrl+C
{
if ((Common.GetTick() - Common.LastClipboardEventTime > 5000) && Common.CheckClipboard())
{
Common.ReHookClipboard();
}
}
* */
}
// One more time after 1/3 minutes (Sometimes XP has explorer started late)
if (count == 600 || count == 1800)
{
Common.RunDDHelper();
}
if (count == 600)
{
if (!Common.GeneratedKey)
{
Common.MyKey = Setting.Values.MyKey;
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Common.ShowMachineMatrix();
Common.MatrixForm?.UpdateKeyTextBox();
Common.Sk?.Close(false);
Common.ShowToolTip("连接密码不可以手动修改,必须点击生成按钮自动生成.", 10000);
}
}
else if (!Common.KeyCorrupted && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && !Setting.Values.FirstRun && Common.AtLeastOneSocketConnected())
{
int myKeyDaysToExpire = Setting.Values.MyKeyDaysToExpire;
if (myKeyDaysToExpire <= 0)
{
Common.ShowMachineMatrix();
Common.Sk?.Close(false);
string msg = "连接密码已过期,请重新生成.";
Common.ShowToolTip(msg, 10000);
}
else if (myKeyDaysToExpire <= 15)
{
Common.ShowToolTip($"连接密码将在 {myKeyDaysToExpire} 天内过期! 请注意重新生成密码.", 10000);
}
}
}
}
if (count == 20)
{
#if SHOW_ON_WINLOGON
// if (Common.RunOnLogonDesktop) ShowMouseWithoutBordersUiOnWinLogonDesktop(false);
#endif
Common.CheckForDesktopSwitchEvent(true);
Common.UpdateClientSockets("helperTimer_Tick"); // Sockets may be closed by the remote host when both machines switch desktop at the same time.
}
count++;
if (count % 5 == 0)
{
if (Common.RunOnLogonDesktop)
{
ShowMessageOnLogonDesktop(Common.DesMachineID != ID.ALL);
}
if (Common.ToggleIcons != null)
{
Common.ToggleIcon();
}
if (count % 20 == 0)
{
Logger.LogAll();
// Need to review this code on why it is needed (moved from MoveToMyNeighbourIfNeeded(...))
for (int i = 0; i < Common.MachineMatrix.Length; i++)
{
if (string.IsNullOrEmpty(Common.MachineMatrix[i]) && !Common.InMachineMatrix(Common.MachineName))
{
Common.MachineMatrix[i] = Common.MachineName;
}
}
if (count % 600 == 0 && Common.Sk != null)
{
// Send out Heartbeat every 1 or 5 mins
if (Setting.Values.BlockScreenSaver || count % 3000 == 0)
{
Common.SendAwakeBeat();
Common.RemoveDeadMachines();
// GC.Collect();
// GC.WaitForPendingFinalizers();
}
Common.CloseAnUnusedSocket();
}
}
else if ((count % 36005) == 0)
{// One hour
Common.SaveSwitchCount();
int rv = 0;
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && Common.IsMyDesktopActive() && (rv = Common.SendMessageToHelper(0x400, IntPtr.Zero, IntPtr.Zero)) <= 0)
{
Logger.TelemetryLogTrace($"{Common.HELPER_FORM_TEXT} not found: {rv}", SeverityLevel.Warning);
}
}
}
}
catch (Exception ex)
{
Logger.Log(ex);
}
finally
{
busy = false;
}
}
private void MenuMachineMatrix_Click(object sender, EventArgs e)
{
Common.ShowMachineMatrix();
}
private void FrmScreen_MouseMove(object sender, MouseEventArgs e)
{
if (!Common.IsDropping)
{
if (Cursor != dotCur)
{
Cursor = dotCur;
Refresh();
// Application.DoEvents();
}
}
}
internal void ChangeIcon(int iconCode)
{
try
{
Graphics g;
Pen p;
Bitmap bm = Images.notify_default;
/*
if (curIcon == Common.ICON_ONE)
{
string[] x = Common.MachineMatrix;
Graphics g = Graphics.FromImage(bm);
if (x != null)
{
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
if (x[i].Trim().Length > 0) g.FillEllipse(
#if DEBUG
Brushes.White,
#else
Brushes.Salmon,
#endif
3 + (i % 2) * 16, 3 + (i / 2) * 16, 10, 10);
}
}
g.Dispose();
}
*/
if (CurIcon != Common.ICON_ONE)
{
p = new Pen(Color.Red, 2);
g = Graphics.FromImage(bm);
g.DrawRectangle(p, 1, 1, bm.Width - 2, bm.Height - 2);
g.Dispose();
}
if (iconCode == Common.ICON_SMALL_CLIPBOARD)
{
g = Graphics.FromImage(bm);
g.FillEllipse(Brushes.Blue, 8, 8, 16, 16);
g.Dispose();
}
else if (iconCode == Common.ICON_BIG_CLIPBOARD)
{
g = Graphics.FromImage(bm);
g.FillEllipse(Brushes.Yellow, 8, 8, 16, 16);
g.Dispose();
}
else if (iconCode == Common.ICON_ERROR)
{
g = Graphics.FromImage(bm);
g.FillEllipse(Brushes.Red, 8, 8, 16, 16);
g.Dispose();
}
#if DEBUG
p = new Pen(Color.White, 4);
g = Graphics.FromImage(bm);
g.DrawRectangle(p, 6, 6, bm.Width - 12, bm.Height - 12);
g.Dispose();
p.Dispose();
#endif
Logger.LogDebug($"Changing icon to {iconCode}.");
if (NotifyIcon.Icon != null)
{
NativeMethods.DestroyIcon(NotifyIcon.Icon.Handle);
}
NotifyIcon.Icon = Icon.FromHandle(bm.GetHicon());
bm.Dispose();
}
catch (Exception e)
{
Logger.Log(e);
}
}
internal void MenuAllPC_Click(object sender, EventArgs e)
{
Logger.LogDebug("menuAllPC_Click");
Common.SwitchToMultipleMode(MenuAllPC.Checked, true);
CurIcon = MenuAllPC.Checked ? Common.ICON_ALL : Common.ICON_ONE;
ChangeIcon(CurIcon);
}
internal void UpdateMultipleModeIconAndMenu()
{
Common.DoSomethingInUIThread(() =>
{
MenuAllPC.Checked = Common.NewDesMachineID == ID.ALL;
CurIcon = MenuAllPC.Checked ? Common.ICON_ALL : Common.ICON_ONE;
ChangeIcon(CurIcon);
});
}
// private bool checkClipboard = false;
protected override void WndProc(ref Message m)
{
const int WM_ENDSESSION = 0x0016;
const int WM_QUERYENDSESSION = 0x0011;
// const int WM_DRAWCLIPBOARD = 0x0308;
// const int WM_CHANGECBCHAIN = 0x030D;
switch (m.Msg)
{
/*
case WM_DRAWCLIPBOARD:
if (Common.NextClipboardViewer != IntPtr.Zero && Common.NextClipboardViewer != this.Handle)
{
int rv = NativeMethods.SendMessage(Common.NextClipboardViewer, m.Msg, m.WParam, m.LParam);
Common.Log("SendMessage returned " + rv.ToString(CultureInfo.CurrentCulture));
}
if (Common.GetTick() - Common.LastClipboardEventTime < 1000)
{
Common.Log("GetTick() - lastClipboardEventTime < 1000");
Common.LastClipboardEventTime = Common.GetTick();
return;
}
Common.LastClipboardEventTime = Common.GetTick();
checkClipboard = true;//Do the task in a next message loop.
break;
case WM_CHANGECBCHAIN:
if (m.WParam == Common.NextClipboardViewer)
Common.NextClipboardViewer = m.LParam;
else
if (Common.NextClipboardViewer != IntPtr.Zero && Common.NextClipboardViewer != this.Handle)
{
int rv = NativeMethods.SendMessage(Common.NextClipboardViewer, m.Msg, m.WParam, m.LParam);
Common.Log("SendMessage returned " + rv.ToString(CultureInfo.CurrentCulture));
}
break;
*/
case NativeMethods.WM_SHOW_DRAG_DROP:
Point p = default;
_ = NativeMethods.GetCursorPos(ref p);
Width = 70;
Height = 70;
Left = p.X - (Width / 3);
Top = p.Y - (Height / 3);
BackColor = Color.White;
Opacity = 0.15;
if (Cursor != dropCur)
{
Cursor = dropCur;
}
Show();
break;
case NativeMethods.WM_HIDE_DRAG_DROP:
Common.MainFormDot();
/*
this.Width = 1;
this.Height = 1;
this.Left = 0;
this.Top = 0;
//this.Hide();
//Common.MainFormVisible = false;
* */
if (Cursor != dotCur)
{
Cursor = dotCur;
}
break;
case NativeMethods.WM_HIDE_DD_HELPER:
Common.MainForm3Pixels();
Common.MMSleep(0.2);
if (m.WParam.ToInt32() == 1)
{
InputSimulation.MouseUp(); // A file is being dragged
}
IntPtr h = (IntPtr)NativeMethods.FindWindow(null, Common.HELPER_FORM_TEXT);
if (h.ToInt32() > 0)
{
Logger.LogDebug("Hide Mouse Without Borders Helper.");
// Common.ShowWindow(h, 1);
_ = NativeMethods.ShowWindow(h, 0);
// Common.SetWindowPos(h, Common.HWND_NOTOPMOST, 10, 10, 50, 50, 0);
// Common.SetWindowPos(h, Common.HWND_TOPMOST, 0, 0, 800, 60, 0);// For debug
}
break;
case NativeMethods.WM_CHECK_EXPLORER_DRAG_DROP:
Logger.LogDebug("Got WM_CHECK_EXPLORER_DRAG_DROP!");
Common.DragDropStep04();
break;
case NativeMethods.WM_QUIT:
// Quit(true);
break;
case NativeMethods.WM_SWITCH:
break;
case WM_QUERYENDSESSION:
Logger.LogDebug("WM_QUERYENDSESSION...");
Common.StartServiceAndSendLogoffSignal();
break;
case WM_ENDSESSION:
Quit(true, true);
break;
case NativeMethods.WM_SHOW_SETTINGS_FORM:
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
Common.ShowMachineMatrix();
}
break;
default:
base.WndProc(ref m);
break;
}
}
private void NotifyIcon_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Common.ShowMachineMatrix();
}
}
internal void SetTrayIconText(string value)
{
if (value.Length > 63)
{
value = value[..63];
}
NotifyIcon.Text = value;
}
internal void UpdateNotifyIcon()
{
string[] x = Common.MachineMatrix;
string iconText;
if (x != null && (x[0].Length > 0 || x[1].Length > 0 || x[2].Length > 0 || x[3].Length > 0))
{
iconText = Setting.Values.MatrixOneRow
? string.Format(
CultureInfo.CurrentCulture,
"[{0}][{1}][{2}][{3}]",
x[0].Trim(),
x[1].Trim(),
x[2].Trim(),
x[3].Trim())
: string.Format(
CultureInfo.CurrentCulture,
"[{0}][{1}]\r\n[{2}][{3}]",
x[0].Trim(),
x[1].Trim(),
x[2].Trim(),
x[3].Trim());
SetTrayIconText(iconText);
}
else
{
SetTrayIconText(Application.ProductName);
}
}
internal void ShowToolTip(string txt, int timeOutInMilliseconds, ToolTipIcon icon = ToolTipIcon.Info, bool forceEvenIfHidingOldUI = false)
{
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
var oldNotifyVisibility = NotifyIcon.Visible;
// In order to show tooltips, the icon needs to be shown.
if (forceEvenIfHidingOldUI)
{
NotifyIcon.Visible = true;
}
NotifyIcon.ShowBalloonTip(timeOutInMilliseconds, Application.ProductName, txt, icon);
if (forceEvenIfHidingOldUI)
{
NotifyIcon.Visible = oldNotifyVisibility;
}
}
}
private void MenuSendScreenCaptureClick(object sender, EventArgs e)
{
string menuCaption = (sender as ToolStripMenuItem).Text;
string captureFile = Common.CaptureScreen();
if (captureFile != null && File.Exists(captureFile))
{
if (menuCaption.Equals("此电脑", StringComparison.OrdinalIgnoreCase))
{
Common.OpenImage(captureFile);
}
else
{
Common.SendImage(menuCaption, captureFile);
}
}
}
private void MenuGetScreenCaptureClick(object sender, EventArgs e)
{
string menuCaption = (sender as ToolStripMenuItem).Text;
// Send CaptureScreenCommand
ID des = menuCaption.Equals("所有电脑", StringComparison.OrdinalIgnoreCase) ? ID.ALL : Common.IdFromName(menuCaption);
Common.SendPackage(des, PackageType.CaptureScreenCommand);
}
private void FrmScreen_Shown(object sender, EventArgs e)
{
Common.AssertOneInstancePerDesktopSession();
Common.MainForm = this;
Hide();
if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)
{
NotifyIcon.Visible = false;
NotifyIcon.Visible = Setting.Values.ShowOriginalUI;
}
if (Program.ShowServiceModeErrorTooltip)
{
Common.ShowToolTip("服务启动失败,将以一般模式继续运行,请在设置中重新打开服务模式.", 10000, forceEvenIfHidingOldUI: true);
}
}
private void MenuAbout_Click(object sender, EventArgs e)
{
if (Common.AboutForm == null)
{
_ = (Common.AboutForm = new FrmAbout()).ShowDialog();
}
else
{
Common.AboutForm.Activate();
}
}
#if SHOW_ON_WINLOGON
private void ShowMouseWithoutBordersUiOnWinLogonDesktop(bool initMenuState)
{
Common.PaintCount = 0;
try
{
if (initMenuState)
{
HideMenuWhenRunOnLogonDesktop();
}
#if !USING_FORM
PaintMyNameOnDesktop();
#else
if (fLogon == null) fLogon = new frmLogon();
fLogon.Show();
fLogon.LabelDesktop.ContextMenuStrip = fLogon.ContextMenuStrip = MainMenu;
#endif
}
catch (Exception e)
{
Logger.Log(e);
}
}
internal void HideMenuWhenRunOnLogonDesktop()
{
menuHelp.Visible = false;
menuGetScreenCapture.Visible = false;
menuSendScreenCapture.Visible = false;
toolStripSeparator1.Visible = false;
toolStripSeparator2.Visible = false;
menuAbout.Visible = false;
menuMachineMatrix.Visible = false;
menuReinstallKeyboardAndMouseHook.Visible = false;
toolStripMenuItem1.Visible = false;
toolStripMenuItem2.Visible = false;
menuExit.Visible = false;
}
#endif
private void MainMenu_MouseLeave(object sender, EventArgs e)
{
#if SHOW_ON_WINLOGON
if (Common.RunOnLogonDesktop)
{
MainMenu.Hide();
Thread.Sleep(50);
PaintMyNameOnDesktop();
}
#endif
}
private int colorB = 240;
private int colorBlueDelta = 5;
private bool turnedOff = true;
internal void ShowMessageOnLogonDesktop(bool turnOff)
{
if (turnOff && turnedOff)
{
colorB = 240;
colorBlueDelta = 5;
return;
}
turnedOff = false;
IntPtr hDesktop = NativeMethods.GetDesktopWindow();
IntPtr hdc = NativeMethods.GetWindowDC(hDesktop);
int textLengthInPixels;
if (hdc != IntPtr.Zero)
{
NativeMethods.RECT r;
string machineMatrix = Application.ProductName + " is in multiple mode, keyboard may repeat in all machines: ";
r.Top = 0;
r.Left = Common.ScreenWidth / 5;
r.Right = Common.ScreenWidth - (Common.ScreenWidth / 5);
r.Bottom = 20;
for (int i = 0; i < Common.MAX_MACHINE; i++)
{
string newMachine = Common.MachineMatrix[i].Trim();
if (Common.MachinePool.TryFindMachineByName(newMachine, out MachineInf inf) && MachinePool.IsAlive(inf))
{
machineMatrix += "[" + inf.Name.Trim() + "]";
}
}
if (turnOff)
{
turnedOff = true;
colorBlueDelta = -40;
colorB = 0;
}
else
{
colorBlueDelta = colorB == 255 ? -colorBlueDelta : colorB == 240 ? colorBlueDelta > 0 ? 5 : -40 : colorB == 0 ? -colorBlueDelta : colorBlueDelta;
colorB += colorBlueDelta;
}
_ = NativeMethods.SetBkColor(hdc, 0);
_ = NativeMethods.SetTextColor(hdc, colorB << 8);
_ = NativeMethods.DrawText(hdc, machineMatrix, machineMatrix.Length, ref r, 0x1 | 0x4 | 0x100 | 0x400);
textLengthInPixels = r.Right - r.Left;
r.Left = (Common.ScreenWidth - textLengthInPixels) / 2;
r.Right = r.Left + textLengthInPixels;
_ = NativeMethods.DrawText(hdc, machineMatrix, machineMatrix.Length, ref r, 0x1 | 0x4 | 0x100);
_ = NativeMethods.ReleaseDC(hDesktop, hdc);
}
}
#if SHOW_ON_WINLOGON
private const byte MIN_COLOR = 185;
private const byte MAX_COLOR = 255;
private const byte MIN_COLOR_DOWN = 10;
private byte paintColorR = MIN_COLOR;
private byte paintColorG = MIN_COLOR;
private byte paintColorB = MIN_COLOR;
private bool paintColorDown;
internal void PaintMyNameOnDesktop()
{
if (Setting.Values.HideLogonLogo)
{
return;
}
if (Common.PaintCount > 1500)
{
return; // running for 5 mins only
}
Common.PaintCount++;
IntPtr hDesktop = NativeMethods.GetDesktopWindow();
IntPtr hdc = NativeMethods.GetWindowDC(hDesktop);
if (hdc != IntPtr.Zero)
{
int c;
// int rv = NativeMethods.DrawText(hdc, Common.BinaryName, 10, ref r, 0);
for (int i = 0; i < logonLogo.GetUpperBound(0); i++)
{
for (int j = 0; j < logonLogo.GetUpperBound(1); j++)
{
if (logonLogo[i, j] != -1)
{
c = logonLogo[i, j];
if (c == 0xFFFFFF)
{
c = (paintColorB << 16) | (paintColorG << 8) | paintColorR;
}
int rv = (int)NativeMethods.SetPixel(hdc, i, j, (uint)c);
}
}
}
// Common.Log("PaintMyNameOnDesktop: last rv = " + rv.ToString(CultureInfo.CurrentCulture));
_ = NativeMethods.ReleaseDC(hDesktop, hdc);
}
if (!paintColorDown)
{
if (paintColorR < MAX_COLOR)
{
paintColorR += MIN_COLOR_DOWN;
}
else
{
if (paintColorG < MAX_COLOR)
{
paintColorG += MIN_COLOR_DOWN;
}
else
{
if (paintColorB < MAX_COLOR)
{
paintColorB += MIN_COLOR_DOWN;
}
else
{
paintColorDown = true;
}
}
}
}
else
{
if (paintColorB > MIN_COLOR)
{
paintColorB -= MIN_COLOR_DOWN;
}
else
{
if (paintColorR > MIN_COLOR)
{
paintColorR -= MIN_COLOR_DOWN;
}
else
{
if (paintColorG > MIN_COLOR)
{
paintColorG -= MIN_COLOR_DOWN;
}
else
{
paintColorDown = false;
}
}
}
}
}
#endif
private void MenuHelp_Click(object sender, EventArgs e)
{
}
internal void MenuReinstallKeyboardAndMouseHook_Click(object sender, EventArgs e)
{
Common.DoSomethingInTheInputCallbackThread(() =>
{
if (Common.Hook != null)
{
Common.Hook.Stop();
Common.Hook = null;
}
Common.InputCallbackForm.Close();
Common.InputCallbackForm = null;
Program.StartInputCallbackThread();
});
}
private void MenuGenDumpFile_Click(object sender, EventArgs e)
{
Logger.GenerateLog();
}
private void MainMenu_Opening(object sender, CancelEventArgs e)
{
UpdateMenu();
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/App/Helper/FormHelper.cs
================================================
// 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 focusZone = new();
private readonly Lock 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())
{
EventLogger.LogEvent(Application.ProductName + " cannot be used in a remote desktop or virtual machine session.");
}
else
{
_ = MessageBox.Show(
"无法连接到无界鼠标进程,剪贴板共享功能失效.\r\n查看事件日志来获取更多信息.",
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)
{
EventLogger.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
{
EventLogger.LogEvent(log, EventLogEntryType.Warning);
}
catch (Exception e)
{
EventLogger.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)
{
EventLogger.LogEvent("WM_DRAWCLIPBOARD: " + ex.Message, EventLogEntryType.Error);
QuitDueToCommunicationError();
}
GC.Collect();
}
else
{
SendLog("Null clipboard data returned. See previous messages (if any) for more information.");
}
break;
case WM_CHANGECBCHAIN:
if (!ClipboardMMHelper.UpdateNextClipboardViewer(m))
{
ClipboardMMHelper.PassMessageToTheNextViewer(m);
}
break;
case 0x401:
screenLeft = 0;
screenTop = 0;
foreach (Screen s in Screen.AllScreens)
{
if (s.Bounds.Left < screenLeft)
{
screenLeft = s.Bounds.Left;
}
if (s.Bounds.Top < screenTop)
{
screenTop = s.Bounds.Top;
}
}
customScreenCaptureInProgress = 1;
lastClipboardEventTime = GetTick();
SendLog("**************************************************\r\nScreen capture triggered.");
m.Result = new IntPtr(1);
break;
case 0x406:
if (m.Msg == 0x406)
{
lock (bmScreenLock)
{
bmScreen = null;
for (int i = 0; i < 30; i++)
{
Thread.Sleep(100);
if (ClipboardMMHelper.ContainsImage())
{
bmScreen = ClipboardMMHelper.GetImage();
customScreenCaptureInProgress = 1;
break;
}
}
if (bmScreen == null)
{
customScreenCaptureInProgress = 0;
SendLog("No image found in the clipboard.");
}
else
{
Opacity = 1;
picScr = new PictureBox();
picScr.Dock = DockStyle.Fill;
picScr.SizeMode = PictureBoxSizeMode.StretchImage;
picScr.Image = bmScreen;
picScr.Refresh();
Controls.Add(picScr);
AssignEventHandlers(picScr);
}
}
}
MouseMoveHandler();
break;
case 0x407:
Program.DotForm.SetPosition(m.WParam.ToInt32(), m.LParam.ToInt32());
Program.DotForm.TopMost = true;
Program.DotForm.Show();
Application.DoEvents();
// Simulate input to help bring to the foreground, as it doesn't seem to work in every case otherwise.
NativeMethods.INPUT input = new NativeMethods.INPUT { type = (int)NativeMethods.InputType.INPUT_MOUSE, mi = { } };
NativeMethods.INPUT[] inputs = new NativeMethods.INPUT[] { input };
_ = NativeMethods.SendInput(1, inputs, Marshal.SizeOf(typeof(NativeMethods.INPUT)));
m.Result = SetForeGround() ? new IntPtr(1) : IntPtr.Zero;
break;
case 0x408:
Program.DotForm.Hide();
break;
case 0x400:
m.Result = Handle;
break;
case SharedConst.QUIT_CMD:
Process.GetCurrentProcess().Kill();
break;
default:
base.WndProc(ref m);
break;
}
}
private bool SetForeGround()
{
string logTag = nameof(SetForeGround);
IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();
if (foreGroundWindow == Program.DotForm.Handle)
{
SendLog($"{logTag}.Foreground window is already the dot form: {foreGroundWindow}.");
return true;
}
Program.DotForm.Activate();
bool setForegroundWindow = NativeMethods.SetForegroundWindow(Program.DotForm.Handle);
SendLog($"{logTag}.{nameof(NativeMethods.SetForegroundWindow)}({Program.DotForm.Handle}) returned: {setForegroundWindow}.");
return LogForeGroundWindow(logTag);
}
private bool LogForeGroundWindow(string logTag)
{
IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();
if (foreGroundWindow == Program.DotForm.Handle)
{
SendLog($"{logTag}.Foreground window is now the dot form: {Program.DotForm.Handle}.");
return true;
}
else
{
SendLog($"{logTag}.Foreground window is: [{foreGroundWindow}].");
return false;
}
}
private void AssignEventHandlers(PictureBox p)
{
p.MouseDown += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseDown);
p.MouseMove += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseMove);
p.MouseUp += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseUp);
}
private void MouseMoveHandler()
{
lock (bmScreenLock)
{
if (bmScreen != null && Opacity == 1)
{
focusZone.Clear();
TopMost = true;
Show();
startOrg = new Point(MousePosition.X - screenLeft, MousePosition.Y - screenTop);
if (left == null)
{
left = new PictureBox();
left.BackColor = Color.Red;
Controls.Add(left);
left.BringToFront();
AssignEventHandlers(left);
}
left.Left = startOrg.X;
left.Top = startOrg.Y;
left.Width = 2;
left.Height = 100;
left.Show();
left.Refresh();
if (top == null)
{
top = new PictureBox();
top.BackColor = Color.Red;
Controls.Add(top);
top.BringToFront();
AssignEventHandlers(top);
}
top.Left = startOrg.X;
top.Top = startOrg.Y;
top.Height = 2;
top.Width = 100;
top.Show();
top.Refresh();
}
}
}
private void MouseDownMoveHandler()
{
lock (bmScreenLock)
{
if (bmScreen != null && left != null && top != null)
{
int x = MousePosition.X - screenLeft;
int y = MousePosition.Y - screenTop;
start = new Point(startOrg.X < x ? startOrg.X : x, startOrg.Y < y ? startOrg.Y : y);
stop = new Point(startOrg.X > x ? startOrg.X : x, startOrg.Y > y ? startOrg.Y : y);
left.Left = start.X;
left.Top = start.Y;
left.Width = 2;
left.Height = stop.Y - start.Y;
left.Show();
top.Left = start.X;
top.Top = start.Y;
top.Height = 2;
top.Width = stop.X - start.X;
top.Show();
if (right == null)
{
right = new PictureBox();
right.BackColor = Color.Red;
Controls.Add(right);
right.BringToFront();
AssignEventHandlers(right);
}
right.Left = stop.X;
right.Top = start.Y;
right.Width = 2;
right.Height = stop.Y - start.Y;
right.Show();
if (bottom == null)
{
bottom = new PictureBox();
bottom.BackColor = Color.Red;
Controls.Add(bottom);
bottom.BringToFront();
AssignEventHandlers(bottom);
}
bottom.Left = start.X;
bottom.Top = stop.Y;
bottom.Height = 2;
bottom.Width = stop.X - start.X;
bottom.Show();
TopMost = true;
Show();
}
}
}
private void MouseUpHandler(bool canceled = false, bool rightMouseButton = false)
{
lock (bmScreenLock)
{
MouseDownMoveHandler();
customScreenCaptureInProgress = 0;
if (!canceled && bmScreen != null && left != null && top != null && right != null && bottom != null
&& stop.X - start.X > 0 && stop.Y - start.Y > 0)
{
start = PointInStandardDPI(start);
stop = PointInStandardDPI(stop);
Bitmap bm = new(stop.X - start.X, stop.Y - start.Y);
Graphics g = Graphics.FromImage(bm);
try
{
g.DrawImage(bmScreen, 0, 0, new Rectangle(start, bm.Size), GraphicsUnit.Pixel);
g.DrawRectangle(Pens.DarkOrange, 0, 0, stop.X - start.X - 1, stop.Y - start.Y - 1);
foreach (FocusArea f in focusZone)
{
RectangleF rec = RectangleFInStandardDPI(f.Rec);
rec.X -= start.X;
rec.Y -= start.Y;
g.DrawEllipse(new Pen(f.Color, 2), rec);
}
if (rightMouseButton)
{
try
{
string tempFile = Path.GetTempPath() + Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + ".png";
SendLog(tempFile);
bm.Save(tempFile, ImageFormat.Png);
lastClipboardEventTime = GetTick();
ClipboardMMHelper.SetText(tempFile);
}
catch (IOException ioException)
{
SendLog("IO!Exception!: " + ioException.Message);
}
catch (ArgumentNullException argException)
{
SendLog("ArgNull!Exception!: " + argException.Message);
}
catch (ExternalException internalException)
{
SendLog("Internal!Exception!: " + internalException.Message);
}
}
else
{
lastClipboardEventTime = GetTick() - 10000;
ClipboardMMHelper.SetImage(bm);
}
}
finally
{
g.Dispose();
bm.Dispose();
bmScreen.Dispose();
bmScreen = null;
}
}
ShowInTaskbar = false;
Hide();
Controls.Clear();
Opacity = 0.11;
left?.Dispose();
top?.Dispose();
right?.Dispose();
bottom?.Dispose();
picScr?.Dispose();
left = top = right = bottom = picScr = null;
SendLog("Screen capture ended.\r\n**************************************************");
}
}
private void FormHelper_FormClosed(object sender, FormClosedEventArgs e)
{
ClipboardMMHelper.UnhookClipboard();
}
private void FormHelper_LocationChanged(object sender, EventArgs e)
{
lock (bmScreenLock)
{
if (picScr == null && !timerHelper.Enabled)
{
Opacity = 0.11;
timerHelper.Start();
}
}
}
private void FormHelper_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
MouseUpHandler(true);
}
if (focus1.IsEmpty)
{
focus1 = stop;
}
}
private void FormHelper_KeyUp(object sender, KeyEventArgs e)
{
focus2 = stop;
float x = Math.Min(focus1.X, focus2.X);
float y = Math.Min(focus1.Y, focus2.Y);
float w = Math.Abs(focus1.X - focus2.X);
float h = Math.Abs(focus1.Y - focus2.Y);
x -= 0.25F * w;
y -= 0.25F * h;
w *= 1.5F;
h *= 1.5F;
focusZone.Add(new FocusArea(new RectangleF(x, y, w, h), e.KeyCode == Keys.B ? Color.Blue : e.KeyCode == Keys.G ? Color.Green : Color.Red));
focus1 = focus2 = Point.Empty;
}
private void FormHelper_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
}
}
private void FormHelper_MouseDown(object sender, MouseEventArgs e)
{
SendLog("Screen capture Mouse down.");
MouseMoveHandler();
customScreenCaptureInProgress = 2;
}
private void FormHelper_MouseMove(object sender, MouseEventArgs e)
{
if (customScreenCaptureInProgress == 1)
{
MouseMoveHandler();
}
else if (customScreenCaptureInProgress == 2)
{
MouseDownMoveHandler();
}
}
private void FormHelper_MouseUp(object sender, MouseEventArgs e)
{
MouseUpHandler(false, e.Button == MouseButtons.Right);
}
private Point PointInStandardDPI(Point p)
{
// Since the process is DPI awareness, just log and return.
// TODO: Test in Win8/7/XP.
SendLog(string.Format(CultureInfo.CurrentCulture, "this.Width={0}, this.Height={1}, bmScreen.Width={2}, bmScreen.Height={3}, x={4}, y={5}", Width, Height, bmScreen.Width, bmScreen.Height, p.X, p.Y));
return p;
}
private RectangleF RectangleFInStandardDPI(RectangleF r)
{
// Since the process is DPI awareness, just return.
return r;
}
}
}
================================================
FILE: PowerToys/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp
================================================
#include "pch.h"
#include
#include
#include
#include "trace.h"
#include "generateSecurityDescriptor.h"
#include
#include
#include
#include
#include
#include
#include
HINSTANCE g_hInst_MouseWithoutBorders = 0;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst_MouseWithoutBorders = hModule;
Trace::MouseWithoutBorders::RegisterProvider();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
Trace::MouseWithoutBorders::UnregisterProvider();
break;
}
return TRUE;
}
bool GetUserSid(const wchar_t* username, PSID& sid)
{
DWORD sidSize = 0;
DWORD domainNameSize = 0;
SID_NAME_USE sidNameUse;
LookupAccountName(nullptr, username, nullptr, &sidSize, nullptr, &domainNameSize, &sidNameUse);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
Logger::error("Failed to get buffer sizes");
return false;
}
sid = LocalAlloc(LPTR, sidSize);
LPWSTR domainName = static_cast(LocalAlloc(LPTR, domainNameSize * sizeof(wchar_t)));
if (!LookupAccountNameW(nullptr, username, sid, &sidSize, domainName, &domainNameSize, &sidNameUse))
{
Logger::error("Failed to lookup account name");
LocalFree(sid);
LocalFree(domainName);
return false;
}
LocalFree(domainName);
return true;
}
std::wstring GetCurrentUserSid()
{
wchar_t username[UNLEN + 1];
DWORD usernameSize = UNLEN + 1;
std::wstring result;
if (!GetUserNameW(username, &usernameSize))
{
Logger::error("Failed to get the current user name");
return result;
}
PSID sid;
if (GetUserSid(username, sid))
{
LPWSTR sidString;
if (ConvertSidToStringSid(sid, &sidString))
{
result = sidString;
LocalFree(sidString);
}
LocalFree(sid);
}
else
{
Logger::error(L"Failed to get SID for user \"");
}
return result;
}
std::wstring escapeDoubleQuotes(const std::wstring& input)
{
std::wstring output;
output.reserve(input.size());
for (const wchar_t& ch : input)
{
if (ch == L'"')
{
output += L'\\';
}
output += ch;
}
return output;
}
const static wchar_t* MODULE_NAME = L"MouseWithoutBorders";
const static wchar_t* MODULE_DESC = L"A module to move your mouse across computers.";
const static wchar_t* SERVICE_NAME = L"PowerToys.MWB.Service";
const static std::wstring_view USE_SERVICE_PROPERTY_NAME = L"UseService";
class MouseWithoutBorders : public PowertoyModuleIface
{
std::wstring app_name;
std::wstring app_key;
private:
bool m_enabled = false;
bool run_in_service_mode = false;
PROCESS_INFORMATION p_info = {};
bool is_enabled_by_default() const override
{
return false;
}
bool is_process_running()
{
return WaitForSingleObject(p_info.hProcess, 0) == WAIT_TIMEOUT;
}
void launch_process()
{
Logger::trace(L"Launching PowerToys MouseWithoutBorders process");
const std::wstring application_path = L"PowerToys.MouseWithoutBorders.exe";
STARTUPINFO info = { sizeof(info) };
std::wstring full_command_path = application_path;
if (run_in_service_mode)
{
full_command_path += L" ";
full_command_path += USE_SERVICE_PROPERTY_NAME;
}
if (!CreateProcessW(application_path.c_str(), full_command_path.data(), nullptr, nullptr, true, {}, nullptr, nullptr, &info, &p_info))
{
DWORD error = GetLastError();
std::wstring message = L"PowerToys MouseWithoutBorders failed to start with error: ";
message += std::to_wstring(error);
Logger::error(message);
}
Trace::MouseWithoutBorders::Activate();
}
void unregister_service()
{
SC_HANDLE schSCManager = OpenSCManagerW(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
SC_HANDLE hService = OpenServiceW(schSCManager, SERVICE_NAME, SERVICE_STOP | DELETE);
if (!hService)
{
Logger::error("Failed to open MWB service");
return;
}
SERVICE_STATUS ss;
if (ControlService(hService, SERVICE_CONTROL_STOP, &ss))
{
Sleep(1000);
for (int i = 0; i < 5; ++i)
{
while (QueryServiceStatus(hService, &ss))
{
if (ss.dwCurrentState == SERVICE_STOP_PENDING)
{
Sleep(1000);
}
else
{
goto outer;
}
}
}
}
outer:
BOOL deleteResult = DeleteService(hService);
CloseServiceHandle(hService);
if (!deleteResult)
{
Logger::error("Failed to delete MWB service");
return;
}
Trace::MouseWithoutBorders::ToggleServiceRegistration(false);
}
void
register_service()
{
SC_HANDLE schSCManager = OpenSCManagerW(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);
if (schSCManager == nullptr)
{
Logger::error(L"Couldn't open sc manager");
return;
}
const auto closeSCM = wil::scope_exit([&] {
CloseServiceHandle(schSCManager);
});
SC_HANDLE schService = OpenServiceW(schSCManager, SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);
const auto closeService = wil::scope_exit([&] {
CloseServiceHandle(schService);
});
const auto servicePath = get_module_folderpath(g_hInst_MouseWithoutBorders) + L"/PowerToys.MouseWithoutBordersService.exe";
// Check that the service doesn't exist already and is not disabled
DWORD bytesNeeded;
LPQUERY_SERVICE_CONFIGW pServiceConfig = nullptr;
if (!QueryServiceConfigW(schService, nullptr, 0, &bytesNeeded))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
pServiceConfig = static_cast(LocalAlloc(LMEM_FIXED, bytesNeeded));
if (!QueryServiceConfigW(schService, pServiceConfig, bytesNeeded, &bytesNeeded))
{
LocalFree(pServiceConfig);
pServiceConfig = nullptr;
CloseServiceHandle(schService);
}
}
}
// Pass local app data of the current user to the service
wil::unique_cotaskmem_string cLocalAppPath;
winrt::check_hresult(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &cLocalAppPath));
std::wstring localAppPath{ cLocalAppPath.get() };
std::wstring binaryWithArgsPath = L"\"";
binaryWithArgsPath += servicePath;
binaryWithArgsPath += L"\" ";
binaryWithArgsPath += escapeDoubleQuotes(localAppPath);
bool alreadyRegistered = false;
bool isServicePathCorrect = true;
if (pServiceConfig)
{
std::wstring_view existingServicePath{ pServiceConfig->lpBinaryPathName };
alreadyRegistered = true;
isServicePathCorrect = (existingServicePath == binaryWithArgsPath);
if (isServicePathCorrect)
{
Logger::warn(L"The service path is not correct. Current: {} Expected: {}", existingServicePath, binaryWithArgsPath);
}
if (alreadyRegistered && pServiceConfig->dwStartType == SERVICE_DISABLED)
{
if (!ChangeServiceConfigW(schService,
SERVICE_NO_CHANGE,
SERVICE_DEMAND_START,
SERVICE_NO_CHANGE,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr))
{
const bool markedForDelete = GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE;
// We cannot remove the mark for deletion from the service.
if (markedForDelete)
{
alreadyRegistered = false;
CloseServiceHandle(schService);
}
}
}
LocalFree(pServiceConfig);
}
if (alreadyRegistered)
{
if (!isServicePathCorrect)
{
if (!ChangeServiceConfigW(schService,
SERVICE_NO_CHANGE,
SERVICE_NO_CHANGE,
SERVICE_NO_CHANGE,
binaryWithArgsPath.c_str(),
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr))
{
Logger::error(L"Failed to update the service's path. ERROR: {}", GetLastError());
}
else
{
Logger::info(L"Updated the service's path.");
}
}
return;
}
schService = CreateServiceW(
schSCManager,
SERVICE_NAME,
SERVICE_NAME,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
binaryWithArgsPath.c_str(),
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
if (schService == nullptr)
{
Logger::error(L"Failed to create service");
return;
}
// Set up the security descriptor to allow non-elevated users to start the service
PSECURITY_DESCRIPTOR pSD = nullptr;
ULONG szSD = 0;
std::wstring securityDescriptor = generateSecurityDescriptor(GetCurrentUserSid());
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(
securityDescriptor.c_str(),
SDDL_REVISION_1,
&pSD,
&szSD))
{
Logger::error(L"Failed to convert security descriptor string");
CloseServiceHandle(schService);
return;
}
if (!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, pSD))
{
Logger::error("Failed to set service object security");
}
LocalFree(pSD);
CloseServiceHandle(schService);
}
void update_state_from_settings(const PowerToysSettings::PowerToyValues& values)
{
const bool new_run_in_service_mode = values.get_bool_value(USE_SERVICE_PROPERTY_NAME).value_or(false);
if (new_run_in_service_mode != run_in_service_mode)
{
run_in_service_mode = new_run_in_service_mode;
shutdown_processes();
if (new_run_in_service_mode)
{
register_service();
}
// Wait until Settings -> MWB IPC Shutdown() call is completed
else
{
const auto ps = getProcessHandlesByName(L"PowerToys.MouseWithoutBorders.exe", PROCESS_QUERY_LIMITED_INFORMATION);
for (const auto& p : ps)
{
DWORD status = STILL_ACTIVE;
do
{
GetExitCodeProcess(p.get(), &status);
} while (status == STILL_ACTIVE);
}
Sleep(1000);
}
if (m_enabled)
{
launch_process();
}
Trace::MouseWithoutBorders::ToggleServiceRegistration(new_run_in_service_mode);
}
}
public:
MouseWithoutBorders()
{
app_name = L"MouseWithoutBorders";
app_key = app_name;
std::filesystem::path logFilePath(PTSettingsHelper::get_module_save_folder_location(app_key));
logFilePath.append(LogSettings::mouseWithoutBordersLogPath);
Logger::init(LogSettings::mouseWithoutBordersLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
try
{
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::load_from_settings_file(MODULE_NAME);
update_state_from_settings(values);
}
catch (std::exception&)
{
// Initial start/
}
};
// Return the configured status for the gpo policy for the module
virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override
{
return powertoys_gpo::getConfiguredMouseWithoutBordersEnabledValue();
}
void shutdown_process(HANDLE handle)
{
auto cb = [](HWND hwnd, LPARAM lParam) -> BOOL {
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processId == lParam)
{
PostMessageW(hwnd, WM_CLOSE, 0, 0);
return FALSE;
}
return TRUE;
};
DWORD processId = GetProcessId(handle);
EnumWindows(cb, processId);
DWORD waitResult = WaitForSingleObject(handle, 3000);
if (waitResult != WAIT_OBJECT_0)
{
TerminateProcess(handle, 0);
}
}
void shutdown_processes()
{
const auto services = getProcessHandlesByName(L"PowerToys.MouseWithoutBordersService.exe", PROCESS_TERMINATE);
for (const auto& svc : services)
TerminateProcess(svc.get(), 0);
wil::unique_process_handle s;
std::array processes_names = { L"PowerToys.MouseWithoutBorders.exe",
L"PowerToys.MouseWithoutBordersHelper.exe" };
for (const auto process : processes_names)
{
const auto apps = getProcessHandlesByName(process, PROCESS_TERMINATE);
for (const auto& app : apps)
shutdown_process(app.get());
}
}
virtual void destroy() override
{
shutdown_processes();
TerminateProcess(p_info.hProcess, 1);
delete this;
}
virtual const wchar_t* get_name() override
{
return MODULE_NAME;
}
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
{
HINSTANCE hinstance = reinterpret_cast(&__ImageBase);
PowerToysSettings::Settings settings(hinstance, get_name());
settings.set_description(MODULE_DESC);
return settings.serialize_to_buffer(buffer, buffer_size);
}
virtual const wchar_t* get_key() override
{
return app_key.c_str();
}
virtual void set_config(const wchar_t* config) override
{
try
{
// Parse the input JSON string.
PowerToysSettings::PowerToyValues values =
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
update_state_from_settings(values);
// If you don't need to do any custom processing of the settings, proceed
// to persists the values.
values.save_to_settings_file();
}
catch (std::exception&)
{
// Improper JSON.
}
}
virtual void enable()
{
Trace::MouseWithoutBorders::Enable(true);
launch_process();
m_enabled = true;
};
virtual void disable()
{
if (m_enabled)
{
Trace::MouseWithoutBorders::Enable(false);
Logger::trace(L"Disabling MouseWithoutBorders...");
Logger::trace(L"Signaled exit event for PowerToys MouseWithoutBorders.");
TerminateProcess(p_info.hProcess, 1);
shutdown_processes();
CloseHandle(p_info.hProcess);
}
m_enabled = false;
}
virtual bool is_enabled() override
{
return m_enabled;
}
void launch_add_firewall_process()
{
Logger::trace(L"Starting Process to add firewall rule");
std::wstring executable_path = get_module_folderpath();
executable_path.append(L"\\PowerToys.MouseWithoutBorders.exe");
std::wstring executable_args = L"";
executable_args.append(L"/S /c \"");
executable_args.append(L"chcp 65001>nul");
executable_args.append(L" & echo 为 PowerToys.MouseWithoutBorders.exe 删除所有原有的入站规则");
executable_args.append(L" & netsh advfirewall firewall delete rule dir=in name=all program=\"");
executable_args.append(executable_path);
executable_args.append(L"\" & echo 为 PowerToys.MouseWithoutBorders.exe 添加一条允许通过的入站规则");
executable_args.append(L" & netsh advfirewall firewall add rule name=\"PowerToys.MouseWithoutBorders\" dir=in action=allow program=\"");
executable_args.append(executable_path);
executable_args.append(L"\" enable=yes remoteip=LocalSubnet profile=any protocol=tcp & echo 现在可以关掉这个窗口了 & pause\"");
SHELLEXECUTEINFOW sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"cmd.exe";
sei.nShow = SW_SHOWNORMAL;
sei.lpParameters = executable_args.data();
sei.lpVerb = L"runas";
if (ShellExecuteExW(&sei))
{
Logger::trace("Successfully started the firewall rule adding process");
}
else
{
Logger::error(L"The firewall rule adding process failed to start. {}", get_last_error_or_default(GetLastError()));
}
}
virtual void call_custom_action(const wchar_t* action) override
{
try
{
PowerToysSettings::CustomActionObject action_object =
PowerToysSettings::CustomActionObject::from_json_string(action);
if (action_object.get_name() == L"add_firewall")
{
launch_add_firewall_process();
Trace::MouseWithoutBorders::AddFirewallRule();
}
else if (action_object.get_name() == L"uninstall_service")
{
unregister_service();
}
}
catch (std::exception&)
{
Logger::error(L"Failed to parse action. {}", action);
}
}
};
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
{
return new MouseWithoutBorders();
}
================================================
FILE: PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj
================================================
17.0
Win32Proj
{8acb33d9-c95b-47d4-8363-9731ee0930a0}
NewPlusShellExtension
10.0.20348.0
NewPlus.ShellExtension
DynamicLibrary
true
v143
Unicode
DynamicLibrary
false
v143
true
Unicode
.dll
..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\
PowerToys.NewPlus.ShellExtension
$(SolutionDir)$(Platform)\$(Configuration)\TemporaryBuild\obj\$(ProjectName)\
..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\
PowerToys.NewPlus.ShellExtension
$(SolutionDir)$(Platform)\$(Configuration)\TemporaryBuild\obj\$(ProjectName)\
Level3
true
WIN32;_DEBUG;NEWPLUSCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
true
Use
pch.h
stdcpplatest
..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)
Windows
true
false
dll.def
runtimeobject.lib;$(CoreLibraryDependencies)
del $(OutDir)\NewPlusPackage.msix /q
MakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv
Level3
true
true
true
WIN32;NDEBUG;NEWPLUSCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
true
Use
pch.h
stdcpplatest
..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)
Windows
true
true
true
false
dll.def
runtimeobject.lib;$(CoreLibraryDependencies)
del $(OutDir)\NewPlusPackage.msix /q
MakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv
Create
true
Document
$(OutDir)\Assets\NewPlus\Templates
true
Document
$(OutDir)\Assets\NewPlus\Templates\示例文件夹
true
Document
$(OutDir)\Assets\NewPlus\Templates\示例文件夹
{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}
{6955446d-23f7-4023-9bb3-8657f904af99}
{8f021b46-362b-485c-bfba-ccf83e820cbd}
{98537082-0fdb-40de-abd8-0dc5a4269bab}
{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
PreserveNewest
Designer
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
================================================
FILE: PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj.filters
================================================
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Source Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Header Files
Generated Files
Header Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Resource Files
Resource Files
Source Files
Source Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
Asset Files
{82bf7d46-1201-4fc2-99e0-6c1f48f97f1f}
{0c915b9c-0e6a-4d16-8620-507a10fc29c9}
{0c64a1a0-1f9e-4663-8649-454da469d15c}
rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
{4f319851-7d86-4180-b3a3-fd497a320c34}
{a998f674-d126-488b-8457-7673fe986f94}
{b442cb0f-9f62-46e8-b269-fefa8ceacb21}
{e7904759-7b6c-4609-9c6d-e3eae3cb866c}
Generated Files
================================================
FILE: PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/TemplateExamples/模板文件夹里的一切都会出现在新建+菜单中.txt
================================================
访问 https://aka.ms/PowerToysOverview_NewPlus 了解如何使用新建+
================================================
FILE: PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/TemplateExamples/示例文件夹/另一个示例文本文件.txt
================================================
另一个示例文本文件
================================================
FILE: PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/TemplateExamples/示例文件夹/示例文本文件.txt
================================================
示例文本文件
================================================
FILE: PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
新建+
The main context menu item that users click on. This should be localized to match New in Windows. e.g. Danish it would become Ny+
打开模板文件夹
The menu item in the context menu that enables user to open the folder that contains their templates.
模板
Default subfolder name where templates are stored.
================================================
FILE: PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu.win10/resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
新建+
The main context menu item that users click on. This should be localized to match New in Windows. e.g. Danish it would become Ny+
打开模板文件夹
The menu item in the context menu that enables user to open the folder that contains their templates.
模板
Default subfolder name where templates are stored.
================================================
FILE: PowerToys/src/modules/PowerOCR/PowerOCR/Properties/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
关闭
关闭 (Esc)
(Esc) indicates the keyboard shortcut
单行
单行 (S)
(S) indicates the keyboard shortcut
表格
表格 (T)
(T) indicates the keyboard shortcut
当前语言
设置
================================================
FILE: PowerToys/src/modules/ShortcutGuide/ShortcutGuide/Resources.resx
================================================
text/microsoft-resx
2.0
System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Opacity of the Shortcut Guide's overlay background (%)
Choose Shortcut Guide overlay color
Light
Dark
System default app mode
Shows a help overlay with Windows shortcuts when the Windows key is pressed.
Shortcut Guide
无动作
还原
右贴靠
左贴靠
右上贴靠
左上贴靠
右下贴靠
左下贴靠
最小化
最大化
================================================
FILE: PowerToys/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs
================================================
// 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.Drawing;
using System.Globalization;
using System.Linq;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using ManagedCommon;
using WorkspacesEditor.Data;
using WorkspacesEditor.Utils;
namespace WorkspacesEditor.Models
{
public class Project : INotifyPropertyChanged
{
[JsonIgnore]
public string EditorWindowTitle { get; set; }
public string Id { get; private set; }
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(Name)));
OnPropertyChanged(new PropertyChangedEventArgs(nameof(CanBeSaved)));
}
}
public long CreationTime { get; } // in seconds
public long LastLaunchedTime { get; } // in seconds
public bool IsShortcutNeeded { get; set; }
public bool MoveExistingWindows { get; set; }
public string LastLaunched
{
get
{
string lastLaunched = WorkspacesEditor.Properties.Resources.LastLaunched + ":";
if (LastLaunchedTime == 0)
{
return lastLaunched + WorkspacesEditor.Properties.Resources.Never;
}
const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;
DateTime lastLaunchDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(LastLaunchedTime);
TimeSpan ts = DateTime.UtcNow - lastLaunchDateTime;
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 1 * MINUTE)
{
return lastLaunched + WorkspacesEditor.Properties.Resources.Recently;
}
if (delta < 2 * MINUTE)
{
return lastLaunched + WorkspacesEditor.Properties.Resources.OneMinuteAgo;
}
if (delta < 45 * MINUTE)
{
return lastLaunched + ts.Minutes + " " + WorkspacesEditor.Properties.Resources.MinutesAgo;
}
if (delta < 90 * MINUTE)
{
return lastLaunched + WorkspacesEditor.Properties.Resources.OneHourAgo;
}
if (delta < 24 * HOUR)
{
return lastLaunched + ts.Hours + " " + WorkspacesEditor.Properties.Resources.HoursAgo;
}
if (delta < 48 * HOUR)
{
return lastLaunched + WorkspacesEditor.Properties.Resources.Yesterday;
}
if (delta < 30 * DAY)
{
return lastLaunched + ts.Days + " " + WorkspacesEditor.Properties.Resources.DaysAgo;
}
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return lastLaunched + (months <= 1 ? WorkspacesEditor.Properties.Resources.OneMonthAgo : months + " " + WorkspacesEditor.Properties.Resources.MonthsAgo);
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return lastLaunched + (years <= 1 ? WorkspacesEditor.Properties.Resources.OneYearAgo : years + " " + WorkspacesEditor.Properties.Resources.YearsAgo);
}
}
}
public bool CanBeSaved => Name.Length > 0 && Applications.Count > 0;
private bool _isRevertEnabled;
public bool IsRevertEnabled
{
get => _isRevertEnabled;
set
{
if (_isRevertEnabled != value)
{
_isRevertEnabled = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRevertEnabled)));
}
}
}
private bool _isPopupVisible;
[JsonIgnore]
public bool IsPopupVisible
{
get => _isPopupVisible;
set
{
_isPopupVisible = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsPopupVisible)));
}
}
public List Applications { get; set; }
public List