ASyncPro 5.00 in Delphi 2010 - Range Validation Error

Trying to run AsyncPro in D2010. Using version 5.00 of Source Forge.

Below is the AsyncPro code (in OOMisc.pas) below with a range check error on the MakeLong line below. I do not know how to start debugging.

Does anyone have ASyncPro running in D2010, or have some idea of โ€‹โ€‹what might happen below? The message I sent to SourceForge did not respond.

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
source share
4 answers

It seems that you are compiling code with a range check:

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

You can disable range checking to get rid of runtime error, but the result

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

incorrect if one of the arguments (or both) is above 2 ^ 16 - 1.

It seems that the code was ported from the 16-bit version of AsyncPro without changing to the 32-bit version, and the error was where through all 32-bit versions of AsyncPro.

+2
source

Having seen how MAKELONG uses two parameters of the Word type (16 bits), and Msg.Message and Msg.HWnd - 32 bits, it is not surprising that you get range checking errors. In general, window messages are <$ 8000, so I doubt this is a problem. However, the integral value of HWnd can be across the map and, of course,> $ FFFF quite often. Because of this, the above code does not actually make sense, except that it seems to have left an artifact from the 16-bit version long ago.

Since range checking is enabled, this clearly emphasizes the fact that the above code needs to be rethought. In Win32, you can no longer accommodate the message value and window handle in 32 bits.

I hope I have given you some tips on how to proceed. Without taking into account the code that calls this function, it is impossible to offer an alternative implementation.

+1
source

I would repeat Allen's comment, but I will go further. If you look at how the code is used (look at DelayTicks also in OoMisc), either the return value is assumed to be irrelevant or just a message. Adding Msg.hwnd to the number will not only not work, but also not what the waiting subscribers expect.

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

This code only expects messages.

I would change the line

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

to

  SafeYield := Msg.Message; 
+1
source

(1) This code is a Message Pump and

(2) (in context) it is protected by the R-compiler directive. Range check disabled: {$ R- No range check} in AwDefine.inc

So (1) If any other message causes the code to stop, this is where it will be when the message passes, and

(2) Range check error does not come from here.

This indicates that the asynchronous process is causing a range check exception or modal message. In the Delphi version I'm working with, range checking errors (and list index messages) do not give any information about the initial / debug state, so I can only assume that the error may be due to the asynchronous event Comm, focus / lost-focus / activate / paint.

0
source

All Articles