software center, download, programy, pliki, teledyski, mp3
Menu główne


strona główna
darmowy download
baza artykułów i porad
kontakt z nami
Programy
line Systemy
line Artykuły PDF

Security

line Skanery
line Sniffery
line Security

Windows

line Użytkowe
line Przeglądarki graficzne
line Kodeki
line Narzędzia plikowe
line Narzędzia dyskowe
line Narzędzia systemowe
line Sterowniki
line Szyfrowanie danych
line Zarządzanie hasłami
line Zarządzanie rejestrem
line Łaty i Patche
line Zarządzanie pamięcią
line Synchronizacja czasu
line Nagrywanie płyt
line Free Antivirus (Darmowe Antyvirusy)
line Sterowniki
line Obróbka dźwięku
line Edycja wideo

Internetowe

line Bezpieczeństwo
line Programy p2p
line Komunikatory
line Dodatki do przeglądarek
line Klienty poczty elektronicznej
line Narzędzia Antyspamowe
line Przeglądarki grup dyskusyjnych
line Przeglądarki Offline
line Serwery poczty elektronicznej
line Telefonia komórkowa
line Wyszukiwarki internetowe
line Zdalny dostęp
line Cybernianie
line Klienty FTP
line Narzędzia internetowe
line Prywatnośc
line Przeglądarki internetowe
line Serwery FTP
line Serwery WWW
line Wspomagacze ściągania
line Zarządzanie siecią lokalną

Tuning Systemu

line Diagnostyka i testowanie
line Inne
line Rozszerzenia pulpitu
line Tapety na pulpit
line Tuning Systemu
line Ikony
line Powłoki
line Tuning sprzętu
line Wygaszacze ekranu

Programowanie

line Kompilatory
line Biblioteki i komponenty
line Bazy danych
line Edytory programistyczne
line Środowiska programistyczne
line Debugery
line Tworzenie wersji instalacyjnych

Webmastering

line Użytkowe
line Kursy

Linux

line Użytkowe
line Internetowe
line Multimedialne

Programy biurowe

line Programy dla firm
line Pakiety biurowe
line Administracja
line Edytory tekstu
line Grafika prezentacyjna
line Kadry i płace
line Wspomaganie projektowania
line Zarządzanie projektami
line Bazy danych
line Finanse i księgowośc
line Handel
line Programy ewidencyjne
line Zarządzanie informacją osobistą (PIM)
Nasze serwisy

Programy download
Bramka SMS
Download
Gry
Gry Online
Linux
Muzyka
Newsy
Programowanie
Program TV
Śmieszne Filmy
Teledyski
Kobiety


Artykuły > Programowanie w Delphi > Hint - Kolorowanie składni
Witam wszystkich.
O czym będzie ten artykuł? Myślę, że tytuł przemawia sam za siebie jednak sprecyzuję. Zajmiemy się hintami czyli dymkami podpowiedzi a konkretniej ich "ulepszaniem". Ostatnio byłem na Torry'm i zaciekawił mnie jeden z komponentów - HTMLHint - jest to komponent, który umożliwia m.in. stosowanie w hintach różnych kolorów czcionki, stylów, wstawianie obrazków itp. Wszystko dobrze, tylko nie darmowe...

O hintach pisał już Adam Boduch, więc nie będziemy się zajmowali samymi hintami jako takimi, lecz właśnie tymi właściwościami które wcześniej wymieniłem a więc kolorowaniem składni i stylami czcionki czyli pogrubianiem, kursywą, podkreśleniem i przekreśleniem.

Na samym początku należałoby się zastanowić nad tym w jaki sposób chcemy wykonać nasze zadanie. Oczywiście musimy stworzyć klasę pochodną od THintWindow i zająć się własnym "malowaniem" płótna hinta. Jednak wcześniej musimy zastanowić się nad tym w jaki sposób będziemy chcieli by kolory czcionki zmieniały się zgodnie z tym jak chcemy. Powiedzmy, że chcesz napisać "To jest przykładowy hint" przy czym "To" ma być czerwone "jest" fioletowe, "przykładowy" żółte i wreszcie "hint" zielone. Można by kazać programowi kodować poszczególne wyrazy właśnie tymi kolorami ale jest to bezsensowne, gdyż na przykład hint dotyczący innego komponentu chcemy kolorować w inny sposób. Musimy więc zastosować "kodowanie" hinta, które później w czasie wyświetlania będzie "rozkodowywane".
Dla naszych rozważań przyjmiemy następujące kodowanie:

<0> - kolor zerowy
<1> - kolor pierwszy
...
<9> - kolor dziewiąty
<b> - włączenie / wyłączenie pogrubienia
<u> - włączenie / wyłączenie podkreślenia
<i> - włączenie / wyłączenie kursywy
<s> - włączenie / wyłączenie przekreślenia

Jak już pewnie zdążyliście się domyślić następujące kodowanie będzie się wpisywało we właściwość HINT danego komponentu w postaci np. "<1>To <2>jest <3>przykładowy <5><b><u>hint". W porządku teraz zajmijmy się tworzeniem naszego "dymka".

TCodeHint=class(THintWindow)
public
  procedure ActivateHint(ARect: TRect; const AHint: string); override;
  procedure Paint; override;
end


Zajmijmy się najpierw rysowaniem czyli procedure Paint ponieważ to przede wszystkim tutaj rozgrywa się cały główny problem. Zadeklarujemy sobie zmienną licznik typu integer, która będzie odpowiedzialna za ustalenie pozycji znaku, który obecnie analizujemy a także zmienną pozycja typu  TPoint, która będzie odpowiadała za pozycję pisanego znaku na canvas hint'a.
Najpierw napiszę kod a później go omówię:

procedure TCodeHint.Paint;
var
  pozycja: TPoint;
  licznik: integer;
begin
  licznik:=0;
  with Canvas do
    begin
     Font.Color := clBlack; // domyślny kolor jeżeli nie wpisano kodu
     Font.Style:=[]; // domyślny styl jeżeli nie wpisano kodu
     repeat // powtarzanie pętli tak długo aż skończą się znaki w hint

       licznik := licznik+1;
       if Caption[licznik] <> '<' then
       begin
         if (Caption[licznik]=Chr(13)) and (Caption[licznik+1]=Chr(10)) then // następna linijka hinta
           begin
             pozycja.y := pozycja.y+TextHeight('X');
             pozycja.x := ClientRect.Left+2; // 2 - margines
             licznik := licznik+1;
           end
         else
           begin
             TextOut(pozycja.x, pozycja.y, Caption[licznik]);
             pozycja.x:=pozycja.x+TextWidth(Caption[licznik]); // ustal nowa pozycje
           end;
       end
       else // pojawił się znacznik
       begin

         if licznik+2<=Length(Caption) then
         begin
           case Caption[licznik+1] of // ustawienie stylu zależnie od znacznika
             'b': if Font.Style=Font.Style+[fsBold] then Font.Style:=Font.Style-[fsBold]
                  else Font.Style:=Font.Style+[fsBold];
             'i': if Font.Style=Font.Style+[fsItalic] then Font.Style:=Font.Style-[fsItalic]
                  else Font.Style:=Font.Style+[fsItalic];
             'u': if Font.Style=Font.Style+[fsUnderline] then Font.Style:=Font.Style-[fsUnderline]
                  else Font.Style:=Font.Style+[fsUnderline];
             's': if Font.Style=Font.Style+[fsStrikeOut] then Font.Style:=Font.Style-[fsStrikeOut]
                  else Font.Style:=Font.Style+[fsStrikeOut];
             '0': Font.Color:=clBlack;
             '1': Font.Color:=clRed;
             '2': Font.Color:=clBlue;
             '3': Font.Color:=clGreen;
             '4': Font.Color:=clAqua;
             '5': Font.Color:=clFuchsia;
             '6': Font.Color:=clLime;
             '7': Font.Color:=clPurple;
             '8': Font.Color:=clMaroon;
             '9': Font.Color:=clWhite;
           end;
           licznik:=licznik+2;
         end;
       end;

     until licznik>=Length(Caption);
   end;
end;


Wpierw ustalamy domyślny kolor czcionki i jej styl - gdybyśmy tego nie zrobili to hint przyjmowałby taki kolor jaki był używany przy ostatnim wyświetleniu. Możesz to sprawdzić kładąc np. dwa Buttony i w hint jednego wpisać hint zakodowany a w drugim bez kodowania. Między pętlą repeat a until wykonuje się kod tak długo aż zostaną przeanalizowane wszystkie znaki. Przy każdym przejściu przez pętlę zostaje zwiększony licznik - pozycja znaku. Jeżeli napotkamy na znak "<" analizujemy czy pojawił się kod czy nie. Rozwiązujemy to sprawdzając jaki jest następny znak. Jeżeli jest to jeden z uwzględnionych przez nas znaków wówczas dokonujemy zmian w stylu czcionki lub w jej kolorze. Następnie przeskakujemy o dwa znaki (pomijamy znak ">"). Jeżeli jednak to nie jest znak z naszego kodowania lub nie trafiliśmy na znak "<" wówczas rysujemy go na płótnie hint'a. Tłumaczenia wymaga ta linia:

pozycja.x := pozycja.x + TextWidth(Caption[licznik]);


Jest ona po to abyśmy wiedzieli gdzie mamy rozpocząć rysowanie kolejnego znaku. Analogicznie jest z:


if (Caption[licznik]=Chr(13)) and (Caption[licznik+1]=Chr(10)) then // następna linijka hinta
           begin
             pozycja.y := pozycja.y+TextHeight('X');
...


Sprawdzamy czy znaki nie tworzą znaku następnej linii (jeżeli tego nie uwzględnimy to hint będzie wprawdzie wyświetlał dwie i więcej linijek ale tekst pojawi się tylko w pierwszej linijce).

Myślę, że powinno to być zrozumiałe. Teraz powinniśmy się zająć procedurą ActivateHint. Jednak proponuję ci dać na razie tę procedurę jako komentarz w np. w znaki {} lub //
(czyli
TCodeHint=class(THintWindow)
public
  // procedure ActivateHint(ARect: TRect; const AHint: string); override;
  procedure Paint; override;
end;
)

W FormCreate uaktywnij nasz stworzony hint:
  HintWindowClass := TCodeHint;
  Application.ShowHint := false;
  Application.ShowHint := true


Daj na formę jakiś Button i wpisz mu we właściwość hint: "<b>Tego hinta niestety nie widać poprawnie" i nie zapomnij ustawić mu ShowHint na True. Uruchom program. Zauważyłeś coś? Nasz hint wyświetla się ale tekst nie jest cały. Wyłącz program i wpisz we właściwość hint Buttona: "<1>To <2>jest <3>przykładowy <5><b><u>hint".

Uruchom. Super, koloruje składnię tak jak chcieliśmy. Teraz widzimy cały tekst ale niestety pojawia się duży margines z prawej strony. Dlaczego? Ponieważ Windows dobrał wielkość hinta do długości wpisanego tekstu. Zapytasz czemu więc raz jest za mały a drugim razem za długi. Już tłumaczę - za pierwszym razem pogrubialiśmy tekst a za drugim kolorowaliśmy (no i na końcu też pogrubiliśmy i podkreśliliśmy). Jak więc pewnie się domyśliłeś zależy to od rodzaju czcionki a konkretniej jej stylu. I o to chodzi. Czcionki pogrubione, kursywa mają inną szerokość niż ta sama czcionka bez pogrubienia. To jeżeli chodzi o za mały rozmiar hinta. Zaś dodatkowy margines brał się z tego, że wpisywaliśmy dodatkowe znaki, które nie były przecież później rysowane. Musimy więc jakoś rozwiązać ten problem - musimy znać rozmiar potrzebny i taki wyświetlić. Stwórzmy więc funkcję, która nam to określi i umieśćmy ją w sekcji

private:
  function MaxHW (Tekst: string): TPoint;

function TCodeHint.MaxHW(Tekst: string): TPoint;
var
  pozycja: integer;
  licznik: integer;
  Max: TPoint;
  Plotno: TBitmap;
begin

  // ustalamy maksymalna szerokość i wysokość tekstu w hint

 Plotno:=TBitmap.Create;
 try
  Plotno.Width:=10; // rozmiary nie są istotne
  Plotno.Height:=10;

  Plotno.Canvas.Font.Assign(Form1.Font); // przypisanie czcionki
 
  pozycja:=2;
  licznik:=0;
  Max.x:=0; // wyzerowaie pozycji x
  Max.y:=0; // wyzerowanie pozycji y

  with Plotno.Canvas do // symulacja rysowania
    begin
     Font.Color:=clBlack;
     Font.Style:=[];
     Max.y:=2+TextHeight('X'); // wstępne ustalenie wysokości
     repeat
       licznik:=licznik+1;
       if Tekst[licznik] <> '<' then
       begin
         if (Tekst[licznik]=Chr(13)) and (Tekst[licznik+1]=Chr(10)) then
           begin
             if Max.x&lt;pozycja then Max.x:=pozycja;
             Max.y:=Max.y+TextHeight('X');
             pozycja:=2; // wyzerowanie pozycji x
             licznik:=licznik+1;
           end
         else
           begin
             pozycja:=pozycja+TextWidth(Tekst[licznik]); // ustal nowa pozycje
           end;
       end
       else // pojawił się znacznik
       begin

         if licznik+2<=Length(Tekst) then
         begin
           case Tekst[licznik+1] of // ustawienie stylu zależnie od znacznika
             'b': if Font.Style=Font.Style+[fsBold] then Font.Style:=Font.Style-[fsBold]
                  else Font.Style:=Font.Style+[fsBold];
             'i': if Font.Style=Font.Style+[fsItalic] then Font.Style:=Font.Style-[fsItalic]
                  else Font.Style:=Font.Style+[fsItalic];
             'u': if Font.Style=Font.Style+[fsUnderline] then Font.Style:=Font.Style-[fsUnderline]
                  else Font.Style:=Font.Style+[fsUnderline];
             's': if Font.Style=Font.Style+[fsStrikeOut] then Font.Style:=Font.Style-[fsStrikeOut]
                  else Font.Style:=Font.Style+[fsStrikeOut];
             // '0' .. '9' są nieistotne z pkt widzenia szerokości
           end;
           licznik:=licznik+2;

         end;
       end;

     if Max.x<pozycja then Max.x:=pozycja;
     until licznik>=Length(Tekst);

   end;
 finally
   Plotno.Free// zwolnienie bitmapy
 end;
 Result:=Max;
end;


Myślę, że powyższy kod powinien być wystarczająco czytelny - przeprowadzamy symulację jakbyśmy rysowali na hincie, tyle, że bez pokazywania efektu - w wyniku otrzymujemy wymiary nam potrzebne

Przystąpmy więc do oprogramowania ActivateHint:

procedure TCodeHint.ActivateHint (ARect: TRect; const AHint: string);
var
 Rozmiar: TPoint;
 PozycjaHinta: TPoint;
begin
 
 // ustalamy rozmiar i właściwości hinta
 Canvas.Font.Assign(Form1.Font);

 Caption  := AHint;

 Rozmiar := MaxHW(AHint);

 ARect.Right := ARect.Left + Rozmiar.x+4; // 4 - margines lewi i prawy
 ARect.Bottom:= ARect.Top + Rozmiar.y+4; // 4 - margines górny i dolny

 BoundsRect := ARect;

 PozycjaHinta := ClientToScreen(Point(0, 0));

 SetWindowPos(Handle, HWND_TOPMOST, PozycjaHinta.X, PozycjaHinta.Y, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE); // wyświetlamy hinta
end;


Nie ma tu wiele do tłumaczenia - ustalamy rozmiar ARect na podstawie funkcji która nam wyliczyła potrzebne wymiary i zwiększamy te rozmiary o 4 (po 2 piksele z każdej strony)
Następnie wyświetlamy hinta.

Tak wygląda cały kod:
(***********************************************)
(*                                                                *)
(*TCodeHint                                                         *)
(* Copyright (c) 2003 by Rafał J. Łabudek <21.04.2003>   *)
(* E - mail: mrrafi@interia.pl                                *)
(*                                                                 *)
(***********************************************)
unit ColorHint;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1=class(TForm)
    procedure FormCreate(Sender:
komentarz[2] |

programy download hacking program tv bramka sms teledyski kody do gier
trailery filmiki gry online antywirusy artykuły tutoriale systemy
© 2006-2009 haksior.com. Wszelkie prawa zastrzeżone.
Design by jPortal.info
0.017 |