• Vui lòng đọc nội qui diễn đàn để tránh bị xóa bài viết
  • Tìm kiếm trước khi đặt câu hỏi

Tìm hWnd với SendMessage

Các thủ thuật về hệ thống, thư mục, tập tin và mạng
User avatar
truongphu
VIP
VIP
Posts: 4766
Joined: Sun 04/11/2007 10:57 am
Location: Cam Đức, Khánh hòa
Has thanked: 14 times
Been thanked: 519 times

Tìm hWnd với SendMessage

Postby truongphu » Wed 12/08/2009 8:25 am

Thủ thuật: Tìm hWnd với SendMessage
Tác giả: truongphu
Mô tả: Bài viết nầy trình bày cách tìm hWnd mới: có 2 vấn đề mới lạ và độc đáo (nhất thế giới)!
1- Chỉ dựa trên hàm API SendMessage:
Thông thường chúng ta hay tìm hWnd của cửa sổ với FindWindow (chỉ tìm W-cha) và FindWindowEx (W-con) mà các đối số của 2 hàm khá phức tạp, nhất là hàm FindWindowEx.
Thực chất khi chạy hàm FindWindow hay FindWindowEx thì chúng cũng phải dò tìm (vòng lặp) các cửa sổ cho đến khi gặp điều kiện thích hợp hoặc duyệt hết các cửa sổ...
Dùng SendMessage ta cũng chủ động động dò tìm các cửa sổ trùng Window Title, không quan tâm đến khai báo ClassName.

2- Chỉ dùng số hWnd nhỏ: (tôi đã có trao đổi với NoBi vấn đề nầy)
Một cửa sổ có 2 số hWnd, số hWnd lớn thì các hàm FindWindow và FindWindowEx "chuyên trị"
Ngoài ra cửa sổ ấy còn có số hWnd nhỏ (<1000) từ trước đến giờ chưa ai dùng đến.
Số hWnd nhỏ nầy vẫn có tất cả đặc tính biểu trưng như số hWnd lớn, ta có thể gởi các thông điệp đến hWnd nhỏ để thực thi tác vụ mong muốn...



* Sau đây là Code:

Code: Select all

  1. 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
  2. '---------------------
  3. Const WM_GETTEXTLENGTH = &HE:  Const WM_GETTEXT = &HD: Const WM_CLOSE = &H10
  4. Const WM_KEYDOWN = &H100: Const VK_RETURN = &HD: Const WM_KEYUP = &H101
  5. Const MK_LBUTTON = &H1: Const WM_LBUTTONDOWN = &H201: Const WM_LBUTTONUP = &H202
  6. Dim i&
  7.  
  8. Public Function WinGetText(hwnd As Long) As String
  9. On Error Resume Next
  10.     Dim Length&, result&, strtmp$, S As Variant
  11.     Length& = SendMessage(hwnd, WM_GETTEXTLENGTH, ByVal 0, ByVal 0) + 1
  12.     strtmp$ = Space$(Length)
  13.     result& = SendMessage(hwnd, WM_GETTEXT, ByVal Length, ByVal strtmp)
  14.     S = Split(strtmp, vbNullChar)
  15.     WinGetText$ = S(0)
  16. End Function
  17.  
  18. Private Sub Command1_Click()
  19. If TextBox1 = "" Then Exit Sub
  20.     For i& = 0 To 1000
  21.         If UCase(WinGetText(i&)) = UCase(TextBox1.Text) Then
  22.             Exit For
  23.         End If
  24.     Next
  25.     If i = 1001 Then Me.Caption = 0 Else Me.Caption = i
  26. End Sub
  27.  
  28. Private Sub Command2_Click()
  29. SendMessage i, WM_CLOSE, 0, 0
  30. End Sub
  31.  
  32. Private Sub Command3_Click()
  33. SendMessage i, WM_KEYDOWN, VK_RETURN, 0
  34. SendMessage i, WM_KEYUP, VK_RETURN, 0
  35. End Sub
  36.  
  37. Private Sub Form_Load()
  38. Shell "calc"
  39. End Sub

* Ứng dụng:
- Khi chạy Project trên, Calculator được gọi thêm cho tiện
Bạn chỉ việc nhấn nút "Find hWnd" sẽ hiện số hWnd của Calculator lên Form1.caption; Nhấn nút "SendMessage WM_CLOSE" để đóng Calculator
- Bạn gõ 'start' vào textbox, nhấn "Find hWnd", sẽ tìm hWnd của nút Start góc trái dưới màn hình, nhấn "SendMessage Enter" để mở Menu Start
- Gọi lại Calculator, gõ 'pi' vào textbox, nhấn "Find hWnd" rồi "SendMessage WM_CLOSE" để làm biến mất nút 'pi' trên Calculator...
Attachments
Du`ng SendMessage Ðê tìm hWnd.rar
(1.88 KiB) Downloaded 578 times


o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

User avatar
alexanderdna
Guru
Guru
Posts: 214
Joined: Tue 14/07/2009 11:13 am
Location: Sài Gòn
Has thanked: 3 times
Been thanked: 15 times

Re: Tìm hWnd với SendMessage

Postby alexanderdna » Wed 12/08/2009 9:18 am

Chào bác Phú. Quả thực điều bác đề cập rất mới mẻ và lý thú.
Alex muốn hỏi vài chỗ:
1. Vì sao phải dùng vòng lặp đối với FindWindow(Ex)? Vì với hai tham số lpClassName (tên lớp cửa sổ) và lpWindowName (tiêu đề cửa sổ) là đã có thể tìm ra. Nếu một trong hai tham số ta chưa biết thì ta điền vào là vbNullString.
2. Alex chạy thử chương trình mẫu với tiêu đề "Calculator" cho sẵn thì chương trình và cả IDE bị đứng, có lẽ do vòng lặp thực hiện hàm WinGetText hơi phức tạp chăng, Alex không chắc. Tuy nhiên, nếu dùng tiêu đề "start" thì chương trình tìm được. Bác thử kiểm tra lại coi sao.

User avatar
truongphu
VIP
VIP
Posts: 4766
Joined: Sun 04/11/2007 10:57 am
Location: Cam Đức, Khánh hòa
Has thanked: 14 times
Been thanked: 519 times

Re: Tìm hWnd với SendMessage

Postby truongphu » Wed 12/08/2009 9:58 am

alexanderdna wrote:1. Vì sao phải dùng vòng lặp đối với FindWindow(Ex)?

Tôi đâu có nói phải dùng vòng lặp! tôi chỉ nói là "Thực chất khi chạy hàm FindWindow hay FindWindowEx thì chúng cũng phải dò tìm (vòng lặp)". Nếu chúng không dò, làm sao mà biết hWnd đích xác trong mớ windows hổn độn?

alexanderdna wrote:Alex chạy thử chương trình mẫu với tiêu đề "Calculator" cho sẵn thì chương trình và cả IDE bị đứng

Tôi chạy nhiều lần, rất êm: Xem code thì chỉ chạy vòng 1000 có là bao? Hơn nữa đã có code: On Error Resume Next... Mà Calculator lại là tiêu đề của cửa sổ (cha), rất dễ tìm... Trường hợp Alex báo quả khó hiểu nghen
alexanderdna wrote:Tuy nhiên, nếu dùng tiêu đề "start" thì chương trình tìm được. Bác thử kiểm tra lại coi sao.

Thế là êm rồi, nhờ Alex test lại với: untitled - notepad, freecell ..vv
Tôi test êm lắm!
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

User avatar
alexanderdna
Guru
Guru
Posts: 214
Joined: Tue 14/07/2009 11:13 am
Location: Sài Gòn
Has thanked: 3 times
Been thanked: 15 times

Re: Tìm hWnd với SendMessage

Postby alexanderdna » Wed 12/08/2009 10:15 am

1. Con xin lỗi bác, con nhìn lầm "chúng" thành "chúng ta"!
2. Con đã kiểm tra lại, vẫn chỉ có start là êm, các chương trình khác đều gây dứng. Nếu không tìm ra thì phải báo 0, đằng này không báo 0, nghĩa là không đến được dòng lệnh đó, nên con nghĩ có vấn đề ở vòng lặp hoặc ở hàm WinGetText.

User avatar
thuongall
Quản trị
Quản trị
Posts: 456
Joined: Wed 26/01/2005 8:05 am
Location: Quê hương Đồng Khởi
Been thanked: 9 times
Contact:

Re: Tìm hWnd với SendMessage

Postby thuongall » Wed 12/08/2009 10:37 am

Thanks bác Phú, đề tài rất hay.
Tuy nhiên, nếu gọi tìm hWnd với SendMessage thì chưa hợp lý lắm bởi vì thực chất là tìm dựa vào tiêu đề của cửa sổ (mà lấy tiêu đề của cửa sổ lại dựa vào hWnd). Có thể gọi đây là sử dụng chỉ số hWnd thấp?
truongphu wrote:Tôi đâu có nói phải dùng vòng lặp! tôi chỉ nói là "Thực chất khi chạy hàm FindWindow hay FindWindowEx thì chúng cũng phải dò tìm (vòng lặp)". Nếu chúng không dò, làm sao mà biết hWnd đích xác trong mớ windows hổn độn?

Cách tìm này cũng dùng vòng lặp, có điều biết trước số vòng lặp là <= 1001, còn FindWindow hay FindWindowEx chưa biết dùng bao nhiêu vòng lặp và nếu cung cấp các thông số như classname, title, hWnd cha... thì liệu nó có dùng ít vòng lặp và nhanh hơn chăng (cung cấp càng nhiều thông tin thì tìm càng nhanh)?
Một điều cần quan tâm nữa là con số từ 0 đến 1000, liệu nó có đủ sức để dành chỗ khi hệ thống chạy quá nhiều ứng dụng? Và tại sao người ta thường dùng chỉ số hWnd cao (>60000), hay là chưa phát hiện ra?

User avatar
truongphu
VIP
VIP
Posts: 4766
Joined: Sun 04/11/2007 10:57 am
Location: Cam Đức, Khánh hòa
Has thanked: 14 times
Been thanked: 519 times

Re: Tìm hWnd với SendMessage

Postby truongphu » Wed 12/08/2009 6:35 pm

thuongall wrote:thực chất là tìm dựa vào tiêu đề của cửa sổ (mà lấy tiêu đề của cửa sổ lại dựa vào hWnd). Có thể gọi đây là sử dụng chỉ số hWnd thấp?

Nếu lấy tiêu đề bài viết là chỉ số hWnd thấp thì lạ quá!
Thôi thì xem như tôi nêu vấn đề vậy

thuongall wrote:Một điều cần quan tâm nữa là con số từ 0 đến 1000, liệu nó có đủ sức để dành chỗ khi hệ thống chạy quá nhiều ứng dụng? Và tại sao người ta thường dùng chỉ số hWnd cao (>60000), hay là chưa phát hiện ra?


Tôi có test thử tìm toàn bộ hWnd với vòng lặp 1000, chỉ được non 100 hWnd
Thử vòng lặp 1000000 (hơi lâu) thì nhiều cửa sổ lặp lại. Hình như có cửa sổ mới
Attachments
Toàn Bô HWnd1.rar
(1.81 KiB) Downloaded 354 times
o0o--truongphu--o0o

.........
Ghé thăm:
Chuyện Linh Tinh

User avatar
andylam1992
Thành viên danh dự
Thành viên danh dự
Posts: 380
Joined: Mon 06/04/2009 12:57 pm
Location: TP.HCM Q5
Has thanked: 2 times
Been thanked: 4 times
Contact:

Re: Tìm hWnd với SendMessage

Postby andylam1992 » Wed 12/08/2009 9:45 pm

Vậy cho con hỏi nếu lấy được hwnd của none-client thì mình có thể dùng setwinlong để làm cho vùng none- client có hiệu ứng alpha như win7 ko Bác Phú!

不相信未作牺牲竟先可拥有
只相信是靠双手找到我欲求
Cần - Kiệm- Liêm(liêm kiết) - Nghĩa - Chí - Tín


Return to “[VB] Hệ thống - Tập tin - Thư mục và Mạng”

Who is online

Users browsing this forum: No registered users and 1 guest