' Simple .ZIP viewer (doesn't extract or anything useful like that). 
' You're free to modify and distribute the code without restrictions. 
' Written in Rapid-Q by William Yu 
' Demonstrates QOpenDialog, QFileStream, QListView, QMainMenu, QMenuItem 
'              and QImageList. 
$APPTYPE GUI
$TYPECHECK ON
$INCLUDE "RAPIDQ.INC"
$RESOURCE ICO_ZIP AS "ZIP.ICO"
$RESOURCE ICO_APP AS "APP.ICO"
DECLARE SUB ZipView (ZIPFile AS STRING)
DECLARE SUB FormResize
DECLARE SUB OpenClick
DECLARE SUB ExitClick
DECLARE SUB IconClick
DECLARE SUB SmallIconClick
DECLARE SUB ReportClick
DECLARE SUB ItemDblClick
CONST SIG = &H04034B50         ' ZIP Signature/ID 
TYPE ZFHeader
  Signature AS LONG
  Version AS WORD
  GPBFlag AS WORD              ' ? 
  Compress AS WORD             ' Compression types 
  DateTime AS LONG             ' Packed format 
  CRC32 AS LONG
  CSize AS LONG                ' Compressed size 
  USize AS LONG                ' Uncompressed size 
  FileNameLen AS LONG
END TYPE
TYPE PackedDateType            ' I think this is it: 
  Year AS SHORT                ' 7 bits 
  Month AS BYTE                ' 4 bits 
  Day AS BYTE                  ' 5 bits 
  Hour AS BYTE                 ' 5 bits 
  Minute AS BYTE               ' 6 bits 
  Secs AS BYTE                 ' 5 bits 
END TYPE                       ' Total = 32 bits 
DIM CompType(0 TO 9) AS STRING
    CompType(0) = "Stored"
    CompType(1) = "Shrunk"
    CompType(2) = "Reduced1"
    CompType(3) = "Reduced2"
    CompType(4) = "Reduced3"
    CompType(5) = "Reduced4"
    CompType(6) = "Imploded"
    CompType(7) = "Defalted"
    CompType(8) = "DeflatN"      '' Could be DeflatX as well... 
    CompType(9) = "DeflatX"
DIM OpenItem AS QMenuItem
    OpenItem.Caption = "&Open"
    OpenItem.OnClick = OpenClick
DIM BreakItem AS QMenuItem
    BreakItem.Caption = "-"
DIM ExitItem AS QMenuItem
    ExitItem.Caption = "E&xit"
    ExitItem.OnClick = ExitClick
DIM IconItem AS QMenuItem
    IconItem.Caption = "vs&Icon"
    IconItem.RadioItem = True
    IconItem.OnClick = IconClick
DIM SmallIconItem AS QMenuItem
    SmallIconItem.Caption = "vs&SmallIcon"
    SmallIconItem.RadioItem = True
    SmallIconItem.OnClick = SmallIconClick
DIM ReportItem AS QMenuItem
    ReportItem.Caption = "vs&Report"
    ReportItem.RadioItem = True
    ReportItem.Checked = True
    ReportItem.OnClick = ReportClick
DIM FileMenu AS QMenuItem
    FileMenu.Caption = "&File"
    FileMenu.AddItems OpenItem, BreakItem, ExitItem
DIM ViewMenu AS QMenuItem
    ViewMenu.Caption = "&View"
    ViewMenu.AddItems IconItem, SmallIconItem, ReportItem
DIM ImageList1 AS QImageList
    ImageList1.Height = 32
    ImageList1.Width = 32
    ImageList1.AddICOHandle ICO_APP
    ImageList1.AddICOHandle ICO_ZIP
DIM ImageList2 AS QImageList            ' Scale 16x16 
    ImageList2.Height = 16
    ImageList2.Width = 16
    ImageList2.AddICOHandle ICO_APP
    ImageList2.AddICOHandle ICO_ZIP
CREATE Form AS QForm
  ICOHandle = ICO_ZIP
  Center
  OnResize = FormResize
  Height = 330
  Width = 525
  Caption = "Simple .ZIP Viewer for Rapid-Q"
  CREATE MainMenu AS QMainMenu
    AddItems FileMenu, ViewMenu
  END CREATE
  CREATE ListView AS QListView
    Width = Form.ClientWidth
    Height = Form.ClientHeight
    SmallImages = ImageList2
    LargeImages = ImageList1
    ViewStyle = vsReport
    AddColumns "FileName","Length","Method","Size","Rate","Date","Time","CRC-32"
    Column(0).Width = 200
    Column(4).Width = 40
    Column(5).Width = 70
    Column(7).Width = 70
    OnDblClick = ItemDblClick
  END CREATE
  ShowModal
END CREATE
'------------------------------------------------------------------ 
SUB ZipView (ZIPFile AS STRING)
  DIM Hdr      AS ZFHeader
  DIM ZF       AS QFileStream
  DIM PD       AS PackedDateType
  DIM FileName AS STRING
  DIM Index    AS INTEGER
  IF ZF.Open(ZIPFile, fmOpenRead) = False THEN
    ShowMessage("Problem with reading "+ZIPFile)
    EXIT SUB
  END IF
  ListView.Clear
  Hdr.Signature = ZF.ReadNum(4)
  Index = 0
  WHILE Hdr.Signature = SIG
    Hdr.Version  = ZF.ReadNum(2)
    Hdr.GPBFlag  = ZF.ReadNum(2)
    Hdr.Compress = ZF.ReadNum(2)
    Hdr.DateTime = ZF.ReadNum(4)
    Hdr.CRC32 = ZF.ReadNum(4)
    Hdr.CSize = ZF.ReadNum(4)
    Hdr.USize = ZF.ReadNum(4)
    Hdr.FileNameLen = ZF.ReadNum(4)
    FileName = ZF.ReadStr(Hdr.FileNameLen)
    PD.Year = ((Hdr.DateTime SHR 25) AND &H7F) + 1980
    PD.Month = (Hdr.DateTime SHR 21) AND &H0F
    PD.Day = (Hdr.DateTime SHR 16) AND &H1F
    PD.Hour = (Hdr.DateTime SHR 11) AND &H1F
    PD.Minute = (Hdr.DateTime SHR 5) AND &H3F
    PD.Secs = Hdr.DateTime AND &H1F
    ListView.AddItems FileName
    IF INSTR(UCASE$(FileName), ".ZIP") THEN
      ListView.Item(Index).ImageIndex = 1
    END IF
    ListView.AddSubItem Index, STR$(Hdr.USize)
    ListView.AddSubItem Index, CompType(Hdr.Compress)
    ListView.AddSubItem Index, STR$(Hdr.CSize)
    IF Hdr.USize = 0 THEN
      ListView.AddSubItem Index, "----"
    ELSE
      ListView.AddSubItem Index, STR$(INT((Hdr.USize - Hdr.CSize) / Hdr.USize * 100))+"%"
    END IF
    ListView.AddSubItem Index, STR$(PD.Month)+"-"+STR$(PD.Day)+"-"+STR$(PD.Year)
    ListView.AddSubItem Index, STR$(PD.Hour)+":"+STR$(PD.Minute)
    ListView.AddSubItem Index, LCASE$(HEX$(Hdr.CRC32))
    ZF.Seek(Hdr.CSize, soFromCurrent)
    Hdr.Signature = ZF.ReadNum(4)
    Index = Index + 1
  WEND
  IF Index = 0 THEN
     '-- Likely not a .ZIP file 
     ShowMessage(ZIPFile+" is not a valid ZIP file!")
  END IF
END SUB
SUB OpenClick
  DIM OpenDialog AS QOpenDialog
  OpenDialog.InitialDir = CurDir$
  OpenDialog.Filter = "ZIP Files (*.zip)|*.zip|All Files (*.*)|*.*"
  IF OpenDialog.Execute THEN
    ZipView(OpenDialog.FileName)
  END IF
END SUB
SUB ExitClick
  Form.Close
END SUB
SUB FormResize
  ListView.Height = Form.ClientHeight
  ListView.Width = Form.ClientWidth
END SUB
SUB IconClick
  IconItem.Checked = True
  ListView.ViewStyle = vsIcon
END SUB
SUB SmallIconClick
  SmallIconItem.Checked = True
  ListView.ViewStyle = vsSmallIcon
END SUB
SUB ReportClick
  ReportItem.Checked = True
  ListView.ViewStyle = vsReport
END SUB
SUB ItemDblClick
  IF ListView.ItemIndex >= 0 THEN
    ShowMessage("Can't extract "+ListView.Item(ListView.ItemIndex).Caption);
  END IF
END SUB