Delphi - Piszemy prosty edytor tekstu
Mon, 13 May 2002
Wprowadzenie
Witam! W tym artykule zajmiemy się pisaniem prostego edytora tekstów. Fajnie?
Nasz Edytor będzie miał niektóre możliwości formatowania tekstu np. wytłuszczenie, pochylenie, podkreślenie czcionki.
W pierwszym artykule z tej serii - 'Delphi - Własny odtwarzacz' opisałem Delphi'ego powierzchownie. Także do tego art'u nie będzie nam potrzebna bliższa znajomość. Jednak pokaże dzisiaj co zrobić by w właściwościach naszego programu widniała zakładka 'Wersja'.
Przypomnę teraz sposób w jaki umieszczamy komponenty. Otóż należy kliknąc na odpowiedni komponent (np. Button - Przycisk) znajdujący się na palecie:
(siódmy od lewej), a następnie umieszczamy go klikając raz na formę. W ten sposób umieściliśmy komponent :)
Piszemy Edytor tekstu
Obróbka kosmetyczna
Na początku należy umieścić wszystkie komponenty i przygotować formularz. Po uruchomieniu Delphi'ego domyślnie tworzy się nowa aplikacja (pusty formularz). Na formularzu układamy (wybierając z palety element i klikając na formularzu) ToolBar [Zakładka Win32],

Teraz kolej na przyciski formatowania. Muszą być to być przyciski innego typu (tzw. SpeedButton'y by można je było wcisnąć i zostawić wciśnięte).
Wybieramy więc z palety 'Additional' komponent SpeedButton i wstawiamy go na formę. Zaznaczamy go i przechodzimy do Inspektora Obiektów, w którym odnajdujemy właściwość Caption i zmieniamy na 'Wytłuszczenie'. W ten sposób zmieniamy widoczną etykiete przycisku.
Wstawiamy jeszcze dwa tego typu przyciski (SpeedButton z palety Additional) i nadajemy im kolejno etykiety 'Pochylenie' i 'Podkreślenie'.
Zaznaczamy przycisk odpowiadający wytłuszczeniu i w inspektorze obiektów odnajdujemy właściwość GroupIndex, którą zmieniamy na 1, następnie odnajdujemy właściwość 'AllowAllUp' i zmieniamy ją na True.
Zaznaczamy przycisk odpowiadający pochyleniu i w inspektorze obiektów odnajdujemy właściwość GroupIndex, którą zmieniamy na 2, następnie odnajdujemy właściwość 'AllowAllUp' i zmieniamy ją na True.
Zaznaczamy przycisk odpowiadający podkreśleniu i w inspektorze obiektów odnajdujemy właściwość GroupIndex, którą zmieniamy na 3, następnie odnajdujemy właściwość 'AllowAllUp' i zmieniamy ją na True.
W ten sposób nasze przyciski będą się wciskać i pozostawać wciśnięte niezależnie od siebie.
Znów klikamy na ToolBar (prawym przyciskiem myszy) i wybieramy 'New Separator'. Pojawiła się jakby pionowa linia. Służy ona do oddzialania grup przycisków i nie ma znaczenia w działaniu programu tj. możemy równie dobrze o niej zapomnieć. Przeciągamy ową linię między przyciski 'Zapisz', a 'Wytłuszczenie'. W ten sposób oddzieliliśmy przyciski standardowe od przycisków formatowania.
Kolejnym krokiem jest umieszczenie na formularzu komponentu RichEdit [Zakładka Win32]. Po jego umieszczeniu klikamy nań, a w inspektorze obiektów odszukujemy i wybieramy z właściwości 'Align' wartość 'alClient'. Służy ona do dystrybuowania miejscem zajmowanym przez komponent na formie. Od tej chwili bezwzględnie czy zmaksymalizujemy nasz program, czy nie kontrolka (komponent) RichEdit zawsze będzie zajmował pozostałą część formy.
Ustawiliśmy RichEdit, ale w jego polu coś piszę: 'RichEdit1'??? Aby to zmienić musimy kliknąć na niego i z inspektora obiektów wybrać 'Lines' (klikajta te trzy kropki). Tym sposobem otworzyliśmy okno umożliwiające nam wpisane stałej treści komponentu. Usuwamy napis 'RichEdit1' i klikamy na OK. Mamy już puste pole :)
Kolejnym krokiem jest zmiana nazwy komponentu 'RichEdit1' na 're' (zmieniamy właściwość 'Name' w inspektorze obiektów na wartość 're').
Ostatnim krokiem jest umieszczenie na formularzu komponentów 'SaveDialog' i 'OpenDialog'. Służą one do wyświetlania popularnego okienka służącego do zapisywania czy otwierania dokumentu. Znajdują się one na zakładce 'Dialogs'.
Oki, skończyliśmy robotę z wyglądem. Teraz coś bardziej zaawansowanego...
Piszemy program...
Zaznaczam tutaj, że do przełączania się między edytorem kodu, a formularzem posłuży nam klawisz F12. Klikamy teraz podwójnie na przycisk 'Nowy'. Ukazuje się nam edytor kodu, w którym widzimy na razie coś takiego:
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
end;
Pomiędzy słówka 'begin' i 'end' będziemy wpisywali kod procedury tworzącej nam nowy dokument. Czyli po kliknięciu na przycisk 'Nowy' program ma wyczyścić zawartość komponentu 'RichEdit' ('re') (w tym wypadku wpisany przez użytkownika tekst). Instrukcja wykonująca tę czynność jest banalna:
procedure TForm1.ToolButton1Click(Sender: TObject);
begin
re.Clear;
end;
Kod przycisku Otwórz uzupełniamy następująco (musimy przejść do widoku formy - klawisz F12 - i kliknąć dwukrotnie przycisk 'Otwórz')
procedure TForm1.ToolButton2Click(Sender: TObject);
begin
If OpenDialog1.Execute Then // Wywołanie okna służącego do otwierania plików
re.Lines.LoadFromFile(OpenDialog1.FileName); // Wczytanie zawartości pliku w RichEdit
end;
Tu mamy już coś trudniejszego. Pierwsza linijka wywołuje nam okno (otwiera je) otwierania pliku. Można ją tłumaczyć następująco: Jeśli OpenDialog1 jest otwarty to... OpenDialog właśnie w tej linijce się otwiera. Dziwne? Przyzwyczaicie się... Jeśli powyższe wytłumaczenie do Was nie przemawia to mogę wyjaśnić to w ten sposób: Obiekt OpenDialog1 posiada funkcję Execute() - służy ona do wyświetlania okna i zwraca pewną wartość po jego zamknięciu. Jeśli użytkownik zamknie okno wyboru pliku poprzez OK, funkcja Execute() zwróci True, jeśli natomiast kliknie Anuluj - funkcja zwróci False (i w tym przypadku w naszym programie nie zostaną wykonane czynności zawarte po słówku Then - czyli instrukcje wczytywania pliku do komponentu RichEdit (nazwanego u nas 're').)
Druga linia ładuje do RichEdit ('re') linijki zawarte w pliku wskazanym przez użytkownika. OpenDialog1.FileName to nic innego jak ścieżka do pliku, który chce otworzyć użytkownik.
Notka: Aby załadować do komponentu RichEdit jakiś plik np. informacje o autorze nie wyświetlając okna 'Otwórz plik...' zamiast tych dwóch linii możemy napisać:
procedure TForm1.ToolButton2Click(Sender: TObject);
begin
re.Lines.LoadFromFile('C:\autor.txt'); // Otworzenie pliku w RichEdit
end;
Jednak taki sposób w Edytorze tekstu nie jest nam potrzebny, gdyż przy każdym kliknięciu na przycisk 'Otwórz' do RichEdit'a ładowałby się nam plik C:\autor.txt.
Przyszła kolej na ostatni przycisk z serii Standard ;) Kod przycisku Zapisz uzupełniamy następująco:
procedure TForm1.ToolButton3Click(Sender: TObject);
begin
If SaveDialog1.Execute Then // Otworzenie okna 'Zapisz plik...'
Begin
re.PlainText := True; // Zwykły tekst
re.Lines.SaveToFile(SaveDialog1.FileName); // Zapisanie Lini RichEdit'a do pliku
end;
end;
Taki kod nie jest zbyt rozbudowany. Wywołując okno zapisu musimy ręcznie określać rozszerzenie dla naszego pliku np. plik.txt
W pierwszej linii mamy do czynienia z otworzeniem okna. Druga linia naszego kodu to słówko 'Begin' stawia się je wtedy go pod warunkim If ... Then mamy więcej niż jedną linie (zauważ, że w procedurze otwierania pliku nie było 'Begin' ponieważ kod warunku
If OpenDialog1.Execute Then
Miał tylko jedną linię czyli :
re.Lines.LoadFromFile(OpenDialog1.FileName);
Trzecia linika naszego kodu (procedura służąca do zapisywania pliku) to jakby skonwertowanie zawartości RichEdit na zwykły tekst tj. taki który można otworzyć za pomocą innego programu i nie pokażą się dziwne znaki jak :
{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fnil MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\fswiss\fcharset1 MS Sans Serif;}}
{\colortbl\red0\green0\blue0;}
\deflang1045\pard\plain\f2\fs16 ssssssssssssssss
\par }
Dziwne? To po prostu zapis formatowania tekstu (np. użyta czcionka itp.)
Czwarta linijka to zapisanie lini RichEdit'a do pliku o ścieżce tkwiącej w 'FileName'
Teraz mamy kolejne, trzy ostatnie przyciski formatowania:
- wytłuszczenie
- pochylenie
- podkreślenie
Uzupełniamy ich kod następująco:
Wytłuszczenie:
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
If SpeedButton1.Down Then
re.SelAttributes.Style:= re.SelAttributes.Style + [fsBold]
else
re.SelAttributes.Style:= re.SelAttributes.Style - [fsBold];
end;
Można to przetłumaczyć: Jeśli przycisk odpowiadający wytłuszczeniu jest wciśnięty to dodaj do zaznaczonego tekstu styl pogrubienia (fsBold), jeśli natomiast przycisk nie jest wciśnięty to odbierz zaznaczonemu fragmentowi tekstu styl pogrubienia. Dla pochylenia i podkreślenia postępujemy analogicznie.
Pochylenie:
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
If SpeedButton2.Down Then
re.SelAttributes.Style:= re.SelAttributes.Style + [fsItalic]
else
re.SelAttributes.Style:= re.SelAttributes.Style - [fsItalic];
end;
Podkreślenie:
procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
If SpeedButton3.Down Then
re.SelAttributes.Style:= re.SelAttributes.Style + [fsUnderline]
else
re.SelAttributes.Style:= re.SelAttributes.Style - [fsUnderline];
end;
Pogrubianie, pochylanie i podkreślanie tekstu zachowuje się już u nas tak jak w Wordzie:
Jeśli chcesz zobaczyć taki program, napisz: lukas.home.page@gmail.com .
Zapisywanie z użyciem różnych formatów plików:
Rozwiązałem ten problem następująco:
var
roz: integer;
begin
SaveDialog1.FileName := 'Dokument';
If SaveDialog1.Execute Then
Begin
roz := SaveDialog1.FilterIndex;
// Wybór rozszerzenia (roz=numer filtru rozszerzenia pliku)
If roz=1 Then
begin
SaveDialog1.FileName := SaveDialog1.FileName+'.tek';
end;
If roz=2 Then
begin
SaveDialog1.FileName := SaveDialog1.FileName+'.doc';
end;
If roz=3 Then
begin
re.PlainText := True; // wyłączanie formatowania tekstu
SaveDialog1.FileName := SaveDialog1.FileName+'.txt';
end;
If roz=4 Then
begin
re.PlainText := True; // wyłączanie formatowania tekstu
SaveDialog1.FileName := SaveDialog1.FileName+'.html';
end;
If roz=5 Then
begin
re.PlainText := True; // wyłączanie formatowania tekstu
SaveDialog1.FileName := SaveDialog1.FileName+'.pas';
end;
re.Lines.SaveToFile(SaveDialog1.FileName);
re.PlainText := False; // ponowne włączenie formartowania
end;
Należy w inspektorze obiektów (w komponencie SaveDialog1) wybrać Filter (pojawi się okno) i uzupełnić je następująco:
W ten sposób umożliwimy zapisanie pliku w wielu formatach...
Zakończenie
Mam nadzieję, że artykuł się podobał? Było coś dla początkujących, było dla 'średnio-zaawansowanych'. Wydaje mi się, że wszystko tłumaczyłem, ale jeśli czegoś nie rozumiesz - pisz: lukas.home.page@gmail.com
Do artykułu dołączam również
kod źródłowy pisanego edytora tekstu.





Podobne artykuly:
- Delphi - Piszemy własny odtwarzacz multimedialny
- KillAd
- Delphi - Budowa modułu
- Delphi - Jak pisać?
- Delphi - Pobieranie plików z Internetu
- Delphi - Potęga możliwości ShellExecute()
- Delphi - Zasoby
Skomentuj
Komentarze czytelników
-
- lukasz9646
- Sun, 12 December 2010, 0:04
- zastosowałem filters na rozszerzenia plików, ale po wybraniu rozszerzenia w okienku zapisu np txt zapisuje się sama nazwa pliku bez rozszerzenia.. jak to naprawić?
Odp: Jeśli chodzi o Pana problem, to rozumiem, że rozpoznaje Pan w kodzie wybrane rozszerzenie pliku (FilterIndex) i dokleja odpowiednie rozszerzenie do nazwy pliku? Nie wiem na jakim poziomie zaawansowania Pan jest, początkujący niestety często o tym zapominają. Jednym słowem należy, uzupełnić w Inspektorze Obiektów pole „Filters” okienka SaveDialog, a w procedurze zapisującej plik dodać kod odpowiedzialny za dodawanie do nazwy pliku rozszerzenia odpowiadającego wybranemu przez użytkownika. Robi się to w następujący sposób. Przypuśćmy, że na formularzu ma Pan komponent Memo, oraz przycisk Button. Kod zdarzenia OnClick przycisku Button powinien być następujący:
procedure TForm1.Button1Click(Sender: TObject);
var
rozszerzenie : string;
begin
if not SaveDialog1.Execute Then Exit;
rozszerzenie := Trim(ExtractFileExt(SaveDialog1.FileName));
if (rozszerzenie='') Then
begin
case (SaveDialog1.FilterIndex) of
1: rozszerzenie := '.txt';
2: rozszerzenie := '.sub';
3: rozszerzenie := '.html';
end;
end else
begin
// ponieważ nazwa pliku SaveDialog1.FileName zawiera już w tym wypadku rozszerzenie
rozszerzenie := '';
end;
Memo1.Lines.SaveToFile(SaveDialog1.FileName+rozszerzenie);
end;
-
- Damian
- Sat, 6 November 2010, 18:14
- Wszystko pięknie działa!! Wielkie dzięki za pomoc ;)
-
- Damian
- Fri, 5 November 2010, 20:19
- Witaj, mam pytanie. Pracuje wlasnie nad edytorem tekstu w delphi, i napotkalem problem, nie moge poprawnie użyć funkcji Alignment(Wysrodkowywanie tekstu, do lewej, do prawej...) w komponencie RichEdit. Czytałem na internecie w tej sprawie, lecz nie uzyskalem odpowiedzi. Dodam ,iz w komponencie Memo wszysttko dziala bez problemu. Delphi zachowuje się jakby poprostu nie umiał wykonać tej operacji. Jeżeli potrafisz mi pomóc prosze o odpowiedź.
Odp: Próbowałeś w ten sposób?:
RichEdit1.Paragraph.Alignment := taRightJustify;
-
- 1234
- Fri, 5 November 2010, 18:27
- Bardzo ciekawy i przydatny komentarz. Dzieki ;]
-
- Dżyszla
- Thu, 30 October 2008, 14:11
- Ten zapis do HTML i innych to taki pic na wodę trochę chyba ;)
-
- mam problem 2 :
- Thu, 1 May 2008, 15:04
- kurcze ten sam błąd co w odtwarzaczu :( Klkam na "pogrubienie" i błąd ...