ASyncPro 5.00 в Delphi 2010 - ошибка проверки диапазона - PullRequest
4 голосов
/ 09 декабря 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 ]

2 голосов
/ 09 декабря 2010

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

{$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 голос
/ 11 января 2011

Я бы повторил комментарий Аллена - но иди дальше. Если вы посмотрите на то, как используется код (посмотрите на 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;
1 голос
/ 09 декабря 2010

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

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

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

0 голосов
/ 03 сентября 2013

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

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

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

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

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

...