Положение формы на экране (FMX, Win32) - PullRequest
0 голосов
/ 11 декабря 2018

Я хочу знать, где находится моя форма на экране.Я смотрел на свойства позиции (например, this-> Top, this-> Left и т. Д.), Но они, кажется, не отвечают всем требованиям.Я хочу определить, как далеко находится моя форма от верхней / нижней части экрана и от левой / правой стороны экрана.

Я использую C ++ Builder и FMX для создания приложения Win32.

спасибо, русс

enter image description here

ОБНОВЛЕНИЕ 1: Оказывается, что мне действительно нужно найти эту координату (X, Y) относительнона весь рабочий стол, а не только на основной монитор.Рабочий стол охватывает несколько мониторов.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

На основе данных от Теда и Дэвида я собрал следующий код.Появится всплывающее сообщение, если левый край формы будет близок (в пределах errX пикселей) к левому краю рабочего стола.Появится всплывающее сообщение, если верхний край клиентской области форм находится близко (в пределах ошибочных пикселей) к верхнему краю рабочего стола.Не красиво, но показывает идею.

void __fastcall TForm1::Button4Click(TObject *Sender)
{

int dWidth = Screen->DesktopWidth;
int dLeft = Screen->DesktopLeft;
int dRight = dWidth + dRight;  // deskLeft is 0 if primary monitor is most left monitor
int dTop = Screen->DesktopTop;
int errX = 10;  // within 10 pixels is fine enough
int errY = 40; // remember 30 or so pixels for caption bar
TPointF cli(0.0, 0.0);
TPointF sp = ClientToScreen(cli); //sp holds the coordinates for top left of form client area
ShowMessage("X = " + FloatToStr(sp.x) + "\nY = " + FloatToStr(sp.y));  //show coordinates of top/left of form client area

if (dLeft < 0) {  //negative value
 if ((abs(dLeft)-abs(sp.x)) < errX) {
  ShowMessage("Within " + IntToStr(errX) + " pixels of left edge."); // or further left of edge
 }
}
else {
 if ((dLeft + sp.x)< errX) {
  ShowMessage("Within " + IntToStr(errX) + " pixels of left edge."); // or further left of edge
 }
}

if (sp.x > 0) {  // no need to test the negative case
 if ((dRight-sp.x) < errX) {
  ShowMessage("Within " + IntToStr(errX) + " pixels of right edge."); // or further right of edge
 }
}

if ((dTop + sp.y)< errY) {
 ShowMessage("Within " + IntToStr(errY) + " pixels of top edge.");
}

}

Этот код работает независимо от того, какой монитор является основным.

ОБНОВЛЕНИЕ 1: этот код имеет проблемы, когда мониторы не выровнены по верхнему краю,На картинке ниже мониторы 1 и 3 выровнены по вершинам.2 нет.В этом примере DesktopTop вернул -876.Таким образом, похоже, что совет Дэвида в отношении «Мониторов» - это путь - в C ++ это «Дисплеи».например, TRect myR = Screen->Displays[0].BoundsRect;, чтобы получить прямоугольник дисплея 0, а затем int theTop = myR.top;, чтобы найти верх этого конкретного дисплея.

enter image description here

спасибо, русс

0 голосов
/ 11 декабря 2018

Свойства ваших форм Top и Left должны указывать вам позицию относительно верхней левой позиции активных рабочих столов, но вам, возможно, придется также использовать ClientToScreen / ScreenToClient.Кажется, трудно получить точное смещение в FMX.

void __fastcall TForm1::MoveToTopLeft()
{
    TPointF cli(0.0, 0.0);
    TPointF sp = ClientToScreen(cli);

    Left -= sp.x;
    Top = 0;
}

В этом решении есть что-то очень асимметричное ...

...