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 или даже с полученной ошибкой. фокус / потерял фокус / активировать / рисовать событие.