2016-03-18 2 views
3

У меня есть Delphi 7 основную форму с кнопкой «открыть», который открывает другую форму, так же, как это:Многоканальный - Открыть окно приложения на мониторе, где курсор мыши находится

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

На frmPswd OnCreate событие я пытаюсь централизовать его, в зависимости от монитора, где находится курсор мыши, как это:

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; 

Когда основной формой находится в том же мониторе, как курсор мыши, frmPswd форма открывается, как и следовало ожидать, в центр этого монитора. Но когда основная форма находится на мониторе, отличном от мыши, frmPswd появляется в странной позиции, я не могу понять, почему.

EDIT:

Вот результаты, как просили Реми Лебо, даже с новым кодом:

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 
+2

Различный монитор, вероятно, не в точке (0, 0), добавить его смещение. Таким образом form.left = monitor.left + ..... –

+0

Кстати, мы не рекомендуем использовать мышь в качестве определяющего фактора для размещения формы. Вы можете запустить свою программу, используя клавиатуру из ее ярлыка на главном мониторе, а затем задаться вопросом, куда ушла форма входа в систему. –

+0

@SertacAkyuz, спасибо, что ответили. Вы правы, второй верхний левый монитор - нет (0, 0). но при выполнении frmPswd.Left: = Monitor.Left + Round ((Monitor.Width - frmPswd.Width)/2) У меня такая же проблема :( – Guybrush

ответ

3

Вы не должны использовать Application.CreateForm() как это. Вместо этого используйте TfrmPswd.Create(). И используйте Free() вместо Release().

Избавьтесь от звонков Application.NormalizeTopMosts() и Application.ProcessMessages(), они не принадлежат к этому коду вообще.

В вашем мероприятии OnCreate используйте Self вместо глобальной переменной frmPswd.

И вам нужно добавить Monitor.Left и Monitor.Top коррекций к новым координатам, чтобы учесть мониторы, которые не делают ни начала со смещением 0,0 из Virtual Screen.

Попробуйте что-то больше, как это:

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; 
+0

спасибо! Я сделаю тесты! Btw, я отредактировал вопрос с результатами позиции моих тестов ... – Guybrush

+0

К сожалению, у меня такие же результаты с Self, а не с frmPswd :(Кстати, результаты, которые я включил в вопрос, уже используют Monitor.Left + ... и Monitor .Top + ... Пожалуйста, любая другая идея? – Guybrush

+0

'Mouse.CursorPos' использует функцию Win32' GetCursorPos() ', на которую влияют проблемы с DPI и LargeAddress. Попробуйте использовать Win32' GetCursorInfo() 'или' GetPhysicalCursorPos () 'функции вместо этого. –

Смежные вопросы