Własny interfejs aplikacji – przegląd kontrolek i test działania

0

Przy każdym twoim demie (od czwartego wzwyż) wyskakuje mi coś takiego
avast.png

Pomijając rozważania czy avast jest dobry czy zły musisz wziąć to pod uwagę bo twoi klienci mogą używać avasta i raczej średnio byli by zadowoleni widząc taki komunikat.

Ach no i oczywiście kolejna próba odpalenia dema po tym komunikacie kończy się wyświetleniem "system nie może uzyskać dostępu bla bla bla, możesz nie mieć uprawnień bla bla bla"

Przy czym dopóki program działa w tym całym cybercapture to uruchamia się, ale nie zdążyłem przeczytać logów czy porobić screenów bo się wyłącza dość szybko, ale tak działa cybercapture, w każdym razie wszystko się wyświetla, tylko tak jak pisałem, nie zdążyłem obejrzeć dokładnie poprawności rysowania czcionek.

0

To ja poczekam te 176 minut na odpowiedź, bo sam jestem ciekaw co oni w tym pliku widzą podejrzanego. IMO najniebezpieczniejszy w tej aplikacji jest wrzosowy kolor interfejsu. :D

Edit: skan ostatniego załączonego dema jest tutajAvast, BitDefender, ESET, F-Secure, Kaspersky i inne z wyższej ligi nic nie zgłaszają. Sam plik zawiera wyłącznie trzy osadzone fonty i je instaluje przy rozruchu, to wszystko. Plik ten nie stanowi absolutnie żadnego zagrożenia. Heurystyka antywirusów daje popalić i niczego nie jestem w stanie z tym zrobić.

1

Nie wspominałem, ale przy każdej wersji Win10 wyświetla u mnie coś takiego:

a.png

0

@Azarien: a jak to wygląda w przypadku jałowej wersji (tej bez fontów i ich ładowania) z tego posta? Też system blokuje ten plik? Cholera… to jest jakiś obłęd…

Choć system może z automatu blokować wszystkie pliki „nieznanego wydawcy” – i na to wygląda, że to robi.

1

System windows 10 pokazuje to okienko przy obcych aplikacjach dla nieznanych wydawców, wymagany jest certyfikat uwierzytelniający. Jest kilka tego typu utrudnień.

1

Instaling embedded fonts:

font_oswald_light - stream created
font_oswald_light - handle: 201327130, count: 1
font_oswald_light - stream freed

font_ubuntu_regular - stream created
font_ubuntu_regular - handle: 218104347, count: 1
font_ubuntu_regular - stream freed

font_ubuntu_bold - stream created
font_ubuntu_bold - handle: 234881563, count: 1
font_ubuntu_bold - stream freed

i to wszystko co widać.

0

Czyli fonty instalują się prawidłowo – problem leży w tych dwóch linijkach:

Application.CreateForm(TMainForm, MainForm);
Application.Run();

TMainForm nie posiada żadnego kodu w OnCreate ani w OnShow, więc nie mam żadnego punktu zaczepienia. Nie lecą też wyjątki, bo wyskoczyłby lazarusowy komunikat z koniecznością kontynuacji lub ubicia procesu. Kosmos.

Uwielbiam Lazarusa. :D

0

może jednak naciskał ENTER. Nie ma ostatniego komunikatu o poprawnym zainstalowaniu czcionek.

0

Następna instrukcja to SendMessage rozgłaszający komunikat WM_FONTCHANGE.

Czyżby system udławił się tym komunikatem? Można to sprawdzić. ;)

1

A to po co skoro:

This function allows an application to get a font that is embedded in a document or a webpage. A font that is added by AddFontMemResourceEx is always private to the process that made the call and is not enumerable.

https://msdn.microsoft.com/en-us/library/windows/desktop/dd183325(v=vs.85).aspx
Ten komunikat wysyła się po dodaniu lub usunięciu czcionki innymi metodami (gdy jest dostępna dla innych aplikacji).

0

Wplotło się przy okazji testowania różnych demówek – kombinowałem na różne sposoby i co nieco zdążyłem namieszać (jak np. z kolejnością wykonywania kodu). We właściwym kodzie tego nie ma – tzn. jest, ale w metodzie ładującej fonty z zewnętrznych plików, dostarczonych wraz z aplikacją (która używa AddFontResource).

W każdym razie samo wysłanie komunikatu nie powinno w niczym przeszkadzać, ale zaraz podłubię jeszcze przy tej demówce i dołączę do załączników jeszcze jedną. Tym razem z pełną jej funkcjonalnością, ale bez warunku sprawdzającego czy fonty zostały prawidłowo zainstalowane, bo widzę, że i tak wszystkim instalują się prawidłowo.

Najważniejsze, że większości działa prawidłowo – spodziewałem się większych problemów. Na certyfikaty i walkę z antywirusami jeszcze stanowczo za wcześnie. ;)

0

No dobrze, poprawiłem wszystko co wymagało poprawienia. Dodałem trochę logów do konsoli na początku, w kluczowych miejscach – pierwsze info wyskakuje po załadowaniu fontów i czeka na Enter, następnie pojawia się info na temat ładowania głównej formy i czeka na Enter. Po wciśnięciu owego przycisku, odpalana jest metoda Application.Run.

Dłużej raczej nie będę gnębił tej demówki, bo to nie ma większego sensu. Konkretne testy wykonam jak już będę miał co testować – jeszcze wiele rzeczy mam do zrobienia. Natomiast ta demówka jest w sumie taka sama jak ta z pierwszego posta tego wątku, tyle że usunąłem zbędne instrukcje i ułożyłem je w odpowiedniej kolejności. U większości znów zadziała – u @_JarekZ nie wiem, oby. ;)

1

U mnie działa, dwa razy przed Enterem napisało, że jest OK. A potem wszystko się wyświetliło poprawnie.

1

teraz śmiga aż miło ;) ;)

0

To jeszcze pytanie do osób, które zgłaszały problemy z antywirusami - czy teraz program jest "czysty" czy nadal wzbudza zastrzeżenia pod względem bezpieczeństwa?

0
_JarekZ napisał(a):

teraz śmiga aż miło ;) ;)

meme

Wygląda na to, że to ten niepotrzebny SendMessage powodował problem. :D

cerrato napisał(a):

To jeszcze pytanie do osób, które zgłaszały problemy z antywirusami - czy teraz program jest "czysty" czy nadal wzbudza zastrzeżenia pod względem bezpieczeństwa?

Raczej nadal będzie to samo. Martwi mnie to, bo nawet jałowa demówka (nie ładująca fontów z zasobów i bez absolutnie żadnego kodu) była podejrzana dla AV (ale nie dla VirusTotal). Sam komunikat defendera o niezaufanej aplikacji jest oczywisty – demówka nie jest podpisana, a wydawca nieznany. Podobne okienko wyskakiwało nawet pod XP, tyle że w przypadku niepodpisanych sterowników. ;)

0

Skoro przyczyna problemu została zlokalizowana i naprawiona, usunąłem z demówki obsługę konsoli. Program działa już u wszystkich, na różnych wersjach Windows, co mnie bardzo cieszy. Zresztą, sam program nie robi niczego nadzwyczajnego, żaden komponent nie wymaga jakichś dodatków czy niestandardowych bibliotek, więc siłą rzeczy demówka musi działać wszędzie.

Co innego właściwy program – ten robi mnóstwo różnych rzeczy, związanych zarówno z przystosowaniem okna do bieżącej rozdzielczości, ale i z wyświetlaniem okien, ładowaniem danych z wielu binarek, rejestrowaniem uruchomień, ustawieniami i ogólnie plikami użytkownika itd., więc tam coś może pójść nie tak. Ale to już zupełnie inna liga.

No to fajnie – cieszę się z aktywności w tym wątku, dziękuję za sugestie i krytykę. Finalną wersję demówki dorzucam do załączników tego posta, a w razie gdyby ktoś kiedyś wpadł do tego wątku i chciał ją odpalić, podmienię też załącznik w pierwszym poście, tak aby nie trzeba było szukać tej ”ostatecznie działającej”. ;)

0

Korzystając z okazji – czy zauważyliście, że linia podkreślająca link po najechaniu nań kursorem, jest przerywana?

Dokładnie chodzi o te wielkie, formatowalne etykiety z nagłówkami i paragrafami. Póki co, podczas renderowania zawartości tych kontrolek, do malowania każdego kolorowego tekstu używam małego filtru, który lekko pogrubia tekst, aby był bardziej wyrazisty i bardziej rzucał się w oczy. Jeśli ten filtr wyłączę, to podkreślenie aktywnego linku jest przerywane. Dzieje się tak dlatego, że każde słowo w etykiecie malowane jest z osobna, wykorzystując standardowe podkreślenie.

Z włączonym filtrem wygląda to tak:

filter-on.png

a z wyłączonym tak:

filter-off.png

Ktoś coś takiego zauważył? W demówce filtr jest włączony i włączony będzie również w głównej apce, jednak mimo wszystko chciałbym wiedzieć, czy u kogoś jest z tym problem. W razie czego zrezygnuję ze standardowego podkreślenia i linie rysować będę ręcznie.

1

screenshot-20180306163717.png

Czy o to Ci chodzi? Bo szczerze mówiąc nie do końca rozumiem, o co pytasz.
Screen jest zrobiony na Win10 64bit. Kursor myszy jest na linku (ale print screen go nie pokazał).

Przy okazji - demo się odpaliło natychmiast, nie było żadnych problemów, antywirus F-secure nie miał zastrzeżeń do pliku.
Jedyne co to dziwnie się wyświetla ikona aplikacji - albo właściwie jej brak. Tak ma być, czy coś nawaliło?
screenshot-20180306163918.png

0
cerrato napisał(a):

Czy o to Ci chodzi? Bo szczerze mówiąc nie do końca rozumiem, o co pytasz.

Chodzi o duże etykiety. Dodałem zrzuty w poprzednim poście – zobacz sobie.

To co pokazałeś na zrzucie to TLinkLabel, którego cały tekst malowany jest jednocześnie (jedno wywołanie metody Canvas.TextOut), więc linia go podkreślająca zawsze będzie ciągła.

Przy okazji - demo się odpaliło natychmiast, nie było żadnych problemów, antywirus F-secure nie miał zastrzeżeń do pliku.

Dobrze, bo nie ma żadnego powodu aby uznawać ten plik za niebezpieczny.

Jedyne co to dziwnie się wyświetla ikona aplikacji - albo właściwie jej brak. Tak ma być, czy coś nawaliło?

Nie no taka ma być – zobacz sobie do zasobów, jeśli nie wierzysz. ;)

0

Po wrzuceniu przez Ciebie screena ilustrującego o co chodzi - wszystko jest jasne.
U mnie jest linia ciągła, nic się nie przerywa.

0

A co sądzicie o takim zabiegu jak na zrzucie niżej? ;)

Przyciski formularza staną się bardziej widoczne, rzucając się w oczy wystającym fragmentem, a aktywna zakładka jaśniej sugerować będzie swoją funkcję w oknie. Prototyp (namalowany w Paint):

prototype.png

Nie jest to trudne w implementaji – można to załatwić regionami (więcej zabawy), lub w sposób nieco łatwiejszy, czyli za pomocą dodatkowych paneli. Zakładki natomiast musiałyby być położone bez pośrednio na formularzu, a nie na kontrolce imitującej okno.

To tylko pomysł i tylko dla głównego okna. Potomne, posiadające zakładki, musiały by mieć określany kształt na podstawie regionów, co dość skomplikowałoby sprawę. :D

1

No dobrze – co nieco poprawiłem w interfejsie, biorąc pod uwagę wskazówki z wcześniejszych postów/komentarzy.

Przeniosłem systemowe przyciski formularza na prawą stronę, trochę powiększyłem ich klikalny obszar i wyróżniłem poprzez ich umieszczenie na ”wystającym” panelu, zakotwiczonym w kontrolce imitującej obramowanie okna. Gradientowe przejścia mogą być konfigurowane – można ustalić offset początku przejścia i jego długość, pionowego i poziomego z osobna.

Druga rzecz to lekka zmiana wyglądu dużych przycisków (tych w ostatniej zakładce) – pełne szare obramowanie zmieniłem na gradientowe przejścia. Ich offsety i długości możliwe są do ustawienia niezależnie. Dzięki temu górne może być inne niż dolne, co już zdążyłem wykorzystać we właściwej aplikacji. W sumie pełnego obramowania nie stosuję nigdzie, dlatego się go pozbyłem na rzecz nowego efektu.

Trzecią rzeczą było usunięcie ”glitcha” związanego z markerem aktywnej zakładki. Teraz jest to po prostu strzałka, nie domek. :D

demo.png

Pozostało mi jeszcze przerobić przyciski zakładek na podobnie wystające co menu z przyciskami formularza (tak jak na zrzucie w poście wyżej). Te też zakotwiczę w kontrolce imitującej obramowanie okna – jako standardowo podpinane kontrolki w oknie OI.

A jak to zrobię to ostatnim krokiem będzie ustalanie rozmiaru i kształtu okna na podstawie CreatePolygonRgn i SetWindowRgn, co nie będzie jakoś szczególnie trudne. Jednak to sprawi, że aktywna zakładka będzie bardziej widoczna (skoro sama strzałka nie wystarcza).

Demówka w załączniku, do poklikania, jeśli ktoś chce. Obsługa taka sama jak poprzednio. ;)

0

Skończyłem implementować ”wystające” elementy okna – teraz wszystko wygląda tak, jak ma wyglądać. Nie spodziewałem się, że będzie tyle komplikacji związanych ze zmianą kształtu okna, jednak wszystko dało się zrobić. :]


Zrobiłem to w ten sposób, że do kontrolki imitującej tło dodałem opublikowane właściwości, dzięki którym mogę przypisać przyciski do kontrolki tła. W ten sam sposób podpina się wystający panel z przyciskami formularza (prawy górny róg). Dzięki temu podczas modyfikacji komponentu tła (zmiany pozycji i/lub rozmiaru), ten z kolei dostosowuje pozycję wszystkich wystających kontrolek, bo ma do nich dostęp. Wszystko można ustawić z poziomu okna inspektora obiektów, więc wystarczy trochę poklikać.

Następnie zmodyfikowałem kod przycisków zakładek, tak aby zmieniały pozycję po zaznaczeniu i odznaczeniu. Dodałem nową właściwość liczbową, określającą rozmiar przesunięcia (domyślnie 10px). Trochę zabawy było, aby te przyciski przesuwały się właściwie – w designerze mają nie zmieniać pozycji, podczas działania owszem. Chwilę mi to zajęło, bo zależności było dość sporo i ciągle mi te przyciski uciekały.

Kolejną rzeczą do zrobienia była implementacja metody wyznaczającej region formularza. Szału nima – potrzebna jest wyłącznie referencja formularza. Ten szuka kontrolki tła i jeśli ją znajdzie, to ma dostęp do wszystkich innych wymaganych do obliczeń (do panelu i aktywnego przycisku zakładki). Teraz na podstawie referencji tych rzech komponentów, można wyznaczyć region. I tu niespodzianka – nie trzeba bawić się w ręczne pakowanie współrzędnych wierzchołków do tablicy i używać gołych funkcji systemowych (a tymi bawiłem się wcześniej). Do dyspozycji jest klasa TRegion i metoda SetShape. Tak więc ustalenie kształtu okna wykonuje poniższa, krótka i prosta metoda:

procedure TAppForm.UpdateFormShape();
var
  LBackground: TBaseWindowBackground;
  LGroupBox: TBaseConvexGroupBox;
  LButton: TBaseTabButton;
var
  LRegion: TRegion;
begin
  LBackground := FindBackground();

  if Assigned(LBackground) then
  begin
    LGroupBox := LBackground.ConvexCorner.GroupBox;
    LButton := LBackground.ConvexTab.SelectedButton;

    LRegion := TRegion.Create();
    try
      LRegion.AddRectangle(LBackground.BoundsRect);

      if Assigned(LGroupBox) then
        LRegion.AddRectangle(LGroupBox.BoundsRect);

      if Assigned(LButton) then
        LRegion.AddRectangle(LButton.BoundsRect);

      Self.SetShape(LRegion);
    finally
      LRegion.Free();
    end;
  end;
end;

Przy okazji warto zaznaczyć, że klasa TRegion oraz metoda SetShape korzystają z aktualnego widgetsetu, więc ten kod jest przenośny na inne platformy. Jeszcze jedno, bo przecież zbyt łatwo być nie może. Klasa TRegion nie posiada metody AddRectangle pobierającej w parametrze TRect – tę dodałem sobie za pomocą helpera. Ta istniejąca pobiera cztery inty, a więc zmusza do pisania długich linijek.

Ostatnią rzeczą było sprawienie, aby każdy formularz przyjmował odpowiedni kształt podczas jego tworzenia (bo wszystkie formularze tworzę dynamicznie, oprócz głównego, czym zarządza obiekt Application) oraz po klikaniu w przyciski zakładek. Tu drugi problem – wywołanie metody UpdateFormShape w konstruktorze formularza nie zmienia kształtu okna. Widać na tym etapie okno jeszcze nie jest na gotowe. Natomiast po wykonaniu kodu konstruktora, można już dobrać się do okna i manipulować jego kształtem.

Dlatego też skorzystałem z wirtualnej metody DoShow – ona wołana jest tuż przed pokazaniem okna na ekranie. W sumie to służy ona wyłącznie do odpalania zdarzenia OnShow, jednak do mojego celu nadaje się idealnie, więc ją nadpisałem i najpierw wywołałem w niej UpdateFormShape, a następnie wywołałem bazową za pomocą inherited. Aby formularz zmieniał kształt również po klikaniu w przyciski zakładek, w zdarzeniu OnClick przycisków (jedno dla wszystkich w danym oknie) wołam samo UpdateFormShape. Działa bezbłędnie.


To w sumie tyle, jeśli chodzi o ten design. Gdyby ktoś kiedyś potrzebował pobawić się w zmianę kształtu okna to kod podany wyżej może być pomocny. Demówkę prezentującą finalny efekt dorzucę później do załączników, jak będę miał chwilkę.

Szkoda tylko, że klasa TRegion nie umożliwia tworzenia bardziej skomplikowanych kształtów, na podstawie różnych figur. Bo system posiada funkcje CreatePolygonRgn, CreateRectRgn, CreateRoundRectRgn, CreateEllipticRgn czy CreatePolyPolygonRgn, a klasa TRegion ma jedynie metodę do zwykłych prostokątów. Może kiedyś zostanie ona rozszerzona o inne kształty.

1

W załączniku podaję demówkę z kilkoma oknami, aby zobaczyć jak to cholerstwo działa.

W głównym oknie, po kliknięciu w ikonkę z kluczem i śrubokrętem, otworzy się okno potomne (również z zakładkami). Natomiast po kliknięciu w ikonkę żarówki, otworzy się nieco inne okno – bez zakładek (tak będzie wyglądać okienko about). To z kolei nie posiada przycisku zamknięcia, więc pozostaje Alt+F4 (normalnie będzie).

Teraz przynajmniej widać jak zachowuje się nieaktywne okno:

demo - main.png
demo - settings.png
demo - about.png

To póki co wszystko, dzięki za dotychczasowe sugestie – z końcowego efektu jestem zadowolony. ;)

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