Ergebnis 1 bis 20 von 47

Thema: Delphi - Fragen!

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Hm. Ich würde sagen, die Reihenfolge lautet doch eigentlich repeat-Codeblock-until-Bedingungen-Labeländerung. Und im Codeblock ist jetzt meinetwegen das sleep und noch Application.ProcessMessages, damit die Welt nicht untergeht, wenn man das Programm ausführt. *g*

  2. #2
    Code:
     repeat
     if not (v1 = v2) then
     until ok <> 1;
     Label1.Caption := zahl[v1]; 
     ok := 1;
    Solche Blöcke gibt es jetzt mehrmals in meinem Projekt. Ich programmiere etwas, das viele verschiedene Zahlen ausgibt, mit einem einzigen Buttonklick, und alle Zahlen sollen eben verschieden sein, was nicht immer der Fall ist (im Moment jedenfalls). Als es klappte, hing es sich ja immer auf.

    Edit: Habe noch eine Frage. Warum sehen Panels unter dem XP-Manifest Befehl (D7) immer so komisch aus? (Schrift nicht lesbar, nur Rand zu sehen) Was kann man da tun?

    Geändert von Expresseon (24.11.2007 um 17:09 Uhr)

  3. #3
    Ich glaube, du hast das Arbeitsprinzip von Windows-Applikationen nicht ganz verstanden.

    Die Callback Funktionen, die ein Button aufruft, oder jedes andere GUI Element, sollten immer so kurz wie moeglich gehalten werden. Denn die ganze GUI ist idR blockiert, solange diese CallBack Funktion nicht verlassen wird.

    Daher sind Repeat ... Until Schleifen, die unabhaengig von der konkreten eingabe auf etwas warten, ein ganz ganz boeses NoNo. Dafuer hat man andere Mechanismen zur Verfuegung. Die Call Back Funktion ist idR nur dazu da, bestimmte Flags und Variablen deines Programms zu aendern. Was diese dann bewirken, das steht in einer anderen Routine (oder sogar in einem anderen Thread) und nicht in der GUI.

    Du musst dich von der Vorstellung des sequentiellen Programmablaufes trennen. Unter Windows ist alles Message-Orientiert.

    Ich mache mal ein kleines Beispiel:

    Mach ein neues Formular und erzeuge ein Label, einen Button und einen Timer (Ich denke, der steht im Panel Systemkomponenten). Zudem lege eine integer Variable namens Counter in deinem Form an. Dann mach einen Doppelklick auf den Button und schreibe folgende Funktion zum Abarbeiten in das OnClickEvent

    Code:
    Form1.Timer1.enable := not(Form1.Timer1.enable);
    Dann mache einen Doppelklick auf das Timer Objekt und gibt im OnTimerEvent folgenden Code ein:

    Code:
    inc(Form1.Counter);
    Form1.Label1.Caption := toString(Form1.Counter);
    Form1.Label1.Update;
    Dann starte das Programm. Wenn du nun auf den button klickst, sollte das Label anfangen, im Sekundenrakt die Natuerlichen Zahlen sukzessiv anzuzeigen. Wenn du ein weiteres Mal auf den Button klickst, wird das Zaehlen angehalten. Ein weiterer Klick setzt das zaehlen fort. usw.

    Der ganze Post ist aus der Erinnerung geschrieben, und ich glaube, ich hab das letzte Mal mit Delphi intensiv vor 5 jahren gearbeitet. Daher keine Gewaehr auf die syntaktische Richtigkeit.

  4. #4
    Damit kann ich wenig anfangen, da es erstens nicht funktioniert (enable und Counter werden nicht erkannt) und da ich zweitens etwas ganz anderes umsetzen möchte, was mit repeat...until locker möglich sein sollte.

  5. #5
    Zitat Zitat
    und da ich zweitens etwas ganz anderes umsetzen möchte, was mit repeat...until locker möglich sein sollte.
    Aber nicht in einer GUI-Umgebung. In einem Kommandozeilenprogramm wäre eine repeat-schleife sicher die richtige Idee, in einem GUI-Programm aber nicht.

    Ich versuch es mal anschaulich zu erklären:
    Wenn du eine GUI-Applikation schreibst verzahnst du dein Programm eng mit der Funktionsweise von Windows. Sprich, Windows überwacht für dich den gesamten Userinput, also Mausbewegungen, Mausklicks und Tastendrücke. Wenn Windows nun merkt "Der Benutzer hat die linke Maustaste gedrückt" guckt Windows welches offene Programm gerade den Fokus hat und benarichtigt dieses Programm über dieses Ereigniss, indem es eben dem Programm eine Message sendet.
    Das Programm wiederrum empfängt diese Message, verarbeitet diese und wartet wiederrum auf neue Messages.

    Das Problem bei deinem Programm und der Schleife ist, der Verarbeitungsprozess der Nachricht "Button wurde angeklickt" ist erst beendet wenn die aufgerufene Funktion zuende ist. Baust du dort nun eine Schleife ein, wird dieser Prozess erst beendet wenn die Schleife beendet ist. Solange dieser Prozess aber nicht beendet wird, wird dein Programm auf neue Nachrichten von Windows nicht reagieren, also auch nicht auf neuen Userinput. Wenn du eine solche Schleife benutzt musst du auch innerhalb der Schleife selber dafür sorgen, daß sie irgendwann verlassen wird. Alles andere ist eine Endlosschleife. Bei deinem Code bricht die Schleife nur ab wenn eine Variable eine bestimmte Bedingung erfüllt, nur da die Variable innerhalb der Schleife nicht verändert wird gibt es nur 2 Möglichkeiten:
    - Die Schleife bricht sofort ab da die Variable die Bedingung erfüllt
    - Die Schleife bricht nie ab, da die Variable die Bedingung nicht erfüllt und auch nicht geändert wird

    Wenn du willst, daß etwas geändert wird sobald Bedingung X erfüllt ist, aber gleichzeitig den normalen Programmablauf nicht unterbrechen willst (da du noch auf Userinput reagieren willst) musst du dich eben da einhaken wo eine Funktion periodisch immer aufgerufen wird, ein Timer wie Ineluki es im Beispiel benutzt wäre da eine Lösung.

  6. #6
    Nun, ich hatte letztendlich nur einen begin + end Rahmen vergessen, es hat sich geklärt. Falls es jemanden interessiert:

    Code:
     begin 
     repeat 
     ok := false;
     v1 := random(51) + 1;
     if not (v1 = v2) 
     then
     begin 
     lbltext.Caption := text[v1];
     ok := true; 
     end;
     until ok; 
     end;
    Ich hätte vielleicht sagen sollen, dass ich Random-Integers verwende. Diese mussten natürlich jedesmal neu bestimm werden, daher kam das Aufhängen. Da ich begin und end (rot markiert) vergessen hatte, wurde ok := true (ok ist ein Boolean) nicht ausgeführt und es kam zu Fehlern. Habe es zum Glück endlich herausgefunden, das, was ich wollte war wohl zu schaffen. Habe die Schleife nochmal blau markiert. Danke nochmal an alle anderen.


    EDIT:
    Dann mal meine nächste Frage.^^
    Es gibt ja den sleep - Befehl. Wenn ich mitten beim Ausführen des Programmierten eine Pause haben will, dann gehts weiter, wie kann ich das dann machen? Mit sleeps funktioniert es irgendwie nicht richtig.

    Geändert von Expresseon (30.11.2007 um 16:14 Uhr)

  7. #7
    Zitat Zitat von PX Beitrag anzeigen
    Damit kann ich wenig anfangen, da es erstens nicht funktioniert (enable und Counter werden nicht erkannt) und da ich zweitens etwas ganz anderes umsetzen möchte, was mit repeat...until locker möglich sein sollte.
    Es kann nicht sein, dass Couter nicht gefunden wird, denn das ist die Variable, die du in deinem TForm1 definieren solltest.

    Ausserdem hat TTimer (zumindest zu meiner Zeit bis Delphi6) eine Property namens enable. Also hast du entweder den Timer nicht aufs Formular gesetzt, wie ich gesagt habe, oder sie haben was in TTimer geaendert, was ich aber nicht glaube.

    Am Besten, du postest mal den gesamten Quelltext deiner Unit.

  8. #8
    Die Property, die du meinst, heißt "enabled".
    Counter muss man als Boolean definieren, oder was meinst du?

  9. #9
    enable oder enabled ... wie gesagt, auf den Sinn kommt es an. Nach 5 Jahren verschwimmen langsam die Erinnerungen, ob da nun ein d am ende stand oder nicht ...

    Und was Counter angeht:
    Zitat Zitat von Ineluki
    Zudem lege eine integer Variable namens Counter in deinem Form an.
    Dran denken, die muss in deinem Form definiert werden, und nicht innerhalb des Counter-Events, damit der Wert zwischen zwei Methodenaufrufen erhalten bleibt.

  10. #10
    Naja, das Problem habe ich ja schon gelöst.
    Ich würde lieber mal wissen, wie man auf 5er runden kann, also 32 = 35 oder 99 = 100.

  11. #11
    Zitat Zitat von PX Beitrag anzeigen
    Ich würde lieber mal wissen, wie man auf 5er runden kann, also 32 = 35 oder 99 = 100.
    Kenn mich zwar in Delphi nicht aus, das dürfte aber dennoch möglich sein:

    Wenn <zahl> Modulo 5 gleich 0 ist:
    Gib <zahl> zurück
    Ansonsten:
    Gib <zahl> + (<zahl> Modulo 5) zurück

  12. #12
    Zitat Zitat von Brainstar Beitrag anzeigen
    Wenn <zahl> Modulo 5 gleich 0 ist:
    Gib <zahl> zurück
    Ansonsten:
    Gib <zahl> + (<zahl> Modulo 5) zurück
    Oder gleich
    Zahl = Zahl + (Zahl modulo 5)
    Zumindest falls du wirklich immer aufrunden willst, PX.

  13. #13
    modulo gibt es doch gar nicht. Ihr meint wohl mod oder so etwas in der Art...

  14. #14
    mod ist die Kurzform für modulo

  15. #15
    Zitat Zitat von Crash-Override Beitrag anzeigen
    Im Grunde hab ich nur grad keine Ahnung was dein Problem dabei ist.
    Lol, das weiß ich auch nicht.
    Manchmal stelle ich mich schon ziemlich blöd an. Aber das Problem dabei war warscheinlich, dass ich mich nicht an die Reihenfolge gehalten habe.


    Neue Frage bezüglich Images:
    Wie kann ich auf einfache Weise das Picture eines Images ändern, also mit einem Befehl? [Image1.Picture......]

  16. #16
    Zitat Zitat von PX Beitrag anzeigen
    [Image1.Picture......]
    LoadFrom* [File|Steam]

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •