Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Memo.Clear zeigt keinen Effekt - Falsche Anzeige (https://www.delphipraxis.net/58898-memo-clear-zeigt-keinen-effekt-falsche-anzeige.html)

gordon freeman 14. Dez 2005 12:30


Memo.Clear zeigt keinen Effekt - Falsche Anzeige
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Leute,
ich habe eine Lösung für das unten dargestellte Problem für den Informatik-Unterricht programmiert. Innerhalb einer selbst definierten Klasse habe ich folgendes:
Delphi-Quellcode:
procedure TTurm.ZeigeDich(Memo : TMemo);
var i:integer;
begin
  Memo.Clear;
  for i:=0 to length(Elemente)-1 do
    Memo.Lines.Add(inttostr(Elemente[i]));
end;
Auch wenn das Array Elemente leer ist wird jedoch immer noch eine Zahl im Memo angezeigt. Ich hab mal das ganze Programm angehängt, wäre nett, wenn ihr's euch mal ansehen könntet. Ich bin mit meinem Latein am Ende :(


Problem:
Ein Eingeborenenstamm hat 3 Türme. Auf dem ersten liegen sortiert und nummeriert 100 Scheiben. Die 100te ist die dickste und liegt ganz unten. darüber die 99te bis oben die 1te liegt, die ist am dünnsten. Jetzt sollen alle Scheiebn in genauso sortiert auf den 3.ten Turm gebracht werden, allerdings müssen 2 Regeln beachtet werden:
  • Es darf immer nur eine Scheibe bewegt werden.
  • Eine Scheibe darf nur auf dem Boden oder auf einer größeren Scheibe liegen, nie auf einer kleineren.

RavenIV 14. Dez 2005 12:37

Re: Memo.Clear zeigt keinen Effekt - Falsche Anzeige
 
dein Problem nennt man auch "Türme von Hanoi".
Das ist eine sehr beliebte Programmeiraufgabe, für die es tonnenweise fertige Lösungen gibt.

Zu deinem Memo:
übergib das memo mal so:
Delphi-Quellcode:
procedure TTurm.ZeigeDich(var Memo : TMemo);
wenn Du einen Parameter als var-Parameter übergibst, kann das Original verändert werden.
Sonst wird mit der lokalen Kopie gearbeitet und das Original bleibt unverändert.

tigerman33 14. Dez 2005 12:44

Re: Memo.Clear zeigt keinen Effekt - Falsche Anzeige
 
Bei Klassen dürfte das eigentlich keinen Unterschied machen. Denn das, was du da bekommst ist ja ein Zeiger. Die lokale Kopie ist also in Wirklichkeit ein zweiter Zeiger. Das heißt der Unterschied ist hier folgender:

Delphi-Quellcode:
procedure Test1(x: TObject);
begin
  x := nil;
  // x ist nil
end;
procedure Test2(var x: TObject);
begin
  x := nil;
end;
var a: TObject;
begin
  a := TObject.Create; // Zeigt jetzt an Adresse xyz
  Test1(a); // a zeigt immer noch auf xyz
 Test2(a); // Jetzt ist auch a auf nil
end;
Alle Änderungen, die du am Objekt machst werden also auch ohne var übernommen. (Sieht man ja leicht z.B. am Sender-Parameter im TNotifyEvent).

Khabarakh 14. Dez 2005 12:45

Re: Memo.Clear zeigt keinen Effekt - Falsche Anzeige
 
Zitat:

Zitat von RavenIV
Zu deinem Memo:
übergib das memo mal so:
Delphi-Quellcode:
procedure TTurm.ZeigeDich(var Memo : TMemo);
wenn Du einen Parameter als var-Parameter übergibst, kann das Original verändert werden.
Sonst wird mit der lokalen Kopie gearbeitet und das Original bleibt unverändert.

Aber doch nicht bei einem Objekt :shock: . Klassen sind Referenztypen, Objektvariablen bestehen also nur aus einem Pointer, der auf das wirkliche Objekt im Speicher zeigt [edit] wie tigerman33 oben anschaulich demonstriert hat. [/edit]

@gordon: Ich kann dein Problem nicht nachvollziehen. Wenn ich beispielsweise n = 1 setzte, wird die Scheibe korrekt von links nach rechts gesetzt, weder im linken noch im mittleren Memo steht etwas.
Btw: Du musst die Türme auch wieder freigeben.

Der_Unwissende 14. Dez 2005 12:46

Re: Memo.Clear zeigt keinen Effekt - Falsche Anzeige
 
Hi,
ach die schönen Türme von Hanoi. Dein sleep legt den Hauptprozess schlafen, dass heißt natürlich auch, dass dieser nicht neu zeichnet. Dein Algorithmus ist also so wie er ist schon vollkommen richtig, aber du solltest in deiner Methode procedure TForm1.Schiebe(n, Turm1, Turm2, Turm3: integer); noch ein Application.ProcessMessages; vor dem sleep einfügen (gibt Rechenzeit frei und damit wird neu gezeichnet).

Ein (wie ich glaube) schönerer Weg ist es dann einfach anders zu warten, statt sleep(500) kannst du auch
Delphi-Quellcode:
var time : Int64;
begin
  time := GetTickCount;
  while (GetTickCount - time) < 500 do
    begin
      Application.ProcessMessages;
    end;
end;
verwenden, das sollte auf jeden Fall klappen.

Schau einfach mal,
Gruß Der Unwissende

Ps: Nicht schlecht, ich hatte damals (gut, noch Pascal) eine deutlich unschönere Lösung

Gollum 14. Dez 2005 12:49

Re: Memo.Clear zeigt keinen Effekt - Falsche Anzeige
 
Zitat:

Zitat von RavenIV
wenn Du einen Parameter als var-Parameter übergibst, kann das Original verändert werden.
Sonst wird mit der lokalen Kopie gearbeitet und das Original bleibt unverändert.

Das stimmt so nur bedingt.
Normalerweise sind Objekte die in Delphi mit "T" anfangen (im Prinzip) Pointer. Also wird in dem Fall auch nicht mit einer Lokalkopie gearbeitet. Wenn dem so wäre, würde kein Programm von mir funktionieren.

@gordon freeman:
Wenn Elemente ein Array ist, würde ich statt Length, High nehmen:
Delphi-Quellcode:
procedure TTurm.ZeigeDich(Memo : TMemo);
var i:integer;
begin
  Memo.Clear;
  for i:=Low(Elemente) to High(Elemente) do Memo.Lines.Add(inttostr(Elemente[i]));
end;

gordon freeman 14. Dez 2005 13:20

Re: Memo.Clear zeigt keinen Effekt - Falsche Anzeige
 
Zitat:

Zitat von Khabarakh
Btw: Du musst die Türme auch wieder freigeben.

:oops: Hab ich glatt vergessen, danke!

Zitat:

Zitat von Der_Unwissende
(...) aber du solltest in deiner Methode procedure TForm1.Schiebe(n, Turm1, Turm2, Turm3: integer); noch ein Application.ProcessMessages; vor dem sleep einfügen (gibt Rechenzeit frei und damit wird neu gezeichnet).(...)

Das war's! jetzt funktioniert's perfekt. Danke! :thumb: :dp:


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:11 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