RTL.CheckWin32Version. Функция некорректна
Автор: Дмитрий Померанцев
Только Delphi6 (SP2, возможно и более младшие версии Delphi6). Delphi5 и младше не исследовались, но в них отсутствовали проблемы, связанные с этой функцией. В Delphi7 ошибка исправлена.
Функция
CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean;
|
предназначена для того, чтобы удостовериться, что версия Windows не меньше указанной. Эта функция используется самой VCL для того, чтобы убедиться в правомерности вызовов API в разных версиях Windows. Во встреченных мной случаях проверялось несоответствие WindowsXP вызовом not CheckWin32Version(5, 1) — некоторых API (например, Flat ScrollBars устарели и не рекомендуются к использованию в Windows XP и выше). Поскольку функция небольшая, то для понимания ошибки лучше привести ее целиком (модуль Sysutils.pas из Delphi6 SP2):
function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean;
begin
Result := (AMajor > Win32MajorVersion) or
((AMajor = Win32MajorVersion) and
(AMinor >= Win32MinorVersion));
end;
|
Несложно понять, что функция будет возвращать True с параметрами 5, 1 как на Windows 2000 (версия 5.0), так и на Windows NT (версия 4.0) и других версиях Windows, предшествующих Windows XP.
В Delphi7 эта функция была исправлена:
function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean;
begin
Result := (Win32MajorVersion > AMajor) or
((Win32MajorVersion = AMajor) and
(Win32MinorVersion >= AMinor));
end;
|
Проблемы, связанные с этой функцией, двояки — во первых, в Delphi6 все функции, опирающиеся на проверку версии Windows через вызов CheckWin32Version, не будут работать — в Windows XP они могут не поддерживаться, а в более младших версиях они так и не будут использованы. Приложения, созданные в Delphi6, использующие эту функцию (при условии, что програмист "адаптировался" к реализации от Borland), могут неожиданно перестать работать правильно после перекомпиляции в Delphi7.
ТИПОВЫЕ РЕШЕНИЯ
Учитывая, что ServicePack2 для Delphi6 на данный момент последнее, а скорее всего — совсем последнее обновление для Delphi6, можно рекомендовать (варианты):
Обновить Delphi6 до Delphi7 Studio.
Заменить функцию CheckWin32Version в модуле SysUtils на версию из Delphi7 (выше). Перекомпилировать VCL.
|