Guybrush
Guybrush

Reputation: 1611

Multimonitor - Open the application window in the monitor where mouse cursor is located

I have a Delphi 7 main form with an "open" button, that opens another form, just like this:

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    Application.CreateForm(TfrmPswd, frmPswd);
    Application.NormalizeTopMosts;
    Application.ProcessMessages;
    frmPswd.ShowModal;
  finally
    frmPswd.Release;
    frmPswd := nil;
  end;
end;

On the frmPswd OnCreate event I am trying to centralize it, depending on monitor where mouse cursor is located, like this:

procedure TfrmPswd.FormCreate(Sender: TObject);
var
  Monitor: TMonitor;
begin
  Monitor := Screen.MonitorFromPoint(Mouse.CursorPos);
  frmPswd.Top := Round((Monitor.Height - frmPswd.Height) / 2);
  frmPswd.Left := Round((Monitor.Width - frmPswd.Width) / 2);
end;

When the main form is located in the same monitor as the mouse cursor, frmPswd form opens like expected, in the center of that monitor. But when the main form is in a monitor different from mouse, frmPswd appears in a strange position I can't understand why.

EDIT:

Here are the results as asked by Remy Lebeau, even with the new code:

Monitor := Screen.MonitorFromPoint(Mouse.CursorPos);
Self.Left := Monitor.Left + ((Monitor.Width - Self.Width) div 2);
Self.Top := Monitor.Top + ((Monitor.Height - Self.Height) div 2);

Monitor 0
Top: 0
Left: 0
Width: 1440
Height: 900

Monitor 1
Top: -180
Left: -1920
Width: 1920
Height: 1080

frmPswd.Width = 200
frmPswd.Height = 200

Main form in Monitor 0 and Mouse cursor in Monitor 0
frmPswd.Top = 350
frmPswd.Left = 620

Main form in Monitor 1 and Mouse cursor in Monitor 1
frmPswd.Top = 260
frmPswd.Left = -1060

Main form in Monitor 0 and Mouse cursor in Monitor 1
frmPswd.Top = 440
frmPswd.Left = 860

Main form in Monitor 1 and Mouse cursor in Monitor 0
frmPswd.Top = 170
frmPswd.Left = -1300

Upvotes: 4

Views: 1478

Answers (2)

Dhanushwaran P S
Dhanushwaran P S

Reputation: 1

This can be achieved with the help of Microsoft powertoys too. Were you will be given with an option to use active focus or mouse pointer under fancy zones.

Upvotes: -1

Remy Lebeau
Remy Lebeau

Reputation: 597215

You shouldn't be using Application.CreateForm() like this. Use TfrmPswd.Create() instead. And use Free() instead of Release().

Get rid of Application.NormalizeTopMosts() and Application.ProcessMessages() calls, they don't belong in this code at all.

In your OnCreate event, use Self instead of the global frmPswd variable.

And you need to add the Monitor.Left and Monitor.Top offsets to your new coordinates, to account for monitors that do no start at offset 0,0 of the Virtual Screen.

Try something more like this:

procedure TForm1.Button1Click(Sender: TObject);
var
  frm: TfrmPswd;
begin
  frm := TfrmPswd(nil);
  try
    frm.ShowModal;
  finally
    frm.Free;
  end;
end;

procedure TfrmPswd.FormCreate(Sender: TObject);
var
  Monitor: TMonitor;
begin
  Monitor := Screen.MonitorFromPoint(Mouse.CursorPos);
  Self.Left := Monitor.Left + ((Monitor.Width - Self.Width) div 2);
  Self.Top := Monitor.Top + ((Monitor.Height - Self.Height) div 2);
end;

Upvotes: 3

Related Questions