Announcement

Collapse
No announcement yet.

Zip/Unzip Files

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #21
    I got it off my on-dosk SDK from 2002 under the "copyhere" method of the Folder object.

    I'll bet I can find it at MSDN....



    MCM
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


      #22
      Hi MCM,
      And so you did ... thanks!

      I searched on several of the equate names, such as CHO_NOPROGRESS, and got no hits.

      It's not the first time I've had someone find something in the SDK docs that was different/missing from MSDN.

      But, I also checked my local copy of the SDK (v7.1) for the equate name, and got no search results there, either - it matches what I see on MSDN. I guess you have an older, "golden" copy?
      Last edited by Gary Beene; 11 May 2012, 12:54 PM.

      Comment


        #23
        > searched on several of the equate names, such as CHO_NOPROGRESS, and got no hits.

        AFAIK the only place those names exist is on my hard disk and in this forum. I made them up. All by myself.

        MCM
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


          #24
          Hey MCM,
          Re: this:
          ...only place those names exist is on my hard disk and in this forum. I made them up. All by myself.
          and this:
          I got it off my on-disk SDK from 2002 under the "copyhere" method of the Folder object.
          Well, then, you should have given yourself attribution instead of leaving it unattributed. It would kept me from going on a wild CHO_NoProgress goosechase! Well, not that wild, but I did search for the term.

          Comment


            #25
            here's a fixed version for your example gary above. as I was interesting in zip file technology I made this example too
            Code:
            #COMPILE EXE
            #DIM ALL
            #DEBUG ERROR ON
            #DEBUG DISPLAY ON
            #INCLUDE "win32api.inc"
            #INCLUDE "winshell.inc"
            
            FUNCTION PBMAIN() AS LONG
               DIM fList(1) AS STRING
               fList(0) = "c:\test\arguments.txt"                     '<--------- use your own  --------
               fList(1) = "c:\test\unicode.txt"                       '<--------- use your own  --------
            
               CreateZipFileFromList fList(), "c:\test\allfiles.zip"  '<--------- use your own  --------
            END FUNCTION
            
            '==================================================
            '  CreateZipFile - creates a zip file
            '==================================================
            FUNCTION CreateZipFileFromList(fList() AS STRING, BYVAL sTo AS STRING) AS LONG
               LOCAL hFile          AS DWORD
               'Object Variables
               DIM oShellClass      AS IShellDispatch
               DIM oSourceFolder    AS Folder
               DIM oTargetFolder    AS Folder
               DIM oItem            AS FolderItem
               'variants
               DIM vSourceFolder    AS VARIANT
               DIM vTargetFolder    AS VARIANT
               DIM vOptions         AS VARIANT
               DIM vFile            AS VARIANT
               DIM sFile            AS STRING
               DIM i                AS LONG          '-----------new---------------------------
            
               'First we create an empty ZIP file using a standard zip file header
               TRY
                  hFile = FREEFILE
                  OPEN sTo FOR OUTPUT AS #hFile
                  PRINT #hFile, CHR$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
                  CLOSE #hFile
               CATCH
                  ? "Error creating Zip file: " & sTo & "  Error:" & ERROR$(ERR)
                  EXIT FUNCTION
               END TRY
            
            
               ' Get an instance of our Windows Shell
               oShellClass = ANYCOM $PROGID_SHELL32_SHELL
            
               ' Did we get the object? If not, terminate this app
               IF ISFALSE ISOBJECT(oShellClass) OR ERR THEN
                  ? "Could not get the Windows Shell object.  Error:" & STR$(ERR)
                  EXIT FUNCTION
               END IF
            
            
            FOR i = 0 TO UBOUND(fList)                  '-----------new----------------------
            
            
               'assign the source folder we want to zip up
               vSourceFolder = RTRIM$(PATHNAME$(PATH, fList(i)),"\")    '--------modified------------
               oSourceFolder = oShellClass.NameSpace(vSourceFolder)
            
               IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN
                  ? "Could not get the Source folder object.  Error:" & STR$(ERR)
                  GOTO TerminateZip
               END IF
            
            
               'assign the target folder we want to create (in this case it is a zip file)
               vTargetFolder = sTo
               oTargetFolder = oShellClass.NameSpace(vTargetFolder)
            
               IF ISFALSE ISOBJECT(oTargetFolder) OR ERR THEN
                  ? "Could not get the Target folder object.  " & sTo & " Error:" & STR$(ERR)
                  GOTO TerminateZip
               END IF
            
            
               'get the file name we are copying
               'sFile = ucode$(PATHNAME$(NAME, sFrom) & PATHNAME$(EXTN, sFrom))
               sFile = PATHNAME$(NAMEX, fList(i))                '-----------modified for PBWin10 -----
            
            '------------> fixed part --------------------------->
            ' ---> change "oItem" with "sSourceFolder" and the example will work.
            ' ---> You will find in new created zipfolder the textfile ! :)
            
               'assign the file item
               oItem = oSourceFolder.ParseName(sFile)
            '   oSourceFolder = oShellClass.NameSpace(vSourceFolder)
               IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN 'change oItem
                  ? "Could not get the Item object. " & sFile & " Error:" & STR$(ERR) '
                  GOTO TerminateZip
               END IF
            
               'now we start the copy in to the new zip file
               vOptions = 20
               oTargetFolder.CopyHere(oSourceFolder, vOptions) 'change oItem
            
               IF ERR THEN
                  ? "Got an Error during the CopyHere method.  Error:" & STR$(ERR)
                  GOTO TerminateZip
               END IF
            
            '------------> fixed part end --------------------------->
            
            NEXT i                                      '-----------new----------------------
            
               'NOTE:  the above copyhere method starts a seperate thread to do the copy
               'so the command could return before the copy is finished, so we need to
               'allow time to complete.   Thus the next Sleep command.
               SLEEP 6000   'increase for larger folders
            
               ? sTo + " was successfully created."
               FUNCTION = %TRUE
            
               TerminateZip:
            
               ' Close all of the Interfaces
               vFile             = EMPTY
               vSourceFolder     = EMPTY
               vTargetFolder     = EMPTY
               vOptions          = EMPTY
               oItem             = NOTHING
               oTargetFolder     = NOTHING
               oSourceFolder     = NOTHING
               oShellClass       = NOTHING
            END FUNCTION
            best regards, frank
            Attached Files
            Last edited by frank bruebach; 12 May 2012, 10:46 AM.

            Comment


              #26
              my code tags are not working here at the moment, sorry

              Comment


                #27
                try adding the end tag.

                [ /code ] without the spaces.

                Comment


                  #28
                  Originally posted by Gary Beene View Post
                  Hi William,
                  ...
                  2. If the target zip file exists, it is replaced with a zip file containing only the first file in the list.
                  3. It sometimes fails with "File not found or no permission". I can't get this to happen on demand.
                  Gary, sorry for the delay. As for question 2, yes part of the code is creating a new blank zip file to copy the new file(s) to, so if you want to add to existing zip files, it should be as simple as adding some basic code to see if the file already exists and if it does, skip the "create empty ZIP file" step.

                  As for question 3, my guess would be either the file or path you tried to copy was not found or maybe the zip file is open or "locked" by some process?
                  "I haven't lost my mind... its backed up on tape... I think??" :D

                  Comment


                    #29
                    I'm sorry to disturb you, but I am getting frustrated:

                    All I need is a routine that zips one file:

                    Having:
                    FilepathStr = "C:\Documents and Settings\a.mariani\Desktop\Nuova cartella\"
                    DestFile = "ev_v1.4_(619AD993).inc"
                    ZipFile = "ev_v1.4_(619AD993).zip"
                    I tried
                    Code:
                        CreateZipFile(FilePathStr + DestFile, FilePathStr + ZipFile)
                    But I get an empty zip file
                    Code:
                    '==================================================
                    '  CreateZipFile - creates a zip file
                    '==================================================
                    FUNCTION CreateZipFile(BYVAL sFrom AS STRING, BYVAL sTo AS STRING) AS LONG
                       LOCAL hFile          AS DWORD
                       'Object Variables
                       DIM oShellClass      AS IShellDispatch
                       DIM oSourceFolder    AS Folder
                       DIM oTargetFolder    AS Folder
                       DIM oItem            AS FolderItem
                       'variants
                       DIM vSourceFolder    AS VARIANT
                       DIM vTargetFolder    AS VARIANT
                       DIM vOptions         AS VARIANT
                       DIM vFile            AS VARIANT
                       DIM sFile            AS STRING
                    
                       'First we create a empty ZIP file using a standard zip file header
                       TRY
                          hFile = FREEFILE
                          OPEN sTo FOR OUTPUT AS #hFile
                          PRINT #hFile, CHR$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
                          CLOSE #hFile
                       CATCH
                          ? "Error creating Zip file: " & sTo & "  Error:" & ERROR$(ERR)
                          EXIT FUNCTION
                       END TRY
                    
                    
                       ' Get an instance of our Windows Shell
                       oShellClass = ANYCOM $PROGID_SHELL32_SHELL
                    
                       ' Did we get the object? If not, terminate this app
                       IF ISFALSE ISOBJECT(oShellClass) OR ERR THEN
                          ? "Could not get the Windows Shell object.  Error:" & STR$(ERR)
                          EXIT FUNCTION
                       END IF
                    
                    
                       'assign the source folder we want to zip up
                       vSourceFolder = RTRIM$(PATHNAME$(PATH, sFrom),"\")
                       oSourceFolder = oShellClass.NameSpace(vSourceFolder)
                    
                       IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN
                          ? "Could not get the Source folder object.  Error:" & STR$(ERR)
                          GOTO TerminateZip
                       END IF
                    
                    
                       'assign the target folder we want to create (in this case it is a zip file)
                       vTargetFolder = sTo
                       oTargetFolder = oShellClass.NameSpace(vTargetFolder)
                    
                       IF ISFALSE ISOBJECT(oTargetFolder) OR ERR THEN
                          ? "Could not get the Target folder object.  " & sTo & " Error:" & STR$(ERR)
                          GOTO TerminateZip
                       END IF
                    
                    
                       'get the file name we are copying
                       sFile = PATHNAME$(NAMEX, sFrom)
                    
                       'assign the file item
                       oItem = oSourceFolder.ParseName(sFile)
                        
                       IF ISFALSE ISOBJECT(oSourceFolder) THEN
                          ? "Could not get the Item object. " & sFile & " Error:" & STR$(ERR)
                          GOTO TerminateZip
                       END IF
                    
                       'now we start the copy in to the new zip file
                       vOptions = 20
                    '   oTargetFolder.CopyHere(oItem, vOptions)
                        oTargetFolder.CopyHere(oSourceFolder, vOptions)
                       IF ERR THEN
                          ? "Got an Error during the CopyHere method.  Error:" & STR$(ERR)
                          GOTO TerminateZip
                       END IF
                    
                       'NOTE:  the above copyhere method starts a seperate thread to do the copy
                       'so the command could return before the copy is finished, so we need to
                       'allow time to complete.   Thus the next Sleep command.
                       'sleep 6000   'increase for larger folders
                    
                       '? sTo + " was successfully created."
                       FUNCTION = %TRUE
                    
                       TerminateZip:
                    
                       ' Close all of the Interfaces
                        vFile                   = EMPTY
                       vSourceFolder     = EMPTY
                       vTargetFolder     = EMPTY
                       vOptions          = EMPTY
                       oItem             = NOTHING
                       oTargetFolder     = NOTHING
                       oSourceFolder     = NOTHING
                       oShellClass       = NOTHING
                    END FUNCTION
                    So i also tried the second one:
                    Code:
                            DIM fList(0) AS STRING
                       fList(0) = FilePathStr + DestFile
                       CreateZipFileFromList fList(), FilePathStr + ZipFile
                    It Zips my whole folder!
                    Code:
                    '==================================================
                    '  CreateZipFile - creates a zip file
                    '==================================================
                    FUNCTION CreateZipFileFromList(fList() AS STRING, BYVAL sTo AS STRING) AS LONG
                       LOCAL hFile          AS DWORD
                       'Object Variables
                       DIM oShellClass      AS IShellDispatch
                       DIM oSourceFolder    AS Folder
                       DIM oTargetFolder    AS Folder
                       DIM oItem            AS FolderItem
                       'variants
                       DIM vSourceFolder    AS VARIANT
                       DIM vTargetFolder    AS VARIANT
                       DIM vOptions         AS VARIANT
                       DIM vFile            AS VARIANT
                       DIM sFile            AS STRING
                       DIM i                AS LONG          '-----------new---------------------------
                    
                       'First we create an empty ZIP file using a standard zip file header
                       TRY
                          hFile = FREEFILE
                          OPEN sTo FOR OUTPUT AS #hFile
                          PRINT #hFile, CHR$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
                          CLOSE #hFile
                       CATCH
                          ? "Error creating Zip file: " & sTo & "  Error:" & ERROR$(ERR)
                          EXIT FUNCTION
                       END TRY
                    
                    
                       ' Get an instance of our Windows Shell
                       oShellClass = ANYCOM $PROGID_SHELL32_SHELL
                    
                       ' Did we get the object? If not, terminate this app
                       IF ISFALSE ISOBJECT(oShellClass) OR ERR THEN
                          ? "Could not get the Windows Shell object.  Error:" & STR$(ERR)
                          EXIT FUNCTION
                       END IF
                    
                    
                    FOR i = 0 TO UBOUND(fList)                  '-----------new----------------------
                    
                    
                       'assign the source folder we want to zip up
                       vSourceFolder = RTRIM$(PATHNAME$(PATH, fList(i)),"\")    '--------modified------------
                       oSourceFolder = oShellClass.NameSpace(vSourceFolder)
                    
                       IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN
                          ? "Could not get the Source folder object.  Error:" & STR$(ERR)
                          GOTO TerminateZip
                       END IF
                    
                    
                       'assign the target folder we want to create (in this case it is a zip file)
                       vTargetFolder = sTo
                       oTargetFolder = oShellClass.NameSpace(vTargetFolder)
                    
                       IF ISFALSE ISOBJECT(oTargetFolder) OR ERR THEN
                          ? "Could not get the Target folder object.  " & sTo & " Error:" & STR$(ERR)
                          GOTO TerminateZip
                       END IF
                    
                    
                       'get the file name we are copying
                       'sFile = ucode$(PATHNAME$(NAME, sFrom) & PATHNAME$(EXTN, sFrom))
                       sFile = PATHNAME$(NAMEX, fList(i))                '-----------modified for PBWin10 -----
                    
                    '------------> fixed part --------------------------->
                    ' ---> change "oItem" with "sSourceFolder" and the example will work.
                    ' ---> You will find in new created zipfolder the textfile ! :)
                    
                       'assign the file item
                       oItem = oSourceFolder.ParseName(sFile)
                    '   oSourceFolder = oShellClass.NameSpace(vSourceFolder)
                       IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN 'change oItem
                          ? "Could not get the Item object. " & sFile & " Error:" & STR$(ERR) '
                          GOTO TerminateZip
                       END IF
                    
                       'now we start the copy in to the new zip file
                       vOptions = 20
                       oTargetFolder.CopyHere(oSourceFolder, vOptions) 'change oItem
                    
                       IF ERR THEN
                          ? "Got an Error during the CopyHere method.  Error:" & STR$(ERR)
                          GOTO TerminateZip
                       END IF
                    
                    '------------> fixed part end --------------------------->
                    
                    NEXT i                                      '-----------new----------------------
                    
                       'NOTE:  the above copyhere method starts a seperate thread to do the copy
                       'so the command could return before the copy is finished, so we need to
                       'allow time to complete.   Thus the next Sleep command.
                       SLEEP 6000   'increase for larger folders
                    
                       ? sTo + " was successfully created."
                       FUNCTION = %TRUE
                    
                       TerminateZip:
                    
                       ' Close all of the Interfaces
                       vFile             = EMPTY
                       vSourceFolder     = EMPTY
                       vTargetFolder     = EMPTY
                       vOptions          = EMPTY
                       oItem             = NOTHING
                       oTargetFolder     = NOTHING
                       oSourceFolder     = NOTHING
                       oShellClass       = NOTHING
                    END FUNCTION
                    I'm really beginning to hate objects
                    Andrea Mariani
                    AS/400 expert
                    Basic programmer @ Home

                    Comment


                      #30
                      I have made a demo from the zlib-gary-fixed.zip:

                      In this zipfile there is the sourcecode, modified to work on file1.txt and file1.doc

                      There is also file2.txt and file2.doc, together with the sourcecode and executable.

                      If I run this, I will find the the whole folder zipped, not just the two requested files.

                      BTW Win XP and PBWIN 9.0
                      Attached Files
                      Andrea Mariani
                      AS/400 expert
                      Basic programmer @ Home

                      Comment


                        #31
                        I think you will find that
                        oTargetFolder.CopyHere(oSourceFolder, vOptions) 'change oItem

                        should be
                        oTargetFolder.CopyHere(oitem, vOptions) 'change oItem
                        =========================
                        https://camcopng.com
                        =========================

                        Comment


                          #32
                          Originally posted by Stuart McLachlan View Post
                          I think you will find that
                          oTargetFolder.CopyHere(oSourceFolder, vOptions) 'change oItem

                          should be
                          oTargetFolder.CopyHere(oitem, vOptions) 'change oItem
                          I did try that - the result is that no files are copied.
                          Andrea Mariani
                          AS/400 expert
                          Basic programmer @ Home

                          Comment


                            #33
                            I found this sample code by William Burns in my "Windows ZIP" folder... is supposed to zip just 1 file:

                            Code:
                            '==================================================
                            '  CreateZipFile - creates a zip file
                            '==================================================
                            Function CreateZipFile(byval sFrom as string, byval sTo as string) as long
                               local hFile          as dword
                               'Object Variables
                               DIM oShellClass      AS IShellDispatch
                               DIM oSourceFolder    AS Folder
                               DIM oTargetFolder    AS Folder
                               DIM oItem            AS FolderItem
                               'variants
                               DIM vSourceFolder    AS VARIANT
                               DIM vTargetFolder    AS VARIANT
                               DIM vOptions         AS VARIANT
                               DIM vFile            AS VARIANT
                               dim sFile            as string
                            
                               'First we create a empty ZIP file using a standard zip file header
                               try
                                  hFile = freefile
                                  open sTo for output as #hFile
                                  print #hFile, Chr$(80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
                                  close #hFile
                               catch
                                  ? "Error creating Zip file: " & sTo & "  Error:" & Error$(err)
                                  exit function
                               end try
                            
                            
                               ' Get an instance of our Windows Shell
                               oShellClass = ANYCOM $PROGID_SHELL32_SHELL
                            
                               ' Did we get the object? If not, terminate this app
                               IF ISFALSE ISOBJECT(oShellClass) OR ERR THEN
                                  ? "Could not get the Windows Shell object.  Error:" & str$(err)
                                  EXIT FUNCTION
                               END IF
                            
                            
                               'assign the source folder we want to zip up
                               vSourceFolder = rtrim$(PATHNAME$(PATH, sFrom),"\")
                               oSourceFolder = oShellClass.NameSpace(vSourceFolder)
                            
                               IF ISFALSE ISOBJECT(oSourceFolder) OR ERR THEN
                                  ? "Could not get the Source folder object.  Error:" & str$(err)
                                  goto TerminateZip
                               END IF
                            
                            
                               'assign the target folder we want to create (in this case it is a zip file)
                               vTargetFolder = sTo
                               oTargetFolder = oShellClass.NameSpace(vTargetFolder)
                            
                               IF ISFALSE ISOBJECT(oTargetFolder) OR ERR THEN
                                  ? "Could not get the Target folder object.  " & sTo & " Error:" & str$(err)
                                  goto TerminateZip
                               END IF
                            
                            
                               'get the file name we are copying
                               sFile = ucode$(PATHNAME$(NAME, sFrom) & PATHNAME$(EXTN, sFrom))
                            
                               'assign the file item
                               oItem = oSourceFolder.ParseName(sFile)
                            
                               IF ISFALSE ISOBJECT(oItem) THEN
                                  ? "Could not get the Item object. " & sFile & " Error:" & str$(err)
                                  goto TerminateZip
                               END IF
                            
                               'now we start the copy in to the new zip file
                               vOptions = 20
                               oTargetFolder.CopyHere(oItem, vOptions)
                            
                               IF ERR THEN
                                  ? "Got an Error during the CopyHere method.  Error:" & str$(err)
                                  goto TerminateZip
                               END IF
                            
                               'NOTE:  the above copyhere method starts a seperate thread to do the copy
                               'so the command could return before the copy is finished, so we need to
                               'allow time to complete.   Thus the next Sleep command.
                               sleep 6000   'increase for larger folders
                            
                               '? sTo + " was successfully created."
                               function = %TRUE
                            
                               TerminateZip:
                            
                               ' Close all of the Interfaces
                            	vFile					= EMPTY
                               vSourceFolder     = EMPTY
                               vTargetFolder     = EMPTY
                               vOptions          = EMPTY
                               oItem             = NOTHING
                               oTargetFolder     = NOTHING
                               oSourceFolder     = NOTHING
                               oShellClass       = NOTHING
                            end function
                            
                            function pbmain
                            	If CreateZipFile("C:\Path\MyData.mdb", "C:\Path\MyData.zip") Then
                            end function
                            3.14159265358979323846264338327950
                            "Ok, yes... I like pie... um, I meant, pi."

                            Comment


                              #34
                              Thank you John Dunn,

                              Thanks to you I discovered the error:
                              Code:
                              sFile = PATHNAME$(NAMEX, fList(i))                '-----------modified for PBWin10 -----
                              Need to be:
                              Code:
                              sFile = UCODE$(PATHNAME$(NAMEX, fList(i)))                '-----------modified for PBWin10 -----
                              Andrea Mariani
                              AS/400 expert
                              Basic programmer @ Home

                              Comment


                                #35
                                Now I am confused....

                                Without the SLEEP, it does not work.

                                With the SLEEP, it does.

                                Sleep 10, it does not work.
                                Sleep 20, it does.

                                The program generates a 1MB text file, whick I ZIP end exit the program - but if it starts a new thread, the new thread should continue, even if the parent thread terminates, no?
                                Andrea Mariani
                                AS/400 expert
                                Basic programmer @ Home

                                Comment


                                  #36
                                  Yeah, we need a "wait for process to end" function... : (
                                  3.14159265358979323846264338327950
                                  "Ok, yes... I like pie... um, I meant, pi."

                                  Comment


                                    #37
                                    Originally posted by Jim Dunn View Post
                                    Yeah, we need a "wait for process to end" function... : (
                                    You have one... Just review the docs:


                                    METHOD JOIN(ThreadObjectVar AS InterfaceName, TimeOutVal AS Long) <7>

                                    Waits for the thread referenced by ThreadObjectVar to complete before execution of this thread continues. TimeOutVal specifies the maximum length of time to wait, in MilliSeconds. If TimeOutVal is zero (0), the time to wait is infinite.

                                    Regards,

                                    Bob Zale

                                    Comment


                                      #38
                                      Bob,
                                      You beat me to the punch!
                                      I was going to recommend:

                                      CreateProcessA
                                      WaitForSingleObject
                                      GetExitCodeProcess
                                      CloseHandle(hThread)
                                      CloseHandle(hProcess)


                                      Not needed with your suggestion.
                                      It's impossible to make anything foolproof because fools are so ingenious.

                                      Comment


                                        #39
                                        Wrong quote - delete
                                        Last edited by Andrea Mariani; 23 Sep 2012, 06:10 PM.
                                        Andrea Mariani
                                        AS/400 expert
                                        Basic programmer @ Home

                                        Comment


                                          #40
                                          PowerBASIC 10.0 for Windows has a lot of great new features (like JOIN), and it does not require Win7. It is fully compatible with all 32-bit and 64-bit versions of Windows. Win95 through Win7.

                                          Best regards,

                                          Bob Zale

                                          Comment

                                          Working...
                                          X
                                          😀
                                          🥰
                                          🤢
                                          😎
                                          😡
                                          👍
                                          👎