{$IFNDEF WINCE}
type
TGetTickCount64 = function : QWord; stdcall;
var
WinGetTickCount64: TGetTickCount64 = Nil;
{$ENDIF}
function GetTickCount64: QWord;
{$IFNDEF WINCE}
var
lib: THandle;
{$ENDIF}
begin
{$IFNDEF WINCE}
{ on Vista and newer there is a GetTickCount64 implementation }
if Win32MajorVersion >= 6 then begin
if not Assigned(WinGetTickCount64) then begin
lib := LoadLibrary('kernel32.dll');
WinGetTickCount64 := TGetTickCount64(
GetProcAddress(lib, 'GetTickCount64'));
end;
Result := WinGetTickCount64();
end else
{$ENDIF}
Result := Windows.GetTickCount;
end;
It is usually better to not rely on OS version checking like that (especially since Win32MajorVersion is just a variable in memory and subject to memory corruption). It is better to just check if the function actually exists, and if not then fallback to the older function
Also, the code should be using GetModuleHandle() instead of LoadLibrary(), since kernel32.dll is guaranteed to already be in memory, so LoadLibrary() would just increment its reference count, which is not necessary.
{$IFNDEF WINCE}
type
TGetTickCount64 = function : QWord; stdcall;
var
WinGetTickCount64: TGetTickCount64 = Nil;
function GetTickCount64_Fallback: QWord; stdcall;
begin
Result := Windows.GetTickCount;
end;
{$ENDIF}
function GetTickCount64: QWord;
begin
{$IFNDEF WINCE}
{ on Vista and newer there is a GetTickCount64 implementation }
if not Assigned(WinGetTickCount64) then begin
WinGetTickCount64 := TGetTickCount64(GetProcAddress(GetModuleHandle('kernel32.dll'), 'GetTickCount64'));
if WinGetTickCount64 = nil then
WinGetTickCount64 := @GetTickCount64_Fallback;
end;
Result := WinGetTickCount64();
{$ELSE}
Result := Windows.GetTickCount;
{$ENDIF}
end;
Indy does something similar, but in a slightly different way:
{$IFDEF WINDOWS}
type
TGetTickCount64Func = function: UInt64; stdcall;
var
GetTickCount64: TGetTickCount64Func = nil;
function Impl_GetTickCount64: UInt64; stdcall;
{$IFDEF USE_INLINE}inline;{$ENDIF}
begin
// TODO: implement some kind of accumulator so the Result
// keeps growing even when GetTickCount() wraps back to 0
Result := UInt64(Windows.GetTickCount);
end;
function Stub_GetTickCount64: UInt64; stdcall;
function GetImpl: Pointer;
begin
Result := GetProcAddress(GetModuleHandle('KERNEL32'), 'GetTickCount64'); {do not localize}
if Result = nil then begin
Result := @Impl_GetTickCount64;
end;
end;
begin
@GetTickCount64 := GetImpl();
Result := GetTickCount64();
end;
{$ENDIF}
...
initialization
...
{$IFDEF WINDOWS}
GetTickCount64 := Stub_GetTickCount64;
{$ENDIF}
...
[code]