1

There are some methods from the Screen class to retrieve the respective screen, which contains the most area of a control.

They are the:

  • Screen.FromRectangle(Rectangle rect)
  • Screen.FromControl(Control control)
  • Screen.FromHandle(IntPtr hwnd)
  • Screen.FromPoint(Point point)

The issue here is that I have a problem getting my second Form to be opened in the second monitor. It kept on displaying only on the primary screen. According to the answer from here, the suspect is that the DpiAware was not enabled. However, the problem was still not fixed even after I have enabled the DpiAware.

To help me to check what was going on, I've added code for debugging. Then, I called/ opened the popup menu on \\\\.\\DISPLAY2. Inside of the debug console, the chosen Screen for FromPoint() was written \\\\.\\DISPLAY2. However, the popup menu was still opened on \\\\.\\DISPLAY1. Can anyone help me with this issue, please?

Below are the codes example:

Under main form class:

//mouseup event handler
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    //if RMB clicked
    if(e.Button == MouseButtons.Right)
    {
        //----set PopupMenu form location----
        popupMenuObj.Location = popupMenuObj.popupMenuLocation((sender as Control).PointToScreen(e.Location));
        //----set PopupMenu form location----

        //process the form location
        popupMenuObj.Location = popupMenuObj.processFormLocation(popupMenuObj.Location);

        //----set PopupMenu cursor location----
        Cursor.Position = popupMenuObj.middleOfPopupMenu(popupMenuObj.Location);
        //----set PopupMenu cursor location----

        //----display the popup menu----
        popupMenuObj.displayPopupMenu(1);
        //----display the popup menu----
    }
}

Under popup menu class:

//to set cursor to middle of popup menu
public Point middleOfPopupMenu(Point mousePoint)
{
    int theCenterWidth = this.Width / 2;
    int theCenterHeight = this.Height / 2;

    //set the mouse pointer location at middle of PopupMenu
    mousePoint.X += theCenterWidth;
    mousePoint.Y += theCenterHeight;

    return Cursor.Position = mousePoint;
}
//to set popupmenu location
public Point popupMenuLocation(Point thePoint)
{
    return this.Location = thePoint;
}
//set popup menu display status
public bool displayPopupMenu(int displayFlag)
{
    switch(displayFlag)
    {
        case 1: //if argument 1 -> display the PopupMenu
            this.Visible = true;
            return true;
        case 0: //if argument 0 -> close the PopupMenu
            this.Visible = false;
            return false;
        default: //by default, no need to display
            return false;
    }
}
//to process if popupmenu opens exceeding the screen working area
public Point processFormLocation(Point currentPoint)
{
    Point newPoint = new Point();
    int selectedScrWidth, selectedScrHeight; //screen dimension of the selected screen
    Screen selectedScreen;
    int totalXPos, totalYPos; //where the form is located before exceed screen is handled

    //---get screen where point is at---
    selectedScreen = Screen.FromPoint(currentPoint);
    Console.WriteLine("\nSelected screen info: {0}\n", selectedScreen); //for debugging purposes
    //---get screen where point is at---

    //---get selected screen dimension---
    selectedScrWidth = selectedScreen.WorkingArea.Width;
    selectedScrHeight = selectedScreen.WorkingArea.Height;
    //---get selected screen dimension---

    totalXPos = currentPoint.X + this.Width; //mouseXCoor + popupMenu width
    totalYPos = currentPoint.Y + this.Height; //mouseXCoor + popupMenu height

    //if exceed selected screen width and height
    if ((totalXPos >= selectedScrWidth) && (totalYPos >= selectedScrHeight))
    {
        newPoint.X = selectedScrWidth - this.Width;
        newPoint.Y = selectedScrHeight - this.Height;
    }
    //if exceed selected screen width
    else if ((totalXPos >= selectedScrWidth))
    {
        newPoint.X = selectedScrWidth - this.Width;
        newPoint.Y = currentPoint.Y;
    }
    //if exceed selected screen height
    else if ((totalYPos >= selectedScrHeight))
    {
        newPoint.X = newPoint.X;
        newPoint.Y = selectedScrHeight - this.Height;
    }
    else //if x exceed screen, just set the location as is
    {
        return this.Location = Cursor.Position;
    }
    return this.Location = newPoint;
}

Update 1: As per Jimi's request under the comment section, after creating a simple test project based on given answer here, here's what I got: screenInfo

Please note the reason why the code in the question from the previous thread has no Width, Height, and StartPosition = FormStartPosition.Manual defined was because the popup menu is from a class on another .cs file where, those specific properties have already been declared in the PopupMenu.Designer.cs file. Therefore, I don't feel like redefining was necessary.


Update 2: Now that it works, a newer problem arises is that, only when popup menu exceeds right boundary of secondary display, the popup menu was displayed on primary screen. However this didn't occur when I try to open the popup menu when exceeding the height of secondary screen. Example is shown below:

newIssue1 Above is the case when I try to open the popup menu when exceeding the width of secondary screen. The popup menu opens at the right boundary of primary screen.

newIssue2 It however worked just fine when I tried the case for exceeding the height of secondary display.

ewu11
  • 65
  • 9
  • 2
    "Additionally, to further confirm my issue, I have even tried to debug the program. Still, the Screen used was still on \\\\.\\DISPLAY1" -- Debugging is to help you understand why something happens, it doesn't magically fix anything for you. – Blindy Feb 23 '22 at 17:36
  • 1
    @Blindy -- I think I have misused my words. I have updated the question. Hopefully, its more understandable. – ewu11 Feb 23 '22 at 18:27
  • 2
    Can you try to use [this code](https://stackoverflow.com/a/71055631/7444103) exactly as it's written, without any change? Copy it and add it to a test Project. -- Note that the `MouseUp` event is related to the Control where the event is raised, not the Form; the click location is translated to Screen coordinates. -- The popup's `StartPosition` must be `FormStartPosition.Manual`. -- When debugging, write down the measures specified by `SystemInformation.VirtualScreen`, `Screen[0]`, `SystemInformation.PrimaryMonitorSize` and post them here. – Jimi Feb 23 '22 at 18:38
  • 1
    @Jimi -- Updates has been done as necessary. – ewu11 Feb 23 '22 at 20:21
  • All right. Now, take the code you find in that post (take a new copy, don't use what you have), create a new Project, add a Form and add some Controls to it, let them all subscribe to `MouseUp` event using the same handler (`someControl_MouseUp` in that code) and tell me the popup window opens in the primary screen instead of a secodary. – Jimi Feb 23 '22 at 20:34
  • @Jimi -- Sorry, but which 'that post' are you referring to? -- Weird enough..it works after I have done the test project using the answer from the previous post. However, a newer problem arises. I've updated the post above as necessary. – ewu11 Feb 23 '22 at 20:55
  • The [code you find in your previous post](https://stackoverflow.com/a/71055631/7444103), the same you also linked. Get the current version and use it as it is the way I described before. – Jimi Feb 23 '22 at 21:50
  • Anyway, I'll give it a look tomorrow. I'll notify you if I change something. – Jimi Feb 23 '22 at 22:08

0 Answers0