วันจันทร์ที่ 4 มกราคม พ.ศ. 2553

Drag-and-Drop

Drag-and-Drop

Visual Basic มีความสามารถ drag-and-drop ตั้งแต่เวอร์ชันแรก ๆ แต่ใน Visual Basic 5 ได้เพิ่มกลุ่มของคุณสมบัติ, เมธอด และ event ที่ใช้พัฒนาเครื่องมือสำหรับ OLE มาตรฐานและการ drag-and-drop ข้ามโปรแกรมประยุกต์

Automatic Drag-and-Drop

โดย พื้นฐาน ตัว control สามารถทำงานเป็นต้นทางหรือปลายทางของการ drag-and-drop และมีการทำงานเป็น 2 โหมด คือ automatic หรือ manual ในโหมด automatic การตั้งค่าคุณสมบัติในการออกแบบหรือเรียกใช้และให้ Visual Basic ทำทุกอย่างให้ส่วนโหมด manual เป็นการตอบสนอง event ที่เกิดขึ้นขณะที่มีการ drag ซึ่งทำให้มีการควบคุมกระบวนการที่ดีกว่า

ถ้า ตัว control สนับสนุนการ drag-and-drop แบบอัตโนมัติ ให้ตั้งค่าคุณสมบัติ OLEDragMode หรือ OLEDropMode (หรือทั้ง 2 ค่า) เป็น vbAutomatic เช่น ถ้าต้องการให้โปรแกรมสนับสนุนการ drag-and-drop ข้อความ RTF ให้วาง Rich Text box บนฟอร์ม และตั้งค่าคุณสมบัติ OLEDragMode และ OLEDropMode เป็น vbAutomatic จะทำให้สามารถ drag ข้อความไปที่หรือมาจาก Microsoft Word, WordPad หรือโปรแกรมประมวลผลคำต่าง ๆ ได้ และสามารถ drag-and-drop กับ Rich text box อื่นรวมถึง Text box และ Mask ed box

Manual Drag-and-Drop

การ drag-and-drop แบบจัดการเองหรือ manual ต้องการคำสั่งใน event procedure สำหรับ event ต่าง ๆ ที่เกิดขึ้น ทั้งตัว control ต้นทางและปลายทางตามรูป ได้สรุปการเกิด event ของการ drag-and-drop

ตาม โปรแกรมตัวอย่างที่ ประกอบด้วย Rich text box ซึ่งทำหน้าที่เป็นต้นทางหรือปลายทางของการ drag-and-drop บนฟอร์มมี List box ที่สามารถวางข้อความได้ ทั้งจาก Rich text box หรือแหล่งอื่น ๆ ถ้ามีการวางข้อความใน List box จะมีการตรวจข้อความ ค้นหาคำที่ไม่ซ้ำ เรียงลำดับ และแสดงผลให้ผู้ใช้โดย List box

Initiated การทำงาน Drag-and-Drop

การ ทำให้ตัว control สามารถ Initiate การทำงานดังกล่าวต้องตั้งค่าคุณสมบัติ OLEDragMode เป็น vbManual และเริ่มกระบวนการโดยการกระตุ้นเมธอด OLEDrag ซึ่งมักจะใช้ MouseDown event

Private Sub rtfText_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
' เริ่มต้นการ drag ถ้ามีการกดเมาส์ปุ่มชวา
If Button = 2 Then rtfText.OLEDrag
End Sub

เมื่อ การ drag จากเมธอด OLEDrag จะเกิด OLEStartDrag event ที่ตัว control ต้นทาง ซึ่ง event นี้จะรับอ๊อบเจค DataObject และพารามิเตอร์ AllowedEffects โดยการเก็บข้อมูลในอ๊อบเจคใช้เมธอด SetData

Private Sub rtfText_OLEStartDrag(Data As RichTextLib.DataObject, AllowedEffects As Long)
' ใช้การเลือกข้อความหรือข้อความทั้งหมดถ้าไม่มีการเลือก
If chkLoadOnDemand Then
' แจ้งถึงรูปแบบที่ตัว control สนับสนุน
Data.SetData , vbCFRTF
Data.SetData , vbCFText
ElseIf rtfText.SelLength Then
Data.SetData rtfText.SelRTF, vbCFRTF
Data.SetData rtfText.SelText, vbCFText
Else
Data.SetData rtfText.TextRTF, vbCFRTF
Data.SetData rtfText.text, vbCFText
End If
AllowedEffects = vbDropEffectMove Or vbDropEffectCopy
End Sub

ควร กำหนดค่าให้พารามิเตอร์ AllwedEffects เพื่อระบุผลที่ต้องการให้สนับสนุน การทำงาน drag-and-drop โดยตั้งค่าเป็น 1-vbDropEffectCopy หรือ 2-vbDropEffectMove หรือ รวมทั้งหมดถ้าต้องการสนับสนุนผลทั้งสองแบบ

เตรียมการ Drop ตัว Control ต้นทาง

ระหว่าง การ drag ดำเนินอยู่ Visual Basic จะเกิด OLEDragOver สำหรับตัว control ที่เมาส์อยู่บนตัว control นั้น event นี้รับอ๊อบเจค DataObject และค่า Effect ที่ตั้งโดยตัว control ต้นทาง และสารสนเทศ ตำแหน่งเมาส์และสถานของปุ่ม

Private Sub lstWords_OLEDragOver(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, State As Integer)
' เลือก copy ถ้าทำได้ กรณีอื่นเลือก move
If Not Data.GetFormat(vbCFText) Then
' source ตัว control ต้นทางไม่ส่งออกเป็นรูปแบบ text
Effect = 0
ElseIf Effect And vbDropEffectCopy Then
Effect = vbDropEffectCopy
ElseIf Effect And vbDropEffectMove Then
Effect = vbDropEffectMove
End If
' เปลี่ยนพื้นหลังของ list box เมื่อเมาส์อยู่เหนือ list box
If State = vbLeave Then
' เปลี่ยนกลับเมื่อเมาส์ออกไปแล้ว
lstWords.BackColor = vbWindowBackground
ElseIf Effect <> 0 And State = vbEnter Then
' เปลี่ยนสีพื้นหลังเมื่อ entry
lstWords.BackColor = vbYellow
End If
End Sub

event ที่เกิดต่อจาก OLEDragOver event สำหรับตัว control ต้นทางคือ OLEGiveFeedBack event ซึ่ง event ที่ตัว control ต้นทาง จะรับรู้การเลือก Effect จากตัว control ปลายทางและเปลี่ยนเคอร์เซอร์ของเมาส์

Private Sub lstWords_OLEGiveFeedback(Effect As Long, DefaultCursors As Boolean)
If Effect = vbDropEffectCopy Then
DefaultCursors = False
Screen.MousePointer = vbCustom
Screen.MouseIcon = imgCopy.Picture
Else
DefaultCursors = True
End If
End Sub

พารามิเตอร์ DefaultCursors ควรตั้งค่าเป็น False

การวางข้อมูล

เมื่อ ผู้ใช้ปล่อยปุ่มเมาส์ เหนือตัว control ปลายทาง Visual Basic จะให้เกิด OLEDragDrop event สำหรับตัว control ปลายทาง Event นี้จะรับพารามิเตอร์เหมือนกับ OLEDragOver event

Private Sub lstWords_OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single)
' เปลี่ยนกลับสีพื้นหลังที่ถูกต้อง
lstWords.BackColor = vbWindowBackground
' เลือก copy ถ้าทำได้ กรณีอื่นเลือก move
If Effect And vbDropEffectCopy Then
Effect = vbDropEffectCopy
ElseIf Effect And vbDropEffectMove Then
Effect = vbDropEffectMove
End If
' ขอข้อมูล - เฉพาะการสนับสนุน plain text
Dim text As String, w As Variant
text = Data.GetData(vbCFText)
' เพิ่มช่องว่างท้ายคำเพื่อทำให้มั่นใจว่าคำสุดท้ายได้รับการแยกอย่างถูกต้อง
text = text & " "

' กระจายข้อความและแยกแต่ละคำ
Dim i As Long, start As Long, words As New Collection
On Error Resume Next

For i = 1 To Len(text)
If Mid$(text, i, 1) Like "[!A-Za-z0-9]" Then
If start Then
' เพิ่มคำใน collection แต่ไม่สนใจคำซ้ำ
w = Mid$(text, start, i - start)
words.Add w, w
start = 0
End If
ElseIf start = 0 Then
' ถ้าพบคำใหม่
start = i
End If
Next

' เพิ่มคำทั้งหมดใน list box
lstWords.Clear
For Each w In words
lstWords.AddItem w
Next
End Sub

เมื่อ OLEDragDropevent ได้รับการประมวล Visual Basic จะให้ตัว control ต้นทางเกิด OLECompleteDrag event

Private Sub rtfText_OLECompleteDrag(Effect As Long)
If Effect = vbDropEffectMove Then
' การ move ลบข้อความที่ไฮไลต์
rtfText.SelText = ""
Else
' การ copy ยกเลิกการเลือก clear the selection
rtfText.SelLength = 0
End If
End Sub

การโหลดข้อมูลตามคำสั่ง

ถ้า ตัว control ต้นทางสนับสนุนข้อมูลหลายรูปแบบ การโหลดข้อมูลไปที่อ๊อบเจค Data ใน OLEStartDrag ไม่ใช่วิธีการที่มีประสิทธิภาพ แต่ Visual Basic สนับสนุนวิธีการอื่น โดยใช้ OLESetData event และเปลี่ยนจากการโหลดข้อมูลให้อ๊อบเจค DataObject เมื่อมีการ drag เป็นการระบุรูปแบบที่สนับสนุน

Private Sub rtfText_OLEStartDrag(Data As RichTextLib.DataObject, AllowedEffects As Long)
' ใช้การเลือกข้อความหรือข้อความทั้งหมดถ้าไม่มีการเลือก
If chkLoadOnDemand Then
' แจ้งถึงรูปแบบที่ตัว control สนับสนุน
Data.SetData , vbCFRTF
Data.SetData , vbCFText
ElseIf rtfText.SelLength Then
Data.SetData rtfText.SelRTF, vbCFRTF
Data.SetData rtfText.SelText, vbCFText
Else
Data.SetData rtfText.TextRTF, vbCFRTF
Data.SetData rtfText.text, vbCFText
End If
AllowedEffects = vbDropEffectMove Or vbDropEffectCopy
End Sub

ถ้า ต้องการ drag-and-drop ไม่ได้ถูกยกเลิก ตัว control ปลายทางจะให้เมธอด GetData รับข้อมูลตามรูปแบบที่กำหนด Visual Basic จะทำให้เกิด OLESetData event สำหรับตัว control ต้นทาง

Private Sub rtfText_OLESetData(Data As RichTextLib.DataObject, DataFormat As Integer)
' event นี้เกิดเฉพาะถ้า chkLoadOnDemand ได้รับการเลือก when
' เมื่อตัว control เป้าหมายใช้ the Data's GetData method
If DataFormat = vbCFText Then
If rtfText.SelLength Then
Data.SetData rtfText.SelText, vbCFText
Else
Data.SetData rtfText.text, vbCFText
End If
ElseIf DataFormat = vbCFRTF Then
If rtfText.SelLength Then
Data.SetData rtfText.SelRTF, vbCFRTF
Else
Data.SetData rtfText.TextRTF, vbCFRTF
End If
End If

End Sub

ดาวน์โหลดตัวอย่าง (DropWord.vbp)

ไม่มีความคิดเห็น:

แสดงความคิดเห็น