Rozdzielczość ekranu i DPI (bez użycia TScreen)

0

Mam aplikację, która nie używa form (bez GUI, nie używam klasy TForm). Program ma za zadanie odpalić inny program, wykonać kilka akcji i zamknąć się po zamknięciu uruchomionej aplikacji. Niestety, w takim przypadku nie mam dostępu do klasy TScreen, która pozwala w prosty i szybki sposób pobrać informacje o ekranie, rozdzielczości oraz DPI.

Używając klasę TScreen jest to proste i szybkie.
Przykład:

var
   i : integer;
   MyMonitor : TMonitor;
begin
   Memo1.Lines.Clear;
   for i:= 0 to Screen.MonitorCount-1 do
      begin
         Memo1.Lines.Add('MONITOR: ' + inttostr(i));
         Memo1.Lines.Add(#9 + 'Pixels Per Inch: ' + inttostr(Screen.Monitors[i].PixelsPerInch));

         Memo1.Lines.Add(#9 + 'Monitor Handle: ' + inttostr(Screen.Monitors[i].Handle));
         Memo1.Lines.Add(#9 + 'Monitor Number: ' + inttostr(Screen.Monitors[i].MonitorNum));

         Memo1.Lines.Add(#9 + 'Left: ' + inttostr(Screen.Monitors[i].Left));
         Memo1.Lines.Add(#9 + 'Top: ' + inttostr(Screen.Monitors[i].Top));

         Memo1.Lines.Add(#9 + 'Width: ' + inttostr(Screen.Monitors[i].Width));
         Memo1.Lines.Add(#9 + 'Height: ' + inttostr(Screen.Monitors[i].Height));

         Memo1.Lines.Add(#9 + 'BoundsRect Width: ' + inttostr(Screen.Monitors[i].BoundsRect.Width));
         Memo1.Lines.Add(#9 + 'BoundsRect Height: ' + inttostr(Screen.Monitors[i].BoundsRect.Height));

         Memo1.Lines.Add(#9 + 'BoundsRect Left: ' + inttostr(Screen.Monitors[i].BoundsRect.Left));
         Memo1.Lines.Add(#9 + 'BoundsRect Top: ' + inttostr(Screen.Monitors[i].BoundsRect.Top));
         Memo1.Lines.Add(#9 + 'BoundsRect Right: ' + inttostr(Screen.Monitors[i].BoundsRect.Right));
         Memo1.Lines.Add(#9 + 'BoundsRect Bottom: ' + inttostr(Screen.Monitors[i].BoundsRect.Bottom));


         Memo1.Lines.Add(#9 + 'WorkareaRect Width: ' + inttostr(Screen.Monitors[i].WorkareaRect.Width));
         Memo1.Lines.Add(#9 + 'WorkareaRect Height: ' + inttostr(Screen.Monitors[i].WorkareaRect.Height));
         Memo1.Lines.Add(#9 + 'WorkareaRect Left: ' + inttostr(Screen.Monitors[i].WorkareaRect.Left));
         Memo1.Lines.Add(#9 + 'WorkareaRect Top: ' + inttostr(Screen.Monitors[i].WorkareaRect.Top));
         Memo1.Lines.Add(#9 + 'WorkareaRect Right: ' + inttostr(Screen.Monitors[i].WorkareaRect.Right));
         Memo1.Lines.Add(#9 + 'WorkareaRect Bottom: ' + inttostr(Screen.Monitors[i].WorkareaRect.Bottom));

         Memo1.Lines.Add('');

         MyMonitor :=Screen.MonitorFromWindow(Self.Handle);
         Memo1.Lines.Add(#9 + 'Current Monitor: ' + inttostr(MyMonitor.MonitorNum));
      end;
end;

Pytanie, za 100 punktów, jak pobrać informacje jak powyżej (bieżąca rozdzielczość oraz DPI monitora(ów), monitor na którym odpalona jest dana aplikacja)?
Jakoś nie mogę znaleźć w miarę prostego rozwiązania...

Ps: Nie chcę używać WMI, przy użyciu którego to nie problem.
Ps: W ostateczności mógłbym dodać TForm do programu i ukryć formatkę, ale zwiększa to drastycznie rozmiar programu i jest bez sensu... a to ma być tylko program uruchamiający i ustawiający kilka parametrów (launcher).
-Pawel

0

przeczytaj to z rejestru

1
Pepe napisał(a):

Pytanie, za 100 punktów, jak pobrać informacje jak powyżej (bieżąca rozdzielczość oraz DPI monitora(ów), monitor na którym odpalona jest dana aplikacja)?
Jakoś nie mogę znaleźć w miarę prostego rozwiązania...

Ale ty tak poważnie się pytasz?

Ps: Nie chcę używać WMI, przy użyciu którego to nie problem.

Dlaczego nie?

Ps: W ostateczności mógłbym dodać TForm do programu i ukryć formatkę, ale zwiększa to drastycznie rozmiar programu i jest bez sensu...

Fakt, to jest totalnie bez sensu.
Mój serdeczny kolega miał na takie rozwiązania jedno określenie: wiązania krawata przez gardło trzymając rękę w dupie.

a to ma być tylko program uruchamiający i ustawiający kilka parametrów (launcher).

Skoro nie chcesz użyć WMI (i nie rozumiem dlaczego) to użyj WinAPI; dwie funkcje powinny rozwiązać twój problem: GetSystemMetrics oraz GetSystemMetricsForDpi

Poza tym, ja mam trzy monitory.
A kolega ma 2 monitory, ale z różnymi rozdzielczościami i różnymi DPI.
Wziąłeś to pod uwagę?

0

@robertz68
Uhm, mam to na uwadze. Thx.

@wloochacz

  • Tak, na poważnie. Rozważam możliwe rozwiązania. Do implementacji daleka droga.
  • Z moich doświadczeń z WMI wychodzi, że nie każdy system ma WMI. Nie każda funkcja jest dostępna. Inicjalizacja trwa za długo (może coś źle robię). Zatem wolę inne prostsze rozwiązanie. Kluczem tutaj jest prostota.
  • Bardzo ładna analogia :P
  • GetSystemMetrics ładnie zwraca wyniki...
  • Muszę obadać jeszcze GetSystemMetricsForDpi

Tak, mam na uwadze różne monitory, każdy z nich może mieć różną rozdzielczość i DPI. Sprawa nie wydaje się być banalna. Dlatego podpytuje na forum. Thx.
-Pawel

0
Pepe napisał(a):

Mam aplikację, która nie używa form (bez GUI, nie używam klasy TForm).
[…]
Ps: W ostateczności mógłbym dodać TForm do programu i ukryć formatkę […]

Eeee coooo? :/

Przecież obiekt Screen nie ma nic wspólnego z formularzami. Możesz ręcznie dopisać moduł Forms do uses i mieć do niego dostęp, w dalszym ciagu nie mając w ogóle żadnych formularzy w projekcie. Kombinujesz niepotrzebnie.

0

Hmm, tak to się chyba nie da...
Musiałbym dodać jakiś fakeowy formularz... no i problemem jest to, że nawet jakby się udało, to doda mi od groma nadmiarowego kodu, który zwiększy rozmiar exe pewnie o 2 MB...

Edit: Dokładnie. Było 2.1MB, po dodaniu 1 formularza (taki od picu), jest 4MB...
Edit2: Dodanie formularza nie jest potrzebne. Musiałem dodać framework VCL (chyba usunąłem kiedyś). Problemem jedynym jest rozmiar.... Może jednak muszę z tym żyć.

0

Przecież napisałem wyraźnie – dodaj do uses moduł Forms i nie twórz żadnych formularzy.

Obiekt Screen tworzony jest w sekcji initialization modułu Forms, a więc jego działanie jest niezależne od formularzy. Możesz z niego korzystać nawet w aplikacji konsolowej, a nawet w programie-usłudze.

0

Lazarusa NIE da się używać na poważnie? No kurczę, nie wiedziałem... Jutro w robocie powyłączam urządzenia pod kontrolą programów zrobionych Laz...Straszne, straszne :)

0

@machinebyte4: na pewno kłamiesz – przecież się nie da niczego sensownego w tym zrobić. :]

A tak na poważnie – myślę, że tutaj nie chodzi o jakość czy funkcjonalność tworzonych aplikacji, a o jakość, stabilność i funkcjonalność środowiska, a także dostęp do wygodnych i funkcjonalnych narzędzi dla IDE oraz pakietów do wykorzystania w programach. Na tym polu Delphi od zawsze wygrywa i niejeden wieloletni programista Delphi jest w stanie podać masę przykładów.

To jednak w dalszym ciągu nie zmienia faktu, że z Lazarusem da się pracować bez większych problemów i tworzyć naprawdę świetny software. Co prawda jest to bardziej wnerwiająca praca, bo ileż można się użerać z designerem, code completion czy wyjątkami z d**y, no ale da się. Zresztą jak tak patrzę na wpisy z serii #visualstudiohate, to i tak Lazarus wypada całkiem nieźle.

A tak przy okazji – stabilne FPC 3.2.0 już ino ino. :d

0
machinebyte4 napisał(a):

Lazarusa NIE da się używać na poważnie?

Tak, dokładnie jest w moim przypadku.
Jak mi pokażesz DevExy, Spring4D oraz FireDAC (chociaż tu lepiej, bo mogę sobie zamienić na UniDAC, aczkolwiek to dalej w cholerę niepotrzebnej pracy i niepotrzebnych problemów) do Lazarusa to MOŻE zmienię zdanie.
Może...

Ale wróć; jednak nie.
To ichnie IDE to jakiś mało śmieszny żart. To że "może być podobne" oznacza tyle, że podobnie wygląda...
Coś co przypomina konia, nie oznacza że startuje w tej samej klasie i zwyczajnie dalej jest mułem.

IDE Delphi to w sumie też żart, ale Lazarus jest zdecydowanie mniej śmieszny.
I to jest niestety smutny fakt.

Był już taki wątek w 2017r i o ile w Delphi zmieniło się trochę i to na lepsze, to w Lazarusie co przepraszam?
Zresztą, proszę nie musisz odpowiadać , ponieważ w sumie mam gdzieś te "niesamowite możliwości" itd.
Na pewno nie użyję FPC/Lazarusa do niczego nowego, a jeśli już to raczej użyję .NET niż Delphi/FPC.

Zarówno Delphi i FPC (nawet bardziej) mają poważny problem z integrowaniem się z systemami klasy Enterprise.
Jeśli ktoś sobie pisze jakieś apki w zamkniętym sosie, mało skomplikowane desktopy do wystawiania faktur itp. to pewnie, może to działać z sukcesem.
W przypadku Lazarusa ten sukces będzie zależał dodatkowo od tego, jak dany twórca jest biegły w plemiennym slangu FPC/Lazarusa (dokumentacja do Delphi jest słaba, ale do FPC/Lazarusa praktycznie nie istnieje).
Jeśli ktoś pisze backend oparty na mORMocie i wszystko inne na webie, ale nie musi się integrować z obcym API typu SAP ERP, to pewnie nawet FPC da radę. Jako tako.
Ale to są jakieś wyjątki, a nie bezpieczny rozwój i utrzymanie systemów.

No kurczę, nie wiedziałem... Jutro w robocie powyłączam urządzenia pod kontrolą programów zrobionych Laz...Straszne, straszne :)

No to już wiesz, szkoda życia na kopanie się z koniem ;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1