Programowanie w języku Delphi » Artykuły

Zabawa z formularzem (formą)

  • 2012-02-18 00:32
  • 22 komentarze
  • 6701 odsłon
  • Oceń ten tekst jako pierwszy
Ten artykuł wymaga dopracowania!

Jeżeli możesz popraw ten artykuł według zaleceń, które możesz znaleźć na stronie Artykuły do poprawy. Po dopracowaniu tego tekstu można usunąć ten komunikat.



Witam!

W tym artykule przedstawię zagadnienia dotyczące pracy z formą (formularzem) w Delphi.
Standardowo mamy ustawioną formę tak jak większość aplikacji w Windows - prostokątne pole, z ramką u góry (tytuł) oraz efektami 3D (:)) na brzegach (różne w zależności od wersji naszej windy).

No więc w standardowej aplikacji typu notatnik to nie przeszkadza - możemy łatwo zmieniać rozmiar, w tytule możemy podać np. nazwę otwartego pliku. Co jednak mają zrobić osoby piszące np. odtwarzacz wideo? Pełny ekran z ramką i paskiem zadań u góry nie jest zbyt efektowny. Innym problemem są osoby, które chcą wyposażyć swoje aplikacje w okna o niestandardowych kształtach, z własną powłoką graficzną (np. Winamp, czy choćby Windows Media Player > 6.0).

Uruchamiając Delphi mamy domyślną formę, a obok Object Inspectora z właściwościami formy. Przedstawię teraz większość z opcji z OI.:
W wersji 7.0 jest dodatkowa opcja Active Control , jednak ją pomijam, gdyż nie ma wpływu na wygląd formy.

WłaściwośćOpis
Alignułożenie formy, możemy wybrać następujące opcje:
alNone - nie będzie się dopasowywała do dostępnej przestrzeni na pulpicie - pozostanie w takich rozmiarach, w jakich ją zostawiliśmy
alClient - forma wypełni całą dostępną przestrzeń na pulpicie
alTop - formularz zostanie rozciągnięty wypełniając całą górną przestrzeń aż do dolnego brzegu formy (tzn. gdy dolna krawędź formy w trybie edycji będzie w punkcie X, to po uruchomieniu wypełniona zostanie cała górna przestrzeń pulpitu, zaczynając od punktu X)
alBottom - formularz zostanie rozciągnięty wypełniając całą dolną przestrzeń od górnego brzegu formy
alLeft - zajęta zostanie przestrzeń od prawego brzegu formy do lewej krawędzi ekranu
alRight - forma zajmie obszar od lewego brzegu formularza do prawej krawędzi ekranu
alCustom - forma pozostanie w takich samych rozmiarach jak w trybie edycji, a do tego nie będzie można jej przesuwać
AlphaBlendwprowadzone bodajże w wersji 7.0 Delphi parametr określający czy forma jest przezroczysta
AlphaBlendValueokreśla poziom przezroczystości (od 0 do 255 - 0 - całkiem przezroczyste, 255 - brak przezroczystości)
BorderIconsta wartość definiuje, jakie ikonki ma zawierać pasek tytułowy naszej formy. Mamy do wyboru:
biMinimize - ikonka minimalizacji okna
biMaximize - maksymalizacja okna
biHelp - ikonka pomocy (patrz w apletach windowsowych, np.właściwości ekranu)
biSystemMenu - menu podręczne pokazujące się po kliknięciu w ikonkę aplikacji
BorderStylejedna z najciekawszych opcji - możemy tu wybrać typ obramowania okna (domyślnie jest wybrane bsSizeable, ale do wyboru mamy również:
bsDialog - ma tylko ikonkę zamknij, nie ma ikony aplikacji, nie można zmieniac rozmiaru okna
bsNone - brak obramowania, brak jakichkolwiek ikonek, brak systemowego menu (doskonale komponuje się z opcją WindowState ustawioną na wmMaximized)
bsSingle - wybrane ikonki, menu systemowe, obramowanie. (nie można zmienić rozmiaru okna - można tylko je przesuwać)
bsSizeToolWin - okienko narzędzia - cieńkie obramowanie, można zmieniać rozmiar, ikonka zamknij
bsToolWindow - to samo co wyżej, tylko nie można zmieniać rozmiaru
BorderWidthszerokość ramki wewnątrz formy (wbrew pozorom nie zmienia to rozmiaru efektu 3d obramowania)
Captionnapis na pasku tytułowym formy, przydaje się do wyświetlenia np. tytułu otwartego dokumentu. Dla upiększenia aplikacji można pokusić się o scrolowanie (przewijanie) napisu na tytule formy
Colorwłaściwość ta przydaje się, gdy samodzielnie robimy grafikę (nie korzystamy z windowsowych grafik) lub gdy robimy np. pełnoekranowy podgląd
Constrainstpozwala nam określić maksymalną i minimalną wielkość okna (domyślnie jest zero, co znaczy, że nie ma żadnych ograniczeń), poszczególne wartości:
MaxWidth - maksymalna szerokość
MaxHeight - maksymalna wysokość
MinWidth - minimalna szerokość
MinHeight - minimalna wysokość
Cursorpozwala zmienić domyślny kursor (strzałkę) na inny, na liście mamy zainstalowane kursory systemowe
Enabledwartość ustawiona na True pozwala nam na klikanie elementów, ustawiona na False ignoruje akcje użytkownika (z górnym paskiem tytułowym włącznie)
Fontta opcja pozwala nam zmienić czcionkę domyślną formy. Jej zmiana zmieni parametry czcionki na wszystkich komponentach znajdujęcych się na formie. Wyróżniamy następujące opcje czcionki:
Charset - zestaw znaków
Color - zmienia kolor czcionki (poza zdefiniowanymi kolorami, można też wybrać swoje)
Height - wysokość napisu, od własności Size różni się tym, że w przypadku dużych liter będą widoczne postrzępienia (litery są powiększane)
Name - nazwa czcionki
Size - wielkość napisu (w odróżnieniu od własności Height ta nie strzępi brzegów napisu)
Style - efekty czcionki, dostępne wartości zbioru: fsBold - pogrubienie, fsItalic - kursywa, fsUnderline - podkreślenie oraz fsStrikeOut - przekreślenie
Hint"dymek" nad formą i nad wszystkimi komponentami, które dymku nie mają, a właściwość ParentShowHint mają ustawioną na True
Iconikonka na pasku tytułowym okna (można ją także zmienić w Project/Options/Application)
Positionpozycja okna, do wyboru:
poDefault - ustawia okno w pozycji domyślnej (lewy górny róg) oraz nadaje domyślne rozmiary
poDefaultPosOnly - nie będzie zmiany rozmiaru okna
poDefaultSizeOnly - nie będzie zmiany położenia okna (formy) aplikacji
poDesigned - pozostawia wielkość i położenie formy w tym samym trybie, w jakim mamy ją w trybie edycji formularza
peDesktopCenter - okno zostanie wycentrowane względem pulpitu
poMainFormCenter - wycentruje nam formę podrzędną względem formy głównej (gdy jej nie ma (tzn. sama jest formą główną), forma nie zmieni swojej pozycji)
poOwnerFormCenter - ustawi formę na środku formy nadrzędnej (nie głównej!)
poScreenCenter - ustawi formę na środku ekranu
WindowState"status" okna, dostępne wartości:
wsNormal - forma nie zmienia swoich rozmiarów
wsMinimized - forma wystartuje zminimalizowana
wsMaximized - maksymalizuje formę

Teraz kod, który spowoduje, że forma przybierze kształt bitmapy. Zastrzegam, że kod nie jest w 100% napisany przeze mnie, lecz ja go zdecydowanie zmieniłem i poprawiłem (chyba) na lepsze:). Na formę wrzuć TImage. We właściwości Picture ustaw twoją bitmapę. kolorem przezroczystym jest domyślnie kolor biały. Możesz go oczywiście zmienić. Oto kod - wrzuć go do OnCreate formy:

var
  { regiony typu Canvas, więcej w helpie }
  tot_reg, tmp_reg: HRGN;
  color, fill, x_a, x_b: Integer;
  { kolor przezroczysty }
  transparent: TColor;
  linia: PByteArray;
  Virtual_Image: TBitmap;
begin
  tot_reg := CreateRectRgn(0, 0, Image1.Width, Image1.Height);
  Virtual_Image := Image1.Picture.BitMap;
  linia := Virtual_Image.ScanLine[0];
  transparent := linia[0];
 
  { skanujemy po koleji całą formę(tzn nasz obrazek) linia po linii }
  for fill := 0 to (Virtual_Image.Height-1) do
    begin
      { zmienna linia przyjmuje wartość ciągu bitów określających kolory }
      { pikseli w danej linii                                            }
      linia := Virtual_Image.ScanLine[fill];
      color := 0;
      x_a := color;
 
      { póki nie skończy nam się obrazek (nie dojdziemy do brzegu) w pętli }
      { sprawdzamy czy dany piksel ma wyświetlać to co jest pod nim, czyli }
      { być teoretycznie przezroczysty                                     }
      while (color >= (Virtual_Image.Width - 1)) do
        begin
          x_b := TColor(linia[color]);
 
          { jeśli nie jest przezroczysty }
          if (x_b <> transparent) then
            begin
              tmp_reg := CreateRectRgn(x_a, fill, color, fill+1);
 
              { łączymy mapę wynikową z tymczasową (zawierającą 1 linie) metodą xor }
              CombineRgn(tot_reg, tot_reg, tmp_reg, RGN_XOR);
              DeleteObject(tmp_reg);
 
              { omijamy piksele, aż trafimy na ten, który ma być przezroczysty, lub }
              { skończy nam sie obrazek (tzn linia)                                 }
              repeat
                Inc(color);
              until ((TColor(linia[color]) = transparent) or (color = Virtual_Image.Width - 1));
 
              x_a := color;
            end;
 
          Inc(color);
        end;
 
      { Jeżeli napotkany piksel ma być transparentny (przezroczysty) }
      if TColor(linia[color-1])=transparent then
        begin
          tmp_reg := CreateRectRgn(x_a, fill, color+1, fill+1);
          { metodą xor różnicujemy (odejmujemy od siebie) obydwie mapy }
          CombineRgn(tot_reg, tot_reg, tmp_reg, RGN_XOR);
          { usuwamy obiekt z pamięci }
          DeleteObject(tmp_reg);
        end;
    end;
 
  { definiujemy obszar (nieregularny) który jest naszą aplikacją (Można za pomocą właściwości }
  { Handle zmienić kształt np. worda)                                                         }
  SetWindowRgn(form1.Handle, tot_reg, true);
  { czyścimy pamięć }
  deleteobject(tot_reg);
end;


Więcej artykułów na www.vxcdelphi.prv.pl

22 komentarze

furious programming 2012-02-17 00:10

Sprowadziłem listę właściwości i ich wartości do postaci tabeli - łatwiej teraz odnaleźć to, co nas interesuje;

Demonical Monk 2008-10-07 15:40

wsMaximized maksymalizuje formę. W połączeniu z ustawieniem koloru formy na czarny, usunięciem obramowania (border style) daje efekt pełnego ekranu.

A co ma do tego czarny kolor?

Spine 2007-06-06 19:41

Czy ja wiem, czy to taka zabawa z formą... może praca z formą ?? Przekształcenia ?? Tytuł taki... nieprofesjonalny.

nav 2007-06-06 19:01

Na przykład

procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then begin
    ReleaseCapture;
    PostMessage(Handle, WM_SYSCOMMAND, SC_MOVE + 2, 0);
  end;
end;
Lub
procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest; 
//[...]
    procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest) ;
    begin
       inherited;
       if Msg.Result = htClient then Msg.Result := htCaption;
    end; 
Takie pytania to na google lub forum, nie w komentarzach.

Morgoth_ 2007-06-06 18:13

A jak zrobić by kliknięciem i przytrzymaniem w dowolną część formy zmienić jej pozycję? - też się dorzucam do tego pytania!
Ps. poprawiłem "Delphiego" na "Delphi"

rifi90 2006-08-13 00:06

A jak zrobić by kliknięciem i przytrzymaniem w dowolną część formy zmienić jej pozycję?

sosik 2006-02-05 18:34

Nie to ja akurat wiem, ale ciekawa mogła by być możliwośc dla niektórych coderów stworzenia formy o dowolnym kształcie, nie gwiada, nie trójkąt, nie elipsa ;). No, a poprostu uważam, że ten kod można trochę poprawić to wszystko :p.

Coldpeer 2006-02-03 11:23

michalfo: jak chcesz zaokraglone rogi, to do OnCreate daj:

 SetWindowRgn( Handle, CreateRoundRectRgn( 0,0,width,height,20,20 ),true );



sosik: zamień "&lt;" na "<", bo to jest znak specjalny html... I nie najwięcej, tylko dwa :D

sosik 2006-01-28 05:03

Ten "poprawiony" kod coś się nie kompiluje :)  (w d7). Najwięcej błędów wyskakuje przy " &lt ". Pozatym do miejsca gdzie umieściłeś kod to chyba każdy [email protected] (np. taki jak ja :) )bez czytania twojego tekstu dałby sobie doskonale rade (Caption... lol dziwne?? itd... przypomina mi się KS-Ekspert, nie wiem czemu :], może dlatego, że to lamerska gazeta i tam tak chyba właśnie wszystko opisują jak coś robią w delphim... przypisz do wartości Caption, From1 wartość... plepleple).
No to chyba wszystko
Pozdrawiam

michalfo 2005-10-21 09:31

Przydało by się jeszcze zaokrąglanie formy, tzn. rogów. Jak to zrobić przy border innym niż none

vegat 2005-01-06 08:37

nie, no bezpośredniego Alpha blendów D5 nie ma... ale zrobić się da, tylko troche trzeba sie napisać :P

Ktos 2005-01-05 19:36

na windowsie ME też nie działa AlphaBlending. only NT >= 5.0

piwko28 2004-11-28 13:35

Spoko art, napewno się komuś przyda.
Co do alpha blend... ja tez mam zastrzezenia. Nie pamietam dokladnie, ale chyba widzialem to nawet w D5 :D
Przezroczystosc formy mozna wykorzystywac w systemach serii NT (Windows 2000 [NT 5.0]; Windows XP [NT 5.1]; Windows 2003 [NT 5.2] i nowszych :)) oraz (glowy nie dam) Windows ME [9x 4.90].

vegat 2004-11-03 14:27

hey, a co jeszcze napisać mam? Prawie cały Object Inspector jest tu opisany... poza tym to, jak już wspomniałem, mój pierwszy art, a ja mam jeszcze szkołe... (w tym roku egzamin:))

vegat 2004-11-03 14:24

Kodzik radził sobie u mnie z owalami, trapezami, a nawet bardziej skomplikowanymi kształtami.... faktem jest, że czasem to nawet kwadrat źle rysuje...

aZgon 2004-10-28 07:48

Jak dla mnie to kod nie radzi sobie nawet z trapezem wiec ...

Deti 2004-10-22 16:58

Hmm.. szkoda, że tak mało tych opisów - brak jest znacznej częsci.. wysilił byś się i opisał wszystkie :) ...

vegat 2004-10-20 19:00

no, czasem kodzik sobie ze skomplikowanymi kształtami nie radzi, ale działać działa:) to mój pierwszy art na 4p, proszę więc o ocenę

brodny 2004-10-20 20:55

3. Dlaczego? Delphi, nie Delphiego. Już mnie to naprawdę denerwuje. Sorki vegat, trafiło na Ciebie :|

akarame 2004-10-20 23:05

delphi nie odmienia sie w jezyku polskim, nazwa wlasna sory

akarame 2004-10-20 23:04

delphi nie odmienia sie w jezyku polskim, nazwa wlasna sory

wesoledi 2004-10-21 15:27

"ALPHA BLEND - wprowadzone bodajże w wersji 7.0"
w 6 tez jest :) to czy bedzie wykorzystywane zalezy od windy :)