Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/xwt.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Corrado <alexc@xamarin.com>2013-11-15 00:37:23 +0400
committerAlex Corrado <alexc@xamarin.com>2013-11-15 00:47:27 +0400
commit0f6541f64866b6f45efd111fa116adf93694f48d (patch)
tree54b72321a4f5fa16f26faee65ed6772fc287ed86 /Xwt.WPF
parentde09ae41195dd7c703cdc36a5b98de6865568e06 (diff)
[WPF] Improve GetScaleFactor and return device-independent pixels from GetMouseLocation
This enables us to use the value of Desktop.MouseLocation to accurately set the ScreenBounds of a window on WPF.
Diffstat (limited to 'Xwt.WPF')
-rw-r--r--Xwt.WPF/Xwt.WPFBackend/WpfDesktopBackend.cs62
1 files changed, 44 insertions, 18 deletions
diff --git a/Xwt.WPF/Xwt.WPFBackend/WpfDesktopBackend.cs b/Xwt.WPF/Xwt.WPFBackend/WpfDesktopBackend.cs
index 1a0fa7e9..6eb8b7c7 100644
--- a/Xwt.WPF/Xwt.WPFBackend/WpfDesktopBackend.cs
+++ b/Xwt.WPF/Xwt.WPFBackend/WpfDesktopBackend.cs
@@ -23,7 +23,8 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-using System;
+using System;
+using System.Reflection;
using System.Runtime.InteropServices;
using Xwt.Backends;
using SWF = System.Windows.Forms;
@@ -42,31 +43,54 @@ namespace Xwt.WPFBackend
{
System.Windows.Application.Current.Dispatcher.BeginInvoke (new Action (OnScreensChanged));
};
- }
+ }
+ static bool cannotCallGetDpiForMonitor;
public override double GetScaleFactor (object backend)
- {
- var hdc = GetDC (IntPtr.Zero);
- if (hdc == IntPtr.Zero) {
- // GetDC failed for some reason
- return base.GetScaleFactor (backend);
- }
- try {
- //FIXME: Is it possible for the Y dpi to differ from the X dpi,
- // and if so, what should we do about it?
- var dpiX = GetDeviceCaps (hdc, LOGPIXELSX);
- return dpiX / BASELINE_DPI;
- } finally {
- ReleaseDC (IntPtr.Zero, hdc);
- }
+ {
+ //FIXME: Is it possible for the Y dpi to differ from the X dpi,
+ // and if so, what should we do about it?
+ int dpi = (int)BASELINE_DPI;
+
+ // In Windows 8.1, there can be a different dpi per monitor
+ if (!cannotCallGetDpiForMonitor) {
+ // .. I wish there was a less hacky way of getting the HMONITOR from the SWF.Screen :/
+ var hmonitorField = typeof (SWF.Screen).GetField ("hmonitor", BindingFlags.Instance | BindingFlags.NonPublic);
+ if (hmonitorField == null) {
+ cannotCallGetDpiForMonitor = true;
+ } else {
+ try {
+ int dpiY;
+ GetDpiForMonitor ((IntPtr)hmonitorField.GetValue (backend), MDT_Effective_DPI, out dpi, out dpiY);
+ } catch {
+ cannotCallGetDpiForMonitor = true;
+ }
+ }
+ }
+ if (cannotCallGetDpiForMonitor) {
+ // Get system-wide dpi
+ var hdc = GetDC (IntPtr.Zero);
+ if (hdc != IntPtr.Zero) {
+ try {
+ dpi = GetDeviceCaps (hdc, LOGPIXELSX);
+ } finally {
+ ReleaseDC (IntPtr.Zero, hdc);
+ }
+ }
+ }
+ return dpi / BASELINE_DPI;
}
#region implemented abstract members of DesktopBackend
public override Point GetMouseLocation()
{
- var loc = SWF.Cursor.Position;
- return new Point (loc.X, loc.Y);
+ var loc = SWF.Cursor.Position;
+ var screen = SWF.Screen.FromPoint (loc);
+ var scale = GetScaleFactor (screen);
+
+ // We need to convert the device pixels into WPF's device-independent pixels..
+ return new Point (loc.X / scale, loc.Y / scale);
}
public override IEnumerable<object> GetScreens ()
@@ -102,10 +126,12 @@ namespace Xwt.WPFBackend
const int LOGPIXELSX = 88;
const int LOGPIXELSY = 90;
+ const int MDT_Effective_DPI = 0;
[DllImport ("user32")] static extern IntPtr GetDC (IntPtr hWnd);
[DllImport ("user32")] static extern int ReleaseDC (IntPtr hWnd, IntPtr hdc);
[DllImport ("gdi32")] static extern int GetDeviceCaps (IntPtr hdc, int nIndex);
+ [DllImport ("Shcore")] static extern int GetDpiForMonitor (IntPtr hmonitor, int dpiType, out int dpiX, out int dpiY);
#endregion
}
}