
15 changed files with 583 additions and 3 deletions
-
1.gitignore
-
40NativeHelpers/AssemblyInfo.cpp
-
108NativeHelpers/NativeHelpers.vcxproj
-
38NativeHelpers/NativeHelpers.vcxproj.filters
-
75NativeHelpers/PerMonitorDPIHelpers.cpp
-
30NativeHelpers/PerMonitorDPIHelpers.h
-
155NativeHelpers/PerMonitorDPIWindow.cpp
-
81NativeHelpers/PerMonitorDPIWindow.h
-
13NativeHelpers/pch.cpp
-
12NativeHelpers/pch.h
-
14Text-Grab.sln
-
2Text-Grab/AssemblyInfo.cs
-
5Text-Grab/MainWindow.xaml
-
3Text-Grab/MainWindow.xaml.cs
-
9Text-Grab/Text-Grab.csproj
@ -0,0 +1,40 @@ |
|||||
|
#include "pch.h"
|
||||
|
|
||||
|
using namespace System; |
||||
|
using namespace System::Reflection; |
||||
|
using namespace System::Runtime::CompilerServices; |
||||
|
using namespace System::Runtime::InteropServices; |
||||
|
using namespace System::Security::Permissions; |
||||
|
|
||||
|
//
|
||||
|
// General Information about an assembly is controlled through the following
|
||||
|
// set of attributes. Change these attribute values to modify the information
|
||||
|
// associated with an assembly.
|
||||
|
//
|
||||
|
[assembly:AssemblyTitleAttribute("NativeHelpers")]; |
||||
|
[assembly:AssemblyDescriptionAttribute("")]; |
||||
|
[assembly:AssemblyConfigurationAttribute("")]; |
||||
|
[assembly:AssemblyCompanyAttribute("")]; |
||||
|
[assembly:AssemblyProductAttribute("NativeHelpers")]; |
||||
|
[assembly:AssemblyCopyrightAttribute("Copyright (c)")]; |
||||
|
[assembly:AssemblyTrademarkAttribute("")]; |
||||
|
[assembly:AssemblyCultureAttribute("")]; |
||||
|
|
||||
|
//
|
||||
|
// Version information for an assembly consists of the following four values:
|
||||
|
//
|
||||
|
// Major Version
|
||||
|
// Minor Version
|
||||
|
// Build Number
|
||||
|
// Revision
|
||||
|
//
|
||||
|
// You can specify all the value or you can default the Revision and Build Numbers
|
||||
|
// by using the '*' as shown below:
|
||||
|
|
||||
|
[assembly:AssemblyVersionAttribute("1.0.*")]; |
||||
|
|
||||
|
[assembly:ComVisible(false)]; |
||||
|
|
||||
|
[assembly:CLSCompliantAttribute(true)]; |
||||
|
|
||||
|
//[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
|
@ -0,0 +1,108 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<ItemGroup Label="ProjectConfigurations"> |
||||
|
<ProjectConfiguration Include="Debug|Win32"> |
||||
|
<Configuration>Debug</Configuration> |
||||
|
<Platform>Win32</Platform> |
||||
|
</ProjectConfiguration> |
||||
|
<ProjectConfiguration Include="Release|Win32"> |
||||
|
<Configuration>Release</Configuration> |
||||
|
<Platform>Win32</Platform> |
||||
|
</ProjectConfiguration> |
||||
|
</ItemGroup> |
||||
|
<PropertyGroup Label="Globals"> |
||||
|
<ProjectGuid>{938E65D0-EC9C-4181-87CA-A43D4747610D}</ProjectGuid> |
||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
||||
|
<Keyword>ManagedCProj</Keyword> |
||||
|
<RootNamespace>NativeHelpers</RootNamespace> |
||||
|
<SccProjectName> |
||||
|
</SccProjectName> |
||||
|
<SccAuxPath> |
||||
|
</SccAuxPath> |
||||
|
<SccLocalPath> |
||||
|
</SccLocalPath> |
||||
|
<SccProvider> |
||||
|
</SccProvider> |
||||
|
<ProjectName>NativeHelpers</ProjectName> |
||||
|
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
|
<UseDebugLibraries>true</UseDebugLibraries> |
||||
|
<PlatformToolset>v142</PlatformToolset> |
||||
|
<CLRSupport>true</CLRSupport> |
||||
|
<CharacterSet>Unicode</CharacterSet> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
|
<UseDebugLibraries>false</UseDebugLibraries> |
||||
|
<PlatformToolset>v142</PlatformToolset> |
||||
|
<CLRSupport>true</CLRSupport> |
||||
|
<CharacterSet>Unicode</CharacterSet> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||
|
<ImportGroup Label="ExtensionSettings"> |
||||
|
</ImportGroup> |
||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
|
</ImportGroup> |
||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
|
</ImportGroup> |
||||
|
<PropertyGroup Label="UserMacros" /> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
|
<LinkIncremental>true</LinkIncremental> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
|
<LinkIncremental>false</LinkIncremental> |
||||
|
</PropertyGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
|
<ClCompile> |
||||
|
<WarningLevel>Level4</WarningLevel> |
||||
|
<Optimization>Disabled</Optimization> |
||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<PrecompiledHeader>Use</PrecompiledHeader> |
||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
<AdditionalDependencies /> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
|
<ClCompile> |
||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
|
<PrecompiledHeader>Use</PrecompiledHeader> |
||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> |
||||
|
<WarningLevel /> |
||||
|
</ClCompile> |
||||
|
<Link> |
||||
|
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
|
<AdditionalDependencies /> |
||||
|
</Link> |
||||
|
</ItemDefinitionGroup> |
||||
|
<ItemGroup> |
||||
|
<Reference Include="PresentationCore" /> |
||||
|
<Reference Include="PresentationFramework" /> |
||||
|
<Reference Include="System" /> |
||||
|
<Reference Include="WindowsBase" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ClInclude Include="PerMonitorDPIHelpers.h" /> |
||||
|
<ClInclude Include="PerMonitorDPIWindow.h" /> |
||||
|
<ClInclude Include="pch.h" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ClCompile Include="AssemblyInfo.cpp" /> |
||||
|
<ClCompile Include="PerMonitorDPIHelpers.cpp" /> |
||||
|
<ClCompile Include="PerMonitorDPIWindow.cpp" /> |
||||
|
<ClCompile Include="pch.cpp"> |
||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> |
||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> |
||||
|
</ClCompile> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
|
<ImportGroup Label="ExtensionTargets"> |
||||
|
</ImportGroup> |
||||
|
</Project> |
@ -0,0 +1,38 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<ItemGroup> |
||||
|
<Filter Include="Source Files"> |
||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> |
||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> |
||||
|
</Filter> |
||||
|
<Filter Include="Header Files"> |
||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> |
||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> |
||||
|
</Filter> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ClInclude Include="PerMonitorDPIWindow.h"> |
||||
|
<Filter>Header Files</Filter> |
||||
|
</ClInclude> |
||||
|
<ClInclude Include="PerMonitorDPIHelpers.h"> |
||||
|
<Filter>Header Files</Filter> |
||||
|
</ClInclude> |
||||
|
<ClInclude Include="pch.h"> |
||||
|
<Filter>Header Files</Filter> |
||||
|
</ClInclude> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ClCompile Include="AssemblyInfo.cpp"> |
||||
|
<Filter>Source Files</Filter> |
||||
|
</ClCompile> |
||||
|
<ClCompile Include="PerMonitorDPIWindow.cpp"> |
||||
|
<Filter>Source Files</Filter> |
||||
|
</ClCompile> |
||||
|
<ClCompile Include="PerMonitorDPIHelpers.cpp"> |
||||
|
<Filter>Source Files</Filter> |
||||
|
</ClCompile> |
||||
|
<ClCompile Include="pch.cpp"> |
||||
|
<Filter>Source Files</Filter> |
||||
|
</ClCompile> |
||||
|
</ItemGroup> |
||||
|
</Project> |
@ -0,0 +1,75 @@ |
|||||
|
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
|
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
|
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
|
//// PARTICULAR PURPOSE.
|
||||
|
////
|
||||
|
//// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
|
|
||||
|
|
||||
|
//Main helper class that provides helper functions used by the PerMonitorDPIWindow class
|
||||
|
|
||||
|
#include "pch.h"
|
||||
|
#include "PerMonitorDPIHelpers.h"
|
||||
|
|
||||
|
|
||||
|
// Returns the DPI awareness of the current process
|
||||
|
|
||||
|
PROCESS_DPI_AWARENESS NativeHelpers::PerMonitorDPIHelper::GetPerMonitorDPIAware() |
||||
|
{ |
||||
|
|
||||
|
PROCESS_DPI_AWARENESS awareness; |
||||
|
HANDLE hProcess; |
||||
|
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessId()); |
||||
|
auto result = GetProcessDpiAwareness(hProcess, &awareness); |
||||
|
|
||||
|
if (S_OK != result) |
||||
|
{ |
||||
|
throw gcnew System::Exception(L"Unable to read process DPI level"); |
||||
|
} |
||||
|
return awareness; |
||||
|
} |
||||
|
|
||||
|
//Sets the current process as Per_Monitor_DPI_Aware. Returns True if the process was marked as Per_Monitor_DPI_Aware
|
||||
|
|
||||
|
BOOL NativeHelpers::PerMonitorDPIHelper::SetPerMonitorDPIAware() |
||||
|
{ |
||||
|
auto result = SetProcessDpiAwareness(PROCESS_DPI_AWARENESS::PROCESS_PER_MONITOR_DPI_AWARE); |
||||
|
|
||||
|
if (S_OK != result) |
||||
|
{ |
||||
|
return FALSE; |
||||
|
} |
||||
|
return TRUE; |
||||
|
} |
||||
|
|
||||
|
//Returns the DPI of the window handle passed in the parameter
|
||||
|
|
||||
|
double NativeHelpers::PerMonitorDPIHelper::GetDpiForWindow(IntPtr hwnd) |
||||
|
{ |
||||
|
return GetDpiForHwnd(static_cast<HWND>(hwnd.ToPointer())); |
||||
|
} |
||||
|
|
||||
|
double NativeHelpers::PerMonitorDPIHelper::GetDpiForHwnd(HWND hWnd) |
||||
|
{ |
||||
|
auto monitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); |
||||
|
UINT newDpiX; |
||||
|
UINT newDpiY; |
||||
|
if (FAILED(GetDpiForMonitor(monitor, MONITOR_DPI_TYPE::MDT_EFFECTIVE_DPI, &newDpiX, &newDpiY))) |
||||
|
{ |
||||
|
newDpiX = 96; |
||||
|
newDpiY = 96; |
||||
|
} |
||||
|
return ((double) newDpiX); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//Returns the system DPI
|
||||
|
|
||||
|
double NativeHelpers::PerMonitorDPIHelper::GetSystemDPI() |
||||
|
{ |
||||
|
int newDpiX(0); |
||||
|
auto hDC = GetDC(NULL); |
||||
|
newDpiX = GetDeviceCaps(hDC, LOGPIXELSX); |
||||
|
ReleaseDC(NULL, hDC); |
||||
|
return (double)newDpiX; |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF |
||||
|
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO |
||||
|
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A |
||||
|
//// PARTICULAR PURPOSE. |
||||
|
//// |
||||
|
//// Copyright (c) Microsoft Corporation. All rights reserved |
||||
|
|
||||
|
#pragma once |
||||
|
#include "pch.h" |
||||
|
|
||||
|
using namespace System; |
||||
|
|
||||
|
namespace NativeHelpers |
||||
|
{ |
||||
|
public ref class PerMonitorDPIHelper |
||||
|
{ |
||||
|
public: |
||||
|
|
||||
|
static BOOL SetPerMonitorDPIAware(); |
||||
|
|
||||
|
static PROCESS_DPI_AWARENESS GetPerMonitorDPIAware(); |
||||
|
|
||||
|
static double GetDpiForWindow(IntPtr hwnd); |
||||
|
|
||||
|
static double GetSystemDPI(); |
||||
|
|
||||
|
private: |
||||
|
static double GetDpiForHwnd(HWND hWnd); |
||||
|
}; |
||||
|
} |
@ -0,0 +1,155 @@ |
|||||
|
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
|
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
|
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
|
//// PARTICULAR PURPOSE.
|
||||
|
////
|
||||
|
//// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
|
|
||||
|
#include "pch.h"
|
||||
|
#include "PerMonitorDPIWindow.h"
|
||||
|
|
||||
|
namespace NativeHelpers |
||||
|
{ |
||||
|
|
||||
|
//Constructor; sets the current process as Per_Monitor_DPI_Aware
|
||||
|
PerMonitorDPIWindow::PerMonitorDPIWindow(void) |
||||
|
{ |
||||
|
Loaded += gcnew System::Windows::RoutedEventHandler(this, &NativeHelpers::PerMonitorDPIWindow::OnLoaded); |
||||
|
if (PerMonitorDPIHelper::SetPerMonitorDPIAware()) |
||||
|
{ |
||||
|
m_perMonitorEnabled = true; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
throw gcnew System::Exception(L"Enabling Per-monitor DPI Failed. Do you have [assembly: DisableDpiAwareness] in your assembly manifest [AssemblyInfo.cs]?"); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
PerMonitorDPIWindow::~PerMonitorDPIWindow() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
//OnLoaded Handler: Adjusts the window size and graphics and text size based on current DPI of the Window
|
||||
|
|
||||
|
void PerMonitorDPIWindow::OnLoaded(Object^ , RoutedEventArgs^ ) |
||||
|
{ |
||||
|
// WPF has already scaled window size, graphics and text based on system DPI. In order to scale the window based on monitor DPI, update the
|
||||
|
// window size, graphics and text based on monitor DPI. For example consider an application with size 600 x 400 in device independent pixels
|
||||
|
// - Size in device independent pixels = 600 x 400
|
||||
|
// - Size calculated by WPF based on system/WPF DPI = 192 (scale factor = 2)
|
||||
|
// - Expected size based on monitor DPI = 144 (scale factor = 1.5)
|
||||
|
|
||||
|
// Similarly the graphics and text are updated updated by applying appropriate scale transform to the top level node of the WPF application
|
||||
|
|
||||
|
// Important Note: This method overwrites the size of the window and the scale transform of the root node of the WPF Window. Hence,
|
||||
|
// this sample may not work "as is" if
|
||||
|
// - The size of the window impacts other portions of the application like this WPF Window being hosted inside another application.
|
||||
|
// - The WPF application that is extending this class is setting some other transform on the root visual; the sample may
|
||||
|
// overwrite some other transform that is being applied by the WPF application itself.
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
if (m_perMonitorEnabled) |
||||
|
{ |
||||
|
m_source = (HwndSource^) PresentationSource::FromVisual((Visual^) this); |
||||
|
HwndSourceHook^ hook = gcnew HwndSourceHook(this, &PerMonitorDPIWindow::HandleMessages); |
||||
|
m_source->AddHook(hook); |
||||
|
|
||||
|
|
||||
|
//Calculate the DPI used by WPF; this is same as the system DPI.
|
||||
|
|
||||
|
m_wpfDPI = 96.0 * m_source->CompositionTarget->TransformToDevice.M11; |
||||
|
|
||||
|
//Get the Current DPI of the monitor of the window.
|
||||
|
|
||||
|
m_currentDPI = NativeHelpers::PerMonitorDPIHelper::GetDpiForWindow(m_source->Handle); |
||||
|
|
||||
|
//Calculate the scale factor used to modify window size, graphics and text
|
||||
|
m_scaleFactor = m_currentDPI / m_wpfDPI; |
||||
|
|
||||
|
//Update Width and Height based on the on the current DPI of the monitor
|
||||
|
|
||||
|
Width = Width * m_scaleFactor; |
||||
|
Height = Height * m_scaleFactor; |
||||
|
|
||||
|
//Update graphics and text based on the current DPI of the monitor
|
||||
|
|
||||
|
UpdateLayoutTransform(m_scaleFactor); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//Called when the DPI of the window changes. This method adjusts the graphics and text size based on the new DPI of the window
|
||||
|
void PerMonitorDPIWindow::OnDPIChanged() |
||||
|
{ |
||||
|
m_scaleFactor = m_currentDPI / m_wpfDPI; |
||||
|
UpdateLayoutTransform(m_scaleFactor); |
||||
|
DPIChanged(this, EventArgs::Empty); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void PerMonitorDPIWindow::UpdateLayoutTransform(double scaleFactor) |
||||
|
{ |
||||
|
// Adjust the rendering graphics and text size by applying the scale transform to the top level visual node of the Window
|
||||
|
if (m_perMonitorEnabled) |
||||
|
{ |
||||
|
auto child = GetVisualChild(0); |
||||
|
if (m_scaleFactor != 1.0) { |
||||
|
ScaleTransform^ dpiScale = gcnew ScaleTransform(scaleFactor, scaleFactor); |
||||
|
child->SetValue(Window::LayoutTransformProperty, dpiScale); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
child->SetValue(Window::LayoutTransformProperty, nullptr); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Message handler of the Per_Monitor_DPI_Aware window. The handles the WM_DPICHANGED message and adjusts window size, graphics and text
|
||||
|
// based on the DPI of the monitor. The window message provides the new window size (lparam) and new DPI (wparam)
|
||||
|
|
||||
|
IntPtr PerMonitorDPIWindow::HandleMessages(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool% ) |
||||
|
{ |
||||
|
double oldDpi; |
||||
|
switch (msg) |
||||
|
{ |
||||
|
case WM_DPICHANGED: |
||||
|
LPRECT lprNewRect = (LPRECT)lParam.ToPointer(); |
||||
|
SetWindowPos(static_cast<HWND>(hwnd.ToPointer()), 0, lprNewRect->left, lprNewRect->top, lprNewRect->right - lprNewRect->left, lprNewRect->bottom - lprNewRect->top, SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE); |
||||
|
oldDpi = m_currentDPI; |
||||
|
m_currentDPI = static_cast<int>(LOWORD(wParam.ToPointer())); |
||||
|
if (oldDpi != m_currentDPI) |
||||
|
{ |
||||
|
OnDPIChanged(); |
||||
|
} |
||||
|
break; |
||||
|
} |
||||
|
return IntPtr::Zero; |
||||
|
} |
||||
|
|
||||
|
System::String^ PerMonitorDPIWindow::GetCurrentDpiConfiguration() |
||||
|
{ |
||||
|
System::Text::StringBuilder^ stringBuilder = gcnew System::Text::StringBuilder(); |
||||
|
|
||||
|
auto awareness = NativeHelpers::PerMonitorDPIHelper::GetPerMonitorDPIAware(); |
||||
|
|
||||
|
auto systemDpi = NativeHelpers::PerMonitorDPIHelper::GetSystemDPI(); |
||||
|
|
||||
|
switch (awareness) |
||||
|
{ |
||||
|
case PROCESS_DPI_AWARENESS::PROCESS_DPI_UNAWARE: |
||||
|
|
||||
|
stringBuilder->AppendFormat(gcnew System::String(L"Application is DPI Unaware. Using {0} DPI."), systemDpi); |
||||
|
break; |
||||
|
case PROCESS_DPI_AWARENESS::PROCESS_SYSTEM_DPI_AWARE: |
||||
|
stringBuilder->AppendFormat(gcnew System::String(L"Application is System DPI Aware. Using System DPI:{0}."), systemDpi); |
||||
|
break; |
||||
|
case PROCESS_DPI_AWARENESS::PROCESS_PER_MONITOR_DPI_AWARE: |
||||
|
stringBuilder->AppendFormat(gcnew System::String(L"Application is Per-Monitor DPI Aware. Using \tmonitor DPI = {0} \t(System DPI = {1})."), m_currentDPI, systemDpi); |
||||
|
break; |
||||
|
} |
||||
|
return stringBuilder->ToString(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,81 @@ |
|||||
|
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF |
||||
|
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO |
||||
|
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A |
||||
|
//// PARTICULAR PURPOSE. |
||||
|
//// |
||||
|
//// Copyright (c) Microsoft Corporation. All rights reserved |
||||
|
|
||||
|
|
||||
|
#pragma once |
||||
|
#include "PerMonitorDPIHelpers.h" |
||||
|
using namespace System; |
||||
|
using namespace System::Windows::Interop; |
||||
|
using namespace System::Windows; |
||||
|
using namespace System::Windows::Media; |
||||
|
using namespace System::Security::Permissions; |
||||
|
|
||||
|
namespace NativeHelpers |
||||
|
{ |
||||
|
public ref class PerMonitorDPIWindow : public Window |
||||
|
{ |
||||
|
public: |
||||
|
PerMonitorDPIWindow(void); |
||||
|
|
||||
|
event EventHandler^ DPIChanged; |
||||
|
|
||||
|
System::String^ GetCurrentDpiConfiguration(); |
||||
|
|
||||
|
property double CurrentDPI |
||||
|
{ |
||||
|
double get() |
||||
|
{ |
||||
|
return m_currentDPI; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
property double WpfDPI |
||||
|
{ |
||||
|
double get() |
||||
|
{ |
||||
|
return m_wpfDPI; |
||||
|
} |
||||
|
void set(double value) |
||||
|
{ |
||||
|
m_wpfDPI = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
property double ScaleFactor |
||||
|
{ |
||||
|
double get() |
||||
|
{ |
||||
|
return m_scaleFactor; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected: |
||||
|
~PerMonitorDPIWindow(); |
||||
|
|
||||
|
[EnvironmentPermissionAttribute(SecurityAction::LinkDemand, Unrestricted = true)] |
||||
|
void OnLoaded(Object^ sender, RoutedEventArgs^ args); |
||||
|
|
||||
|
void OnDPIChanged(); |
||||
|
|
||||
|
void UpdateLayoutTransform(double scaleFactor); |
||||
|
|
||||
|
IntPtr HandleMessages(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, bool %handled); |
||||
|
|
||||
|
private: |
||||
|
System::Boolean m_perMonitorEnabled; |
||||
|
|
||||
|
double m_currentDPI; |
||||
|
|
||||
|
double m_systemDPI; |
||||
|
|
||||
|
double m_wpfDPI; |
||||
|
|
||||
|
double m_scaleFactor; |
||||
|
|
||||
|
System::Windows::Interop::HwndSource^ m_source; |
||||
|
}; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
//// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
|
//// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
|
//// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
|
//// PARTICULAR PURPOSE.
|
||||
|
////
|
||||
|
//// Copyright (c) Microsoft Corporation. All rights reserved
|
||||
|
|
||||
|
|
||||
|
// stdafx.cpp : source file that includes just the standard includes
|
||||
|
// NativeHelpers.pch will be the pre-compiled header
|
||||
|
// stdafx.obj will contain the pre-compiled type information
|
||||
|
|
||||
|
#include "pch.h"
|
@ -0,0 +1,12 @@ |
|||||
|
// stdafx.h : include file for standard system include files, |
||||
|
// or project specific include files that are used frequently, |
||||
|
// but are changed infrequently |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <Windows.h> |
||||
|
#include <ShellScalingApi.h> |
||||
|
|
||||
|
#pragma comment(lib, "user32.lib") |
||||
|
#pragma comment(lib, "shcore.lib") |
||||
|
#pragma comment(lib, "Gdi32.lib") |
Write
Preview
Loading…
Cancel
Save
Reference in new issue