• 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
Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4763
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 518 time

Tìm hWnd với SendMessage

Gửi bàigửi bởi truongphu » T.Tư 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:

Mã: Chọn hết

  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...
Tập tin đính kèm
Du`ng SendMessage Ðê tìm hWnd.rar
(1.88 KiB) Đã tải 573 lần


o0o--truongphu--o0o

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

Hình đại diện của người dùng
alexanderdna
Guru
Guru
Bài viết: 214
Ngày tham gia: T.Ba 14/07/2009 11:13 am
Đến từ: Sài Gòn
Has thanked: 3 time
Been thanked: 15 time

Re: Tìm hWnd với SendMessage

Gửi bàigửi bởi alexanderdna » T.Tư 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.

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4763
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 518 time

Re: Tìm hWnd với SendMessage

Gửi bàigửi bởi truongphu » T.Tư 12/08/2009 9:58 am

alexanderdna đã viết: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 đã viết: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 đã viết: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

Hình đại diện của người dùng
alexanderdna
Guru
Guru
Bài viết: 214
Ngày tham gia: T.Ba 14/07/2009 11:13 am
Đến từ: Sài Gòn
Has thanked: 3 time
Been thanked: 15 time

Re: Tìm hWnd với SendMessage

Gửi bàigửi bởi alexanderdna » T.Tư 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.

Hình đại diện của người dùng
thuongall
Quản trị
Quản trị
Bài viết: 455
Ngày tham gia: T.Tư 26/01/2005 8:05 am
Đến từ: Quê hương Đồng Khởi
Been thanked: 9 time
Liên hệ:

Re: Tìm hWnd với SendMessage

Gửi bàigửi bởi thuongall » T.Tư 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 đã viết: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?

Hình đại diện của người dùng
truongphu
VIP
VIP
Bài viết: 4763
Ngày tham gia: CN 04/11/2007 10:57 am
Đến từ: Cam Đức, Khánh hòa
Has thanked: 14 time
Been thanked: 518 time

Re: Tìm hWnd với SendMessage

Gửi bàigửi bởi truongphu » T.Tư 12/08/2009 6:35 pm

thuongall đã viết: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 đã viết: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
Tập tin đính kèm
Toàn Bô HWnd1.rar
(1.81 KiB) Đã tải 349 lần
o0o--truongphu--o0o

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

Hình đại diện của người dùng
andylam1992
Thành viên danh dự
Thành viên danh dự
Bài viết: 380
Ngày tham gia: T.Hai 06/04/2009 12:57 pm
Đến từ: TP.HCM Q5
Has thanked: 2 time
Been thanked: 4 time
Liên hệ:

Re: Tìm hWnd với SendMessage

Gửi bàigửi bởi andylam1992 » T.Tư 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


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

Đang trực tuyến

Đang xem chuyên mục này: Không có thành viên nào trực tuyến.0 khách