在Delphi 2010中使用ASyncPro 5.00 - 范围检查错误

4
尝试在D2010中运行AsyncPro。使用来自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个回答

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版本中都存在。


1
我会附和Allen的评论 - 但更进一步。如果您看一下代码如何被使用(在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;

1

由于MAKELONG需要两个Word类型(16位)的参数,而Msg.Message和Msg.HWnd都是32位,所以出现范围检查错误并不奇怪。一般来说,窗口消息<$8000,因此我怀疑该值不是问题所在。然而,HWnd的整数值可能会非常大,通常>$FFFF。因此,上述代码实际上没有意义,除了它似乎是16位版本中留下的遗物。

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

我希望我已经给了您一些关于如何继续的提示。如果不考虑调用此函数的代码,就无法建议替代实现。


0
(1)那段代码是一个消息泵,
(2)(在上下文中)它受到了R-编译指令的保护。范围检查已关闭:{$R- No range checking} 在AwDefine.inc中。
所以(1)如果其他消息导致代码停止,当消息通过时,它将停留在这里,
(2)范围检查错误不是从这里产生的。
这表明异步进程可能会引发范围检查异常或模态消息。在我使用的Delphi版本中,范围检查错误(和列表索引消息)不提供任何源代码/调试信息,因此我只能建议错误可能与异步通信事件,甚至是获取焦点/失去焦点/激活/绘制事件有关。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接