Last active
May 27, 2017 13:35
-
-
Save YSRKEN/0c804fb4633e27443d4a2776ac18483e to your computer and use it in GitHub Desktop.
WPFアプリを高DPI対応にしよう! ref: http://qiita.com/YSRKEN/items/b8072f4816a88924605d
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<DockPanel> | |
<DockPanel.LayoutTransform> | |
<ScaleTransform ScaleX="{Binding ScaleX}" ScaleY="{Binding ScaleY}"/> | |
</DockPanel.LayoutTransform> | |
<!-- ここにリサイズしたいオブジェクトを置く --> | |
</DockPanel> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MonitorFromWindowが返したディスプレイの種類 | |
public enum MonitorDefaultTo { Null, Primary, Nearest } | |
// GetDpiForMonitorが返したDPIの種類 | |
enum MonitorDpiType { Effective, Angular, Raw, Default = Effective } | |
// NativeMethods | |
class NativeMethods { | |
// ウィンドウハンドルから、そのウィンドウが乗っているディスプレイハンドルを取得 | |
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] | |
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MonitorDefaultTo dwFlags); | |
// ディスプレイハンドルからDPIを取得 | |
[DllImport("SHCore.dll", CharSet = CharSet.Unicode, PreserveSig = false)] | |
public static extern void GetDpiForMonitor(IntPtr hmonitor, MonitorDpiType dpiType, ref uint dpiX, ref uint dpiY); | |
} | |
// 現在のディスプレイにおけるDPIを取得する | |
Dpi GetDpi() { | |
// 当該ウィンドウののハンドルを取得する | |
var helper = new WindowInteropHelper(this); | |
var hwndSource = HwndSource.FromHwnd(helper.Handle); | |
// ウィンドウが乗っているディスプレイのハンドルを取得する | |
var hmonitor = NativeMethods.MonitorFromWindow(hwndSource.Handle, MonitorDefaultTo.Nearest); | |
// ディスプレイのDPIを取得する | |
uint dpiX = Dpi.Default.X; | |
uint dpiY = Dpi.Default.Y; | |
NativeMethods.GetDpiForMonitor(hmonitor, MonitorDpiType.Default, ref dpiX, ref dpiY); | |
return new Dpi(dpiX, dpiY); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 初期化直後の処理 | |
protected override void OnSourceInitialized(EventArgs e) { | |
base.OnSourceInitialized(e); | |
// 最初にDPIを取得する | |
ResizeWindowByDpi(GetDpi()); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// DPI変更時に飛んでくるウィンドウメッセージ | |
enum WindowMessage { DpiChanged = 0x02E0 } | |
// フックするルーチン | |
protected override void OnSourceInitialized(EventArgs e) { | |
base.OnSourceInitialized(e); | |
// ウィンドウメッセージを取得する | |
var helper = new WindowInteropHelper(this); | |
var source = HwndSource.FromHwnd(helper.Handle); | |
source.AddHook(new HwndSourceHook(WndProc)); | |
} | |
// ウィンドウプロシージャ | |
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { | |
if(msg == (int)WindowMessage.DpiChanged) { | |
// wParamの下位16bit・上位16bitがそれぞれX・Y方向のDPIを表している | |
var dpiX = (uint)wParam & 0xFFFF; //下位16bit | |
var dpiY = (uint)wParam >> 16; //上位16bit | |
ResizeWindowByDpi(new Dpi(dpiX, dpiY)); | |
handled = true; | |
} | |
return IntPtr.Zero; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment