Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Memo zeichen pro zeile (https://www.delphipraxis.net/165136-memo-zeichen-pro-zeile.html)

Mystery 15. Dez 2011 17:45

Memo zeichen pro zeile
 
ich habe eine, vermutlich simple frage mit simpler erklärung :)

ich habe ein memo das immer so groß und breit ist wie der ganze screen. Jetzt möchte ich einen allgemeinen Code der ausgibt wieviele zeichen in eine zeile passen.

Ich könnte jetzt schauen wieviele das bei mir wären bei meiner bildschirmauflösung. ich würde es aber auch gern für alle anderen wissen, sodass ich ein allgemeines programm schreiben kann.

Beispiel das Memo wird mit lauter nullen gefüllt mit einem timer sodass jede sekunde eine dazukommt.
Jetzt möchte ich wissen wann die erste zeile voll ist und ab wann die nächste 0 demnach in zeile 2 erscheinen würde

Darkface 15. Dez 2011 18:03

AW: Memo zeichen pro zeile
 
Auch wenn es an deiner eigentlichen Frage ein wenig vorbei geht möchte ich darauf hinweisen, das die meißten Schriftarten unterschiedliche Breiten pro Zeichen haben. So ist es ein gewaltiger Unterschied ob du das Memo mit lauter "i"-en füllst oder ob du z.B. "@"'s nimmst. Um das zu Umgehen solltest du eine Konsolen-Schriftart als Memo Font benutzen.

Bummi 15. Dez 2011 18:09

AW: Memo zeichen pro zeile
 
ich schließe mich meinem Vorredner an, wenn Du eine entsprechende Schrift verwendest könntest DU hiermit weiterkommen:
Delphi-Quellcode:
Function GetMemoCharactersPerLine(M:TMemo):Integer;
var
  DC:THandle;
  C:TCanvas;
begin
  Result := 0;
  C:=TCanvas.Create;
  DC := GetDC(M.Handle);
  try
      C.Handle := DC;
      C.Font.Size := M.Font.Size;
      Result := C.TextWidth('X');
  finally
    ReleaseDC(M.Handle,DC);
    C.Free;
  end;
end;

Function GetMemoTextWidth(M:TMemo;Const s:String):Integer;
var
  DC:THandle;
  C:TCanvas;
begin
  Result := 0;
  C:=TCanvas.Create;
  DC := GetDC(M.Handle);
  try
      C.Handle := DC;
      C.Font.Size := M.Font.Size;
      Result := C.TextWidth(s);
  finally
    ReleaseDC(M.Handle,DC);
    C.Free;
  end;
end;


procedure TForm2.Button1Click(Sender: TObject);
begin
  memo1.Font.Size := 8;
  Showmessage( IntToStr(GetMemoCharactersPerLine(Memo1)));
  memo1.Font.Size := 90;
  Showmessage( IntToStr(GetMemoCharactersPerLine(Memo1)));
  Showmessage(IntToStr(GetMemoTextWidth(Memo1,'Nasenbär')));
end;

Mystery 15. Dez 2011 18:32

AW: Memo zeichen pro zeile
 
Der Quellcode gibt so im moment immer die Zahlen 8, 85 und schließlich 525 aus ?!

Bummi 15. Dez 2011 18:36

AW: Memo zeichen pro zeile
 
Die erste der aufgerufenen Funktionen liefert die die Zeichenbreite in Pixel zurück , unter der Annahme das Du eine Proportionale Schrift gewählt hat kannst Du so ermitteln wieviele Zeichen in eine Zeile passen, Breite des Memos / Rückgabewert (gegf. muß man von der Breite noch ein paar Pixel abziehen wegen der Margins/Ränder).

Die zweite Funktion liefert die Breite des übergebenen Textes in Pixeln.

DeddyH 15. Dez 2011 18:59

AW: Memo zeichen pro zeile
 
Wenn man allerdings lediglich ermitteln möchte, wie oft derselbe String in eine Zeile passt, könnte es so klappen (Fehler vorbehalten):
Delphi-Quellcode:
function GetStringCountPerLine(Memo: TMemo; const aString: string): integer;
var
  tempDC: hDC;
  cv: TCanvas;
  NeededWidth, Margins, XOffset: integer;
begin
  Result := -1;
  if Assigned(Memo) then
    begin
      tempDC := CreateCompatibleDC(0);
      if tempDC <> 0 then
        try
          cv := TCanvas.Create;
          try
            cv.Handle := tempDC;
            cv.Font.Assign(Memo.Font);
            NeededWidth := cv.TextWidth(aString);
            Margins := SendMessage(Memo.Handle, EM_GETMARGINS, 0, 0);
            XOffset := (Margins shr 16) + (Margins and $0000FFFF);
            if NeededWidth <> 0 then
              Result := (Memo.ClientWidth - XOffset) div NeededWidth
            else
              Result := 0;
          finally
            cv.Free;
          end;
        finally
          DeleteDC(tempDC);
        end;
    end;
end;

Mystery 15. Dez 2011 19:57

AW: Memo zeichen pro zeile
 
Soweit so gut:

Habe Schrift bei der alles gleich groß geschrieben wird. Außerdem Code der genau die Zeile füllt nicht mehr nicht weniger.

Was leider noch fehlt:

ich möchte wenn die zeile 1 gefüllt ist, dass der geschriebene Text, also zeile 1 im memo zu zeile 2 wird, also zeile 1 wieder frei wird.

wenn zeile 1 erneut gefüllt wurde soll zeile 1 zu zwei werden und zwei zu 3 usw. bis irgendwann zeile ca 15 nicht mehr auf den bildschirm passt.

Bummi 15. Dez 2011 20:03

AW: Memo zeichen pro zeile
 
Delphi-Quellcode:
var
 i:Integer;
begin
  for i := 2 to 10 do
    begin
    memo1.Lines.Insert(0,'');
    Memo1.lines[0] := Format('%d. Zeile',[i]);
    end;
end;

Mystery 15. Dez 2011 20:13

AW: Memo zeichen pro zeile
 
DANKE *_* werds mal probieren :-)

himitsu 15. Dez 2011 20:17

AW: Memo zeichen pro zeile
 
Wenn dir eigentlich alles egal ist, dann setze WordWrap auf True und füge deinen Text immer am Anfang ein.
Den rest macht das Memo alleine.

Delphi-Quellcode:
// S = dein neuer hinzuzufügender Text
Memo1.SelStart := 0;
Memo1.SelText := S + ' ';

Furtbichler 16. Dez 2011 06:55

AW: Memo zeichen pro zeile
 
Ausprobieren:
Delphi-Quellcode:
Function WieOftEinStringInEinMemoPasst (memo : TMemo; einString : String) : Integer;
Var
  text : String;

begin
  memo.WordWrap := true;
  memo.Lines.BeginUpdate;
  text := '';
  Try
    repeat
      inc(Result);
      text := text + einString;
      memo.Lines.Text := text;
    until memo.Lines.Count = 2;
    Dec (Result);
  finally
    memo.Lines.EndUpdate;
  end
end;
Andere Lösungen vertun sich manchmal um 1.

Übrigens würde ich statt dem GetDC Gedöns ein TControlCanvas nehmen. Ist einfacher.

Mystery 16. Dez 2011 12:50

AW: Memo zeichen pro zeile
 
Das klappt alles ganz gut :-)

Letzte Frage, dann bin ich fertig:
//anders gesagt das Programm ist fertig, will nur ein etwas anderes schreiben jetzt

Habe wieder ein canvas
dann 2 integer variablen a und b

a:=random(screen.width);
b:=random(screen.height);


Außerdem eine procedure
in meiner procedure zeichen(canv:Tcanvas ; farbe:Tcolor);
begin
with canv do begin
moveto(a,b);
//und hier soll er dann an der stelle (a,b) eine "1" schreiben..
kann man mit einem canvas zahlen wie 1 oder null an bestimmte stekllen auf das formular schreiben?
wenn ja wie sieht der befehl aus?

DeddyH 16. Dez 2011 12:57

AW: Memo zeichen pro zeile
 
Delphi-Referenz durchsuchenTCanvas.TextOut


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz