// Es wird auf schwarzem Hintergrund Text in Großbuchstaben Zeile für
// Zeile eingerollt. Der obere und/oder der untere Teil der Schrift kann
// überschattet werden. Es ist wichtig, dass die Schriftfarbe relativ
// hell ist, ansonsten sieht man im Schatten Abstufungen oder der
// Schatten ist gar nicht zu sehen. Der Hintergrund sollte stets schwarz sein.
// Falls sie ihn trotzdem ändern wollen, muss er dann natürlich ausreichend
// dunkel sein. Die Anzahl der Buchstaben pro Textzeile darf 50 nicht
// überschreiten.

// Variante 1:
// Der Text wird zeilenweise nacheinander und untereinander von oben her eingerollt.

  Hier nur einzeilig als Demo (oberer Teil überschattet)
  Drei Zeilen komplett eingerollt


// Getestet mit D4 unter XP

type 
  TForm1 = class(TForm) 
    Button1: TButton; 
    Timer1: TTimer; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure Timer1Timer(Sender: TObject); 
  private 
    { Private-Deklarationen } 
  public 
    procedure build(bm: TBitmap; s: string; FontC: TColor); 
    procedure start(f: array of TColor; mito, mitu: boolean; 
      geschw: cardinal; loesch: boolean); 
  end; 
 
var 
  Form1: TForm1; 
function GradientFill(hdc: HDC; pVertex: PTriVertex; 
  dwNumVertex: DWORD; pMesh: Pointer; 
  dwNumMesh: DWORD; dwMode: DWORD): Boolean; stdcall; 
external 'gdi32.dll' name 'GdiGradientFill'; 
 
implementation 
 
{$R *.DFM} 
 
var 
  schrift: array[0..2] of string = ('Versuch', 'Delphi', 'Test'); 
  font1: array[0..2] of TColor = (clRed, clWhite, clFuchsia); 
  font2: array[0..2] of TColor = (clLime, clYellow, clAqua); 
  bmps: array of TBitmap; 
  welches, breit, hoch, step, diff: integer; 
  Rand: integer = 4; 
  Img: TImage; 
  schattenoben, schattenunten: TBitmap; 
  obenMit, untenMit: Boolean; 
  Hig: TColor = clBlack; 
 
procedure Verlauf(DC: HDC; x1, y1, x2, y2: integer; von, nach: TColor); 
type 
  TVertex = packed record 
    x, y: Integer; 
    rot, gruen, blau, Alpha: Word; 
  end; 
const 
  VertexCount = 2; 
var 
  Vertex: array[0..VertexCount - 1] of TVertex; 
  TVRect: TGradientRect; 
begin 
  von := ColorToRGB(von); 
  nach := ColorToRGB(nach); 
  Vertex[0].x := x1; 
  Vertex[0].y := y1; 
  Vertex[0].rot := getrvalue(von) shl 8; 
  Vertex[0].gruen := getgvalue(von) shl 8; 
  Vertex[0].blau := getbvalue(von) shl 8; 
  Vertex[0].Alpha := 0; 
  Vertex[1].x := x2; 
  Vertex[1].y := y2; 
  Vertex[1].rot := getrvalue(nach) shl 8; 
  Vertex[1].gruen := getgvalue(nach) shl 8; 
  Vertex[1].blau := getbvalue(nach) shl 8; 
  Vertex[1].Alpha := 0; 
  with TVREct do begin 
    UpperLeft := 0; 
    LowerRight := 1; 
  end; 
  GradientFill(DC, @Vertex[0], VertexCount, @TVREct, 1, GRADIENT_FILL_RECT_V); 
end; 
 
procedure TForm1.build(bm: TBitmap; s: string; FontC: TColor); 
var 
  r: TRect; 
begin 
  bm.width := breit; 
  bm.height := hoch - diff; 
  with bm.canvas do begin 
    Font.Color := FontC; 
    r := Cliprect; 
    brush.color := Hig; 
    fillrect(r); 
    drawtext(handle, pchar(s), -1, r, 
      dt_singleline or dt_center); 
  end; 
end; 
 
procedure TForm1.FormCreate(Sender: TObject); 
var 
  x, b: integer; 
  tm: tagTEXTMETRICA; 
begin 
  Timer1.enabled := false; 
  breit := -1; 
  img := TImage.create(self); 
  img.visible := false; 
  img.parent := self; 
  img.autosize := true; 
  setlength(bmps, length(schrift)); 
  for x := 0 to high(bmps) do begin 
    bmps[x] := TBitmap.create; 
    schrift[x] := copy(ansiuppercase(schrift[x]), 1, 50); 
    with bmps[x].canvas do begin 
      Font.Name := 'Arial'; // sollte TrueType sein 
      Font.size := 20; 
      Font.style := [fsBold]; 
      b := TextWidth(schrift[x]); 
      if b > breit then breit := b; 
    end; 
  end; 
  GetTextMetrics(bmps[0].canvas.handle, tm); 
  diff := tm.tmInternalLeading + tm.tmExternalLeading; 
  hoch := tm.tmHeight; 
  breit := breit + Rand * 2; 
  with img.picture.bitmap, canvas do begin 
    width := breit; 
    height := hoch * length(bmps) + Rand; 
  end; 
  schattenoben := TBitmap.create; 
  schattenoben.width := breit; 
  schattenunten := TBitmap.create; 
  schattenunten.width := breit; 
  schattenoben.height := round(hoch / 2.5); 
  schattenunten.height := schattenoben.height; 
end; 
 
procedure TForm1.FormDestroy(Sender: TObject); 
var 
  x: integer; 
begin 
  img.free; 
  for x := 0 to high(bmps) do bmps[x].free; 
  bmps := nil; 
  schattenoben.free; 
  schattenunten.free; 
end; 
 
procedure TForm1.Timer1Timer(Sender: TObject); 
begin 
  with img.canvas do begin 
    copyrect(rect(0, welches * (bmps[welches].height + diff), width, step + 
      welches * (bmps[welches].height + diff)), 
      bmps[welches].canvas, rect(0, bmps[welches].height - step, 
      width, bmps[welches].height)); 
    if obenMit then 
      bitblt(handle, 0, welches * (bmps[welches].height + diff), img.width, 
        schattenoben.height + diff, schattenoben.canvas.handle, 0, 0, SRCAND); 
    if untenMit then 
      bitblt(handle, 0, hoch + welches * (bmps[welches].height + diff) - 
        schattenunten.height, img.width, hoch + diff, 
        schattenunten.canvas.handle, 0, 0, SRCAND); 
  end; 
  inc(step); 
  if step > bmps[welches].height + rand div 2 
    then begin 
    step := 1; 
    inc(welches); 
    if welches > high(bmps) then 
      Timer1.enabled := false; 
  end; 
end; 
 
procedure TForm1.start(f: array of TColor; mito, mitu: boolean; 
  geschw: cardinal; loesch: boolean); 
var 
  x: integer; 
begin 
  obenMit := mito; 
  untenMit := mitu; 
  verlauf(schattenoben.canvas.handle, 0, 0, breit, schattenoben.height, 
    Hig, clWhite); 
  verlauf(schattenunten.canvas.handle, 0, 0, breit, schattenunten.height, 
    clWhite, Hig); 
  for x := 0 to high(bmps) do 
    build(bmps[x], schrift[x], f[x]); 
  welches := 0; 
  img.left := 200; 
  img.top := 50; 
  with img, picture.bitmap.canvas do begin 
    brush.color := Hig; 
    if loesch then fillrect(cliprect); 
    visible := true; 
  end; 
  step := 1; 
  Timer1.interval := geschw; 
  Timer1.enabled := true; 
end; 
 
 
// Beispielaufruf 
 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  Button1.enabled := false; 
  start(font1, true, false, 50, true); 
  repeat 
    application.processmessages; 
  until not Timer1.enabled; 
  start(font2, true, false, 50, false); 
  repeat 
    application.processmessages; 
  until not Timer1.enabled; 
  Button1.enabled := true; 
end;


//-----------------------------------------------------------


// Variante 2:
// Der Text wird nacheinander in eine einzige Zeile von unten her eingerollt.
// Die Variable
Pause entscheidet, wie lange eine Textzeile stehen bleit,
// bevor sie weitergerollt wird. Bei negativen Werten muss manuell mittels
// Klick auf Button2 weitergerollt werden. Die Variable
Loop läßt bei True
// den Text ständig wiederholen. Setzt man die Variable
Rollen auf False,
// werden die Textzeilen schlagartig angezeigt. Dafür sollte
Pause einen
// ausreichenden Wert besitzen, da sonst die Zeilen einfach "vorbeirauschen".
// Die Variable
Geschw ist für den Intervall des Timers verantwortlich und
// sollte nicht über 100 ms liegen. Die Anzahl der Buchstaben pro Textzeile
// darf 50 nicht überschreiten.

  Hier nur eine Zeile Text als Demo (mit Schatten)
type 
  TForm1 = class(TForm) 
    Button1: TButton; 
    Timer1: TTimer; 
    Button2: TButton; 
    Button3: TButton; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure Timer1Timer(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    procedure Button3Click(Sender: TObject); 
  private 
    { Private-Deklarationen } 
  public 
    procedure build; 
  end; 
 
var 
  Form1: TForm1; 
function GradientFill(hdc: HDC; pVertex: PTriVertex; 
  dwNumVertex: DWORD; pMesh: Pointer; 
  dwNumMesh: DWORD; dwMode: DWORD): Boolean; stdcall; 
external 'gdi32.dll' name 'GdiGradientFill'; 
 
implementation 
 
{$R *.DFM} 
 
var 
  geschw, welches, breit, hoch, step, rand, pause: integer; 
  schattenoben, schattenunten: TBitmap; 
  stopp, loop, rollen: boolean; 
  FontC: array of TColor; 
  durch: boolean = true; 
  mitSchatten: boolean; 
  schrift: Tstringlist; 
  HigC: TColor; 
  bmp: TBitmap; 
  Img: TImage; 
 
procedure Verlauf(DC: HDC; x1, y1, x2, y2: integer; von, nach: TColor); 
type 
  TVertex = packed record 
    x, y: Integer; 
    rot, gruen, blau, Alpha: Word; 
  end; 
const 
  VertexCount = 2; 
var 
  Vertex: array[0..VertexCount - 1] of TVertex; 
  TVRect: TGradientRect; 
begin 
  von := ColorToRGB(von); 
  nach := ColorToRGB(nach); 
  Vertex[0].x := x1; 
  Vertex[0].y := y1; 
  Vertex[0].rot := getrvalue(von) shl 8; 
  Vertex[0].gruen := getgvalue(von) shl 8; 
  Vertex[0].blau := getbvalue(von) shl 8; 
  Vertex[0].Alpha := 0; 
  Vertex[1].x := x2; 
  Vertex[1].y := y2; 
  Vertex[1].rot := getrvalue(nach) shl 8; 
  Vertex[1].gruen := getgvalue(nach) shl 8; 
  Vertex[1].blau := getbvalue(nach) shl 8; 
  Vertex[1].Alpha := 0; 
  with TVREct do begin 
    UpperLeft := 0; 
    LowerRight := 1; 
  end; 
  GradientFill(DC, @Vertex[0], VertexCount, @TVREct, 1, GRADIENT_FILL_RECT_V); 
end; 
 
procedure TForm1.build; 
var 
  tm: TTextMetric; 
  x, b: integer; 
  r: TRect; 
begin 
  with bmp.canvas do begin 
    Font.Name := 'Arial'; 
    Font.size := 20; 
    Font.style := [fsBold]; 
    brush.color := HigC; 
    GetTextMetrics(handle, tm); 
    hoch := tm.tmHeight; 
    breit := -1; 
    Rand := round(sqrt(Font.size) * 2); 
    for x := 0 to schrift.count - 1 do begin 
      schrift[x] := copy(ansiuppercase(schrift[x]), 1, 50); 
      b := TextWidth(schrift[x]); 
      if b > breit then breit := b; 
    end; 
    breit := breit + rand * 2; 
    bmp.width := breit; 
    bmp.height := hoch * (schrift.count + ord(loop)) + 1; 
    fillrect(cliprect); 
  end; 
  with img.picture.bitmap do begin 
    width := breit; 
    height := hoch + rand * 2 - 1; 
    with canvas do begin 
      brush.color := HigC; 
      fillrect(cliprect); 
    end; 
  end; 
  schattenoben.width := breit; 
  schattenunten.width := breit; 
  schattenoben.height := round(hoch / 3.33); 
  schattenunten.height := round(hoch / 1.75); 
  verlauf(schattenoben.canvas.handle, 0, 0, breit, schattenoben.height, 
    HigC, clWhite); 
  verlauf(schattenunten.canvas.handle, 0, 0, breit, schattenunten.height, 
    clWhite, HigC); 
  with bmp.canvas do begin 
    for x := 0 to schrift.count - 1 do begin 
      Font.color := FontC[x]; 
      r := rect(0, x * hoch, breit, x * hoch + hoch); 
      drawtext(handle, pchar(schrift[x]), -1, r, 
        dt_singleline or dt_center); 
    end; 
    if loop then begin 
      Font.color := FontC[0]; 
      r := rect(0, schrift.count * hoch, breit, 
        schrift.count * hoch + hoch); 
      drawtext(bmp.canvas.handle, pchar(schrift[0]), -1, r, 
        dt_singleline or dt_center); 
    end; 
  end; 
  welches := 0; 
  step := hoch * ord(not rollen); 
  Timer1.interval := 1 + geschw * ord(rollen); 
end; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  Timer1.enabled := false; 
  img := TImage.create(self); 
  img.visible := false; 
  img.parent := self; 
  img.autosize := true; 
  bmp := TBitmap.create; 
  schattenoben := TBitmap.create; 
  schattenunten := TBitmap.create; 
  schrift := TStringlist.create; 
  schrift.add('Versuch'); 
  schrift.add('Delphi'); 
  schrift.add('Test'); 
  setlength(FontC, 3); 
  FontC[0] := clYellow; 
  FontC[1] := clLime; 
  FontC[2] := clAqua; 
end; 
 
procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  schrift.free; 
  img.free; 
  bmp.free; 
  schattenoben.free; 
  schattenunten.free; 
  FontC := nil; 
end; 
 
procedure TForm1.Timer1Timer(Sender: TObject); 
var 
  zeit: cardinal; 
begin 
  with img.canvas do begin 
    copyrect(rect(0, rand, width, hoch + rand), 
      bmp.canvas, rect(0, step - hoch + welches * hoch, 
      width, step + welches * hoch)); 
    if mitSchatten then begin 
      bitblt(handle, 0, rand, img.width, schattenoben.height + rand, 
        schattenoben.canvas.handle, 0, 0, SRCAND); 
      bitblt(handle, 0, hoch - schattenunten.height + rand, img.width, 
        hoch + rand, schattenunten.canvas.handle, 0, 0, SRCAND); 
    end; 
  end; 
  application.processmessages; 
  if stopp or application.terminated 
    then begin 
    Timer1.enabled := false; 
    exit; 
  end; 
  inc(step, 1 + ord(not rollen) * hoch); 
  if step >= hoch 
    then begin 
    Timer1.enabled := false; 
    step := 0; 
    inc(welches, 1 + ord((welches = 0) and not rollen)); 
    if loop and (welches > schrift.count) then welches := 1; 
    if pause < 0 then 
      stopp := true; 
    zeit := gettickcount + dword(pause); 
    repeat 
      application.processmessages; 
      if stopp or application.terminated 
        then begin 
        Timer1.enabled := false; 
        exit; 
      end; 
    until gettickcount >= zeit; 
    if welches <= schrift.count then 
      Timer1.enabled := true 
    else durch := true; 
  end; 
end; 
 
// Starten 
 
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  if schrift.count = 0 then schrift.add('-- Nix --'); 
  while length(FontC) < schrift.count do begin 
    setlength(FontC, length(FontC) + 1); 
    FontC[high(FontC)] := clwhite; 
  end; 
  HigC := clBlack; 
  pause := 1000; 
  img.left := 100; 
  img.top := 25; 
  mitSchatten := true; 
  stopp := false; 
  durch := false; 
  loop := false; 
  rollen := true; 
  geschw := 50; 
  build; 
  Timer1.enabled := true; 
  img.visible := true; 
end; 
 
// Anhalten / weiterlaufen lassen 
 
procedure TForm1.Button2Click(Sender: TObject); 
begin 
  if stopp and not durch then begin 
    stopp := false; 
    Timer1.enabled := true; 
  end else 
    stopp := true; 
end; 
 
// Grundstellung 
 
procedure TForm1.Button3Click(Sender: TObject); 
begin 
  Timer1.enabled := false; 
  stopp := true; 
  durch := true; 
  with img.canvas do fillrect(cliprect); 
  // und bei Bedarf: 
  // img.visible := false; 
end; 


 

Zugriffe seit 6.9.2001 auf Delphi-Ecke