Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Multi-Monitor Positioning


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 15 - Last Post: Feb 6, 2018 11:08 AM Last Post By: Quentin Correll
Mark Williams

Posts: 120
Registered: 5/8/10
Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 28, 2018 11:04 AM
I am trying to work out how to position a pop up form (which is contained in a component) in a multi monitor set up.

It need to pop up relative to the mouse position.

I pass through the mouse cursorpos to the component and then try the following within the component code to position the form:

for i:=0 to screen.MonitorCount-1 do
  begin    
    if (pt.x>=screen.monitors[i].left)
    and (pt.x<=screen.monitors[i].left+screen.monitors[i].width) then
      begin
        if screen.monitors[i].left=0 then //this is the main window
            break;
        r:=Screen.Monitors[i].boundsRect;
        break;
      end;
  end;
 
popUp.left:=pt.x-r.Left;
popUp.y:=pt.y-r.Top;


It works as expected on the main monitor , but when on a monitor to the right of the main monitor the top position is almost ok (sometimes), but the left position is much too far to the right.
John Treder

Posts: 349
Registered: 8/2/02
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 28, 2018 4:43 PM   in response to: Mark Williams in response to: Mark Williams
Mark Williams wrote:

I am trying to work out how to position a pop up form (which is contained in a component) in a multi monitor set up.

It need to pop up relative to the mouse position.
Mouse.CursorPos gives you the coodinates of the mouse on a single imaginary screen from left of the leftmost monitor to right of the rightmost monitor and top of the topmost monitor to bottom of the bottmmost monitor.
You may want to use ScreenToClient to pop up relative to some component.

--
Tredmill
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 5, 2018 11:00 AM   in response to: John Treder in response to: John Treder
John,

Hi!

--

Q -- XanaNews 1.20-0cfde51 - 2018-02-05 11:00:22

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
John Treder

Posts: 349
Registered: 8/2/02
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 5, 2018 5:25 PM   in response to: Quentin Correll in response to: Quentin Correll
Quentin Correll wrote:

John,

Hi!

Happy New Year!

--
don't Tred on me
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 6, 2018 11:07 AM   in response to: John Treder in response to: John Treder
John,

| Happy New Year!

Ditto to you!

--

Q -- XanaNews 1.20-0cfde51 - 2018-02-06 11:06:55

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
John Treder

Posts: 349
Registered: 8/2/02
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 6, 2018 9:19 AM   in response to: Quentin Correll in response to: Quentin Correll
Quentin Correll wrote:

John,

Hi!

Happy New Year!

--
don't Tred on me
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 6, 2018 11:08 AM   in response to: John Treder in response to: John Treder
John,

| Happy New Year!

Ditto again. <giggle>

--

Q -- XanaNews 1.20-0cfde51 - 2018-02-06 11:07:31

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2018 10:47 AM   in response to: Mark Williams in response to: Mark Williams
Mark Williams wrote:

I am trying to work out how to position a pop up form (which is
contained in a component) in a multi monitor set up.

The position of the mouse cursor is reported in screen coordinates
relative to the Virtual Screen:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd145136.aspx

Top-level windows are also positioned in screen coordinates relative to
the Virtual Screen.

So, what is the problem? Just position your Form at the current mouse
coordinates, no weird calculations are needed:

pt := Mouse.CursorPos;
popUp.Left := pt.X;
popUp.Top := pt.Y;


It need to pop up relative to the mouse position.

So, then just do so. What is stopping you?

I pass through the mouse cursorpos to the component and then try the
following within the component code to position the form:

You don't need that logic at all.

But, if you do need to figure out which monitor a given screen
coordinate falls in, I would suggest an alternative approach:

for i := 0 to screen.MonitorCount-1 do
begin    
  r := Screen.Monitors[i].BoundsRect;
  if PtInRect(r, pt) then
  begin
    ...
    Break;
  end;
end;


Or:

hMonitor := MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
for i := 0 to screen.MonitorCount-1 do
begin    
  if Screen.Monitors[i].Handle = hMonitor then
  begin
    ...
    Break;
  end;
end;


Or:

Monitor := Screen.MonitorFromPoint(pt);
...


--
Remy Lebeau (TeamB)
Mark Williams

Posts: 120
Registered: 5/8/10
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2018 12:51 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:


So, what is the problem? Just position your Form at the current mouse
coordinates, no weird calculations are needed:

I have changed code as follows in the calling form

pt:=Mouse.CursorPos;
  popup.left:=pt.x;
  popup.top:=pt.y;


It seems to work ok on main screen. And on the screen to the right, top position seems okay but left is way off. The popup form is popping up to the far right of the calling form rather than a quarter way inside it's left border.

On the right screen I get the following readouts:

Calling form's left =2314
Mouse.CursorPos.x=2513, which is about quarter way in from left of the calling form.

I have checked the left property of the popup form after call to show and it is 2513 as you would expect yet it is far too far to the right.

I have the feeling I am still missing something!

The mouse is positioned about quarter way into the

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2018 1:28 PM   in response to: Mark Williams in response to: Mark Williams
Mark Williams wrote:
I have changed code as follows in the calling form

pt:=Mouse.CursorPos;
  popup.left:=pt.x;
  popup.top:=pt.y;


It seems to work ok on main screen. And on the screen to the right,
top position seems okay but left is way off. The popup form is
popping up to the far right of the calling form rather than a quarter
way inside it's left border.

Makes sense, if you don't take into account which monitor you are
displaying on. Remember, the Form's Left/Top properties represent the
upper-left corner of the window. When the X,Y coordinates are on a
monitor that is to the left, or above, the main monitor, you may have
to reduce the X,Y coordinate values to account for the Form's
Width/Height so the Form can be shown fully visible on that monitor.

Also, since you are explicitly setting the popup Form's Left/Top
properties, make sure its Position property is set to poDesigned. The
calling Form's current position should not have an effect on the
positioning of the popup Form.

--
Remy Lebeau (TeamB)
Mark Williams

Posts: 120
Registered: 5/8/10
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2018 1:40 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

Makes sense, if you don't take into account which monitor you are
displaying on. Remember, the Form's Left/Top properties represent the
upper-left corner of the window.

But this is on a monitor to the right. What should I be taking into account to position the popup form correctly on a monitor to the right of the main monitor?

When the X,Y coordinates are on a
monitor that is to the left, or above, the main monitor, you may have
to reduce the X,Y coordinate values to account for the Form's
Width/Height so the Form can be shown fully visible on that monitor.

Not sure which form you mean. The calling form or the popup form? How do I account for whichever form it is? Is it simply a case where the secondary monitor is above the main monitor of deducting the form's entire height? Ditto if it is to the left?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 29, 2018 3:45 PM   in response to: Mark Williams in response to: Mark Williams
Mark Williams wrote:

But this is on a monitor to the right. What should I be taking into
account to position the popup form correctly on a monitor to the
right of the main monitor?

Nothing really, it should "just work". Unless, of course, the mouse is
near the far edge of the monitor, and there is not another monitor past
that edge. Then you might want to adjust the coordinates so the popup
doesn't get obscured in limbo.

When the X,Y coordinates are on a monitor that is to the left, or
above, the main monitor, you may have to reduce the X,Y coordinate
values to account for the Form's Width/Height so the Form can be
shown fully visible on that monitor.

Not sure which form you mean. The calling form or the popup form?

The popup Form, the one you are trying to display.

How do I account for whichever form it is? Is it simply a case where
the secondary monitor is above the main monitor of deducting the
form's entire height? Ditto if it is to the left?

Try something like this:

var
  pt: TPoint;
  r: TRect;
begin
  pt := ...;
  r := Screen.MonitorFromPoint(pt).BoundsRect;
 
  if (pt.X + popUp.Width) > r.Right then
    Dec(pt.X, popUp.Width);
 
  if (pt.Y + popUp.Height) > r.Bottom then
    Dec(pt.Y, popUp.Height);
 
  popUp.Left := pt.X;
  popUp.Top := pt.Y;
end;


--
Remy Lebeau (TeamB)
Mark Williams

Posts: 120
Registered: 5/8/10
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 2:40 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

Nothing really, it should "just work".
A clean test with a simple form works fine so there is a specific problem with my component. Though I can't for the life of me figure out why. The popup form's left and width positions are correct when read after the form is shown, but it is definitely in the wrong place. But evidently there is something else in my code affecting this.

Try something like this:

var
  pt: TPoint;
  r: TRect;
begin
  pt := ...;
  r := Screen.MonitorFromPoint(pt).BoundsRect;
 
  if (pt.X + popUp.Width) > r.Right then
    Dec(pt.X, popUp.Width);
 
  if (pt.Y + popUp.Height) > r.Bottom then
    Dec(pt.Y, popUp.Height);
 
  popUp.Left := pt.X;
  popUp.Top := pt.Y;
end;

Thanks.
Mark Williams

Posts: 120
Registered: 5/8/10
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 3:23 AM   in response to: Mark Williams in response to: Mark Williams
I have solved the issue although I don't understand why it was an issue.

The popup form was created using CreateNew procedure.

Immediately after creating the form I set its border style to BSNone. The I created various components on the form before calling show. Moving the borderstyle:=bsNone to immediately before the call to show, all works as expected, but no idea why the borderstyle should effect the position of the form!
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 10:58 AM   in response to: Mark Williams in response to: Mark Williams
Mark Williams wrote:

I am trying to work out how to position a pop up form (which is
contained in a component) in a multi monitor set up.

It need to pop up relative to the mouse position.

I pass through the mouse cursorpos to the component and then try the
following within the component code to position the form:

Set the form's DefaultMonitor property to dmDesktop, this way the form
position is relative to the virtual screen (the union of all monitors),
like the mouse position Mouse.Cursorpos gives you. No weird calculation
needed this way.

for i:=0 to screen.MonitorCount-1 do
  begin    
    if (pt.x>=screen.monitors[i].left)
    and (pt.x<=screen.monitors[i].left+screen.monitors[i].width) then
      begin
        if screen.monitors[i].left=0 then //this is the main window
            break;
        r:=Screen.Monitors[i].boundsRect;
        break;
      end;
  end;
 
popUp.left:=pt.x-r.Left;
popUp.y:=pt.y-r.Top;


It works as expected on the main monitor , but when on a monitor to
the right of the main monitor the top position is almost ok
(sometimes), but the left position is much too far to the right.


--
Peter Below
TeamB

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Multi-Monitor Positioning  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 30, 2018 11:13 AM   in response to: Peter Below in response to: Peter Below
Peter Below wrote:

Set the form's DefaultMonitor property to dmDesktop, this way the
form position is relative to the virtual screen (the union of all
monitors), like the mouse position Mouse.Cursorpos gives you.

Good point.

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02