Private Sub Timer1_Timer()
' เปรียบเทียบ Drive จาก DriveListBox กับ ListView ตามเวลาที่ตั้งไว้ เช่น ทุกๆ 1000 millisecond (1 วินาที)
Call RefreshDrives
End Sub
' โปรแกรมย่อยในการเปรียบเทียบ Drive จาก DriveListBox กับ ListView
Private Sub RefreshDrives()
Dim DrvDet As Integer ' ตัวแปร Drive Detect ตรวจสอบ Drive ทั้งหมดจาก DriveListBox
Dim DrvChk As Integer ' Drive Check ดัก Drive ใหม่ที่เข้ามา
Dim DriveFlag As Boolean ' ตรรกะที่แจ้งให้รู้ว่ามีการเพิ่ม หรือ ถอด Removeable Drive หรือไม่
' อ่าน Drive ทั้งหมดเข้ามาเก็บไว้ใน DriveListBox ก่อน ... ตามเวลาที่ตั้งไว้
DriveDetect.Refresh
' เปรียบเทียบจำนวน DriveListBox กับ ListView
' เงื่อนไข จริง ... แสดงว่ามีการนำ Removable Drive เข้ามาใหม่
If DriveDetect.ListCount > lvwDrives.ListCount Then
' ลูปวงนอกสุดให้นับตามจำนวน Drive ที่มีอยู่ทั้งหมดจาก DriveListBox
For DrvDet = 0 To DriveDetect.ListCount
' ลูปวงในคือการทดสอบว่ามี Removable Drive ตัวไหนที่เข้ามาใหม่
For DrvChk = 0 To lvwDrives.ListCount
' หากมีค่าเท่ากันให้ออกจากลูปใน (DrvChk) ไปเลย แสดงว่าเป็น Drive ที่มีอยู่เดิม
If lvwDrives.List(DrvChk) = DriveDetect.List(DrvDet) Then
DriveFlag = False
Exit For
' กรณี "เท็จ" จะเกิดขึ้นได้ 2 กรณี คือ
' 1. เปรียบเทียบ Drive ไม่ตรงกันก็จริง แต่ยังไม่หมดข้อมูล จะลูปต่อก่อน
' 2. เปรียบเทียบค่าแล้วไม่ตรงกันเลย และ หมดข้อมูล แสดงว่าเกิดการเพิ่ม Removable Drive เข้าไป
' ในข้อที่ 2 จะเกิดการหลุดจากลูปนอก (DrvDet) ด้วยเงื่อนไข DriveFlag = จริง ด้วย
Else
DriveFlag = True
End If
' มันมี 2 ลูป ... เลยใส่ชื่อตัวแปรเงื่อนไข (DrvChk) มาต่อท้าย เพื่อที่จะได้ไม่งง และ ...
' เราเรียกมันว่าเป็น Nested Loop ... คือ วงรอบต้องอยู่ภายในของอีกลูป ... ลูปซ้อนลูป
Next DrvChk
' จากกรณีที่ 2 ด้านบน ... รู้ทันทีเลยว่ามี Removable Drive เข้ามาใหม่
If DriveFlag Then
' เพิ่มรายการ Drive ตัวใหม่เข้าไปที่ lvwDrives (ListView Control ตัวที่ซ่อนเอาไว้)
lvwDrives.AddItem DriveDetect.List(DrvDet)
'Debug.Print "Found New Drive: " & DriveDetect.List(DrvDet)
' ส่งชื่อ Drive ไปทดสอบก่อนว่าเป็นประเภท Removable Drive หรือไม่
' หากใช่ให้นำรายการไฟล์ต่างๆเข้ามาใน ListView (ฟังค์ชั่น AddToListView)
If CheckRemovable(Left$(DriveDetect.List(DrvDet), 2)) Then _
Call AddToListView(UCase$(Left$(DriveDetect.List(DrvDet), 2)))
End If
' มันมี 2 ลูป ... เลยใส่ชื่อตัวแปรเงื่อนไข (DrvDet) มาต่อท้าย เพื่อที่จะได้ไม่งง ...
Next DrvDet
' เงื่อนไข เท็จ ... แสดงว่ามีการนำ Removable Drive ออกไปจากเครื่อง
ElseIf DriveDetect.ListCount < lvwDrives.ListCount Then
' ทำงานกลับด้านกันกับเงื่อนไข "จริง" น่ะครับ ... พี่น้อง
' ลูปวงนอกสุดให้นับตามจำนวน Drive ที่มีอยู่ทั้งหมดจาก ListView Control ที่ซ่อนเอาไว้ (lvwDrives)
For DrvDet = 0 To lvwDrives.ListCount
' ลูปวงในคือการทดสอบว่ามี Removable Drive ตัวไหนที่ถูกถอดออกไปแล้ว
For DrvChk = 0 To DriveDetect.ListCount
' หากมีค่าเท่ากันให้ออกจากลูปไปเลย (แสดงว่าเป็น Drive เดิม)
' คำอธิบายจะเหมือนกันกับการเพิ่ม Removable Drive เข้ามาใหม่
If DriveDetect.List(DrvChk) = lvwDrives.List(DrvDet) Then
DriveFlag = False
Exit For
Else
DriveFlag = True
End If
Next DrvChk
If DriveFlag Then
'Debug.Print "Drive Has Been Removed: " & lvwDrives.List(DrvDet)
' ไม่ต้องตรวจสอบก็ได้ว่ามันเป็น Removable Drive หรือไม่ ... ถอดมันออกไปก็นั่นแหละมันเป็น ... อิอิอิอิอิ
'If CheckRemovable(UCase$(Left$(lvwDrives.List(DrvDet), 2))) Then _
Call RemoveFromListView(UCase$(Left$(lvwDrives.List(DrvDet), 2)))
' ลบรายการออกจาก ListView Control (lvwViewer)
Call RemoveFromListView(UCase$(Left$(lvwDrives.List(DrvDet), 2)))
' ลบรายการ Drive ออกจาก ListView Control ตัวที่ซ่อนเอาไว้ใน lvwDrives
lvwDrives.RemoveItem DrvDet
End If
Next DrvDet
End If
End Sub
' มี Remove Drive เพิ่มขึ้นมา ก็ต้องนำรายชื่อไฟล์ - โฟลเดอร์ ไปเพิ่มใน ListView (lvwViewer)
Private Function AddToListView(Drive As String)
Set mDrive = FSO.GetDrive(Drive)
If mDrive.DriveType = Removable And mDrive.IsReady = True Then
For Each mFile In mDrive.RootFolder.Files
DoEvents
lvwViewer.AddItem mFile.Path
nFiles = nFiles + 1
Next
' อันนี้ก็แค่แจ้งรายการจำนวนไฟล์ครับผม
fraViewer.Caption = " จำนวน " & nFiles & " ไฟล์" & " "
' ยกมาทั้งโฟลเดอร์ด้วย
For Each mFolder In mDrive.RootFolder.SubFolders
DoEvents
' แสดงชื่อโฟลเดอร์ออกมา
lvwViewer.AddItem mFolder.Path
nFolders = nFolders + 1
Next
' ส่วนของการนับจำนวนโฟลเดอร์
fraViewer.Caption = fraViewer.Caption & " / จำนวน " & nFolders & " โฟลเดอร์" & " "
End If
End Function
' มีการถอด Remove Drive ออกไป ก็ต้องนำรายชื่อไฟล์ - โฟลเดอร์ ออกจาก ListView (lvwViewer)
Private Function RemoveFromListView(Drive As String)
Dim sRow As Integer
Dim CountRow As Integer
CountRow = lvwViewer.ListCount - 1
For sRow = 0 To CountRow
If UCase$(Left$(lvwViewer.List(sRow), 2)) = Drive Then
' เพราะนับมาจากทางขวามือสุดเข้ามา 3 ตัวอักษร ตัวถัดมาหากเป็นจุด (Dot) ... มันคือไฟล์
If Mid$(lvwViewer.List(sRow), Len(lvwViewer.List(sRow)) - 3, 1) = "." Then
nFiles = nFiles - 1
Else
nFolders = nFolders - 1
End If
lvwViewer.RemoveItem sRow
CountRow = lvwViewer.ListCount - 1
sRow = lvwViewer.ListIndex - 1
End If
Next
fraViewer.Caption = " จำนวน " & nFiles & " ไฟล์" & " / จำนวน " & nFolders & " โฟลเดอร์" & " "
End Function
' ฟังค์ชั่นตรวจสอบว่า Drive ที่เข้ามานั้นเป็น Removable Drive หรือไม่
' หากใช่ ให้คืนค่ากลับเป็น True ... ไม่ใช่ให้คืนค่า False
Public Function CheckRemovable(Drive As String) As Boolean
On Error Resume Next
Set mDrive = FSO.GetDrive(Drive)
If mDrive.DriveType = Removable And mDrive.IsReady = True Then
CheckRemovable = True
Else
CheckRemovable = False
End If
End Function
|