Das Problem ist, dass der Wert, den ich bei der Berechnung der Bildschirmposition erhalte, nicht den Erwartungen entspricht. Diese Testanwendung zeigt die berechnete Position „vom Bildschirm“ und die tatsächlichen Bildschirmpositionen der schwebenden Fenster, wenn sie an ihren Platz gezogen werden.

Berechnungen von Koordinaten in der Windows-Anwendung
Unter „ControlBlock“ ist die Breite des ControlBlocks und der „Fensterposition“ angegeben die Bildschirmkoordinaten berechnet mit:
Code: Select all
//Application window position
var mainWindow = (Application.Current as App) ? ._window;
PointInt32 windowPos = mainWindow.AppWindow.Position;
//Get monitor from a window
IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(mainWindow);
IntPtr hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
//Control block
WindowPos.Text = $ "Window Pos: ({windowPos.X:N0}, {windowPos.Y:N0})";
ControlBlockWidth.Text = $ "Width: {ControlBlock.ActualWidth:N0}";
Code: Select all
//Left block
LeftBlockWidth.Text = $ "Width: {LeftBlock.ActualWidth:N0}";
var transformLeftBlock = LeftBlock.TransformToVisual(mainWindow.Content as UIElement);
var pointLeftBlock = transformLeftBlock.TransformPoint(new Point(0, 0));
LeftBlockScreenCoord.Text = $ "LeftBlock Screen: ({pointLeftBlock.X + windowPos.X:N0}, {pointLeftBlock.Y + windowPos.Y:N0})";
Code: Select all
//Middle block
var transform = MiddleBlock.TransformToVisual(LeftBlock);
var pointInRoot = transform.TransformPoint(new Point(0, 0));
MiddleBlockFromLeftBlock.Text = $ "From LeftBlock: ({pointInRoot.X:N0}, {pointInRoot.Y:N0})";
var transform2 = MiddleBlock.TransformToVisual(RootGrid);
var pointInRoot2 = transform2.TransformPoint(new Point(0, 0));
MiddleBlockFromRootGrid.Text = $ "From RootGrid: ({pointInRoot2.X:N0}, {pointInRoot2.Y:N0})";
var transform3 = MiddleBlock.TransformToVisual(mainWindow.Content as UIElement);
var pointInRoot3 = transform3.TransformPoint(new Point(0, 0));
MiddleBlockWindowCoord.Text = $ "From AppWindow: ({pointInRoot3.X:N0}, {pointInRoot3.Y:N0})";
MiddleBlockScreenCoord.Text = $ "From Screen: ({pointInRoot3.X + windowPos.X:N0}, {pointInRoot3.Y + windowPos.Y:N0})";
Das schwebende Fenster wird an die richtige Position gezogen und „Bildschirmposition“ ist der Wert „floatingWindow.AppWindow.Position“.
Ich kann auch genaue Bildschirmkoordinaten angeben, die dann das schwebende Fenster mit „floatingWindow.AppWindow.Move(new PointInt32(targetX, targetY))“
Wenn ich das schwebende Fenster nahe der rechten Seite des Bildschirms positioniere, lautet die X-Koordinate 3397 + die Breite des Fensters (500), das liegt nahe an der Bildschirmauflösung (3840 x 2160).
Skalierungsverhältnis zwischen der virtuellen Auflösung und der realen Auflösung
Ich habe versucht, das Skalierungsverhältnis zu ermitteln, das in dieser Frage besprochen wurde, aber es ist so 1.0.
Wie erkennt man die aktuelle Bildschirmauflösung?
Frage
Weiß jemand, wie man die Bildschirmposition des linken Randes von MiddleBlock richtig berechnet? Offensichtlich sind die Koordinaten innerhalb der Anwendung keine Pixel. Ist eine Konvertierung erforderlich, um von Anwendungskoordinaten in Bildschirmkoordinaten zu gelangen?
Hinzugefügt
Eine Minimalversion, die nur den wesentlichen Teil enthält:
MinimalVersionPage.xaml
Code: Select all
Code: Select all
Code: Select all
public sealed partial class MinimalVersionPage : Page
{
public MinimalVersionPage()
{
InitializeComponent();
}
private void UpdateCoordsButton_Click(object sender, RoutedEventArgs e)
{
//Application window position
var mainWindow = (Application.Current as App)?._window;
PointInt32 windowPos = mainWindow.AppWindow.Position;
//Left block
WindowPos.Text = $"Window Pos: ({windowPos.X:N0}, {windowPos.Y:N0})";
LeftBlockWidth.Text = $"Width: {LeftBlock.ActualWidth:N0}";
//Middle block
var transform3 = MiddleBlock.TransformToVisual(mainWindow.Content as UIElement);
var pointInRoot3 = transform3.TransformPoint(new Point(0, 0));
MiddleBlockWindowCoord.Text = $"From AppWindow: ({pointInRoot3.X:N0}, {pointInRoot3.Y:N0})";
MiddleBlockScreenCoord.Text = $"From Screen: ({pointInRoot3.X + windowPos.X:N0}, {pointInRoot3.Y + windowPos.Y:N0})";
}
private void CreateWindow_Click(object sender, RoutedEventArgs e)
{
var floatingWindow = new Window
{
Title = "Floating Window"
};
floatingWindow.AppWindow.Resize(new Windows.Graphics.SizeInt32(500, 700));
var presenter = floatingWindow.AppWindow.Presenter as Microsoft.UI.Windowing.OverlappedPresenter;
if (presenter != null)
{
presenter.IsAlwaysOnTop = true;
}
var stackPanel = new StackPanel
{
Padding = new Thickness(20),
Spacing = 10
};
var coordinateText = new TextBlock
{
Text = "Screen Position: (0, 0)",
FontSize = 16,
HorizontalAlignment = HorizontalAlignment.Center
};
stackPanel.Children.Add(coordinateText);
floatingWindow.Content = stackPanel;
// Set up a timer to update the coordinates every 16 milliseconds (~60 FPS)
var dispatcherQueue = floatingWindow.DispatcherQueue;
var timer = dispatcherQueue.CreateTimer();
timer.Interval = TimeSpan.FromMilliseconds(16);
timer.IsRepeating = true;
timer.Tick += (s, args) =>
{
var position = floatingWindow.AppWindow.Position;
var size = floatingWindow.AppWindow.Size;
coordinateText.Text = $"Screen Position: ({position.X}, {position.Y})";
};
floatingWindow.Closed += (s, args) =>
{
timer.Stop();
};
timer.Start();
floatingWindow.Activate();
}
}
Mobile version