尝试在D2010中运行AsyncPro。使用Source Forge的5.00版本。
下面的MakeLong行中的AsyncPro代码(在OOMisc.pas中)失败,并且范围检查错误。我不知道如何开始调试这个。
是否有人在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
答案 0 :(得分: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 :(得分:1)
看到MAKELONG如何获取两个Word类型的参数(16位),而Msg.Message和Msg.HWnd都是32位,因此您获得范围检查错误就不足为奇了。通常,窗口消息是< $ 8000所以我怀疑价值是问题。然而,HWnd的整数值可以在整个地图上,并且肯定是> $ FFFF经常。因此,上面的代码实际上没有意义,除了它似乎是很久以前遗留在16位版本的神器。
由于范围检查已启用,因此显然突出显示上述代码需要重新思考的事实。在Win32中,您不能再将消息值和窗口句柄放入32位。
我希望我已经给你一些关于如何继续的提示。如果不考虑调用此函数的代码,则无法建议替代实现。
答案 2 :(得分:1)
我会回应艾伦的评论 - 但要更进一步。 如果你看看如何使用代码(在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;
答案 3 :(得分:0)
(1)该代码是消息泵,
(2)(在上下文中)它受R-编译器指令保护。范围检查已关闭:AwDefine.inc中的{$ R-无范围检查}
所以(1)如果某些其他消息导致代码停止,那么这就是消息通过时的位置,并且
(2)范围检查错误不是来自此处。
这表明异步进程导致范围检查异常或模态消息。在我正在使用的Delphi版本中,范围检查错误(和列表索引消息)不提供任何源/调试信息,因此我只能建议错误可能链接到异步Comm事件,或者甚至是 - 焦点/失去焦点/激活/绘画事件。