Search code examples
c#multiple-monitors

PointToScreen multiple montors


I am using PointToScreen to figure out the position of a popupwindow so that it is besides the button that was used to pop it up. However, the button is on a toolbar, so the user can move the pop-up around.

The position of the pop-up works well, but if the user is on a quadrant I want to move the pop-up above the bottom (instead of below) or left (instead of right).

The problem is that in a multi-monitor setup, PointToScreen delivers to position of the control of the main screen, so if I have another screen left of it, the X could be negative and so on.

Point location = new Point(buttonItem.ButtonBounds.X, buttonItem.ButtonBounds.Y);
location = toolBar.PointToScreen(location);
int screenHeight = Screen.FromControl(this).Bounds.Height;
int screenWidth = Screen.FromControl(this).Bounds.Width;
PopupWindow.Quadrant quad = location.Y < screenHeight / 2
    ? PopupWindow.Quadrant.Top
    : PopupWindow.Quadrant.Bottom;
quad |= location.X < screenWidth / 2
    ? PopupWindow.Quadrant.Left
    : PopupWindow.Quadrant.Right;

// ...
//Do stuff to adjust the position of the pop-up based on the quadrant

Now, here I am hoping I can get the position of the button relative to the screen that it is on without doing some ugly DllImport. Any ideas?


Solution

  • Transforming Ron Beyer comment into an answer:

    static class ControlExtensions
    {
        ///<summary>
        /// Returns the position of the point in screen coordinates of that control instead
        /// of the main-screen coordinates
        ///</summary>
        public static Point PointToCurrentScreen(this Control self, Point location)
        {
            var screenBounds = Screen.FromControl(self).Bounds;
            var globalCoordinates = self.PointToScreen(location);
            return new Point(globalCoordinates.X - screenBounds.X, globalCoordinates.Y - screenBounds.Y);
        }
    }