2010-12-12 6 views
0

J'utilise ce code pour afficher un formulaire avec une fenêtre contextuelle comme messager:Pourquoi l'effet de déplacement de formulaire ne se produit pas la première fois?

TimeSleep := 5; 

    for i := 1 to FormHeight do 
    begin 
    Form.Top := Form.Top - 1; 

    Sleep(TimeSleep); 
    end 

Il travaille en douceur, mais seulement de la deuxième fois. Je veux dire que j'ai un bouton sur mon formulaire qui invoque la boucle et la première fois que je clique sur le formulaire montre soudainement sans effet de glissement. Si je clique à nouveau, l'effet fonctionne.

Comment puis-je le faire fonctionner de la première fois?

Merci.

+0

Quand faites-vous l'affectation à TimeSleep? – frogb

Répondre

2

Vous ne publiez pas assez de code pour être sûr à ce sujet, mais je suppose que votre formulaire n'est pas visible ou n'a même pas un handle de fenêtre avant de cliquer sur le bouton la première fois, donc le déplacement du formulaire n'est pas visible. Si vous insérez

Form.Show; 
Form.Update; 

avant que les éléments de boucle ne fonctionnent également la première fois. Notez l'appel à Update(), il est nécessaire de montrer vraiment le formulaire qui a été rendu visible dans la ligne précédente.

De même, vous devez insérer un appel à Update() après la modification de la propriété Top à l'intérieur de votre boucle - il fait aussi l'appel à Application.ProcessMessages(), sans être un tel sledgehammer. Essayez de faire sans Application.ProcessMessages() chaque fois qu'il y a un meilleur moyen, recherchez Stack Overflow pour les discussions à ce sujet.

Deux autres morceaux de conseils concernant votre boucle:

  • Mouvement ne sera pas facile si quelque chose provoque votre Sleep() être plus long que les 5 millisecondes vous demande - il est préférable de calculer le montant à diminuer la coordonnée supérieure du formulaire depuis le temps écoulé depuis le dernier mouvement. Personne ne verra votre formulaire se déplacer par incréments de 1 pixel - l'œil humain et le cerveau ne sont pas assez rapides pour collecter et traiter les informations à cette vitesse, et même les chats et les insectes dans votre chambre ne verront que le 60 ou plus met à jour votre moniteur chaque seconde. Donc un paramètre à Sleep() de 20 ou même 50 est beaucoup plus sensible que 5. Ajustez le mouvement du formulaire en conséquence.

Edit:

Voici quelques exemples de code qui crée un mouvement constant de la forme même avec des retards différents:

uses 
    MMSystem; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Frm: TForm; 
    TicksStart, TicksNow: Longword; 
    Progress: Single; 
begin 
    Frm := TForm.CreateNew(Self); 
    try 
    // slide a form of 600 by 500 pixel into view over a period of 100 millis 
    Frm.SetBounds((Screen.Width - 600) div 2, -500, 600, 500); 
    Frm.Show; 

    TicksStart := timeGetTime; 
    while True do begin 
     Sleep(15); 
     TicksNow := timeGetTime; 
     if TicksNow - TicksStart >= 1000 then 
     break; 
     Progress := (TicksNow - TicksStart)/1000; 
     Frm.Top := - Round((1.0 - Progress) * 500); 
    end; 
    Frm.Top := 0; 

    Sleep(500); 
    finally 
    Frm.Free; 
    end; 
end; 
+0

Merci pour les conseils. Vous dites "il est préférable de calculer le montant pour décrémenter la coordonnée supérieure du formulaire à partir du temps écoulé depuis le dernier mouvement." Pouvez-vous me fournir le code corrigé s'il vous plaît?Et que voulez-vous dire par "Ajuster le mouvement de la forme en conséquence"? Je suis un débutant absolu en Delphi. – emurad

+0

@emurad: Vous voulez dire que vous êtes un débutant absolu en * programmation *? –

+0

@emurad: Je poste un exemple de code, mais étant donné votre attitude envers Andreas, j'ai été tenté de ne pas le faire. Son commentaire n'a peut-être pas été utile, mais votre impolitesse est toujours complètement inacceptable. – mghie

2

Essayez d'ajouter "Application.ProcessMessages;" avant de dormir.

+0

MERCI BEAUCOUP. Cela a fonctionné mais pourquoi les messages ne sont pas traités automatiquement lors de la première invocation? – emurad

+0

@emurad: Bien sûr qu'ils ne le sont pas. Le code en cours d'exécution dans votre thread est le code que vous écrivez. Donc, dans une boucle dans votre programme, si vous voulez traiter des messages, vous devez le faire vous-même. (Indice: achetez un livre sur la programmation Win32.) –

Questions connexes