一个可以再WIN2000及以上操作系统使用的GetTickCount64

以后尽量用Delphi/C++双代码写.

GetTickCount返回值是整数,这样的话最多49天多就会复位重新从0开始.Vista以后提供了GetTickCount64这个函数,但是WindowsXP还是主流.在项目中为了处理这个,自己实现了一套办法.这个GetTickCount和真正的额GetTickCount相比会恒定的相差800毫秒左右.不过这个不影响使用.获取开机时间这800毫秒完全可以忽略.计算时间差的话就和GetTickCount是一样的了.

 

Delphi版XE下编译通过.

 

type
  _SYSTEM_INFORMATION_CLASS = (
    SystemBasicInformation,
    SystemProcessorInformation,
    SystemPerformanceInformation,
    SystemTimeOfDayInformation,
    SystemNotImplemented1,
    SystemProcessesAndThreadsInformation,
    SystemCallCounts,
    SystemConfigurationInformation,
    SystemProcessorTimes,
    SystemGlobalFlag,
    SystemNotImplemented2,
    SystemModuleInformation,
    SystemLockInformation,
    SystemNotImplemented3,
    SystemNotImplemented4,
    SystemNotImplemented5,
    SystemHandleInformation,
    SystemObjectInformation,
    SystemPagefileInformation,
    SystemInstructionEmulationCounts,
    SystemInvalidInfoClass1,
    SystemCacheInformation,
    SystemPoolTagInformation,
    SystemProcessorStatistics,
    SystemDpcInformation,
    SystemNotImplemented6,
    SystemLoadImage,
    SystemUnloadImage,
    SystemTimeAdjustment,
    SystemNotImplemented7,
    SystemNotImplemented8,
    SystemNotImplemented9,
    SystemCrashDumpInformation,
    SystemExceptionInformation,
    SystemCrashDumpStateInformation,
    SystemKernelDebuggerInformation,
    SystemContextSwitchInformation,
    SystemRegistryQuotaInformation,
    SystemLoadAndCallImage,
    SystemPrioritySeparation,
    SystemNotImplemented10,
    SystemNotImplemented11,
    SystemInvalidInfoClass2,
    SystemInvalidInfoClass3,
    SystemTimeZoneInformation,
    SystemLookasideInformation,
    SystemSetTimeSlipEvent,
    SystemCreateSession,
    SystemDeleteSession,
    SystemInvalidInfoClass4,
    SystemRangeStartInformation,
    SystemVerifierInformation,
    SystemAddVerifier,
    SystemSessionProcessesInformation);
  SYSTEM_INFORMATION_CLASS = _SYSTEM_INFORMATION_CLASS;
  TSystemInformationClass = SYSTEM_INFORMATION_CLASS;

  _SYSTEM_TIME_OF_DAY_INFORMATION = record // Information Class 3
    BootTime: LARGE_INTEGER;
    CurrentTime: LARGE_INTEGER;
    TimeZoneBias: LARGE_INTEGER;
    CurrentTimeZoneId: ULONG;
  end;
  SYSTEM_TIME_OF_DAY_INFORMATION = _SYSTEM_TIME_OF_DAY_INFORMATION;
  PSYSTEM_TIME_OF_DAY_INFORMATION = ^SYSTEM_TIME_OF_DAY_INFORMATION;



function  NtQuerySystemInformation(
    SystemInformationClass : SYSTEM_INFORMATION_CLASS;
    SystemInformation : PVOID;
    SystemInformationLength : ULONG;
    ReturnLength : PULONG
  ): Integer; stdcall; external 'ntdll.dll';

function  NtQuerySystemTime(
    var CurrentTime : LARGE_INTEGER
  ): Integer; stdcall; external 'ntdll.dll';


function _GetTickCount64():Int64;
var
  st : SYSTEM_TIME_OF_DAY_INFORMATION;
  r : ULONG;
  ct : LARGE_INTEGER;
begin
  NtQuerySystemInformation(SystemTimeOfDayInformation,
                           @st,
                           SizeOf(SYSTEM_TIME_OF_DAY_INFORMATION),
                           @r);
  NtQuerySystemTime(ct);
  Result :=(ct.QuadPart-st.BootTime.QuadPart)div 10000;
end;

 

VC版:

typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);
typedef ULONG (__stdcall * NTQUERYSYSTEMINFORMATION)(IN     /*SYSTEM_INFORMATION_CLASS*/int, IN OUT PVOID, INT    ULONG, OUT    PULONG OPTION);
GetTickCount64Proc* VistaGetTickCount64 = (GetTickCount64Proc*)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetTickCount64");

NTQUERYSYSTEMINFORMATION _NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), ("NtQuerySystemInformation"));

INT64 _GetTickCount64()
{
    typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION
    {
        LARGE_INTEGER BootTime;
        LARGE_INTEGER CurrentTime;
        LARGE_INTEGER TimeZoneBias;
        ULONG CurrentTimeZoneId;
    } SYSTEM_TIME_OF_DAY_INFORMATION, *PSYSTEM_TIME_OF_DAY_INFORMATION;
    //如果系统存在VistaGetTickCount64函数则调用系统的
    if (VistaGetTickCount64)
        return VistaGetTickCount64();
    SYSTEM_TIME_OF_DAY_INFORMATION  st ={0};
    ULONG                           oSize = 0;
    if((NULL == _NtQuerySystemInformation)||0 !=(_NtQuerySystemInformation(3, &st, sizeof(st), &oSize))||
        (oSize!= sizeof(st)))
        return GetTickCount();
    return (st.CurrentTime.QuadPart - st.BootTime.QuadPart)/10000;
}

 

你可能感兴趣的:(Delphi技术,Windows技术,C++技术)