CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Inny kształt okna - ambitnie
Strona 1 z 1

Inny kształt okna - ambitnie

Nowy postNapisane: poniedziałek, 3 września 2012, 16:34
przez Mironas
Witam,
Chciałbym utworzyć okienko o specyficznym kształcie (łatwizna) ale tak aby tłem okna była grafika z przeźroczystością (np PNG). Chodzi np o cień obrysu. Ważne też jest abym mógł na nim umieścić dodatkowe komponenty (label, memo, button).
Podobny efekt można uzyskać za pomocą komponentu TAdvSmoothSplashScreen (z TMS Component Pack) ale tam nie ma możliwości dodania Memo lub przycisków.
Czy ktoś może ma pomysł jak zbudować/narysować takie okno?
Przykładowy wygląd:
Obrazek

Re: Inny kształt okna - ambitnie

Nowy postNapisane: wtorek, 4 września 2012, 09:57
przez Cyfrowy Baron
NIe da się tego załatwić żadną bitmapą, czy też plikiem PNG z cieniem, przeźroczystością itp. To wymaga rysowania cienia bezpośrednio na ekranie wokół okna w zdarzeniu OnPaint. Samo rysowanie po ekranie to nie problem, ale narysowanie cienia wymaga już użycia jakichś masek, niestety nie wiem jakich i jak się robi taki cień.

Re: Inny kształt okna - ambitnie

Nowy postNapisane: wtorek, 4 września 2012, 10:18
przez Mironas
Dziękuję za odpowiedź.
Nie chodzi tu tylko o cień wokół okna ale o przeźroczystość całej bitmapy. Myślę że istnieje jakiś sposób na wyświetlenie grafiki z kanałem alfa (przerysowanie?). Tak działa np wspomniany komponent TAdvSmoothSplashScreen:
Obrazek
Ten dymek z cieniowanym obrysem i przeźroczystością to grafika PNG którą umieściłem w tym komponencie. Wygląda świetnie ale ma wady o których pisałem wyżej. Nie wiem jak jest to realizowane ale okno pod dymkiem można normalnie obsługiwać, przesuwać itp. Ciekawostka - jak chciałem zrobić zrzut ekranu za pomocą programu MWSnap3 to po kliknięciu 'Zrzucaj...' dymek zniknął. Zrzut ekranu udało się zrobić zwykłym PrintScreen-em z klawiatury.

Może ktoś w przyszłości wymyśli jakieś rozwiązanie tego problemu i podzieli się z nami pomysłem.
Pozdrawiam.

Re: Inny kształt okna - ambitnie

Nowy postNapisane: wtorek, 4 września 2012, 10:43
przez Cyfrowy Baron
Przecież okno ma dwie właściwości:

AlphaBlend = true - włącza przeźroczystość okna
AlphaBlendValue - określa stopień przeźroczystości w zakresie od 0 - całkowicie przeźroczyste do 255 nieprzeźroczyste.

Problem w tym, że jeżeli określisz w ten sposób przeźroczystość okna to wszystko na tym oknie będzie miało ten sam stopień przeźroczystości, czyli nie tylko np. Bitmapa wczytana np. do Image, ale również wszystkie przyciski, itp.

By to zrobić inaczej musiałbyś użyć dwóch okien z których to pod spodem jest tylko tłem dla tego na wierzchu. Spodnie okno ma regulowany stopień przeźroczystości, a to wierzchnie nie. Okno wierzchnie jest jednak całkowicie przeźroczyste poprzez usunięcie koloru TransparentColor = true, a w TransparentColorValue określasz kolor, który ma być przeźroczysty potem nadajesz oknu kolor ten sam który jest w TransparentColorValue.

TAdvSplashScreen działa na zasadzie rysowania na ekranie z użyciem masek, to nie jest obiekt, który by posiadał powierzchnię lecz zwykła grafika.

Mironas napisał(a):Ten dymek z cieniowanym obrysem i przeźroczystością to grafika PNG którą umieściłem w tym komponencie.


Niczego nie umieściłeś w komponencie, lecz wskazałeś komponentowi grafikę którą ma odrysować na ekranie. Ten komponent nie posiada powierzchni na której można by cokolwiek umieścić. To działa bardziej jak dymek podpowiedzi.

Mironas napisał(a):jak chciałem zrobić zrzut ekranu za pomocą programu MWSnap3 to po kliknięciu 'Zrzucaj...' dymek zniknął.


Gdyż to nie jest okno, lecz grafika, więc nie dało się pobrać do niej uchwytu. PrtScr zrobił zrzut całej zawartości ekranu, ale spróbuj zrobić zrzut dymka z kombinacją Alt+PrtScr a efekt będzie taki sam jak w MWSnap3.

Takie sztuczki z oknem można bez problemu realizować w Windows 7 gdyż ten system to obsługuje, ale w Windows XP tego nie ma dlatego jest to takie kombinowane.

Nie licz na to, że umieszczając grafikę na oknie załatwisz sprawę. Czytałem kiedyś o tym i wiem, że potrzeba jakichś masek, ale nie było kodu więc nie kontynuowałem tematu.

Re: Inny kształt okna - ambitnie

Nowy postNapisane: wtorek, 4 września 2012, 12:06
przez Mironas
Cyfrowy Baron napisał(a):AlphaBlend = true - włącza przeźroczystość okna
AlphaBlendValue - określa stopień przeźroczystości w zakresie od 0 - całkowicie przeźroczyste do 255 nieprzeźroczyste.

Próbowałem już podobnego rozwiązania ale się sprawdza tylko połowicznie. Można uzyskać efekt przeźroczystości ale przeźroczystość jest jednolita na całym obszarze. Nie da się zrobić np zanikających cieni na krawędziach.

Cyfrowy Baron napisał(a):By to zrobić inaczej musiałbyś użyć dwóch okien z których to pod spodem jest tylko tłem dla tego na wierzchu.

Podsunąłeś mi tym inny (podobny) pomysł który rozwiązał wszystkie problemy. Dodałem nowe okientko (Form7) umieściłem na nim wszystkie potrzebne komponenty i ustawiłem takie właściwości formy:
BorderStyle = bsNone;
FormStyle = fsStayOnTop;
Color = clAqua;
TransparentColor = true;
TransparentColorValue = clAqua;
Position = poDesigned;

Dodałem publiczną funkcję:
KOD cpp:     UKRYJ  
public:
  void Start(int X, int Y);
 

W oknie umieściłem komponent TAdvSmoothSplashScreen (z TMS Component Pack) i wstawiłem mu tło PNG z dymkiem.
Okno to wywołuję podając współrzędne gdzie ma się ukazać:
KOD cpp:     UKRYJ  
  Form7->Start(x, y);
  SetFocus();
 

W tym oknie mam coś takiego:
KOD cpp:     UKRYJ  
void TForm7::Start(int X, int Y)
{
  // pokaz dymek
  AdvSmoothSplashScreen1->DisplayPosX = X;
  AdvSmoothSplashScreen1->DisplayPosY = Y;
  AdvSmoothSplashScreen1->Show();
  // pokaz komponenty okna
  Left = X;
  Top = Y;
  Show();
}
//---------------------------------------------------------------------------
void __fastcall TForm7::AdvGlowButton2Click(TObject *Sender)
{
  Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm7::FormClose(TObject *Sender, TCloseAction &Action)
{
  AdvSmoothSplashScreen1->Hide();
}
//---------------------------------------------------------------------------
 

Całość daje taki efekt:
Obrazek
Czyli rozmyte cienie, to co ma być przeźroczyste to jest, można wstawiać dowolne komponenty, można dalej pracować na oknie pod dymkiem, no i całość łatwo się obsługuje. Jedyna wada - trzeba mieć TAdvSmoothSplashScreen który niestety jest płatny.

Dzięki za inspirację.

Re: Inny kształt okna - ambitnie

Nowy postNapisane: niedziela, 9 grudnia 2012, 11:30
przez sebaskow
Witam.

Spodobał mi się problem przeźroczystej podpowiedzi, postanowiłem więc utworzyć sobie takiego hinta. Zrobiłem to w następujący sposób:

1) Skopiowałem fragment ekranu do utworzonej bitmapy.
2) Narysowałem na kolejnej bitmapie przy pomocy GDI obrazek hinta ( jeszcze jest graficznie nie dopracowany )
3) Wykonałem obliczenia na kolorach pixeli, odjąłem kolor obrazka hinta od kolorów fragmentu ekranu - tutaj tła.
4) Kopiuje nowo utworzona bitmape połączoną z dwóch na ekran w dowolnym miejscu.
5) Przy usuwaniu hinta odrysowuje fragment ekranu utworzony w punkcie 1.

W załączniku programik :)

Muszę jeszcze oprogramować zdarzenie odświeżania "chmurki"

Pozdrawiam

Re: Inny kształt okna - ambitnie

Nowy postNapisane: niedziela, 9 grudnia 2012, 18:52
przez Cyfrowy Baron
sebaskow napisał(a):W załączniku programik :)


:?: :!: :?:

Re: Inny kształt okna - ambitnie

Nowy postNapisane: poniedziałek, 10 grudnia 2012, 10:43
przez Mironas
A co jeśli zmienia się obraz pod hint-em?

PS
Może zamiast EXE-ka podasz kawałek kodu?

Re: Inny kształt okna - ambitnie

Nowy postNapisane: poniedziałek, 10 grudnia 2012, 13:48
przez Cyfrowy Baron
To niestety nic innego jak rysowanie po ekranie.

Re: Inny kształt okna - ambitnie

Nowy postNapisane: wtorek, 11 grudnia 2012, 09:52
przez sebaskow
Na razie pracuję nad tym obecny mój kod to jeden wielki bałagan, ale nie ma problemu. Jak już będzie gotowa funkcja oczywiście podam kod poukładany :D
Wiem że muszę wykonać odświeżanie pod Hintem. :)

Pozdrawiam

Re: Inny kształt okna - ambitnie

Nowy postNapisane: wtorek, 11 grudnia 2012, 10:57
przez polymorphism
Kod potencjalnie powoduje wyciek. obrazek, tlo i ekran tworzysz za każdym wciśnięciem przycisku, a usuwasz tylko raz, przy zamykaniu okna. Użyj inteligentnych wskaźników (auto_ptr na przykład)

Re: Inny kształt okna - ambitnie

Nowy postNapisane: niedziela, 23 grudnia 2012, 22:39
przez sebaskow
W załączniku programik :D