Delphi 2010中的ASyncPro 5.00 - 范围检查错误

问题描述:

试图在D2010中运行AsyncPro。使用Source Forge的5.00版本。Delphi 2010中的ASyncPro 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

看来你对范围检查编译代码:

{$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版本。

看到,因为MAKELONG如何进行类型字的两个参数(16位),以及Msg.Message和Msg.HWnd都是32位,这并不奇怪,你得到的范围检查错误。一般来说,窗口消息是< $ 8000,所以我怀疑价值是问题所在。然而,一个HWnd的整数值可以遍布整个地图,而且经常是> $ FFFF。正因为如此,上述代码并没有什么意义,除了它似乎是一个很久以前遗留下来的16位版本的工件。

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

我希望我给你提供了一些关于如何继续的提示。在不考虑调用此函数的代码的情况下,不可能建议替代实现。

我会回应艾伦的评论 - 但走得更远。 如果你看看如何使用代码(查看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)该代码是一个消息泵,和

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

所以,(1)如果其他消息导致代码停止,这是那里的消息经过时,它会和

(2)范围检查错误并非来自这里。

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