4

试图让 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

4

4 回答 4

2

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

{$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 版本中都存在错误。

于 2010-12-09T05:34:51.897 回答
1

看到 MAKELONG 如何采用 Word 类型(16 位)的两个参数,并且 Msg.Message 和 Msg.HWnd 都是 32 位,因此遇到范围检查错误也就不足为奇了。一般来说,窗口消息是 < 8000 美元,所以我怀疑这个值是问题所在。但是,HWnd 的整数值可以在整个地图上,并且肯定经常 > $FFFF。因此,上面的代码实际上并没有什么意义,只是它似乎是 16 位版本的很久以前遗留下来的工件。

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

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

于 2010-12-09T05:09:02.540 回答
1

I would echo Allen's comment - but go further. If you look at how the code is being used (Look at DelayTicks also in OoMisc) callers either assume that the return value is unimportant or is JUST the message. Adding the Msg.hwnd to the number is not just not going to work, it is also not what the callers are expecting.

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

This code is expecting a message only.

I would change the line

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

to

 SafeYield := Msg.Message;
于 2011-01-10T22:35:03.633 回答
0

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

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

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

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

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

于 2013-09-03T08:52:08.143 回答