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

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

[VB.NET] โค้ดการเปิดหลายๆโฟลเดอร์แบบอัตโนมัติ

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

333

กระทู้

529

โพสต์

7356

เครดิต

ผู้ดูแลระบบ

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

Rank: 9Rank: 9Rank: 9

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


หน้าจอ GUI (Graphics User Interface) สามารถเปิดโฟลเดอร์ได้หลายๆโฟลเดอร์แบบ Manual และ Automatic


การทำ Registry เพื่อสั่งให้รันโปรแกรมตอนที่ Start Windows
Registry: Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

โค้ดโปรแกรมชุดนี้มีจุดประสงค์ก็เพื่อต้องการให้ ทำการเปิดหลายๆโฟลเดอร์ได้ทั้งแบบ Manual (กดปุ่มเปิดเอาเอง) และการเปิดโฟลเดอร์แบบอัตโนมัติ ตอนที่สตาร์ทวินโดวส์เข้ามาทุกครั้ง ซึ่งจะอาศัยการกำหนดค่าใน Registry เอาไว้ โฟลเดอร์ที่ถูกเลือกจะถูกเก็บเอาไว้ใน Config.ini ซึ่งแอดมินจะใช้โค้ด Win32API ในการอ่านและเขียนค่าเข้าไปในไฟล์  INI ...

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

  5. Public Class frmOpenMultipleFolder
  6.     '// กำหนด Icon ให้กับ ListView
  7.     Private imgList As New ImageList()

  8.     '// ไฟล์ Config.ini จะเป็นไฟล์ที่เก็บตำแหน่งของโฟลเดอร์ต่างๆ
  9.     Private iniPath As String = MyPath(Application.StartupPath) & "Config.ini"

  10.     '// สร้าง CheckBox แบบ Run Time เพื่อกำหนดให้รันโปรแกรมตอน Start Windows
  11.     Dim chkStartup As New CheckBox()

  12.     '// การจัดเรียงใน ListView ด้วยการเก็บคอลัมน์ล่าสุดที่กดกับลำดับการเรียง
  13.     Private SortColumn As Integer = -1
  14.     Private SortOrder As SortOrder = SortOrder.None

  15.     '// เพิ่มเติมข้อมูล
  16.     '// Win32 API (Application Programming Interface) คือ ชุดฟังก์ชั่นพื้นฐานที่ Microsoft จัดเตรียมไว้สำหรับนักพัฒนาเพื่อโต้ตอบกับระบบปฏิบัติการ Windows โดยตรง เป็นการทำงานระดับต่ำ (Low-level Access) ดังนั้นมันจึงทำงานได้เร็ว และมีประสิทธิภาพสูง
  17.     '// แปลเป็นไทยง่ายๆว่า การดึงพลังและขีดความสามารถของ Windows ออกมาใช้งานได้อย่างเต็มที่นั่นเอง

  18. #Region "INI API"
  19.     '// --------------------------------------------------------------------------------------
  20.     '// APIs for Read/Write INI File.
  21.     <DllImport("kernel32", CharSet:=CharSet.Unicode)>
  22.     Private Shared Function WritePrivateProfileString(lpAppName As String, lpKeyName As String, lpString As String, lpFileName As String) As Long
  23.     End Function

  24.     <DllImport("kernel32", CharSet:=CharSet.Unicode)>
  25.     Private Shared Function GetPrivateProfileString(lpAppName As String, lpKeyName As String, lpDefault As String,
  26.         lpReturnedString As StringBuilder, nSize As Integer, lpFileName As String) As Integer
  27.     End Function

  28.     Private Sub WriteIni(section As String, key As String, value As String, filePath As String)
  29.         WritePrivateProfileString(section, key, value, filePath)
  30.     End Sub

  31.     Private Function ReadIni(section As String, key As String, defaultValue As String, filePath As String) As String
  32.         Dim sb As New StringBuilder(1024)
  33.         Dim count As Integer = GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, filePath)
  34.         If count > 0 Then
  35.             Return sb.ToString().Trim
  36.         Else
  37.             Return ""
  38.         End If
  39.     End Function
  40. #End Region

  41. #Region "ICON API"
  42.     '// ------------------------------------------------ APIs ดึงไอคอนมาใช้งาน ------------------------------------------------
  43.     <DllImport("shell32.dll", CharSet:=CharSet.Auto)>
  44.     Private Shared Function SHGetFileInfo(pszPath As String, dwFileAttributes As UInteger, ByRef psfi As SHFILEINFO,
  45.                                           cbFileInfo As UInteger, uFlags As UInteger) As IntPtr
  46.     End Function

  47.     <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
  48.     Private Structure SHFILEINFO
  49.         Public hIcon As IntPtr
  50.         Public iIcon As Integer
  51.         Public dwAttributes As UInteger
  52.         <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)>
  53.         Public szDisplayName As String
  54.         <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=80)>
  55.         Public szTypeName As String
  56.     End Structure

  57.     Private Const SHGFI_ICON As UInteger = &H100
  58.     Private Const SHGFI_SMALLICON As UInteger = &H1

  59.     '// ดึงไอคอนโฟลเดอร์
  60.     Private Function GetFolderIcon(path As String) As Icon
  61.         Dim shinfo As New SHFILEINFO()
  62.         SHGetFileInfo(path, 0, shinfo, CUInt(Marshal.SizeOf(shinfo)), SHGFI_ICON Or SHGFI_SMALLICON)
  63.         Return Icon.FromHandle(shinfo.hIcon)
  64.     End Function
  65. #End Region

  66.     '// --------------------------------------------------------------------------------------
  67.     '// S T A R T . . . H E R E
  68.     '// --------------------------------------------------------------------------------------
  69.     Private Sub frmOpenMultipleFolder_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  70.         '// ImageList สำหรับ Icon
  71.         imgList.ImageSize = New Size(18, 22)    '// จะมีผลต่อความสูงของแถวในตัว ListView
  72.         imgList.ColorDepth = ColorDepth.Depth32Bit
  73.         lvwFolder.SmallImageList = imgList

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

  82.         '// โค้ดที่เกี่ยวข้องจะอยู่ที่ Region "LISTVIEW"
  83.         '// TIPS: ใช้เมื่อต้องการการแสดงผลที่พิเศษกว่าเดิม เช่น เปลี่ยนสีแต่ละแถวสลับกัน หรือใส่รูปภาพหรือไอคอนพิเศษ
  84.         lvwFolder.OwnerDraw = True
  85.         '// ตั้งค่าให้กับ ListView
  86.         Call InitializeListView()
  87.         '// โหลดรายการที่เก็บเอาไว้มาจากไฟล์ Config.ini
  88.         Call LoadConfig()

  89.         '// -------------------------------------------- IMPORTANT --------------------------------------------
  90.         '// Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  91.         '// ทดสอบการกำหนดให้ Run ตอน Start Windows
  92.         If IsStartupEnabled() Then
  93.             tsbOpenFolder.PerformClick()    '// สั่งโปรแกรมให้เปิดโฟลเดอร์
  94.             chkStartup.Checked = True
  95.         Else
  96.             chkStartup.Checked = False
  97.         End If
  98.         '// --------------------------------------------------------------
  99.     End Sub

  100.     '// --------------------------------------------------------------------------------------
  101.     '// Add Event Handler เพื่อกำหนดให้โปรแกรมทำงานตอน Start Windows หรือไม่
  102.     '// --------------------------------------------------------------------------------------
  103.     Private Sub chkStartup_CheckedChanged(sender As System.Object, e As System.EventArgs)
  104.         If chkStartUp.Checked Then
  105.             '// Run on Windows Start
  106.             Call SetStartup(True)
  107.         Else
  108.             Call SetStartup(False)
  109.         End If
  110.     End Sub

  111.     '// ============= สร้างค่าใน Registry เพื่อให้รันตอน Startup =============
  112.     '// หาก enable กำหนดเป็น True จะทำการ Registry เพื่อให้โปรแกรม Run ตอน Start Windows
  113.     '// หาก enable กำหนดเป็น False จะทำการลบ Registry ออกไป
  114.     '// Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
  115.     Private Sub SetStartup(enable As Boolean)
  116.         Try
  117.             Using key As RegistryKey = Registry.CurrentUser.OpenSubKey(
  118.                 "Software\Microsoft\Windows\CurrentVersion\Run", True)
  119.                 If key Is Nothing Then
  120.                     MessageBox.Show("ไม่สามารถเข้าถึง Registry ได้", "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
  121.                     Return
  122.                 End If
  123.                 If enable Then
  124.                     key.SetValue("OpenMultipleFolder", Application.ExecutablePath)
  125.                 Else
  126.                     '// ลบค่าออก ถ้าไม่ต้องการให้รันอัตโนมัติ
  127.                     If key.GetValue("OpenMultipleFolder") IsNot Nothing Then key.DeleteValue("OpenMultipleFolder")
  128.                 End If
  129.             End Using
  130.         Catch ex As Exception
  131.             MessageBox.Show("เกิดข้อผิดพลาดในการตั้งค่า Startup: " & ex.Message, "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Error)
  132.         End Try
  133.     End Sub

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

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

  146.                     '// เปรียบเทียบแบบไม่สนใจตัวพิมพ์ใหญ่/เล็ก และตัด quote ออกถ้ามี
  147.                     Dim CleanRegistryPath As String = RegistryPath.Replace("""", "")
  148.                     Return String.Equals(CleanRegistryPath, ProgramPath, StringComparison.OrdinalIgnoreCase)
  149.                 Else
  150.                     Return False
  151.                 End If
  152.             End Using
  153.         Catch ex As Exception
  154.             '// ถ้าเกิดข้อผิดพลาด เช่น สิทธิ์ไม่พอ ถือว่าไม่ได้ตั้งค่า รีเทิร์นค่า False กลับไป
  155.             'MessageBox.Show("Error checking startup: " & ex.Message)
  156.             Return False
  157.         End Try
  158.     End Function

  159.     '// ---------------------- ตั้งค่าเริ่มต้นให้กับ ListView Control ----------------------
  160.     Private Sub InitializeListView()
  161.         With lvwFolder
  162.             .View = View.Details
  163.             .MultiSelect = False
  164.             .HideSelection = False
  165.             .FullRowSelect = True
  166.             .GridLines = True
  167.             .Columns.Clear()
  168.             .Columns.Add("Folder Path", lvwFolder.Width - 5)
  169.         End With
  170.     End Sub

  171.     '// ---------------------- ดับเบิลคลิกที่รายการ ListView เพื่อแก้ไขตำแหน่งเปิดโฟลเดอร์ ----------------------
  172.     Private Sub lvwFolder_DoubleClick(sender As Object, e As EventArgs) Handles lvwFolder.DoubleClick
  173.         '// เรียกไปยังเหตุการณ์คลิ๊กที่ปุ่ม ToolStrip
  174.         tsbEditFolder.PerformClick()
  175.     End Sub

  176.     Private Sub frmOpenMultipleFolder_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
  177.         Me.Dispose()
  178.         GC.SuppressFinalize(Me)
  179.         Application.Exit()
  180.     End Sub

  181. #Region "TOOLBAR EVENTS"
  182.     '// ทุกๆครั้งที่มีการเปลี่ยนแปลงแก้ไขรายการใน ListView จะทำการบันทึกลง Config.ini ทุกครั้ง (SaveConfig)
  183.     '// การเพิ่ม Folder Full Path
  184.     Private Sub tsbAddFolder_Click(sender As Object, e As EventArgs) Handles tsbAddFolder.Click
  185.         Using fbd As New FolderBrowserDialog
  186.             fbd.Description = "เลือกโฟลเดอร์ที่ต้องการ"
  187.             If fbd.ShowDialog() = DialogResult.OK Then
  188.                 AddFolderToListView(fbd.SelectedPath)
  189.                 Call SaveConfig()
  190.             End If
  191.         End Using
  192.     End Sub

  193.     '// แก้ไขตำแหน่ง Folder Full Path
  194.     Private Sub tsbEditFolder_Click(sender As Object, e As EventArgs) Handles tsbEditFolder.Click
  195.         If lvwFolder.SelectedItems.Count = 0 Then
  196.             MessageBox.Show("กรุณาเลือกรายการที่จะแก้ไข", "แก้ไขข้อมูล", MessageBoxButtons.OK, MessageBoxIcon.Information)
  197.             Exit Sub
  198.         End If
  199.         Using fbd As New FolderBrowserDialog
  200.             fbd.Description = "เลือกโฟลเดอร์ที่ต้องการ"
  201.             fbd.SelectedPath = lvwFolder.SelectedItems(0).Text   '// ตั้งค่าเริ่มต้นเป็นโฟลเดอร์เดิม
  202.             If fbd.ShowDialog() = DialogResult.OK Then
  203.                 lvwFolder.SelectedItems(0).Text = fbd.SelectedPath
  204.                 Call SaveConfig()
  205.             End If
  206.         End Using
  207.     End Sub

  208.     '// ลบตำแหน่ง Folder Full Path
  209.     Private Sub tsbRemoveFolder_Click(sender As Object, e As EventArgs) Handles tsbRemoveFolder.Click
  210.         If lvwFolder.SelectedItems.Count = 0 Then
  211.             MessageBox.Show("กรุณาเลือกรายการที่จะลบ", "ลบข้อมูล", MessageBoxButtons.OK, MessageBoxIcon.Information)
  212.             Exit Sub
  213.         End If
  214.         If MessageBox.Show("คุณต้องการลบโฟลเดอร์ที่เลือกใช่หรือไม่?", "ยืนยันการลบ", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then
  215.             lvwFolder.Items.Remove(lvwFolder.SelectedItems(0))
  216.             Call SaveConfig()
  217.         End If
  218.     End Sub

  219.     '// เปิดโฟลเดอร์ขึ้นมาตามรายการแถวใน ListView
  220.     Private Sub tsbOpenFolder_Click(sender As Object, e As EventArgs) Handles tsbOpenFolder.Click
  221.         If lvwFolder.Items.Count = 0 Then
  222.             MessageBox.Show("ไม่มีรายการโฟลเดอร์ให้เปิด", "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Warning)
  223.             Exit Sub
  224.         End If
  225.         For Each itm As ListViewItem In lvwFolder.Items
  226.             If Directory.Exists(itm.Text) Then Process.Start("explorer.exe", itm.Text)
  227.         Next
  228.     End Sub

  229.     Private Sub tsbExit_Click(sender As Object, e As EventArgs) Handles tsbExit.Click
  230.         Me.Close()
  231.     End Sub
  232. #End Region

  233. #Region "CONFIG"
  234.     '// ------------------------------------ โหลดจาก Config.ini ------------------------------------
  235.     Private Sub LoadConfig()
  236.         lvwFolder.Items.Clear()
  237.         imgList.Images.Clear()
  238.         Dim idx As Integer = 1
  239.         Do
  240.             Dim folder As String = ReadIni("Folder", "Path" & idx, vbNullString, iniPath).Replace("""", "")
  241.             If String.IsNullOrEmpty(folder) OrElse folder = "" Then Exit Do
  242.             AddFolderToListView(folder)
  243.             idx += 1
  244.         Loop
  245.     End Sub

  246.     '// ------------------------------------ บันทึกลง Config.ini ------------------------------------
  247.     Private Sub SaveConfig()
  248.         '// ล้างค่าทั้ง Section [Folder] ของเดิมทิ้งออกไปก่อน
  249.         WriteIni("Folder", Nothing, Nothing, iniPath)
  250.         Dim idx As Integer = 1
  251.         For Each item As ListViewItem In lvwFolder.Items
  252.             WriteIni("Folder", "Path" & idx, item.Text, iniPath)
  253.             idx += 1
  254.         Next
  255.     End Sub
  256. #End Region

  257. #Region "HELPER"

  258.     '// เพิ่มรายการ Folder Full Path เข้าไปใน ListView
  259.     Private Sub AddFolderToListView(folderPath As String)
  260.         Dim key As String = AddIconToImageList(folderPath)
  261.         Dim item As New ListViewItem(folderPath, key)
  262.         lvwFolder.Items.Add(item)
  263.     End Sub

  264.     '// ใส่ไอคอนโฟลเดอร์ไว้ก่อนตำแหน่ง Path
  265.     Private Function AddIconToImageList(folderPath As String) As String
  266.         Dim key As String = folderPath.ToLower()
  267.         If Not imgList.Images.ContainsKey(key) Then
  268.             Try
  269.                 Dim ico As Icon = GetFolderIcon(folderPath)
  270.                 imgList.Images.Add(key, ico)
  271.             Catch ex As Exception
  272.                 '// ถ้า error ให้ใส่ icon ว่าง
  273.                 imgList.Images.Add(key, SystemIcons.WinLogo)
  274.             End Try
  275.         End If
  276.         Return key
  277.     End Function
  278. #End Region

  279. #Region "LISTVIEW"
  280.     '// เมื่อคลิ๊กส่วนหัว (Column) ของ ListView จะทำการจัดเรียงข้อมูลไอเทม ListView
  281.     Private Sub lvwFolder_ColumnClick(sender As Object, e As ColumnClickEventArgs) Handles lvwFolder.ColumnClick
  282.         '// ถ้ากดซ้ำที่คอลัมน์เดิมสลับ ASC/DESC การจัดเรียงจากน้อยไปมาก หรือ มากไปน้อย
  283.         If e.Column = SortColumn Then
  284.             If SortOrder = SortOrder.Ascending Then
  285.                 SortOrder = SortOrder.Descending
  286.             Else
  287.                 SortOrder = SortOrder.Ascending
  288.             End If
  289.         Else
  290.             SortColumn = e.Column
  291.             SortOrder = SortOrder.Ascending
  292.         End If
  293.         '// เรียกไปยังคลาส ListViewItemComparer
  294.         lvwFolder.ListViewItemSorter = New ListViewItemComparer(e.Column, SortOrder)
  295.         lvwFolder.Sort()
  296.         '// บันทึกข้อมูลลง INI
  297.         Call SaveConfig()
  298.     End Sub

  299.     '// --------------------------------------------------------------------------------------
  300.     '// TIPS: การปรับฟอนต์ในส่วนของ Column Header ของ ListView Control
  301.     '// วาด Column Header
  302.     '// --------------------------------------------------------------------------------------
  303.     Private Sub lvwFolder_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles lvwFolder.DrawColumnHeader
  304.         Using HeaderFont As New Font("Tahoma", 10, FontStyle.Bold)
  305.             e.Graphics.FillRectangle(SystemBrushes.ControlDark, e.Bounds)
  306.             TextRenderer.DrawText(e.Graphics, e.Header.Text, HeaderFont, e.Bounds, Color.White, TextFormatFlags.VerticalCenter Or TextFormatFlags.VerticalCenter)
  307.         End Using
  308.     End Sub

  309.     '// วาด Item
  310.     Private Sub lvwFolder_DrawItem(sender As Object, e As DrawListViewItemEventArgs) Handles lvwFolder.DrawItem
  311.         e.DrawDefault = True
  312.     End Sub

  313.     '// วาด SubItem
  314.     Private Sub lvwFolder_DrawSubItem(sender As Object, e As DrawListViewSubItemEventArgs) Handles lvwFolder.DrawSubItem
  315.         e.DrawDefault = True
  316.     End Sub

  317. #End Region

  318. #Region "FUNCTION"
  319.     Function MyPath(ByVal AppPath As String) As String
  320.         Dim p = AppPath.ToLower().Replace("\bin\debug", "").Replace("\bin\release", "").Replace("\bin\x86\debug", "").Replace("\bin\x86\release", "")
  321.         '// Chr(92) คือ ASCII Code ของเครื่องหมาย Back Slash
  322.         If Not p.EndsWith(Chr(92)) Then p &= Chr(92)
  323.         Return p
  324.     End Function
  325. #End Region

  326. 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-3 04:54 , Processed in 0.091135 second(s), 5 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

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