Delphi, cz. 7
W poprzednim rozdziale obiecałem, że tym razem zajmiemy się trochę grafiką. Będziemy także kończyć pisanie edytora tekstów. Właściwie nie będziemy tego ciągnąć w nieskończoność. :)
No dobra. Zdaje się, że począwszy od wersji 3 Delphi umożliwia kompresje plików JPG. W twoim programie odszukaj na samej górze słowo "uses". Dodaj to tej listy słowo "jpeg". Teraz będziesz mógł kompresować pliki BMP na JPG. Umieść na formularzu przycisk. Uzupełnij jego procedurę "OnClick" w ten sposób:
var
Bitmap : TBitmap; // BMP
JPG : TJPEGImage; // JPG
begin
{
Procedura pobiera obrazek BMP i kompresuje go do JPG.
Na samym końcu obrazek zostaje wyświetlony w punkcie 10,10
}
Bitmap := TBitmap.Create; // stwórz zmienna
JPG := TJPEGImage.Create;
try
// załaduj obrazek
Bitmap.LoadFromFile('C:\Moje dokumenty\mikolaj.bmp');
JPG.Assign(Bitmap); // pobierz
JPG.SaveToFile( // zapisz obrazek
'C:\Moje dokumenty\mikolaj.JPG');
Canvas.Draw(10, 10, Bitmap); // wispiest
finally
Bitmap.Free; // zwolnij pamiec
JPG.Free;
end;
Jak możesz przeczytać w komentarzu procedura kompresuje obrazek z BMP do JPG. Na samym początku tworzone są dwie zmienne symbolizujące dwa typy obrazków: BMP i JPG. Później następuje stworzenie dwóch zmiennych. Później wyjątek ( omawiany w poprzednim rozdziale ). Następnie do zmiennej "Bitmap" zostaje załadowany obrazek przy pomocy polecenia "LoadFromFile". W kolejnej linii następuje pobieranie danych ze zmiennej "Bitmap" do zmiennej "JPG". Dokonuje tego funkcja "Assign". I w końcu zapisanie obrazka "SaveToFile" JPG. Teraz podczas zapisywania następuje kompresja. W nawiasach zapisana jest nowa ścieżka obrazka.
I w końcu wyświetlenie obrazka. "Canvas" to inaczej "płótno”, czyli obszar formularza. Następnie funkcja "Draw" powoduje wyświetlenie obrazka. W nawiasie dwa pierwsze parametry to pozycja obrazka, a ostatni to sama zmienna, która ma być wyświetlana. Na samym końcu następuje zwolnienie zmiennych. Dokonuje tego funkcja "Free". Jest to bardzo ważne! Zawsze zwalniaj zmienne tego typu. Powód jest prosty. Gdy tworzysz taka zmienna w obszarze pamięci zarezerwowany zostaje dla niej rozmiar. Teraz podczas zakończenia programu, jeżeli nie użyjesz tej linii zajęta pamięć zostanie! Wyobraź sobie, ze uruchamiasz taki program kilka razy. Ciągle zostaje rezerwowana pamięć, która nie zostaje zwalniana. Może to doprowadzić w końcu do zawieszenia się komputera, a pamięć zwolni się dopiero po restarcie.
Teraz przedstawię jeszcze przykład dynamicznego tworzenia komponentu. Dynamiczne tworzenie komponentu to nic innego jak tworzenie ich dopiero po uruchomieniu programu. Oto kod:
var
Button : TButton; // Komponent Button
begin
Button := TButton.Create(Self);
Button.Parent := Self; // rodzic
with Button do
begin
Left := 100; // pozycja: X
Top := 100; // pozycja: Y
Caption := 'Naciśnij mnie!'; // tekst na przycisku
end;
end;
W tym wypadku tworzony zostaje komponent Button. Zauważ słowo "Self". Określa ona gdzie ma być komponent umieszczony. Określenie "Self" to formularz. Można np. umieścić komponent Button na komponencie "Panel". Umieszczasz komponent "Panel" na formularzu, a w kodzie piszesz zamiast "Self" piszesz "Panel1". Tutaj tez przydałoby się zwalnianie komponentu przy zakończeniu pracy programu. W takim jednak wypadku zmienna "Button" musi zostać umieszczona w sekcji "private".
Jeszcze jedna rzecz. W Inspektorze Obiektów kliknij na zakładkę "Events" i tam masz listę dostępnych zdarzeń. Przy uzupełnieniu którejś z nich możesz być pewien, ze Twój kod zostanie wykonany podczas zajścia określonego zdarzenia. Przykład: Masz na tej liście zdarzenie "OnDestroy". Gdy ja wygenerujesz to kod, który tam wpiszesz może zostać wykonany podczas zamykania programu.
No, ale powróćmy do JPG. Jest jeszcze jedna rzecz, która wpływa na kompresje. To jej jakość. Określa ja właściwość "CompressionQuality". To jest wartość typu "Integer", która określa właśnie stopień kompresji. Jest to liczba od 1 do 100. Im mniejsza jest ta cyfra tym kompresja jest lepsza:
JPG.CompressionQuality := 50; // kompresja na 50%
Polecam artykuł o plikach JPG w dziale "Delphi" na stronie: www.programowanie.of.pl Tam także możesz znaleźć kod źródłowy "View Image Compress", który kompresuje pliki JPG.
Przyozdabianie programu
Teraz po dodaniu ikonek do paska program wygląda nieco lepiej, nieprawdaż? Teraz dodamy obsługę pomocy ( tzw. Hint albo ToolTips ). Polega to na tym, że gdy zatrzymasz kursor na którymś z komponentów to wyświetlony zostaje Hint. Najlepiej sam to zobacz.
Zaznasz komponent "Tools" i w Inspektorze Obiektów odszukaj właściwość "ShowHint" i ustaw ja na True. Dzięki temu wszystkie przyciski leżące na tym komponencie również będą miały właściwość "ShowHint" przełączone na True. Dzięki temu będzie wyświetlona pomoc. Teraz zaznacz np. komponent "btnNew" i w Inspektorze Obiektów odszukaj pole "Hint". Wpisz w nie słowo "Nowy". Teraz możesz uruchomić program i najechać kursorem myszy na ten komponent. Po chwili rozwinie się pole z podpowiedzią. Fajne nie?! :) Możesz tak zrobić z pozostałymi przyciskami przypisując im odpowiednia pomoc. Cóż przydałaby się jakaś obszerniejsza pomoc, prawda? Fajnie by było gdyby tak jak w innych programach u dołu na pasku wyświetliła się obszerniejsza pomoc. Ty też możesz tak zrobić. Na palecie "Win32" znajduje się komponent "StatusBar" - umieść go na formularzu - powinien automatycznie zostać umieszczony u dołu formy. Nazwij ten komponent "HelpBar". Teraz mając zaznaczony ten komponent w polu "AutoHint" zmień na True, a "SimplePanel" zmień również na True. Ale pozostało jeszcze zmienić treść podpowiedzi rożnych komponentów. Bo treść hinta komponentu "btnNew" napisałeś pewnie tak: "Nowy". Musisz ja zmienić na taka: "Nowy | Wyczyść dotychczasowy dokument". Pierwszy człon tego tekstu ( przed znakiem " | " ) będzie wyświetlany w ramce w miejscu kursora, a drugi człon na komponencie "HelpBar".
Cóż jeszcze? Zmień właściwość "Flat" komponentu "Tools" na True - pasek zostanie "spłaszczony".
Dodamy jeszcze jeden komponent - "MainMenu" ( paleta: "Standard" ). Komponent tez służy do tworzenia standardowego dla Windows menu. Menu zostanie stworzone, gdy klikniesz na tym komponencie - otwarty zostanie edytor menu. Teraz w Inspektorze Obiektów we właściwości "Caption" wpisz "Plik" i naciśnij ENTER. Stworzyłeś właśnie nowa właściwość - nazwij ja "FileMenu". Kliknij na nią - stworzone zostanie pod menu do menu "Plik". Zaznacz tę nową właściwość i wpisz "Nowy", tę właściwość nazwij "FileNew". Właśnie stworzyłeś sub menu ( inaczej: pod menu ). Ponieważ napisałeś już kod dla procedury otwierającej nowy plik nie musisz tego robić dwa razy. Zaznacz właściwość "Nowy" i w Inspektorze Obiektów kliknij na zakładkę "Events". Kliknij na "OnClick". Po prawej stronie kliknij na przycisku strzałki - kliknij na nią - rozwinie się menu, z którego wybierz "btnNewClick". Od tej pory po kliknieciu na przycisk jak i wybierając pozycje z menu wywoływana będzie ta sama procedura.
Ok, teraz stwórz nowe pozycje w menu. Całość powinna wyglądać tak:
Plik / FileMenu Edycja / EditMenu Pomoc / HelpMenu
Nowy / FileNew Zaznacz wszystko / EditSelAll O programie / HelpAbout
Otwórz / FileOpen Usuń / EditDel
Zapisz / FileSave -
Zapisz jako / FileSaveAs Wytnij / EditCut
- Kopiuj / EditCopy
Drukuj / FilePrint Wklej / EditPaste
Ustawienia drukarki / FilePrinterSetup -
- Zawijaj wiersze / WordWrap
Wyjście / FileExit
Jak widzisz przestawiłem strukturę menu. Po lewej stronie zawarta jest właściwość "Caption", a po znaku " / " zawarta jest nazwa ( "Name" ) danej pozycji. Aha, jeszcze znak "-" to tzw. separator. Jeżeli w pozycji "Caption" wpiszesz taki znak to postawiona będzie pozioma linia oddzielająca jedna pozycje od drugiej.
Oczywiście nie musisz nazywać tych pozycji tak jak ja, ale będzie to myślę wygodniejsze podczas omawiania dalszej części programu. Na razie są to zwykle pozycje i nic nie robią, gdy na nie klikniesz. Jest to tylko podstawa ( fundamenty ). Teraz możesz już zamknąć edytor menu. W Twoim programie powstało menu.
W przyszłej części skończę omawiać ten program i napiszemy resztę procedur, a teraz stworzymy okno "O programie". W tym celu musisz stworzyć nowa formę:
"File" -> "New Form". Zmniejsz jej rozmiary i nazwij ja np. "AboutFrm", a "Caption" zmień na: "O programie TeXT Edit". Umieść na tej formie komponent "Image". ( na palecie "Additional" ). Komponent ten służy do przechowywania obrazków. Kliknij na ten komponent dwukrotnie - pojawi się okno do wyboru ikony. Wybierz ikonę symbolizującą ikonę programu. Teraz mając zaznaczony komponent "Image" zmień w Inspektorze Obiektów właściwość "AutoSize" na True - spowoduje to dopasowanie rozmiarów komponentu to ikony w nim się znajdującej. No dobra - mamy już ikonę. Teraz wypadałoby cos napisać ( np. informacje o autorze, strona internetowa, e-mail, itp. ). Nie będę się tutaj rozpisywał na temat samego wyglądu tej formy ( jeżeli chcesz zobaczyć jak ja to zrobiłem to ściągnij źródła programu "TeXT Edit" ze strony: www.programowanie.of.pl ). Jeżeli już napisałeś coś na temat praw autorskich i inne pierdoły to można napisać procedurę otwierającą tę formę. Na początek zapisz wszystko ( "File" -> "Save All" ). Formularz "O programie" zapisz pod nazwą "AboutFrmU". Polecam także zmianę właściwości "BorderStyle" formy na "bsSizeToolWin". Powoduje to wyświetlenie jedynie przycisku to zamykania okna.
Teraz należy jeszcze napisać procedurę wyświetlająca formę. W Delphi kliknij na pozycji "Poject" -> "Options". Powinna być zaznaczona zakładkę "Forms". Po lewej stronie są nazwy formularzy, które są tworzone automatycznie po uruchomieniu programu. Po co nasza forma "O programie" ma być uruchamiana po odpaleniu programu i zajmować niepotrzebnie pamięć. A więc zaznacz "AboutFrm" i kliknij znaczek ">", następnie OK, aby zamknąć okno. Teraz w menu swojego programu wybierz "Pomoc" i "O programie" - zostaniesz przeniesiony do edytora kodu. Tutaj musisz wpisać odpowiedni kod:
AboutFrm := TAboutFrm.Create(Self); // stwórz
AboutFrm.ShowModal; // wyswietl
AboutFrm.Free; // zwolnij pamięć
Najpierw wpisz ten kod do programu i spróbuj go uruchomić. Wyświetli się okno z informacja, czy dodać do Twojego projektu formularz "AboutFrm". wybierz "Yes". Na samym początku zostanie stworzona forma ( inaczej: następuje zarezerwowanie pamięci dla zmiennej, czyli dla formy ). Następnie następuje wyświetlenie formy ( procedura "ShowModal" ). Na samym końcu zostanie zwolniona pamięć dla tej zmiennej, czyli dla formy.
Teraz stwórzmy jeszcze trzy przyciski na komponencie "Tools". Prawy przycisk na komponent "Tools" i "New Separator" - utworzenie separatora. Następnie stwórz 3 przyciski, które będą wycinać, kopiować i wklejać tekst. A wiec stwórz te przyciski i nazwij je: "btnCut", "btnCopy", "btnPaste". Dodaj do komponentu "ImageList" kolejne ikonki wycinania, kopiowania, wklejania. Uzupełnij procedurę OnClick tych przycisków po kolei w ten sposób:
RichEdit.CutToClipboard; // wytnij tekst
W "btnCopy":
RichEdit.CopyToClipboard; // skopiuj
W "btnPaste":
RichEdit.PasteFromClipboard; // wklej do RichEdit
Jeżeli nie wiesz jak to zrobić sięgnij po wcześniejsze części kursu, a wszystko stanie się jaśniejsze :) [ mam nadzieje :)]. Jeżeli nadal czegoś nie wiesz to możesz zajrzeć na stronę www.programowanie.of.pl do działu FAQ [ pytania i odpowiedzi do Delphi ], albo napisz do mnie: boduch@poland.com
Następny rozdział będzie dłuższy, bo nie dość, że ukończymy pisanie programu "TeXT Edit" to omówię podstawę grafiki. A później rejestr Windows, pliki INI, biblioteki DLL i trudniejsze już rzeczy :) Tak wiec zapraszam :)
Adam Boduch <boduch@poland.com>
http://www.programowanie.of.pl
9 luty 2001