【问题标题】:ASyncPro 5.00 in Delphi 2010 - Range Check ErrorDelphi 2010 中的 ASyncPro 5.00 - 范围检查错误
【发布时间】:2010-12-09 04:01:56
【问题描述】:

试图让 AsyncPro 在 D2010 中运行。使用 Source Forge 的 5.00 版本。

下面的 AsyncPro 代码(在 OOMisc.pas 中)失败,下面的 MakeLong 行出现范围检查错误。我不知道如何开始调试它。

是否有人在 D2010 中运行 ASyncPro,或者对下面可能发生的情况有所了解?我在 SourceForge 上发帖没有得到任何回应。

function SafeYield : LongInt;
  {-Allow other processes a chance to run}
var
  Msg : TMsg;
begin
  SafeYield := 0;
  if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then begin
    if Msg.Message = wm_Quit then
      {Re-post quit message so main message loop will terminate}
      PostQuitMessage(Msg.WParam)
    else begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
    end;
    {Return message so caller can act on message if necessary}
    SafeYield := MAKELONG(Msg.Message, Msg.hwnd);  // Range Check Error on this line!
  end;
end;

TIA

【问题讨论】:

    标签: delphi turbopower


    【解决方案1】:

    您似乎在编译代码时启用了范围检查:

    {$R+}
    function Test(A, B: LongWord): LongInt;
    begin
      Result:= MakeLong(A,B);
    // Project .. raised exception class ERangeError with message 'Range check error'.
    end;
    

    您可以关闭范围检查以摆脱运行时错误,但结果

    SafeYield := MAKELONG(Msg.Message, Msg.hwnd)
    

    如果参数之一(或两者)大于 2^16 - 1,则不正确。

    看起来代码是从 16 位 AsyncPro 版本移植到 32 位版本的,并且在所有 32 位 AsyncPro 版本中都存在该错误。

    【讨论】:

      【解决方案2】:

      看到 MAKELONG 如何接受两个 Word 类型(16 位)的参数,而 Msg.Message 和 Msg.HWnd 都是 32 位,因此遇到范围检查错误也就不足为奇了。一般来说,窗口消息是 $FFFF。因此,上面的代码实际上并没有什么意义,只是它似乎是 16 位版本的很久以前遗留下来的工件。

      由于启用了范围检查,它清楚地强调了上述代码需要重新思考的事实。在 Win32 中,您不能再将消息值和窗口句柄放入 32 位。

      我希望我已经给了你一些关于如何继续的提示。如果不考虑调用此函数的代码,就不可能提出替代实现。

      【讨论】:

        【解决方案3】:

        我会回应艾伦的评论 - 但更进一步。 如果您查看代码是如何使用的(在 OoMisc 中也可以查看 DelayTicks),调用者要么假设返回值不重要,要么只是消息。将 Msg.hwnd 添加到号码不仅不起作用,而且也不是呼叫者所期望的。

        repeat
          if Yield then
            Res := SafeYield;
        until (**Res = wm_Quit**) or TimerExpired(ET);
        

        此代码只需要一条消息。

        我会换行

         SafeYield := MAKELONG(Msg.Message, Msg.hwnd);
        

         SafeYield := Msg.Message;
        

        【讨论】:

          【解决方案4】:

          (1) 该代码是一个消息泵,并且

          (2)(在上下文中)它受 R 编译器指令的保护。范围检查已关闭:AwDefine.inc 中的 {$R- 无范围检查}

          所以(1)如果其他一些消息导致代码停止,这就是消息通过时的位置,并且

          (2) 范围检查错误不是来自这里。

          这表明异步进程正在导致范围检查异常或模式消息。在我正在使用的 Delphi 版本中,范围检查错误(和列表索引消息)不提供任何源/调试信息,所以我只能建议该错误可能与异步 Comm 事件相关联,甚至是焦点/失去焦点/激活/绘制事件。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-07-24
            • 2021-08-11
            • 1970-01-01
            • 1970-01-01
            • 2014-12-02
            • 1970-01-01
            • 1970-01-01
            • 2022-10-14
            相关资源
            最近更新 更多