diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1f09762623..37ba10bc4d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -79,6 +79,7 @@ body: - TextExtractor - Workspaces - Welcome / PowerToys Tour window + - ZoomIt validations: required: true diff --git a/.github/ISSUE_TEMPLATE/translation_issue.yml b/.github/ISSUE_TEMPLATE/translation_issue.yml index 63efb7c928..ffddacb9aa 100644 --- a/.github/ISSUE_TEMPLATE/translation_issue.yml +++ b/.github/ISSUE_TEMPLATE/translation_issue.yml @@ -53,6 +53,7 @@ body: - TextExtractor - Workspaces - Welcome / PowerToys Tour window + - ZoomIt validations: required: true - type: input diff --git a/.github/actions/spell-check/allow/names.txt b/.github/actions/spell-check/allow/names.txt index d82eb28c11..4941c62e13 100644 --- a/.github/actions/spell-check/allow/names.txt +++ b/.github/actions/spell-check/allow/names.txt @@ -33,6 +33,7 @@ Adoumie Advaith alekhyareddy Aleks +amihaiuc angularsen Anirudha arjunbalgovind @@ -67,6 +68,7 @@ Essey Feng ethanfangg ferraridavide +foxmsft frankychen Gaarden gaardmark @@ -114,6 +116,7 @@ martinchrzan martinmoene Melman Mengyuan +Mihaiuc Mikhayelyan msft Mykhailo @@ -141,6 +144,7 @@ ricardosantos riri ritchielawrence robmikh +Russinovich Rutkas ryanbodrug saahmedm @@ -185,6 +189,7 @@ Zykova Bilibili BVID +capturevideosample cmdow Controlz cortana diff --git a/.github/actions/spell-check/excludes.txt b/.github/actions/spell-check/excludes.txt index 80fee9ff24..912d72d472 100644 --- a/.github/actions/spell-check/excludes.txt +++ b/.github/actions/spell-check/excludes.txt @@ -16,6 +16,7 @@ (?:|$^ 92.31% - excluded 12/13)/editor/[^/]+$ /images/launcher/[^/]+$ /TestFiles/ +[^/]\.cur$ [^/]\.gcode$ [^/]\.rgs$ \.a$ @@ -119,5 +120,6 @@ ^src/modules/MouseWithoutBorders/App/Helper/.*\.resx$ ^src/modules/previewpane/UnitTests-MarkdownPreviewHandler/HelperFiles/MarkdownWithHTMLImageTag\.txt$ ^src/Monaco/ +^src/common/sysinternals/Eula/ ^tools/Verification scripts/Check preview handler registration\.ps1$ ignore$ diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index f0d15e6ba2..c802457500 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -15,6 +15,7 @@ AColumn acrt ACTIVATEAPP activationaction +ADDSTRING ADDUNDORECORD ADifferent adml @@ -27,8 +28,10 @@ AGGREGATABLE ahk AHybrid akv +ALIGNRIGHT ALarger ALLAPPS +ALLCHILDREN ALLINPUT ALLOWUNDO ALLVIEW @@ -39,6 +42,7 @@ AMPROPSETID amr ANDSCANS animatedvisuals +Animnate ansicolor ANull AOC @@ -69,6 +73,7 @@ ARemapped ARPINSTALLLOCATION ARPPRODUCTICON ARRAYSIZE +ARROWKEYS asf AShortcut ASingle @@ -86,9 +91,14 @@ atlstr ATRIOX aumid Authenticode +AUTOBUDDY +AUTOCHECKBOX AUTOHIDE +AUTOHSCROLL AUTOMATIONPROPERTIES +AUTORADIOBUTTON Autorun +AUTOTICKS AUTOUPDATE AValid awakeness @@ -105,12 +115,17 @@ BIF bigbar bigobj binlog +binres BITMAPFILEHEADER bitmapimage BITMAPINFO BITMAPINFOHEADER +Bitmaps +BITSPERPEL BITSPIXEL bla +BLACKFRAME +BLENDFUNCTION Blockquotes blogs Blt @@ -143,6 +158,7 @@ BVal BValue byapp BYPOSITION +CALCRECT CALG callbackptr calpwstr @@ -171,6 +187,7 @@ CHANGECBCHAIN changecursor CHILDACTIVATE CHILDWINDOW +CHOOSEFONT cidl cim CImage @@ -209,6 +226,7 @@ colorformat colorhistory colorhistorylimit COLORKEY +comctl comdef comdlg comexp @@ -231,14 +249,17 @@ CONTEXTMENUHANDLER CONTROLL CONTROLPARENT copiedcolorrepresentation +COPYPEN COREWINDOW cotaskmem COULDNOT countof cph +cplusplus CPower cppwinrt createdump +CREATEPROCESS CREATESCHEDULEDTASK CREATESTRUCT CREATEWINDOWFAILED @@ -254,6 +275,8 @@ cso CSRW CStyle CTest +CTEXT +CTLCOLORSTATIC currentculture CURRENTDIR CURSORINFO @@ -313,10 +336,12 @@ DELA DELETEDKEYIMAGE DELETESCANS deletethis +DEMOTYPE DENORMAL depersist deprioritized DESELECTOTHERS +DESIGNINFO DESKTOPABSOLUTEEDITING DESKTOPABSOLUTEPARSING desktopshorcutinstalled @@ -331,12 +356,17 @@ DEVMON devpkey DEVSOURCE DGR +DIALOGEX DIIRFLAG dimm DISABLEASACTIONKEY +DISABLENOSCROLL diskmgmt DISPLAYCHANGE DISPLAYCONFIG +DISPLAYFLAGS +DISPLAYFREQUENCY +DISPLAYORIENTATION displayname divyan Dlg @@ -360,8 +390,11 @@ DRAWFRAME drawingcolor dreamsofameaningfullife drivedetectionwarning +DROPFILES dshow DSTINVERT +DSurface +DTexture DUMMYUNIONNAME Dutil DVASPECT @@ -398,12 +431,15 @@ EData Edid EDITKEYBOARD EDITSHORTCUTS +EDITTEXT EFile ekus emmintrin Emoji ENABLEDELAYEDEXPANSION ENABLEDPOPUP +ENABLETAB +ENABLETEMPLATE encodedlaunch encryptor endpointvolume @@ -423,8 +459,10 @@ ERRORTITLE erwrite ESettings esrp +ETDT etl etw +eula eurochange eventlog eventvwr @@ -454,6 +492,7 @@ exsb exstyle EXTENDEDKEY EXTENDEDVERBS +EXTRALIGHT EXTRINSICPROPERTIES eyetracker FANCYZONESDRAWLAYOUTTEST @@ -464,12 +503,14 @@ fff FILEEXPLORER FILEFLAGS FILEFLAGSMASK +FILEINFOSIG FILELOCKSMITH FILELOCKSMITHCONTEXTMENU FILELOCKSMITHEXT FILELOCKSMITHLIBINTEROP FILEMUSTEXIST FILEOP +FILEOPENDIALOGOPTIONS FILEOS FILESUBTYPE FILESYSPATH @@ -477,9 +518,11 @@ Filetime FILEVERSION Filtergraph Filterkeyboard +FILTERMODE Filterx findfast FIXEDFILEINFO +FIXEDSYS flac flyouts FMask @@ -487,7 +530,10 @@ FOF FOFX FOLDERID folderpath +FONTTYPE +FORCEFILESYSTEM FORCEMINIMIZE +FORMATDLGORD formatetc FORPARSING FRAMECHANGED @@ -504,18 +550,23 @@ GC'ed GCLP gdi gdiplus +GDIPVER GDISCALED GEmoji GETCLIENTAREAANIMATION +GETCURSEL GETDESKWALLPAPER GETDLGCODE GETDPISCALEDSIZE getfilesiginforedist GETICON +GETHOTKEY GETMINMAXINFO +GETNONCLIENTMETRICS GETPROPERTYSTOREFLAGS GETSCREENSAVERRUNNING GETSECKEY +GETSTICKYKEYS GETTEXTLENGTH GHND GMEM @@ -548,6 +599,7 @@ hbm hbmp hbr HBRBACKGROUND +hbrush hcblack HCERTSTORE HCRYPTHASH @@ -555,6 +607,7 @@ HCRYPTPROV hcursor hcwhite hdc +hdr hdrop hdwwiz Helpline @@ -567,6 +620,7 @@ Hiber Hiberboot HIBYTE hicon +HIDEREADONLY HIDEWINDOW Hif HIMAGELIST @@ -575,10 +629,12 @@ hinst hinstance HIWORD HKCC +HKCOMB HKCR HKCU hkey HKLM +HKM HKPD HKU HMD @@ -586,9 +642,11 @@ hmenu hmodule hmonitor homljgmgpmcbpjbnjpfijnhipfkiclkd +HORZRES HORZSIZE Hostbackdropbrush hotkeycontrol +HOTKEYF hotkeys hotlight hotspot @@ -616,15 +674,19 @@ hwnd HWNDFIRST HWNDLAST HWNDNEXT +HWNDPARENT HWNDPREV hyjiacan IAI IBeam ICONERROR ICONLOCATION +idc +IDCANCEL IDD idl idlist +IDOK IDR IDXGI ietf @@ -645,12 +707,15 @@ imageresizerinput imageresizersettings imagingdevices ime +INCONTACT Indo inetcpl Infobar INFOEXAMPLE Infotip +INITDIALOG INITGUID +INITTOLOGFONTSTRUCT inorder INPC inproc @@ -733,18 +798,23 @@ lcb LCIDTo Lclean Ldone +Ldr ldx LEFTSCROLLBAR +LEFTTEXT LError LEVELID LExit lhwnd LIBID +LIMITSIZE +LIMITTEXT lindex linkid LINKOVERLAY LINQTo listview +LIVEZOOM lld LLKH llkhf @@ -762,12 +832,15 @@ LOGFONT LOGFONTW logon LOGPIXELSX +LOGPIXELSY longdate LONGLONG +LONGNAMES lowlevel LOWORD lparam LPBITMAPINFOHEADER +LPCFHOOKPROC LPCITEMIDLIST LPCLSID lpcmi @@ -797,12 +870,15 @@ LPTSTR LPW lpwcx lpwndpl +lpv LReader LRESULT LSTATUS lstrcmp lstrcmpi +lstrcpyn lstrlen +LTEXT LTRB LTRREADING luid @@ -812,12 +888,16 @@ LVal LWA lwin LZero +MAGTRANSFORM majortype makecab MAKEINTRESOURCE MAKEINTRESOURCEA MAKEINTRESOURCEW MAKELANGID +MAKELONG +MAKELPARAM +MAKEWPARAM manifestdependency MAPPEDTOSAMEKEY MAPTOSAMESHORTCUT @@ -857,6 +937,7 @@ MINIMIZEBOX MINIMIZEEND MINIMIZESTART miniz +MINMAXINFO Mip Miracast mjpg @@ -870,6 +951,7 @@ mmi mmsys mmsystem mockapi +MODALFRAME MODESPRUNED MONITORENUMPROC MONITORINFO @@ -891,6 +973,7 @@ MRT mru msc mscorlib +msctls msdata MSDL msedge @@ -898,6 +981,7 @@ MSGFLT msiexec MSIFASTINSTALL MSIHANDLE +Msimg msiquery MSIRESTARTMANAGERCONTROL msixbundle @@ -909,6 +993,7 @@ msrc msstore mst msvcp +msvsmon MTND MULTIPLEUSE multizone @@ -958,33 +1043,40 @@ newsgroups NIF NLog NLSTEXT +NMAKE NNN NOACTIVATE NOAGGREGATION NOASYNC +NOCLIP NOCLOSEPROCESS NOCOALESCE NOCOMM NOCONFIRMMKDIR NOCOPYBITS NOCOPYSECURITYATTRIBS +NOCRLF nodeca nodoc NODRAWCAPTION NODRAWICON NOINHERITLAYOUT NOINTERFACE +NOINVERT NOLINKINFO NOMCX NOMINMAX NOMIRRORBITMAP NOMOVE +NONANTIALIASED nonclient +NONCLIENTMETRICSW NONELEVATED NONINFRINGEMENT nonstd NOOWNERZORDER NOPARENTNOTIFY +NOPREFIX NOREDIRECTIONBITMAP NOREDRAW NOREMOVE @@ -997,6 +1089,8 @@ NORMALUSER NOSEARCH NOSENDCHANGING NOSIZE +NOTHOUSANDS +NOTICKS NOTIFICATIONSDLL NOTIFYICONDATA NOTIFYICONDATAW @@ -1006,6 +1100,7 @@ NOTOPMOST NOTRACK NOTSRCCOPY NOTSRCERASE +NOTXORPEN NOZORDER NPH npmjs @@ -1015,6 +1110,8 @@ NTAPI ntdll ntfs NTSTATUS +NTSYSAPI +NULLCURSOR nullonfailure numberbox nwc @@ -1023,6 +1120,7 @@ objidl ocr Ocrsettings odbccp +OEMCONVERT officehubintl OFN ofs @@ -1042,8 +1140,10 @@ ORPHANEDDIALOGTITLE ORSCANS oss ostr +OSVERSIONINFO OSVERSIONINFOEX OSVERSIONINFOEXW +OSVERSIONINFOW osvi OUTOFCONTEXT outpin @@ -1053,7 +1153,9 @@ outsettings OVERLAPPEDWINDOW overlaywindow Oversampling +OVERWRITEPROMPT OWNDC +OWNERDRAWFIXED Packagemanager PACL PAINTSTRUCT @@ -1082,7 +1184,9 @@ PCIDLIST PCTSTR PCWSTR pdbs +PDEVMODE pdisp +PDLL pdo pdto pdtobj @@ -1090,6 +1194,8 @@ pdw Peb PElems Pels +PELSHEIGHT +PELSWIDTH PERCEIVEDFLAG perfmon pesi @@ -1116,9 +1222,13 @@ ploc ploca plocm pluginsmodel +PMAGTRANSFORM PMSIHANDLE pnid +PNMLINK Pnp +POINTERID +POINTERUPDATE Popups POPUPWINDOW POSITIONITEM @@ -1164,6 +1274,7 @@ PROCESSENTRY PROCESSKEY processthreadsapi PROCESSTRACE +procmon PRODEXT PRODUCTVERSION Progman @@ -1174,6 +1285,7 @@ PROPERTYKEY propkey PROPVARIANT propvarutil +PRTL prvpane psapi pscid @@ -1192,6 +1304,7 @@ PSYSTEM psz ptb ptc +PTCHAR ptd PTOKEN PToy @@ -1223,6 +1336,8 @@ RAWMODE RAWPATH rbhid rclsid +RCZOOMIT +RDW READMODE READOBJECTS recents @@ -1325,6 +1440,7 @@ SCID Scip scipbe Scode +SCREENFONTS screensaver screenshots scrollviewer @@ -1333,16 +1449,27 @@ SDKDDK sdns searchterm SEARCHUI +SECONDARYDISPLAY secpol +SELCHANGE SENDCHANGE sendvirtualinput serverside +SETBUDDYINT SETCONTEXT +SETCURSEL setcursor SETFOCUS SETFOREGROUND +SETHOTKEY SETICON +SETLOWPOWERACTIVE +SETPOWEROFFACTIVE +SETRANGE SETREDRAW +SETRULES +SETSCREENSAVEACTIVE +SETSTICKYKEYS SETTEXT SETTINGCHANGE SETTINGSCHANGED @@ -1352,6 +1479,7 @@ setvariable SETWORKAREA sfgao SFGAOF +SHACF SHANDLE sharpkeys SHCNE @@ -1389,6 +1517,7 @@ shortsplit showcolorname SHOWDEFAULT SHOWELEVATIONPROMPT +SHOWMAGNIFIEDCURSOR SHOWMAXIMIZED SHOWMINIMIZED SHOWMINNOACTIVE @@ -1463,6 +1592,7 @@ STATICEDGE STATSTG stdafx STDAPI +stdc stdcpplatest STDMETHODCALLTYPE STDMETHODIMP @@ -1470,8 +1600,10 @@ STGC STGM STGMEDIUM sticpl +STICKYKEYS stl storelogo +stprintf streamjsonrpc STRINGIZE stringtable @@ -1480,12 +1612,14 @@ Strm strret strsafe strutil +stscanf sttngs Stubless STYLECHANGED STYLECHANGING subkeys sublang +SUBMODULEUPDATE subquery Superbar sut @@ -1516,6 +1650,7 @@ SYSKEYUP SYSLIB SYSMENU SYSTEMAPPS +SYSTEMMODAL SYSTEMTIME tailwindcss tapp @@ -1530,9 +1665,18 @@ targetver taskkill taskschd TCHAR +TCIF +TCITEM +TCN Tcollab tcs +tcscat +tcschr +tcscmp tcscpy +tcsdup +tcslen +tcsrchr TCustom tdbuild TDefault @@ -1543,6 +1687,7 @@ testprocess TEXCOORD TEXTEXTRACTOR TEXTINCLUDE +tfopen tgz themeresources THH @@ -1556,6 +1701,7 @@ timedate timediff timeunion timeutil +TITLEBARINFO Titlecase tkcontrols tkconverters @@ -1576,6 +1722,7 @@ touchpad TRACEHANDLE tracelogging tracerpt +trackbar trafficmanager traies transicc @@ -1586,6 +1733,7 @@ trx tsa Tsd TServer +tstoi TStr tweakme TWF @@ -1594,8 +1742,10 @@ TYPEKEYBOARD TYPEMOUSE TYPESHORTCUT UAC +UACUI UAL uap +UBR UCallback udit uefi @@ -1609,6 +1759,7 @@ ums uncompilable UNCPRIORITY UNDNAME +unhiding UNICODETEXT uninstantiated uniquifier @@ -1622,9 +1773,13 @@ unregistering unremapped unvirtualized unwide +unzoom UOffset UOI Updatelayout +UPDATENOW +UPDATEREGISTRY +updown UPGRADINGPRODUCTCODE Uptool urld @@ -1639,7 +1794,7 @@ USRDLL UType uuidv uwp -Uxtheme +uxtheme vabdq validmodulename valuegenerator @@ -1650,6 +1805,7 @@ vcgtq VCINSTALLDIR Vcpkg VCRT +VCENTER vcruntime vcvars VDesktop @@ -1660,6 +1816,7 @@ VERBW VERIFYCONTEXT verrsrc VERSIONINFO +VERTRES VERTSIZE VFT vget @@ -1669,6 +1826,7 @@ VIDCAP VIDEOINFOHEADER viewmodel vih +VIRTKEY VIRTUALDESK VISEGRADRELAY visiblecolorformats @@ -1695,6 +1853,7 @@ vsonline vstemplate vstest VSTHRD +vstprintf VSTT vswhere Vtbl @@ -1711,6 +1870,7 @@ wcsicmp wcsncpy wcsnicmp WDA +wdm wdp wdupenv webbrowsers @@ -1731,6 +1891,7 @@ windef windir WINDOWCREATED WINDOWEDGE +WINDOWINFO WINDOWNAME WINDOWPLACEMENT WINDOWPOSCHANGED @@ -1847,4 +2008,7 @@ ZEROINIT zonable zoneset Zoneszonabletester +Zoomin +zoomit +ZOOMITX zzz diff --git a/.github/actions/spell-check/patterns.txt b/.github/actions/spell-check/patterns.txt index 12c1ef6b08..f8c9761933 100644 --- a/.github/actions/spell-check/patterns.txt +++ b/.github/actions/spell-check/patterns.txt @@ -231,3 +231,7 @@ _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING # ignore long runs of a single character: \b([A-Za-z])\g{-1}{3,}\b + +# ZoomIt menu items with accelerator keys +E&xit +St&yle diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json index 76b55d0597..13181ebfd1 100644 --- a/.pipelines/ESRPSigning_core.json +++ b/.pipelines/ESRPSigning_core.json @@ -211,6 +211,10 @@ "PowerToys.ShortcutGuide.exe", "PowerToys.ShortcutGuideModuleInterface.dll", + "PowerToys.ZoomIt.exe", + "PowerToys.ZoomItModuleInterface.dll", + "PowerToys.ZoomItSettingsInterop.dll", + "WinUI3Apps\\PowerToys.Settings.dll", "WinUI3Apps\\PowerToys.Settings.exe" ], diff --git a/COMMUNITY.md b/COMMUNITY.md index 17b722facb..8b3d7035da 100644 --- a/COMMUNITY.md +++ b/COMMUNITY.md @@ -130,6 +130,8 @@ Find My Mouse is based on Raymond Chen's SuperSonar. Crop And Lock is based on the original work of Robert Mikhayelyan, with Program Manager support from [@kevinguo305](https://github.com/kevinguo305) - Kevin Guo. +ZoomIt's Video Recording Session code is based on Robert Mikhayelyan's https://github.com/robmikh/capturevideosample code. + ### Microsoft InVEST team This amazing team helped PowerToys develop PowerToys Run and Keyboard manager as well as update our Settings to v2. @alekhyareddy28, @arjunbalgovind, @jyuwono @laviusmotileng-ms, @ryanbodrug-microsoft, @saahmedm, @somil55, @traies, @udit3333 @@ -169,6 +171,14 @@ Other contributors: * Paul Schmitt - WWL * And many other Users! +## ZoomIt original contributors + +ZoomIt source code was originally implemented by [Sysinternals](https://sysinternals.com): + +- [@markrussinovich](https://github.com/markrussinovich) - Mark Russinovich +- [@foxmsft](https://github.com/foxmsft) - Alex Mihaiuc +- [@johnstep](https://github.com/johnstep) - John Stephens + ## PowerToys core team - [@crutkas](https://github.com/crutkas/) - Clint Rutkas - Lead diff --git a/DATA_AND_PRIVACY.md b/DATA_AND_PRIVACY.md index a8714fa903..92711f00dd 100644 --- a/DATA_AND_PRIVACY.md +++ b/DATA_AND_PRIVACY.md @@ -977,6 +977,50 @@ _If you want to find diagnostic data events in the source code, these two links +### ZoomIt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Event NameDescription
Microsoft.PowerToys.ZoomIt_EnableZoomItTriggered when ZoomIt is enabled/disabled.
Microsoft.PowerToys.ZoomIt_StartedTriggered when the ZoomIt process starts.
Microsoft.PowerToys.ZoomIt_ActivateBreakTriggered when the Break mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateDrawTriggered when the Draw mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateZoomTriggered when the Zoom mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateLiveZoomTriggered when the Live Zoom mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateDemoTypeTriggered when the DemoType mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateRecordTriggered when the Record mode is entered.
Microsoft.PowerToys.ZoomIt_ActivateSnipTriggered when the Snip mode is entered.
+ + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp new file mode 100644 index 0000000000..3a197714b7 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.cpp @@ -0,0 +1,274 @@ +#include "pch.h" +#include "ZoomItSettings.h" +#include "ZoomItSettings.g.cpp" +#include "../ZoomIt/ZoomItSettings.h" +#include +#include +#include +#pragma comment(lib, "Crypt32.lib") // For the CryptStringToBinaryW and CryptBinaryToStringW functions + +namespace winrt::PowerToys::ZoomItSettingsInterop::implementation +{ + ClassRegistry reg(_T("Software\\Sysinternals\\") APPNAME); + + const unsigned int SPECIAL_SEMANTICS_SHORTCUT = 1; + const unsigned int SPECIAL_SEMANTICS_COLOR = 2; + const unsigned int SPECIAL_SEMANTICS_LOG_FONT = 3; + + std::vector base64_decode(const std::wstring& base64_string) + { + DWORD binary_len = 0; + // Get the required buffer size for the binary data + if (!CryptStringToBinaryW(base64_string.c_str(), 0, CRYPT_STRING_BASE64, nullptr, &binary_len, nullptr, nullptr)) + { + throw std::runtime_error("Error in CryptStringToBinaryW (getting size)"); + } + + std::vector binary_data(binary_len); + + // Decode the Base64 string into binary data + if (!CryptStringToBinaryW(base64_string.c_str(), 0, CRYPT_STRING_BASE64, binary_data.data(), &binary_len, nullptr, nullptr)) + { + throw std::runtime_error("Error in CryptStringToBinaryW (decoding)"); + } + + return binary_data; + } + + std::wstring base64_encode(const unsigned char* data, size_t length) + { + DWORD base64_len = 0; + // Get the required buffer size for Base64 string + if (!CryptBinaryToStringW(data, static_cast(length), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &base64_len)) + { + throw std::runtime_error("Error in CryptBinaryToStringW (getting size)"); + } + + std::wstring base64_string(base64_len, '\0'); + + // Encode the binary data to Base64 + if (!CryptBinaryToStringW(data, static_cast(length), CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, &base64_string[0], &base64_len)) + { + throw std::runtime_error("Error in CryptBinaryToStringW (encoding)"); + } + + // Resize the wstring to remove any trailing null character. + if (!base64_string.empty() && base64_string.back() == L'\0') + { + base64_string.pop_back(); + } + + return base64_string; + } + + std::map settings_with_special_semantics = { + { L"ToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"LiveZoomToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"DrawToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"RecordToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"SnipToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"BreakTimerKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"DemoTypeToggleKey", SPECIAL_SEMANTICS_SHORTCUT }, + { L"PenColor", SPECIAL_SEMANTICS_COLOR }, + { L"BreakPenColor", SPECIAL_SEMANTICS_COLOR }, + { L"Font", SPECIAL_SEMANTICS_LOG_FONT }, + }; + + hstring ZoomItSettings::LoadSettingsJson() + { + PowerToysSettings::PowerToyValues _settings(L"ZoomIt",L"ZoomIt"); + reg.ReadRegSettings(RegSettings); + PREG_SETTING curSetting = RegSettings; + while (curSetting->ValueName) + { + switch (curSetting->Type) + { + case SETTING_TYPE_DWORD: + { + auto special_semantics = settings_with_special_semantics.find(curSetting->ValueName); + DWORD value = *static_cast(curSetting->Setting); + if (special_semantics == settings_with_special_semantics.end()) + { + _settings.add_property(curSetting->ValueName, value); + } + else + { + if (special_semantics->second == SPECIAL_SEMANTICS_SHORTCUT) + { + auto hotkey = PowerToysSettings::HotkeyObject::from_settings( + value & (HOTKEYF_EXT << 8), //WIN + value & (HOTKEYF_CONTROL << 8), + value & (HOTKEYF_ALT << 8), + value & (HOTKEYF_SHIFT << 8), + value & 0xFF); + _settings.add_property(curSetting->ValueName, hotkey.get_json()); + } + else if (special_semantics->second == SPECIAL_SEMANTICS_COLOR) + { + // PowerToys settings likes colors as #FFFFFF strings. + hstring s = winrt::to_hstring(std::format("#{:02x}{:02x}{:02x}", value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF)); + _settings.add_property(curSetting->ValueName, s); + } + } + break; + } + case SETTING_TYPE_BOOLEAN: + _settings.add_property(curSetting->ValueName, *static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_DOUBLE: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_STRING: + _settings.add_property(curSetting->ValueName, static_cast(curSetting->Setting)); + break; + case SETTING_TYPE_DWORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_BINARY: + auto special_semantics = settings_with_special_semantics.find(curSetting->ValueName); + if (special_semantics != settings_with_special_semantics.end() && special_semantics->second == SPECIAL_SEMANTICS_LOG_FONT) + { + // This is the font setting. It's a special case where the default value needs to be calculated if it's still 0. + if (g_LogFont.lfFaceName[0] == L'\0') + { + GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof g_LogFont, &g_LogFont); + g_LogFont.lfWeight = FW_NORMAL; + auto hDc = CreateCompatibleDC(NULL); + g_LogFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72); + DeleteDC(hDc); + } + } + + // Base64 encoding is likely the best way to serialize a byte array into JSON. + auto encodedFont = base64_encode(static_cast(curSetting->Setting), curSetting->Size); + _settings.add_property(curSetting->ValueName, encodedFont); + break; + } + curSetting++; + } + + return _settings.get_raw_json().Stringify(); + } + + void ZoomItSettings::SaveSettingsJson(hstring json) + { + reg.ReadRegSettings(RegSettings); + + // Parse the input JSON string. + PowerToysSettings::PowerToyValues valuesFromSettings = + PowerToysSettings::PowerToyValues::from_json_string(json, L"ZoomIt"); + + PREG_SETTING curSetting = RegSettings; + while (curSetting->ValueName) + { + switch (curSetting->Type) + { + case SETTING_TYPE_DWORD: + { + auto special_semantics = settings_with_special_semantics.find(curSetting->ValueName); + if (special_semantics == settings_with_special_semantics.end()) + { + auto possibleValue = valuesFromSettings.get_uint_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + *static_cast(curSetting->Setting) = possibleValue.value(); + } + } + else + { + if (special_semantics->second == SPECIAL_SEMANTICS_SHORTCUT) + { + auto possibleValue = valuesFromSettings.get_json(curSetting->ValueName); + if (possibleValue.has_value()) + { + auto hotkey = PowerToysSettings::HotkeyObject::from_json(possibleValue.value()); + unsigned int value = 0; + value |= hotkey.get_code(); + if (hotkey.ctrl_pressed()) + { + value |= (HOTKEYF_CONTROL << 8); + } + if (hotkey.alt_pressed()) + { + value |= (HOTKEYF_ALT << 8); + } + if (hotkey.shift_pressed()) + { + value |= (HOTKEYF_SHIFT << 8); + } + if (hotkey.win_pressed()) + { + value |= (HOTKEYF_EXT << 8); + } + *static_cast(curSetting->Setting) = value; + } + } + else if (special_semantics->second == SPECIAL_SEMANTICS_COLOR) + { + auto possibleValue = valuesFromSettings.get_string_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + uint8_t r, g, b; + if (checkValidRGB(possibleValue.value(), &r, &g, &b)) + { + *static_cast(curSetting->Setting) = RGB(r, g, b); + } + + } + } + } + break; + } + case SETTING_TYPE_BOOLEAN: + { + auto possibleValue = valuesFromSettings.get_bool_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + *static_cast(curSetting->Setting) = static_cast(possibleValue.value()); + } + break; + } + case SETTING_TYPE_DOUBLE: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_STRING: + { + auto possibleValue = valuesFromSettings.get_string_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + const TCHAR* value = possibleValue.value().c_str(); + _tcscpy_s(static_cast(curSetting->Setting), curSetting->Size / sizeof(TCHAR), value); + } + break; + } + case SETTING_TYPE_DWORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_WORD_ARRAY: + assert(false); // ZoomIt doesn't use this type of setting. + break; + case SETTING_TYPE_BINARY: + auto possibleValue = valuesFromSettings.get_string_value(curSetting->ValueName); + if (possibleValue.has_value()) + { + // Base64 encoding is likely the best way to serialize a byte array into JSON. + auto decodedValue = base64_decode(possibleValue.value()); + assert(curSetting->Size == decodedValue.size()); // Should right now only be used for LOGFONT, so let's hard check it to avoid any insecure overflows. + memcpy(static_cast(curSetting->Setting), decodedValue.data(), decodedValue.size()); + } + break; + } + curSetting++; + } + reg.WriteRegSettings(RegSettings); + } +} diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.h b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.h new file mode 100644 index 0000000000..9ea60451c0 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.h @@ -0,0 +1,20 @@ +#pragma once + +#include "ZoomItSettings.g.h" + +namespace winrt::PowerToys::ZoomItSettingsInterop::implementation +{ + struct ZoomItSettings : ZoomItSettingsT + { + ZoomItSettings() = default; + static hstring LoadSettingsJson(); + static void SaveSettingsJson(hstring json); + }; +} + +namespace winrt::PowerToys::ZoomItSettingsInterop::factory_implementation +{ + struct ZoomItSettings : ZoomItSettingsT + { + }; +} diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.idl b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.idl new file mode 100644 index 0000000000..bd4d1915db --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettings.idl @@ -0,0 +1,10 @@ +namespace PowerToys +{ + namespace ZoomItSettingsInterop + { + [default_interface] static runtimeclass ZoomItSettings { + static String LoadSettingsJson(); + static void SaveSettingsJson(String json); + } + } +} diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.def b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.def new file mode 100644 index 0000000000..24e7c1235c --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.rc b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.rc new file mode 100644 index 0000000000..5fa3c8b90d --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.rc @@ -0,0 +1,40 @@ +#include +#include "resource.h" +#include "../../../common/version/version.h" + +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +1 VERSIONINFO +FILEVERSION FILE_VERSION +PRODUCTVERSION PRODUCT_VERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG +FILEFLAGS VS_FF_DEBUG +#else +FILEFLAGS 0x0L +#endif +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset + BEGIN + VALUE "CompanyName", COMPANY_NAME + VALUE "FileDescription", FILE_DESCRIPTION + VALUE "FileVersion", FILE_VERSION_STRING + VALUE "InternalName", INTERNAL_NAME + VALUE "LegalCopyright", COPYRIGHT_NOTE + VALUE "OriginalFilename", ORIGINAL_FILENAME + VALUE "ProductName", PRODUCT_NAME + VALUE "ProductVersion", PRODUCT_VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset + END +END diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj new file mode 100644 index 0000000000..21998a40da --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj @@ -0,0 +1,132 @@ + + + + + true + true + true + true + {ca7d8106-30B9-4aec-9d05-b69b31b8c461} + ZoomItSettingsInterop + PowerToys.ZoomItSettingsInterop + en-US + 14.0 + false + false + Windows Store + 10.0 + + + + DynamicLibrary + v143 + Unicode + false + + + true + true + + + false + true + false + + + + + + + + + + + + + + + PowerToys.ZoomItSettingsInterop + ..\..\..\..\$(Platform)\$(Configuration)\ + + + + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + _WINRT_DLL;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions) + ../../..;%(AdditionalIncludeDirectories) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + false + ZoomItSettingsInterop.def + Shell32.lib;gdi32.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + ZoomItSettings.idl + + + + + + Create + + + ZoomItSettings.idl + + + + + + + + + + + + + + + + {d9b8fc84-322a-4f9f-bbb9-20915c47ddfd} + + + {6955446d-23f7-4023-9bb3-8657f904af99} + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj.filters b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj.filters new file mode 100644 index 0000000000..056f948c95 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/ZoomItSettingsInterop.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {de682ddf-17ab-471d-9761-82b42e6baa70} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {c02d42a3-682e-499a-8b28-638a0802d43f} + + + + + + + + + + + + + + + + + + + + + + + Resources + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/packages.config b/src/modules/ZoomIt/ZoomItSettingsInterop/packages.config new file mode 100644 index 0000000000..ff4b059648 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/pch.cpp b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.cpp new file mode 100644 index 0000000000..bcb5590be1 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/pch.h b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.h new file mode 100644 index 0000000000..ea0275969f --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/pch.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include +#include +#include + +#define GDIPVER 0x0110 +#include +// DirectX +#include +#include +#include + +// Must come before C++/WinRT +#include + +#include + +#include +#include diff --git a/src/modules/ZoomIt/ZoomItSettingsInterop/resource.h b/src/modules/ZoomIt/ZoomItSettingsInterop/resource.h new file mode 100644 index 0000000000..73711ef9a9 --- /dev/null +++ b/src/modules/ZoomIt/ZoomItSettingsInterop/resource.h @@ -0,0 +1,13 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ZoomItSettingsInterop.rc + +////////////////////////////// +// Non-localizable + +#define FILE_DESCRIPTION "PowerToys ZoomItSettingsInterop" +#define INTERNAL_NAME "PowerToys.ZoomItSettingsInterop" +#define ORIGINAL_FILENAME "PowerToys.ZoomItSettingsInterop.dll" + +// Non-localizable +////////////////////////////// diff --git a/src/runner/main.cpp b/src/runner/main.cpp index 81a94c5e6c..76a6f68d5c 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -173,6 +173,7 @@ int runner(bool isProcessElevated, bool openSettings, std::string settingsWindow L"PowerToys.CropAndLockModuleInterface.dll", L"PowerToys.CmdNotFoundModuleInterface.dll", L"PowerToys.WorkspacesModuleInterface.dll", + L"PowerToys.ZoomItModuleInterface.dll", }; for (auto moduleSubdir : knownModules) diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index 8a5c2fcf40..671fec0018 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -694,6 +694,8 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value) return "AdvancedPaste"; case ESettingsWindowNames::NewPlus: return "NewPlus"; + case ESettingsWindowNames::ZoomIt: + return "ZoomIt"; default: { Logger::error(L"Can't convert ESettingsWindowNames value={} to string", static_cast(value)); @@ -789,6 +791,10 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value) { return ESettingsWindowNames::NewPlus; } + else if (value == "ZoomIt") + { + return ESettingsWindowNames::ZoomIt; + } else { Logger::error(L"Can't convert string value={} to ESettingsWindowNames", winrt::to_hstring(value)); diff --git a/src/runner/settings_window.h b/src/runner/settings_window.h index 4d2a4595ae..251fff28c7 100644 --- a/src/runner/settings_window.h +++ b/src/runner/settings_window.h @@ -25,6 +25,7 @@ enum class ESettingsWindowNames EnvironmentVariables, AdvancedPaste, NewPlus, + ZoomIt, }; std::string ESettingsWindowNames_to_string(ESettingsWindowNames value); diff --git a/src/settings-ui/Settings.UI.Library/EnabledModules.cs b/src/settings-ui/Settings.UI.Library/EnabledModules.cs index e38db5eeb4..2b582f396a 100644 --- a/src/settings-ui/Settings.UI.Library/EnabledModules.cs +++ b/src/settings-ui/Settings.UI.Library/EnabledModules.cs @@ -480,6 +480,23 @@ namespace Microsoft.PowerToys.Settings.UI.Library } } + private bool zoomIt; + + [JsonPropertyName("ZoomIt")] + public bool ZoomIt + { + get => zoomIt; + set + { + if (zoomIt != value) + { + LogTelemetryEvent(value); + zoomIt = value; + NotifyChange(); + } + } + } + private void NotifyChange() { notifyEnabledChangedAction?.Invoke(); diff --git a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj index a967dd28a7..c3832b11c5 100644 --- a/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj +++ b/src/settings-ui/Settings.UI.Library/Settings.UI.Library.csproj @@ -19,6 +19,7 @@ + diff --git a/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs b/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs new file mode 100644 index 0000000000..3cd7562673 --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/ZoomItProperties.cs @@ -0,0 +1,107 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization; +using Settings.UI.Library.Attributes; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class ZoomItProperties + { + public ZoomItProperties() + { + } + + [CmdConfigureIgnore] + public static HotkeySettings DefaultToggleKey => new HotkeySettings(false, true, false, false, '1'); // Ctrl+1 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultLiveZoomToggleKey => new HotkeySettings(false, true, false, false, '4'); // Ctrl+4 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultDrawToggleKey => new HotkeySettings(false, true, false, false, '2'); // Ctrl+2 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultRecordToggleKey => new HotkeySettings(false, true, false, false, '5'); // Ctrl+5 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultSnipToggleKey => new HotkeySettings(false, true, false, false, '6'); // Ctrl+6 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultBreakTimerKey => new HotkeySettings(false, true, false, false, '3'); // Ctrl+3 + + [CmdConfigureIgnore] + public static HotkeySettings DefaultDemoTypeToggleKey => new HotkeySettings(false, true, false, false, '7'); // Ctrl+7 + + public KeyboardKeysProperty ToggleKey { get; set; } + + public KeyboardKeysProperty LiveZoomToggleKey { get; set; } + + public KeyboardKeysProperty DrawToggleKey { get; set; } + + public KeyboardKeysProperty RecordToggleKey { get; set; } + + public KeyboardKeysProperty SnipToggleKey { get; set; } + + public StringProperty PenColor { get; set; } + + public IntProperty PenWidth { get; set; } + + public StringProperty BreakPenColor { get; set; } + + public KeyboardKeysProperty BreakTimerKey { get; set; } + + public StringProperty Font { get; set; } + + public KeyboardKeysProperty DemoTypeToggleKey { get; set; } + + public StringProperty DemoTypeFile { get; set; } + + public IntProperty DemoTypeSpeedSlider { get; set; } + + public BoolProperty DemoTypeUserDrivenMode { get; set; } + + public IntProperty BreakTimeout { get; set; } + + public IntProperty BreakOpacity { get; set; } + + public BoolProperty BreakPlaySoundFile { get; set; } + + public StringProperty BreakSoundFile { get; set; } + + public BoolProperty BreakShowBackgroundFile { get; set; } + + public BoolProperty BreakBackgroundStretch { get; set; } + + public StringProperty BreakBackgroundFile { get; set; } + + public IntProperty BreakTimerPosition { get; set; } + + public BoolProperty BreakShowDesktop { get; set; } + + public BoolProperty BreakOnSecondary { get; set; } + + public IntProperty FontScale { get; set; } + + public BoolProperty ShowExpiredTime { get; set; } + + public BoolProperty ShowTrayIcon { get; set; } + + public BoolProperty AnimnateZoom { get; set; } + + public BoolProperty TelescopeZoomOut { get; set; } + + public BoolProperty SnapToGrid { get; set; } + + public IntProperty ZoominSliderLevel { get; set; } + + public IntProperty RecordFrameRate { get; set; } + + public IntProperty RecordScaling { get; set; } + + public BoolProperty CaptureAudio { get; set; } + + public StringProperty MicrophoneDeviceId { get; set; } + } +} diff --git a/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs b/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs new file mode 100644 index 0000000000..db3b07f363 --- /dev/null +++ b/src/settings-ui/Settings.UI.Library/ZoomItSettings.cs @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json.Serialization; +using Microsoft.PowerToys.Settings.UI.Library.Interfaces; + +namespace Microsoft.PowerToys.Settings.UI.Library +{ + public class ZoomItSettings : BasePTModuleSettings, ISettingsConfig + { + public const string ModuleName = "ZoomIt"; + + [JsonPropertyName("properties")] + public ZoomItProperties Properties { get; set; } + + public ZoomItSettings() + { + Name = ModuleName; + Properties = new ZoomItProperties(); + Version = "1.0"; + } + + public string GetModuleName() + { + return Name; + } + + // This can be utilized in the future if the settings.json file is to be modified/deleted. + public bool UpgradeSettingsConfiguration() + { + return false; + } + } +} diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Icons/ZoomIt.png b/src/settings-ui/Settings.UI/Assets/Settings/Icons/ZoomIt.png new file mode 100644 index 0000000000..f3c8aff3de Binary files /dev/null and b/src/settings-ui/Settings.UI/Assets/Settings/Icons/ZoomIt.png differ diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/ZoomIt.gif b/src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/ZoomIt.gif new file mode 100644 index 0000000000..74c024ae81 Binary files /dev/null and b/src/settings-ui/Settings.UI/Assets/Settings/Modules/OOBE/ZoomIt.gif differ diff --git a/src/settings-ui/Settings.UI/Assets/Settings/Modules/ZoomIt.png b/src/settings-ui/Settings.UI/Assets/Settings/Modules/ZoomIt.png new file mode 100644 index 0000000000..c4fb8b00f6 Binary files /dev/null and b/src/settings-ui/Settings.UI/Assets/Settings/Modules/ZoomIt.png differ diff --git a/src/settings-ui/Settings.UI/Converters/ZoomItInitialZoomConverter.cs b/src/settings-ui/Settings.UI/Converters/ZoomItInitialZoomConverter.cs new file mode 100644 index 0000000000..2107caa391 --- /dev/null +++ b/src/settings-ui/Settings.UI/Converters/ZoomItInitialZoomConverter.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.UI.Xaml.Data; + +namespace Microsoft.PowerToys.Settings.UI.Converters +{ + public sealed partial class ZoomItInitialZoomConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + string targetValue = string.Empty; + int zoomLevel = System.Convert.ToInt32((double)value); + + // Should match the zoom values expected by ZoomIt internal logic. + switch (zoomLevel) + { + case 0: targetValue = "1.25"; break; + case 1: targetValue = "1.5"; break; + case 2: targetValue = "1.75"; break; + case 3: targetValue = "2.0"; break; + case 4: targetValue = "3.0"; break; + case 5: targetValue = "4.0"; break; + } + + return targetValue; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException(); + } +} diff --git a/src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs b/src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs new file mode 100644 index 0000000000..61208b00b3 --- /dev/null +++ b/src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.PowerToys.Settings.UI.Helpers; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.UI.Xaml.Data; + +namespace Microsoft.PowerToys.Settings.UI.Converters +{ + public sealed partial class ZoomItTypeSpeedSliderConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, string language) + { + string targetValue = string.Empty; + int zoomLevel = System.Convert.ToInt32((double)value); + string explanation = ResourceLoaderInstance.ResourceLoader.GetString("ZoomIt_DemoType_SpeedSlider_Thumbnail_Explanation"); + + targetValue = $"{zoomLevel} ({explanation})"; + + return targetValue; + } + + public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException(); + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/CHOOSEFONT.cs b/src/settings-ui/Settings.UI/Helpers/CHOOSEFONT.cs new file mode 100644 index 0000000000..026a9f01a1 --- /dev/null +++ b/src/settings-ui/Settings.UI/Helpers/CHOOSEFONT.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.PowerToys.Settings.UI.Helpers +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Keep original names from original structure")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:Field names should begin with lower-case letter", Justification = "Keep original names from original structure")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Structure used for win32 interop. We need to access the fields")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1805:Do not initialize unnecessarily", Justification = "Let's have initializations be explicit for these win32 interop types")] + + // Class to select the Dialog options to call ChooseFont. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class CHOOSEFONT + { + public int lStructSize = Marshal.SizeOf(typeof(CHOOSEFONT)); + public IntPtr hwndOwner = IntPtr.Zero; + public IntPtr hDC = IntPtr.Zero; + public IntPtr lpLogFont = IntPtr.Zero; + public int iPointSize = 0; + public int Flags = 0; + public int rgbColors = 0; + public IntPtr lCustData = IntPtr.Zero; + public IntPtr lpfnHook = IntPtr.Zero; + public string lpTemplateName = null; + public IntPtr hInstance = IntPtr.Zero; + public string lpszStyle = null; + public short nFontType; + private short __MISSING_ALIGNMENT__; + public int nSizeMin; + public int nSizeMax; + } + + [Flags] + public enum CHOOSE_FONT_FLAGS + { + CF_SCREENFONTS = 0x00000001, + CF_PRINTER_FONTS = 0x00000002, + CF_BOTH = CF_SCREENFONTS | CF_PRINTER_FONTS, + CF_SHOW_HELP = 0x00000004, + CF_ENABLE_HOOK = 0x00000008, + CF_ENABLETEMPLATE = 0x00000010, + CF_ENABLETEMPLATE_HANDLE = 0x00000020, + CF_INITTOLOGFONTSTRUCT = 0x00000040, + CF_USE_STYLE = 0x00000080, + CF_EFFECTS = 0x00000100, + CF_APPLY = 0x00000200, + CF_ANSI_ONLY = 0x00000400, + CF_SCRIPTS_ONLY = CF_ANSI_ONLY, + CF_NO_VECTOR_FONTS = 0x00000800, + CF_NO_OEM_FONTS = CF_NO_VECTOR_FONTS, + CF_NO_SIMULATIONS = 0x00001000, + CF_LIMITSIZE = 0x00002000, + CF_FIXED_PITCH_ONLY = 0x00004000, + CF_WYSIWYG = 0x00008000, + CF_FORCE_FONT_EXIST = 0x00010000, + CF_SCALABLE_ONLY = 0x00020000, + CF_TT_ONLY = 0x00040000, + CF_NO_FACE_SEL = 0x00080000, + CF_NO_STYLE_SEL = 0x00100000, + CF_NO_SIZE_SEL = 0x00200000, + CF_SELECT_SCRIPT = 0x00400000, + CF_NO_SCRIPT_SEL = 0x00800000, + CF_NO_VERT_FONTS = 0x01000000, + CF_INACTIVE_FONTS = 0x02000000, + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/LOGFONT.cs b/src/settings-ui/Settings.UI/Helpers/LOGFONT.cs new file mode 100644 index 0000000000..575f91d117 --- /dev/null +++ b/src/settings-ui/Settings.UI/Helpers/LOGFONT.cs @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.PowerToys.Settings.UI.Helpers +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "Keep original names from original structure")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Structure used for win32 interop. We need to access the fields")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1805:Do not initialize unnecessarily", Justification = "Let's have initializations be explicit for these win32 interop types")] + + // Result from calling ChooseFont. + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class LOGFONT + { + public int lfHeight = 0; + public int lfWidth = 0; + public int lfEscapement = 0; + public int lfOrientation = 0; + public int lfWeight = 0; + public byte lfItalic = 0; + public byte lfUnderline = 0; + public byte lfStrikeOut = 0; + public byte lfCharSet = 0; + public byte lfOutPrecision = 0; + public byte lfClipPrecision = 0; + public byte lfQuality = 0; + public byte lfPitchAndFamily = 0; + + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string lfFaceName = string.Empty; + } + + public enum FontWeight : int + { + FW_DONT_CARE = 0, + FW_THIN = 100, + FW_EXTRALIGHT = 200, + FW_LIGHT = 300, + FW_NORMAL = 400, + FW_MEDIUM = 500, + FW_SEMIBOLD = 600, + FW_BOLD = 700, + FW_EXTRABOLD = 800, + FW_HEAVY = 900, + } + + public enum FontCharSet : byte + { + ANSI_CHARSET = 0, + DEFAULT_CHARSET = 1, + SYMBOL_CHARSET = 2, + SHIFT_JIS_CHARSET = 128, + HANGEUL_CHARSET = 129, + HANGUL_CHARSET = HANGEUL_CHARSET, + GB2312_CHARSET = 134, + CHINESE_BIG5_CHARSET = 136, + OEM_CHARSET = 255, + JOHAB_CHARSET = 130, + HEBREW_CHARSET = 177, + ARABIC_CHARSET = 178, + GREEK_CHARSET = 161, + TURKISH_CHARSET = 162, + VIETNAMESE_CHARSET = 163, + THAI_CHARSET = 222, + EAST_EUROPE_CHARSET = 238, + RUSSIAN_CHARSET = 204, + MAC_CHARSET = 77, + BALTIC_CHARSET = 186, + } + + public enum FontPrecision : byte + { + OUT_DEFAULT_PRECIS = 0, + OUT_STRING_PRECIS = 1, + OUT_CHARACTER_PRECIS = 2, + OUT_STROKE_PRECIS = 3, + OUT_TT_PRECIS = 4, + OUT_DEVICE_PRECIS = 5, + OUT_RASTER_PRECIS = 6, + OUT_TT_ONLY_PRECIS = 7, + OUT_OUTLINE_PRECIS = 8, + OUT_SCREEN_OUTLINE_PRECIS = 9, + OUT_PS_ONLY_PRECIS = 10, + } + + public enum FontClipPrecision : byte + { + CLIP_DEFAULT_PRECIS = 0, + CLIP_CHARACTER_PRECIS = 1, + CLIP_STROKE_PRECIS = 2, + CLIP_MASK = 0xf, + CLIP_LH_ANGLES = 1 << 4, + CLIP_TT_ALWAYS = 2 << 4, + CLIP_DFA_DISABLE = 4 << 4, + CLIP_EMBEDDED = 8 << 4, + } + + public enum FontQuality : byte + { + DEFAULT_QUALITY = 0, + DRAFT_QUALITY = 1, + PROOF_QUALITY = 2, + NONANTIALIASED_QUALITY = 3, + ANTIALIASED_QUALITY = 4, + CLEAR_TYPE_QUALITY = 5, + CLEAR_TYPE_NATURAL_QUALITY = 6, + } + + [Flags] + public enum FontPitchAndFamily : byte + { + DEFAULT_PITCH = 0, + FIXED_PITCH = 1, + VARIABLE_PITCH = 2, + FF_DONT_CARE = DEFAULT_PITCH, + FF_ROMAN = 1 << 4, + FF_SWISS = 2 << 4, + FF_MODERN = 3 << 4, + FF_SCRIPT = 4 << 4, + FF_DECORATIVE = 5 << 4, + } +} diff --git a/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs b/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs index c3eef509c0..60de12a4c9 100644 --- a/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs +++ b/src/settings-ui/Settings.UI/Helpers/ModuleHelper.cs @@ -72,6 +72,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers case ModuleType.MeasureTool: return generalSettingsConfig.Enabled.MeasureTool; case ModuleType.ShortcutGuide: return generalSettingsConfig.Enabled.ShortcutGuide; case ModuleType.PowerOCR: return generalSettingsConfig.Enabled.PowerOcr; + case ModuleType.ZoomIt: return generalSettingsConfig.Enabled.ZoomIt; default: return false; } } @@ -106,6 +107,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers case ModuleType.MeasureTool: generalSettingsConfig.Enabled.MeasureTool = isEnabled; break; case ModuleType.ShortcutGuide: generalSettingsConfig.Enabled.ShortcutGuide = isEnabled; break; case ModuleType.PowerOCR: generalSettingsConfig.Enabled.PowerOcr = isEnabled; break; + case ModuleType.ZoomIt: generalSettingsConfig.Enabled.ZoomIt = isEnabled; break; } } @@ -139,6 +141,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers case ModuleType.MeasureTool: return GPOWrapper.GetConfiguredScreenRulerEnabledValue(); case ModuleType.ShortcutGuide: return GPOWrapper.GetConfiguredShortcutGuideEnabledValue(); case ModuleType.PowerOCR: return GPOWrapper.GetConfiguredTextExtractorEnabledValue(); + case ModuleType.ZoomIt: return GPOWrapper.GetConfiguredZoomItEnabledValue(); default: return GpoRuleConfigured.Unavailable; } } @@ -173,6 +176,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers ModuleType.MeasureTool => typeof(MeasureToolPage), ModuleType.ShortcutGuide => typeof(ShortcutGuidePage), ModuleType.PowerOCR => typeof(PowerOcrPage), + ModuleType.ZoomIt => typeof(ZoomItPage), _ => typeof(DashboardPage), // never called, all values listed above }; } diff --git a/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs b/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs index c895866c1e..072f12b00c 100644 --- a/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs +++ b/src/settings-ui/Settings.UI/Helpers/NativeMethods.cs @@ -48,6 +48,12 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers [DllImport("Comdlg32.dll", CharSet = CharSet.Unicode)] internal static extern bool GetOpenFileName([In, Out] OpenFileName openFileName); + [DllImport("comdlg32.dll", CharSet = CharSet.Auto, EntryPoint = "ChooseFont", SetLastError = true)] + internal static extern bool ChooseFont(IntPtr lpChooseFont); + + [DllImport("comdlg32.dll", SetLastError = true)] + internal static extern int CommDlgExtendedError(); + #pragma warning disable CA1401 // P/Invokes should not be visible [DllImport("user32.dll")] public static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow); diff --git a/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs b/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs index 98e5beb107..f6e0f7c861 100644 --- a/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs +++ b/src/settings-ui/Settings.UI/OOBE/Enums/PowerToysModules.cs @@ -33,5 +33,6 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Enums WhatsNew, RegistryPreview, NewPlus, + ZoomIt, } } diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index 7a465fbd01..1e460af13d 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -33,7 +33,7 @@ - PowerToys.GPOWrapper + PowerToys.GPOWrapper;PowerToys.ZoomItSettingsInterop $(OutDir) false @@ -87,6 +87,7 @@ + diff --git a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs index 24910afc6c..1fb40ce907 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs @@ -448,6 +448,7 @@ namespace Microsoft.PowerToys.Settings.UI case "EnvironmentVariables": return typeof(EnvironmentVariablesPage); case "NewPlus": return typeof(NewPlusPage); case "Workspaces": return typeof(WorkspacesPage); + case "ZoomIt": return typeof(ZoomItPage); default: // Fallback to Dashboard Debug.Assert(false, "Unexpected SettingsWindow argument value"); diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml index 6c37ec15ea..d419daf1ab 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml @@ -161,6 +161,10 @@ x:Uid="Shell_Workspaces" Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/Workspaces.png}" Tag="Workspaces" /> + + + + + + + + + + +