Sebelum kita melanjutkan pembahasan ada beberapa istilah yang harus kita ketahui yaitu Parent Window (Window Induk), Child Window (Window Anak) dan bagaimana cara mendapatkan nilai Handle Window (hWnd) atau dengan istilah yang lebih sederhana Process ID.
Setiap aplikasi yang berjalan di Windows umumnya memiliki jendela atau form. Jika ada beberapa jendela/form aplikasi berbeda yang terbuka, maka sistem akan memberikan semacam identitas bagi setiap jendela yang terbuka tersebut, di mana masing-masing jendela/form memiliki identitas atau alamat yang berbeda satu sama lain.
Konsep Child-Parent sangat sederhana, karena pengertian yang diberikan sama persis dengan namanya. Child/anak merupakan sebuah handle window yang berada di dalam handle window lainnya yang biasa disebut parent/induk. Oke kita lihat contoh berikut :
Dengan cara yang sama lakukan terhadap YM dan menghasilkan gambar berikut :
Nah yang jadi pertanyaan bagaimana caranya untuk mendapatkan nilai Handle, Caption dan Class dan yang terpenting disini adalah nilai Class. Ada banyak tool yang bisa digunakan salah satunya adalah Spy++, merupakan tool bawaan visual studio 6.
Oke kita langsung saja menjalankan program Spy++, lihat gambar :
Selanjutnya Anda tinggal drag icon ke aplikasi YM, lihat gambar :
Nah sampe disini analisis sudah selesai dan kita sudah mendapatkan semua informasi yang dibutuhkan, yaitu urutan windows parent<-anak :
YSearchMenuWndClass <- IMClass <- YHTMLContainer <- Internet Explorer_Server
YSearchMenuWndClass <- IMClass <- YIMInputWindow
Perlu diketahui bahwal class/window Internet Explorer_Server dan YIMInputWindow bukan class terluar, sehingga kita perlu mengetahui class diatasnya. Jadi untuk membaca pesan yang masuk, urutan class yang harus kita lalui adalah :
YSearchMenuWndClass -> IMClass -> YHTMLContainer -> Internet Explorer_Server
Sedangkan untuk membalas pesan yang masuk, urutan kelas yang harus kita lalui adalah :
YSearchMenuWndClass -> IMClass -> YIMInputWindow
Untuk memanipulasi class/window diatas kita membutuhkan windows handle/process id dari class tersebut, bagi yang sudah terbiasa menggunakan fungsi-fungsi API kemungkinan sudah tau fungsi API apa saja yang kita butuhkan. Jika masih bingung apa itu fungsi API, coba mampir ke sini.
Yaph benar udah taukan fungsi API yang kita gunakan untuk mendapatkan windows handle/process id :
1. FindWindow -> untuk mendapatkan process id induk class (YSearchMenuWndClass)
2. FindWindowEx -> untuk mendapatkan process id sub class (IMClass, YHTMLContainer, Internet Explorer_Server dan YIMInputWindow)
berikut deklarasi lengkapnya :
12
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Oke berikutnya adalah bagian coding lengkap, bagaimana cara mengambil informasi yang ada di window Internet Explorer_Server dan mengirim pesan melalui window YIMInputWindow dan jangan lupa tambahkan references Microsoft HTML Object Library di project Anda.
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
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
Private Declare Function ObjectFromLresult Lib "oleacc" (ByVal lResult As Long, riid As UUID, ByVal wParam As Long, ppvObject As Any) As Long
Private Declare Function SendMessageTimeout Lib "user32" Alias "SendMessageTimeoutA" (ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As Any, ByVal fuFlags As Long, ByVal uTimeout As Long, lpdwResult As Long) As Long
Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long
Type UUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Const SMTO_ABORTIFHUNG = &H2
Private Const WM_SETTEXT = &HC
Private Const WM_KEYDOWN = &H100
Private Const VK_RETURN = &HD
Dim hwndYMMainClass As Long
Dim hwndIMClass As Long
Private Function IEDOMFromhWnd(ByVal hWnd As Long) As IHTMLDocument
Dim IID_IHTMLDocument As UUID
Dim doc As IHTMLDocument2
Dim lres As Long 'if = 0 isn't inet window.
Dim lMsg As Long
Dim hr As Long
'---END-DECLARES---------
lMsg = RegisterWindowMessage("WM_HTML_GETOBJECT") 'Register Wnd Message
Call SendMessageTimeout(hWnd, lMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, lres) 'Get's Object
'---CHECKS-FOR-WINDOW----
hr = ObjectFromLresult(lres, IID_IHTMLDocument, 0, IEDOMFromhWnd)
End Function
Private Function getIEText(ByVal hWnd As Long) As String
Dim doc As IHTMLDocument2
'On Error Resume Next
If hWnd <> 0 Then
Set doc = IEDOMFromhWnd(hWnd)
Else
getIEText = "-[TEXT CANNOT BE FOUND]-"
Exit Function
End If
'---CHECKS-FOR-HWND------
If doc.body.innerText = vbNullString Then
getIEText = "ERROR! [WINDOW DOESN'T CONTAIN HTML]"
Exit Function
End If
'---CHECKS-FOR-HTML-EMBEDDED
getIEText = doc.body.innerText
End Function
Private Sub cmdCetakPesan_Click()
Dim hwndYHTMLContainer As Long
Dim hwndIEServer As Long
Dim pesan As String
hwndYMMainClass = FindWindow("YSearchMenuWndClass", vbNullString)
If hwndYMMainClass <> 0 Then
hwndIMClass = FindWindowEx(hwndYMMainClass, 0&, "IMClass", vbNullString)
hwndYHTMLContainer = FindWindowEx(hwndIMClass, 0&, "YHTMLContainer", vbNullString)
hwndIEServer = FindWindowEx(hwndYHTMLContainer, 0&, "Internet Explorer_Server", vbNullString)
pesan = getIEText(hwndIEServer) 'informasi pesan disini masih kurang bagus jadi harus di parsing lagi
Debug.Print pesan
End If
End Sub
Private Sub cmdKirimPesan_Click()
Dim hwndYIMInputWindow As Long
Dim hwndButton As Long
hwndYMMainClass = FindWindow("YSearchMenuWndClass", vbNullString)
hwndIMClass = FindWindowEx(hwndYMMainClass, 0&, "IMClass", vbNullString)
hwndYIMInputWindow = FindWindowEx(hwndIMClass, 0&, "YIMInputWindow", vbNullString)
Call SendMessageByString(hwndYIMInputWindow, WM_SETTEXT, 0&, "Isi pesannya disini...")
Call SendMessage(hwndYIMInputWindow, WM_KEYDOWN, VK_RETURN, 0&)
End Sub
Yaph mungkin itu saja penjelasan singkat untuk membuat mesin penjawab otomatis YM! untuk uji coba ini saya menggunakan YM! versi 8.1.0.421 bagi yang akan mencoba di versi 9 sudah saya cek ada sedikit perbedaan nama class/window, yang penting caranya sama seperti diatas tinggal sesuaikan saja.
Bagian terakhir dari artikel ini bisa Anda ikuti disini.