|

แจ้งเตือนสถานะการทำงานโดยใช้ 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
- Imports System.IO
- Imports System.Text
- Imports System.Runtime.InteropServices
- Imports System.Windows.Forms
- Imports Microsoft.Win32
- '// .Net Framework from 4.0+
- '// https://www.nuget.org/packages/Tulpep.NotificationWindow
- Imports Tulpep.NotificationWindow
- Public Class frmAutoBackup
- '// ตำแหน่งเก็บไฟล์ Config.ini
- Private iniPath As String = MyPath(Application.StartupPath) & "\Config.ini"
- '// Path เก็บไฟล์ Image
- Private imagePath = MyPath(Application.StartupPath) & "Images"
- '// Path เก็บไอคอนเพื่อใช้กับ System Tray
- Private IconPath As String = MyPath(Application.StartupPath) & "Images"
- '// ฟอนต์ของ Notifiaction
- Private TitleFont As New Font("Tahoma", 15, FontStyle.Bold)
- Private ContentFont As New Font("Tahoma", 12, FontStyle.Regular)
- ' ==== Notify Icon ====
- Private WithEvents TrayIcon As NotifyIcon
- Private WithEvents TrayMenu As ContextMenuStrip
- '// ==== Timer ตั้งเวลา ====
- Private WithEvents tmr As New Timer()
- Private BackupInterval As Integer = 1 '// หน่วยชั่วโมง (1 – 24) เมื่อนำไปใช้งานจริง
- Private ElapsedTime As Integer = 0 '// นับเวลาที่ผ่านไป
- '// ---------------------------------------------------------------------------------------------------
- '// สร้าง CheckBox แบบ Run Time เพื่อกำหนดให้รันโปรแกรมตอน Start Windows
- Dim chkStartup As New CheckBox()
- '// สร้าง ComboBox ในการตั้งเวลา
- Dim cmbInterval As New ComboBox
- #Region "INI"
- '// --------------------------------------------------------------------------------------
- '// APIs for Read/Write INI File.
- <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
- Private Shared Function WritePrivateProfileString(
- lpAppName As String,
- lpKeyName As String,
- lpString As String,
- lpFileName As String) As Long
- End Function
- <DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
- Private Shared Function GetPrivateProfileString(
- lpAppName As String,
- lpKeyName As String,
- lpDefault As String,
- lpReturneDstring As StringBuilder,
- nSize As Integer,
- lpFileName As String) As Integer
- End Function
- Private Sub WriteIni(section As String, key As String, value As String, filePath As String)
- WritePrivateProfileString(section, key, value, filePath)
- End Sub
- Private Function ReadIni(section As String, key As String, defaultValue As String, filePath As String) As String
- Dim sb As New StringBuilder(1024)
- GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, filePath)
- Return sb.ToString()
- End Function
- #End Region
- '// --------------------------------------------------------------------------------------
- #Region "NOTIFICATION"
- '// Popup Notification
- Private Sub Notification(
- ByVal img As String,
- ByVal BodyColor As System.Drawing.Color,
- ByVal TitleText As String,
- ByVal TitleColor As System.Drawing.Color,
- ByVal ContentText As String,
- ByVal ContentColor As System.Drawing.Color
- )
- Dim Popup As PopupNotifier = New PopupNotifier()
- Dim bitmap As Bitmap
- Try
- bitmap = Image.FromFile(imagePath & img)
- With Popup
- .Image = bitmap
- .BodyColor = BodyColor
- .TitleText = TitleText
- .TitleColor = TitleColor
- .TitleFont = TitleFont
- .ContentText = ContentText
- .ContentColor = ContentColor
- .ContentFont = ContentFont
- .Popup()
- End With
- Catch ex As Exception
- MessageBox.Show(ex.Message)
- End Try
- End Sub
- #End Region
- '// ---------------------------------------------- ImageList เก็บ Icon ----------------------------------------------
- Private imgList As New ImageList()
- '// เก็บคอลัมน์ล่าสุดที่กด กับลำดับการเรียง
- Private SortColumn As Integer = -1
- Private SortOrder As SortOrder = SortOrder.None
- '// --------------------------------------------------------------------------------------
- '// S T A R T . . . H E R E
- '// --------------------------------------------------------------------------------------
- Private Sub frmAutoBackup_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
- Me.MinimumSize = New Point(884, 603) '// กำหนดขนาดของฟอร์มต่ำสุด
- '// ImageList สำหรับ Icon
- imgList.ImageSize = New Size(22, 22) '// จะมีผลต่อความสูงของแถวในตัว ListView
- imgList.ColorDepth = ColorDepth.Depth32Bit
- lvwFile.SmallImageList = imgList
- '// ตั้งค่าให้กับ CheckBox เพื่อให้พื้นหลังกลมกลืนกับ ToolStrip
- chkStartup.Text = "Run on Windows Startup"
- chkStartup.Font = New Font("Tahoma", 10, FontStyle.Regular)
- chkStartup.BackColor = Color.Transparent
- Dim host As New ToolStripControlHost(chkStartup)
- ToolStrip1.Items.Add(host)
- '// Add Event Handler เพื่อกำหนดค่าการเปิดโฟลเดอร์อัตโนมัติ เมื่อ Start Windows
- AddHandler chkStartup.CheckedChanged, AddressOf chkStartup_CheckedChanged
- '// ตั้งค่า ComboBox เพื่อเก็บค่าเวลา
- cmbInterval.Name = "cmbInterval"
- cmbInterval.DropDownStyle = ComboBoxStyle.DropDownList
- cmbInterval.ItemHeight = 10 '// จำกัดการแสดงผล 10 Items
- cmbInterval.IntegralHeight = False
- cmbInterval.Width = 60
- '// ------------------------ ใช้กับงานจริงให้นับ 1 - 24 ชั่วโมง --------------------------
- '// เพิ่มค่า 1 - 24 ชั่วโมง
- For i As Integer = 1 To 24
- cmbInterval.Items.Add(i.ToString())
- Next
- cmbInterval.SelectedIndex = 0 '// ค่าเริ่มต้น = 1 ชั่วโมง
- BackupInterval = CInt(cmbInterval.SelectedItem)
- '// === สร้าง Label ต่อท้าย ===
- Dim lblHours As New ToolStripLabel("Hours.")
- '// ------------------------------------------------------------------------------------------
- '=== เพิ่มลงใน ToolStrip ===
- ToolStrip1.Items.Add(New ToolStripSeparator())
- ToolStrip1.Items.Add(New ToolStripLabel("Interval:"))
- host = New ToolStripControlHost(cmbInterval)
- ToolStrip1.Items.Add(host)
- ToolStrip1.Items.Add(lblHours)
- '=== ดักจับเหตุการณ์เปลี่ยนค่า ===
- AddHandler cmbInterval.SelectedIndexChanged, AddressOf cmbInterval_SelectedIndexChanged
- '// เปิด OwnerDraw สำหรับการปรับฟอนต์ใน Column Header ของ ListView Control
- '// โค้ดที่เกี่ยวข้องจะอยู่ทางด้านล่างสุด
- lvwFile.OwnerDraw = True
- Call InitializeListView()
- Call AdjustListViewColumnWidths()
- '// โหลดจาก Config.ini
- Call LoadConfig()
- Call SaveConfig() '// บันทึกค่าเวลาด้วย
- '// -------------------------------------------- IMPORTANT --------------------------------------------
- '// Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
- '// ทดสอบการกำหนดให้ Run ตอน Start Windows
- If IsStartupEnabled() Then
- chkStartup.Checked = True
- 'tsbBackupFile.PerformClick() '// สั่งโปรแกรมให้สำรองข้อมูลทันที
- Else
- chkStartup.Checked = False
- End If
- '// สร้าง System Tray
- Call InitTrayIcon()
- '// ตั้งค่า Timer ให้เกิดการ Tick ทุกๆ 1 วินาที
- '// หากให้เวลาเร็วขึ้นโดยไม่ต้องรอให้ครบ 1 ชม. ก็ปรับลดค่า Interval ลง
- tmr.Interval = 1000
- tmr.Start()
- '// ปิดหน้าจอลงไปเก็บไว้ใน System Tray พร้อมกับการแจ้งเตือน
- 'Me.WindowState = FormWindowState.Minimized
- End Sub
- #Region "TIMER"
- '// ----------------------------------------- เมื่อใช้งานจริงให้หน่วยนับเป็นชั่วโมง ---------------------------------
- Private Sub tmr_Tick(sender As Object, e As EventArgs) Handles tmr.Tick
- ElapsedTime += 1
- '// แปลงชั่วโมงที่เลือกเป็นวินาที
- '// 1000 millisecond = 1 Second, 60 Seconds = 1 Minute, 60 Minute = 1 Hour. (3,600 Seconds)
- Dim targetSeconds As Integer = BackupInterval * 3600
- If ElapsedTime >= targetSeconds Then
- ElapsedTime = 0
- '// === เรียกทำงาน Backup Data ===
- Call tsbBackupFile_Click(Nothing, Nothing)
- End If
- End Sub
- Private Sub cmbInterval_SelectedIndexChanged(sender As Object, e As EventArgs)
- If cmbInterval.SelectedItem IsNot Nothing Then
- BackupInterval = CInt(cmbInterval.SelectedItem)
- ElapsedTime = 0 '// รีเซ็ตเวลาใหม่ทุกครั้งที่เปลี่ยน
- Call SaveConfig() '// บันทึกค่าใหม่
- End If
- End Sub
- '// ---------------------------------------------------------------------------------------------------------------------
- #End Region
- #Region "STARTUP"
- '// --------------------------------------------------------------------------------------
- '// Add Event Handler เพื่อกำหนดให้โปรแกรมทำงานตอน Start Windows หรือไม่
- '// --------------------------------------------------------------------------------------
- Private Sub chkStartup_CheckedChanged(sender As System.Object, e As System.EventArgs)
- If chkStartup.Checked Then
- '// Run on Windows Start
- Call SetStartup(True)
- Else
- Call SetStartup(False)
- End If
- End Sub
- '// ============= สร้างค่าใน Registry เพื่อให้รันตอน Startup =============
- '// หาก enable กำหนดเป็น True จะทำการ Registry เพื่อให้โปรแกรม Run ตอน Start Windows
- '// หาก enable กำหนดเป็น False จะทำการลบ Registry ออกไป
- '// Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
- Private Sub SetStartup(enable As Boolean)
- Try
- Using key As RegistryKey = Registry.CurrentUser.OpenSubKey(
- "Software\Microsoft\Windows\CurrentVersion\Run", True)
- If key Is Nothing Then
- MessageBox.Show("ไม่สามารถเข้าถึง Registry ได้", "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Return
- End If
- If enable Then
- key.SetValue("AutoBackup", Application.ExecutablePath)
- Else
- '// ลบค่าออก ถ้าไม่ต้องการให้รันอัตโนมัติ
- If key.GetValue("AutoBackup") IsNot Nothing Then key.DeleteValue("AutoBackup")
- End If
- End Using
- Catch ex As Exception
- MessageBox.Show("เกิดข้อผิดพลาดในการตั้งค่า Startup: " & ex.Message, "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
- End Try
- End Sub
- '// ---------------------- ทดสอบค่า Run on Windows Start ----------------------
- Private Function IsStartupEnabled() As Boolean
- Try
- Using key As RegistryKey = Registry.CurrentUser.OpenSubKey(
- "Software\Microsoft\Windows\CurrentVersion\Run", False) '// อ่านอย่างเดียว (ReadOnly)
- If key Is Nothing Then Return False '// ไม่สามารถเปิด Registry ได้ (ถือว่าไม่ได้ตั้งค่า)
- '// ตรวจสอบว่ามีค่า "OpenMultipleFolder" หรือไม่
- Dim value As Object = key.GetValue("AutoBackup")
- If value IsNot Nothing Then
- '// ตรวจสอบว่าค่าที่เก็บเป็นพาธของโปรแกรมตัวเองหรือไม่
- Dim ProgramPath As String = Application.ExecutablePath
- Dim RegistryPath As String = value.ToString()
- '// เปรียบเทียบแบบไม่สนใจตัวพิมพ์ใหญ่/เล็ก และตัด quote ออกถ้ามี
- Dim CleanRegistryPath As String = RegistryPath.Replace("""", "")
- Return String.Equals(CleanRegistryPath, ProgramPath, StringComparison.OrdinalIgnoreCase)
- Else
- Return False
- End If
- End Using
- Catch ex As Exception
- '// ถ้าเกิดข้อผิดพลาด เช่น สิทธิ์ไม่พอ ถือว่าไม่ได้ตั้งค่า รีเทิร์นค่า False กลับไป
- 'MessageBox.Show("Error checking startup: " & ex.Message)
- Return False
- End Try
- End Function
- #End Region
- #Region "TRAYICON"
- Private Sub InitTrayIcon()
- '// โหลด Icon ที่เราเตรียมไว้
- Dim iconBackup As Icon = New Icon(Path.Combine(IconPath, "backupdisk.ico"))
- Dim iconAbout As Icon = New Icon(Path.Combine(IconPath, "about.ico"))
- Dim iconExit As Icon = New Icon(Path.Combine(IconPath, "exit.ico"))
- Dim appIcon As Icon = New Icon(Path.Combine(IconPath, "backup.ico")) '// ไอคอนหลักของโปรแกรม
- '// สร้าง ContextMenu สำหรับ System Tray
- TrayMenu = New ContextMenuStrip()
- ' === เมนู Backup Data ===
- Dim mnuBackup As New ToolStripMenuItem("Backup Data", iconBackup.ToBitmap())
- AddHandler mnuBackup.Click, AddressOf mnuBackup_Click
- TrayMenu.Items.Add(mnuBackup)
- ' === เมนู About Me ===
- Dim mnuAbout As New ToolStripMenuItem("About Me", iconAbout.ToBitmap)
- AddHandler mnuAbout.Click, AddressOf mnuAbout_Click
- TrayMenu.Items.Add(mnuAbout)
- ' === Separator ===
- TrayMenu.Items.Add(New ToolStripSeparator())
- ' === เมนู Exit ===
- Dim mnuExit As New ToolStripMenuItem("Exit", iconExit.ToBitmap)
- AddHandler mnuExit.Click, AddressOf mnuExit_Click
- TrayMenu.Items.Add(mnuExit)
- '// สร้าง NotifyIcon
- TrayIcon = New NotifyIcon()
- TrayIcon.Icon = appIcon
- TrayIcon.Text = "Backup Application"
- TrayIcon.ContextMenuStrip = TrayMenu
- TrayIcon.Visible = True
- End Sub
- '// ดับเบิ้ลคลิกที่ TrayIcon เพื่อ Restore กลับมา
- Private Sub TrayIcon_DoubleClick(sender As Object, e As EventArgs) Handles TrayIcon.DoubleClick
- Me.Show()
- Me.WindowState = FormWindowState.Normal
- End Sub
- '// === Event ของเมนู ===
- Private Sub mnuBackup_Click(sender As Object, e As EventArgs)
- '// เรียกใช้งานเหตุการณ์ Backup Data
- 'tsbBackupFile.PerformClick()
- Me.Show()
- Me.WindowState = FormWindowState.Normal
- End Sub
- Private Sub mnuAbout_Click(sender As Object, e As EventArgs)
- 'Dim frm As New frmAboutMe()
- 'frm.ShowDialog()
- MessageBox.Show("About Me")
- End Sub
- Private Sub mnuExit_Click(sender As Object, e As EventArgs)
- TrayIcon.Visible = False
- Me.Close()
- End Sub
- #End Region
- #Region "LISTVIEW"
- '// --------------------------------------------------------------------------------------
- '// ตั้งค่าเริ่มต้นให้กับ ListView Control
- Sub InitializeListView()
- With lvwFile
- .View = View.Details
- .MultiSelect = False
- .HideSelection = False
- .FullRowSelect = True
- .GridLines = True
- .Columns.Clear()
- .Columns.Add("Source File", lvwFile.Width - 300)
- .Columns.Add("Destination Folder", 280)
- End With
- End Sub
- '// ดับเบิ้ลคลิ๊กเพื่อแก้ไขรายการแถวใน ListView Control
- Private Sub lvwFile_DoubleClick(sender As Object, e As EventArgs) Handles lvwFile.DoubleClick
- tsbEditFile.PerformClick()
- End Sub
- '// เมื่อคลิ๊กส่วนหัว (Column) ของ ListView จะทำการจัดเรียงข้อมูลไอเทม ListView
- Private Sub lvwFile_ColumnClick(sender As Object, e As ColumnClickEventArgs) Handles lvwFile.ColumnClick
- '// ถ้ากดซ้ำที่คอลัมน์เดิมสลับ ASC/DESC การจัดเรียงจากน้อยไปมาก หรือ มากไปน้อย
- If e.Column = SortColumn Then
- If SortOrder = SortOrder.Ascending Then
- SortOrder = SortOrder.Descending
- Else
- SortOrder = SortOrder.Ascending
- End If
- Else
- SortColumn = e.Column
- SortOrder = SortOrder.Ascending
- End If
- '// เรียกไปยังคลาส ListViewItemComparer
- lvwFile.ListViewItemSorter = New ListViewItemComparer(e.Column, SortOrder)
- lvwFile.Sort()
- End Sub
- '// ฟังก์ชันปรับความกว้างคอลัมน์ให้เต็มพื้นที่ว่าง
- Private Sub AdjustListViewColumnWidths()
- If lvwFile.Columns.Count = 0 Then Return
- If Me.WindowState = FormWindowState.Minimized Then
- Me.Hide()
- 'TrayIcon.ShowBalloonTip(1000, "กำลังทำงาน", "โปรแกรมถูกย่อไปที่ System Tray", ToolTipIcon.Info)
- Call Notification("Info.png", Color.FromArgb(255, 193, 7), "INFORMATION", Color.Black, "โปรแกรมกำลังทำงานและถูกย่อไปที่ System Tray.", Color.Black)
- End If
- '// ใช้ ClientSize.Width — คือพื้นที่ใช้งานจริงของ ListView
- Dim AvailableWidth As Integer = lvwFile.ClientSize.Width
- '// รวมความกว้างของคอลัมน์ที่ไม่ต้องการให้ขยาย (ยกเว้นคอลัมน์ที่ 1)
- Dim FixedWidth As Integer = 0
- For i As Integer = 0 To lvwFile.Columns.Count - 1
- If i <> 1 Then ' คอลัมน์ที่ 1 คือคอลัมน์ที่จะขยาย
- FixedWidth += lvwFile.Columns(i).Width
- End If
- Next
- '// คำนวณพื้นที่ที่เหลือสำหรับคอลัมน์ที่ 1
- Dim RemainingWidth As Integer = AvailableWidth - FixedWidth
- '// ป้องกันไม่ให้คอลัมน์แคบเกินไป
- If RemainingWidth < 50 Then RemainingWidth = 50
- '// ตั้งความกว้างของคอลัมน์ที่ 1
- lvwFile.Columns(1).Width = RemainingWidth
- End Sub
- '// เหตุการณ์การปรับขนาดจอ จะปรับระยะของหลักใน ListView ให้อัตโนมัติ
- Private Sub frmAutoBackup_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
- Call AdjustListViewColumnWidths()
- End Sub
- '// --------------------------------------------------------------------------------------
- '// TIPS: การปรับฟอนต์ในส่วนของ Column Header ของ ListView Control
- '// วาด Header
- '// --------------------------------------------------------------------------------------
- Private Sub lvwFile_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles lvwFile.DrawColumnHeader
- Using HeaderFont As New Font("Tahoma", 10, FontStyle.Bold)
- e.Graphics.FillRectangle(SystemBrushes.ControlDark, e.Bounds) '// พื้นหลัง SystemBrushes.Control
- TextRenderer.DrawText(e.Graphics, e.Header.Text, HeaderFont, e.Bounds, Color.Black, TextFormatFlags.VerticalCenter Or TextFormatFlags.VerticalCenter)
- End Using
- End Sub
- '// วาด Item (ให้ระบบจัดการเอง)
- Private Sub lvwFile_DrawItem(sender As Object, e As DrawListViewItemEventArgs) Handles lvwFile.DrawItem
- e.DrawDefault = True
- End Sub
- '// วาด SubItem (ให้ระบบจัดการเอง)
- Private Sub lvwFile_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles lvwFile.DrawSubItem
- e.DrawDefault = True
- End Sub
- '// --------------------------------------------------------------------------------------
- #End Region
- #Region "TOOLSTRIP"
- '// ปุ่ม Add เพื่อเปิด Popup ฟอร์ม frmSelectFileFolder
- Private Sub tsbAddFile_Click(sender As Object, e As EventArgs) Handles tsbAddFile.Click
- Dim f As New frmSelectFileFolder()
- If f.ShowDialog() = DialogResult.OK Then
- Try
- Dim Src As String = f.txtFile.Text
- Dim Dst As String = f.txtFolder.Text
- '// --- ดึง Icon ของไฟล์ ---
- Dim ic As Icon = Nothing
- If File.Exists(Src) Then
- ic = Icon.ExtractAssociatedIcon(Src)
- If Not imgList.Images.ContainsKey(Src) Then
- imgList.Images.Add(Src, ic)
- End If
- Else
- '// ไฟล์ไม่เจอให้ใช้ Default Icon
- If Not imgList.Images.ContainsKey("missing") Then
- imgList.Images.Add("missing", SystemIcons.WinLogo)
- End If
- End If
- '// --- เพิ่มข้อมูลลง ListView ---
- Dim item As New ListViewItem(Src) '// ใช้ Full Path แทน FileName
- If ic IsNot Nothing Then
- item.ImageKey = Src
- Else
- item.ImageKey = "missing"
- End If
- item.Tag = Src '// เก็บ path เต็มไว้ใน Tag
- item.SubItems.Add(Dst) '// คอลัมน์ที่สอง = โฟลเดอร์ปลายทาง
- lvwFile.Items.Add(item)
- '// --- บันทึกลง Config.INI ---
- Call SaveConfig()
- Catch ex As Exception
- MessageBox.Show("เกิดข้อผิดพลาด: " & ex.Message, "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Error)
- End Try
- End If
- End Sub
- '// ปุ่ม Edit แก้ไขรายการบนฟอร์ม frmSelectFileFolder
- Private Sub tsbEditFile_Click(sender As Object, e As EventArgs) Handles tsbEditFile.Click
- If lvwFile.SelectedItems.Count = 0 Then Exit Sub
- Dim sel As ListViewItem = lvwFile.SelectedItems(0)
- Dim f As New frmSelectFileFolder()
- f.txtFile.Text = sel.Tag.ToString() '// ใช้ path เต็ม
- f.txtFolder.Text = sel.SubItems(1).Text
- If f.ShowDialog() = DialogResult.OK Then
- Dim newSrc As String = f.txtFile.Text
- Dim newDst As String = f.txtFolder.Text
- sel.Text = newSrc '// ใช้ Full Path
- sel.Tag = newSrc
- sel.SubItems(1).Text = newDst
- '// อัพเดทไอคอนใหม่
- If File.Exists(newSrc) Then
- Dim ic As Icon = Icon.ExtractAssociatedIcon(newSrc)
- If Not imgList.Images.ContainsKey(newSrc) Then
- imgList.Images.Add(newSrc, ic)
- End If
- sel.ImageKey = newSrc
- Else
- sel.ImageKey = "missing"
- End If
- '// บันทึกลงใน INI
- Call SaveConfig()
- End If
- End Sub
- '// ปุ่ม Remove ลบรายการออกจาก ListView
- Private Sub tsbRemoveFile_Click(sender As Object, e As EventArgs) Handles tsbRemoveFile.Click
- If lvwFile.SelectedItems.Count = 0 Then Exit Sub
- Dim sel As ListViewItem = lvwFile.SelectedItems(0)
- Dim fullPath As String = sel.Tag.ToString() '// Full Path เก็บอยู่ใน Tag
- Dim result As DialogResult = MessageBox.Show(
- "คุณต้องการลบรายการนี้ออกหรือไม่?" & Environment.NewLine & fullPath,
- "ยืนยันการลบ",
- MessageBoxButtons.YesNo,
- MessageBoxIcon.Question,
- MessageBoxDefaultButton.Button2
- )
- If result = DialogResult.Yes Then
- lvwFile.Items.Remove(sel)
- '// บันทึกลงใน INI
- Call SaveConfig()
- End If
- End Sub
- '// ปุ่ม Backup คัดลอกไฟล์
- Private Sub tsbBackupFile_Click(sender As Object, e As EventArgs) Handles tsbBackupFile.Click
- '// ตรวจสอบก่อนว่ามีไฟล์ใน ListView หรือไม่
- If lvwFile.Items.Count = 0 Then
- 'MessageBox.Show("ยังไม่มีรายการไฟล์สำหรับสำรองข้อมูล", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Warning)
- Call Notification("Warning.png", Color.Red, "WARNING", Color.Black, "ยังไม่มีรายการไฟล์สำหรับสำรองข้อมูล.", Color.Black)
- Exit Sub
- End If
- '// เริ่มทำการสำรองไฟล์ (วนถอยหลังเพื่อสามารถลบได้)
- For i As Integer = lvwFile.Items.Count - 1 To 0 Step -1
- Dim item As ListViewItem = lvwFile.Items(i)
- Dim Source As String = item.Tag.ToString()
- Dim DestFolder As String = item.SubItems(1).Text
- '// ตรวจสอบว่ามีไฟล์ต้นทางและโฟลเดอร์ปลายทางหรือไม่
- If Not File.Exists(Source) OrElse Not Directory.Exists(DestFolder) Then
- '// ถ้าไม่เจอต้องลบรายการออกจากแถวใน ListView และบันทึกข้อมูลลงไฟล์ INI ใหม่อีกรอบ
- lvwFile.Items.RemoveAt(i)
- Call SaveConfig()
- Continue For
- End If
- Try
- Dim DestFile As String = Path.Combine(DestFolder, Path.GetFileName(Source))
- File.Copy(Source, DestFile, True)
- Catch ex As Exception
- '// ไม่ต้องโชว์ Error
- 'MessageBox.Show(ex.Message, "Report Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
- End Try
- Next
- 'MessageBox.Show("Backup Completed!", "Report Status", MessageBoxButtons.OK, MessageBoxIcon.Information)
- Call Notification("Success.png", Color.FromArgb(40, 167, 69), "SUCCESS", Color.Black, "การสำรองข้อมูลเสร็จสิ้นสมบูรณ์.", Color.Black)
- ElapsedTime = 0
- End Sub
- #End Region
- #Region "CONFIG"
- '// ------------------------------------ โหลดจาก Config.ini ------------------------------------
- Private Sub LoadConfig()
- lvwFile.Items.Clear()
- Dim idx As Integer = 1
- Do
- Dim Src As String = ReadIni("BackupData", "SourceFile" & idx, "", iniPath).Replace("""", "")
- Dim Dest As String = ReadIni("BackupData", "DestinationFile" & idx, "", iniPath).Replace("""", "")
- If String.IsNullOrWhiteSpace(Src) OrElse String.IsNullOrWhiteSpace(Dest) Then Exit Do
- Dim iconKey As String = Src
- If Not imgList.Images.ContainsKey(iconKey) Then
- Try
- If File.Exists(Src) Then
- Dim ic As Icon = Icon.ExtractAssociatedIcon(Src)
- imgList.Images.Add(iconKey, ic)
- Else
- If Not imgList.Images.ContainsKey("missing") Then
- imgList.Images.Add("missing", SystemIcons.WinLogo)
- End If
- iconKey = "missing"
- End If
- Catch ex As Exception
- If Not imgList.Images.ContainsKey("missing") Then
- imgList.Images.Add("missing", SystemIcons.WinLogo)
- End If
- iconKey = "missing"
- End Try
- End If
- '// ใช้ Full Path แสดงใน ListView
- Dim item As New ListViewItem(Src)
- item.ImageKey = iconKey
- item.Tag = Src
- item.SubItems.Add(Dest)
- lvwFile.Items.Add(item)
- idx += 1
- Loop
- '// โหลดค่าช่วงเวลา Timer จาก Config
- Dim intervalStr As String = ReadIni("Timer", "Interval", "1", iniPath)
- Dim intervalVal As Integer
- If Integer.TryParse(intervalStr, intervalVal) Then
- BackupInterval = intervalVal '// หน่วยนับเป็นชั่วโมง
- '// ------------------------------------------------------------------------------
- '// อัปเดต ComboBox cmbInterval ถ้ามีอยู่
- For i As Integer = 0 To cmbInterval.Items.Count - 1
- If cmbInterval.Items(i).ToString() = intervalVal.ToString() Then
- cmbInterval.SelectedIndex = i
- Exit For
- End If
- Next
- End If
- End Sub
- '// ------------------------------------ บันทึกลง Config.ini ------------------------------------
- Private Sub SaveConfig()
- '// ลบ Section เก่าทั้งหมดก่อน
- WriteIni("BackupData", Nothing, Nothing, iniPath)
- '// เขียนใหม่ตาม ListView ที่เหลือ
- For i As Integer = 0 To lvwFile.Items.Count - 1
- Dim Src As String = lvwFile.Items(i).Tag.ToString()
- Dim Dest As String = lvwFile.Items(i).SubItems(1).Text
- WriteIni("BackupData", "SourceFile" & (i + 1), """" & Src & """", iniPath)
- WriteIni("BackupData", "DestinationFile" & (i + 1), """" & Dest & """", iniPath)
- Next
- '// เขียนค่า Timer Interval
- If cmbInterval.SelectedItem IsNot Nothing Then
- WriteIni("Timer", "Interval", cmbInterval.SelectedItem.ToString(), iniPath)
- Else
- '// การใช้งานจริงมีหน่วยนับเป็นชั่วโมง
- WriteIni("Timer", "Interval", BackupInterval.ToString(), iniPath) '// หน่วยนับเป็นชั่วโมง
- End If
- End Sub
- #End Region
- Private Sub tsbExit_Click(sender As System.Object, e As System.EventArgs) Handles tsbExit.Click
- Me.Close()
- End Sub
- '// Event ตอนปิดฟอร์มหลัก
- Private Sub frmBackypData_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
- Try
- If TrayIcon IsNot Nothing Then
- TrayIcon.Visible = False
- TrayIcon.Dispose()
- End If
- Catch
- End Try
- End Sub
- '// เผื่อกรณีปิดโปรแกรมด้วย Application.Exit
- Protected Overrides Sub Finalize()
- Try
- If TrayIcon IsNot Nothing Then
- TrayIcon.Visible = False
- TrayIcon.Dispose()
- End If
- Finally
- MyBase.Finalize()
- End Try
- End Sub
- #Region "FUNCTION"
- '// --------------------------------------------------------------------------------
- '// Get my project path
- '// AppPath = C:\My Project\bin\debug
- '// Replace "\bin\debug" with ""
- '// Return : C:\My Project\
- Function MyPath(ByVal AppPath As String) As String
- Dim p = AppPath.ToLower().Replace("\bin\debug", "").Replace("\bin\release", "").Replace("\bin\x86\debug", "").Replace("\bin\x86\release", "")
- '// Chr(92) คือ ASCII Code ของเครื่องหมาย Back Slash
- If Not p.EndsWith(Chr(92)) Then p &= Chr(92)
- Return p
- End Function
- #End Region
- End Class
คัดลอกไปที่คลิปบอร์ด
โค้ดในการเบราซ์ไฟล์และกำหนดโฟลเดอร์ปลายทางในการสำรองข้อมูล ... frmSelectFileFolder.vb
- Imports System.IO
- Public Class frmSelectFileFolder
- Private Sub btnBrowseFile_Click(sender As Object, e As EventArgs) Handles btnBrowseFile.Click
- Using ofd As New OpenFileDialog
- ofd.Filter = "All Files (*.*)|*.*"
- If ofd.ShowDialog() = DialogResult.OK Then
- txtFile.Text = ofd.FileName
- End If
- End Using
- End Sub
- Private Sub btnBrowseFolder_Click(sender As Object, e As EventArgs) Handles btnBrowseFolder.Click
- Using fbd As New FolderBrowserDialog
- fbd.Description = "เลือกโฟลเดอร์ที่ต้องการ"
- If fbd.ShowDialog() = DialogResult.OK Then
- txtFolder.Text = fbd.SelectedPath
- End If
- End Using
- End Sub
- '// --------------------------------------------------------------------------------------
- Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
- If txtFile.Text.Trim = "" Or txtFolder.Text.Trim = "" Then
- MessageBox.Show("กรุณาเลือกไฟล์และโฟลเดอร์ปลายทาง", "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Warning)
- Exit Sub
- End If
- '// ตรวจสอบว่า Source กับ Destination เป็นโฟลเดอร์เดียวกันหรือไม่
- Dim sourceFile As String = txtFile.Text.Trim
- Dim destFolder As String = txtFolder.Text.Trim
- Try
- Dim sourceFolder As String = Path.GetDirectoryName(sourceFile)
- '// เปรียบเทียบแบบ Case-Insensitive และตัด \ ท้ายออกก่อนเทียบ
- If String.Equals(sourceFolder.TrimEnd(""c), destFolder.TrimEnd(""c), StringComparison.OrdinalIgnoreCase) Then
- MessageBox.Show("ไม่สามารถเลือกโฟลเดอร์ปลายทางที่ตรงกับโฟลเดอร์ของไฟล์ต้นทางได้", "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Exit Sub
- End If
- Catch ex As Exception
- MessageBox.Show("เกิดข้อผิดพลาดในการตรวจสอบโฟลเดอร์: " & ex.Message, "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Exit Sub
- End Try
- Me.DialogResult = DialogResult.OK
- Me.Close()
- End Sub
- Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
- Me.DialogResult = DialogResult.Cancel
- Me.Close()
- End Sub
- Private Sub frmSelectFileFolder_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
- Me.Height = 195
- Me.MinimumSize = New Size(Me.Width, 195)
- End Sub
- Private Sub frmSelectFileFolder_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
- '// ถ้าความสูงไม่เท่ากับค่าที่ต้องการปรับกลับทันที เพื่อไม่ให้ความสูงของฟอร์มเกินที่กำหนด
- If Me.Height <> 195 Then Me.Height = 195
- End Sub
- Private Sub txtFile_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtFile.KeyPress
- e.Handled = True
- End Sub
- Private Sub txtFolder_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtFolder.KeyPress
- e.Handled = True
- End Sub
- End Class
คัดลอกไปที่คลิปบอร์ด
โค้ดในการจัดเรียงข้อมูลบนตัว ListView Control ... ListViewItemComparer.vb
- '// คลาสสำหรับจัดเรียงข้อมูลจากการคลิ๊กเมาส์ที่ส่วนหัวหรือหลักของ ListView
- Public Class ListViewItemComparer
- Implements IComparer
- Private col As Integer
- Private order As SortOrder
- Public Sub New(column As Integer, sortOrder As SortOrder)
- col = column
- order = sortOrder
- End Sub
- Public Function Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
- Dim lviX As ListViewItem = CType(x, ListViewItem)
- Dim lviY As ListViewItem = CType(y, ListViewItem)
- Dim result As Integer = String.Compare(lviX.SubItems(col).Text, lviY.SubItems(col).Text)
- If order = SortOrder.Descending Then result = -result
- Return result
- End Function
- End Class
คัดลอกไปที่คลิปบอร์ด
ดาวน์โหลดโค้ดฉบับเต็ม VB.NET (2010) + .Net Framework 4.0 ได้ที่นี่ ...
|
ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง
คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน
x
|