Конференция "KOL" » Определение версии Windows в KOL
 
  • Ruzzz © (23.02.10 04:15) [0]
    1) ASM версия WinVer немного некорректна:
     INC   AL // wvSeven
     CMP   DX, $0601
     JZ    @@save_exit
    @@platform_9x:


    Если это будет новая версия или вообще какая нибудь не известная старая :), то мы попадем в ветку кода platform_9x

    2) Зачем нужна
    //[function IsWinVer]
    function IsWinVer( Ver : TWindowsVersions ) : Boolean;
    {* Returns True if Windows version is in given range of values. }
    begin
     Result := WinVer in Ver;
    end;



    ?

    Она нигде в KOL не используется, на оборот в том же KOL используется код типа:
    function MenuStructSize: Integer;
    begin
     Result := 44;
     if not( WinVer in [wv31, wv95, wvNT] ) then
       Result := {48=} 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 // wvSeven
     CMP   DX, $0601
     JZ    @@save_exit
    @@platform_9x:


    Если это будет новая версия или вообще какая нибудь не известная старая :), то мы попадем в ветку кода platform_9x

    2) Зачем нужна
    //[function IsWinVer]
    function IsWinVer( Ver : TWindowsVersions ) : Boolean;
    {* Returns True if Windows version is in given range of values. }
    begin
     Result := WinVer in Ver;
    end;



    ?

    Она нигде в KOL не используется, на оборот в том же KOL используется код типа:
    function MenuStructSize: Integer;
    begin
     Result := 44;
     if not( WinVer in [wv31, wv95, wvNT] ) then
       Result := {48=} 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-линейки делает то же самое, да еще и выше указанная не точность. Так что в случае с нестандартной версией :) все равно беда.
  • Ruzzz © (23.02.10 04:20) [1]
    Извиняюсь. Что-то ужасное случилось с этим сообщением :( Может модераторы подредактируют и остаят только первых два пункта?

    Вот 3-ий пункт отдельно, чтобы понятней было:

    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-линейки делает то же самое, да еще и выше указанная не точность. Так что в случае с нестандартной версией :) все равно беда.

    Вы хоть скажите что думаете?
  • miek (23.02.10 13:30) [2]
    Есть такой хороший подход - не хранить то, что можно вычислить. Часто ли проверяется версия win при работе программы? Обычно не больше одного раза. Может ли она измениться после запуска? Нет.
  • Ruzzz © (23.02.10 22:14) [3]
    Можно и не кешировать, но цена за удобство (если нужно уточнить), всего 7 байт.
 
Конференция "KOL" » Определение версии Windows в KOL
Есть новые Нет новых   [134431   +10][b:0][p:0.005]