├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── CONTRIBUTORS.md ├── Changelog.md ├── LICENSE.txt ├── README.md ├── ScreenRuler.sln ├── ScreenRuler ├── App.config ├── Colors │ ├── ColorSetting.cs │ ├── CommonThemes.cs │ └── Theme.cs ├── Configuration │ ├── ActionCode.cs │ ├── Enums.cs │ ├── LocalizedDescriptionAttribute.cs │ ├── ManagerExtensions.cs │ ├── Monitor │ │ ├── MonitorIdForm.Designer.cs │ │ ├── MonitorIdForm.cs │ │ ├── MonitorIdForm.resx │ │ ├── MonitorInfo.cs │ │ ├── MonitorSetup.cs │ │ └── MonitorSetupOverlay.cs │ ├── MonitorDpiConfiguration.cs │ ├── MonitorDpiConfigurationCollection.cs │ ├── Settings.cs │ └── Shortcuts.cs ├── Controls │ ├── MarkerListBox.cs │ ├── ShortcutActions.Designer.cs │ ├── ShortcutActions.cs │ ├── ShortcutActionsEdit.Designer.cs │ ├── ShortcutActionsEdit.cs │ ├── ShortcutActionsEdit.de.resx │ ├── ShortcutActionsEdit.es.resx │ └── ShortcutActionsEdit.resx ├── FodyWeavers.xml ├── Forms │ ├── BaseForm.cs │ ├── CalibrationForm.Designer.cs │ ├── CalibrationForm.cs │ ├── CalibrationForm.de.resx │ ├── CalibrationForm.es.resx │ ├── CalibrationForm.fi.resx │ ├── CalibrationForm.it.resx │ ├── CalibrationForm.ko.resx │ ├── CalibrationForm.ml.resx │ ├── CalibrationForm.nl.resx │ ├── CalibrationForm.pl.resx │ ├── CalibrationForm.pt-PT.resx │ ├── CalibrationForm.resx │ ├── CalibrationForm.ru.resx │ ├── CalibrationForm.sk.resx │ ├── CalibrationForm.sv.resx │ ├── CalibrationForm.th-TH.resx │ ├── CalibrationForm.tr.resx │ ├── CalibrationForm.zh-CN.resx │ ├── CustomLineForm.Designer.cs │ ├── CustomLineForm.cs │ ├── CustomLineForm.de.resx │ ├── CustomLineForm.es.resx │ ├── CustomLineForm.fi.resx │ ├── CustomLineForm.it.resx │ ├── CustomLineForm.ko.resx │ ├── CustomLineForm.ml.resx │ ├── CustomLineForm.nl.resx │ ├── CustomLineForm.pl.resx │ ├── CustomLineForm.pt-PT.resx │ ├── CustomLineForm.resx │ ├── CustomLineForm.ru.resx │ ├── CustomLineForm.sk.resx │ ├── CustomLineForm.sv.resx │ ├── CustomLineForm.th-TH.resx │ ├── CustomLineForm.tr.resx │ ├── CustomLineForm.zh-CN.resx │ ├── FormResizeMode.cs │ ├── HelpForm.Designer.cs │ ├── HelpForm.cs │ ├── HelpForm.de.resx │ ├── HelpForm.es.resx │ ├── HelpForm.fi.resx │ ├── HelpForm.it.resx │ ├── HelpForm.ko.resx │ ├── HelpForm.ml.resx │ ├── HelpForm.nl.resx │ ├── HelpForm.pl.resx │ ├── HelpForm.pt-PT.resx │ ├── HelpForm.resx │ ├── HelpForm.ru.resx │ ├── HelpForm.sk.resx │ ├── HelpForm.sv.resx │ ├── HelpForm.th-TH.resx │ ├── HelpForm.tr.resx │ ├── HelpForm.zh-CN.resx │ ├── MarkerListForm.Designer.cs │ ├── MarkerListForm.cs │ ├── MarkerListForm.de.resx │ ├── MarkerListForm.es.resx │ ├── MarkerListForm.fi.resx │ ├── MarkerListForm.ko.resx │ ├── MarkerListForm.ml.resx │ ├── MarkerListForm.nl.resx │ ├── MarkerListForm.pl.resx │ ├── MarkerListForm.pt-PT.resx │ ├── MarkerListForm.resx │ ├── MarkerListForm.ru.resx │ ├── MarkerListForm.sk.resx │ ├── MarkerListForm.sv.resx │ ├── MarkerListForm.th-TH.resx │ ├── MarkerListForm.tr.resx │ ├── MarkerListForm.zh-CN.resx │ ├── RulerForm.Designer.cs │ ├── RulerForm.cs │ ├── RulerForm.de.resx │ ├── RulerForm.es.resx │ ├── RulerForm.fi.resx │ ├── RulerForm.it.resx │ ├── RulerForm.ko.resx │ ├── RulerForm.ml.resx │ ├── RulerForm.nl.resx │ ├── RulerForm.pl.resx │ ├── RulerForm.pt-PT.resx │ ├── RulerForm.resx │ ├── RulerForm.ru.resx │ ├── RulerForm.sk.resx │ ├── RulerForm.sv.resx │ ├── RulerForm.th-TH.resx │ ├── RulerForm.tr.resx │ ├── RulerForm.zh-CN.resx │ ├── SetSizeForm.Designer.cs │ ├── SetSizeForm.cs │ ├── SetSizeForm.de.resx │ ├── SetSizeForm.es.resx │ ├── SetSizeForm.fi.resx │ ├── SetSizeForm.it.resx │ ├── SetSizeForm.ko.resx │ ├── SetSizeForm.ml.resx │ ├── SetSizeForm.nl.resx │ ├── SetSizeForm.pl.resx │ ├── SetSizeForm.pt-PT.resx │ ├── SetSizeForm.resx │ ├── SetSizeForm.ru.resx │ ├── SetSizeForm.sk.resx │ ├── SetSizeForm.sv.resx │ ├── SetSizeForm.th-TH.resx │ ├── SetSizeForm.tr.resx │ ├── SetSizeForm.zh-CN.resx │ ├── SettingsForm.Designer.cs │ ├── SettingsForm.cs │ ├── SettingsForm.de.resx │ ├── SettingsForm.es.resx │ ├── SettingsForm.fi.resx │ ├── SettingsForm.it.resx │ ├── SettingsForm.ko.resx │ ├── SettingsForm.ml.resx │ ├── SettingsForm.nl.resx │ ├── SettingsForm.pl.resx │ ├── SettingsForm.pt-PT.resx │ ├── SettingsForm.resx │ ├── SettingsForm.ru.resx │ ├── SettingsForm.sk.resx │ ├── SettingsForm.sv.resx │ ├── SettingsForm.th-TH.resx │ ├── SettingsForm.tr.resx │ ├── SettingsForm.zh-CN.resx │ ├── ShortcutsForm.Designer.cs │ ├── ShortcutsForm.cs │ ├── ShortcutsForm.de.resx │ ├── ShortcutsForm.es.resx │ ├── ShortcutsForm.ko.resx │ └── ShortcutsForm.resx ├── Help │ ├── Help.de.html │ ├── Help.en.html │ ├── Help.es.html │ ├── Help.fi.html │ ├── Help.it.html │ ├── Help.ko.html │ ├── Help.ml.html │ ├── Help.nl.html │ ├── Help.pl.html │ ├── Help.pt.html │ ├── Help.ru.html │ ├── Help.sk.html │ ├── Help.sv.html │ ├── Help.th-TH.html │ ├── Help.zh-CN.html │ └── Help.zh.html ├── Marker.cs ├── MarkerCollection.cs ├── MouseTracker.cs ├── Options.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── EnumResources.Designer.cs │ ├── EnumResources.de.resx │ ├── EnumResources.es.resx │ ├── EnumResources.fi.resx │ ├── EnumResources.it.resx │ ├── EnumResources.ko.resx │ ├── EnumResources.ml.resx │ ├── EnumResources.nl.resx │ ├── EnumResources.pl.Designer.cs │ ├── EnumResources.pl.resx │ ├── EnumResources.pt-PT.resx │ ├── EnumResources.resx │ ├── EnumResources.ru.resx │ ├── EnumResources.sk.resx │ ├── EnumResources.sv.resx │ ├── EnumResources.th-TH.resx │ ├── EnumResources.tr.resx │ ├── EnumResources.zh-CN.Designer.cs │ ├── EnumResources.zh-CN.resx │ ├── Resources.Designer.cs │ ├── Resources.de.resx │ ├── Resources.es.resx │ ├── Resources.fi.resx │ ├── Resources.it.resx │ ├── Resources.ko.resx │ ├── Resources.ml.resx │ ├── Resources.nl.resx │ ├── Resources.pl.Designer.cs │ ├── Resources.pl.resx │ ├── Resources.pt-PT.resx │ ├── Resources.resx │ ├── Resources.ru.resx │ ├── Resources.sk.resx │ ├── Resources.sv.resx │ ├── Resources.th-TH.resx │ ├── Resources.tr.resx │ ├── Resources.zh-CN.Designer.cs │ ├── Resources.zh-CN.resx │ └── app.manifest ├── RulerPainter.cs ├── ScreenRuler.csproj ├── Units │ ├── MeasuringUnit.cs │ └── UnitConverters.cs ├── WinApi.cs ├── packages.config └── rulerico.ico ├── choco ├── screenruler.nuspec └── tools │ ├── VERIFICATION.txt │ ├── chocolateyUninstall.ps1 │ └── chocolateyinstall.ps1 └── img ├── icon.png ├── screenruler_2d.png └── screenruler_styles_small.png /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: alxnull 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | 244 | # Custom 245 | *.py 246 | *.bat 247 | FodyWeavers.xsd 248 | *.zip 249 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Screen Ruler Contributors 2 | 3 | - [alxnull](https://github.com/alxnull): Core development, English & German translation 4 | - [jensbrak](https://github.com/jensbrak): Golden ratio marker & marker symbols 5 | - Leandro Martin Drudi: Spanish translation 6 | - [lzporter](https://github.com/lzporter): Chinese translation 7 | - [CloverGit](https://github.com/CloverGit): Chinese translation 8 | - [IlBako](https://github.com/IlBako): Italian translation 9 | - [3t8](https://github.com/3t8): Italian translation 10 | - [João Felício](https://github.com/Joaolfelicio): Portuguese translation 11 | - [SvA1](https://github.com/SvA1): Russian translation 12 | - [id-konstantin-stepanov](https://github.com/id-konstantin-stepanov): Russian translation 13 | - [Farshan Ahamed](https://github.com/FarshanAhamed): Malayalam translation 14 | - [SentiWW](https://github.com/SentiWW): Polish translation 15 | - [Minna N.](https://github.com/minna-xD): Finnish translation, bug fixes 16 | - [Michel van Os](https://github.com/michelvosje): Dutch translation 17 | - [FrejBjornsson](https://github.com/FrejBjornsson): Swedish translation 18 | - [kerlos](https://github.com/kerlos): Thai translation 19 | - Peter Ditrich: Slovak translation 20 | -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | # Screen Ruler Changelog 2 | 3 | ### v.0.10 (2022-09) 4 | - **New:** Fine-grained calibration to display scaling using four scaling modes. 5 | - **New:** Monitor DPI awareness & automatic scaling. 6 | - **New:** Configuration of keyboard shortcuts. 7 | - **New:** Turkish translation. 8 | - **Fixed:** Placement of marker labels in flipped orientation. 9 | - **Fixed:** Intersecting mouse & offset labels. 10 | - **Fixed:** Various UI and usability issues & causes for app crashes 11 | - **Updated:** Spanish translation 12 | 13 | ### v.0.9 (2021-08) 14 | - **New:** Horizontal and vertical flipping of ruler scale 15 | - **New:** Optionally show hypotenuse ("H") and angles in 2D ruler mode 16 | - **New:** Command-line arguments to set startup location or measure opened window 17 | - **New:** Add shortcut ("X") to set marker at cursor position 18 | - **New:** Allow changing of units in marker list 19 | - **New:** Setting to snap ruler scale to screen edges 20 | - **Updated:** Chinese translation 21 | 22 | #### v.0.9.1 (2021-10) 23 | - **Fixed**: Misplaced markers on flipped ruler 24 | - **Fixed**: Crashing marker list window when no markers are set 25 | 26 | ### v.0.8 (2020-11) 27 | - **New:** Portuguese, Russian, Malayalam, Polish, Finnish, Dutch, Swedish and Thai translation 28 | - **Updated:** Italian and Spanish translation 29 | - **Changed:** Divide inch scale into 16 parts; minor UI fixes 30 | 31 | #### v.0.8.1 (2021-01) 32 | - **New:** Slovak translation 33 | - **New:** Increase precision of screen DPI setting 34 | - **New:** Keyboard shortcuts for toggling theme and setting opacity 35 | - **Fixed:** Position of marker labels on ruler 36 | 37 | ### v.0.7 (2020-09) 38 | - **New:** Added window for listing & managing custom markers 39 | - **New:** Option to hide ruler scale 40 | - **New:** Let ruler automatically follow mouse pointer 41 | - **New:** Italian translation 42 | - **New/ Changed:** Minor changes in options & settings (opacity, markers, step size) 43 | 44 | ### v.0.6 (2020-04) 45 | - **New:** Two-dimensional mode: measure the width and height simultaneously 46 | - **New:** Toggle ruler mode using 'Space' 47 | - **New:** Slim ruler scale 48 | - **New:** Ruler icon in notification area instead of task bar 49 | - **New:** Improved dialog for setting ruler size 50 | - **New:** Chinese translation 51 | 52 | ### v.0.5 (2020-02) 53 | - **New:** Marker for Golden Ratio 54 | - **New:** Symbols for marker lines (optional) 55 | - **New:** Spanish translation 56 | - **Changed:** Added window for easy ruler calibration 57 | 58 | ### v.0.4 (2020-01) 59 | - **New:** Configure marker thickness. 60 | - **New:** Configure size of resize/ move steps. 61 | - **New:** Minor: Tool tip and copy shortcut 62 | 63 | ### v.0.3 (2019-07) 64 | - **New:** Select a window from screen to measure it automatically. 65 | - **New:** Measuring unit: percentage of screen width/ height. 66 | - **New:** Fast resizing with mouse wheel. 67 | - **Changed:** Switched shortcuts for resizing and moving (!). 68 | - **Fixed:** Unclear menu label. 69 | 70 | ### v.0.2 (2018-10) 71 | - **New:** Measure in different units (cm, pt, in). 72 | - **New:** Dark ruler theme. 73 | - **New:** Custom coloring of the ruler. 74 | - **New:** Easily resize the ruler with the mouse wheel. 75 | - **New:** Add unlimited number of custom markers and delete them one by one. 76 | 77 | ### v.0.1 (2017-06) 78 | - First released version 79 | 80 | #### v.0.1.1 (2018-02) 81 | - **Fixed:** Bug with negative screen coordinates. 82 | 83 | #### v.0.1.2 (2018-04) 84 | - **New:** Saves the last ruler state for next startup. 85 | - **Fixed:** Resizing with keyboard in vertical mode. 86 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017-2021, Bluegrams. 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Screen Ruler 2 | 3 | [![Updates](https://img.shields.io/badge/updates-RSS-ffa500?logo=rss)](https://sourceforge.net/p/screenruler/news/feed.rss) 4 | [![GitHub](https://img.shields.io/github/tag/bluegrams/screenruler.svg)](https://github.com/bluegrams/screenruler) 5 | [![License](https://img.shields.io/github/license/bluegrams/screenruler.svg)](https://github.com/bluegrams/screenruler/blob/master/LICENSE.txt) 6 | [![Download](https://img.shields.io/sourceforge/dm/screenruler.svg)](https://sourceforge.net/projects/screenruler/files/) 7 | 8 | > Configurable screen ruler for measuring in pixels, centimeters, inches, points and percent. 9 | 10 | [![](https://a.fsdn.com/con/app/sf-download-button)](https://sourceforge.net/projects/screenruler/files/) 11 | 12 | Screen Ruler is a lightweight and configurable ruler tool for Windows Desktop. 13 | It allows you to measure the size of elements on the screen in different units, including pixels, centimeters and inches. 14 | Measuring is possible either using a two-dimensional, rectangular ruler scale or a one-dimensional, horizontal or vertical scale. 15 | The ruler can be moved and resized precisely using either the mouse or the keyboard and custom marking lines can be added. 16 | Besides coming with a light and a dark theme, Screen Ruler also allows you to fully customize its appearance by changing all color settings. 17 | 18 |

19 | 20 |

21 | 22 | ## Features 23 | 24 | - Measure in pixels, centimeters, inches, points and percent 25 | 26 | - Two-dimensional, rectangular ruler scale 27 | 28 | - One-dimensional, horizontal or vertical ruler scale 29 | 30 | - Dark theme and option for custom coloring 31 | 32 | - Automatically measure the size of windows on screen 33 | 34 | - Add arbitrary number of custom marking lines 35 | 36 | - Measure triangle hypotenuse and angles 37 | 38 | - Auto-mark center, thirds or golden ratio 39 | 40 | - Precise moving, resizing and flipping with keyboard shortcuts 41 | 42 | - Fully portable with no installation needed 43 | 44 | ## Setup and Usage 45 | 46 | #### Requirements 47 | 48 | Screen Ruler requires Windows 7 or newer and .NET Framework 4.8 or higher. 49 | 50 | #### Get Screen Ruler 51 | 52 | - Download the [latest release from SourceForge](https://sourceforge.net/projects/screenruler/files/) 53 | 54 | or 55 | 56 | - Install from [Chocolatey](https://chocolatey.org): 57 | ``` 58 | choco install screenruler 59 | ``` 60 | 61 | #### How To Use 62 | 63 | From the help window (press `F1` in the app): 64 | 65 | > Keyboard Actions: 66 | Space - Switch ruler mode between horizontal, vertical and two-dimensional. 67 | Z - Select a window to measure. Cancel with 'Esc'. 68 | Arrow keys - Move the ruler by one pixel. 69 | Shift + Arrow keys - Move the ruler by one medium step (defaults to 5px). 70 | Ctrl + Arrow keys - Resize the ruler by one pixel. 71 | Ctrl + Shift + Arrow keys - Resize the ruler by one medium step (defaults to 5px). 72 | Alt + Arrow keys - Dock the ruler to screen boundaries. 73 | Ctrl + C - Copy current length to clipboard. 74 | L - Set marker at current length. 75 | C - Remove the first custom marking line. 76 | Esc - Exit Screen Ruler, window selection or help. 77 | See more keyboard actions in context menu. 78 | > 79 | > Mouse Actions: 80 | Click on a position where a marker is set - Open dialog to view/ delete marker. 81 | Double-click on ruler - Set marker at the clicked position. 82 | Mouse wheel - Resize the ruler. 83 | Shift + Mouse wheel - Fast resizing of the ruler (large steps). 84 | 85 | 86 | ## Version History 87 | 88 | Read [the changelog](https://github.com/bluegrams/screenruler/blob/master/Changelog.md) to see changes in each version. 89 | 90 | ## Feedback and Support 91 | 92 | _Please leave a feedback on [Sourceforge](https://sourceforge.net/p/screenruler/reviews), on [AlternativeTo](https://alternativeto.net/software/bluegrams-screen-ruler/) or anywhere else. Thank you!_ 93 | 94 | Places to get help: 95 | 96 | * Ask on [Sourceforge](https://sourceforge.net/p/screenruler/discussion/) (General help, ideas etc.) 97 | * Open an issue on [GitHub](https://github.com/bluegrams/screenruler/issues) (Bugs, feature requests etc.) 98 | 99 | ## Contribute 100 | 101 | You are very welcome to support the development of this app by reporting bugs, adding fixes, translating or suggesting new features. 102 | The easiest way to contribute is to open [pull request on GitHub](https://github.com/bluegrams/screenruler/pulls). 103 | 104 | See all the great people that have contributed in the [list of contributors](https://github.com/bluegrams/screenruler/blob/master/CONTRIBUTORS.md). 105 | Make sure to add yourself in your pull request! 106 | 107 | ## License 108 | 109 | This software is published under [BSD-3-Clause license](https://github.com/Bluegrams/ScreenRuler/blob/master/LICENSE.txt) by Bluegrams. 110 | -------------------------------------------------------------------------------- /ScreenRuler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30406.217 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScreenRuler", "ScreenRuler\ScreenRuler.csproj", "{67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6A4246E2-D82B-4BAC-BDD1-F3B198ABC8A4}" 9 | ProjectSection(SolutionItems) = preProject 10 | Changelog.md = Changelog.md 11 | CONTRIBUTORS.md = CONTRIBUTORS.md 12 | LICENSE.txt = LICENSE.txt 13 | README.md = README.md 14 | EndProjectSection 15 | EndProject 16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "img", "img", "{E2560076-F4E6-44D0-843A-2F251607367E}" 17 | ProjectSection(SolutionItems) = preProject 18 | img\icon.png = img\icon.png 19 | img\screenruler_2d.png = img\screenruler_2d.png 20 | img\screenruler_styles_small.png = img\screenruler_styles_small.png 21 | EndProjectSection 22 | EndProject 23 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "choco", "choco", "{AAA7F469-AAC5-4DD7-AC3C-619BAE233F57}" 24 | ProjectSection(SolutionItems) = preProject 25 | choco\screenruler.nuspec = choco\screenruler.nuspec 26 | EndProjectSection 27 | EndProject 28 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{07FDF133-B8EB-40FF-9216-9F8D2239D11F}" 29 | ProjectSection(SolutionItems) = preProject 30 | choco\tools\chocolateyinstall.ps1 = choco\tools\chocolateyinstall.ps1 31 | choco\tools\chocolateyUninstall.ps1 = choco\tools\chocolateyUninstall.ps1 32 | EndProjectSection 33 | EndProject 34 | Global 35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 36 | Debug|Any CPU = Debug|Any CPU 37 | Publish-Portable|Any CPU = Publish-Portable|Any CPU 38 | Publish-Release|Any CPU = Publish-Release|Any CPU 39 | Release|Any CPU = Release|Any CPU 40 | EndGlobalSection 41 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 42 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Publish-Portable|Any CPU.ActiveCfg = Portable|Any CPU 45 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Publish-Portable|Any CPU.Build.0 = Portable|Any CPU 46 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Publish-Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Publish-Release|Any CPU.Build.0 = Release|Any CPU 48 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {67B8F96E-8237-4C57-983B-A2CA5BDDC9AE}.Release|Any CPU.Build.0 = Release|Any CPU 50 | EndGlobalSection 51 | GlobalSection(SolutionProperties) = preSolution 52 | HideSolutionNode = FALSE 53 | EndGlobalSection 54 | GlobalSection(NestedProjects) = preSolution 55 | {E2560076-F4E6-44D0-843A-2F251607367E} = {6A4246E2-D82B-4BAC-BDD1-F3B198ABC8A4} 56 | {AAA7F469-AAC5-4DD7-AC3C-619BAE233F57} = {6A4246E2-D82B-4BAC-BDD1-F3B198ABC8A4} 57 | {07FDF133-B8EB-40FF-9216-9F8D2239D11F} = {AAA7F469-AAC5-4DD7-AC3C-619BAE233F57} 58 | EndGlobalSection 59 | GlobalSection(ExtensibilityGlobals) = postSolution 60 | RESX_TaskErrorCategory = Message 61 | RESX_ShowErrorsInErrorList = True 62 | SolutionGuid = {3D95859A-FF01-44A8-A580-18614EAEC245} 63 | RESX_Rules = {"EnabledRules":["StringFormat","WhiteSpaceLead","WhiteSpaceTail","PunctuationTail"]} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /ScreenRuler/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ScreenRuler/Colors/ColorSetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Xml.Serialization; 4 | 5 | namespace ScreenRuler.Colors 6 | { 7 | /// 8 | /// Wraps System.Drawing.Color into a serializable object. 9 | /// 10 | [Serializable] 11 | public class ColorSetting 12 | { 13 | public ColorSetting() { } 14 | 15 | public ColorSetting(Color color) 16 | { 17 | this.Color = color; 18 | } 19 | 20 | [XmlIgnore] 21 | public Color Color { get; set; } 22 | 23 | [XmlText] 24 | public string HexCode 25 | { 26 | get { return ToString(); } 27 | set { Color = ColorTranslator.FromHtml(value); } 28 | } 29 | 30 | public override string ToString() 31 | { 32 | return String.Format("#{0}{1}{2}", Color.R.ToString("X2"), 33 | Color.G.ToString("X2"), Color.B.ToString("X2")); 34 | } 35 | 36 | public static implicit operator Color(ColorSetting colorSetting) 37 | { 38 | return colorSetting.Color; 39 | } 40 | 41 | public static implicit operator ColorSetting(Color color) 42 | { 43 | return new ColorSetting(color); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ScreenRuler/Colors/CommonThemes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | 4 | namespace ScreenRuler.Colors 5 | { 6 | public enum ThemeOption 7 | { 8 | Light = 0, 9 | Dark = 1, 10 | Custom = 2 11 | } 12 | 13 | public static class CommonThemes 14 | { 15 | /// 16 | /// The default light theme. 17 | /// 18 | public static Theme LightTheme = new Theme() 19 | { 20 | Background = Color.White, 21 | TickColor = Color.Black, 22 | LengthLabelColor = Color.Green, 23 | CenterLineColor = Color.Blue, 24 | MouseLineColor = Color.Orange, 25 | ThirdsLinesColor = Color.DeepSkyBlue, 26 | GoldenLineColor = Color.Gold, 27 | CustomLinesColor = Color.Red 28 | }; 29 | 30 | /// 31 | /// The default dark theme. 32 | /// 33 | public static Theme DarkTheme = new Theme() 34 | { 35 | Background = Color.FromArgb(16, 16, 16), 36 | TickColor = Color.White, 37 | LengthLabelColor = Color.White, 38 | CenterLineColor = Color.Fuchsia, 39 | MouseLineColor = Color.Orange, 40 | ThirdsLinesColor = Color.DarkTurquoise, 41 | GoldenLineColor = Color.DarkGoldenrod, 42 | CustomLinesColor = Color.OrangeRed 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ScreenRuler/Colors/Theme.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenRuler.Colors 4 | { 5 | /// 6 | /// A collection of colors that specify the appearance of the ruler. 7 | /// 8 | [Serializable] 9 | public class Theme 10 | { 11 | /// 12 | /// The background color of the ruler. 13 | /// 14 | public ColorSetting Background { get; set; } 15 | /// 16 | /// The color of the ticks on the ruler scale. 17 | /// 18 | public ColorSetting TickColor { get; set; } 19 | /// 20 | /// The color of the label that shows the total length of the ruler. 21 | /// 22 | public ColorSetting LengthLabelColor { get; set; } 23 | /// 24 | /// The color of the marker that indicates the cursor position. 25 | /// 26 | public ColorSetting MouseLineColor { get; set; } 27 | /// 28 | /// The color of the marker that indicates the center of the ruler. 29 | /// 30 | public ColorSetting CenterLineColor { get; set; } 31 | /// 32 | /// The color of the markers that divide the ruler into three parts. 33 | /// 34 | public ColorSetting ThirdsLinesColor { get; set; } 35 | /// 36 | /// The color of the marker that indicates the golden ratio on the ruler. 37 | /// 38 | public ColorSetting GoldenLineColor { get; set; } 39 | 40 | /// 41 | /// The color of custom markers. 42 | /// 43 | public ColorSetting CustomLinesColor { get; set; } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/ActionCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenRuler.Properties; 3 | 4 | namespace ScreenRuler.Configuration 5 | { 6 | /// 7 | /// Defines possible keyboard actions of the app. 8 | /// Mappings from action codes to keys in DefaultShortcuts dict in Configuration/Shortcuts.cs. 9 | /// 10 | public enum ActionCode 11 | { 12 | // No action 13 | None, 14 | // Ruler modes 15 | [LocalizedDescription("Actions_ToggleRulerMode", typeof(EnumResources))] 16 | ToggleRulerMode, 17 | [LocalizedDescription("Actions_ToggleVertical", typeof(EnumResources))] 18 | ToggleVertical, 19 | [LocalizedDescription("conFlipVertically.Text", typeof(RulerForm))] 20 | FlipVertically, 21 | [LocalizedDescription("conFlipHorizontally.Text", typeof(RulerForm))] 22 | FlipHorizontally, 23 | [LocalizedDescription("Actions_ToggleSlimMode", typeof(EnumResources))] 24 | ToggleSlimMode, 25 | [LocalizedDescription("Actions_ToggleHypotenuseMode", typeof(EnumResources))] 26 | ToggleHypotenuseMode, 27 | [LocalizedDescription("conFollowMousePointer.Text", typeof(RulerForm))] 28 | ToggleFollowMouseMode, 29 | // Tools 30 | [LocalizedDescription("conMeasure.Text", typeof(RulerForm))] 31 | MeasureWindow, 32 | [LocalizedDescription("Actions_CopySize", typeof(EnumResources))] 33 | CopySize, 34 | [LocalizedDescription("conLength.Text", typeof(RulerForm))] 35 | SetSize, 36 | // Appearance 37 | [LocalizedDescription("conTopmost.Text", typeof(RulerForm))] 38 | PinTop, 39 | [LocalizedDescription("conMinimize.Text", typeof(RulerForm))] 40 | Minimize, 41 | [LocalizedDescription("Actions_ToggleTheme", typeof(EnumResources))] 42 | ToggleTheme, 43 | [LocalizedDescription("Actions_IncreaseOpacity", typeof(EnumResources))] 44 | IncreaseOpacity, 45 | [LocalizedDescription("Actions_DecreaseOpacity", typeof(EnumResources))] 46 | DecreaseOpacity, 47 | [LocalizedDescription("conHideRulerScale.Text", typeof(RulerForm))] 48 | HideRulerScale, 49 | // Markers 50 | [LocalizedDescription("conMarkCenter.Text", typeof(RulerForm))] 51 | MarkCenter, 52 | [LocalizedDescription("conMarkThirds.Text", typeof(RulerForm))] 53 | MarkThirds, 54 | [LocalizedDescription("conMarkGolden.Text", typeof(RulerForm))] 55 | MarkGoldenRatio, 56 | [LocalizedDescription("conMarkMouse.Text", typeof(RulerForm))] 57 | MarkMouse, 58 | [LocalizedDescription("conEditMarkers.Text", typeof(RulerForm))] 59 | EditMarkers, 60 | [LocalizedDescription("conClearCustomMarker.Text", typeof(RulerForm))] 61 | ClearAllMarkers, 62 | [LocalizedDescription("Actions_DeleteFirstMarker", typeof(EnumResources))] 63 | DeleteFirstMarker, 64 | [LocalizedDescription("Actions_AddMarkerAtCurrent", typeof(EnumResources))] 65 | AddMarkerAtCurrent, 66 | [LocalizedDescription("Actions_AddMarkerAtLength", typeof(EnumResources))] 67 | AddMarkerAtLength, 68 | // Others 69 | [LocalizedDescription("conSettings.Text", typeof(RulerForm))] 70 | Settings, 71 | [LocalizedDescription("conShortcuts.Text", typeof(RulerForm))] 72 | ConfigureShortcuts, 73 | [LocalizedDescription("conCalibrate.Text", typeof(RulerForm))] 74 | CalibrateRuler, 75 | [LocalizedDescription("conHelp.Text", typeof(RulerForm))] 76 | ShowHelp, 77 | [LocalizedDescription("conExit.Text", typeof(RulerForm))] 78 | ExitApp, 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Enums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using ScreenRuler.Properties; 3 | 4 | namespace ScreenRuler.Configuration 5 | { 6 | public enum HypotenuseMode 7 | { 8 | [LocalizedDescription("HypotenuseMode_None", typeof(EnumResources))] 9 | None = 0, 10 | [LocalizedDescription("HypotenuseMode_FixedAtLength", typeof(EnumResources))] 11 | FixedAtLength = 1, 12 | [LocalizedDescription("HypotenuseMode_Moving", typeof(EnumResources))] 13 | Moving = 2, 14 | } 15 | 16 | [Flags] 17 | public enum RulerTransform 18 | { 19 | None = 0, 20 | FlippedX = 1, 21 | FlippedY = 2, 22 | CornerUpperLeft = None, 23 | CornerUpperRight = FlippedX, 24 | CornerLowerLeft = FlippedY, 25 | CornerLowerRight = FlippedX | FlippedY, 26 | } 27 | 28 | public enum DpiScalingMode 29 | { 30 | [LocalizedDescription("DpiScalingMode_Unaware", typeof(EnumResources))] 31 | Unaware = 0, 32 | [LocalizedDescription("DpiScalingMode_Auto", typeof(EnumResources))] 33 | Auto = 1, 34 | [LocalizedDescription("DpiScalingMode_Manual", typeof(EnumResources))] 35 | Manual = 2, 36 | [LocalizedDescription("DpiScalingMode_ManualPerMonitor", typeof(EnumResources))] 37 | ManualPerMonitor = 3, 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/LocalizedDescriptionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Resources; 4 | using System.Linq; 5 | 6 | namespace ScreenRuler.Configuration 7 | { 8 | public class LocalizedDescriptionAttribute : DescriptionAttribute 9 | { 10 | ResourceManager resMan; 11 | readonly string resourceKey; 12 | 13 | public LocalizedDescriptionAttribute(string resourceKey, Type resourceType) 14 | { 15 | resMan = new ResourceManager(resourceType); 16 | this.resourceKey = resourceKey; 17 | } 18 | 19 | public override string Description 20 | { 21 | get 22 | { 23 | var s = resMan.GetString(resourceKey); 24 | return String.IsNullOrWhiteSpace(s) ? resourceKey : s; 25 | } 26 | } 27 | } 28 | 29 | public static class EnumExtensions 30 | { 31 | public static string GetDescription(this Enum en) 32 | { 33 | DescriptionAttribute attr = (DescriptionAttribute)en.GetType() 34 | .GetField(en.ToString()) 35 | .GetCustomAttributes(typeof(DescriptionAttribute), false) 36 | .FirstOrDefault(); 37 | if (attr != null) 38 | { 39 | return attr.Description; 40 | } 41 | else return en.ToString(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/ManagerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Bluegrams.Application; 4 | 5 | namespace ScreenRuler.Configuration 6 | { 7 | public static class ManagerExtensions 8 | { 9 | /// 10 | /// Loads managed settings from a specified configuration file. 11 | /// 12 | public static void LoadSettingsFromFile(this WinFormsWindowManager manager, string configPath) 13 | { 14 | if (!String.IsNullOrEmpty(configPath)) 15 | { 16 | string directory = Path.GetDirectoryName(configPath); 17 | string file = Path.GetFileName(configPath); 18 | PortableSettingsProvider.SettingsDirectory = directory; 19 | PortableSettingsProvider.SettingsFileName = file; 20 | // We only really care about the custom settings object, so only reload that. 21 | var provider = new PortableSettingsProvider(); 22 | manager.CustomSettings.Providers.Clear(); 23 | manager.CustomSettings.Providers.Add(provider); 24 | foreach (System.Configuration.SettingsProperty prop in manager.CustomSettings.Properties) 25 | prop.Provider = provider; 26 | manager.CustomSettings.Reload(); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Monitor/MonitorIdForm.Designer.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace ScreenRuler.Configuration.Monitor 3 | { 4 | partial class MonitorIdForm 5 | { 6 | /// 7 | /// Required designer variable. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Clean up any resources being used. 13 | /// 14 | /// true if managed resources should be disposed; otherwise, false. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Windows Form Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | this.lblNum = new System.Windows.Forms.Label(); 33 | this.lblName = new System.Windows.Forms.Label(); 34 | this.SuspendLayout(); 35 | // 36 | // lblNum 37 | // 38 | this.lblNum.Font = new System.Drawing.Font("Microsoft Sans Serif", 72F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 39 | this.lblNum.Location = new System.Drawing.Point(0, 9); 40 | this.lblNum.Margin = new System.Windows.Forms.Padding(0); 41 | this.lblNum.Name = "lblNum"; 42 | this.lblNum.Size = new System.Drawing.Size(184, 110); 43 | this.lblNum.TabIndex = 0; 44 | this.lblNum.Text = "2"; 45 | this.lblNum.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 46 | // 47 | // lblName 48 | // 49 | this.lblName.Font = new System.Drawing.Font("Microsoft Sans Serif", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 50 | this.lblName.Location = new System.Drawing.Point(0, 119); 51 | this.lblName.Margin = new System.Windows.Forms.Padding(0); 52 | this.lblName.Name = "lblName"; 53 | this.lblName.Size = new System.Drawing.Size(184, 33); 54 | this.lblName.TabIndex = 1; 55 | this.lblName.Text = "Name"; 56 | this.lblName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 57 | // 58 | // MonitorIdForm 59 | // 60 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 61 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 62 | this.BackColor = System.Drawing.Color.Black; 63 | this.ClientSize = new System.Drawing.Size(184, 161); 64 | this.Controls.Add(this.lblName); 65 | this.Controls.Add(this.lblNum); 66 | this.ForeColor = System.Drawing.Color.White; 67 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 68 | this.Name = "MonitorIdForm"; 69 | this.Opacity = 0.8D; 70 | this.ShowInTaskbar = false; 71 | this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; 72 | this.Text = "MonitorIdForm"; 73 | this.ResumeLayout(false); 74 | 75 | } 76 | 77 | #endregion 78 | 79 | private System.Windows.Forms.Label lblNum; 80 | private System.Windows.Forms.Label lblName; 81 | } 82 | } -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Monitor/MonitorIdForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ScreenRuler.Configuration.Monitor 5 | { 6 | public partial class MonitorIdForm : Form 7 | { 8 | public MonitorIdForm(string monitorId, string monitorName = null) 9 | { 10 | InitializeComponent(); 11 | lblNum.Text = monitorId; 12 | lblName.Text = monitorName; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Monitor/MonitorIdForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Monitor/MonitorInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text.RegularExpressions; 4 | using WindowsDisplayAPI.DisplayConfig; 5 | 6 | namespace ScreenRuler.Configuration.Monitor 7 | { 8 | /// 9 | /// Represents information on a monitor device. 10 | /// 11 | public class MonitorInfo 12 | { 13 | /// 14 | /// Gets the monitor ID from the display name. 15 | /// 16 | public int Id { get; } 17 | /// 18 | /// Gets the display friendly name. 19 | /// 20 | public string FriendlyName { get; } 21 | /// 22 | /// Gets the display device source name. 23 | /// 24 | public string DisplayName { get; } 25 | /// 26 | /// Gets the display device path. 27 | /// 28 | public string DevicePath { get; } 29 | 30 | public MonitorInfo(PathDisplayTarget pathDisplayTarget) 31 | { 32 | if (int.TryParse(Regex.Match(pathDisplayTarget.ToDisplayDevice().DisplayName, @"\d+").Value, out int result)) 33 | Id = result; 34 | else Id = 0; 35 | FriendlyName = pathDisplayTarget.FriendlyName; 36 | DisplayName = pathDisplayTarget.ToDisplayDevice().DisplayName; 37 | DevicePath = pathDisplayTarget.DevicePath; 38 | } 39 | 40 | public override string ToString() 41 | { 42 | string name = !String.IsNullOrEmpty(FriendlyName) ? FriendlyName : DevicePath; 43 | return $"[{Id}] {name}"; 44 | } 45 | 46 | /// 47 | /// Retrieves a list of currently attached monitor devices. 48 | /// 49 | /// An array of MonitorInfo instances. 50 | public static MonitorInfo[] GetMonitorInfos() 51 | { 52 | return PathDisplayTarget.GetDisplayTargets().Select(d => new MonitorInfo(d)).ToArray(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Monitor/MonitorSetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Windows.Forms; 4 | 5 | namespace ScreenRuler.Configuration.Monitor 6 | { 7 | /// 8 | /// Provides information on currently connected monitors. 9 | /// 10 | public class MonitorSetup 11 | { 12 | #region Singleton 13 | private static readonly MonitorSetup instance; 14 | 15 | static MonitorSetup() 16 | { 17 | instance = new MonitorSetup(); 18 | } 19 | 20 | public static MonitorSetup Instance => instance; 21 | #endregion 22 | 23 | public MonitorInfo[] Monitors { get; set; } 24 | 25 | private MonitorSetup() 26 | { 27 | Update(); 28 | } 29 | 30 | /// 31 | /// Update list of currently connected monitors. 32 | /// 33 | public void Update() 34 | { 35 | Monitors = MonitorInfo.GetMonitorInfos(); 36 | } 37 | 38 | public string GetDevicePath(Screen screen) 39 | => Monitors.Where(m => m.DisplayName == screen.DeviceName).FirstOrDefault()?.DevicePath; 40 | 41 | /// 42 | /// Show a screen overlay that identifies the connected monitors for the specified number of seconds. 43 | /// 44 | /// The number of seconds the overlay should be visible. If <= 0, show until Close() is called. 45 | /// Whether to show the friendly names of the monitors on the overlay windows. 46 | public MonitorSetupOverlay ShowOverlay(short seconds = -1, bool showMonitorNames = true) 47 | { 48 | MonitorSetupOverlay overlay = new MonitorSetupOverlay(Monitors, showMonitorNames); 49 | overlay.Show(seconds); 50 | return overlay; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Monitor/MonitorSetupOverlay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Windows.Forms; 4 | 5 | namespace ScreenRuler.Configuration.Monitor 6 | { 7 | /// 8 | /// Provides a screen overlay that shows IDs on all connected monitors. 9 | /// 10 | public class MonitorSetupOverlay 11 | { 12 | private MonitorInfo[] monitors; 13 | private bool showMonitorNames; 14 | private Timer timer; 15 | private MonitorIdForm[] overlayForms; 16 | 17 | /// 18 | /// Creates a new instance of MonitorSetupOverlay. 19 | /// 20 | /// The used monitor info data. 21 | /// Whether to show the friendly names of the monitors on the overlay windows. 22 | public MonitorSetupOverlay(MonitorInfo[] monitors, bool showMonitorNames = true) 23 | { 24 | this.monitors = monitors; 25 | this.showMonitorNames = showMonitorNames; 26 | this.timer = new Timer(); 27 | this.timer.Tick += Timer_Tick; 28 | } 29 | 30 | /// 31 | /// Show the monitor ID overlay for the specified number of seconds. 32 | /// 33 | /// The number of seconds the overlay should be visible. If <= 0, show until Close() is called. 34 | public void Show(short seconds = -1) 35 | { 36 | Close(); // Make sure overlay is not shown twice. 37 | overlayForms = Screen.AllScreens.Select(s => createFormForScreen(s)).ToArray(); 38 | overlayForms.ToList().ForEach(form => form.Show()); 39 | if (seconds > 0) 40 | { 41 | timer.Interval = seconds * 1000; 42 | timer.Start(); 43 | } 44 | } 45 | 46 | private MonitorIdForm createFormForScreen(Screen screen) 47 | { 48 | MonitorInfo monitorInfo = monitors.Where(d => d.DisplayName == screen.DeviceName).FirstOrDefault(); 49 | if (monitorInfo != null) 50 | { 51 | MonitorIdForm form = new MonitorIdForm( 52 | monitorInfo.Id.ToString(), 53 | showMonitorNames ? monitorInfo.FriendlyName : String.Empty 54 | ); 55 | form.Location = screen.WorkingArea.Location; 56 | return form; 57 | } 58 | else throw new InvalidOperationException($"Could not find valid monitor information for '{screen.DeviceName}'."); 59 | } 60 | 61 | private void Timer_Tick(object sender, EventArgs e) 62 | { 63 | this.Close(); 64 | } 65 | 66 | public void Close() 67 | { 68 | if (timer.Enabled) 69 | { 70 | timer.Stop(); 71 | } 72 | if (overlayForms != null) 73 | { 74 | foreach (var form in overlayForms) 75 | { 76 | form.Close(); 77 | } 78 | overlayForms = null; 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/MonitorDpiConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenRuler.Configuration 4 | { 5 | /// 6 | /// Represents the DPI configuration of one monitor. 7 | /// 8 | [Serializable] 9 | public class MonitorDpiConfiguration 10 | { 11 | /// 12 | /// Monitor ID string. 13 | /// 14 | public string Id { get; set; } 15 | /// 16 | /// Manual setting for the monitor's DPI. 17 | /// 18 | public float HorizontalDpi { get; set; } = 96; 19 | /// 20 | /// Manual setting for the monitor's vertical DPI. 21 | /// 22 | public float VerticalDpi { get; set; } = 96; 23 | 24 | public MonitorDpiConfiguration() { } 25 | 26 | public MonitorDpiConfiguration(string id) 27 | { 28 | Id = id; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/MonitorDpiConfigurationCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Xml.Serialization; 6 | 7 | namespace ScreenRuler.Configuration 8 | { 9 | /// 10 | /// Models a serializable collection of MonitorDpiConfiguration. 11 | /// 12 | [Serializable] 13 | public class MonitorDpiConfigurationCollection : ICollection 14 | { 15 | [XmlIgnore] 16 | private Dictionary configurations = new Dictionary(); 17 | 18 | [XmlElement] 19 | public MonitorDpiConfiguration[] ConfigurationList 20 | { 21 | get => configurations.Values.ToArray(); 22 | set 23 | { 24 | configurations = value.ToDictionary(v => v.Id); 25 | } 26 | } 27 | 28 | public MonitorDpiConfiguration this[string key] 29 | { 30 | get => configurations[key]; 31 | set => configurations[key] = value; 32 | } 33 | 34 | public int Count => configurations.Count; 35 | 36 | public bool IsReadOnly => false; 37 | 38 | public void Add(MonitorDpiConfiguration item) => configurations.Add(item.Id, item); 39 | 40 | public void Clear() => configurations.Clear(); 41 | 42 | public bool Contains(MonitorDpiConfiguration item) => configurations.ContainsValue(item); 43 | 44 | public bool ContainsKey(string key) => configurations.ContainsKey(key); 45 | 46 | public void CopyTo(MonitorDpiConfiguration[] array, int arrayIndex) 47 | { 48 | configurations.Values.CopyTo(array, arrayIndex); 49 | } 50 | 51 | public IEnumerator GetEnumerator() => configurations.Values.GetEnumerator(); 52 | 53 | public bool Remove(MonitorDpiConfiguration item) => configurations.Remove(item.Id); 54 | 55 | IEnumerator IEnumerable.GetEnumerator() => configurations.Values.GetEnumerator(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ScreenRuler/Configuration/Shortcuts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | using System.Xml.Serialization; 6 | 7 | namespace ScreenRuler.Configuration 8 | { 9 | /// 10 | /// Represents a mapping from application action to shortcut keys. 11 | /// 12 | [Serializable] 13 | public class Shortcut 14 | { 15 | public ActionCode Action { get; set; } 16 | [XmlIgnore] 17 | public Keys Keys { get; set; } 18 | 19 | // TODO: KeysConverter is unable to convert to/from invariant culture strings. 20 | // See https://stackoverflow.com/q/61331395/9145461 and https://github.com/dotnet/winforms/issues/2886. 21 | // Therefore, this property is used for serialization to settings, 22 | // meaning that custom shortcuts are NOT preserved when changing the app language. 23 | [XmlElement(ElementName="Keys")] 24 | public string KeysString 25 | { 26 | get 27 | { 28 | KeysConverter keysConverter = new KeysConverter(); 29 | string keysString = keysConverter.ConvertToString(Keys); 30 | // Replace some special chars to make string more readable 31 | keysString = keysString.Replace("Oemcomma", ",").Replace("OemPeriod", ".").Replace("None", ""); 32 | return keysString; 33 | } 34 | set 35 | { 36 | KeysConverter keysConverter = new KeysConverter(); 37 | string keysString = value.Replace(",", "Oemcomma").Replace(".", "OemPeriod"); 38 | if (String.IsNullOrEmpty(keysString)) 39 | keysString = "None"; 40 | Keys = (Keys)keysConverter.ConvertFromString(keysString); 41 | } 42 | } 43 | 44 | public Shortcut() 45 | { } 46 | 47 | public Shortcut(ActionCode action, Keys keys) 48 | { 49 | this.Action = action; 50 | this.Keys = keys; 51 | } 52 | 53 | public override string ToString() => $"{Action}: {Keys}"; 54 | 55 | public string[] ToStringArray() 56 | { 57 | return new[] { Action.GetDescription(), KeysString }; 58 | } 59 | } 60 | 61 | public static class Shortcuts 62 | { 63 | public static List DefaultShortcuts = new List() 64 | { 65 | // Ruler modes 66 | new Shortcut(ActionCode.ToggleRulerMode, Keys.Space), 67 | new Shortcut(ActionCode.ToggleVertical, Keys.V), 68 | new Shortcut(ActionCode.FlipVertically, Keys.Shift | Keys.F), 69 | new Shortcut(ActionCode.FlipHorizontally, Keys.F), 70 | new Shortcut(ActionCode.ToggleSlimMode, Keys.J), 71 | new Shortcut(ActionCode.ToggleHypotenuseMode, Keys.H), 72 | new Shortcut(ActionCode.ToggleFollowMouseMode, Keys.W), 73 | // Tools 74 | new Shortcut(ActionCode.MeasureWindow, Keys.Z), 75 | new Shortcut(ActionCode.CopySize, Keys.Control | Keys.C), 76 | new Shortcut(ActionCode.SetSize, Keys.Control | Keys.L), 77 | // Appearance 78 | new Shortcut(ActionCode.PinTop, Keys.S), 79 | new Shortcut(ActionCode.Minimize, Keys.Control | Keys.M), 80 | new Shortcut(ActionCode.ToggleTheme, Keys.Control | Keys.T), 81 | new Shortcut(ActionCode.IncreaseOpacity, Keys.Control | Keys.Oemplus), 82 | new Shortcut(ActionCode.DecreaseOpacity, Keys.Control | Keys.OemMinus), 83 | new Shortcut(ActionCode.HideRulerScale, Keys.Control | Keys.H), 84 | // Markers 85 | new Shortcut(ActionCode.MarkCenter, Keys.M), 86 | new Shortcut(ActionCode.MarkThirds, Keys.T), 87 | new Shortcut(ActionCode.MarkGoldenRatio, Keys.G), 88 | new Shortcut(ActionCode.MarkMouse, Keys.P), 89 | new Shortcut(ActionCode.EditMarkers, Keys.Control | Keys.E), 90 | new Shortcut(ActionCode.ClearAllMarkers, Keys.Delete), 91 | new Shortcut(ActionCode.DeleteFirstMarker, Keys.C), 92 | new Shortcut(ActionCode.AddMarkerAtCurrent, Keys.X), 93 | new Shortcut(ActionCode.AddMarkerAtLength, Keys.L), 94 | // Others 95 | new Shortcut(ActionCode.Settings, Keys.Control | Keys.Oemcomma), 96 | new Shortcut(ActionCode.ConfigureShortcuts, Keys.Control | Keys.Shift | Keys.Oemcomma), 97 | new Shortcut(ActionCode.CalibrateRuler, Keys.Control | Keys.K), 98 | new Shortcut(ActionCode.ShowHelp, Keys.F1), 99 | new Shortcut(ActionCode.ExitApp, Keys.Escape), 100 | }; 101 | 102 | /// 103 | /// Gets the default shortcut keys for a given action. 104 | /// 105 | /// The action for which to retrieve shortcut keys. 106 | /// The corresponding default shortcut keys. 107 | public static Keys GetDefaultKeys(ActionCode action) 108 | { 109 | return DefaultShortcuts.Where(s => s.Action == action).Select(s => s.Keys).FirstOrDefault(); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /ScreenRuler/Controls/MarkerListBox.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Drawing; 5 | using System.Linq; 6 | using System.Windows.Forms; 7 | using ScreenRuler.Units; 8 | 9 | namespace ScreenRuler.Controls 10 | { 11 | public class MarkerListBox : ListBox 12 | { 13 | private UnitConverter unitConverter; 14 | 15 | public UnitConverter UnitConverter 16 | { 17 | get => unitConverter; 18 | set 19 | { 20 | unitConverter = value; 21 | Refresh(); 22 | } 23 | } 24 | 25 | public MarkerListBox() 26 | { 27 | // Use pixels as default if nothing else is given 28 | UnitConverter = new UnitConverter(MeasuringUnit.Pixels, Size.Empty, 0); 29 | // We draw the items ourself 30 | DrawMode = DrawMode.OwnerDrawFixed; 31 | } 32 | 33 | protected override void Sort() 34 | { 35 | var sortedItems = Items.Cast() 36 | .OrderBy(m => m, new MarkerComparer()) 37 | .Cast().ToArray(); 38 | Items.Clear(); 39 | Items.AddRange(sortedItems); 40 | } 41 | 42 | protected override void OnDrawItem(DrawItemEventArgs e) 43 | { 44 | e.DrawBackground(); 45 | 46 | if (e.Index >= 0 && e.Index < Items.Count) 47 | { 48 | // Get the total number of horizontal markers for correct index 49 | int nHorizontal = Items.Cast().Where(m => !m.Vertical).Count(); 50 | // Draw marker 51 | Marker marker = (Marker)Items[e.Index]; 52 | string valueString = UnitConverter.FormatFromPixel(marker); 53 | string directionString = marker.Vertical ? "⇅" : "⇄"; 54 | int index = marker.Vertical ? e.Index + 1 - nHorizontal : e.Index + 1; 55 | string fullString = String.Format("{0} ({1}) {2,12}", directionString, index, valueString); 56 | e.Graphics.DrawString(fullString, e.Font, new SolidBrush(e.ForeColor), e.Bounds, StringFormat.GenericDefault); 57 | } 58 | 59 | e.DrawFocusRectangle(); 60 | base.OnDrawItem(e); 61 | } 62 | } 63 | 64 | class MarkerComparer : Comparer 65 | { 66 | public override int Compare(Marker x, Marker y) 67 | { 68 | if (x.Vertical != y.Vertical) 69 | { 70 | return Convert.ToInt32(x.Vertical) - Convert.ToInt32(y.Vertical); 71 | } 72 | else 73 | { 74 | return (int)x.Value - (int)y.Value; 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ScreenRuler/Controls/ShortcutActions.Designer.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace ScreenRuler.Controls 3 | { 4 | partial class ShortcutActions 5 | { 6 | /// 7 | /// Required designer variable. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Clean up any resources being used. 13 | /// 14 | /// true if managed resources should be disposed; otherwise, false. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Component Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | components = new System.ComponentModel.Container(); 33 | } 34 | 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ScreenRuler/Controls/ShortcutActions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Windows.Forms; 6 | using ScreenRuler.Configuration; 7 | using Shortcut = ScreenRuler.Configuration.Shortcut; 8 | 9 | namespace ScreenRuler.Controls 10 | { 11 | [ProvideProperty("ShortcutAction", typeof(ToolStripMenuItem))] 12 | public partial class ShortcutActions : Component, IExtenderProvider 13 | { 14 | private readonly Dictionary shortcuts = new Dictionary(); 15 | private readonly Dictionary controlMap = new Dictionary(); 16 | 17 | public ShortcutActions() 18 | { 19 | InitializeComponent(); 20 | SetShortcuts(Shortcuts.DefaultShortcuts.ToArray()); 21 | } 22 | 23 | public ShortcutActions(IContainer container) 24 | { 25 | container.Add(this); 26 | 27 | InitializeComponent(); 28 | SetShortcuts(Shortcuts.DefaultShortcuts.ToArray()); 29 | } 30 | 31 | public Shortcut this[ActionCode action] 32 | { 33 | get => shortcuts[action]; 34 | } 35 | 36 | public ICollection GetShortcuts() 37 | { 38 | return shortcuts.Values; 39 | } 40 | 41 | public void SetShortcuts(params Shortcut[] shortcuts) 42 | { 43 | if (shortcuts == null) 44 | return; 45 | foreach (Shortcut shortcut in shortcuts) 46 | { 47 | if (this.shortcuts.ContainsKey(shortcut.Action)) 48 | this.shortcuts[shortcut.Action] = shortcut; 49 | else 50 | this.shortcuts.Add(shortcut.Action, shortcut); 51 | } 52 | InvokeChanged(); 53 | } 54 | 55 | public ActionCode HandleInput(Keys keys) 56 | { 57 | // Retrieve action code 58 | ActionCode action = GetShortcuts() 59 | .Where(s => s.Keys == keys) 60 | .Select(s => s.Action) 61 | .FirstOrDefault(); 62 | // Invoke control if applicable 63 | ToolStripMenuItem control = controlMap 64 | .Where(kv => kv.Value == action) 65 | .Select(kv => kv.Key) 66 | .Where(c => c.ShortcutKeys == Keys.None) 67 | .FirstOrDefault(); 68 | if (control != null) 69 | { 70 | control.PerformClick(); 71 | return ActionCode.None; 72 | } 73 | else 74 | { 75 | return action; 76 | } 77 | } 78 | 79 | public bool CanExtend(object extendee) 80 | { 81 | return extendee is ToolStripMenuItem; 82 | } 83 | 84 | [DisplayName("ShortcutAction")] 85 | [DefaultValue(ActionCode.None)] 86 | [ExtenderProvidedProperty] 87 | public ActionCode GetShortcutAction(ToolStripMenuItem extendee) 88 | { 89 | if (controlMap.ContainsKey(extendee)) 90 | { 91 | return controlMap[extendee]; 92 | } 93 | else 94 | { 95 | return ActionCode.None; 96 | } 97 | } 98 | 99 | public void SetShortcutAction(ToolStripMenuItem extendee, ActionCode action) 100 | { 101 | if (action == ActionCode.None) 102 | { 103 | if (controlMap.Remove(extendee)) 104 | { 105 | extendee.ShortcutKeys = Keys.None; 106 | } 107 | } 108 | else 109 | { 110 | controlMap[extendee] = action; 111 | applyShortcutToControl(extendee, action); 112 | } 113 | } 114 | 115 | public void InvokeChanged() 116 | { 117 | foreach (var item in controlMap) 118 | { 119 | applyShortcutToControl(item.Key, item.Value); 120 | } 121 | } 122 | 123 | private void applyShortcutToControl(ToolStripMenuItem item, ActionCode action) 124 | { 125 | Shortcut shortcut = shortcuts[action]; 126 | if (ToolStripManager.IsValidShortcut(shortcut.Keys)) 127 | { 128 | item.ShortcutKeys = shortcut.Keys; 129 | item.ShortcutKeyDisplayString = shortcut.KeysString; 130 | } 131 | else 132 | { 133 | item.ShortcutKeys = Keys.None; 134 | item.ShortcutKeyDisplayString = shortcut.KeysString; 135 | } 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /ScreenRuler/Controls/ShortcutActionsEdit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | using Bluegrams.Windows.Tools; 5 | using ScreenRuler.Configuration; 6 | using Shortcut = ScreenRuler.Configuration.Shortcut; 7 | 8 | namespace ScreenRuler.Controls 9 | { 10 | public partial class ShortcutActionsEdit : UserControl 11 | { 12 | public ShortcutActions ShortcutActions { get; private set; } 13 | 14 | public ShortcutActionsEdit() 15 | { 16 | InitializeComponent(); 17 | } 18 | 19 | public void LoadShortcutActions(ShortcutActions shortcutActions) 20 | { 21 | ShortcutActions = shortcutActions; 22 | // Fill shortcuts 23 | foreach (Shortcut shortcut in shortcutActions.GetShortcuts()) 24 | { 25 | lstShortcuts.Items.Add(new ListViewItem(shortcut.ToStringArray()) { Tag = shortcut.Action }); 26 | } 27 | } 28 | 29 | private void ScaleListViewColumns(ListView listview, SizeF factor) 30 | { 31 | foreach (ColumnHeader column in listview.Columns) 32 | { 33 | column.Width = (int)Math.Round(column.Width * factor.Width); 34 | } 35 | } 36 | 37 | protected override void ScaleControl(SizeF factor, BoundsSpecified specified) 38 | { 39 | base.ScaleControl(factor, specified); 40 | ScaleListViewColumns(lstShortcuts, factor); 41 | } 42 | 43 | private void lstShortcuts_SelectedIndexChanged(object sender, EventArgs e) 44 | { 45 | if (lstShortcuts.SelectedItems.Count > 0) 46 | { 47 | lblShortcut.Text = lstShortcuts.SelectedItems[0].SubItems[1].Text; 48 | } 49 | else 50 | { 51 | lblShortcut.Text = String.Empty; 52 | } 53 | } 54 | 55 | private void butEdit_Click(object sender, EventArgs e) 56 | { 57 | if (lstShortcuts.SelectedItems.Count < 1) 58 | return; 59 | editShortcut(lstShortcuts.SelectedItems[0]); 60 | } 61 | 62 | private void lstShortcuts_MouseDoubleClick(object sender, MouseEventArgs e) 63 | { 64 | ListViewHitTestInfo hit = lstShortcuts.HitTest(e.Location); 65 | if (hit.Item != null) 66 | { 67 | editShortcut(hit.Item); 68 | } 69 | } 70 | 71 | private void butReset_Click(object sender, EventArgs e) 72 | { 73 | if (lstShortcuts.SelectedItems.Count < 1) 74 | return; 75 | ActionCode action = (ActionCode)lstShortcuts.SelectedItems[0].Tag; 76 | Shortcut shortcut = new Shortcut(action, Shortcuts.GetDefaultKeys(action)); 77 | ShortcutActions.SetShortcuts(shortcut); 78 | applyShortcutChange(lstShortcuts.SelectedItems[0], shortcut); 79 | } 80 | 81 | private void conClear_Click(object sender, EventArgs e) 82 | { 83 | if (lstShortcuts.SelectedItems.Count < 1) 84 | return; 85 | ActionCode action = (ActionCode)lstShortcuts.SelectedItems[0].Tag; 86 | Shortcut shortcut = new Shortcut(action, Keys.None); 87 | ShortcutActions.SetShortcuts(shortcut); 88 | applyShortcutChange(lstShortcuts.SelectedItems[0], shortcut); 89 | } 90 | 91 | private void editShortcut(ListViewItem selectedItem) 92 | { 93 | ActionCode action = (ActionCode)selectedItem.Tag; 94 | HotKeyInputForm hotKeyInputForm = new HotKeyInputForm(ShortcutActions[action].Keys) 95 | { 96 | DescriptionText = selectedItem.SubItems[0].Text, 97 | ModifiersRequired = false, 98 | }; 99 | if (hotKeyInputForm.ShowDialog(this.ParentForm) == DialogResult.OK) 100 | { 101 | Shortcut shortcut = new Shortcut(action, hotKeyInputForm.SelectedKeys); 102 | ShortcutActions.SetShortcuts(shortcut); 103 | applyShortcutChange(selectedItem, shortcut); 104 | } 105 | } 106 | 107 | private void applyShortcutChange(ListViewItem item, Shortcut shortcut) 108 | { 109 | string[] stringArray = shortcut.ToStringArray(); 110 | for (int i = 0; i < stringArray.Length; i++) 111 | { 112 | item.SubItems[i] = new ListViewItem.ListViewSubItem(item, stringArray[i]); 113 | } 114 | item.Tag = shortcut.Action; 115 | lblShortcut.Text = shortcut.KeysString; 116 | this.Invalidate(); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /ScreenRuler/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/CustomLineForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenRuler 2 | { 3 | partial class CustomLineForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomLineForm)); 32 | this.lblLine = new System.Windows.Forms.Label(); 33 | this.butCancel = new System.Windows.Forms.Button(); 34 | this.butDelete = new System.Windows.Forms.Button(); 35 | this.lblDirection = new System.Windows.Forms.Label(); 36 | this.SuspendLayout(); 37 | // 38 | // lblLine 39 | // 40 | resources.ApplyResources(this.lblLine, "lblLine"); 41 | this.lblLine.Name = "lblLine"; 42 | // 43 | // butCancel 44 | // 45 | this.butCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 46 | resources.ApplyResources(this.butCancel, "butCancel"); 47 | this.butCancel.Name = "butCancel"; 48 | this.butCancel.UseVisualStyleBackColor = true; 49 | // 50 | // butDelete 51 | // 52 | resources.ApplyResources(this.butDelete, "butDelete"); 53 | this.butDelete.Name = "butDelete"; 54 | this.butDelete.UseVisualStyleBackColor = true; 55 | this.butDelete.Click += new System.EventHandler(this.butDelete_Click); 56 | // 57 | // lblDirection 58 | // 59 | resources.ApplyResources(this.lblDirection, "lblDirection"); 60 | this.lblDirection.Name = "lblDirection"; 61 | // 62 | // CustomLineForm 63 | // 64 | resources.ApplyResources(this, "$this"); 65 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 66 | this.CancelButton = this.butCancel; 67 | this.Controls.Add(this.lblDirection); 68 | this.Controls.Add(this.butDelete); 69 | this.Controls.Add(this.butCancel); 70 | this.Controls.Add(this.lblLine); 71 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 72 | this.MaximizeBox = false; 73 | this.MinimizeBox = false; 74 | this.Name = "CustomLineForm"; 75 | this.ShowIcon = false; 76 | this.ShowInTaskbar = false; 77 | this.ResumeLayout(false); 78 | 79 | } 80 | 81 | #endregion 82 | 83 | private System.Windows.Forms.Label lblLine; 84 | private System.Windows.Forms.Button butCancel; 85 | private System.Windows.Forms.Button butDelete; 86 | private System.Windows.Forms.Label lblDirection; 87 | } 88 | } -------------------------------------------------------------------------------- /ScreenRuler/Forms/CustomLineForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using ScreenRuler.Colors; 4 | using ScreenRuler.Units; 5 | 6 | namespace ScreenRuler 7 | { 8 | public partial class CustomLineForm : Form 9 | { 10 | public CustomLineForm(Marker marker, UnitConverter converter, Theme theme) 11 | { 12 | InitializeComponent(); 13 | this.BackColor = theme.Background; 14 | lblDirection.ForeColor = theme.TickColor; 15 | lblLine.ForeColor = theme.TickColor; 16 | butDelete.ForeColor = theme.TickColor; 17 | butCancel.ForeColor = theme.TickColor; 18 | lblDirection.Text = marker.Vertical ? "⇅" : "⇄"; 19 | if (converter.Unit == MeasuringUnit.Pixels) 20 | { 21 | lblLine.Text = String.Format("{0} px", marker.Value); 22 | } 23 | else 24 | { 25 | lblLine.Text = String.Format("{0} px\n{1:N2} {2}", marker.Value, 26 | converter.ConvertFromPixel(marker), converter.UnitString); 27 | } 28 | } 29 | 30 | private void butDelete_Click(object sender, EventArgs e) 31 | { 32 | this.DialogResult = DialogResult.OK; 33 | this.Close(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/FormResizeMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenRuler 4 | { 5 | /// 6 | /// Defines possible appearance modes of the form. 7 | /// 8 | [Flags] 9 | public enum FormResizeMode 10 | { 11 | Horizontal = 1, 12 | Vertical = 2, 13 | TwoDimensional = 3 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ScreenRuler 2 | { 3 | partial class HelpForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HelpForm)); 32 | this.webBrowser1 = new System.Windows.Forms.WebBrowser(); 33 | this.SuspendLayout(); 34 | // 35 | // webBrowser1 36 | // 37 | resources.ApplyResources(this.webBrowser1, "webBrowser1"); 38 | this.webBrowser1.Name = "webBrowser1"; 39 | // 40 | // HelpForm 41 | // 42 | resources.ApplyResources(this, "$this"); 43 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 44 | this.Controls.Add(this.webBrowser1); 45 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 46 | this.MaximizeBox = false; 47 | this.MinimizeBox = false; 48 | this.Name = "HelpForm"; 49 | this.ShowInTaskbar = false; 50 | this.Load += new System.EventHandler(this.HelpForm_Load); 51 | this.ResumeLayout(false); 52 | 53 | } 54 | 55 | #endregion 56 | 57 | private System.Windows.Forms.WebBrowser webBrowser1; 58 | } 59 | } -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Windows.Forms; 4 | using System.Globalization; 5 | using System.Linq; 6 | 7 | namespace ScreenRuler 8 | { 9 | public partial class HelpForm : Form 10 | { 11 | private string lang; 12 | private string HelpFileLocation { get { return Path.Combine(Application.StartupPath, $@"Help\Help.{lang}.html"); } } 13 | 14 | public HelpForm() 15 | { 16 | InitializeComponent(); 17 | this.KeyPreview = true; 18 | // Set lang and check if there is a help file for it. 19 | // If not, fall back to English. 20 | lang = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; 21 | if (!File.Exists(HelpFileLocation)) 22 | lang = "en"; 23 | } 24 | 25 | private void HelpForm_Load(object sender, EventArgs e) 26 | { 27 | try 28 | { 29 | webBrowser1.DocumentText = File.ReadAllText(HelpFileLocation); 30 | } 31 | catch 32 | { 33 | webBrowser1.DocumentText = String.Format("Error: Help document not found at {0}.", 34 | HelpFileLocation); 35 | } 36 | } 37 | 38 | protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 39 | { 40 | switch (keyData) 41 | { 42 | case Keys.Escape: 43 | this.Close(); 44 | return true; 45 | default: 46 | return base.ProcessCmdKey(ref msg, keyData); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.de.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Screen Ruler - Hilfe 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.es.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Screen Ruler - Ayuda 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.fi.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Screen Ruler - Ohje 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.nl.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Schermliniaal - Hulp 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.pt-PT.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Screen Ruler - Ajuda 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.ru.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Экранная линейка- Помощь 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.sv.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Skärmlinjal - Hjälp 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/HelpForm.tr.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Screen Ruler - Yardım 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/MarkerListForm.Designer.cs: -------------------------------------------------------------------------------- 1 | using ScreenRuler.Controls; 2 | 3 | namespace ScreenRuler 4 | { 5 | partial class MarkerListForm 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private System.ComponentModel.IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | base.Dispose(disposing); 23 | } 24 | 25 | #region Windows Form Designer generated code 26 | 27 | /// 28 | /// Required method for Designer support - do not modify 29 | /// the contents of this method with the code editor. 30 | /// 31 | private void InitializeComponent() 32 | { 33 | this.components = new System.ComponentModel.Container(); 34 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MarkerListForm)); 35 | this.lstMarkers = new ScreenRuler.Controls.MarkerListBox(); 36 | this.contxtListMarkers = new System.Windows.Forms.ContextMenuStrip(this.components); 37 | this.conUnits = new System.Windows.Forms.ToolStripMenuItem(); 38 | this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); 39 | this.conDelete = new System.Windows.Forms.ToolStripMenuItem(); 40 | this.contxtListMarkers.SuspendLayout(); 41 | this.SuspendLayout(); 42 | // 43 | // lstMarkers 44 | // 45 | this.lstMarkers.BorderStyle = System.Windows.Forms.BorderStyle.None; 46 | this.lstMarkers.ContextMenuStrip = this.contxtListMarkers; 47 | this.lstMarkers.DisplayMember = "DisplayString"; 48 | resources.ApplyResources(this.lstMarkers, "lstMarkers"); 49 | this.lstMarkers.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; 50 | this.lstMarkers.FormattingEnabled = true; 51 | this.lstMarkers.Name = "lstMarkers"; 52 | this.lstMarkers.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; 53 | this.lstMarkers.Sorted = true; 54 | this.lstMarkers.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.lstMarkers_MouseDoubleClick); 55 | // 56 | // contxtListMarkers 57 | // 58 | this.contxtListMarkers.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 59 | this.conUnits, 60 | this.toolStripSeparator1, 61 | this.conDelete}); 62 | this.contxtListMarkers.Name = "contxtListMarkers"; 63 | resources.ApplyResources(this.contxtListMarkers, "contxtListMarkers"); 64 | // 65 | // conUnits 66 | // 67 | this.conUnits.Name = "conUnits"; 68 | resources.ApplyResources(this.conUnits, "conUnits"); 69 | // 70 | // toolStripSeparator1 71 | // 72 | this.toolStripSeparator1.Name = "toolStripSeparator1"; 73 | resources.ApplyResources(this.toolStripSeparator1, "toolStripSeparator1"); 74 | // 75 | // conDelete 76 | // 77 | this.conDelete.Name = "conDelete"; 78 | resources.ApplyResources(this.conDelete, "conDelete"); 79 | this.conDelete.Click += new System.EventHandler(this.conDelete_Click); 80 | // 81 | // MarkerListForm 82 | // 83 | resources.ApplyResources(this, "$this"); 84 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 85 | this.Controls.Add(this.lstMarkers); 86 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 87 | this.MaximizeBox = false; 88 | this.MinimizeBox = false; 89 | this.Name = "MarkerListForm"; 90 | this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.MarkerListForm_FormClosed); 91 | this.DpiChanged += new System.Windows.Forms.DpiChangedEventHandler(this.MarkerListForm_DpiChanged); 92 | this.contxtListMarkers.ResumeLayout(false); 93 | this.ResumeLayout(false); 94 | 95 | } 96 | 97 | #endregion 98 | private MarkerListBox lstMarkers; 99 | private System.Windows.Forms.ContextMenuStrip contxtListMarkers; 100 | private System.Windows.Forms.ToolStripMenuItem conDelete; 101 | private System.Windows.Forms.ToolStripMenuItem conUnits; 102 | private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; 103 | } 104 | } -------------------------------------------------------------------------------- /ScreenRuler/Forms/MarkerListForm.cs: -------------------------------------------------------------------------------- 1 | using ScreenRuler.Units; 2 | using System; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | using ScreenRuler.Configuration; 6 | 7 | namespace ScreenRuler 8 | { 9 | public partial class MarkerListForm : Form 10 | { 11 | private Settings settings; 12 | private UnitConverter unitConverter; 13 | 14 | public MarkerCollection MarkerCollection { get; } 15 | 16 | public MarkerListForm(MarkerCollection markerCollection, Settings settings) 17 | { 18 | this.MarkerCollection = markerCollection; 19 | this.settings = settings; 20 | InitializeComponent(); 21 | this.ClientSize = lstMarkers.Size; 22 | setTheme(); 23 | foreach (var marker in markerCollection.Markers) 24 | { 25 | lstMarkers.Items.Add(marker); 26 | } 27 | lstMarkers.ItemHeight = (int)(18 * this.DeviceDpi / 96.0f); 28 | foreach (Enum item in Enum.GetValues(typeof(MeasuringUnit))) 29 | { 30 | conUnits.DropDownItems.Add(new ToolStripMenuItem(item.GetDescription(), null, conUnitsItem_Clicked) { Tag = item }); 31 | } 32 | updateUnitConverter(); 33 | MarkerCollection.MarkerCollectionChanged += markerCollection_MarkerCollectionChanged; 34 | settings.Changed += settings_Changed; 35 | settings.SelectedThemeChanged += settings_SelectedThemeChanged; 36 | } 37 | 38 | protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 39 | { 40 | switch (keyData) 41 | { 42 | case Keys.Escape: 43 | this.Close(); 44 | return true; 45 | default: 46 | return base.ProcessCmdKey(ref msg, keyData); 47 | } 48 | } 49 | 50 | private void conUnitsItem_Clicked(object sender, EventArgs e) 51 | { 52 | var unit = (MeasuringUnit)((ToolStripMenuItem)sender).Tag; 53 | updateUnitConverter(unit); 54 | } 55 | 56 | private void updateUnitConverter(MeasuringUnit? unit = null) 57 | { 58 | unitConverter = UnitConverter.FromSettings(this, settings, unit); 59 | lstMarkers.UnitConverter = unitConverter; 60 | // Set checkmark in dropdown 61 | foreach (var item in conUnits.DropDownItems.Cast()) 62 | { 63 | item.Checked = (MeasuringUnit)item.Tag == unitConverter.Unit; 64 | } 65 | } 66 | 67 | private void settings_Changed(object sender, EventArgs e) => updateUnitConverter(); 68 | 69 | private void setTheme() 70 | { 71 | lstMarkers.BackColor = settings.Theme.Background; 72 | lstMarkers.ForeColor = settings.Theme.TickColor; 73 | } 74 | 75 | private void settings_SelectedThemeChanged(object sender, EventArgs e) => setTheme(); 76 | 77 | private void markerCollection_MarkerCollectionChanged(object sender, MarkerCollectionEventArgs e) 78 | { 79 | if (e.AddedMarkers != null) 80 | { 81 | lstMarkers.Items.AddRange(e.AddedMarkers.Cast().ToArray()); 82 | } 83 | if (e.RemovedMarkers != null) 84 | { 85 | foreach (var marker in e.RemovedMarkers) 86 | { 87 | lstMarkers.Items.Remove(marker); 88 | } 89 | } 90 | } 91 | 92 | private void butDelete_Click(object sender, EventArgs e) 93 | { 94 | conDelete.PerformClick(); 95 | } 96 | 97 | private void conDelete_Click(object sender, EventArgs e) 98 | { 99 | foreach (var marker in lstMarkers.SelectedItems.Cast()) 100 | { 101 | MarkerCollection.Markers.Remove(marker); 102 | } 103 | foreach (int index in lstMarkers.SelectedIndices) 104 | { 105 | lstMarkers.Items.RemoveAt(index); 106 | } 107 | this.Owner.Invalidate(); 108 | } 109 | 110 | private void lstMarkers_MouseDoubleClick(object sender, MouseEventArgs e) 111 | { 112 | Marker marker = (Marker)lstMarkers.SelectedItem; 113 | CustomLineForm lineForm = new CustomLineForm(marker, unitConverter, settings.Theme); 114 | if (lineForm.ShowDialog(this.Owner) == DialogResult.OK) 115 | { 116 | MarkerCollection.Markers.Remove(marker); 117 | lstMarkers.Items.Remove(marker); 118 | this.Owner.Invalidate(); 119 | } 120 | } 121 | 122 | // List box item height doesn't seem to be scaled automatically, so do it manually. 123 | private void MarkerListForm_DpiChanged(object sender, DpiChangedEventArgs e) 124 | { 125 | lstMarkers.ItemHeight = (int)(18 * this.DeviceDpi / 96.0f); 126 | } 127 | 128 | private void MarkerListForm_FormClosed(object sender, FormClosedEventArgs e) 129 | { 130 | MarkerCollection.MarkerCollectionChanged -= markerCollection_MarkerCollectionChanged; 131 | settings.Changed -= settings_Changed; 132 | settings.SelectedThemeChanged -= settings_SelectedThemeChanged; 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/SetSizeForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Windows.Forms; 4 | using ScreenRuler.Configuration; 5 | using ScreenRuler.Units; 6 | 7 | namespace ScreenRuler 8 | { 9 | public partial class SetSizeForm : Form 10 | { 11 | public float RulerWidth { get; private set; } 12 | public float RulerHeight { get; private set; } 13 | 14 | private Settings settings; 15 | private UnitConverter converter; 16 | 17 | public SetSizeForm(Size rulerSize, Settings settings) 18 | { 19 | InitializeComponent(); 20 | this.RulerWidth = rulerSize.Width; 21 | this.RulerHeight = rulerSize.Height; 22 | this.settings = settings; 23 | setConverter(settings.MeasuringUnit); 24 | } 25 | 26 | private void SetSizeForm_Load(object sender, EventArgs e) 27 | { 28 | foreach (Enum item in Enum.GetValues(typeof(MeasuringUnit))) 29 | { 30 | comUnits.Items.Add(item.GetDescription()); 31 | } 32 | comUnits.SelectedIndex = (int)settings.MeasuringUnit; 33 | updateText(); 34 | } 35 | 36 | private void setConverter(MeasuringUnit unit) 37 | { 38 | converter = UnitConverter.FromSettings(this, settings, unit); 39 | } 40 | 41 | private void comUnits_SelectedIndexChanged(object sender, EventArgs e) 42 | { 43 | var unit = (MeasuringUnit)comUnits.SelectedIndex; 44 | setConverter(unit); 45 | updateText(); 46 | } 47 | 48 | /// 49 | /// Updates the ruler length and unit symbol to the currently chosen unit. 50 | /// 51 | private void updateText() 52 | { 53 | numWidth.Value = (decimal)converter.ConvertFromPixel(RulerWidth, false); 54 | numHeight.Value = (decimal)converter.ConvertFromPixel(RulerHeight, true); 55 | lblUnit1.Text = converter.UnitString; 56 | lblUnit2.Text = converter.UnitString; 57 | } 58 | 59 | private void numWidth_ValueChanged(object sender, EventArgs e) 60 | { 61 | this.RulerWidth = converter.ConvertToPixel((float)numWidth.Value, false); 62 | } 63 | 64 | private void numHeight_ValueChanged(object sender, EventArgs e) 65 | { 66 | this.RulerHeight = converter.ConvertToPixel((float)numHeight.Value, true); 67 | } 68 | 69 | private void butSubmit_Click(object sender, EventArgs e) 70 | { 71 | this.DialogResult = DialogResult.OK; 72 | this.Close(); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/ShortcutsForm.Designer.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace ScreenRuler 3 | { 4 | partial class ShortcutsForm 5 | { 6 | /// 7 | /// Required designer variable. 8 | /// 9 | private System.ComponentModel.IContainer components = null; 10 | 11 | /// 12 | /// Clean up any resources being used. 13 | /// 14 | /// true if managed resources should be disposed; otherwise, false. 15 | protected override void Dispose(bool disposing) 16 | { 17 | if (disposing && (components != null)) 18 | { 19 | components.Dispose(); 20 | } 21 | base.Dispose(disposing); 22 | } 23 | 24 | #region Windows Form Designer generated code 25 | 26 | /// 27 | /// Required method for Designer support - do not modify 28 | /// the contents of this method with the code editor. 29 | /// 30 | private void InitializeComponent() 31 | { 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ShortcutsForm)); 33 | this.shortcutActionsEdit = new ScreenRuler.Controls.ShortcutActionsEdit(); 34 | this.SuspendLayout(); 35 | // 36 | // shortcutActionsEdit 37 | // 38 | resources.ApplyResources(this.shortcutActionsEdit, "shortcutActionsEdit"); 39 | this.shortcutActionsEdit.Name = "shortcutActionsEdit"; 40 | // 41 | // ShortcutsForm 42 | // 43 | resources.ApplyResources(this, "$this"); 44 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 45 | this.Controls.Add(this.shortcutActionsEdit); 46 | this.MaximizeBox = false; 47 | this.MinimizeBox = false; 48 | this.Name = "ShortcutsForm"; 49 | this.ShowInTaskbar = false; 50 | this.ResumeLayout(false); 51 | 52 | } 53 | 54 | #endregion 55 | 56 | private Controls.ShortcutActionsEdit shortcutActionsEdit; 57 | } 58 | } -------------------------------------------------------------------------------- /ScreenRuler/Forms/ShortcutsForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using ScreenRuler.Controls; 4 | 5 | namespace ScreenRuler 6 | { 7 | public partial class ShortcutsForm : Form 8 | { 9 | public ShortcutsForm(ShortcutActions shortcutActions) 10 | { 11 | InitializeComponent(); 12 | shortcutActionsEdit.LoadShortcutActions(shortcutActions); 13 | } 14 | 15 | protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 16 | { 17 | switch (keyData) 18 | { 19 | case Keys.Escape: 20 | this.Close(); 21 | return true; 22 | default: 23 | return base.ProcessCmdKey(ref msg, keyData); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ScreenRuler/Forms/ShortcutsForm.de.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Tastaturkürzel 122 | 123 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.de.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Hilfe 7 | 17 | 18 | 19 |

Screen Ruler - Hilfe

20 |

Tastaturaktionen

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
LeerzeichenLinealmodus zwischen horizontal, vertikal und zweidimensional wechseln.
ZFenster zum Ausmessen wählen. Abbruch mit 'Esc'.
PfeiltastenLineal um ein Pixel bewegen.
Shift + PfeiltastenLineal um mittleren Schritt bewegen (Standard 5px).
Strg + PfeiltastenLineal um mittleren Schritt vergrößern/ verkleinern (Standard 5px).
Strg + Shift + PfeiltastenLineal um fünf Pixel vergrößern/ verkleinern.
Alt + PfeiltastenLineal an Bildschirmrand andocken.
Strg + CAktuelle Länge in Zwischenablage kopieren.
Strg + TLinealdesign zwischen hell und dunkel wechseln.
Strg + "+"/"-"Durchsichtigkeit des Lineals erhöhen/ verringern.
HAnzeigemodus für Hypotenuse wechseln (nur 2D).
XMarker bei aktueller Mausposition setzen.
LMarker bei aktueller Länge setzen.
CErsten Marker löschen.
EscLineal, Fensterauswahl oder Hilfe schließen.
Mehr Tastaturkürzel im Kontextmenü.
39 |

Mausaktionen

40 | 41 | 42 | 43 | 44 | 45 |
Klick auf die Position eines vorhandenen MarkersDialog zum Löschen des Markers öffnen.
Doppelklick auf LinealMarker an der geklickten Position setzen.
MausradLineal vergrößern/ verkleinern.
Shift + MausradLineal schnell vergrößern/ verkleinern (große Schritte).
46 |

https://screenruler.sourceforge.io

47 | 48 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.en.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Help 7 | 17 | 18 | 19 |

Screen Ruler - Help

20 |

Keyboard Actions

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
SpaceSwitch ruler mode between horizontal, vertical and two-dimensional.
ZSelect a window to measure. Cancel with 'Esc'.
Arrow keysMove the ruler by one pixel.
Shift + Arrow keysMove the ruler by one medium step (defaults to 5px).
Ctrl + Arrow keysResize the ruler by one pixel.
Ctrl + Shift + Arrow keysResize the ruler by one medium step (defaults to 5px).
Alt + Arrow keysDock the ruler to screen boundaries.
Ctrl + CCopy current length to clipboard.
Ctrl + TToggle the ruler theme between light and dark.
Ctrl + "+"/"-"Increase/ decrease ruler opacity.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LSet marker at current length.
CRemove the first custom marking line.
EscExit Screen Ruler, window selection or help.
See more keyboard actions in context menu.
39 |

Mouse Actions

40 | 41 | 42 | 43 | 44 | 45 |
Click on a position where a marker is setOpen dialog to view/ delete marker.
Double-click on rulerSet marker at the clicked position.
Mouse wheelResize the ruler.
Shift + Mouse wheelFast resizing of the ruler (large steps).
46 |

https://screenruler.sourceforge.io

47 | 48 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.es.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Ayuda 7 | 17 | 18 | 19 |

Screen Ruler - Ayuda

20 |

Teclas de método abreviado

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
ZSeleccione una ventana para medir. Cancele con 'Esc'.
Teclas de dirección (flechas)Mover la regla un píxel.
Mayúsc. + Teclas de dirección (flechas)Mover la regla un espacio medio (valor predeterminado: 5 px).
Ctrl + Teclas de dirección (flechas)Cambiar el tamaño de la regla por un píxel.
Ctrl + Shift + Teclas de dirección (flechas)Cambiar el tamaño de la regla un espacio medio (valor predeterminado: 5 px).
Alt + Teclas de dirección (flechas)Acopla la regla a los límites de la pantalla.
Ctrl + CCopiar longitud actual al portapapeles.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LEstablecer marcador a la longitud actual.
CEliminar la primera línea de marcado personalizada.
EscSalir de Screen Ruler, de la selección de ventana o de la ayuda.
Vea más teclas de método abreviado en el menú contextual.
36 |

Acciones con el ratón

37 | 38 | 39 | 40 | 41 | 42 |
Clic en la posición donde se establece una marcaAbrir diálogo para ver/eliminar marcador.
Doble-clic en la reglaEstablecer marcador en la posición cliqueada.
Rueda del ratónRedimensionar regla.
Shift + Rueda del ratónRedimensionamiento rápido de la regla (espaciado largo).
43 |

https://screenruler.sourceforge.io

44 | 45 | 46 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.fi.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Ohje 7 | 17 | 18 | 19 |

Screen Ruler - Ohje

20 |

Näppäimistötoiminnot

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
VälilyöntiSiirry viivaintilasta toiseen: vaakasuuntainen, pystysuuntainen ja kaksisuuntainen.
ZValitse mitattava ikkuna. Peruuta painamalla Esc-näppäintä.
NuolinäppäimetSiirrä viivainta yhden kuvapisteen verran.
Vaihto + nuolinäppäimetSiirrä viivainta yhden normaalikokoisen askeleen verran (oletusarvo: 5px).
Ctrl + nuolinäppäimetMuuta viivaimen kokoa yhden kuvapisteen verran.
Ctrl + Vaihto + nuolinäppäimetMuuta viivaimen kokoa yhden normaalikokoisen askeleen verran (oletusarvo: 5px).
Alt + nuolinäppäimetKiinnitä viivain näytön reunoihin.
Ctrl + CKopioi nykyinen pituus leikepöydälle.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LAseta merkki nykyisen pituuden kohdalle.
CPoista ensimmäinen mukautettu merkkiviiva.
EscPoistu Screen Ruler -ohjelmasta, ikkunan valinnasta tai ohjeesta.
Lisää näppäimistötoimintoja näet pikavalikosta.
37 |

Hiiritoiminnot

38 | 39 | 40 | 41 | 42 | 43 |
Napsauta hiirtä merkin kohdallaAvaa valintaikkunan, jossa voit tarkastella merkin tietoja tai poistaa sen.
Kaksoisnapsauta viivaintaAseta merkki napsautettuun sijaintiin.
Hiiren vierityspainikeMuuta viivaimen kokoa.
Vaihto + hiiren vierityspainikeMuuta viivaimen kokoa nopeasti (ison askeleen verran).
44 |

https://screenruler.sourceforge.io

45 | 46 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.it.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Aiuto 7 | 17 | 18 | 19 |

Screen Ruler - Aiuto

20 |

Scorciatoie

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
SpazioCambia modalità righello tra orizzontale, verticale e due dimensioni.
ZSeleziona una finestra da misurare. Annulla con 'Esc'.
Frecce DirezionaliMuovi il righello di un pixel.
Shift + Frecce DirezionaliMuovi il righello di un Incremento Medio (default 5px).
Ctrl + Frecce DirezionaliRidimensiona il righello di un pixel.
Ctrl + Shift + Frecce DirezionaliModifica le dimensioni del righello di un Incremento Medio (default 5px).
Alt + Frecce DirezionaliAttacca il righello ai bordi dello schermo.
Ctrl + CCopia negli appunti la lunghezza attuale.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LPosiziona un segno alla lunghezza attuale.
CRimuovi la prima linea del segno personalizzato.
EscChiudi Screen Ruler, la selezione della finestra o l'aiuto.
Vedi ulteriori scorciatoie nel menù contestuale.
37 |

Azioni col Mouse

38 | 39 | 40 | 41 | 42 | 43 |
Click su un segno precedentemente posizionatoApri finestra per visualizzare/ eliminare il segno.
Doppio click sul righelloPosiziona un segno alla posizione clickata.
Rotellina del mouseRidimensiona il righello.
Shift + Rotellina del mouseRidimensionamento rapido del righello (Incremento Grande).
44 |

https://screenruler.sourceforge.io

45 | 46 | 47 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.ko.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Screen Ruler - 도움말 7 | 17 | 18 | 19 |

Screen Ruler - 도움말

20 |

키보드 동작

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |
Space눈금자 모드를 수평, 수직 및 2차원 간에 전환합니다.
Z측정할 창을 선택합니다. 'Esc'로 취소합니다.
Arrow keys눈금자를 한 픽셀 이동합니다.
Shift + Arrow keys눈금자를 중간 단계만큼 이동합니다 (기본값은 5px).
Ctrl + Arrow keys눈금자의 크기를 한 픽셀씩 조정합니다.
Ctrl + Shift + Arrow keys눈금자의 크기를 중간 단계 한 단계씩 조정합니다 (기본값은 5px).
Alt + Arrow keys눈금자를 화면 경계에 도킹합니다.
Ctrl + C현재 길이를 클립보드에 복사합니다.
Ctrl + T눈금자를 밝은 및 어두운 테마로 전환합니다.
Ctrl + "+"/"-"눈금자의 불투명도를 증가/감소합니다.
H빗변 표시 모드 (2D 전용)를 전환합니다.
X표시를 현재 커서 위치에 설정합니다.
L표시를 현재 길이로 설정합니다.
C첫 번째 사용자 지정 표시 선을 제거합니다.
Esc화면 눈금자, 창 선택 또는 도움말을 종료합니다.
상황에 맞는 메뉴에서 더 많은 키보드 동작을 봅니다.
39 |

마우스 동작

40 | 41 | 42 | 43 | 44 | 45 |
표시가 설정된 위치 클릭대화 상자를 열어 표시를 보거나 삭제합니다.
눈금자를 두 번 클릭클릭한 위치에 표시를 설정합니다.
마우스 휠눈금자의 크기를 조정합니다.
Shift + 마우스 휠눈금자의 빠른 크기 조정 (큰 단계)입니다.
46 |

https://screenruler.sourceforge.io

47 | 48 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.ml.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | സ്ക്രീൻ റൂളർ - സഹായം 7 | 17 | 18 | 19 |

സ്ക്രീൻ റൂളർ - സഹായം

20 |

കീബോർഡ് പ്രവർത്തനങ്ങൾ

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
സ്പേസ്തിരശ്ചീന, ലംബ, ദ്വിമാനങ്ങൾക്കിടയിൽ റൂളർ മോഡ് മാറ്റുക.
ഇസെഡ്അളക്കാൻ ഒരു വിൻഡോ തിരഞ്ഞെടുക്കുക. 'എസ്‌കേപ്പ്' ഉപയോഗിച്ച് റദ്ദാക്കുക.
അമ്പടയാള കീകൾറൂളർ ഒരു പിക്സൽ നീക്കുക.
ഷിഫ്റ്റ് + അമ്പടയാള കീകൾറൂളർ ഒരു മീഡിയം സ്റ്റെപ് നീക്കുക (സ്ഥിരസ്ഥിതി 5px ലേക്ക്).
കണ്ട്രോൾ + അമ്പടയാള കീകൾറൂളർ ഒരു പിക്സൽ വലുപ്പം മാറ്റുക.
കണ്ട്രോൾ + ഷിഫ്റ്റ് + അമ്പടയാള കീകൾറൂളർ ഒരു മീഡിയം സ്റ്റെപ് വലുപ്പം മാറ്റുക (സ്ഥിരസ്ഥിതി 5px ലേക്ക്).
ആൾട്ട് + അമ്പടയാള കീകൾസ്‌ക്രീൻ അതിരുകളിലേക്ക് റൂളറിനെ ഡോക്ക് ചെയ്യുക.
കണ്ട്രോൾ + സിനിലവിലെ നീളം ക്ലിപ്പ്ബോർഡിലേക്ക് പകർത്തുക.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
എൽനിലവിലെ നീളത്തിൽ മാർക്കർ സജ്ജമാക്കുക.
സിആദ്യത്തെ കസ്റ്റം മാർകിങ് ലൈൻ നീക്കംചെയ്യുക.
എസ്‌കേപ്പ്സ്‌ക്രീൻ റൂളർ, വിൻഡോ തിരഞ്ഞെടുക്കൽ അല്ലെങ്കിൽ സഹായം എന്നിവയിൽ നിന്ന് പുറത്തുകടക്കുക.
കോണ്ടെക്സ്റ്റ് മെനുവിൽ കൂടുതൽ കീബോർഡ് പ്രവർത്തനങ്ങൾ കാണുക.
37 |

മൗസ് പ്രവർത്തനങ്ങൾ

38 | 39 | 40 | 41 | 42 | 44 |
ഒരു മാർക്കർ സജ്ജമാക്കിയിരിക്കുന്ന സ്ഥാനത്ത് ക്ലിക്കുചെയ്യുകമാർക്കർ കാണാനും ഇല്ലാതാക്കാനും ഡയലോഗ് തുറക്കുക.
റൂളറിൽ ഇരട്ട-ക്ലിക്കുചെയ്യുകക്ലിക്കുചെയ്‌ത സ്ഥാനത്ത് മാർക്കർ സജ്ജമാക്കുക.
മൗസ് ചക്രംറൂളറിൻറ്റെ വലുപ്പം മാറ്റുക.
ഷിഫ്റ്റ് + മൗസ് ചക്രംറൂളറിൻറ്റെ വേഗത്തിലുള്ള വലുപ്പം മാറ്റൽ (വലിയ ഘട്ടങ്ങൾ). 43 |
45 |

https://screenruler.sourceforge.io

46 | 47 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.nl.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Hulp 7 | 17 | 18 | 19 |

Screen Ruler - Hulp

20 |

Toetsenbordacties

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
SpatieWissel liniaalmodus tussen horizontaal, verticaal en tweedimensionaal.
ZSelecteer een venster om op te meten. Annuleer met 'Esc'.
PijltjestoetsenVerplaats de liniaal met een pixel.
Shift + PijltjestoetsenVerplaats de liniaal met een medium stap (standaard 5px).
Ctrl + PijltjestoetsenVerander de liniaal grootte met een pixel.
Ctrl + Shift + PijltjestoetsenVerander de liniaal grootte met een medium stap (standaard 5px).
Alt + PijltjestoetsenPlaats de liniaal tegen de randen van het scherm.
Ctrl + CKopieër de huidige lengte naar het klembord.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LPlaats markering op huidige lengte.
CVerwijder de eerste markeringslijn.
EscScreen Ruler, venster of hulp sluiten.
Zie meer toetsenbordacties in het context menu.
37 |

Muisacties

38 | 39 | 40 | 41 | 42 | 43 |
Klik op een positie waar een markering is geplaatstOpent een dialog om de marker te bekijken of verwijderen.
Dubbelklik op de liniaalStelt een markering in op de aangeklikte positie.
MuiswielVerander de liniaal grootte.
Shift + MuiswielVerander de liniaal grootte versneld (grote stappen).
44 |

https://screenruler.sourceforge.io

45 | 46 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.pl.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Linijka Ekranowa (Screen Ruler) - Pomoc 7 | 17 | 18 | 19 |

Linijka Ekranowa (Screen Ruler) - Pomoc

20 |

Skróty klawiszowe

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
SpacjaObróć linijkę między trybem horyzontalnym, wertykalnym i dwuwymiarowym.
ZWybierz okno do zmierzenia. Anuluj klawiszem 'Esc'.
Klawisze strzałekPrzesuń linijkę o jeden piksel.
Shift + Klawisze strzałekPrzesuń linijkę o jeden średni krok (domyślnie 5px).
Ctrl + Klawisze strzałekZmień rozmiar linijki o jeden piksel.
Ctrl + Shift + Klawisze strzałekZmień rozmiar linijki o jeden średni krok (domyślnie 5px).
Alt + Klawisze strzałekPrzymocuj linijkę do brzegów ekranu.
Ctrl + CSkopiuj aktualną długość do schowka.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LUstaw znacznik na aktualnej długości.
CUsuń pierwszy znacznik linii.
EscWyłącz Linijkę Ekranową (Screen Ruler), selekcję okna lub pomoc.
Zobacz więcej skrótów klawiszowych w menu kontekstowym.
38 |

Akcje myszki

39 | 40 | 41 | 42 | 43 | 44 |
Kliknij na pozycję gdzie ustawiony jest markerOtwórz dialog by podejrzeć/usunąć marker.
Kliknij podwójnie na linijkęUstaw marker na pozycji kliknięcia.
Kółko myszyZmień rozmiar linijki.
Shift + Kółko myszySzybko zmień rozmiar linijki (duże kroki).
45 |

https://screenruler.sourceforge.io

46 | 47 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.pt.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Help 7 | 17 | 18 | 19 |

Screen Ruler - Help

20 |

Keyboard Actions

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
SpaceSwitch ruler mode between horizontal, vertical and two-dimensional.
ZSelect a window to measure. Cancel with 'Esc'.
Arrow keysMove the ruler by one pixel.
Shift + Arrow keysMove the ruler by one medium step (defaults to 5px).
Ctrl + Arrow keysResize the ruler by one pixel.
Ctrl + Shift + Arrow keysResize the ruler by one medium step (defaults to 5px).
Alt + Arrow keysDock the ruler to screen boundaries.
Ctrl + CCopy current length to clipboard.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LSet marker at current length.
CRemove the first custom marking line.
EscExit Screen Ruler, window selection or help.
See more keyboard actions in context menu.
37 |

Mouse Actions

38 | 39 | 40 | 41 | 42 | 43 |
Click on a position where a marker is setOpen dialog to view/ delete marker.
Double-click on rulerSet marker at the clicked position.
Mouse wheelResize the ruler.
Shift + Mouse wheelFast resizing of the ruler (large steps).
44 |

https://screenruler.sourceforge.io

45 | 46 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.ru.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | "Экранная линейка - Помощь 7 | 17 | 18 | 19 |

Экранная линейка - Помощь

20 |

Горячие клавиши

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
SpaceИзменить режим линейки между горизонтальным, вертикальным и двумерным.
ZВыбрать окно для измерений. Отменить на 'Esc'.
Arrow keysПереместить линейку на один пиксель.
Shift + Arrow keysПереместить линейку на один средний шаг (стандартно на 5px).
Ctrl + Arrow keysМасштабировать линейку на один пиксель.
Ctrl + Shift + Arrow keysМасштабировать линейку на один средний шаг (стандартно на 5px).
Alt + Arrow keysЗакрепить линейку на границах экрана.
Ctrl + CСкопировать выбранную длину в буфер обмена.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LУстановить метку на выбранную длину.
CПереместить первую пользовательскую линию разметки.
EscЗакрыть Экранную линейку, окно выбора или помощи.
Посмотрите больше действий с клавиатуры в контекстном меню.
37 |

Действия мыши

38 | 39 | 40 | 41 | 42 | 43 |
Шелчек левой кнопкой мыши на меткеОткрывает диалог обзора / удаления метки.
Двойной шелчек левой кнопкой мыши на линейкеУстанавливает метку на выбранной позиции.
Колесико мышиИзменяет размер линейки.
Shift + колесико мышиБыстрое изменение размера линейки (длинный шаг).
44 |

https://screenruler.sourceforge.io

45 | 46 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.sk.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - Nápoveda 7 | 17 | 18 | 19 |

Screen Ruler - Nápoveda

20 |

Klávesové skratky

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
MedzerníkPrepína mód pravítka na vodorovný, kolmý a dvojrozmerný.
ZVyber okno ktoré chceš zmerať. Ukončenie pomocou 'Esc'.
ŠípkyPosun pravítka o 1 pixel.
Shift + ŠípkyPosun pravítka o jeden stredný krok (predvolené o 5px).
Ctrl + ŠípkyZmeniť veľkosť pravítka o 1 pixel.
Ctrl + Shift + ŠípkyZmeniť veľkosť pravítka o stredný krok (predvolené o 5px).
Alt + ŠípkyUkotviť pravítko k okrajom obrazovky.
Ctrl + CSkopírujte dĺžku do schránky.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LNastaviť značku na aktuálnu dĺžku.
COdstráni prvú vlastnú označenú čiaru .
EscUkončí Screen Ruler, okno výberu, alebo nápovedu.
Viac klávesových skratiek nájdete v kontextovej ponuke.
37 |

Ovládanie myšou

38 | 39 | 40 | 41 | 42 | 43 |
Klik na miesto kde sa nachádza značkaOtvorí okno na zobrazenie / výmaz značky.
Dvojklik na pravítkoNastaví značku na aktuálnej pozícii.
Koliesko myšiZmena veľkosti pravítka.
Shift + Koliesko myšiRýchla zmena veľkosti pravítka (veľké kroky).
44 |

https://screenruler.sourceforge.io

45 | 46 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.sv.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Skärmlinjal - Hjälp 7 | 25 | 26 | 27 |

Skärmlinjal - Hjälp

28 |

Tangentbordsval

29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
Mellanslag Ändra linjalens läge mellan horisontellt, vertikalt och tvådimensionellt.
ZVälj ett fönster att mäta. Avsluta med 'Esc'.
PiltangenterFlytta linjalen med en pixel.
Shift + PiltangenterFlytta linjalen med en medium steglängd (Standard 5px).
Ctrl + PiltangenterÄndra storlek på linjalen med en pixel.
Ctrl + Shift + PiltangenterÄndra storleken på linjalen med en mediumsteglängd (standard 5px)
Alt + PiltangenterFäst linjalen till skärmens gränser.
Ctrl + CKopiera nuvarande längd till urklipp.
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
LSätt markören vid nuvarande längd.
CTa bort den första anpassade markörlinjen.
EscAvsluta Skärmlinjal, Fönsterval eller Hjälp.
Se mer tangentbordsval i kontextmenyn.
45 |

Musfunktioner

46 | 47 | 48 | 49 | 50 | 51 |
Klicka på en position där en markör är satt.Öppna dialog för att se/radera markör.
Dubbelklicka på linjalenSätt markören på den klickade positionen.
MushjulÄndra storlek på linjalen.
Shift + MushjulSnabb storleksändring av linjalen (stora steg).
52 |

https://screenruler.sourceforge.io

53 | 54 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.th-TH.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Screen Ruler - ช่วยเหลือ 7 | 17 | 18 | 19 |

Screen Ruler - ช่วยเหลือ

20 |

คำสั่งคีย์บอร์ด

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
Spaceสลัปโหมดไม้บรรทัดระหว่างแนวนอน, แนวตั้ง, หรือสองมิติ
Zเลือกหน้าต่างที่ต้องการวัด ยกเลิกด้วยปุ่ม Esc
ปุ่มลูกษรขยับไม้บรรทัด 1px
Shift + ปุ่มลูกษรขยับไม้บรรทัดขนาดกลาง (ค่าเดิม 5px)
Ctrl + ปุ่มลูกษรย่อขนาดไม้บรรทัดลง 1px
Ctrl + Shift + ปุ่มลูกษรย่อขนาดไม้บรรทัดลงขนาดกลาง (ค่าเดิม 5px)
Alt + ปุ่มลูกษรนำไม้บรรทัดชิดขอบจอ
Ctrl + Cคัดลอกความยาวปัจจุบันใส่คลิปบอร์ด
Lทำเครื่องหมายที่ความยาวปัจจุบัน
Cลบเครื่องหมายที่กำหนดเองอันแรก
Escออก Screen Ruler, เลือกหน้าต่าง, หรือช่วยเหลือ
ดูคำสั่งคีย์บอร์ดเพิ่มเติมใน context menu
35 |

คำสั่งเมาส์

36 | 37 | 38 | 39 | 40 | 41 |
คลิกบนเครื่องหมายที่ทำไว้เปิดหน้าต่างเพื่อดูหรือลบเครื่องหมาย
ดับเบิ้ลคลิกที่ไม้บรรทัดทำเครื่องหมายที่จุดคลิก
ลูกกลิ้งเมาส์ย่อขนาดไม้บรรทัด
Shift + ลูกกลิ้งเมาส์ย่อขนาดไม้บรรดทัดอย่างเร็ว (ขนาดใหญ่)
42 |

https://screenruler.sourceforge.io

43 | 44 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.zh-CN.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 屏幕标尺 (Screen Ruler) - 帮助 7 | 17 | 18 | 19 |

屏幕标尺(Screen Ruler) - 帮助

20 |

键盘事件

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
快捷键动作
空格切换测量模式 (水平测量,垂直测量,直角尺)
Z选择一个窗口进行测量,按 'Esc' 取消
方向键以 1像素 为单位移动标尺位置
Shift + 方向键以中步长移动标尺位置 (默认步长 5px)
Ctrl + 方向键以 1像素 为单位调整标尺尺寸
Ctrl + Shift + 方向键以中步长调整标尺尺寸 (默认步长 5px)
Alt + 方向键将标尺停靠在屏幕边界/td>
Ctrl + C复制当前长度到剪贴板
Ctrl + T在浅色与暗色之间切换标尺主题
Ctrl + "+"/"-"增加/减小标尺透明度
H显示对角线 (直角尺模式)
X在当前鼠标位置设置标记
L在当前长度设置标记
C移除第一条标记线
Esc关闭窗口/退出屏幕标尺
更多功能信息请在相关菜单的描述中查看
40 |

鼠标事件

41 | 42 | 43 | 44 | 45 | 46 |
单击设置标记的位置打开对话框以查看/删除标记。
在标尺某位置上双击在该位置设置标记
调整滚动鼠标滚轮调整标尺长度
Shift + 鼠标滚轮快速调整标尺长度 (大步长)
47 |

https://screenruler.sourceforge.io

48 | 49 | -------------------------------------------------------------------------------- /ScreenRuler/Help/Help.zh.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 屏幕标尺(Screen Ruler) - 帮助 7 | 17 | 18 | 19 |

屏幕标尺(Screen Ruler) - 帮助

20 |

键盘事件

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
快捷键动作
空格切换测量模式(水平测量,垂直测量,直角尺)
Z选择一个窗口进行测量,按 'Esc' 取消
方向键以 1像素 为单位移动标尺位置
Shift + 方向键以中步长移动标尺位置 (默认步长 5px)
Ctrl + 方向键以 1像素 为单位调整标尺尺寸
Ctrl + Shift + 方向键以中步长调整标尺尺寸(默认步长 5px)
Alt + 方向键将标尺停靠在屏幕边界/td>
Ctrl + C复制当前长度到剪贴板
Ctrl + T在浅色与暗色之间切换标尺主题
Ctrl + "+"/"-"增加/减小标尺透明度
HToggle hypotenuse display mode (2D only).
XSet marker(s) at current cursor position.
L在当前位置设置标记
C移除第一条标记线
Esc关闭窗口/退出屏幕标尺
更多功能信息请在相关菜单的描述中查看
40 |

鼠标事件

41 | 42 | 43 | 44 | 45 | 46 |
单击设置标记的位置打开对话框以查看/删除标记。
在标尺某位置上双击在该位置设置标记
调整滚动鼠标滚轮调整标尺长度
Shift + 鼠标滚轮快速调整标尺长度(大步长)
47 |

https://screenruler.sourceforge.io

48 | 49 | -------------------------------------------------------------------------------- /ScreenRuler/Marker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ScreenRuler 4 | { 5 | /// 6 | /// Models a marking line on the ruler. 7 | /// 8 | public struct Marker 9 | { 10 | public static readonly Marker Default = new Marker(); 11 | 12 | public float Value; 13 | public bool Vertical; 14 | 15 | public Marker(float value, bool vertical) 16 | { 17 | this.Value = value; 18 | this.Vertical = vertical; 19 | } 20 | 21 | public static bool operator ==(Marker x, Marker y) 22 | { 23 | return x.Value == y.Value && x.Vertical == y.Vertical; 24 | } 25 | 26 | public static bool operator !=(Marker x, Marker y) 27 | { 28 | return !(x == y); 29 | } 30 | 31 | public override bool Equals(object obj) 32 | { 33 | if (obj is Marker other) 34 | { 35 | return this.Value == other.Value && this.Vertical == other.Vertical; 36 | } 37 | else return false; 38 | } 39 | 40 | public override int GetHashCode() 41 | { 42 | return Value.GetHashCode(); 43 | } 44 | 45 | public string DisplayString 46 | { 47 | get 48 | { 49 | if (!Vertical) return String.Format("⇄ {0,6} px", Value); 50 | else return String.Format("⇅ {0,6} px", Value); 51 | } 52 | } 53 | 54 | public static Marker FromString(string s) 55 | { 56 | string v = s.Substring(0, s.Length - 1); 57 | string t = s.Substring(s.Length - 1, 1); 58 | float value = float.Parse(v); 59 | bool vertical = t == "v" ? true : t == "h" ? false : throw new ArgumentException(); 60 | return new Marker(value, vertical); 61 | } 62 | 63 | public override string ToString() 64 | { 65 | string type = Vertical ? "v" : "h"; 66 | return $"{Value}{type}"; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ScreenRuler/MarkerCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | using System.Xml.Serialization; 6 | 7 | namespace ScreenRuler 8 | { 9 | [Serializable] 10 | public class MarkerCollection 11 | { 12 | private int limit = int.MaxValue; 13 | 14 | /// 15 | /// This event is raised when a marker was added to the collection or if a marker was removed. 16 | /// 17 | public event EventHandler MarkerCollectionChanged; 18 | 19 | public MarkerCollection() 20 | { 21 | Markers = new LinkedList(); 22 | } 23 | 24 | [XmlIgnore] 25 | public int Limit 26 | { 27 | get => limit; 28 | set 29 | { 30 | limit = value; 31 | // remove additional markers 32 | while (Markers.Count > limit) 33 | RemoveFirstMarker(); 34 | } 35 | } 36 | 37 | [XmlIgnore] 38 | public LinkedList Markers { get; private set; } 39 | 40 | // String property used for serialization 41 | [XmlElement("Markers")] 42 | public string MarkersString 43 | { 44 | get => String.Join(",", Markers); 45 | set 46 | { 47 | Markers = new LinkedList( 48 | value.Split(',').Where(s => !String.IsNullOrWhiteSpace(s)) 49 | .Select(s => Marker.FromString(s)) 50 | ); 51 | } 52 | } 53 | 54 | public IEnumerable Horizontal => Markers.Where(m => !m.Vertical); 55 | 56 | public IEnumerable Vertical => Markers.Where(m => m.Vertical); 57 | 58 | /// 59 | /// Adds a marker to the collection based on its location on the ruler form. 60 | /// 61 | /// The location of the marker. 62 | public void AddMarker(Point pos, int limit, bool verticalOnly = false) 63 | { 64 | // Add the marker as horizontal or vertical marker based on position 65 | bool vertical = verticalOnly || pos.Y >= limit; 66 | Marker newMarker; 67 | if (vertical) 68 | newMarker = new Marker(pos.Y, true); 69 | else newMarker = new Marker(pos.X, false); 70 | AddMarker(newMarker); 71 | } 72 | 73 | public void AddMarker(Marker marker) 74 | { 75 | Markers.AddLast(marker); 76 | // remove first if we hit limit 77 | if (Markers.Count > Limit) 78 | RemoveFirstMarker(); 79 | MarkerCollectionChanged?.Invoke(this, new MarkerCollectionEventArgs(true, marker)); 80 | } 81 | 82 | /// 83 | /// Returns the closest marker within a specified window if available. 84 | /// 85 | /// The search location. 86 | /// The search window size. 87 | /// The found marker if available, a default marker otherwise. 88 | public Marker GetMarker(Point pos, int limit, int diff = 2) 89 | { 90 | Marker marker = Marker.Default; 91 | // first search horizontal markers, then vertical markers 92 | if (pos.Y < limit) 93 | { 94 | marker = Markers.Where((v) => Math.Abs(pos.X - v.Value) <= diff).FirstOrDefault(); 95 | } 96 | if (marker == Marker.Default) 97 | { 98 | return Markers.Where((v) => Math.Abs(pos.Y - v.Value) <= diff).FirstOrDefault(); 99 | } 100 | return marker; 101 | } 102 | 103 | public void RemoveMarker(Marker marker) 104 | { 105 | Markers.Remove(marker); 106 | MarkerCollectionChanged?.Invoke(this, new MarkerCollectionEventArgs(false, marker)); 107 | } 108 | 109 | public void RemoveFirstMarker() 110 | { 111 | var first = Markers.First.Value; 112 | Markers.RemoveFirst(); 113 | MarkerCollectionChanged?.Invoke(this, new MarkerCollectionEventArgs(false, first)); 114 | } 115 | 116 | public void Clear() 117 | { 118 | var removedItems = Markers.ToArray(); 119 | Markers.Clear(); 120 | MarkerCollectionChanged?.Invoke(this, new MarkerCollectionEventArgs(false, removedItems)); 121 | } 122 | } 123 | 124 | public class MarkerCollectionEventArgs : EventArgs 125 | { 126 | public Marker[] AddedMarkers { get; } 127 | public Marker[] RemovedMarkers { get; } 128 | 129 | public MarkerCollectionEventArgs(bool isAdded, params Marker[] changedMarkers) 130 | { 131 | if (isAdded) AddedMarkers = changedMarkers; 132 | else RemovedMarkers = changedMarkers; 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /ScreenRuler/MouseTracker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Threading; 4 | using System.Windows.Forms; 5 | 6 | namespace ScreenRuler 7 | { 8 | public class MouseTracker 9 | { 10 | Thread thread; 11 | 12 | public Point Position { get; private set; } 13 | 14 | public event EventHandler Tick; 15 | 16 | public MouseTracker(Form form, int ticks = 50) 17 | { 18 | thread = new Thread(() => 19 | { 20 | while (true) 21 | { 22 | if (form.IsHandleCreated) 23 | { 24 | form.Invoke(new MethodInvoker(() => { 25 | if (form.Bounds.Contains(Cursor.Position)) 26 | { 27 | this.Position = form.PointToClient(Cursor.Position); 28 | form.Invalidate(); 29 | } 30 | Tick?.Invoke(this, EventArgs.Empty); 31 | })); 32 | } 33 | Thread.Sleep(ticks); 34 | } 35 | }); 36 | thread.IsBackground = true; 37 | } 38 | 39 | public void Start() => thread.Start(); 40 | 41 | public void Stop() 42 | { 43 | thread.Abort(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ScreenRuler/Options.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CommandLine; 3 | 4 | namespace ScreenRuler 5 | { 6 | public class Options 7 | { 8 | [Option('x', SetName = "basic", HelpText = "Set X coordinate of ruler.")] 9 | public int? X { get; set; } 10 | [Option('y', SetName = "basic", HelpText = "Set Y coordinate of ruler.")] 11 | public int? Y { get; set; } 12 | [Option("width", SetName = "basic", HelpText = "Set width of ruler.")] 13 | public int? Width { get; set; } 14 | [Option("height", SetName = "basic", HelpText = "Set height of ruler.")] 15 | public int? Height { get; set; } 16 | 17 | [Option("hwnd", SetName = "hwnd", HelpText = "Specify the handle to a window to be measured.")] 18 | public int? WindowHandle { get; set; } 19 | 20 | [Option('t', "title", SetName = "title", HelpText = "Specify the title of the window to be measured.")] 21 | public string WindowTitle { get; set; } 22 | 23 | [Option("config", HelpText = "A configuration file from which to load ruler settings.")] 24 | public string ConfigFile { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ScreenRuler/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using Bluegrams.Application; 4 | using CommandLine; 5 | using CommandLine.Text; 6 | 7 | namespace ScreenRuler 8 | { 9 | static class Program 10 | { 11 | public const string UPDATE_URL = "https://screenruler.sourceforge.io/update.xml"; 12 | 13 | public const string UPDATE_MODE = "portable"; 14 | 15 | [STAThread] 16 | static void Main(string[] args) 17 | { 18 | var result = Parser.Default.ParseArguments(args); 19 | result.WithParsed(o => Run(o)) 20 | .WithNotParsed(errs => MessageBox.Show(HelpText.AutoBuild(result), AppInfo.Title)); 21 | } 22 | 23 | static void Run(Options options = null) 24 | { 25 | AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 26 | Application.EnableVisualStyles(); 27 | Application.SetCompatibleTextRenderingDefault(false); 28 | Application.Run(new RulerForm(options)); 29 | } 30 | 31 | private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 32 | { 33 | Logger.Default.Log("An unhandled exception caused the application to terminate unexpectedly.", 34 | (Exception)e.ExceptionObject); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ScreenRuler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.InteropServices; 4 | using Bluegrams.Application.Attributes; 5 | 6 | [assembly: AssemblyTitle("Screen Ruler")] 7 | [assembly: AssemblyDescription("Screen measuring tool for Windows")] 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("Bluegrams")] 10 | [assembly: AssemblyProduct("Screen Ruler")] 11 | [assembly: AssemblyCopyright("Copyright © 2017-2022 Bluegrams")] 12 | [assembly: AssemblyTrademark("")] 13 | [assembly: AssemblyCulture("")] 14 | 15 | [assembly: ProductWebsite("https://screenruler.sourceforge.io")] 16 | [assembly: ProductLicense("https://github.com/Bluegrams/ScreenRuler/blob/master/LICENSE.txt", "BSD-3-Clause")] 17 | [assembly: CompanyWebsite("http://bluegrams.com", "Bluegrams")] 18 | 19 | #if PORTABLE 20 | [assembly: AppPortable(true)] 21 | #endif 22 | 23 | // Setting ComVisible to false makes the types in this assembly not visible 24 | // to COM components. If you need to access a type in this assembly from 25 | // COM, set the ComVisible attribute to true on that type. 26 | [assembly: ComVisible(false)] 27 | 28 | // The following GUID is for the ID of the typelib if this project is exposed to COM 29 | [assembly: Guid("67b8f96e-8237-4c57-983b-a2ca5bddc9ae")] 30 | 31 | [assembly: NeutralResourcesLanguage("en")] 32 | 33 | [assembly: AssemblyVersion("0.10.0")] 34 | [assembly: AssemblyFileVersion("0.10.0")] 35 | -------------------------------------------------------------------------------- /ScreenRuler/Properties/EnumResources.pl.Designer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/ScreenRuler/Properties/EnumResources.pl.Designer.cs -------------------------------------------------------------------------------- /ScreenRuler/Properties/EnumResources.zh-CN.Designer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/ScreenRuler/Properties/EnumResources.zh-CN.Designer.cs -------------------------------------------------------------------------------- /ScreenRuler/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ScreenRuler.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ScreenRuler.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Scaling: {0}. 65 | /// 66 | internal static string ScalingText { 67 | get { 68 | return ResourceManager.GetString("ScalingText", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to Width: {0}px 74 | ///Height: {1}px 75 | ///Position: {2}. 76 | /// 77 | internal static string ToolTipText { 78 | get { 79 | return ResourceManager.GetString("ToolTipText", resourceCulture); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /ScreenRuler/Properties/Resources.pl.Designer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/ScreenRuler/Properties/Resources.pl.Designer.cs -------------------------------------------------------------------------------- /ScreenRuler/Properties/Resources.zh-CN.Designer.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/ScreenRuler/Properties/Resources.zh-CN.Designer.cs -------------------------------------------------------------------------------- /ScreenRuler/Properties/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /ScreenRuler/Units/MeasuringUnit.cs: -------------------------------------------------------------------------------- 1 | using ScreenRuler.Properties; 2 | using ScreenRuler.Configuration; 3 | 4 | namespace ScreenRuler.Units 5 | { 6 | /// 7 | /// Possible measuring units used for the user scale. 8 | /// 9 | public enum MeasuringUnit 10 | { 11 | [LocalizedDescription("Pixels", typeof(EnumResources))] 12 | Pixels = 0, 13 | [LocalizedDescription("Centimeters", typeof(EnumResources))] 14 | Centimeters = 1, 15 | [LocalizedDescription("Inches", typeof(EnumResources))] 16 | Inches = 2, 17 | [LocalizedDescription("Points", typeof(EnumResources))] 18 | Points = 3, 19 | [LocalizedDescription("Percent", typeof(EnumResources))] 20 | Percent = 4 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ScreenRuler/WinApi.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Drawing; 4 | using System.Security; 5 | 6 | namespace ScreenRuler 7 | { 8 | public enum MonitorOptions 9 | { 10 | MONITOR_DEFAULTTONULL = 0, 11 | MONITOR_DEFAULTTOPRIMARY = 1, 12 | MONITOR_DEFAULTTONEAREST = 2 13 | } 14 | 15 | public enum MonitorDpiType 16 | { 17 | EFFECTIVE_DPI = 0, 18 | ANGULAR_DPI = 1, 19 | RAW_DPI = 2, 20 | } 21 | 22 | /// 23 | /// A class that wraps used Win32 API calls. 24 | /// 25 | public static class WinApi 26 | { 27 | #region API methods 28 | 29 | [StructLayout(LayoutKind.Sequential)] 30 | internal struct WinPoint 31 | { 32 | public int X; 33 | public int Y; 34 | 35 | public static explicit operator Point(WinPoint point) 36 | { 37 | return new Point(point.X, point.Y); 38 | } 39 | 40 | public static explicit operator WinPoint(Point point) 41 | { 42 | WinPoint pt = new WinPoint(); 43 | pt.X = (int)point.X; 44 | pt.Y = (int)point.Y; 45 | return pt; 46 | } 47 | } 48 | 49 | [StructLayout(LayoutKind.Sequential)] 50 | internal struct WinRect 51 | { 52 | public int Left; 53 | public int Top; 54 | public int Right; 55 | public int Bottom; 56 | 57 | public static explicit operator Rectangle(WinRect winRect) 58 | { 59 | int width = winRect.Right - winRect.Left; 60 | int height = winRect.Bottom - winRect.Top; 61 | return new Rectangle(winRect.Left, winRect.Top, width, height); 62 | } 63 | } 64 | 65 | [DllImport("user32.dll")] 66 | private static extern IntPtr WindowFromPoint(WinPoint point); 67 | 68 | [DllImport("user32.dll", SetLastError = true)] 69 | private static extern bool GetWindowRect(IntPtr hWnd, out WinRect lpRect); 70 | 71 | [DllImport("user32.dll", SetLastError = true)] 72 | private static extern IntPtr FindWindowEx(IntPtr hWndParent, IntPtr hWndChildAfter, string className, string windowTitle); 73 | 74 | [DllImport("dwmapi.dll")] 75 | private static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out WinRect pvAttribute, int cbAttribute); 76 | 77 | [SuppressUnmanagedCodeSecurity] 78 | [DllImport("User32.dll")] 79 | private static extern IntPtr MonitorFromWindow(IntPtr hwnd, MonitorOptions dwFlags); 80 | 81 | // requires Windows 8.1 or newer 82 | [SuppressUnmanagedCodeSecurity] 83 | [DllImport("Shcore.dll")] 84 | private static extern IntPtr GetDpiForMonitor(IntPtr hmonitor, MonitorDpiType dpiType, out int dpiX, out int dpiY); 85 | 86 | #endregion 87 | 88 | #region Static methods 89 | 90 | /// 91 | /// Retrieves the bounding rectangle of the window at the specified point. 92 | /// 93 | public static Rectangle GetWindowRectangle(Point point) 94 | { 95 | IntPtr hWnd = WindowFromPoint((WinPoint)point); 96 | return GetWindowRectangle(hWnd); 97 | } 98 | 99 | /// 100 | /// Retrieves the bounding rectangle of the window with the specified title. 101 | /// 102 | public static Rectangle GetWindowRectangle(string windowTitle) 103 | { 104 | IntPtr hWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, windowTitle); 105 | return GetWindowRectangle(hWnd); 106 | } 107 | 108 | public static Rectangle GetWindowRectangle(IntPtr hWnd) 109 | { 110 | if (hWnd == null) 111 | return Rectangle.Empty; 112 | 113 | int result = DwmGetWindowAttribute( 114 | hWnd, 115 | /*DWMWA_EXTENDED_FRAME_BOUNDS*/ 9, 116 | out WinRect rect, 117 | Marshal.SizeOf(typeof(WinRect))); 118 | if (result < 0) 119 | GetWindowRect(hWnd, out rect); 120 | return (Rectangle)rect; 121 | } 122 | 123 | /// 124 | /// Gets the dpi of the monitor. 125 | /// 126 | /// The window handle used to determine the monitor of interest. 127 | /// A value of MonitorDpiType indicating the dpi type to be returned. 128 | /// The dpi of the monitor. 129 | public static int GetMonitorDpiFromWindow(IntPtr hWnd, MonitorDpiType dpiType) 130 | { 131 | IntPtr hmonitor = MonitorFromWindow(hWnd, MonitorOptions.MONITOR_DEFAULTTONEAREST); 132 | GetDpiForMonitor(hmonitor, dpiType, out int dpiX, out int dpiY); 133 | return dpiX; 134 | } 135 | 136 | #endregion 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /ScreenRuler/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ScreenRuler/rulerico.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/ScreenRuler/rulerico.ico -------------------------------------------------------------------------------- /choco/screenruler.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | screenruler 7 | 0.10.0 8 | alxnull 9 | 10 | 11 | 12 | Screen Ruler 13 | alxnull 14 | https://screenruler.sourceforge.io/ 15 | https://raw.githubusercontent.com/Bluegrams/ScreenRuler/master/img/icon.png 16 | © 2017-2022 Bluegrams 17 | https://github.com/bluegrams/ScreenRuler/blob/master/LICENSE.txt 18 | false 19 | https://github.com/bluegrams/ScreenRuler 20 | https://github.com/bluegrams/ScreenRuler 21 | https://github.com/bluegrams/ScreenRuler/issues 22 | screenruler ruler pixel screen measure 23 | Configurable screen ruler for measuring in pixels, centimeters, inches and points. 24 | Screen Ruler is a lightweight and configurable ruler tool for Windows Desktop. 25 | It allows you to measure the size of elements on the screen in different units, including pixels, centimeters and inches. 26 | Measuring is possible either using a two-dimensional, rectangular ruler scale or a one-dimensional, horizontal or vertical scale. 27 | The ruler can be moved and resized precisely using either the mouse or the keyboard and custom marking lines can be added. 28 | Besides coming with a light and a dark theme, Screen Ruler also allows you to fully customize its appearance by changing all color settings. 29 | https://github.com/bluegrams/ScreenRuler/blob/master/Changelog.md 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /choco/tools/VERIFICATION.txt: -------------------------------------------------------------------------------- 1 | VERIFICATION 2 | Verification is intended to assist the Chocolatey moderators and community 3 | in verifying that this package's contents are trustworthy. 4 | 5 | I (user alxnull) am the developer of Screen Ruler. 6 | -------------------------------------------------------------------------------- /choco/tools/chocolateyUninstall.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = 'Stop'; 2 | 3 | Remove-Item "$HOME\Desktop\Screen Ruler.lnk" 4 | Remove-Item "$([Environment]::GetFolderPath('CommonStartMenu'))\Programs\Bluegrams\Screen Ruler.lnk" 5 | -------------------------------------------------------------------------------- /choco/tools/chocolateyinstall.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = 'Stop'; 2 | $toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" 3 | 4 | 5 | $archive = Join-Path $toolsDir "screenruler.zip" 6 | Get-ChocolateyUnzip -FileFullPath $archive -Destination $toolsDir -PackageName $env:ChocolateyPackageName 7 | 8 | $targetDir = Join-Path $toolsDir "screenruler" 9 | $target = Join-Path $targetDir "screenruler.exe" 10 | Install-ChocolateyShortcut -shortcutFilePath "$HOME\Desktop\Screen Ruler.lnk" -targetPath $target -workingDirectory $targetDir 11 | Install-ChocolateyShortcut -shortcutFilePath "$([Environment]::GetFolderPath('CommonStartMenu'))\Programs\Bluegrams\Screen Ruler.lnk" -targetPath $target -workingDirectory $targetDir 12 | 13 | New-Item -Path "$target.gui" -ItemType File -Force | Out-Null 14 | -------------------------------------------------------------------------------- /img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/img/icon.png -------------------------------------------------------------------------------- /img/screenruler_2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/img/screenruler_2d.png -------------------------------------------------------------------------------- /img/screenruler_styles_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bluegrams/ScreenRuler/4f6460f37464be27f845d69650e393017a33fd56/img/screenruler_styles_small.png --------------------------------------------------------------------------------