/// <summary> /// Attach a DpiHandler to the specified window /// </summary> /// <param name="window">Windows</param> /// <param name="dpiHandler">DpiHandler</param> private static void AttachDpiHandler(Window window, DpiHandler dpiHandler) { if (Log.IsVerboseEnabled()) { Log.Verbose().WriteLine("Registering the UpdateLayoutTransform subscription for {0}", window.GetType()); } // Add the layout transform action var transformSubscription = dpiHandler.OnDpiChanged.Subscribe(dpiChangeInfo => window.UpdateLayoutTransform((double)dpiChangeInfo.NewDpi / DpiHandler.DefaultScreenDpi)); window.WinProcMessages().Subscribe(message => { dpiHandler.HandleWindowMessages(message); switch (message.Message) { case WindowsMessages.WM_NCCREATE: // Apply scaling 1x time window.UpdateLayoutTransform((double)NativeDpiMethods.GetDpi(message.Handle) / DpiHandler.DefaultScreenDpi); break; case WindowsMessages.WM_DESTROY: // Remove layout transform if (Log.IsVerboseEnabled()) { Log.Verbose().WriteLine("Removing the UpdateLayoutTransform subscription for {0}", window.GetType()); } transformSubscription.Dispose(); break; } }); }
/// <summary> /// Handle DPI changes for the specified Form /// Using this DOES NOT enable dpi scaling in the non client area, for this you will need to call: /// DpiHandler.TryEnableNonClientDpiScaling(this.Handle) from the WndProc in the WM_NCCREATE message. /// It's better to extend DpiAwareForm, which does this for you. /// </summary> /// <param name="form">Control</param> /// <returns>DpiHandler</returns> public static DpiHandler AttachDpiHandler(this Form form) { // Create a DpiHandler which runs "outside" of the form (not via WinProc) var dpiHandler = new DpiHandler(true); dpiHandler.MessageHandler = form.WinProcFormsMessages().Subscribe(message => dpiHandler.HandleWindowMessages(message)); return(dpiHandler); }