Lộ trình thông điệp Hệ thống sử dụng hai phương thức để chuyển thông điệp đến thủ tục cửa sổ : chuyển thông điệp đến một hàng đợi, chuyển thông điệp trực tiếp tới thủ tục cửa sổ.. Hệ th
Trang 1KHOA CÔNG NGHỆ THÔNG TIN
BỘ MÔN MẠNG VÀ TRUYỀN THÔNG
Trang 3MỤC LỤC
TỔNG QUAN VỀ ĐỀ TÀI 5
Chương 1 CƠ SỞ LÝ THUYẾT 6
I Giới thiệu 6
II Thông Điệp và HÀNG ĐỢI THÔNG ĐIỆP CỦA WINDOWS 6
II.1 Giới thiệu 6
II.1.1 Thông điệp windows 6
II.1.2 Loại Thông điệp 7
II.1.3 Lộ trình thông điệp 10
II.1.4 Xử lý thông điệp 12
II.1.5 Lọc thông điệp 16
II.1.6 Đăng và chuyển thông điệp 16
II.1.7 Bế tắc thông điệp 18
II.1.8 Thông điệp quảng bá 19
II.1.9 Truy vấn thông điệp 20
II.2 Sử dụng thông điệp và hàng đợi thông điệp 21
II.2.1 Tạo vòng lặp thông điệp 21
II.2.2 Kiểm tra một hàng đợi thông điệp 24
II.2.3 Đăng thông điệp 25
II.2.4 Gửi một thông điệp 26
III kỹ thuật hook 28
III.1 Giới thiệu 28
III.2 Chuỗi Hook 29
III.2.1 Thủ tục Hook 29
III.2.2 Các kiểu Hook 29
III.3 Cách sử dụng 31
III.3.1 Cài đặt Hook 31
III.3.2 Giải phóng Hook 31
IV win 32 api 32
IV.1 Giới thiệu 32
IV.2 Các hàm thường dùng 32
Trang 4IV.2.1 SetWindowsHookEx 32
IV.2.2 UnhookWindowsHookEx 33
IV.2.3 CallNextHookEx 33
IV.2.4 LowLevelKeyboardProc 34
IV.2.5 GetKeyState 35
IV.2.6 GetKeyboardState 35
IV.2.7 ToAscii 35
IV.2.8 LoadLibrary 36
IV.2.9 GetProcAddress 36
IV.2.10 OpenProcess 36
IV.2.11 EnumProcessModules 37
IV.2.12 GetModuleBaseName 37
IV.2.13 GetForegroundWindow 38
IV.2.14 GetWindowThreadProcessId 38
IV.2.15 GetLocalTime 39
IV.3 Mã bàn phím ảo 39
Chương 2 PHÂN TÍCH VÀ XÂY DỰNG CHƯƠNG TRÌNH 47
I PHân tích yêu cầu 47
I.1 Yêu cầu về chức năng 47
I.2 Yêu cầu về giao diện người dùng 47
I.3 Yêu cầu về tương thích 47
II phân tích chức năng 47
III xây dựng chức năng 47
III.1 Tập tin thi hành Jaam.exe 47
III.2 Thư viện Hooker.dll 49
III.2.1 Phiên bản 1 49
III.2.2 Phiên bản 2 51
III.2.3 Phiên bản 3 53
Chương 3 TRIỂN KHAI VÀ ĐÁNH GIÁ KẾT QUẢ 57
I Môi trường triển khai 57
II Kết quả chức nĂng chương trình 57
III Đánh giá và nhận xét 58
Trang 5TỔNG QUAN VỀ ĐỀ TÀI
1 Bối cảnh và lý do thực hiện đề tài
Trong khuôn khổ Đồ Án môn học Nguyên Lý hệ điều hành, dưới sự gợi ý của thầy Huỳnh Công Pháp, tụi em đã chọn đề tài KeyLogger-Sử dụng Hook Windows
Khi mà thị trường windows chiếm hơn 90% trên thế giới thì việc được nghiên cứu về một tính năng quan trọng, cơ bản nhất của windows làm chúng em rất hứng thú Hơn nữa việc thực hiện đề tài giúp chúng em biết rõ hơn về một kỹ thuật phần mềm gián điệp, ăn cắp thông tin để biết cách phòng tránh
2 Phương pháp triển khai đề tài
Sử dụng mô hình Tiến Hóa trong việc phân tích và xây dựng phần mềm Chúng em đã cố gắng để đưa ra các phiên bản nâng cấp để có một phần mềm hoàn chỉnh
3 Kết cấu của đồ án
Phần mềm gồm 2 tập tin :
- Tập tin thi hành Jaam.exe
- Thư viện liên kết động Hooker.dll
Trang 6Chương 1 CƠ SỞ LÝ THUYẾT
I GIỚI THIỆU
Hook là kỹ thuật điều khiển thông điệp (message-handling) giúp cho ứng
dụng có thể cài đặt một thủ tục để điều khiển luồng thông điệp và tiến hành xử lý các thông điệp đó trước khi thông điệp đó đi tới cửa sổ đích
Hook có thể xem là tính năng mạnh mẽ nhất của Windows, nó cho phép ta
đặt bẫy đối với các sự kiện Bằng cách sử dụng hook, ta có thể điều hướng ứng dụng tới một thủ tục mới bất kể khi nào mà sự kiện được quan tâm xuất hiện và bất kể sự kiện đó thuộc tiến trình của bạn hay thuộc tiến trình khác
Để viết được chương trình Hook ta cần nắm bắt cơ chế xử lý thông điệp của Windows, Thư viện Win32 API và Kỹ thuật Hook
II THÔNG ĐIỆP VÀ HÀNG ĐỢI THÔNG ĐIỆP CỦA WINDOWS
II.1 Giới thiệu
Không giống như các ứng dụng trên nền MS-DOS, các ứng dụng trên Windows hướng sự kiện Chúng không thực hiện các chức năng gọi rõ ràng ( như thư viện C ) để có được đầu vào Thay vào đó, chúng chờ đợi cho hệ thống chuyển đầu vào đến chúng
Hệ thống chuyển tất cả đầu vào cho một ứng dụng cho các cửa sổ khác nhau trong hệ thống Mỗi cửa số có một hàm, được gọi là một thủ tục cửa sổ, hệ thống gọi bất cứ khi nào nó có đầu vào cho cửa sổ Thủ tục cửa số xử lý đầu vào và trả kiểm soát cho hệ thống
Nếu một cử số cao nhất dừng trả lời thông điệp trong một vài giây, hệ thống xem như cửa sổ đó là Not Responding Trong trường hợp này, hệ thống ẩn các cửa
sổ và thay thế nó với một cửa sổ ma có cùng Z, vị trí kích thước, và các thuộc tính hình ảnh Điều này cho phép người sử dụng di chuyển, thay đổi kích thước, hoặc đóng ứng dụng Tuy nhiên, đây chỉ là những hành động hợp lệ vì ứng dụng thật sự không được đáp ứng Khi ở chế độ gỡ rối, hệ thống không tạo ra cửa sổ ma
II.1.1 Thông điệp windows
Trang 7Hệ thống chuyển đầu vào đến thủ tục cửa sổ trong hình thức của thông điệp Các thông điệp được sinh ra với cả hệ thống và các ứng dụng Hệ thống sinh ra một thông điệp ở mỗi sự kiện đầu vào – ví dụ, khi người dùng nhập, di chuyển chuột, hoặc nhấp chuột như điều khiển thanh cuộn Hệ thống cũng tạo ra các thông điệp trong hồi đáp để thay đổi trong hệ thống mang lại mởi một ứng dụng, như khi một ứng dụng thay đổi tài nguyên phông chữ hệ thống hoặc thay đổi kích thước cửa sổ của nó Một ứng dụng có thể sinh ra thông điệp đến trực tiếp các cửa sổ riêng của nó
để thực hiện nhiệm vụ hoặc để giao tiếp với cửa sổ trong ứng dụng khác
Hệ thống sẽ gửi một thông điệp tới thông điệp cửa sổ với bốn hằng số : 1 xử
lý cửa sổ, một tin nhắn nhận dạng, và hai giá trị được gọi là tham số tin nhắn Các
xử lý cửa sổ xác định của ố mà thông điệp hướng đến Hệ thống dùng nó để xác định các thủ tục cửa sổ sẽ được nhận thông điệp
Định dạng tin nhắn là một hằng số có tên là xác định mục đích của thông điệp Khi một thủ tục cửa sổ nhận được một thông điệp, nó sử dụng một định danh tin nhắn xác định làm thế nào để xử lý thông điệp Ví dụ, các thông điệp nhân dạng WM_PAINT cho các thủ tục cửa sổ để khu vực cửa sổ đã thay đổi và phải được vẽ lại
Các tham số thông điệp xác định dữ liệu hoặc vị trí dữ liệu được dùng bởi thủ tục cửa sổ khi xử lý thông điệp Ý nghĩa và giá trị của tham số thông điệp phụ thuộc vào thông điệp Một tham số thông điệp có thể chứa một số nguyên, cờ bit đóng gói, một con trỏ đến một cấu trúc dữ liệu chứa dữ liệu bổ sung, và v v Khi một thông điệp không dùng tham số thông điệp, chúng thương được thiết lập là NULL Một thủ tục cửa sổ phải kiểm tra địn danh thông điệp để xác định làm thế nào để phân tích thông số thông điệp
II.1.2 Loại Thông điệp
Có hai loại thông điệp
- Thông điệp định bởi hệ thống
- Thông điệp định bởi ứng dụng
Thông điệp định bởi hệ thống
Trang 8Hệ thống gửi hoặc chuyển một Thông điệp định bởi hệ thống khi nó giao tiếp với một ứng dụng Nó sử dụng những thông điệp để điều khiển hoạt động của ứng dụng và cung cấp đầu vào và các thông tin khác cho ứng dựng xử lý Một ứng dụng
có thể gửi hoặc chuyển thông điệp định bởi hệ thống Ứng dụng thường sử dụng các thông điệp để điều khiển các hoạt động của đối tượng cửa sổ được tạo bằng cách dùng các lớp cửa sổ đã đăng ký
Mỗi thông điệp định bởi hệ thống có một đinh dạnh thông điệp riêng duy nhất và một hằng biểu tượng tương ứng (được đinh nghĩa trong các tập tin header của SDK ) nêu rõ mục đích của thông điệp Ví dụ, WM_PAINT yêu cầu cửa sổ vẽ lại nội dung của nó
Hằng số tượng trưng xác định củ thể danh mục mà thông điệp đinh bởi hệ thống thuộc về Các tiền tố của hằng xác định loại của cửa sổ mà nó phân tích và xử
lý thông điệp Sau đây là danh xác các thông điệp
Tiền tố Loại thông điệp
ABM and ABN Application desktop toolbar
ACM and ACN Animation control
BCM, BCN, BM, and BN Button control
CB and CBN ComboBox control
CBEM and CBEN ComboBoxEx control
DFM Default context menu
DM Default push button control
DTM and DTN Date and time picker control
EM and EN Edit control
HDM and HDN Header control
IPM and IPN IP address control
LB and LBN List box control
LVM and LVN List view control
MCM and MCN Month calendar control
Trang 9PGM and PGN Pager control
PSM and PSN Property sheet
RB and RBN Rebar control
SB and SBN Status bar window
SBM Scroll bar control
STM and STN Static control
TB and TBN Toolbar
TBM and TRBN Trackbar control
TCM and TCN Tab control
TDM and TDN Task dialog
TTM and TTN Tooltip control
TVM and TVN Tree-view control
UDM and UDN Up-down control
Thông điệp định bởi ứng dụng
Một ứng dụng có thể tạo ra các thông điệp được sửa dụng bởi các cửa sổ riêng của nó hoặc để giao tiếp với cửa sổ của ứng dụng khác Nếu một ứng dụng tạo
ra các thông điệp của nó, thủ tục cửa sổ sẽ tiếp nhận và phân tích những thông điệp
và cung cấp xử lý thích hợp
Định danh thông điệp có các giá trị sau :
- Hệ thống dự trữ định danh thông điệp với giá trị từ 0x0000 đến 0x03FF ( giá trị của WM_USER – 1) cho thông điệp định bởi hệ thống Các uwgns dụng không thể dùng những thông điệp riêng này
- Giá trị từ 0x0400 (giá trị của WM_USER) tới 0x7FFF là hợp lệ cho định danh thông điệp cho các lớp cửa sổ riêng
- Nếu các ứng dụng được đánh dấu version 4, ta có thể sử dụng định dạng thông điệp với giá trị trong khoản 0x8000 (WM_APP) tới 0xBFFF trong thông điệp riêng
- Hệ thống trả về một định danh thông điệp trong khoản 0xC000 tới 0xFFFF khi một ứng dụng gọi hàm RegisterWindowMessage để đăng ký một thông điệp
Trang 10Định danh thông điệp trả về bởi hàm này được đảm bảo là duy nhất trong toàn hệ thống Sử dụng chức năng này ngăn chặn xung đột có thể xảy ra nếu ứng dụng khác dùng cùng định danh thông điệp cho mục đích khác
II.1.3 Lộ trình thông điệp
Hệ thống sử dụng hai phương thức để chuyển thông điệp đến thủ tục cửa sổ : chuyển thông điệp đến một hàng đợi, chuyển thông điệp trực tiếp tới thủ tục cửa sổ
Một thông điệp được đưa đến một hàng đợi được gọi là hàng đợi thông điệp Đây là kết quả chủ yếu của đầu vào nhập vào thông qua chuộ hoặc bàn phím như các thông điệp WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN,
và WM_CHAR Các thông điệp hàng đợi khác bao gồm bộ đếm thời gian, vẽ, và thông điệp thoát : WM_TIMER, WM_PAINT, và WM_QUIT Phần lớn thông điệp khác được gửi trực tiếp đến thủ tục cửa sổ, được gọi là thông điệp không hàng đợi
Hàng đợi thông điệp
Hệ thống có thể hiển thị bất kỳ số lượng cửa sổ cùng một lúc Để chuyển dữ liệu chuột và bàn phím đến cửa sổ thích hợp, hệ thống sử dụng hàng đợi thông điệp
Hệ thống duy trì một hàng đợi hệ thống tin nhắn đơn và thread-cụ thể một tin nhắn hàng đợi cho mỗi thread GUI Để tránh các chi phí của việc tạo ra một hàng đợi tin nhắn cho chủ đề giao diện không, tất cả các chủ đề được tạo ra ban đầu mà không có một hàng đợi thông điệp Hệ thống này tạo ra một thread-cụ thể hàng đợi thông điệp chỉ khi chủ đề làm cho cuộc gọi đầu tiên của mình cho một trong những người sử dụng các chức năng cụ thể, không có chức năng giao diện cuộc gọi kết quả trong việc tạo ra các một hàng đợi thông điệp
Bất cứ khi nào người dùng di chuyển chuột, nhấp chuột vào nút chuột, hoặc các loại trên bàn phím, trình điều khiển thiết bị cho các con chuột hoặc bàn phím chuyển đổi đầu vào tin nhắn và đặt chúng trong hàng đợi hệ thống tin nhắn Hệ thống này loại bỏ các tin nhắn, một tại một thời điểm, từ hàng đợi thông điệp hệ thống, kiểm tra để xác định cửa sổ đích, và sau đó bài viết chúng vào hàng đợi tin nhắn của chủ đề đó tạo ra cửa sổ đích Hàng đợi tin nhắn của một chủ đề nhận được tất cả các tin nhắn chuột và bàn phím cho các cửa sổ được tạo ra bởi chủ đề Chủ đề
Trang 11loại bỏ tin nhắn từ hàng đợi của nó và chỉ đạo hệ thống để gửi đến các thủ tục cửa
sổ thích hợp cho chế biến
Với sự ngoại lệ của thông điệp WM_PAINT, thông điệp WM_TIMER, và thông điệp WM_QUIT, hệ thống tin nhắn vào cuối của một hàng đợi thông điệp Điều này đảm bảo rằng một cửa sổ nhận được tin nhắn đầu vào của nó trong lần đầu tiên thích hợp, trình tự (FIFO) đầu tiên ra Thông điệp WM_PAINT, thông điệp WM_TIMER, và thông điệp WM_QUIT, tuy nhiên, được lưu giữ trong hàng đợi và được chuyển tiếp đến các thủ tục cửa sổ chỉ khi hàng đợi không có các tin nhắn khác Ngoài ra, nhiều thông điệp WM_PAINT cho cùng một cửa sổ được kết hợp vào một thông điệp WM_PAINT duy nhất, củng cố tất cả các phần không hợp lệ của các khu vực khách hàng vào một khu vực duy nhất Kết hợp các thông điệp WM_PAINT làm giảm số lần một cửa sổ phải vẽ lại các nội dung của khu vực khách hàng của nó
Các bài viết hệ thống tin nhắn đến hàng đợi thông điệp của một chủ đề bằng cách điền vào một cấu trúc bột ngọt và sau đó sao chép nó vào hàng đợi thông điệp Thông tin trong bột ngọt bao gồm: xử lý của cửa sổ tin nhắn có mục đích, định danh tin nhắn, hai thông số tin nhắn, tin nhắn được đăng, và vị trí con trỏ chuột Một thread có thể gửi một thông điệp tới hàng đợi thông điệp riêng của mình vào hàng đợi của chủ đề khác bằng cách sử dụng chức năng PostMessage hoặc PostThreadMessage
Một ứng dụng có thể loại bỏ một thông điệp từ hàng đợi của nó bằng cách sử dụng chức năng GetMessage Để kiểm tra một tin nhắn mà không cần gỡ bỏ nó khỏi hàng đợi của nó, một ứng dụng có thể sử dụng chức năng PeekMessage Chức năng này đầy bột ngọt với thông tin về tin nhắn
Sau khi loại bỏ một thông điệp từ hàng đợi của nó, một ứng dụng có thể sử dụng chức năng DispatchMessage chỉ đạo hệ thống gửi tin nhắn tới một thủ tục cửa
sổ để xử lý DispatchMessage một con trỏ đến bột ngọt đã được lấp đầy bởi một cuộc gọi trước để GetMessage hoặc chức năng PeekMessage DispatchMessage qua cửa sổ xử lý, nhận dạng tin nhắn, và các thông số tin nhắn hai thủ tục cửa sổ, nhưng
nó không vượt qua thời gian thông điệp được đăng hoặc vị trí con trỏ chuột Một
Trang 12ứng dụng có thể lấy thông tin này bằng cách gọi các chức năng GetMessageTime và GetMessagePos trong khi xử lý tin nhắn
Một thread có thể sử dụng chức năng WaitMessage năng suất kiểm soát các chủ đề khác khi nó không có tin nhắn trong hàng đợi thông điệp của mình Chức năng đình chỉ các chủ đề và không trả lại cho đến khi một tin nhắn mới được đặt trong hàng đợi thông điệp của chủ đề
Bạn có thể gọi hàm SetMessageExtraInfo để kết hợp một giá trị với hàng đợi thông điệp của thread hiện hành Sau đó gọi hàm GetMessageExtraInfo để có được giá trị liên quan đến thông báo cuối cùng lấy GetMessage hoặc chức năng PeekMessage
Thông điệp không hàng đợi
Các tin nhắn Nonqueued được gửi ngay lập tức các thủ tục cửa sổ đích, bỏ qua hàng đợi hệ thống tin nhắn và hàng đợi thông điệp chủ đề Hệ thống này thường gửi tin nhắn nonqueued để thông báo cho một cửa sổ của các sự kiện có ảnh hưởng đến nó Ví dụ, khi người dùng kích hoạt một cửa sổ ứng dụng mới, hệ thống sẽ gửi các cửa sổ một loạt các tin nhắn, bao gồm cả WM_ACTIVATE, WM_SETFOCUS,
và WM_SETCURSOR Các thông điệp này thông báo cho các cửa sổ đã được kích hoạt, bàn phím đầu vào đang được hướng đến cửa sổ, và con trỏ chuột đã được di chuyển trong phạm vi biên giới của cửa sổ Các tin nhắn Nonqueued cũng có thể kết quả khi một ứng dụng gọi một số chức năng hệ thống Ví dụ, hệ thống sẽ gửi tin nhắn WM_WINDOWPOSCHANGED sau khi một ứng dụng sử dụng các chức năng SetWindowPos để di chuyển một cửa sổ
Một số chức năng gửi tin nhắn nonqueued BroadcastSystemMessage, BroadcastSystemMessageEx, SendMessage, SendMessageTimeout, và SendNotifyMessage
II.1.4 Xử lý thông điệp
Một ứng dụng phải loại bỏ và xử lý các tin nhắn được đưa lên hàng đợi tin nhắn của chủ đề của nó Một ứng dụng đơn luồng thường sử dụng một vòng lặp tin nhắn chức năng winmain của nó để loại bỏ và gửi tin nhắn cho các thủ tục cửa sổ
Trang 13thích hợp cho chế biến Các ứng dụng với nhiều chủ đề có thể bao gồm một vòng lặp tin nhắn trong mỗi chủ đề đó tạo ra một cửa sổ Các phần sau đây mô tả làm thế nào một công trình vòng lặp thông điệp và giải thích vai trò của một thủ tục cửa sổ:
Vòng lặp thông điệp
Một vòng lặp tin nhắn đơn giản bao gồm một cuộc gọi chức năng với nhau trong ba chức năng: GetMessage, TranslateMessage, và DispatchMessage Lưu ý rằng nếu có một lỗi, GetMessage trả về -1, do đó sự cần thiết cho việc thử nghiệm đặc biệt
để đóng ứng dụng Một ứng dụng có thể kết thúc vòng lặp của riêng mình bằng cách
Trang 14sử dụng chức năng PostQuitMessage, thường phản ứng với thông điệp WM_DESTROY trong thủ tục cửa sổ của cửa sổ chính của ứng dụng
Nếu bạn chỉ định một cửa sổ xử lý như là tham số thứ hai của GetMessage, tin nhắn chỉ dành cho các cửa sổ chỉ định được lấy từ hàng đợi GetMessage cũng
có thể lọc các thông điệp trong hàng đợi, lấy chỉ những tin nhắn nằm trong một phạm vi chỉ định Để biết thêm thông tin về các tin nhắn lọc, lọc tin nhắn
Vòng lặp thông điệp của chủ đề phải bao gồm TranslateMessage nếu chủ đề
là để nhận được nhân vật đầu vào từ bàn phím Hệ thống này tạo ra các thông điệp chính ảo (WM_KEYDOWN và WM_KEYUP) mỗi lần người dùng nhấn một phím Một tin nhắn phím ảo có chứa một mã phím ảo để xác định phím nào được nhấn, nhưng không phải giá trị của nó nhân vật Để lấy giá trị này, các vòng lặp tin nhắn phải có TranslateMessage, dịch các tin nhắn phím ảo vào một tin nhắn ký tự (WM_CHAR) và đặt nó trở lại vào hàng đợi thông điệp ứng dụng Thông báo nhân vật sau đó có thể được gỡ bỏ sau khi lặp đi lặp lại tiếp theo của vòng lặp tin nhắn và gửi đi một thủ tục cửa sổ
Chức năng DispatchMessage sẽ gửi một thông điệp tới các thủ tục cửa sổ kết hợp với các cửa sổ xử lý quy định trong cấu trúc MSG Nếu cửa sổ xử lý HWND_TOPMOST, DispatchMessage gửi tin nhắn tới các thủ tục cửa sổ của tất cả các cửa sổ cấp cao nhất trong hệ thống Nếu cửa sổ xử lý NULL, DispatchMessage không làm gì với tin nhắn
Chủ đề chính của một ứng dụng bắt đầu vòng lặp thông điệp của mình sau khi khởi tạo các ứng dụng và tạo ra ít nhất một cửa sổ Sau khi nó được bắt đầu, vòng lặp tin nhắn tiếp tục để lấy thông điệp từ hàng đợi thông điệp của chủ đề và gửi chúng cho các cửa sổ thích hợp Các vòng lặp thông điệp kết thúc khi hàm GetMessage loại bỏ các thông điệp WM_QUIT từ hàng đợi thông điệp
Chỉ có một vòng lặp thông điệp là cần thiết cho một hàng đợi tin nhắn, thậm chí nếu một ứng dụng có chứa nhiều cửa sổ DispatchMessage luôn luôn công văn thông điệp đến cửa sổ thích hợp, điều này là bởi vì mỗi tin nhắn trong hàng đợi là một cấu trúc bột ngọt có chứa các xử lý của cửa sổ tin nhắn
Trang 15Bạn có thể sửa đổi một vòng lặp tin nhắn trong nhiều cách khác nhau Ví dụ, bạn có thể lấy các thông điệp từ hàng đợi mà không có cử một cửa sổ Điều này rất hữu ích cho các ứng dụng tin nhắn gửi không quy định cụ thể một cửa sổ Bạn cũng
có thể trực tiếp GetMessage để tìm kiếm thông điệp cụ thể, để lại tin nhắn khác trong hàng đợi Điều này là hữu ích nếu bạn phải tạm thời bỏ qua thứ tự FIFO thông thường của các hàng đợi thông điệp
Một ứng dụng sử dụng các phím gia tốc phải có khả năng dịch tin nhắn bàn phím vào các tin nhắn lệnh Để làm điều này, vòng lặp thông điệp của ứng dụng phải bao gồm một cuộc gọi đến các chức năng TranslateAccelerator Để biết thêm thông tin về các phím gia tốc, gia tốc bàn phím
Nếu một chủ đề sử dụng một hộp thoại modeless, vòng lặp thông báo phải bao gồm các chức năng IsDialogMessage để hộp thoại có thể nhận được đầu vào bàn phím
Thủ tục cửa sổ
Một thủ tục cửa sổ là một chức năng tiếp nhận và xử lý tất cả các tin nhắn gửi đến cửa sổ Mỗi lớp cửa sổ có một thủ tục cửa sổ, và tất cả các cửa sổ tạo ra với lớp học mà sử dụng thủ tục cùng một cửa sổ để trả lời tin nhắn
Hệ thống sẽ gửi một thông điệp tới một thủ tục cửa sổ bằng cách đi qua các thông điệp dữ liệu như các đối số thủ tục Các thủ tục cửa sổ sau đó thực hiện một hành động thích hợp tin nhắn, nó sẽ kiểm tra định danh tin nhắn, trong khi xử lý tin nhắn, sử dụng các thông tin quy định bởi các thông số tin nhắn
Một thủ tục cửa sổ thường không bỏ qua một tin nhắn Nếu nó không xử lý một tin nhắn, nó phải gửi tin nhắn trở lại hệ thống để xử lý mặc định Thủ tục cửa sổ này bằng cách gọi hàm DefWindowProc, thực hiện một hành động mặc định và trả
về một kết quả tin nhắn Thủ tục cửa sổ sau đó phải trả lại giá trị này là kết quả thông điệp riêng của mình Hầu hết các thủ tục cửa sổ xử lý chỉ là một vài tin nhắn
và vượt qua những người khác trên hệ thống bằng cách gọi DefWindowProc
Bởi vì một thủ tục cửa sổ được chia sẻ bởi tất cả các cửa sổ thuộc cùng một lớp, nó có thể xử lý tin nhắn cho các cửa sổ khác nhau Để xác định các cửa sổ cụ
Trang 16thể bị ảnh hưởng bởi tin nhắn, một thủ tục cửa sổ có thể kiểm tra các cửa sổ xử lý được thông qua với một tin nhắn Để biết thêm thông tin về các thủ tục cửa sổ, xem Thủ tục Window
II.1.5 Lọc thông điệp
Một ứng dụng có thể lựa chọn tin nhắn cụ thể lấy từ hàng đợi thông điệp (trong khi bỏ qua các tin nhắn khác) bằng cách sử dụng chức năng GetMessage hoặc PeekMessage để chỉ định một bộ lọc tin nhắn Bộ lọc được một loạt các định danh tin nhắn (quy định bởi một định danh đầu tiên và cuối cùng), xử lý một cửa sổ, hoặc cả hai GetMessage và PeekMessage sử dụng một bộ lọc tin nhắn để chọn các tin nhắn để lấy từ hàng đợi Lọc thư rất hữu ích nếu một ứng dụng phải tìm kiếm các hàng đợi thông điệp cho các tin nhắn đã đến sau đó trong hàng đợi Nó cũng rất hữu ích nếu một ứng dụng phải xử lý đầu vào (phần cứng) tin nhắn trước khi chế biến các bài được đăng
Các hằng số WM_KEYFIRST và WM_KEYLAST có thể được sử dụng như các giá trị lọc để lấy tất cả thông điệp bàn phím, các hằng số WM_MOUSEFIRST
và WM_MOUSELAST có thể được sử dụng để lấy tất cả các tin nhắn chuột
Bất kỳ ứng dụng mà các bộ lọc tin nhắn phải đảm bảo rằng một tin nhắn đáp ứng bộ lọc tin nhắn có thể được đăng Ví dụ, nếu một bộ lọc ứng dụng cho một tin nhắn WM_CHAR trong một cửa sổ mà không nhận được đầu vào bàn phím, chức năng GetMessage không trở lại Hiệu quả này "treo" các ứng dụng
II.1.6 Đăng và chuyển thông điệp
Bất kỳ ứng dụng có thể đăng bài và gửi tin nhắn Giống như hệ thống, một bài viết một ứng dụng tin nhắn bằng cách sao chép nó vào một hàng đợi tin nhắn và gửi một thông điệp bằng cách đi qua các thông điệp dữ liệu như các đối số đến một thủ tục window Để gửi tin nhắn, ứng dụng sử dụng các chức năng PostMessage Một ứng dụng có thể gửi một tin nhắn bằng cách gọi SendMessage, BroadcastSystemMessage, SendMessageCallback, SendMessageTimeout, SendNotifyMessage, hoặc SendDlgItemMessage chức năng
Đăng tin nhắn
Trang 17Một ứng dụng thường gởi một thông điệp để thông báo cho một cửa sổ cụ thể
để thực hiện một nhiệm vụ PostMessage tạo ra một cấu trúc MSG cho tin nhắn và các bản sao tin nhắn tới các hàng đợi thông điệp Vòng lặp thông điệp của ứng dụng cuối cùng lấy được thông báo và công văn đến các thủ tục cửa sổ thích hợp
Một ứng dụng có thể gửi một tin nhắn mà không cần quy định cụ thể một cửa
sổ Nếu ứng dụng cung cấp một cửa sổ xử lý NULL khi gọi PostMessage, tin nhắn được đưa lên hàng đợi kết hợp với các chủ đề hiện tại Vì không có cửa sổ xử lý được quy định cụ thể, ứng dụng phải xử lý các tin nhắn trong vòng lặp tin nhắn Đây là một trong những cách để tạo ra một thông báo áp dụng cho toàn bộ ứng dụng, thay vì đến một cửa sổ cụ thể
Thỉnh thoảng, bạn có thể muốn gửi một thông điệp tới tất cả các cửa sổ cấp cao nhất trong hệ thống Một ứng dụng có thể gửi một tin nhắn cho tất cả các cửa sổ cấp cao nhất bằng cách gọi PostMessage và quy định cụ thể HWND_TOPMOST trong tham số hwnd
Một lỗi lập trình phổ biến là cho rằng chức năng PostMessage luôn luôn nhắn Điều này không đúng khi hàng đợi thông điệp đầy đủ Một ứng dụng nên kiểm tra giá trị trả lại chức năng PostMessage để xác định xem tin nhắn đã được đăng, và nếu nó đã không được, repost nó
Chuyển tin nhắn
Một ứng dụng thường gửi một thông điệp để thông báo cho một thủ tục cửa
sổ để thực hiện một nhiệm vụ ngay lập tức Chức năng SendMessage gửi tin nhắn tới các thủ tục cửa sổ tương ứng với cửa sổ nhất định Chức năng chờ đợi cho đến khi hoàn tất các thủ tục cửa sổ xử lý và sau đó trả về kết quả tin nhắn Cửa sổ cha
mẹ và trẻ em thường liên lạc bằng cách gửi tin nhắn cho nhau Ví dụ, một cửa sổ cha mẹ có một điều khiển chỉnh sửa như cửa sổ con của nó có thể thiết lập các văn bản của kiểm soát bằng cách gửi một thông điệp tới nó Việc kiểm soát có thể thông báo cho cửa sổ cha mẹ thay đổi văn bản được thực hiện bởi người sử dụng bằng cách gửi tin nhắn lại cho phụ huynh
Trang 18Chức năng SendMessageCallback cũng sẽ gửi một thông điệp tới các thủ tục cửa sổ tương ứng với cửa sổ nhất định Tuy nhiên, chức năng này trả về ngay lập tức Sau khi các thủ tục cửa sổ xử lý tin nhắn, hệ thống các cuộc gọi chức năng gọi lại quy định Để biết thêm thông tin về chức năng gọi lại, thấy chức năng SendAsyncProc
Chức năng SendMessageCallback cũng sẽ gửi một thông điệp tới các thủ tục cửa sổ tương ứng với cửa sổ nhất định Tuy nhiên, chức năng này trả về ngay lập tức Sau khi các thủ tục cửa sổ xử lý tin nhắn, hệ thống các cuộc gọi chức năng gọi lại quy định Để biết thêm thông tin về chức năng gọi lại, thấy chức năng SendAsyncProc
Bằng cách sử dụng chức năng InSendMessage hoặc InSendMessageEx, một thủ tục cửa sổ có thể xác định cho dù đó là chế biến một thông báo được gửi bởi thread khác Khả năng này rất hữu ích khi xử lý thông báo phụ thuộc vào nguồn gốc của tin nhắn
II.1.7 Bế tắc thông điệp
Một chủ đề đó gọi hàm SendMessage để gửi tin nhắn đến chủ đề khác không thể tiếp tục thực hiện cho đến khi các thủ tục cửa sổ nhận được tin nhắn trả về Nếu sản lượng chủ đề được kiểm soát trong khi xử lý tin nhắn, các chủ đề gửi không có thể tiếp tục thực hiện, bởi vì nó là chờ đợi cho SendMessage trở lại Nếu các chủ đề nhận được được gắn vào hàng đợi tương tự như người gửi, nó có thể gây ra một bế tắc ứng dụng để xảy ra (Lưu ý rằng tạp chí móc đính kèm các chủ đề cùng một hàng đợi.)
Lưu ý rằng các chủ đề nhận được cần không mang lại kiểm soát một cách rõ ràng, gọi điện thoại bất kỳ của các chức năng sau có thể gây ra một thread để năng suất kiểm soát ngầm
- DialogBox
- DialogBoxIndirect
- DialogBoxIndirectParam
- DialogBoxParam
Trang 19kỳ các chức năng trong danh sách trước khi thực hiện một tin nhắn, các thủ tục cửa
sổ đầu tiên nên gọi InSendMessage hoặc InSendMessageEx Nếu chức năng này trả
về TRUE, các thủ tục cửa sổ phải gọi hàm ReplyMessage trước khi bất kỳ chức năng gây ra các chủ đề để sản lượng kiểm soát
II.1.8 Thông điệp quảng bá
Mỗi thông điệp bao gồm một định danh thông điệp và hai tham số wParam
và lParam Từ định danh tin nhắn là một giá trị duy nhất quy định cụ thể mục đích thông báo Các thông số cung cấp thông tin bổ sung đó là thông điệp cụ thể, nhưng các tham số wParam nói chung là một giá trị kiểu cung cấp thông tin về tin nhắn
Chương trình phát sóng tin nhắn chỉ đơn giản là gửi một tin nhắn tới nhiều người trong hệ thống Để phát sóng một thông điệp từ một ứng dụng, sử dụng chức năng BroadcastSystemMessage, quy định cụ thể người nhận của tin nhắn Thay vì chỉ định người nhận cá nhân, bạn phải chỉ định một hoặc nhiều loại người nhận Những loại ứng dụng, trình điều khiển cài đặt, trình điều khiển mạng, và các trình điều khiển thiết bị hệ thống Hệ thống sẽ gửi tin nhắn quảng bá cho tất cả các thành viên của từng loại quy định
Hệ thống này thường chương trình phát sóng thông điệp phản ứng với những thay đổi diễn ra trong các trình điều khiển thiết bị hệ thống hoặc các thành phần liên quan Người lái xe hoặc thành phần liên quan đến chương trình phát sóng thông điệp đến các ứng dụng và các thành phần khác để thông báo cho họ về sự thay đổi
Trang 20Ví dụ, thành phần chịu trách nhiệm cho các ổ đĩa chương trình phát sóng một thông báo bất cứ khi nào điều khiển thiết bị cho các ổ đĩa mềm phát hiện một sự thay đổi của các phương tiện truyền thông chẳng hạn như khi người sử dụng chèn một đĩa vào ổ đĩa
Hệ thống chương trình phát sóng tin nhắn đến người nhận theo thứ tự này: hệ thống cấp trình điều khiển thiết bị, trình điều khiển mạng, cài đặt trình điều khiển,
và các ứng dụng Điều này có nghĩa là hệ thống cấp trình điều khiển thiết bị, nếu được lựa chọn như người nhận, luôn luôn có được cơ hội đầu tiên để đối phó với một tin nhắn Trong thời hạn một loại người nhận nhất định, lái xe không được đảm bảo để nhận được thông báo đưa ra trước khi bất kỳ trình điều khiển khác Điều này
có nghĩa rằng một thông điệp dành cho một trình điều khiển cụ thể phải có một định danh tin nhắn trên toàn cầu duy nhất để không có trình điều khiển khác vô ý quá trình đó
Bạn cũng có thể phát sóng các tin nhắn cho tất cả các cửa sổ cấp cao nhất bằng cách xác định HWND_BROADCAST trong SendMessage, SendMessageCallback, SendMessageTimeout, hoặc SendNotifyMessage chức năng
Các ứng dụng nhận tin nhắn thông qua các thủ tục cửa sổ của cửa sổ cấp cao nhất của họ Tin nhắn không được gửi đến các cửa sổ con Dịch vụ có thể nhận tin nhắn thông qua một thủ tục xử lý cửa sổ hoặc dịch vụ kiểm soá
Lưu ý hệ thống cấp trình điều khiển thiết bị sử dụng một chức năng, hệ thống cấp liên quan để phát sóng các thông báo hệ thống
II.1.9 Truy vấn thông điệp
Bạn có thể tạo ra các tin nhắn tùy chỉnh của bạn và sử dụng chúng để phối hợp hoạt động giữa các ứng dụng của bạn và các thành phần khác trong hệ thống Điều này đặc biệt hữu ích nếu bạn đã tạo ra trình điều khiển cài đặt riêng của bạn hoặc trình điều khiển thiết bị hệ thống cấp Tin nhắn tuỳ chỉnh của bạn có thể mang thông tin đến và từ trình điều khiển của bạn và các ứng dụng sử dụng các trình điều khiển
Trang 21Bạn có thể tạo ra các tin nhắn tùy chỉnh của bạn và sử dụng chúng để phối hợp hoạt động giữa các ứng dụng của bạn và các thành phần khác trong hệ thống Điều này đặc biệt hữu ích nếu bạn đã tạo ra trình điều khiển cài đặt riêng của bạn hoặc trình điều khiển thiết bị hệ thống cấp Tin nhắn tuỳ chỉnh của bạn có thể mang thông tin đến và từ trình điều khiển của bạn và các ứng dụng sử dụng các trình điều khiển
II.2 Sử dụng thông đi ệp và hàng đợi thông điệp
II.2.1 Tạo vòng lặp thông điệp
Các hệ thống không tự động tạo một hàng đợi tin nhắn cho mỗi thread Thay vào đó, hệ thống sẽ tạo ra một hàng đợi tin nhắn chỉ dành cho các chủ đề thực hiện các hoạt động mà yêu cầu một hàng đợi thông điệp Nếu chủ đề tạo ra một hoặc nhiều cửa sổ, một vòng lặp tin nhắn phải được cung cấp, vòng lặp thông điệp này lấy thông điệp từ hàng đợi thông điệp của thread và công văn cho họ các thủ tục cửa
sổ thích hợp
Bởi vì hệ thống chỉ đạo thông báo cho các cửa sổ trong một ứng dụng cá nhân, một sợi phải tạo ra ít nhất một cửa sổ trước khi bắt đầu vòng lặp thông điệp của mình Hầu hết các ứng dụng có chứa một chủ đề duy nhất mà tạo ra cửa sổ Một ứng dụng điển hình đăng ký lớp cửa sổ cho cửa sổ chính của nó, tạo ra và hiển thị cửa sổ chính, và sau đó bắt đầu vòng lặp thông điệp của nó - tất cả trong hàm WinMain
Bạn tạo ra một vòng lặp tin nhắn bằng cách sử dụng chức năng GetMessage
và DispatchMessage Nếu ứng dụng của bạn phải có đầu vào nhân vật từ người sử dụng, bao gồm các chức năng TranslateMessage trong vòng lặp TranslateMessage dịch ảo-key tin nhắn vào tin nhắn ký tự Ví dụ sau đây cho thấy các vòng lặp tin nhắn trong các chức năng winmain của một ứng dụng đơn giản dựa trên Windows HINSTANCE hinst;
HWND hwndMain;
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
Trang 22hwndMain = CreateWindow("MainWndClass", "Sample",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, (HWND) NULL,
(HMENU) NULL, hinst, (LPVOID) NULL);
Trang 23// Show the window and paint its contents
Trang 24// handle the error and possibly exit
II.2.2 Kiểm tra một hàng đợi thông điệp
Đôi khi, một ứng dụng cần kiểm tra các nội dung của hàng đợi thông điệp của một chủ đề từ bên ngoài vòng lặp thông điệp của chủ đề Ví dụ, nếu thủ tục cửa
sổ của một ứng dụng thực hiện một hoạt động bản vẽ dài, bạn có thể muốn người sử dụng có thể làm gián đoạn hoạt động Trừ khi ứng dụng của bạn định kỳ kiểm tra hàng đợi thông điệp trong quá trình hoạt động cho chuột và tin nhắn bàn phím, nó
sẽ không đáp ứng với người sử dụng đầu vào cho đến khi sau khi hoạt động đã hoàn thành Lý do cho điều này là rằng các chức năng DispatchMessage trong vòng lặp thông điệp của chủ đề không trả lại cho đến khi các thủ tục cửa sổ kết thúc xử lý tin nhắn
Bạn có thể sử dụng chức năng PeekMessage để kiểm tra một hàng đợi thông điệp trong một hoạt động dài PeekMessage tương tự như chức năng GetMessage,
cả hai kiểm tra một hàng đợi tin nhắn cho một tin nhắn phù hợp với tiêu chuẩn bộ lọc và sau đó sao chép tin nhắn tới một cấu trúc MSG Sự khác biệt chính giữa hai chức năng là GetMessage không trở lại cho đến khi một tin nhắn phù hợp với tiêu chuẩn lọc được đặt trong hàng đợi, trong khi PeekMessage trả về ngay lập tức bất
kể cho dù một thông báo là trong hàng đợi
Ví dụ sau đây cho thấy làm thế nào để sử dụng PeekMessage để kiểm tra một hàng đợi tin nhắn cho số lần nhấp chuột và đầu vào bàn phím trong một hoạt động dài
Trang 25// or until the user clicks the mouse or presses a key
// Remove any messages that may be in the queue If the
// queue contains any mouse or keyboard
// messages, end the operation
sử dụng nó là cách nhanh nhất để xác định xem liệu hàng đợi có chứa bất kỳ tin nhắn GetInputState trả về TRUE nếu hàng đợi có chứa tin nhắn chuột hoặc bàn phím Cả hai của các chức năng này có thể được sử dụng để xác định xem hàng đợi
có chứa tin nhắn cần được xử lý
II.2.3 Đăng thông điệp
Bạn có thể gửi một thông điệp tới một hàng đợi thông điệp bằng cách sử dụng chức năng PostMessage PostMessage một tin nhắn vào cuối hàng đợi thông điệp của một chủ đề và trả về ngay lập tức, mà không cần chờ đợi cho thread để xử
lý các tin nhắn Các thông số của chức năng bao gồm một cửa sổ xử lý, nhận dạng một tin nhắn, và hai tham số tin nhắn Hệ thống bản sao các thông số này một cấu trúc MSG, lấp đầy thời gian và các thành viên pt của cấu trúc, và cấu trúc trong các hàng đợi thông điệp
Hệ thống sử dụng cửa sổ xử lý được thông qua với chức năng PostMessage
để xác định mà chủ đề hàng đợi tin nhắn sẽ nhận được thông báo Nếu xử lý là
Trang 26HWND_TOPMOST, các bài viết hệ thống tin nhắn tới hàng đợi tin nhắn của tất cả các cửa sổ cấp cao nhất trong chủ đề
Hệ thống sử dụng cửa sổ xử lý được thông qua với chức năng PostMessage
để xác định mà chủ đề hàng đợi tin nhắn sẽ nhận được thông báo Nếu xử lý là HWND_TOPMOST, các bài viết hệ thống tin nhắn tới hàng đợi tin nhắn của tất cả các cửa sổ cấp cao nhất trong chủ đề
Sử dụng chức năng PostQuitMessage để thoát khỏi vòng lặp thông điệp PostQuitMessage thông điệp WM_QUIT các chủ đề hiện đang thực hiện Vòng lặp thông điệp của chủ đề kết thúc và trả về kiểm soát hệ thống khi gặp phải thông điệp WM_QUIT Một ứng dụng thường gọi PostQuitMessage trong phản ứng với thông điệp WM_DESTROY, như trong ví dụ sau đây
II.2.4 Gửi một thông điệp
Chức năng SendMessage được sử dụng để gửi tin nhắn trực tiếp đến một thủ tục cửa sổ SendMessage gọi một thủ tục cửa sổ và chờ đợi cho rằng thủ tục để xử
lý tin nhắn và trả lại kết quả
Một thông báo có thể được gửi đến bất kỳ cửa sổ trong hệ thống, tất cả những gì cần thiết là một cửa sổ xử lý Hệ thống sử dụng xử lý để xác định thủ tục cửa sổ sẽ nhận được tin nhắn
Trước khi chế biến một thông điệp có thể được gửi từ chủ đề khác, một thủ tục cửa sổ đầu tiên nên gọi chức năng InSendMessage Nếu chức năng này trả về TRUE, các thủ tục cửa sổ nên gọi ReplyMessage trước khi bất kỳ chức năng gây ra các chủ đề năng suất kiểm soát, như trong ví dụ sau đây
Trang 27Một số tin nhắn có thể được gửi đến các điều khiển trong một hộp thoại Những thông điệp điều khiển thiết lập sự xuất hiện, hành vi, và nội dung của các điều khiển hoặc lấy thông tin về điều khiển Ví dụ, thông điệp CB_ADDSTRING có thể thêm một chuỗi một hộp kết hợp, và tin nhắn BM_SETCHECK có thể thiết lập nhà nước kiểm tra một hộp kiểm tra hoặc nút
Sử dụng chức năng SendDlgItemMessage để gửi một tin nhắn để kiểm soát, xác định định danh của kiểm soát và xử lý của cửa sổ hộp thoại có chứa kiểm soát
Ví dụ sau đây, được lấy từ một thủ tục hộp thoại, bản sao một chuỗi từ kiểm soát chỉnh sửa một hộp kết hợp vào hộp danh sách Ví dụ sử dụng SendDlgItemMessage
để gửi một tin nhắn CB_ADDSTRING vào hộp kết hợp
// Get the handle of the combo box and the
// length of the string in the edit control
// of the combo box
hwndCombo = GetDlgItem(hwndDlg, IDD_COMBO);
cTxtLen = GetWindowTextLength(hwndCombo);
// Allocate memory for the string and copy
// the string into the memory
pszMem = (PSTR) VirtualAlloc((LPVOID) NULL,
(DWORD) (cTxtLen + 1), MEM_COMMIT,
PAGE_READWRITE);
GetWindowText(hwndCombo, pszMem,
cTxtLen + 1);
// Add the string to the list box of the
// combo box and remove the string from the
// edit control of the combo box
Trang 28III KỸ THUẬT HOOK
III.1 Giới thiệu
Các mô hình Hook :
- Local hook: là kỹ thuật Hook dùng để bẫy sự kiện ngay trong tiến trình cài
đặt
- Remote hook: là kỹ thuật Hook cho phép bẫy các sự kiện thuộc tiến trình
của ứng dụng khác Trong mô hình này lại tồn tại hai kiểu hook khác :
+ Thread-specific : kiểu Hook này sẽ bẫy sự kiện của một luồng cụ
thể
+ System-wide : bẫy sự kiện của tất cả các luồng trong tất cả các tiến
trình đang thi hành trong hệ thống
Trang 29III.2 Chuỗi Hook
Hệ thống có khả năng hỗ trợ nhiều kiểu hook khác nhau, mỗi kiểu lại được quy định một cách thức truy nhập khác nhau trong kỹ thuật điều khiển thông điệp
Do vậy, hệ thống duy trì một chuỗi các hook cho mỗi một kiểu hook khác nhau
Một chuỗi hook là một danh sách các con trỏ đặc biệt, nó được trỏ tới các hàm CallBack gọi là hook procedure (thủ tục hook) Như vậy khi một sự kiện xuất hiện, hệ thống sẽ chuyển sự kiện đó tới các thủ tục hook được tham chiếu bới chuỗi hook theo thứ tự lần lượt Vì thế phải thực hiện xong thủ tục này mới được gọi thủ tục kế tiếp
III.2.1 Thủ tục Hook
Thủ tục hook sẽ là nơi thực hiện các thao tác sau khi bắt được một sự kiện mong muốn Các thủ tục hook phụ thuộc vào các kiểu hook khác nhau mà có cấu trúc, chức năng khác nhau Có thủ tục chỉ có thể điều khiển thông điệp, một số khác
có thể sửa đổi thông điệp, dừng tiến trình của thông điệp, ngăn cản thực hiện hook tiếp theo hoặc đưa tới cửa sổ cuối cùng …
Thủ tục hook có dạng chung như sau:
LRESULT CALLBACK HookProc( int nCode, WPARAM wParam, LPARAM lParam );
Trong đó :
- HookProc: là tên đại diện của thủ tục hook được cài đặt
- nCode : Đây là mã hook, nó quyết định toàn bộ hoạt động của thủ tục hook,
mã hook phụ thuộc vào kiểu hook và mỗi kiểu hook được gán cho một ký tự để thiết lập mã hook
- wParam, lParam: Hai tham số này chứa các thông tin về thông điệp được hook và nó phụ thuộc vào mã hook (nCode)
III.2.2 Các kiểu Hook
Mỗi một kiểu Hook cho phép ứng dụng điều khiển thông điệp theo những cách khác nhau trong kỹ thuật điều khiển thông điệp (message-handling mechanism) Dưới đây là những kiểu hook khác nhau :
Trang 30- WH_CALLWNDPROC: Cài đặt một thủ tục hook theo dõi message trước
khi hệ thống sẽ gửi chúng đến các thủ tục cửa sổ đích
- WH_CALLWNDPROCRET: Cài đặt một thủ tục hook theo dõi message
sau khi đã được xử lý bởi các thủ tục cửa sổ đích
- WH_CBT: Cài đặt một thủ tục hook tiếp nhận thông báo hữu ích để một
ứng dụng CBT
- WH_DEBUG: Cài đặt một thủ tục hook hữu ích để gỡ lỗi thủ tục hook
khác
- WH_FOREGROUNDIDLE: Cài đặt một thủ tục hook sẽ được gọi khi
luồng của ứng dụng là trở thành nhàn rỗi Hook này rất hữu dụng cho thực hiện nhiệm vụ ưu tiên thấp trong thời gian nhàn rỗi
- WH_GETMESSAGE: Cài đặt một thủ tục hook theo dõi các message
được đưa lên một hàng đợi message
- WH_JOURNALPLAYBACK: Cài đặt một thủ tục hook gởi message
trước đây được ghi lại bằng một thủ tục hook WH_JOURNALRECORD
- WH_JOURNALRECORD: Cài đặt một thủ tục hook ghi lại các message
đầu vào được đưa lên hàng đợi thông điệp hệ thống Hook này rất hữu ích cho các macro ghi
- WH_KEYBOARD: Cài đặt một thủ tục móc theo dõi tin nhắn tổ hợp
phím
- WH_KEYBOARD_LL: Cài đặt một thủ tục móc theo dõi các sự kiện bàn
phím đầu vào ở mức độ thấp
- WH_MOUSE: Cài đặt một thủ tục móc theo dõi tin nhắn chuột
- WH_MOUSE_LL: Cài đặt một thủ tục móc theo dõi các sự kiện chuột đầu
vào ở mức độ thấp
- WH_MSGFILTER: Cài đặt một thủ tục móc theo dõi tin nhắn được tạo ra
như là kết quả của một sự kiện đầu vào trong hộp thoại, hộp thông báo, menu, hoặc
di chuyển một thanh