ASyncPro 5.00 в Delphi 2010 - ошибка проверки диапазона

Попытка запустить AsyncPro в D2010. Использование версии 5.00 от Source Forge.

Код AsyncPro (в OOMisc.pas) ниже не работает с ошибкой проверки диапазона в строке MakeLong ниже. Я понятия не имею, как начать отлаживать это.

У кого-нибудь работает ASyncPro в D2010, или есть представление о том, что может происходить ниже? Публикация мной в 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;

ТИА

4 ответа

Решение

Кажется, вы компилируете код с проверкой диапазона:

{$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.

Я бы повторил комментарий Аллена - но иди дальше. Если вы посмотрите на то, как используется код (посмотрите на DelayTicks также в OoMisc), вызывающие абоненты либо предполагают, что возвращаемое значение неважно, либо просто является сообщением. Добавление Msg.hwnd к номеру не просто не сработает, это также не то, что ожидают абоненты.

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

Этот код ожидает только сообщение.

Я бы поменял строку

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

в

 SafeYield := Msg.Message;

Учитывая, что MAKELONG принимает два параметра типа Word (16 бит), а Msg.Message и Msg.HWnd - 32 бит, неудивительно, что вы получаете ошибки проверки диапазона. В общем, сообщения окна <8000 $, поэтому я сомневаюсь, что значение является проблемой. Тем не менее, интегральное значение HWnd может быть по всей карте и, конечно, часто> $FFFF. Из-за этого приведенный выше код на самом деле не имеет смысла, за исключением того, что он, похоже, давно ушел из 16-битной версии.

Поскольку проверка диапазона включена, это четко подчеркивает тот факт, что приведенный выше код нуждается в некотором переосмыслении. В Win32 вы больше не можете вписать значение сообщения и дескриптор окна в 32 бита.

Я надеюсь, что дал вам несколько советов о том, как поступить. Без учета кода, который вызывает эту функцию, невозможно предложить альтернативную реализацию.

(1) Этот код является насосом сообщений, и

(2) (в контексте) он защищен директивой R-компилятора. Проверка диапазона отключена: {$R- Без проверки диапазона} в AwDefine.inc

Итак (1) Если какое-то другое сообщение приводит к остановке кода, это будет то место, где оно будет, когда сообщение пройдет, и

(2) Отсюда ошибка проверки диапазона.

Это говорит о том, что асинхронный процесс вызывает исключение проверки диапазона или модальное сообщение. В версии Delphi, с которой я работаю, ошибки проверки диапазона (и сообщения индекса списка) не дают никакой информации об источнике / отладке, поэтому я могу только предположить, что ошибка может быть связана с асинхронным событием Comm или даже с полученной ошибкой. фокус / потерял фокус / активировать / рисовать событие.

Другие вопросы по тегам