Dziwne zachowanie się aplikacji w trybie pełnoekranowym

Odpowiedz Nowy wątek
2019-02-23 12:31
Moderator Kariera

Rejestracja: 2 lata temu

Ostatnio: 1 dzień temu

Lokalizacja: Poznań

0

Podczas zabawy/testów zauważyłem pewne dziwne/nietypowe zachowanie. Aby to zweryfikować, stworzyłem specjalną aplikację testową, której cały kod sprowadzał się do obsługi OnCreate w następujący sposób:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.FormStyle:= fsStayOnTop;
  Form1.BorderStyle:= bsNone;
  Form1.Left:= 0;
  Form1.Top:= 0;
  Form1.Width:= Screen.Width;
  Form1.Height:= Screen.Height;
end;

Jak można się domyślić - powyższy kod ma zmienić ustawienia okienka tak, aby było ono bez obramowania, miało wielkość całego ekranu, a do tego pozostawało zawsze na wierzchu, czyli nawet przy próbie przełączenia się (chociażby przez Alt+Tab) na inną aplikację moja była nadal widoczna.

Teraz dziwne zachowanie, które udało mi się stwierdzić:

  • aplikacja skompilowana w Lazarus 2.0 64-bit na Win10: mogę przełączać się na inne aplikacje, ten fsStayOnTop jakby nie ma zastosowania
  • aplikacja skompilowana w Delphi 10.2: działa poprawnie na Win10 oraz WinXP
  • aplikacja skompilowana na Lazarus 2.0 32-bit: Win10 oraz WinXP ten sam objaw, pozostawienie okna na wierzchu nie działa.

Czy macie jakieś pomysły, o co tu chodzi? Podejrzewam, że to jakaś głupota, ale czasami człowiek tak ma, że się zafiksuje na jakiś tok myślenia i cięzko z niego wyskoczyć/spojrzeć na sprawę pod innym kątem ;)


Naczelny forumowy hejter Apple

That game of life is hard to play, I'm gonna lose it anyway
The losing card I'll someday lay, So this is all I have to say

Pozostało 580 znaków

2019-02-23 12:40

Rejestracja: 17 lat temu

Ostatnio: 1 godzina temu

4

w lazarusie użyj FormStyle:=fsSystemStayOnTop; i będzie ok


pozdrawiam
paweld

Pozostało 580 znaków

2019-02-23 12:42

Rejestracja: 14 lat temu

Ostatnio: 4 minuty temu

Lokalizacja: Gorlice

2

A próbowałeś fsSystemStayOnTop?


Nie odpowiadam na PW w sprawie pomocy programistycznej.
Pytania zadawaj na forum, bo:
od tego ono jest ;) | celowo nie zawracasz gitary | przeczyta to więcej osób a więc większe szanse że ktoś pomoże.
Pokaż pozostałe 2 komentarze
i pomyśleć, że wystarczyłoby enum. i wyskoczyłyby możliwe opcje, a i nieskończone prefixy w nazwie nie byłyby potrzebne - spartanPAGE 2019-02-23 14:10
@spartanPAGE ech może zobacz deklarację http://docs.embarcadero.com/p[...]clwin32/Forms_TFormStyle.html (w Delphi nie ma fsSystemStayOnTop) - kAzek 2019-02-23 14:16
@spartanPAGE: kiedyś byłeś normalny, a od jakiegoś czasu zachowujesz się dziwnie – wyczuwam jakiś nienaturalny ból tyłka połączony z zapędami do trollowania. Uspokoisz się sam, czy mam ci pomóc? - furious programming 2019-02-23 16:28
@furious programming: nie ma problemu, zostawię waszą garstkę w spokoju - spartanPAGE 2019-02-23 19:20
Będę wdzięczny. - furious programming 2019-02-23 19:25

Pozostało 580 znaków

2019-02-23 12:57

Rejestracja: 5 lat temu

Ostatnio: 4 godziny temu

Lokalizacja: Warszawa

1

Nie znam się na Lazarusie, ale znalazłem coś takiego: http://wiki.freepascal.org/La[...].30_release_notes#LCL_Changes
I cytat:

TCustomForm.FormStyle added fsSystemStayOnTop.Meaning is same as with fsStayOnTop except that fsStayOnTop is form on app top, so when application deactivates fsStayOnTop is not on top of other application(s), fsSystemStayOnTop is always on top.

Przyznam, że ten cytat jest dla mnie niejasny, ale ostatecznie wydaje się wprowadzać jakąś różnicę, więc może coś pomoże jako ukonkretnienie uogólnienie tego, co @Paweł Dmitruk oraz @kAzek napisali.


edytowany 3x, ostatnio: Silv, 2019-02-23 13:47
nie ma nic niejasnego, fsStayOnTop - formatka na wierzchu tylko dla aplikacji (przydatne przy aplikacjach "wielookienkowych"), a fsSystemStayOnTop - formatka na wierzchu dla całego systemu - Paweł Dmitruk 2019-02-23 14:13
@Paweł Dmitruk: dziękuję, cytat po prostu jest (był) zbyt condensed dla mnie. :) - Silv 2019-02-23 14:27

Pozostało 580 znaków

2019-02-23 15:46
Moderator Kariera

Rejestracja: 2 lata temu

Ostatnio: 1 dzień temu

Lokalizacja: Poznań

0

Dopiero wieczorem będę mógł sprawdzić, ale o ile mnie pamięć nie myli, to "systemOnTop" też robiłem i dawało taki sam efekt (a właściwie jego brak). Tylko nie pamiętam, czy to ustawiałem z poziomu kodu, czy inspektora.

Taka ciekawostka - do zauważenia tego efektu doszło, gdy robiłem śledztwo w sprawie niedzialajacego na Linuksie "ShowModal". Za to "fsStayOnTop" tam działało bez zarzutów... Grrrr ;)


Naczelny forumowy hejter Apple

That game of life is hard to play, I'm gonna lose it anyway
The losing card I'll someday lay, So this is all I have to say

Pozostało 580 znaków

2019-02-23 16:22
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 4 godziny temu

Lokalizacja: Tuchów

3
cerrato napisał(a):

Jak można się domyślić - powyższy kod ma zmienić ustawienia okienka tak, aby było ono bez obramowania, miało wielkość całego ekranu, a do tego pozostawało zawsze na wierzchu, czyli nawet przy próbie przełączenia się (chociażby przez Alt+Tab) na inną aplikację moja była nadal widoczna.

Pamiętaj tylko, że czego byś nie zrobił, to i tak nie ma możliwości utrzymania okna aplikacji zawsze na wierzchu. Systemowe okienka, takie jak np. menedżera zadań czy tooltipy z paska zadań zawsze będą wyświetlane ponad oknem Twojego programu. No i jeśli inna aplikacja też ma ustawiony taki sam enum (fsSystemStayOnTop), to najprawdopodobniej też będzie mogła wskoczyć na wierzch.

Dodam jeszcze, że jeśli ktoś potrzebuje stworzyć okno w taki sposób, aby było rozciągnięte na pełen ekran i jedynie przykrywało systemowy pasek zadań, to nie trzeba zmieniać właściwości FormStyle. Wystarczy domyślny fsNormal, bo system pozwoli formularzowi wskoczyć nad pasek zadań. Ale to tylko w przypadku, gdy okno nie ma obramowania – to podstawowy warunek.

Jak można się domyślić - powyższy kod ma zmienić ustawienia okienka tak, aby było ono bez obramowania, miało wielkość całego ekranu […]

Za dużo tego kodu – BorderStyle i FormStyle ustaw w oknie inspektora obiektów, a w konstruktorze wpisz to:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Form1.BoundsRect := Screen.PrimaryMonitor.BoundsRect;
end;

Jeśli potrzebujesz wyświetlić okno na innym ekranie, też dopasowane do jego krawędzi, to skorzystaj z właściwości Screen.Monitors, wybierz który chcesz i ustaw obszar w ten sam sposób.

Głównie dla wygody (mniej kodu do pisania), ale też w celu uniknięcia możliwego jego migania – ustawia się pozycję i wymiary raz, a nie cztery razy, tak jak w przykładzie który podałeś. ;)


edytowany 4x, ostatnio: furious programming, 2019-02-23 16:26

Pozostało 580 znaków

2019-02-23 18:49

Rejestracja: 1 rok temu

Ostatnio: 11 godzin temu

2

Atrybut okna "bycie na wierzchu" jest rozszerzonym stylem okna WS_EX_TOPMOST (teoretycznie do ustawienia za pomocą SetWindowLong z parametrem GWL_EXSTYLE).

Ale nie należy tego stylu ustawiać "ręcznie". Za wyświetlanie okna na pierwszym planie odpowiedzialna jest funkcja API SetWindowPos
https://docs.microsoft.com/en[...]nuser/nf-winuser-setwindowpos

Pierwszym parametrem jest uchwyt okna, na którym chcemy wykonać operację.
Drugi parametr - to jest to co nas interesuje.
Jeśli jako drugi parametr jest HWND_TOPMOST, to okno będzie zawsze na wierzchu (pod warunkiem, że ostatni parametr nie będzie zawierał flagi SWP_NOZORDER).

Okno, dla którego wykonamy tę funkcję przykryje wszystkie inne okna (nawet systemowego Menedżera).
Jeśli funkcję wykonamy na dwóch lub więcej oknach, to te okna względem siebie działają tak, jakby tego atrybutu nie miały, natomiast względem innych będą zawsze na wierzchu.

Aby okno przestało być na wierzchu trzeba wykonać funkcję SetWindowPos z drugim parametrem HWND_NOTOPMOST.

Funkcja tez umożliwia ustawienie okna na dowolnym planie. Jako drugi parametr należy wtedy podać uchwyt okna względem którego chcemy ustawić nasze okno.

Tak to działa w API. Nie wiem jakich modyfikacji działania funkcji systemowych dokonuje ten program, w którym działacie.

Aby zmienić pozycję wielu okien bez migotania należy użyć funkcji DeferWindowPos:
https://docs.microsoft.com/en[...]ser/nf-winuser-deferwindowpos


Rzuć okiem na mój ostatni post - 2 piętra niżej. Wszystko tam jest wyjaśnione. A co do tego o czym piszesz - wszystko to wiem, ale ponieważ dla mnie ważna jest multilpatformowość (i głównie dlatego piszę w Lazarusie, a nie Delphi), nie używam rozwiązań stricte związanych z konkretnym systemem. W tej chwili np. piszę aplikację na Linuksie, ale docelowo dla klienta ma ona chodzić na Windows. Wszystkie WinAPI i pokrewne rzeczy odpadają, działam jedynie w ramach tego, co LCL oferuje, żadnych hacków i tricków z komunikatami itp. - cerrato 2019-02-24 22:50

Pozostało 580 znaków

2019-02-23 19:06
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 4 godziny temu

Lokalizacja: Tuchów

0

Jeśli chodzi o zmianę pozycji czy z-order okna podczas działania programu to tak – można się wspomóc funkcjami API systemu. Chyba że piszemy apkę multiplatformową, to wtedy korzystamy z wrapperów z modułu LCLIntf, bo ich działanie zależne jest od platformy.

Natomiast jeśli mowa o początkowych ustawieniach formularza, to fsSystemStayOnTop jest tutaj odpowiedni.


Pozostało 580 znaków

2019-02-24 22:32
Moderator Kariera

Rejestracja: 2 lata temu

Ostatnio: 1 dzień temu

Lokalizacja: Poznań

Tak, jak podejrzewałem - chodziło o jakąś głupotę. W sumie to aż mi wstyd się przyznać, ale przyzwoitość względem osób, które brały udział w wątku nakazuje coś napisać na zakończenie ;)

W Lazarusie jest (jak pisaliście w postach, o czym zresztą także wiedziałem) poza fsStayOnTop jeszcze fsSystemStayOnTop. Kiedy pierwsza opcja nie działała, przełączyłem na drugą, ale nie zauważyłem różnicy. Tak jest, jak się człowiek spieszy, żona popędza bo zaraz musimy wychodzić. Wiecie, co odwaliłem? Przełączyłem na systemOnTop w inspektorze, ale jednocześnie nie wywaliłem Form1.FormStyle:= fsStayOnTop; z procedury OnCreate... Nie muszę chyba dodawać, jaki był tego efekt ;) Gdy do tematu usiadłem później, na spokojnie i na świeżo spojrzałem to od razu zauważyłem, w czym był problem. Lekko żenująca wpadka, przepraszam Was za zawracanie głowy :(


Naczelny forumowy hejter Apple

That game of life is hard to play, I'm gonna lose it anyway
The losing card I'll someday lay, So this is all I have to say
Pokaż pozostałe 2 komentarze
Nie określiłbym siebie tak, ciekawią mnie różne rzeczy i różne języki. Szkoda, że tak dużo ich jest. :( Ale wątki pomagają w poznaniu każdego po troszeczku. - Silv 2019-02-24 22:44
Ale co racja, to racja, że C++ był tym językiem, przy którym uczyłem się, co to jest funkcja, klasa i tak dalej. - Silv 2019-02-24 22:45
odnośnie określania Cię jako "plusowicza" - opierałem sie na tym: https://4programmers.net/Profile/64311/Post - cerrato 2019-02-24 22:45
"co to jest funkcja" - widzisz, w tym biednym C masz funkcje, a w Pascalu i funkcje i procedury. Od razu widać, że to lepszy język :D - cerrato 2019-02-24 22:46
A nie, przepraszam, jeszcze przed C++ był Pascal, racja. Ale to tak na mniej poważnie. - Silv 2019-02-24 22:47

Pozostało 580 znaków

Odpowiedz

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