udfStrFormByteSize (numstr, numlen, declen)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfstrformatbytesize",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfstrformatbytesize

#DefineFunction udfStrFormatByteSize (iNumber)
iBBSize = 16
hBB = BinaryAlloc(iBBSize)
BinaryEodSet(hBB,iBBSize)
sFormStr = ""
If DllCall(StrCat(DirWindows(1),"SHLWAPI.DLL"),long:"StrFormatByteSizeA",long:iNumber,lpbinary:hBB,long:iBBSize) Then sFormStr = BinaryPeekStr(hBB,0,iBBSize)
BinaryFree(hBB)
Return (sFormStr)
;..........................................................................................................................................
;   Range for iNumber = 0..(2**32)-1
;..........................................................................................................................................
;   StrFormatByteSizeA Function
;   Converts a numeric value into a string that represents the number expressed
;   as a size value in bytes, kilobytes, megabytes, or gigabytes, depending on the size.
;
;   Syntax
;   LPTSTR StrFormatByteSizeA(
;       DWORD dw,
;       LPSTR pszBuf,
;       UINT cchBuf
;   );
;
;   Parameters
;   dw
;   [in] Numeric value to be converted.
;
;   pszBuf
;   [out] Pointer to the converted string.
;
;   cchBuf
;   [in] Size of pszBuf, in characters.
;
;   Return Value
;   Returns the address of the converted string, or NULL if the conversion fails.
;
;   Remarks
;   The first parameter of this function has a different type for the ANSI and Unicode versions.
;   If your numeric value is a DWORD, you can use StrFormatByteSize with text macros for both cases.
;   The compiler will cast the numerical value to a LONGLONG for the Unicode case.
;   If your numerical value is a LONGLONG, you should use StrFormatByteSizeW explicitly.
;
;   Example
;          532 -> 532 bytes
;         1340 -> 1.3KB
;        23506 -> 23.5KB
;      2400016 -> 2.4MB
;   2400000000 -> 2.4GB
;
;   Function Information
;   Minimum DLL Version shlwapi.dll version 4.71 or later
;..........................................................................................................................................
#EndFunction

:skip_udfstrformatbytesize
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfstrformbytesize",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfstrformbytesize

#DefineFunction udfStrFormByteSize (numstr, numlen, declen)
div = 1024
len = StrLen(div)
dim = 0
lenpre = numlen-declen-(declen>0)
If (lenpre<1) Then Return ("")

While 1
   pos = 1
   num = StrSub(numstr,pos,len)
   pos = pos + len
   numpre = 0
   numpost = 0
   resultstr = ""
   While 1
      numpre = num / div
      numpost = num - (numpre * div)
      resultstr = StrCat(resultstr,numpre)
      digit = StrSub(numstr,pos,1)
      If (digit=="") Then Break
      num = StrCat(numpost,digit)
      pos = pos + 1
   EndWhile
   dim = dim + 1
   If (StrLen(resultstr)<=lenpre) Then Break
   numstr = resultstr
EndWhile

If (numpost>0)
   numpost = 1.0 * numpost / div         ; 0.1234567
   numpost = StrReplace(numpost,".","")  ; "01234567"
   lenpost = StrLen(numpost)

   strpost = ""
   lenmin = Max(2,declen+2)
   For i=lenpost To lenmin By -1
      numround = Min(9,StrSub(numpost,i-1,1) + (StrSub(numpost,i,1)>4))
      strpost = StrCat(numround,strpost)
   Next
   strpost = StrCat(StrSub(numpost,1,declen),strpost)

   resultstr = 0 + resultstr + StrSub(strpost,1,1) ; add maybe overflow

   If (declen>0)
      resultstr = StrCat(resultstr,".")
      For i=1 To declen
         resultstr = StrCat(resultstr,StrSub(strpost,i+1,1))
      Next
   EndIf
Else
   If (declen>0)
      resultstr = StrCat(resultstr,".",StrFill("0",declen))
   EndIf
EndIf

dim = ItemExtract(dim+1," Byte, KB, MB, GB, TB, ??",",")
resultstr = StrCat(resultstr,dim)

Return (resultstr)
;..........................................................................................................................................
; Example:
; sNumString = udfStrFormByte ("23456789", 6, 2)
; This function "udfStrFormByteSize" returns a formatted string like "22.37 MB".
;..........................................................................................................................................
; Detlev Dalitz.20020529
;..........................................................................................................................................
#EndFunction

:skip_udfstrformbytesize
;------------------------------------------------------------------------------------------------------------------------------------------



; --- test ---
; Note: Germany country settings.

:test1
sStr11 = udfStrFormatByteSize (       532)    ; "532 Byte"
sStr12 = udfStrFormatByteSize (      9999)    ; "9,76 KB"
sStr13 = udfStrFormatByteSize (     65536)    ; "64,0 KB"
sStr14 = udfStrFormatByteSize (    131072)    ; "128 KB"
sStr15 = udfStrFormatByteSize (   1048576)    ; "1,00 MB"
sStr16 = udfStrFormatByteSize (  16777216)    ; "16,0 MB"
sStr17 = udfStrFormatByteSize (1073741824)    ; "1,00 GB"
sStr18 = udfStrFormatByteSize (4294967296-1)  ; "3,99 GB"
sStr19 = udfStrFormatByteSize (4294967296)    ; "0 Byte" !!!


:test2
number   = 4294967296
sMsgTitle = number
sMsgText  = udfStrFormByteSize (number, 6, 2) ; "0.00 KB"
Message(sMsgTitle,sMsgText)

number   = "4294967296"
sMsgTitle = number
sMsgText  = udfStrFormByteSize (number, 6, 2) ; "4.00 GB"
Message(sMsgTitle,sMsgText)

number   = "4294967296000"
sMsgTitle = number
sMsgText  = udfStrFormByteSize (number, 6, 2) ; "3.91 TB"
Message(sMsgTitle,sMsgText)


:test3
;sTestNumber = "4294967296"  ; 4 GB = 4096 * 1024 * 1024
sTestNumber = "4294967295"  ; 4GB - 1 Byte
;sTestNumber = "242992069738496" ; 221 TB

BoxOpen(sMsgTitle,"Running test ...")

sList = ""
For declen=3 To 0 By -1
   For numlen=10 To (declen+2) By -1
      BoxText(StrCat("Test ",@TAB,numlen,@TAB,declen))
      numstr = udfStrFormByteSize (sTestNumber, numlen, declen)
      sList = StrCat(sList,'udfStrFormByteSize (',sTestNumber,', ',numlen,', ',declen,')',@TAB,' = ',@TAB,'"',numstr,'"',@LF)
   Next
Next
BoxShut()

IntControl(28,1,0,0,0)
IntControl(63,200,100,800,900)
AskItemlist(sMsgTitle,sList,@LF,@UNSORTED,@SINGLE)

:CANCEL
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*