2009-11-16 4 views
0

J'ai un peu de mal à comprendre ce qui ne va pas avec cette fonction. Je ne suis pas sûr si je devrais utiliser -1 ou plus, et peu importe comment j'essaie d'arranger le code, il semble revenir à zéro, même si ce n'est pas le cas. Quelqu'un avec des yeux frais pourrait jeter un coup d'oeil? Aussi, je ne suis pas sûr que mon résultat: = nul est à la bonne place.Devrais-je soustraire 1 de la limite supérieure de mes boucles «for»?

function TFrmMain.FindQueryFrm(Server, Nickname: String): TFrmMessage; 
var 
    I,M: Integer; 
begin 
    /// No -1 in the I loop - why? Because the first childform will not always be 
    /// of type TFrmMessage, which is what we're looking for. 
    /// 
    /// Is this approach wrong? 
    for I := 0 to MDIChildCount do 
    begin 
    if Screen.Forms[I] is TFrmMessage then 
    begin 
     /// Same concept with -1 here (M Loop)... I need to check all forms 
     /// stored by QueryManager to see if their .MyServer and .QueryWith's match 
     /// 
     /// Is the M Loop wrong? 
     for M := 0 to QueryManager.Count do 
     begin 
     if UpperCase((QueryManager[M] as TFrmMessage).MyServer) = UpperCase(Server) then 
     begin 
      if UpperCase((QueryManager[M] as TFrmMessage).QueryWith) = UpperCase(NickName) then 
      begin // BINGO! 
      Result := (QueryManager[M] as TFrmMessage); 
      exit; 
      end; 
     end; // HOST COMPARE 
     end; // M Loop 
    end; // Is TFrmMessage 
    end; // I Loop 
    Result := nil; // None Found 
end; 
+4

"Les indices de tableau doivent-ils commencer à 0 ou 1? Mon compromis de 0,5 a été rejeté sans, je pense, une considération appropriée. "- Stan Kelly-Bootle –

Répondre

8

Si vous n'êtes intéressé que par les enfants MDI, comme vous semblez être, étant donné que vous utilisez MDIChildCount de la forme, puis utilisez MDIChildren de la forme propriété. Ces deux propriétés vont ensemble, tout comme les propriétés FormCount et Forms de l'écran sont une paire. Votre code mélange une propriété forme avec une propriété écran.

begin 
    for I := 0 to MDIChildCount - 1 do 
    begin 
    if MDIChildren[I] is TFrmMessage then 
    begin 

De plus, vous devez certainement soustraire 1 du nombre de gestionnaires de requête, ou bien cela signifie que vous n'êtes pas garder correctement trace de combien de gestionnaires requête que vous avez en premier lieu. Le "-1" que vous voyez dans la plupart du code est là parce que la limite supérieure d'une boucle Delphi "for" est inclus. La variable de boucle commencera à la limite inférieure et la boucle continuera jusqu'à ce que la variable passe la limite supérieure. Cela peut vous aider à raisonner sur ce qui se passe dans le cas de base, lorsqu'il n'y a aucun élément dans la liste. Dans ce cas, la boucle ne devrait pas fonctionner du tout, n'est-ce pas? Parce qu'il n'y a rien à trouver. Une boucle définie pour s'exécuter à partir de "0 to 0" s'exécutera une fois. La limite supérieure devra donc être négative pour empêcher l'exécution de la boucle. (Tout est décrit dans the documentation.)

En ce qui concerne les raisons pour lesquelles votre fonction renvoie une référence NULL même si vous pensez qu'elle ne devrait pas, je ne peux que supposer que c'est dû aux autres problèmes dans votre code. Peut-être n'avez-vous pas bouclé autant de formulaires que vous pensiez l'être, ou peut-être allez-vous au-delà de la fin de la liste des gestionnaires de requêtes pour obtenir une valeur indéfinie. Le placement de votre affectation Result est correct, même si peu importe où vous l'avez placé puisque le seul autre endroit auquel il est assigné est juste avant la sortie de la fonction.


Je vois you asked about MDI children sur About.com. Là, Zarco Gajic answered your question en vous donnant le code comme ceci:

for cnt := 0 to -1 + MDIChildCount do 

Bien qu'il soit un code valide, ce n'est pas idiomatiques. Je n'ai jamais vu quelqu'un d'autre écrire du code comme ça auparavant, alors il serait sage de ne pas prendre cette habitude. Quand nous voulons un moins que quelque chose, nous n'ajoutons pas un négatif à la valeur.Au contraire, nous soustrayons positif un:

for cnt := 0 to MDIChildCount - 1 do 

Sinon, je l'utilise parfois la fonction standard Pred:

for cnt := 0 to Pred(MDIChildCount) do 
+0

Merci encore Rob! - En outre, cela n'a pas aidé que j'ai eu mes cordes à l'envers lors de l'appel du proc. J'ai pris un min pour le réaliser. Appréciez l'aide à tous. – Commodianus

1

Si je ne me trompe pas, puisque vous utilisez Screen.Forms vous devez également utiliser Screen.FormsCount.
Si le tableau a N éléments et il commence à l'index 0, nous l'énumérons de 0 .. N-1.
Array[N] aurait tort.

Vérifiez si le code ci-dessous fonctionne:

//for I := 0 to MDIChildCount do 
for I := 0 to Screen.FormsCount-1 do 
begin 
    if Screen.Forms[I] is TFrmMessage then 
    begin 
    for M := 0 to QueryManager.Count-1 
    ... 
1

En bref: oui! Les tableaux dans Delphi sont basés sur 0, donc en utilisant le nombre de chose vous en donne un de trop.

MyArray[0] := 'first item'; 
MyArray[1] := 'second item'; 
for i:=0 to MyArray.count-1 do 
begin 
    ... 
end; 

Si vous utilisez le nombre (étant 2) sans le moins 1, la dernière fois que vous passez par la boucle demanderait myarray [2] qui est pas là.

En bref, vous devez utiliser un (propre) syntaxe:

for M := 0 to Pred(QueryManager.Count) do 
+1

Ceci est une réponse quelque peu trompeuse. C'est correct pour les tableaux dynamiques, qui ont toujours 0 comme limite inférieure. Cependant, il existe des tableaux dans Delphi qui peuvent avoir des limites inférieures différentes. Les tableaux peuvent même être indexés par un type ordinal qui n'est pas un entier, comme un type d'énumération. Et le code de la question traite des propriétés de tableau, qui ne sont pas de véritables tableaux, et peuvent également avoir des limites inférieures différentes et être indexées sur des types différents. – mghie

1

Il est de retour nil parce que vous n'êtes pas fait visiter toutes les formes dans l'application dans votre boucle, et qui n'a rien à voir avec utiliser ou non -1 dans la boucle (ce que, dans une version correctement écrite, vous devez faire).

Vous ne visitez pas tous les formulaires parce que vous parcourez la liste des formulaires d'applications, qui contient les formulaires MDIChildren et non-MDI. Mais la valeur que vous utilisez pour déterminer le nombre de ces formulaires à consulter est MDIChildCount. Ce nombre inclut uniquement les MDIChildren. Donc, si votre application a 7 formulaires, dont 4 sont des enfants MDI, vous ne regardez que les 4 premiers sur les 7 formulaires (enfin, 5 à cause du problème de boucle). Si le formulaire que vous voulez est le numéro 6 ou 7 (ce qui est probable), vous ne l'atteindrez jamais.

En outre, je ne vois pas où, à l'intérieur de la boucle sur les formulaires, vous êtes réellement référence à n'importe quelle propriété du formulaire.

Questions connexes