Welcome, Guest
Username: Password: Remember me
Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET
  • Page:
  • 1

TOPIC:

Replacing FUNCky FSetTime FSetDate for low level File control 26 Aug 2021 02:49 #19447

  • Neil
  • Neil's Avatar
  • Topic Author


  • Posts: 11
  • I have a large project that I am looking at Xsharp for but starting on some of the smaller utilities. All in VO 2.8b4

    One of the issues I face is replacing some FUNCky functionality that I need to either rewrite into VO/X# in both is better to have less to deal with on the VO Converter for the next project so something like their old NumTokens is really just Occurs( ). I'm planning to rewrite most of the other string manipulation functionality I need like Token functionality that I need and Julian date handing, but the lowlevel file function is the challenge that I might have to consider an external DLL in C/C++/C#

    But the things I'm looking at are dealing with low level file access. As part of what has been used and still required to be done is to manipulate the file date/time stamps. It's s simple check that was done for speed to not call an index( ) on a DBF on startup if we don't need to, so we set the .IDX file date/time to match the DBF.

    Has anyone made X# versions of some of these or plans to add to the core language?

    Thanks,
    Neil

    Please Log in or Create an account to join the conversation.

    Last edit: by Neil. Reason: adding a thanks at the bottom

    Replacing FUNCky FSetTime FSetDate for low level File control 26 Aug 2021 05:58 #19448

    • wriedmann
    • wriedmann's Avatar


  • Posts: 3366
  • Hi Neil,
    the .NET Framework itself is the largest function library ever.
    Please have a look here:
    docs.microsoft.com/en-us/dotnet/api/syst...iew=netframework-4.8
    Wolfgang
    P.S. if you need to use X# libraries in VO applications you could have a look here: docs.xsharp.it/doku.php?id=com_module_sample
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    Replacing FUNCky FSetTime FSetDate for low level File control 26 Aug 2021 08:19 #19452

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hi Neil,

    In VO you can use the function SetFDateTime(). The same function is also available in X#.

    www.xsharp.eu/runtimehelp/html/M_XSharp_...ons_SetFDateTime.htm

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Last edit: by Karl-Heinz.

    Replacing FUNCky FSetTime FSetDate for low level File control 26 Aug 2021 19:31 #19470

    • Neil
    • Neil's Avatar
    • Topic Author


  • Posts: 11
  • Hi Neil,
    the .NET Framework itself is the largest function library ever.
    Please have a look here:
    docs.microsoft.com/en-us/dotnet/api/syst...iew=netframework-4.8
    Wolfgang
    P.S. if you need to use X# libraries in VO applications you could have a look here: docs.xsharp.it/doku.php?id=com_module_sample


    Thanks. I didn't really want to try to play with .Net inside VO. I've created some C# libs and tied into VO before and it can be "fun". But definitely appreciate the pointer as I might do this as a temporary thing to help and would convert easier.

    FWIW...
    I have come across some things in 26 year old code that was migrated from Clipper to Clip4Win to VO... I just found a function written that reads INIs to get section headers via fOpen and locating "[" instead of just using built in GetPrivateProfileString with a NULL... so it's a task of figuring out what the original code was trying to do and that some now basic functionality didn't exist back then, some of this code should've been redone at least 20 years ago. :lol:

    Thanks,
    Neil

    Please Log in or Create an account to join the conversation.

    Replacing FUNCky FSetTime FSetDate for low level File control 26 Aug 2021 19:36 #19471

    • Neil
    • Neil's Avatar
    • Topic Author


  • Posts: 11
  • In VO you can use the function SetFDateTime(). The same function is also available in X#.


    Thanks Karl-Heinz , I just found this after Wolfgang's reply and checked X# help B) . The problem with using some of the old library methods was as far as I can deduce the last luncky was built with VC6, so has no awareness of modern file access (SMB1 vs SMB2 even), at least VO 2.8 is closer and this will be a no brainer to use for the next conversion run.

    Thanks for the direct function name.
    -Neil

    Please Log in or Create an account to join the conversation.

    Replacing FUNCky FSetTime FSetDate for low level File control 27 Aug 2021 20:43 #19479

    • Neil
    • Neil's Avatar
    • Topic Author


  • Posts: 11
  • I was going to write that I'll have to try something else in VO for now as it still wasn't working in VO. Haven't tried X# yet.

    This reply is now for anyone having the same issue I did with VO's function to be ready for X# just passing on that I realized was a core VO bug. aka "share what you learned".

    SetFDateTime() doesn't seem to quite work in VO.
    DBF was
    04/04/2019 | 15:50:58

    Index before calling it SetFDateTime
    08/27/2021 | 01:24:24

    it sets the date but not the time
    04/04/2019 | 15:51:52

    At first I thought it was not doing it at all since I have so over 200 index files of various create/last write date/time when I look at my logs I noticed something odd, that it seemed to double the seconds and a little math shows that the :58 from the above was being doubled when taken into account

    Desired :08/20/2020|18:49:08
    Written :08/20/2020|18:49:16

    Desired :08/27/2021|02:08:10
    Written :08/27/2021|02:08:20

    I found Karl-Heinz's thread for his creation of SetFDateTime( ) in X# www.xsharp.eu/forum/public-product/1264-...time-is-missing#9155
    And was clearly the modern way, but VO was Win32API, so I I do believe X# would be fine but I noticed that the system library implementation in VO has some visible code for SetFDateTime( )

    After reading more and more into the VO win32 help file and MS online docs. I noticed that the system library implementation in VO has a flaw,
    it had
    		nHour   := Val( SubStr3(cTime, 1,2) )
    		nMinute := Val( SubStr3(cTime, 4,2) )
    		nSecond := Val( SubStr3(cTime, 7,2) ) 

    but based on DosDateTimeToFileTime ( ) should've been seconds halved.
    wFatTime - 
    Specifies the MS-DOS time. The time is a packed 16-bit value with the following format:
    
    Bits        Contents
    0-4     Second divided by 2
    5-10    Minute (0-59)
    11-15   Hour (0-23 on a 24-hour clock)
     
    		nHour   := Val( SubStr3(cTime, 1,2) )
    		nMinute := Val( SubStr3(cTime, 4,2) )
    		nSecond := Val( SubStr3(cTime, 7,2) ) /2

    so indeed the seconds we being doubled as the seconds we not being halved.
    Made my own version of the VO sys that I can easily excise it later after conversion instead of a project that calls X# outside of itself unnecessarily.


    Regards,
    Neil

    Please Log in or Create an account to join the conversation.

    Replacing FUNCky FSetTime FSetDate for low level File control 29 Aug 2021 08:47 #19480

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • Hi Neil,

    In the X# version of SetFDateTime() the seconds problem doesn't exist. With VO, try this modified SetFDateTime().

    FUNCTION SetFDateTime(cFile AS STRING, d AS DATE, cTime AS STRING) AS LOGIC PASCAL
    	LOCAL struFT IS _WINFILETIME   
    	LOCAL struST IS _winSYSTEMTIME
    	LOCAL lRet      AS LOGIC
    	LOCAL hf        AS PTR
    	LOCAL cDate     AS STRING
    	LOCAL nHour     AS WORD
    	LOCAL nMinute   AS WORD
    	LOCAL nSecond   AS WORD
    	LOCAL nYear   AS WORD
    	LOCAL nMonth  AS WORD
    	LOCAL nDay    AS WORD
    
    	hf := FOpen2(cFile, OF_READWRITE)
    
    	IF hf != F_ERROR
    		IF d == NULL_DATE
    			d := Today()
    		ENDIF
    		cDate  := DToS(d) 
    	
    		nYear  := Val( SubStr3(cDate, 1,4) ) 
    		nMonth := Val( SubStr3(cDate, 5,2) )
    		nDay   := Val( SubStr3(cDate, 7,2) ) 
    		
    		struST.wYear := nYear
    		struST.wMonth := nMonth
    		struST.wDay := nDay
    
    
    		IF Secs(cTime) == 0
    			cTime := Time()
    		ENDIF
    
    		nHour   := Val( SubStr3(cTime, 1,2) )	
    		nMinute := Val( SubStr3(cTime, 4,2) )          
    		nSecond := Val( SubStr3(cTime, 7,2) )  
    		
    		struST.wHour := nHour
    		struST.wMinute := nMinute
    		struST.wSecond := nSecond
    
    
      		IF SystemTimeToFileTime(@struST, @struFT) 
    
    			IF LocalFileTimeToFileTime(@struFT, @struFT)
    				
    				lRet := SetFileTime(hf, NULL_PTR, NULL_PTR, @struFT)
    				
    			ENDIF
    			
      		ENDIF
      		
    		FClose(hf)
    		
    	ENDIF
    
    	RETURN lRet

    BTW. I tried your approach of dividing the seconds by 2. Are you aware that this doesn´t help if you want to set odd seconds like "00:02:11"?

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Last edit: by Karl-Heinz.

    Replacing FUNCky FSetTime FSetDate for low level File control 02 Sep 2021 15:40 #19499

    • Karl-Heinz
    • Karl-Heinz's Avatar


  • Posts: 774
  • In Germany we say 'no answer is also an answer' ;-)

    My earlier posted modified VO function SetFDateTime() doesn´t work properly when the datetime to set is either inside the range of the summer- or wintertime. Here is a modified SetFDateTime() that distinguishes whether a summer or winter time is used - at least I hope so. What´s missing in VO is the declaration of the required win api function TzSpecificLocalTimeToSystemTime(). Just run this code with a valid file. i ´m not sure, but do you see the expected dates and always the same time stamp "14:00:01" ? About the used GetFDateTime() function: Such a function doesn´t exist in VO, but i created it to verify the written datetime stamp.

    Just to be clear: That´s plain VO code ;-)


    _DLL FUNC TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation AS _WINTIME_ZONE_INFORMATION,;
    	lpLocaltime AS _winSYSTEMTIME,;
    	lpUniversalTime AS _WINSYSTEMTIME);
    
    FUNCTION Start()
    LOCAL cTime, cFile AS STRING
    LOCAL dDate AS DATE
    
    cFile := "c:\test\Ansi.txt"     
    
    ? SetFDateTime(cFile , ConDate ( 2020 , 6 , 12 ), "14:00:01")   // datetime is inside the summer time 
    ? GetFDateTime ( cFile , @dDate , @cTime ) 
    ? dDate , cTime
    
    ? SetFDateTime(cFile , ConDate ( 2020 , 12 , 12 ), "14:00:01")  // datetime is inside the winter time
    ? GetFDateTime ( cFile , @dDate , @cTime ) 
    ? dDate , cTime
    
    
    FUNCTION SetFDateTime(cFile AS STRING, d AS DATE, cTime AS STRING) AS LOGIC PASCAL
    	LOCAL struFT IS _winFILETIME   
    	LOCAL struLocalST, struST IS _winSYSTEMTIME
    	LOCAL lRet      AS LOGIC
    	LOCAL hf        AS PTR
    	LOCAL cDate     AS STRING
    
    
    	hf := FOpen2(cFile, OF_READWRITE)
    
    	IF hf != F_ERROR
    		IF d == NULL_DATE
    			d := Today()
    		ENDIF
    		cDate  := DToS(d) 
    	
    	
    		struLocalST.wYear := Val( SubStr3(cDate, 1,4) )  
    		struLocalST.wMonth := Val( SubStr3(cDate, 5,2) ) 
    		struLocalST.wDay := Val( SubStr3(cDate, 7,2) )  
    
    
    		IF Secs(cTime) == 0
    			cTime := Time()
    		ENDIF
    
    		
    		struLocalST.wHour := Val( SubStr3(cTime, 1,2) )	 
    		struLocalST.wMinute := Val( SubStr3(cTime, 4,2) )   
    		struLocalST.wSecond := Val( SubStr3(cTime, 7,2) )    
    		
    		
    		IF TzSpecificLocalTimeToSystemTime( NULL_PTR , @struLocalST , @struST ) 
    		
    			IF SystemTimeToFileTime(@struST, @struFT) 
    		
    				lRet := SetFileTime(hf, NULL_PTR, NULL_PTR, @struFT)
    		
    		   ENDIF 
    		   
    		ENDIF
    				
    
    		FClose(hf)
    		
    	ENDIF
    
    	RETURN lRet
    
    
    FUNCTION GetFDateTime ( cFile AS STRING ,dDate REF DATE , cTime REF STRING ) AS LOGIC PASCAL 
    LOCAL struFindData IS _winWIN32_FIND_DATA 
    LOCAL struST, struSTLocal IS _winSYSTEMTIME
    LOCAL hFile AS PTR
    LOCAL lOK AS LOGIC
      
    
    	IF ( hFile := FindFirstFile( String2Psz ( cFile ) , @struFindData) )  != INVALID_HANDLE_VALUE
    		
    		
    		IF FileTimeToSystemTime ( @struFindData.ftLastWriteTime , @struST )   
    			
    	
    			IF SystemTimeToTzSpecificLocalTime ( NULL_PTR , @struST , @struSTLocal )
    				
    				lOK := TRUE
    				 
    	 			dDate := ConDate( struSTLocal.wYear, struSTLocal.wMonth, struSTLocal.wDay )
     			 			
    				cTime := ConTime ( struSTLocal.wHour , struSTLocal.wMinute , struSTLocal.wSecond ) 
              
    			ENDIF 
    		
    		ENDIF      			
    		
    	
    		FindClose ( hFile ) 		
    		
    	ENDIF 	
     
     	
     	RETURN lOK  

    No matter if you are interested on this topic: Still happy VOing / X#ing - and especially VFPing::-)


    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.

    Replacing FUNCky FSetTime FSetDate for low level File control 02 Sep 2021 18:48 #19503

    • Neil
    • Neil's Avatar
    • Topic Author


  • Posts: 11
  • Thanks! I haven't had a chance to get back into testing it. But plan to.
    My old code was able to set the seconds properly as it was via the FUNCky library not in VO itself, but I had also had encountered some systems that couldn't set the date/time at all so it was clear that these needed to be updated.

    for quick conversion I was doing the quick VO way to get the date and time. I had creating surface functions as so many usages wanted a string data type back and wanted to not disturb the dust in some of these places to change data types to match (at least for now)

    func _fGetTime( sFileName as STRING ) as STRING 
    	local sRet as  STRING
        
    	if ( FFirst( sFileName, FC_NORMAL ) )
    		sRet := FTime( )
    	else
    		sRet := ""
    	endif		
    
        return sRet
    
    //////////////
    func _fGetDate( sFileName as STRING ) as STRING 
    	local sRet as  STRING
        
    	if ( FFirst( sFileName, FC_NORMAL ) )
    		sRet := Dtoc( FDate( ) )
    	else
    		sRet := ""
    	endif		
    				
        return sRet
    

    But I might switch to something close to yours (or yours) just because it's using the same API not the VO version of them

    I do appreciate the followup.

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1