mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
* ZoomIt initial code dump * Change vcxproj to normalize dependency versions * Fix code quality to build * Add to PowerToys solution * Clean out C-style casts * Fix some more analyzer errors * Constexpr a function * Disable some warnings locally that it seemed better not to touch * Add ZoomIt module interface * Add GPO * Add Settings page with Enable button * Output as PowerToys.ZoomIt.exe * Extract ZoomIt Settings definition to its own header * Make ZoomItModuleInterface build with ZoomItSettings too * WinRT C++ interop for ZoomItSettings * From Registry To PowerToys Json * Properly fix const_cast analyzer error * Initial Settings page loading from registry * Zoom mode settings * Save settings * Add file picker and DemoType file support * Remaining DemoType settings * Have ZoomIt properly reloading Settings and exiting * Remove context menu entries for Options and Exit * ZoomIt simple Break Options * Break advanced options * Simple Record settings * Record Microphone setting * Fix break background file picker title * Font setting * Fix build issues after merge * Add ZoomIt conflict warning to Settings * Exclude Eula from spell checking * Fix spellcheck errors * Fix spell check for accelerated menu items * Remove cursor files from spellcheck. They're binary * Fix forbidden patterns * Fix XAML style * Fix C# analyzers * Fix signing * Also sign module interface dll * Use actual ZoomIt icon * Add OOBE page for ZoomIt * ZoomIt image for Settings * Flyout and Dashboard entries * Fix type speed slider labels * Correctly load default Font * Correctly register shortcuts on ZoomIt startup first run * Fix modifier keys not changing until restart * Show MsgBox on taken shortcut * Start PowerToys Settings * Normalize ZoomIt file properties with rest of PowerToys * Add attribution * Add ZoomIt team to Community.md * More copyright adjustments * Fix spellcheck * Fix MsgBox simultaneous instance to the front * Add mention of capturevideosample code use * Add ZoomIt to process lists * Add telemetry * Add logging * React to gpo * Normalize code to space identation * Fix installer build * Localize percent setting * Fix XAML styling * Update src/settings-ui/Settings.UI/Strings/en-us/Resources.resw Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com> * Fix spellcheck * One more spellcheck fix * Integrate LiveDraw feature changes from upstream * Fix name reuse in same scope * Fix c-style casts * Also register LIVEDRAW_HOTKEY * Fix newLiveZoomToggleKey * Update LiveZoom description in Settings to take LiveDraw into account * Fix spellcheck * Fix more spellcheck * Fix Sysinternals capitalization * Fix ARM64 Debug build * Support Sysinternals build (#36873) * Remove unneeded files * Make build compatible with Sysinternals * Separate PowerToys ZoomIt product name (#36887) * Separate PowerToys ZoomIt product name To help maintain the Sysinternals branding in the standalone version. * Clarify branding-related includes * Remove ZoomIt.sln * Add foxmsft to spell-check names * Add ZoomIt to README * Add ZoomIt to GH templates * Add ZoomIt events to DATA_AND_PRIVACY.md * Remove publish_config.json * Remove publish_config.json from vcxproj too --------- Co-authored-by: Mark Russinovich <markruss@microsoft.com> Co-authored-by: Alex Mihaiuc <69110671+foxmsft@users.noreply.github.com> Co-authored-by: John Stephens <johnstep@microsoft.com> Co-authored-by: Stefan Markovic <57057282+stefansjfw@users.noreply.github.com>
256 lines
10 KiB
C++
256 lines
10 KiB
C++
#pragma once
|
|
|
|
#include "../utils/json.h"
|
|
|
|
#include <cwctype>
|
|
|
|
namespace PowerToysSettings
|
|
{
|
|
class HotkeyObject;
|
|
|
|
class Settings
|
|
{
|
|
public:
|
|
Settings(
|
|
const HINSTANCE hinstance, // Module handle of the PowerToy DLL 'IMAGE_DOS_HEADER __ImageBase'
|
|
std::wstring_view powertoy_name);
|
|
|
|
// Add additional general information to the PowerToy settings.
|
|
void set_description(UINT resource_id);
|
|
void set_description(std::wstring_view description);
|
|
|
|
void set_icon_key(std::wstring_view icon_key);
|
|
void set_overview_link(std::wstring_view overview_link);
|
|
void set_video_link(std::wstring_view video_link);
|
|
|
|
// Add properties to the PowerToy settings.
|
|
void add_bool_toggle(std::wstring_view name, UINT description_resource_id, bool value);
|
|
void add_bool_toggle(std::wstring_view name, std::wstring_view description, bool value);
|
|
|
|
void add_int_spinner(std::wstring_view name, UINT description_resource_id, int value, int min, int max, int step);
|
|
void add_int_spinner(std::wstring_view name, std::wstring_view description, int value, int min, int max, int step);
|
|
|
|
void add_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
|
|
void add_string(std::wstring_view name, std::wstring_view description, std::wstring_view value);
|
|
|
|
void add_multiline_string(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
|
|
void add_multiline_string(std::wstring_view name, std::wstring_view description, std::wstring_view value);
|
|
|
|
void add_color_picker(std::wstring_view name, UINT description_resource_id, std::wstring_view value);
|
|
void add_color_picker(std::wstring_view name, std::wstring_view description, std::wstring_view value);
|
|
|
|
void add_hotkey(std::wstring_view name, UINT description_resource_id, const HotkeyObject& hotkey);
|
|
void add_hotkey(std::wstring_view name, std::wstring_view description, const HotkeyObject& hotkey);
|
|
|
|
void add_choice_group(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
|
|
void add_choice_group(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
|
|
|
|
void add_dropdown(std::wstring_view name, UINT description_resource_id, std::wstring_view value, const std::vector<std::pair<std::wstring, UINT>>& keys_and_text_ids);
|
|
void add_dropdown(std::wstring_view name, std::wstring_view description, std::wstring_view value, const std::vector<std::pair<std::wstring, std::wstring>>& keys_and_texts);
|
|
|
|
void add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, UINT ext_description_resource_id);
|
|
void add_custom_action(std::wstring_view name, UINT description_resource_id, UINT button_text_resource_id, std::wstring_view value);
|
|
void add_custom_action(std::wstring_view name, std::wstring_view description, std::wstring_view button_text, std::wstring_view value);
|
|
|
|
void add_header_szLarge(std::wstring_view name, std::wstring_view description, std::wstring_view value);
|
|
// Serialize the internal json to a string.
|
|
std::wstring serialize();
|
|
// Serialize the internal json to the input buffer.
|
|
bool serialize_to_buffer(wchar_t* buffer, int* buffer_size);
|
|
|
|
private:
|
|
json::JsonObject m_json;
|
|
int m_curr_priority = 0; // For keeping order when adding elements.
|
|
HINSTANCE m_instance;
|
|
|
|
std::wstring get_resource(UINT resource_id);
|
|
};
|
|
|
|
class PowerToyValues
|
|
{
|
|
public:
|
|
PowerToyValues(std::wstring_view powertoy_name, std::wstring_view powertoy_key);
|
|
static PowerToyValues from_json_string(std::wstring_view json, std::wstring_view powertoy_key);
|
|
static PowerToyValues load_from_settings_file(std::wstring_view powertoy_key);
|
|
|
|
template<typename T>
|
|
inline void add_property(std::wstring_view name, T value)
|
|
{
|
|
json::JsonObject prop_value;
|
|
prop_value.SetNamedValue(L"value", json::value(value));
|
|
m_json.GetNamedObject(L"properties").SetNamedValue(name, prop_value);
|
|
}
|
|
|
|
std::optional<bool> get_bool_value(std::wstring_view property_name) const;
|
|
std::optional<int> get_int_value(std::wstring_view property_name) const;
|
|
std::optional<unsigned int> get_uint_value(std::wstring_view property_name) const;
|
|
std::optional<std::wstring> get_string_value(std::wstring_view property_name) const;
|
|
std::optional<json::JsonObject> get_json(std::wstring_view property_name) const;
|
|
json::JsonObject get_raw_json();
|
|
|
|
std::wstring serialize();
|
|
void save_to_settings_file();
|
|
|
|
private:
|
|
const std::wstring m_version = L"1.0";
|
|
void set_version();
|
|
json::JsonObject m_json;
|
|
std::wstring _key;
|
|
PowerToyValues() {}
|
|
};
|
|
|
|
class CustomActionObject
|
|
{
|
|
public:
|
|
static CustomActionObject from_json_string(std::wstring_view json)
|
|
{
|
|
return CustomActionObject(json::JsonValue::Parse(json).GetObjectW());
|
|
}
|
|
|
|
std::wstring get_name() { return m_json.GetNamedString(L"action_name").c_str(); }
|
|
std::wstring get_value() { return m_json.GetNamedString(L"value").c_str(); }
|
|
|
|
protected:
|
|
CustomActionObject(json::JsonObject action_json) :
|
|
m_json(std::move(action_json)){};
|
|
json::JsonObject m_json;
|
|
};
|
|
|
|
class HotkeyObject
|
|
{
|
|
public:
|
|
static HotkeyObject from_json(json::JsonObject json)
|
|
{
|
|
return HotkeyObject(std::move(json));
|
|
}
|
|
static HotkeyObject from_json_string(std::wstring_view json)
|
|
{
|
|
return HotkeyObject(json::JsonValue::Parse(json).GetObjectW());
|
|
}
|
|
static HotkeyObject from_settings(bool win_pressed, bool ctrl_pressed, bool alt_pressed, bool shift_pressed, UINT vk_code)
|
|
{
|
|
json::JsonObject json;
|
|
json.SetNamedValue(L"win", json::value(win_pressed));
|
|
json.SetNamedValue(L"ctrl", json::value(ctrl_pressed));
|
|
json.SetNamedValue(L"alt", json::value(alt_pressed));
|
|
json.SetNamedValue(L"shift", json::value(shift_pressed));
|
|
json.SetNamedValue(L"code", json::value(vk_code));
|
|
json.SetNamedValue(L"key", json::value(key_from_code(vk_code)));
|
|
return std::move(json);
|
|
}
|
|
const json::JsonObject& get_json() const { return m_json; }
|
|
|
|
std::wstring get_key() const { return m_json.GetNamedString(L"key").c_str(); }
|
|
UINT get_code() const { return static_cast<UINT>(m_json.GetNamedNumber(L"code")); }
|
|
bool win_pressed() const { return m_json.GetNamedBoolean(L"win"); }
|
|
bool ctrl_pressed() const { return m_json.GetNamedBoolean(L"ctrl"); }
|
|
bool alt_pressed() const { return m_json.GetNamedBoolean(L"alt"); }
|
|
bool shift_pressed() const { return m_json.GetNamedBoolean(L"shift"); }
|
|
UINT get_modifiers_repeat() const
|
|
{
|
|
return (win_pressed() ? MOD_WIN : 0) |
|
|
(ctrl_pressed() ? MOD_CONTROL : 0) |
|
|
(alt_pressed() ? MOD_ALT : 0) |
|
|
(shift_pressed() ? MOD_SHIFT : 0);
|
|
}
|
|
UINT get_modifiers() const
|
|
{
|
|
return get_modifiers_repeat() | MOD_NOREPEAT;
|
|
}
|
|
|
|
std::wstring to_string()
|
|
{
|
|
std::wstring result = L"";
|
|
if (shift_pressed())
|
|
{
|
|
result += L"shift+";
|
|
}
|
|
|
|
if (ctrl_pressed())
|
|
{
|
|
result += L"ctrl+";
|
|
}
|
|
|
|
if (win_pressed())
|
|
{
|
|
result += L"win+";
|
|
}
|
|
|
|
if (alt_pressed())
|
|
{
|
|
result += L"alt+";
|
|
}
|
|
|
|
result += key_from_code(get_code());
|
|
return result;
|
|
}
|
|
|
|
static std::wstring key_from_code(UINT key_code)
|
|
{
|
|
auto layout = GetKeyboardLayout(0);
|
|
auto scan_code = MapVirtualKeyExW(key_code, MAPVK_VK_TO_VSC_EX, layout);
|
|
// Determinate if vk is an extended key. Unfortunately MAPVK_VK_TO_VSC_EX
|
|
// does not return correct values.
|
|
static std::vector<UINT> extended_keys = {
|
|
VK_APPS,
|
|
VK_CANCEL,
|
|
VK_SNAPSHOT,
|
|
VK_DIVIDE,
|
|
VK_NUMLOCK,
|
|
VK_LWIN,
|
|
VK_RWIN,
|
|
VK_RMENU,
|
|
VK_RCONTROL,
|
|
VK_RSHIFT,
|
|
VK_RETURN,
|
|
VK_INSERT,
|
|
VK_DELETE,
|
|
VK_PRIOR,
|
|
VK_NEXT,
|
|
VK_HOME,
|
|
VK_END,
|
|
VK_UP,
|
|
VK_DOWN,
|
|
VK_LEFT,
|
|
VK_RIGHT,
|
|
};
|
|
if (find(begin(extended_keys), end(extended_keys), key_code) != end(extended_keys))
|
|
{
|
|
scan_code |= 0x100;
|
|
}
|
|
std::array<BYTE, 256> key_states{}; // Zero-initialize
|
|
std::array<wchar_t, 256> output;
|
|
const UINT wFlags = 1 << 2; // If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer)
|
|
auto output_bytes = ToUnicodeEx(key_code, scan_code, key_states.data(), output.data(), static_cast<int>(output.size()) - 1, wFlags, layout);
|
|
if (output_bytes <= 0)
|
|
{
|
|
// If ToUnicodeEx fails (e.g. for F1-F12 keys) use GetKeyNameTextW
|
|
output_bytes = GetKeyNameTextW(scan_code << 16, output.data(), static_cast<int>(output.size()));
|
|
}
|
|
if (output_bytes > 0)
|
|
{
|
|
output[output_bytes] = 0;
|
|
if (output_bytes == 1 && output[0] >= 'a' && output[0] <= 'z')
|
|
{
|
|
// Make Latin letters keys capital, as it looks better
|
|
output[0] = std::towupper(output[0]);
|
|
}
|
|
return output.data();
|
|
}
|
|
return L"(Key " + std::to_wstring(key_code) + L")";
|
|
}
|
|
|
|
protected:
|
|
HotkeyObject(json::JsonObject hotkey_json) :
|
|
m_json(std::move(hotkey_json))
|
|
{
|
|
if (get_key() == L"~" && get_modifiers_repeat() == MOD_WIN)
|
|
{
|
|
m_json.SetNamedValue(L"key", json::value(key_from_code(get_code())));
|
|
}
|
|
};
|
|
json::JsonObject m_json;
|
|
};
|
|
|
|
}
|