ชุมชนคนรักภาษาเบสิค - Visual Basic Community

 ลืมรหัสผ่าน
 ลงทะเบียน
ค้นหา
ดู: 89|ตอบกลับ: 0

[VB.NET] โค้ดการสำรองข้อมูลหลายๆไฟล์ ทั้งแบบอัตโนมือและอัตโนมัติตามค่าเวลาที่ตั้งเอาไว้

[คัดลอกลิงก์]

334

กระทู้

530

โพสต์

7387

เครดิต

ผู้ดูแลระบบ

ทองก้อน ทับทิมกรอบ

Rank: 9Rank: 9Rank: 9

เครดิต
7387
โพสต์ 3 วันที่แล้ว | ดูโพสต์ทั้งหมด |โหมดอ่าน


แจ้งเตือนสถานะการทำงานโดยใช้ Popup Notification แทน


เมื่อโปรแกรมทำงานให้ทำการซ่อนไอคอนของโปรแกรมไปไว้ที่ System Tray


Add References ... Krypton Toolkit และ Tulpep.NotificationWindow ...


การแก้ไข Inherits เพื่อใช้งานรูปแบบ Theme ของ Kryton Toolkit ...

โค้ดการสำรองข้อมูลหลายๆไฟล์ ทั้งแบบอัตโนมือ (กดปุ่ม Backup เอง) และแบบอัตโนมัติตามค่าเวลาที่ตั้งเอาไว้ แอดมินได้ทำฟอร์มเอาไว้ 2 ชุด เพื่อความสะดวกในการนำไปใช้งานได้ทันที หรือเพื่อศึกษาการทำงานของโค้ดชุดนี้ ... สำหรับ frmAutoBackupTest.vb เอาไว้ทดสอบการใช้งานในระดับวินาที (15 - 60 วินาที) ส่วน frmAutoBackup.vb สำหรับการใช้งานจริง ในระดับชั่วโมง (1 - 24 ชั่วโมง) หรือสามารถลองปรับค่า Interval ในการเกิด Tick ของ Timer เพื่อปรับระยะเวลาการทดสอบให้น้อยลงจากเดิมเลยก็ได้ครับ ...

- หากกดปุ่ม Minimized ตัวโปรแกรมจะปิดหน้าจอลงไปเก็บไว้ที่ System Tray และการแจ้งเตือนจะใช้ Popup Notification แทนการใช้งาน MessageBox เพื่อไม่ให้รบกวนการทำงานของผู้ใช้

- นอกจากนี้ยังป้องกันการสำรองไฟล์ข้อมูลเพื่อไม่ให้ไฟล์ต้นทางและปลายทางอยู่ตำแหน่งเดียวกัน และหากไม่มีไฟล์ข้อมูลต้นทาง หรือโฟลเดอร์ปลายทาง ก็จะทำการลบออกไปจากแถวรายการของ ListView Control ...

- การเก็บข้อมูลของการสำรองไฟล์ และระยะเวลา จะเก็บเอาไว้ที่ไฟล์ INI (Initialized) มีชื่อว่า Config.ini ...

- โปรแกรมสามารถรันหรือทำงานได้อัตโนมัติ เมื่อ Windows Start ขึ้นมาทำงานในทุกๆครั้ง เพื่ออำนวยความสะดวกให้กับผู้ใช้งาน โดยไม่ต้องมากดรันโปรแกรมเอาเอง


มาดูโค้ดฉบับเต็มกันเถอะ ... frmAutoBackup.vb
  1. Imports System.IO
  2. Imports System.Text
  3. Imports System.Runtime.InteropServices
  4. Imports System.Windows.Forms
  5. Imports Microsoft.Win32

  6. '// .Net Framework from 4.0+
  7. '// https://www.nuget.org/packages/Tulpep.NotificationWindow
  8. Imports Tulpep.NotificationWindow

  9. Public Class frmAutoBackup
  10.     '// ตำแหน่งเก็บไฟล์ Config.ini
  11.     Private iniPath As String = MyPath(Application.StartupPath) & "\Config.ini"
  12.     '// Path เก็บไฟล์ Image
  13.     Private imagePath = MyPath(Application.StartupPath) & "Images"
  14.     '// Path เก็บไอคอนเพื่อใช้กับ System Tray
  15.     Private IconPath As String = MyPath(Application.StartupPath) & "Images"
  16.     '// ฟอนต์ของ Notifiaction
  17.     Private TitleFont As New Font("Tahoma", 15, FontStyle.Bold)
  18.     Private ContentFont As New Font("Tahoma", 12, FontStyle.Regular)

  19.     ' ==== Notify Icon ====
  20.     Private WithEvents TrayIcon As NotifyIcon
  21.     Private WithEvents TrayMenu As ContextMenuStrip
  22.     '// ==== Timer ตั้งเวลา ====
  23.     Private WithEvents tmr As New Timer()
  24.     Private BackupInterval As Integer = 1   '// หน่วยชั่วโมง (1 – 24) เมื่อนำไปใช้งานจริง
  25.     Private ElapsedTime As Integer = 0        '// นับเวลาที่ผ่านไป

  26.     '// ---------------------------------------------------------------------------------------------------
  27.     '// สร้าง CheckBox แบบ Run Time เพื่อกำหนดให้รันโปรแกรมตอน Start Windows
  28.     Dim chkStartup As New CheckBox()
  29.     '// สร้าง ComboBox ในการตั้งเวลา
  30.     Dim cmbInterval As New ComboBox

  31. #Region "INI"
  32.     '// --------------------------------------------------------------------------------------
  33.     '// APIs for Read/Write INI File.
  34.     <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
  35.     Private Shared Function WritePrivateProfileString(
  36.             lpAppName As String,
  37.             lpKeyName As String,
  38.             lpString As String,
  39.             lpFileName As String) As Long
  40.     End Function

  41.     <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
  42.     Private Shared Function GetPrivateProfileString(
  43.             lpAppName As String,
  44.             lpKeyName As String,
  45.             lpDefault As String,
  46.             lpReturneDstring As StringBuilder,
  47.             nSize As Integer,
  48.             lpFileName As String) As Integer
  49.     End Function

  50.     Private Sub WriteIni(section As String, key As String, value As String, filePath As String)
  51.         WritePrivateProfileString(section, key, value, filePath)
  52.     End Sub

  53.     Private Function ReadIni(section As String, key As String, defaultValue As String, filePath As String) As String
  54.         Dim sb As New StringBuilder(1024)
  55.         GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, filePath)
  56.         Return sb.ToString()
  57.     End Function
  58. #End Region

  59.     '// --------------------------------------------------------------------------------------
  60. #Region "NOTIFICATION"
  61.     '// Popup Notification
  62.     Private Sub Notification(
  63.                             ByVal img As String,
  64.                             ByVal BodyColor As System.Drawing.Color,
  65.                             ByVal TitleText As String,
  66.                             ByVal TitleColor As System.Drawing.Color,
  67.                             ByVal ContentText As String,
  68.                             ByVal ContentColor As System.Drawing.Color
  69.                             )
  70.         Dim Popup As PopupNotifier = New PopupNotifier()
  71.         Dim bitmap As Bitmap
  72.         Try
  73.             bitmap = Image.FromFile(imagePath & img)
  74.             With Popup
  75.                 .Image = bitmap
  76.                 .BodyColor = BodyColor
  77.                 .TitleText = TitleText
  78.                 .TitleColor = TitleColor
  79.                 .TitleFont = TitleFont
  80.                 .ContentText = ContentText
  81.                 .ContentColor = ContentColor
  82.                 .ContentFont = ContentFont
  83.                 .Popup()
  84.             End With
  85.         Catch ex As Exception
  86.             MessageBox.Show(ex.Message)
  87.         End Try
  88.     End Sub
  89. #End Region

  90.     '// ---------------------------------------------- ImageList เก็บ Icon ----------------------------------------------
  91.     Private imgList As New ImageList()

  92.     '// เก็บคอลัมน์ล่าสุดที่กด กับลำดับการเรียง
  93.     Private SortColumn As Integer = -1
  94.     Private SortOrder As SortOrder = SortOrder.None

  95.     '// --------------------------------------------------------------------------------------
  96.     '// S T A R T . . . H E R E
  97.     '// --------------------------------------------------------------------------------------
  98.     Private Sub frmAutoBackup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  99.         Me.MinimumSize = New Point(884, 603)    '// กำหนดขนาดของฟอร์มต่ำสุด
  100.         '// ImageList สำหรับ Icon
  101.         imgList.ImageSize = New Size(22, 22)    '// จะมีผลต่อความสูงของแถวในตัว ListView
  102.         imgList.ColorDepth = ColorDepth.Depth32Bit
  103.         lvwFile.SmallImageList = imgList

  104.         '// ตั้งค่าให้กับ CheckBox เพื่อให้พื้นหลังกลมกลืนกับ ToolStrip
  105.         chkStartup.Text = "Run on Windows Startup"
  106.         chkStartup.Font = New Font("Tahoma", 10, FontStyle.Regular)
  107.         chkStartup.BackColor = Color.Transparent
  108.         Dim host As New ToolStripControlHost(chkStartup)
  109.         ToolStrip1.Items.Add(host)
  110.         '// Add Event Handler เพื่อกำหนดค่าการเปิดโฟลเดอร์อัตโนมัติ เมื่อ Start Windows
  111.         AddHandler chkStartup.CheckedChanged, AddressOf chkStartup_CheckedChanged

  112.         '// ตั้งค่า ComboBox เพื่อเก็บค่าเวลา
  113.         cmbInterval.Name = "cmbInterval"
  114.         cmbInterval.DropDownStyle = ComboBoxStyle.DropDownList
  115.         cmbInterval.ItemHeight = 10 '// จำกัดการแสดงผล 10 Items
  116.         cmbInterval.IntegralHeight = False
  117.         cmbInterval.Width = 60
  118.         '// ------------------------ ใช้กับงานจริงให้นับ 1 - 24 ชั่วโมง --------------------------
  119.         '// เพิ่มค่า 1 - 24 ชั่วโมง
  120.         For i As Integer = 1 To 24
  121.             cmbInterval.Items.Add(i.ToString())
  122.         Next
  123.         cmbInterval.SelectedIndex = 0   '// ค่าเริ่มต้น = 1 ชั่วโมง
  124.         BackupInterval = CInt(cmbInterval.SelectedItem)
  125.         '// === สร้าง Label ต่อท้าย ===
  126.         Dim lblHours As New ToolStripLabel("Hours.")
  127.         '// ------------------------------------------------------------------------------------------

  128.         '=== เพิ่มลงใน ToolStrip ===
  129.         ToolStrip1.Items.Add(New ToolStripSeparator())
  130.         ToolStrip1.Items.Add(New ToolStripLabel("Interval:"))
  131.         host = New ToolStripControlHost(cmbInterval)
  132.         ToolStrip1.Items.Add(host)
  133.         ToolStrip1.Items.Add(lblHours)
  134.         '=== ดักจับเหตุการณ์เปลี่ยนค่า ===
  135.         AddHandler cmbInterval.SelectedIndexChanged, AddressOf cmbInterval_SelectedIndexChanged

  136.         '// เปิด OwnerDraw สำหรับการปรับฟอนต์ใน Column Header ของ ListView Control
  137.         '// โค้ดที่เกี่ยวข้องจะอยู่ทางด้านล่างสุด
  138.         lvwFile.OwnerDraw = True
  139.         Call InitializeListView()
  140.         Call AdjustListViewColumnWidths()

  141.         '// โหลดจาก Config.ini
  142.         Call LoadConfig()
  143.         Call SaveConfig()   '// บันทึกค่าเวลาด้วย

  144.         '// -------------------------------------------- IMPORTANT --------------------------------------------
  145.         '// Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  146.         '// ทดสอบการกำหนดให้ Run ตอน Start Windows
  147.         If IsStartupEnabled() Then
  148.             chkStartup.Checked = True
  149.             'tsbBackupFile.PerformClick()    '// สั่งโปรแกรมให้สำรองข้อมูลทันที
  150.         Else
  151.             chkStartup.Checked = False
  152.         End If

  153.         '// สร้าง System Tray
  154.         Call InitTrayIcon()
  155.         '// ตั้งค่า Timer ให้เกิดการ Tick ทุกๆ 1 วินาที
  156.         '// หากให้เวลาเร็วขึ้นโดยไม่ต้องรอให้ครบ 1 ชม. ก็ปรับลดค่า Interval ลง
  157.         tmr.Interval = 1000
  158.         tmr.Start()
  159.         '// ปิดหน้าจอลงไปเก็บไว้ใน System Tray พร้อมกับการแจ้งเตือน
  160.         'Me.WindowState = FormWindowState.Minimized
  161.     End Sub

  162. #Region "TIMER"
  163.     '// ----------------------------------------- เมื่อใช้งานจริงให้หน่วยนับเป็นชั่วโมง ---------------------------------
  164.     Private Sub tmr_Tick(sender As Object, e As EventArgs) Handles tmr.Tick
  165.         ElapsedTime += 1
  166.         '// แปลงชั่วโมงที่เลือกเป็นวินาที
  167.         '// 1000 millisecond = 1 Second, 60 Seconds = 1 Minute, 60 Minute = 1 Hour. (3,600 Seconds)
  168.         Dim targetSeconds As Integer = BackupInterval * 3600
  169.         If ElapsedTime >= targetSeconds Then
  170.             ElapsedTime = 0
  171.             '// === เรียกทำงาน Backup Data ===
  172.             Call tsbBackupFile_Click(Nothing, Nothing)
  173.         End If
  174.     End Sub

  175.     Private Sub cmbInterval_SelectedIndexChanged(sender As Object, e As EventArgs)
  176.         If cmbInterval.SelectedItem IsNot Nothing Then
  177.             BackupInterval = CInt(cmbInterval.SelectedItem)
  178.             ElapsedTime = 0  '// รีเซ็ตเวลาใหม่ทุกครั้งที่เปลี่ยน
  179.             Call SaveConfig()   '// บันทึกค่าใหม่
  180.         End If
  181.     End Sub
  182.     '// ---------------------------------------------------------------------------------------------------------------------
  183. #End Region

  184. #Region "STARTUP"
  185.     '// --------------------------------------------------------------------------------------
  186.     '// Add Event Handler เพื่อกำหนดให้โปรแกรมทำงานตอน Start Windows หรือไม่
  187.     '// --------------------------------------------------------------------------------------
  188.     Private Sub chkStartup_CheckedChanged(sender As System.Object, e As System.EventArgs)
  189.         If chkStartup.Checked Then
  190.             '// Run on Windows Start
  191.             Call SetStartup(True)
  192.         Else
  193.             Call SetStartup(False)
  194.         End If
  195.     End Sub

  196.     '// ============= สร้างค่าใน Registry เพื่อให้รันตอน Startup =============
  197.     '// หาก enable กำหนดเป็น True จะทำการ Registry เพื่อให้โปรแกรม Run ตอน Start Windows
  198.     '// หาก enable กำหนดเป็น False จะทำการลบ Registry ออกไป
  199.     '// Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  200.     Private Sub SetStartup(enable As Boolean)
  201.         Try
  202.             Using key As RegistryKey = Registry.CurrentUser.OpenSubKey(
  203.                 "Software\Microsoft\Windows\CurrentVersion\Run", True)
  204.                 If key Is Nothing Then
  205.                     MessageBox.Show("ไม่สามารถเข้าถึง Registry ได้", "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
  206.                     Return
  207.                 End If
  208.                 If enable Then
  209.                     key.SetValue("AutoBackup", Application.ExecutablePath)
  210.                 Else
  211.                     '// ลบค่าออก ถ้าไม่ต้องการให้รันอัตโนมัติ
  212.                     If key.GetValue("AutoBackup") IsNot Nothing Then key.DeleteValue("AutoBackup")
  213.                 End If
  214.             End Using
  215.         Catch ex As Exception
  216.             MessageBox.Show("เกิดข้อผิดพลาดในการตั้งค่า Startup: " & ex.Message, "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
  217.         End Try
  218.     End Sub

  219.     '// ---------------------- ทดสอบค่า Run on Windows Start ----------------------
  220.     Private Function IsStartupEnabled() As Boolean
  221.         Try
  222.             Using key As RegistryKey = Registry.CurrentUser.OpenSubKey(
  223.                 "Software\Microsoft\Windows\CurrentVersion\Run", False) '// อ่านอย่างเดียว (ReadOnly)
  224.                 If key Is Nothing Then Return False '// ไม่สามารถเปิด Registry ได้ (ถือว่าไม่ได้ตั้งค่า)

  225.                 '// ตรวจสอบว่ามีค่า "OpenMultipleFolder" หรือไม่
  226.                 Dim value As Object = key.GetValue("AutoBackup")
  227.                 If value IsNot Nothing Then
  228.                     '// ตรวจสอบว่าค่าที่เก็บเป็นพาธของโปรแกรมตัวเองหรือไม่
  229.                     Dim ProgramPath As String = Application.ExecutablePath
  230.                     Dim RegistryPath As String = value.ToString()

  231.                     '// เปรียบเทียบแบบไม่สนใจตัวพิมพ์ใหญ่/เล็ก และตัด quote ออกถ้ามี
  232.                     Dim CleanRegistryPath As String = RegistryPath.Replace("""", "")
  233.                     Return String.Equals(CleanRegistryPath, ProgramPath, StringComparison.OrdinalIgnoreCase)
  234.                 Else
  235.                     Return False
  236.                 End If
  237.             End Using
  238.         Catch ex As Exception
  239.             '// ถ้าเกิดข้อผิดพลาด เช่น สิทธิ์ไม่พอ ถือว่าไม่ได้ตั้งค่า รีเทิร์นค่า False กลับไป
  240.             'MessageBox.Show("Error checking startup: " & ex.Message)
  241.             Return False
  242.         End Try
  243.     End Function
  244. #End Region

  245. #Region "TRAYICON"
  246.     Private Sub InitTrayIcon()
  247.         '// โหลด Icon ที่เราเตรียมไว้
  248.         Dim iconBackup As Icon = New Icon(Path.Combine(IconPath, "backupdisk.ico"))
  249.         Dim iconAbout As Icon = New Icon(Path.Combine(IconPath, "about.ico"))
  250.         Dim iconExit As Icon = New Icon(Path.Combine(IconPath, "exit.ico"))
  251.         Dim appIcon As Icon = New Icon(Path.Combine(IconPath, "backup.ico")) '// ไอคอนหลักของโปรแกรม
  252.         '// สร้าง ContextMenu สำหรับ System Tray
  253.         TrayMenu = New ContextMenuStrip()

  254.         ' === เมนู Backup Data ===
  255.         Dim mnuBackup As New ToolStripMenuItem("Backup Data", iconBackup.ToBitmap())
  256.         AddHandler mnuBackup.Click, AddressOf mnuBackup_Click
  257.         TrayMenu.Items.Add(mnuBackup)

  258.         ' === เมนู About Me ===
  259.         Dim mnuAbout As New ToolStripMenuItem("About Me", iconAbout.ToBitmap)
  260.         AddHandler mnuAbout.Click, AddressOf mnuAbout_Click
  261.         TrayMenu.Items.Add(mnuAbout)

  262.         ' === Separator ===
  263.         TrayMenu.Items.Add(New ToolStripSeparator())

  264.         ' === เมนู Exit ===
  265.         Dim mnuExit As New ToolStripMenuItem("Exit", iconExit.ToBitmap)
  266.         AddHandler mnuExit.Click, AddressOf mnuExit_Click
  267.         TrayMenu.Items.Add(mnuExit)

  268.         '// สร้าง NotifyIcon
  269.         TrayIcon = New NotifyIcon()
  270.         TrayIcon.Icon = appIcon
  271.         TrayIcon.Text = "Backup Application"
  272.         TrayIcon.ContextMenuStrip = TrayMenu
  273.         TrayIcon.Visible = True
  274.     End Sub

  275.     '// ดับเบิ้ลคลิกที่ TrayIcon เพื่อ Restore กลับมา
  276.     Private Sub TrayIcon_DoubleClick(sender As Object, e As EventArgs) Handles TrayIcon.DoubleClick
  277.         Me.Show()
  278.         Me.WindowState = FormWindowState.Normal
  279.     End Sub

  280.     '// === Event ของเมนู ===
  281.     Private Sub mnuBackup_Click(sender As Object, e As EventArgs)
  282.         '// เรียกใช้งานเหตุการณ์ Backup Data
  283.         'tsbBackupFile.PerformClick()
  284.         Me.Show()
  285.         Me.WindowState = FormWindowState.Normal
  286.     End Sub

  287.     Private Sub mnuAbout_Click(sender As Object, e As EventArgs)
  288.         'Dim frm As New frmAboutMe()
  289.         'frm.ShowDialog()
  290.         MessageBox.Show("About Me")
  291.     End Sub

  292.     Private Sub mnuExit_Click(sender As Object, e As EventArgs)
  293.         TrayIcon.Visible = False
  294.         Me.Close()
  295.     End Sub
  296. #End Region

  297. #Region "LISTVIEW"
  298.     '// --------------------------------------------------------------------------------------
  299.     '// ตั้งค่าเริ่มต้นให้กับ ListView Control
  300.     Sub InitializeListView()
  301.         With lvwFile
  302.             .View = View.Details
  303.             .MultiSelect = False
  304.             .HideSelection = False
  305.             .FullRowSelect = True
  306.             .GridLines = True
  307.             .Columns.Clear()
  308.             .Columns.Add("Source File", lvwFile.Width - 300)
  309.             .Columns.Add("Destination Folder", 280)
  310.         End With
  311.     End Sub

  312.     '// ดับเบิ้ลคลิ๊กเพื่อแก้ไขรายการแถวใน ListView Control
  313.     Private Sub lvwFile_DoubleClick(sender As Object, e As EventArgs) Handles lvwFile.DoubleClick
  314.         tsbEditFile.PerformClick()
  315.     End Sub

  316.     '// เมื่อคลิ๊กส่วนหัว (Column) ของ ListView จะทำการจัดเรียงข้อมูลไอเทม ListView
  317.     Private Sub lvwFile_ColumnClick(sender As Object, e As ColumnClickEventArgs) Handles lvwFile.ColumnClick
  318.         '// ถ้ากดซ้ำที่คอลัมน์เดิมสลับ ASC/DESC การจัดเรียงจากน้อยไปมาก หรือ มากไปน้อย
  319.         If e.Column = SortColumn Then
  320.             If SortOrder = SortOrder.Ascending Then
  321.                 SortOrder = SortOrder.Descending
  322.             Else
  323.                 SortOrder = SortOrder.Ascending
  324.             End If
  325.         Else
  326.             SortColumn = e.Column
  327.             SortOrder = SortOrder.Ascending
  328.         End If
  329.         '// เรียกไปยังคลาส ListViewItemComparer
  330.         lvwFile.ListViewItemSorter = New ListViewItemComparer(e.Column, SortOrder)
  331.         lvwFile.Sort()
  332.     End Sub

  333.     '// ฟังก์ชันปรับความกว้างคอลัมน์ให้เต็มพื้นที่ว่าง
  334.     Private Sub AdjustListViewColumnWidths()
  335.         If lvwFile.Columns.Count = 0 Then Return
  336.         If Me.WindowState = FormWindowState.Minimized Then
  337.             Me.Hide()
  338.             'TrayIcon.ShowBalloonTip(1000, "กำลังทำงาน", "โปรแกรมถูกย่อไปที่ System Tray", ToolTipIcon.Info)
  339.             Call Notification("Info.png", Color.FromArgb(255, 193, 7), "INFORMATION", Color.Black, "โปรแกรมกำลังทำงานและถูกย่อไปที่ System Tray.", Color.Black)
  340.         End If
  341.         '// ใช้ ClientSize.Width — คือพื้นที่ใช้งานจริงของ ListView
  342.         Dim AvailableWidth As Integer = lvwFile.ClientSize.Width
  343.         '// รวมความกว้างของคอลัมน์ที่ไม่ต้องการให้ขยาย (ยกเว้นคอลัมน์ที่ 1)
  344.         Dim FixedWidth As Integer = 0
  345.         For i As Integer = 0 To lvwFile.Columns.Count - 1
  346.             If i <> 1 Then ' คอลัมน์ที่ 1 คือคอลัมน์ที่จะขยาย
  347.                 FixedWidth += lvwFile.Columns(i).Width
  348.             End If
  349.         Next
  350.         '// คำนวณพื้นที่ที่เหลือสำหรับคอลัมน์ที่ 1
  351.         Dim RemainingWidth As Integer = AvailableWidth - FixedWidth
  352.         '// ป้องกันไม่ให้คอลัมน์แคบเกินไป
  353.         If RemainingWidth < 50 Then RemainingWidth = 50
  354.         '// ตั้งความกว้างของคอลัมน์ที่ 1
  355.         lvwFile.Columns(1).Width = RemainingWidth
  356.     End Sub

  357.     '// เหตุการณ์การปรับขนาดจอ จะปรับระยะของหลักใน ListView ให้อัตโนมัติ
  358.     Private Sub frmAutoBackup_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
  359.         Call AdjustListViewColumnWidths()
  360.     End Sub

  361.     '// --------------------------------------------------------------------------------------
  362.     '// TIPS: การปรับฟอนต์ในส่วนของ Column Header ของ ListView Control
  363.     '// วาด Header
  364.     '// --------------------------------------------------------------------------------------
  365.     Private Sub lvwFile_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles lvwFile.DrawColumnHeader
  366.         Using HeaderFont As New Font("Tahoma", 10, FontStyle.Bold)
  367.             e.Graphics.FillRectangle(SystemBrushes.ControlDark, e.Bounds) '// พื้นหลัง SystemBrushes.Control
  368.             TextRenderer.DrawText(e.Graphics, e.Header.Text, HeaderFont, e.Bounds, Color.Black, TextFormatFlags.VerticalCenter Or TextFormatFlags.VerticalCenter)
  369.         End Using
  370.     End Sub

  371.     '// วาด Item (ให้ระบบจัดการเอง)
  372.     Private Sub lvwFile_DrawItem(sender As Object, e As DrawListViewItemEventArgs) Handles lvwFile.DrawItem
  373.         e.DrawDefault = True
  374.     End Sub

  375.     '// วาด SubItem (ให้ระบบจัดการเอง)
  376.     Private Sub lvwFile_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles lvwFile.DrawSubItem
  377.         e.DrawDefault = True
  378.     End Sub
  379.     '// --------------------------------------------------------------------------------------
  380. #End Region

  381. #Region "TOOLSTRIP"
  382.     '// ปุ่ม Add เพื่อเปิด Popup ฟอร์ม frmSelectFileFolder
  383.     Private Sub tsbAddFile_Click(sender As Object, e As EventArgs) Handles tsbAddFile.Click
  384.         Dim f As New frmSelectFileFolder()
  385.         If f.ShowDialog() = DialogResult.OK Then
  386.             Try
  387.                 Dim Src As String = f.txtFile.Text
  388.                 Dim Dst As String = f.txtFolder.Text
  389.                 '// --- ดึง Icon ของไฟล์ ---
  390.                 Dim ic As Icon = Nothing
  391.                 If File.Exists(Src) Then
  392.                     ic = Icon.ExtractAssociatedIcon(Src)
  393.                     If Not imgList.Images.ContainsKey(Src) Then
  394.                         imgList.Images.Add(Src, ic)
  395.                     End If
  396.                 Else
  397.                     '// ไฟล์ไม่เจอให้ใช้ Default Icon
  398.                     If Not imgList.Images.ContainsKey("missing") Then
  399.                         imgList.Images.Add("missing", SystemIcons.WinLogo)
  400.                     End If
  401.                 End If
  402.                 '// --- เพิ่มข้อมูลลง ListView ---
  403.                 Dim item As New ListViewItem(Src)   '// ใช้ Full Path แทน FileName
  404.                 If ic IsNot Nothing Then
  405.                     item.ImageKey = Src
  406.                 Else
  407.                     item.ImageKey = "missing"
  408.                 End If
  409.                 item.Tag = Src      '// เก็บ path เต็มไว้ใน Tag
  410.                 item.SubItems.Add(Dst)  '// คอลัมน์ที่สอง = โฟลเดอร์ปลายทาง
  411.                 lvwFile.Items.Add(item)
  412.                 '// --- บันทึกลง Config.INI ---
  413.                 Call SaveConfig()
  414.             Catch ex As Exception
  415.                 MessageBox.Show("เกิดข้อผิดพลาด: " & ex.Message, "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Error)
  416.             End Try
  417.         End If
  418.     End Sub

  419.     '// ปุ่ม Edit แก้ไขรายการบนฟอร์ม frmSelectFileFolder
  420.     Private Sub tsbEditFile_Click(sender As Object, e As EventArgs) Handles tsbEditFile.Click
  421.         If lvwFile.SelectedItems.Count = 0 Then Exit Sub
  422.         Dim sel As ListViewItem = lvwFile.SelectedItems(0)

  423.         Dim f As New frmSelectFileFolder()
  424.         f.txtFile.Text = sel.Tag.ToString()     '// ใช้ path เต็ม
  425.         f.txtFolder.Text = sel.SubItems(1).Text

  426.         If f.ShowDialog() = DialogResult.OK Then
  427.             Dim newSrc As String = f.txtFile.Text
  428.             Dim newDst As String = f.txtFolder.Text
  429.             sel.Text = newSrc   '// ใช้ Full Path
  430.             sel.Tag = newSrc
  431.             sel.SubItems(1).Text = newDst
  432.             '// อัพเดทไอคอนใหม่
  433.             If File.Exists(newSrc) Then
  434.                 Dim ic As Icon = Icon.ExtractAssociatedIcon(newSrc)
  435.                 If Not imgList.Images.ContainsKey(newSrc) Then
  436.                     imgList.Images.Add(newSrc, ic)
  437.                 End If
  438.                 sel.ImageKey = newSrc
  439.             Else
  440.                 sel.ImageKey = "missing"
  441.             End If
  442.             '// บันทึกลงใน INI
  443.             Call SaveConfig()
  444.         End If
  445.     End Sub

  446.     '// ปุ่ม Remove ลบรายการออกจาก ListView
  447.     Private Sub tsbRemoveFile_Click(sender As Object, e As EventArgs) Handles tsbRemoveFile.Click
  448.         If lvwFile.SelectedItems.Count = 0 Then Exit Sub
  449.         Dim sel As ListViewItem = lvwFile.SelectedItems(0)
  450.         Dim fullPath As String = sel.Tag.ToString()   '// Full Path เก็บอยู่ใน Tag
  451.         Dim result As DialogResult = MessageBox.Show(
  452.             "คุณต้องการลบรายการนี้ออกหรือไม่?" & Environment.NewLine & fullPath,
  453.             "ยืนยันการลบ",
  454.             MessageBoxButtons.YesNo,
  455.             MessageBoxIcon.Question,
  456.             MessageBoxDefaultButton.Button2
  457.         )
  458.         If result = DialogResult.Yes Then
  459.             lvwFile.Items.Remove(sel)
  460.             '// บันทึกลงใน INI
  461.             Call SaveConfig()
  462.         End If
  463.     End Sub

  464.     '// ปุ่ม Backup คัดลอกไฟล์
  465.     Private Sub tsbBackupFile_Click(sender As Object, e As EventArgs) Handles tsbBackupFile.Click
  466.         '// ตรวจสอบก่อนว่ามีไฟล์ใน ListView หรือไม่
  467.         If lvwFile.Items.Count = 0 Then
  468.             'MessageBox.Show("ยังไม่มีรายการไฟล์สำหรับสำรองข้อมูล", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Warning)
  469.             Call Notification("Warning.png", Color.Red, "WARNING", Color.Black, "ยังไม่มีรายการไฟล์สำหรับสำรองข้อมูล.", Color.Black)
  470.             Exit Sub
  471.         End If
  472.         '// เริ่มทำการสำรองไฟล์ (วนถอยหลังเพื่อสามารถลบได้)
  473.         For i As Integer = lvwFile.Items.Count - 1 To 0 Step -1
  474.             Dim item As ListViewItem = lvwFile.Items(i)
  475.             Dim Source As String = item.Tag.ToString()
  476.             Dim DestFolder As String = item.SubItems(1).Text

  477.             '// ตรวจสอบว่ามีไฟล์ต้นทางและโฟลเดอร์ปลายทางหรือไม่
  478.             If Not File.Exists(Source) OrElse Not Directory.Exists(DestFolder) Then
  479.                 '// ถ้าไม่เจอต้องลบรายการออกจากแถวใน ListView และบันทึกข้อมูลลงไฟล์ INI ใหม่อีกรอบ
  480.                 lvwFile.Items.RemoveAt(i)
  481.                 Call SaveConfig()
  482.                 Continue For
  483.             End If

  484.             Try
  485.                 Dim DestFile As String = Path.Combine(DestFolder, Path.GetFileName(Source))
  486.                 File.Copy(Source, DestFile, True)
  487.             Catch ex As Exception
  488.                 '// ไม่ต้องโชว์ Error
  489.                 'MessageBox.Show(ex.Message, "Report Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
  490.             End Try
  491.         Next
  492.         'MessageBox.Show("Backup Completed!", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Information)
  493.         Call Notification("Success.png", Color.FromArgb(40, 167, 69), "SUCCESS", Color.Black, "การสำรองข้อมูลเสร็จสิ้นสมบูรณ์.", Color.Black)
  494.         ElapsedTime = 0
  495.     End Sub
  496. #End Region

  497. #Region "CONFIG"
  498.     '// ------------------------------------ โหลดจาก Config.ini ------------------------------------
  499.     Private Sub LoadConfig()
  500.         lvwFile.Items.Clear()
  501.         Dim idx As Integer = 1
  502.         Do
  503.             Dim Src As String = ReadIni("BackupData", "SourceFile" & idx, "", iniPath).Replace("""", "")
  504.             Dim Dest As String = ReadIni("BackupData", "DestinationFile" & idx, "", iniPath).Replace("""", "")

  505.             If String.IsNullOrWhiteSpace(Src) OrElse String.IsNullOrWhiteSpace(Dest) Then Exit Do

  506.             Dim iconKey As String = Src
  507.             If Not imgList.Images.ContainsKey(iconKey) Then
  508.                 Try
  509.                     If File.Exists(Src) Then
  510.                         Dim ic As Icon = Icon.ExtractAssociatedIcon(Src)
  511.                         imgList.Images.Add(iconKey, ic)
  512.                     Else
  513.                         If Not imgList.Images.ContainsKey("missing") Then
  514.                             imgList.Images.Add("missing", SystemIcons.WinLogo)
  515.                         End If
  516.                         iconKey = "missing"
  517.                     End If
  518.                 Catch ex As Exception
  519.                     If Not imgList.Images.ContainsKey("missing") Then
  520.                         imgList.Images.Add("missing", SystemIcons.WinLogo)
  521.                     End If
  522.                     iconKey = "missing"
  523.                 End Try
  524.             End If
  525.             '// ใช้ Full Path แสดงใน ListView
  526.             Dim item As New ListViewItem(Src)
  527.             item.ImageKey = iconKey
  528.             item.Tag = Src
  529.             item.SubItems.Add(Dest)
  530.             lvwFile.Items.Add(item)
  531.             idx += 1
  532.         Loop
  533.         '// โหลดค่าช่วงเวลา Timer จาก Config
  534.         Dim intervalStr As String = ReadIni("Timer", "Interval", "1", iniPath)
  535.         Dim intervalVal As Integer
  536.         If Integer.TryParse(intervalStr, intervalVal) Then
  537.             BackupInterval = intervalVal   '// หน่วยนับเป็นชั่วโมง
  538.             '// ------------------------------------------------------------------------------
  539.             '// อัปเดต ComboBox cmbInterval ถ้ามีอยู่
  540.             For i As Integer = 0 To cmbInterval.Items.Count - 1
  541.                 If cmbInterval.Items(i).ToString() = intervalVal.ToString() Then
  542.                     cmbInterval.SelectedIndex = i
  543.                     Exit For
  544.                 End If
  545.             Next
  546.         End If
  547.     End Sub

  548.     '// ------------------------------------ บันทึกลง Config.ini ------------------------------------
  549.     Private Sub SaveConfig()
  550.         '// ลบ Section เก่าทั้งหมดก่อน
  551.         WriteIni("BackupData", Nothing, Nothing, iniPath)

  552.         '// เขียนใหม่ตาม ListView ที่เหลือ
  553.         For i As Integer = 0 To lvwFile.Items.Count - 1
  554.             Dim Src As String = lvwFile.Items(i).Tag.ToString()
  555.             Dim Dest As String = lvwFile.Items(i).SubItems(1).Text

  556.             WriteIni("BackupData", "SourceFile" & (i + 1), """" & Src & """", iniPath)
  557.             WriteIni("BackupData", "DestinationFile" & (i + 1), """" & Dest & """", iniPath)
  558.         Next
  559.         '// เขียนค่า Timer Interval
  560.         If cmbInterval.SelectedItem IsNot Nothing Then
  561.             WriteIni("Timer", "Interval", cmbInterval.SelectedItem.ToString(), iniPath)
  562.         Else
  563.             '// การใช้งานจริงมีหน่วยนับเป็นชั่วโมง
  564.             WriteIni("Timer", "Interval", BackupInterval.ToString(), iniPath)  '// หน่วยนับเป็นชั่วโมง
  565.         End If
  566.     End Sub
  567. #End Region

  568.     Private Sub tsbExit_Click(sender As System.Object, e As System.EventArgs) Handles tsbExit.Click
  569.         Me.Close()
  570.     End Sub

  571.     '// Event ตอนปิดฟอร์มหลัก
  572.     Private Sub frmBackypData_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
  573.         Try
  574.             If TrayIcon IsNot Nothing Then
  575.                 TrayIcon.Visible = False
  576.                 TrayIcon.Dispose()
  577.             End If
  578.         Catch
  579.         End Try
  580.     End Sub

  581.     '// เผื่อกรณีปิดโปรแกรมด้วย Application.Exit
  582.     Protected Overrides Sub Finalize()
  583.         Try
  584.             If TrayIcon IsNot Nothing Then
  585.                 TrayIcon.Visible = False
  586.                 TrayIcon.Dispose()
  587.             End If
  588.         Finally
  589.             MyBase.Finalize()
  590.         End Try
  591.     End Sub


  592. #Region "FUNCTION"
  593.     '// --------------------------------------------------------------------------------
  594.     '// Get my project path
  595.     '// AppPath = C:\My Project\bin\debug
  596.     '// Replace "\bin\debug" with ""
  597.     '// Return : C:\My Project\
  598.     Function MyPath(ByVal AppPath As String) As String
  599.         Dim p = AppPath.ToLower().Replace("\bin\debug", "").Replace("\bin\release", "").Replace("\bin\x86\debug", "").Replace("\bin\x86\release", "")
  600.         '// Chr(92) คือ ASCII Code ของเครื่องหมาย Back Slash
  601.         If Not p.EndsWith(Chr(92)) Then p &= Chr(92)
  602.         Return p
  603.     End Function
  604. #End Region

  605. End Class
คัดลอกไปที่คลิปบอร์ด

โค้ดในการเบราซ์ไฟล์และกำหนดโฟลเดอร์ปลายทางในการสำรองข้อมูล ... frmSelectFileFolder.vb
  1. Imports System.IO

  2. Public Class frmSelectFileFolder

  3.     Private Sub btnBrowseFile_Click(sender As Object, e As EventArgs) Handles btnBrowseFile.Click
  4.         Using ofd As New OpenFileDialog
  5.             ofd.Filter = "All Files (*.*)|*.*"
  6.             If ofd.ShowDialog() = DialogResult.OK Then
  7.                 txtFile.Text = ofd.FileName
  8.             End If
  9.         End Using
  10.     End Sub

  11.     Private Sub btnBrowseFolder_Click(sender As Object, e As EventArgs) Handles btnBrowseFolder.Click
  12.         Using fbd As New FolderBrowserDialog
  13.             fbd.Description = "เลือกโฟลเดอร์ที่ต้องการ"
  14.             If fbd.ShowDialog() = DialogResult.OK Then
  15.                 txtFolder.Text = fbd.SelectedPath
  16.             End If
  17.         End Using
  18.     End Sub

  19.     '// --------------------------------------------------------------------------------------
  20.     Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
  21.         If txtFile.Text.Trim = "" Or txtFolder.Text.Trim = "" Then
  22.             MessageBox.Show("กรุณาเลือกไฟล์และโฟลเดอร์ปลายทาง", "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Warning)
  23.             Exit Sub
  24.         End If

  25.         '// ตรวจสอบว่า Source กับ Destination เป็นโฟลเดอร์เดียวกันหรือไม่
  26.         Dim sourceFile As String = txtFile.Text.Trim
  27.         Dim destFolder As String = txtFolder.Text.Trim

  28.         Try
  29.             Dim sourceFolder As String = Path.GetDirectoryName(sourceFile)
  30.             '// เปรียบเทียบแบบ Case-Insensitive และตัด \ ท้ายออกก่อนเทียบ
  31.             If String.Equals(sourceFolder.TrimEnd(""c), destFolder.TrimEnd(""c), StringComparison.OrdinalIgnoreCase) Then
  32.                 MessageBox.Show("ไม่สามารถเลือกโฟลเดอร์ปลายทางที่ตรงกับโฟลเดอร์ของไฟล์ต้นทางได้", "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Error)
  33.                 Exit Sub
  34.             End If
  35.         Catch ex As Exception
  36.             MessageBox.Show("เกิดข้อผิดพลาดในการตรวจสอบโฟลเดอร์: " & ex.Message, "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Error)
  37.             Exit Sub
  38.         End Try
  39.         Me.DialogResult = DialogResult.OK
  40.         Me.Close()
  41.     End Sub

  42.     Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
  43.         Me.DialogResult = DialogResult.Cancel
  44.         Me.Close()
  45.     End Sub

  46.     Private Sub frmSelectFileFolder_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  47.         Me.Height = 195
  48.         Me.MinimumSize = New Size(Me.Width, 195)
  49.     End Sub

  50.     Private Sub frmSelectFileFolder_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
  51.         '// ถ้าความสูงไม่เท่ากับค่าที่ต้องการปรับกลับทันที เพื่อไม่ให้ความสูงของฟอร์มเกินที่กำหนด
  52.         If Me.Height <> 195 Then Me.Height = 195
  53.     End Sub

  54.     Private Sub txtFile_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtFile.KeyPress
  55.         e.Handled = True
  56.     End Sub

  57.     Private Sub txtFolder_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtFolder.KeyPress
  58.         e.Handled = True
  59.     End Sub
  60. End Class
คัดลอกไปที่คลิปบอร์ด

โค้ดในการจัดเรียงข้อมูลบนตัว ListView Control ... ListViewItemComparer.vb
  1. '// คลาสสำหรับจัดเรียงข้อมูลจากการคลิ๊กเมาส์ที่ส่วนหัวหรือหลักของ ListView
  2. Public Class ListViewItemComparer
  3.     Implements IComparer

  4.     Private col As Integer
  5.     Private order As SortOrder

  6.     Public Sub New(column As Integer, sortOrder As SortOrder)
  7.         col = column
  8.         order = sortOrder
  9.     End Sub

  10.     Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
  11.         Dim lviX As ListViewItem = CType(x, ListViewItem)
  12.         Dim lviY As ListViewItem = CType(y, ListViewItem)
  13.         Dim result As Integer = String.Compare(lviX.SubItems(col).Text, lviY.SubItems(col).Text)
  14.         If order = SortOrder.Descending Then result = -result
  15.         Return result
  16.     End Function
  17. End Class
คัดลอกไปที่คลิปบอร์ด

ดาวน์โหลดโค้ดฉบับเต็ม VB.NET (2010) + .Net Framework 4.0 ได้ที่นี่ ...

ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง

คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด
ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | ลงทะเบียน

รายละเอียดเครดิต

ข้อความล้วน|อุปกรณ์พกพา|ประวัติการแบน|G2GNet.com  

GMT+7, 2025-10-16 22:50 , Processed in 0.138986 second(s), 5 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้