我在弄清楚这个功能出了什么问题时遇到了一些麻烦。我不确定我是否应该使用-1或者不再使用-1,无论我如何尝试安排代码,它似乎都会返回nil,即使它不应该。有新鲜眼睛的人可以看看吗?另外,我不确定我的结果:= nil是否在适当的位置。
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;
答案 0 :(得分:8)
如果您对MDI孩子感兴趣,就像您使用表单MDIChildCount
一样,那么请使用表单的MDIChildren
属性。这两个属性组合在一起,就像屏幕的FormCount
和Forms
属性一样。您的代码将表单属性与 screen 属性混合使用。
begin
for I := 0 to MDIChildCount - 1 do
begin
if MDIChildren[I] is TFrmMessage then
begin
此外,您肯定应该从查询管理器的数量中减去1,否则就意味着您没有正确地跟踪您拥有的查询管理器数量。你在大多数代码中看到的“-1”是因为Delphi“for”循环的上限是 inclusive 。循环变量将从下限开始,循环将继续运行,直到变量传递上限。当列表中没有项目时,它可以帮助您推断基本情况中发生的情况。在那种情况下,循环根本不应该运行,对吧?因为找不到任何东西。从“0 to 0
”运行的循环将执行一次,因此上限需要否定以防止循环运行。 (这都在the documentation中描述。)
至于为什么你的函数返回一个空引用,即使你认为它不应该,我只能假设它是由于你的代码中的其他问题。也许你没有像你想象的那样循环多少个表单,或者你可能超出了查询管理器列表的末尾并获得了一些未定义的值。您Result
作业的放置位置是正确的,但在放置它的位置并不重要,因为它被分配的唯一其他位置就在函数退出之前。
我在About.com上看到you asked about MDI children。在那里,Zarco Gajic answered your question给你这样的代码:
for cnt := 0 to -1 + MDIChildCount do
虽然它是有效的代码,但它不是惯用的。我以前从未见过其他人写过这样的代码,所以你明智地不去养习那种习惯。当我们想要一个小于某个东西时,我们不会在该值中添加一个字面上的负数。相反,我们减去积极的一个:
for cnt := 0 to MDIChildCount - 1 do
或者,我有时会使用Pred
标准函数:
for cnt := 0 to Pred(MDIChildCount) do
答案 1 :(得分:1)
如果我没记错,既然你使用Screen.Forms
,你也应该使用Screen.FormsCount
。
如果数组有N个元素并且它从索引0
开始,我们将从0 .. N-1
枚举它。
Array[N]
会出错。
检查以下代码是否有效:
//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
...
答案 2 :(得分:1)
简而言之:是的! Delphi中的数组是基于0的,因此使用某些东西可以得到太多的数据。
MyArray[0] := 'first item';
MyArray[1] := 'second item';
for i:=0 to MyArray.count-1 do
begin
...
end;
如果你在没有减1的情况下使用计数(2),那么你最后一次循环会要求myarray [2]不存在。
简而言之,你应该使用这样的(更干净的)语法:
for M := 0 to Pred(QueryManager.Count) do
答案 3 :(得分:1)
它正在返回nil
,因为你实际上并没有访问循环中应用程序中的每个表单,这与是否在循环中使用-1无关(在正确编写中版本,你必须这样做。)
您没有访问每个表单,因为您正在遍历表单的应用程序列表,其中包含MDIChildren 和非MDI表单。但是您用来决定要查看的表单数量的值是MDIChildCount。该数字仅包括MDIChildren。因此,如果您的应用程序有7个表单,其中4个是MDI子表单,那么您只查看7个表单中的前4个表单(好吧,5表示因为循环问题)。如果您想要的表格是6号或7号(很可能),您将永远无法访问它。
另外,我没有看到表单中的循环内部,您实际上将引用到表单的任何属性。