Pascal: Get field from LPSYSTEMTIME record

2019-08-01 20:47发布

I'm using the Win32 api to get date and time of a file. I have a LPSYSTEMTIME structure, and I'm trying to print its wYear variable.

I've got a function (GetFileDate):

function GetFileDate : LPSYSTEMTIME
var
    CheckFile: Long;
    FileTime: LPFILETIME;
    FileTimeReturn: LPFILETIME;
    SystemTimeReturn: LPSYSTEMTIME;
begin
    CheckFile := CreateFile(PChar('main.pas'), GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    GetFileTime(CheckFile, FileTime, NIL, NIL);
    FileTimeToLocalFileTime(FileTime, FileTimeReturn);
    FileTimeToSystemTime(FileTimeReturn, SystemTimeReturn);
    GetFileDate := SystemTimeReturn;
end;

But when I do this...

begin
    Write(GetFileDate.wYear);
end.

It spits back

main.pas(22,20) Error: Illegal qualifier
main.pas(22,20) Fatal: Syntax error, ")" expected but "identifier WYEAR" found
Fatal: Compilation aborted

Any help on this?

1条回答
一夜七次
2楼-- · 2019-08-01 21:42

LPSYSTEMTIME is a pointer to a SYSTEMTIME structure. Try using the ^ operator to dereference that pointer, eg:

Write(GetFileDate^.wYear);

Or:

Write(GetFileDate()^.wYear);

With that said, aside from the fact that you are not doing any error handling at all, your GetFileDate() implementation is passing the wrong parameter values to the various API functions. That code should not even compile, let alone run correctly.

Try this instead:

function GetFileDate : SYSTEMTIME;
var 
  CheckFile: HANDLE; 
  FileTime: FILETIME; 
  FileTimeReturn: FILETIME; 
  SystemTimeReturn: SYSTEMTIME;
  GetFileDateResult: SYSTEMTIME;
begin 
  ZeroMemory(@GetFileDateResult, SizeOf(GetFileDateResult));
  CheckFile := CreateFile('FullPathTo\main.pas', GENERIC_READ, FILE_SHARE_READ, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
  if CheckFile <> INVALID_HANDLE_VALUE then
  begin
    if GetFileTime(CheckFile, @FileTime, nil, nil) then
    begin
      if FileTimeToLocalFileTime(@FileTime, @FileTimeReturn) then
      begin
        if FileTimeToSystemTime(@FileTimeReturn, @SystemTimeReturn) then
          GetFileDateResult := SystemTimeReturn;
      end;
    end;
    CloseHandle(CheckFile);
  end; 
  GetFileDate := GetFileDateResult;
end; 

begin   
  Write(GetFileDate.wYear);   
end.

Alternatively, I would suggest using FindFirstFile() instead of CreateFile() so you do not have to open the file just to get its date. The filesystem can supply that information, eg:

function GetFileDate : SYSTEMTIME;
var 
  CheckFile: HANDLE; 
  FindFileData: WIN32_FIND_DATA;
  FileTimeReturn: FILETIME; 
  SystemTimeReturn: SYSTEMTIME;
  GetFileDateResult: SYSTEMTIME;
begin 
  ZeroMemory(@GetFileDateResult, SizeOf(GetFileDateResult));
  CheckFile := FindFirstFile('FullPathTo\main.pas', @FindFileData);
  if CheckFile <> 0 then
  begin
    if FileTimeToLocalFileTime(@FindFileData.ftCreationTime, @FileTimeReturn) then
    begin
      if FileTimeToSystemTime(@FileTimeReturn, @SystemTimeReturn) then
        GetFileDateResult := SystemTimeReturn;
    end;
    FindClose(CheckFile);
  end; 
  GetFileDate := GetFileDateResult;
end; 
查看更多
登录 后发表回答