Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any _
) As Long
' อธิบายฟังค์ชั่น SendMessage
' hWnd คือ วัตถุ (Object) หรือ Control ที่เราต้องการติดต่อกับมัน ในที่นี้คือ ComboBox
' wMsg คือ สิ่งที่ส่งไปบอกวัตถุว่าจะให้มันทำอะไร ในที่นี้คือการค้นหา โดยการกำหนดค่าคงที่ให้คือ 14C (ฐาน 16)
' wParam และ lParam คือ พารามิเตอร์เสริมเข้าไป ซึ่งมีหน้าที่ และ ความหมายแตกต่างกันไปใน Message แต่ละชนิด
' พารามิเตอร์ทั้งสองตัวนี้หากไม่ได้ใช้งาน ต้องกำหนดค่า 0 ไว้ด้วย
' กรณีการค้นหา lParam คือ ค่าที่ส่งไปให้กับ ComboBox ในที่นี้คือ ค่าจาก StrKey
' ตัวอย่างการใช้งาน SendMessage(Combo1.hWnd, CB_FINDSTRING, -1, ByVal StrKey)
' hWnd ก็คือติดต่อกับ ComboBox Control (Combo1.hWnd)
' wMsg ก็คือการค้นหาคีย์ที่กดใน ComboBox (CB_FINDSTRING)
' wParam กำหนดค่า (-1) คือการค้นหาคีย์ที่พบจากบนสุด
' lParam คือคีย์ที่ต้องการค้นหานั่นเอง (StrKey)
' ประกาศตัวแปรค่าคงที่ (Constants) ... ตัดมาจาก Win32 API ได้เลย
' CB คือ ComboBox หรือหากเป็น ListBox ชื่อตัวแปรก็จะขึ้นต้นด้วย LB หรือ TextBox ก็จะใช้ TB เป็นต้น
Private Const CB_FINDSTRING = &H14C
Private Const CB_ERR = (-1)
' ประกาศตัวแปรสำหรับการเชื่อมต่อไฟล์ฐานข้อมูล และ ตารางข้อมูล
Dim ConnDB As ADODB.Connection
Dim RS As ADODB.Recordset
Private Sub Form_Load()
' ติดต่อกับไฟล์ฐานข้อมูล - MS Access
Set ConnDB = CreateObject("ADODB.Connection")
ConnDB.Provider = "Microsoft.Jet.OLEDB.4.0"
ConnDB.Open App.Path & "\MyDB.mdb"
Set RS = New ADODB.Recordset
RS.Open "Select ProvinceName FROM tblProvince ORDER BY ProvinceName ", _
ConnDB, adOpenForwardOnly, adLockReadOnly, adCmdText
Combo1.Clear
' ตัวอย่างการนำข้อมูลจากตารางรายชื่อจังหวัดมาแสดงผลใน ComboBox
Do Until RS.EOF
Combo1.AddItem RS("ProvinceName")
RS.MoveNext
Loop
RS.Close: Set RS = Nothing
' ตั้งค่าแสดงผลข้อมูลที่รายการแรกของ ComboBox
If Combo1.ListCount > 0 Then Combo1.ListIndex = 0
End Sub
' #########################################################
' เหตุการณ์รับค่าการกดคีย์ใดๆเข้ามาที่ ComboBox
' #########################################################
Private Sub Combo1_KeyPress(KeyAscii As Integer)
Dim StrKey As String
Dim LenKey As Long
' ตัวแปรนี้จะรับค่าการทดสอบจากฟังค์ชั่น SendMessage
Dim lRet As Long
Combo1.SelText = ""
' รับคีย์ที่กดเข้ามา
StrKey = Combo1.Text & Chr$(KeyAscii)
' หากค้นหาคีย์ที่กดใน ComboBox ไม่พบจะทำให้ค่า lRet = (-1)
' หากค้นหาคีย์ที่กดพบ lRet จะรับค่า Index จาก ComboBox เข้ามาแทน เช่น
' กด "ก" ทำให้ lRet = 1 (กระบี่ ซึ่งจะมีค่า Index = 1)
' กด "ข" ทำให้ lRet = 6 (ขอนแก่น ซึ่งจะมีค่า Index = 6)
' กด "อ" ทำให้ lRet = 70 (อยุธยา ซึ่งจะมีค่า Index = 70)
lRet = SendMessage(Combo1.hWnd, CB_FINDSTRINGG, -1, ByVal StrKey)
' หากพบคีย์ที่กดจะทำให้ lRet <> (-1)
If lRet <> CB_ERR Then
' นับความยาวของคีย์ที่กดเข้ามา
LenKey = Len(StrKey)
' แสดงผลตัวอักษรตัวแรก (หรือตัวต่อไป) ที่กดคีย์แล้วพบ
Combo1.Text = Combo1.List(lRet)
' ให้ชี้ Index ที่ได้
Combo1.ListIndex = lRet
' ลบการกดคีย์เดิมออกไป (เหมือนไม่มีการกดคีย์ใดๆเลย)
KeyAscii = 0
' ทำ HightLight ข้อมูลที่อยู่ใน ComboBox
Combo1.SelStart = LenKey
Combo1.SelLength = Len(Combo1.Text) - LenKey
End If
End Sub
' #########################################################
' เหตุการณ์ที่ไม่ได้มีการ Focus อยู่ที่ Combobox แล้ว
' ตรงนี้นำไปประยุกต์ใช้งานเองด้วยครับ เพราะตัวอย่างนี้ผมมี Control แค่ตัวเดียว
' #########################################################
Private Sub Combo1_LostFocus()
Dim StrKey As String
Dim lRet As Long
' รับค่าข้อมูลที่อยู่ตัวล่าสุดเอาไว้
StrKey = Combo1.Text
' ทดสอบก่อน (CB_FINDSTRING) เพื่อรับค่า Index ของ ComboBox
lRet = SendMessage(Combo1.hWnd, CB_FINDSTRING, -1, ByVal StrKey)
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
' ตรวจสอบว่ามีการเชื่อมโยง - Connect ข้อมูลหรือไม่
If ConnDB.State = adStateOpen Then
ConnDB.Close
Set ConnDB = Nothing
End If
Set frmSearchComboBox = Nothing
End
End Sub
|