1) ASM версия WinVer немного некорректна:
INC AL
CMP DX, $0601
JZ @@save_exit
@@platform_9x:
Если это будет новая версия или вообще какая нибудь не известная старая :), то мы попадем в ветку кода platform_9x
2) Зачем нужна
function IsWinVer( Ver : TWindowsVersions ) : Boolean;
begin
Result := WinVer in Ver;
end;
?
Она нигде в KOL не используется, на оборот в том же KOL используется код типа:
function MenuStructSize: Integer;
begin
Result := 44;
if not( WinVer in [wv31, wv95, wvNT] ) then
Result := Sizeof( TMenuItemInfo );
end;
Не проще ли ее вообще убрать для экономия :)
3)
Я немного изменил код:
unit rzWinVer;
interface
type
TWindowsVersion = (
wvNotInit = 0, wvUnknow,
wv31, wv95, wv98, wvME,
wvNT, wvY2K, wvXP, wvServer2003,
wvVista, wvSeven,
{add here}
wvNew = $FF
);
//TWinVer = TWindowsVersion; // Так короче :)
TWindowsVersions = set of TWindowsVersion;
//TWinVers = TWindowsVersions; // Так короче :)
TCurWinVer = record
Version: TWindowsVersion;
MajorVersion,
MinorVersion: Byte;
VersionExtra: Integer;
end;
function WinVer: TWindowsVersion;
var
CurWinVer: TCurWinVer;
// SaveWinVer: Byte = $FF;
implementation
uses
Windows;
function WinVer: TWindowsVersion;
begin
if CurWinVer.Version <> wvNotInit then begin
Result := CurWinVer.Version; // Form cache :)
Exit;
end;
CurWinVer.VersionExtra := GetVersion;
CurWinVer.MajorVersion := LoByte(CurWinVer.VersionExtra);
CurWinVer.MinorVersion := HiByte(LoWord(CurWinVer.VersionExtra));
if {(Integer)}CurWinVer.VersionExtra < 0 then begin
//
http://support.microsoft.com/kb/158238 case CurWinVer.MajorVersion of
1, 2: Result := wvUnknow;
3: Result := wv31; // 3.1 etc
4: case CurWinVer.MinorVersion of
0..3: Result := wv95; // 4.00 - 4.03
10: Result := wv98; // 4.10
90: Result := wvME; // 4.90
else Result := wvUnknow;
end;
else Result := wvUnknow;
end
end else begin // линейка NT
//
http://msdn.microsoft.com/en-us/library/ms724832(VS.85).aspx
case CurWinVer.MajorVersion of
1, 2: Result := wvUnknow;
3, 4: Result := wvNT; // 3.n or 4.n
5: case CurWinVer.MinorVersion of
0: Result := wvY2K; // 5.0
1: Result := wvXP; // 5.1
2: Result := wvServer2003; // 5.2
else Result := wvUnknow;
end;
6: case CurWinVer.MinorVersion of
0: Result := wvVista; // 6.0 // or Windows Server 2008
1: Result := wvSeven; // 6.1 // or Windows Server 2008 R2
else Result := wvNew;
end;
else Result := wvNew;
end
end;
CurWinVer.Version := Result;
end;
initialization
FillChar(CurWinVer, SizeOf(CurWinVer), 0);
end.
Выделил отдельно wvUnknow - мало ли что может быть :) пусть в этом случае программист решает сам. А для этого я решил:
Кешировать также и
TCurWinVer = record
Version: TWindowsVersion;
MajorVersion,
MinorVersion: Byte;
VersionExtra: Integer;
end;
Ведь все равно вычисляем пусть себе храниться.
Обратная совместимость есть. Единственное - я использую равно при сравнении версии, но текущая асм-версия для nt-линейки делает то же самое, да еще и выше указанная не точность. Так что в случае с нестандартной версией :) все равно беда.
Вы хоть скажите что думаете?1) ASM версия WinVer немного некорректна:
INC AL
CMP DX, $0601
JZ @@save_exit
@@platform_9x:
Если это будет новая версия или вообще какая нибудь не известная старая :), то мы попадем в ветку кода platform_9x
2) Зачем нужна
function IsWinVer( Ver : TWindowsVersions ) : Boolean;
begin
Result := WinVer in Ver;
end;
?
Она нигде в KOL не используется, на оборот в том же KOL используется код типа:
function MenuStructSize: Integer;
begin
Result := 44;
if not( WinVer in [wv31, wv95, wvNT] ) then
Result := Sizeof( TMenuItemInfo );
end;
Не проще ли ее вообще убрать для экономия :)
3)
Я немного изменил код:
unit rzWinVer;
interface
type
TWindowsVersion = (
wvNotInit = 0, wvUnknow,
wv31, wv95, wv98, wvME,
wvNT, wvY2K, wvXP, wvServer2003,
wvVista, wvSeven,
{add here}
wvNew = $FF
);
//TWinVer = TWindowsVersion; // Так короче :)
TWindowsVersions = set of TWindowsVersion;
//TWinVers = TWindowsVersions; // Так короче :)
TCurWinVer = record
Version: TWindowsVersion;
MajorVersion,
MinorVersion: Byte;
VersionExtra: Integer;
end;
function WinVer: TWindowsVersion;
var
CurWinVer: TCurWinVer;
// SaveWinVer: Byte = $FF;
implementation
uses
Windows;
function WinVer: TWindowsVersion;
begin
if CurWinVer.Version <> wvNotInit then begin
Result := CurWinVer.Version; // Form cache :)
Exit;
end;
CurWinVer.VersionExtra := GetVersion;
CurWinVer.MajorVersion := LoByte(CurWinVer.VersionExtra);
CurWinVer.MinorVersion := HiByte(LoWord(CurWinVer.VersionExtra));
if {(Integer)}CurWinVer.VersionExtra < 0 then begin
//
http://support.microsoft.com/kb/158238 case CurWinVer.MajorVersion of
1, 2: Result := wvUnknow;
3: Result := wv31; // 3.1 etc
4: case CurWinVer.MinorVersion of
0..3: Result := wv95; // 4.00 - 4.03
10: Result := wv98; // 4.10
90: Result := wvME; // 4.90
else Result := wvUnknow;
end;
else Result := wvUnknow;
end
end else begin // линейка NT
//
http://msdn.microsoft.com/en-us/library/ms724832(VS.85).aspx
case CurWinVer.MajorVersion of
1, 2: Result := wvUnknow;
3, 4: Result := wvNT; // 3.n or 4.n
5: case CurWinVer.MinorVersion of
0: Result := wvY2K; // 5.0
1: Result := wvXP; // 5.1
2: Result := wvServer2003; // 5.2
else Result := wvUnknow;
end;
6: case CurWinVer.MinorVersion of
0: Result := wvVista; // 6.0 // or Windows Server 2008
1: Result := wvSeven; // 6.1 // or Windows Server 2008 R2
else Result := wvNew;
end;
else Result := wvNew;
end
end;
CurWinVer.Version := Result;
end;
initialization
FillChar(CurWinVer, SizeOf(CurWinVer), 0);
end.
Выделил отдельно wvUnknow - мало ли что может быть :) пусть в этом случае программист решает сам. А для этого я решил:
Кешировать также и
TCurWinVer = record
Version: TWindowsVersion;
MajorVersion,
MinorVersion: Byte;
VersionExtra: Integer;
end;
Ведь все равно вычисляем пусть себе храниться.
Обратная совместимость есть. Единственное - я использую равно при сравнении версии, но текущая асм-версия для nt-линейки делает то же самое, да еще и выше указанная не точность. Так что в случае с нестандартной версией :) все равно беда.