1. Trang chủ
  2. » Công Nghệ Thông Tin

Tìm hiểu về hook và kỹ thuật override hàm api

106 404 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 106
Dung lượng 332 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Từ đó, sẽ phát sinh vấn đề là người sử dụng sẽ cần tìm hiểu ý nghĩa của một từ, một câu hoặc cần phải dịch một đoạn văn bản, một file dữ liệu nào đó ra tiếng Việt và ngược lại. Đây là một nhu cầu cần thiết và hầu như xảy ra thường xuyên đối với nhiều người, do đó nhận dạng từ đặc biệt là nhận dạng từ trên màn hình trong môi trường Windows là việc làm cần thiết và có ý nghĩa thực tế.Kết quả của việc nhận dạng từ sẽ được dùng để xây dựng nên các ứng dụng khác chẳng hạn như các từ điển được tra cứu theo kiểu tương tác trực tiếp sẽ rất thuận tiện cho người sử dụng bởi vì theo cách này thì cho dù đang ở trong bất kỳ ứng dụng nào khi cần tra cứu thì thao tác trực tiếp ngay trên ứng dụng đang dùng tức là chỉ cần click chuột vào đó chứ không cần phải mở từ điển rồi tra cứu từ đó theo kiểu cổ điển.Vì thế, trong thời gian làm Luận Án Tốt nghiệp được sự hướng dẫn của thầy Lê Tấn Hùng nhóm sinh viên chúng tôi thực hiện đề tài: “ Nhận dạng từ dưới cursor mouse trên deskop Windows. Viết chương trình nhận dạng từ này ”. Trong giai đoạn đầu của Luận Án Tốt Nghiệp chúng tôi đã nghiên cứu được một số vấn đề quan trọng và căn bản có ý nghĩa trong việc thực hiện yêu cầu đã đặt ra của đề tài. Đề tài này chỉ tập trung nhận dạng từ ở dạng text trên desktop của môi trường Windows rồi xuất kết quả ra.

Trang 1

MỤC LỤC

LỜI MỞ ĐẦU

3

CHƯƠNG 1: TÌM HIỂU VỀ LẬP TRÌNH WINDOWS 4

I Khái quát về lập trình trong Windows 5

II Thông điệp và xử lý thông điệp 7III Giao diện thiết bị đồ họa GDI 11

V Chương trình Windows tiếp nhận thông điệp chuột22

6 - Giới thiệu một số hàm liên quan đến hook33

CHƯƠNG 3: KỸ THUẬT OVERRIDE HÀM API 36

I Khái quát về kỹ thuật override 37

II Lý do sử dụng kỹ thuật override trong lập trìnhWindows 37

III Cơ chế hoạt động và quản lý bộ nhớ trên

IV Cơ chế hoạt động và quản lý bộ nhớ trên

V Hiện thực kỹ thuật override trên Windows 16bits 45

VI Một số hàm được sử dụng trong kỹ thuật override50

CHƯƠNG 4: KẾT XUẤT VĂN BẢN TRONG WINDOWS 54

I Kết xuất văn bản trong Windows 55

II Các hàm căn bản để kết xuất văn bản 55CHƯƠNG 5: PHÂN TÍCH VÀ THIẾT KẾ CHƯƠNG TRÌNH 66

III Giới thiệu một số hàm có liên quan 78

IV Giới thiệu một số cấu trúc dữ liệu có liên quan92

Trang 2

Đề tài : Nghiên cứu các

phương pháp nhận dạng từ dưới cursor mouse trên Desktop Windows.

Viết chương trình nhận dạng từ này.

Trang 3

Lời Mở Đầu

gày nay, hầu như mọi công việc hàng ngày liên quanđến cuộc sống của chúng ta đều diễn ra trên máy tính

Từ việc soạn thảo văn bản, gởi nhận thông tinđến việc tra cứu, truy cập thông tin từ hệ thống mạngmáy tính toàn cầu Internet đối với người sử dụng làcông việc thường ngày và rất phổ biến

Từ đó, sẽ phát sinh vấn đề là người sử dụng sẽcần tìm hiểu ý nghĩa của một từ, một câu hoặc cầnphải dịch một đoạn văn bản, một file dữ liệu nào đó ratiếng Việt và ngược lại Đây là một nhu cầu cần thiếtvà hầu như xảy ra thường xuyên đối với nhiều người, dođó nhận dạng từ đặc biệt là nhận dạng từ trên mànhình trong môi trường Windows là việc làm cần thiết vàcó ý nghĩa thực tế

Kết quả của việc nhận dạng từ sẽ được dùng đểxây dựng nên các ứng dụng khác chẳng hạn như các từđiển được tra cứu theo kiểu tương tác trực tiếp sẽ rấtthuận tiện cho người sử dụng bởi vì theo cách này thì chodù đang ở trong bất kỳ ứng dụng nào khi cần tra cứu thìthao tác trực tiếp ngay trên ứng dụng đang dùng tức làchỉ cần click chuột vào đó chứ không cần phải mở từđiển rồi tra cứu từ đó theo kiểu cổ điển

Vì thế, trong thời gian làm Luận Án Tốt nghiệp đượcsự hướng dẫn của thầy Lê Tấn Hùng nhóm sinh viênchúng tôi thực hiện đề tài: “ Nhận dạng từ dưới cursormouse trên deskop Windows Viết chương trình nhận dạng từnày ” Trong giai đoạn đầu của Luận Án Tốt Nghiệpchúng tôi đã nghiên cứu được một số vấn đề quantrọng và căn bản có ý nghĩa trong việc thực hiện yêucầu đã đặt ra của đề tài Đề tài này chỉ tập trungnhận dạng từ ở dạng text trên desktop của môi trườngWindows rồi xuất kết quả ra

Trong thời gian làm Luận Án Tốt Nghiệp nhóm sinhviên chúng tôi đã tiến hành nghiên cứu cơ chế hoạtđộng và quản lý của hệ điều hành Windows Nghiêncứu về phương thức lập trình trong môi trường Windowsvà các phương tiện mà Windows hỗ trợ khi lập trình Thamkhảo và nghiên cứu kỹ thuật override các hàm giao tiếpcủa Windows ở chế độ 16 bit và 32 bit Nghiên cứu cáchxử lý các thông điệp trong Windows và tìm hiểu về cáchkết xuất văn bản, về chế độ ánh xạ, vấn đề tọa

Trang 4

độ và cách xử lý văn bản Trên cơ sở đó bướcđầu chúng tôi đã xây dựng xong một ứng dụng có khảnăng nhận dạng được từ trên nền Windows 16 bit đượcviết bằng ngôn ngữ Visual C++ version 1.5 và hướng pháttriển trong thời gian tới là hiện thực nó trên nền Win32.Báo cáo của chúng tôi sẽ lần lượt điểm qua nhữngnội dung mà chúng tôi đã nghiên cứu và tìm hiểu đượctrong thời gian qua Sau đó là phần giới thiệu chi tiết vềchương trình từ khâu phân tích-thiết kế cho đến phầnchương trình nguồn và cuối cùng sẽ là nêu những vấnđề còn tồn tại và hướng phát triển trong tương lai.

Trang 5

Chương 1:

TÌM HIỂU VỀ

LẬP TRÌNH WINDOWS

Trang 6

I - KHÁI QUÁT VỀ LẬP TRÌNH TRONG WINDOWS:

1 - Khái quát về lập trình trong Windows:

Môi trường lập trình Windows về cơ bản là dựa trênbộ hàm API (Application Programmer Interface), nó có chứcnăng như các ngắt trong bảng vector ngắt của DOS, nhưngnó thân thiện hơn ở chỗ cách gọi hàm API giống hệtcách gọi hàm của ngôn ngữ cấp cao, mỗi hàm có mộttên gọi hẳn hoi, và tên gọi thường được đặt rất phùhợp với công dụng của hàm (mặc dù có hơi dài dòng)từ đó tạo khả năng gợi nhớ cao Với Windows, người lậptrình không còn phải lập trình theo kiểu assembly nữa màlập trình theo kiểu ngôn ngữ cấp cao, mọi hoạt động trongmáy ở mức thấp từ hàm API trở xuống thuộc phạm vicủa Windows, và Windows không khuyến khích việc cácứng dụng can thiệp vào lĩnh vực này Bù lại, bằng cáchàm API, nó hỗ trợ rất hiệu quả cho người lập trình,giúp khai thác khả năng của thiết bị triệt để, dễ dàngvà tiện lợi hơn bao giờ hết Có thể nói Windows đã mở

ra cho người lập trình không gian rộng lớn để phát triểnứng dụng, và hạn chế không gian phát triển hệ thống.Điều này dẫn đến hệ quả là các ứng dụng được tạo rahết sức dễ dàng, và quan trọng là hệ thống chạy ổnđịnh hơn, không bị treo do lỗi của ứng dụng, khôngthể xâm nhập, nhưng sẽ rất khó khăn nếu người lậptrình muốn trực tiếp điều khiển hoạt động trong máy vàphát triển về lập trình hệ thống

- Tìm hiểu hàm Windows API: Windows là một hệ điều

hành đa nhiệm (multitasking) mà qua đó các ứng dụng ởtrong môi trường Windows sẽ giao tiếp với user thông quamột hay nhiều giao diện Để truy cập các giao diện nàythì các ứng dụng được xây dựng trên môi trường Windowssẽ sử dụng tập các hàm được gọi là giao diện chươngtrình ứng dụng API (Application Program Interface) Chương trìnhcủa người sử dụng có thể gọi tới các hàm API để truycập tới mọi tài nguyên của Windows GDI là một bộphận của API, giao diện thiết bị đồ họa GDI (Graphic DeviceInterface) có nhiệm vụ duy trì sự độc lập của Windows đối

Trang 7

với các thiết bị đồ họa hay còn gọi là khả năng độclập thiết bị (device independent) tức là cho phép Windowslàm việc với nhiều kiểu thiết bị đồ họa khác nhau.

2 - Thư viện liên kết động DLL (Dynamic Link Library):

Thư viện liên kết động là các tập tin được Windowslưu dưới dạng nhị phân chứa các hàm mà mọi ứngdụng trên Windows đều có thể sử dụng Nét đặc trưngcủa DLL là nó có thể được sử dụng bởi nhiều ứng dụngtại cùng một thời điểm hay nói cách khác thư viện liênkết động có thể cùng một lúc được gọi bởi nhiềuchương trình DLL là một dữ liệu chia sẻ được (shared data).Có 3 loại DLL khác nhau:

- Thư viện liên kết động API: thuộc hệ thống Windows,khi cài hệ điều hành thì nó đã có sẵn Chúng được nạpkhi Windows khởi động

- Thư viện liên kết động third party: do các công tykhác tạo ra trên môi trường Windows, hỗ trợ thêm côngtác lập trình trong Windows

- Thư viện liên kết động do chúng ta tạo ra

Windows sử dụng cấu trúc thư viện liên kết động DLL(Dynamic Link Library) nhằm mục đích không sao chép mộtkhối lượng lớn các mã vào trong chương trình như ở cácthư viện thông thường Nhờ cấu trúc động của DLL nênmọi chương trình đều có thể truy cập thư viện trong thờigian thực thi Các hàm API được Windows giữ dưới dạnghỗn hợp trong một số DLL Trong quá trình dịch khi gặplệnh gọi hàm API từ chương trình ứng dụng thì chương trìnhdịch không thêm mã này vào module thực hiện mà chỉthêm các lệnh liên kết (chứa tên của DLL bên trong cóhàm cần nạp) và tên hàm đó Khi thực thi chương trình thìhàm API thực sự mới được nạp vào bộ nhớ để thực hiện.Cùng với sự phát triển của Windows là sựï pháttriển của lập trình hướng đối tượng, và để hỗ trợ choviệc lập trình hướng đối tượng, Microsoft đã cung cấp chongười lập trình một bộ thư viện các lớp cơ bản để pháttriển các ứng dụng hướng đối tượng gọi là MFC (Microsoft

Trang 8

Foundation Classes), nội dung của nó bao gồm thông tin vềcác lớp cơ bản được chuẩn hóa như lớp application;document; view; OLE; cửa sổ; nút bấm; text; v.v…, trong cáclớp này mọi thứ liên quan đến nó (bao gồm dữ liệu vàcác chương trình xử lý của nó) đều được làm hoànchỉnh, người lập trình chỉ việc lấy ra sử dụng, hoặc cóthể thêm bớt một ít tính năng đặc trưng cho đối tượngcủa mình Mục tiêu chính của MFC là hệ thống hóa cáchàm API, cung cấp một thể thức gọi gọn các hàm API,cung cấp một “khung làm việc” (framework) cực mạnh đểngười lập trình không cần phải quan tâm đến nhữngđoạn chương trình thuộc về “thủ tục” mà chỉ cần quantâm đến phần cốt lõi để đạt được mục đích.

II - THÔNG ĐIỆP VÀ XỬ LÝ THÔNG ĐIỆP:

1 - Khái niệm:

Lập trình trên môi trường Windows khác với lập trình

ở các môi trường khác ở điểm là lập trình trênWindows luôn luôn gắn liền với những thông điệp Mọihoạt động xảy ra trên một chương trình Windows đềuthông qua các thông điệp Thông điệp sẽ được hệthống báo cho các ứng dụng biết các tác động từ bênngoài vào hệ thống Windows Một cửa sổ có thể gởi đimột thông điệp cho một cửa sổ khác và các cửa sổđáp ứng lại thông điệp bằng cách gởi đi một thôngđiệp khác cho một cửa sổ khác

Trong Windows có 3 loại thông điệp cơ bản:

- Những thông điệp tổng quát: có mã nhận diệnmang tiền tố WM_ được coi là phần lớn trong ứng dụngvà Windows đã cung cấp các hàm để giải quyết

- Những control notification: đây là những thông điệpWM_COMMAND được chuyển từ cửa sổ con tới cửa sổ bốmẹ

- Những nút lệnh: là thông điệp WM_COMMAND phát

đi từ trình đơn, từ các nút điều khiển Đây là loại thôngđiệp yêu cầu ứng dụng phải thực hiện một công việc gìđó

Trang 9

2 - Gởi đi các thông điệp:

Windows cho phép ứng dụng gởi đi những thông điệpcho mình, cho các ứng dụng khác hoặc cho hệ thống

Có 3 hàm Windows API để gởi thông điệp đi:

a) Hàm SendMessage:

Cú pháp:

LRESULT SendMessage(hwnd, uMsg, wParam, lParam)

HWND hwnd; // handle của cửa sổ nhận (đích)UINT uMsg; // thông điệp để gởi

WPARAM wParam; // thông số thông điệp đầu tiênLPARAM lParam; // thông số thông điệp thứ hai

- Hàm SendMessage gởi thông điệp tới một hay nhiềucửa sổ Hàm gọi thủ tục cửa sổ cho cửa sổ và khôngtrở về cho đến lúc thủ tục cửa sổ đã xử lý thôngđiệp

- Giá trị trả về: cho biết kết quả xử lý thông điệpvà phụ thuộc vào thông điệp được gởi

b) Hàm PostMessage:

- Cú pháp:

BOOL PostMessage(hwnd, uMsg, wParam, lParam)

HWND hwnd; // handle của của sổ đích

UINT uMsg; // thông điệp gởi

WPARAM wParam; // thông số thông điệp đầu tiênLPARAM lParam; // thông số thông điệp thứ hai

- Hàm PostMessage gởi (đặt) một thông điệp vàotrong hàng thông điệp cửa sổ và rồi trở về mà khôngđợi cửa sổ tương ứng xử lý thông điệp Những thôngđiệp trong một hàng thông điệp được lấy bằng cách gọihàm SetMessage hay PeekMessage

- Giá trị trả về: trả về khác 0 nếu thành công,ngược lại 0

c) Hàm SendDlgItemMessage:

- Cú pháp:

Trang 10

SendDlgItemMessage(hwndDlg,idDlgItem,uMsg,wParam,lParam)HWND hwndDlg; // handle của hộp hội thoại

int idDlgItem; // mã nhận diện ô điều khiển sẽnhận thông điệp

UINT uMsg; // thông điệp gởi đi

WPARAM wParam; // thông số thông điệp đầu tiên LPARAM lParam; // thông số thông điệp thứ hai

- Hàm SendDlgItemMessage gởi một thông điệp tớimột điều khiển trong hộp hội thoại

- Giá trị trả về: cho biết kết quả xử lý thông điệpvà phụ thuộc vào thông điệp được gởi

3 - Vòng lặp thông điệp:

Một thread hoặc một process đẩy một thông điệp rakhỏi hàng đợi bằng cách dùng vòng lặp thông điệp.Vòng loop chính của một ứng dụng đặt tại cuối hàmWinMain() của ứng dụng đó Vòng lặp thông điệp códạng như sau:

while GetMessage(&msg,NULL,0,0)

{ TranslateMessage(&msg);

DispatchMessage(&msg);

}

Sau đây là Sơ đồ dòng thông điệp:

Thread1 Message Queue Thread2 Message Queue Thread3 Message Queue

System Dispatcher

Hardware Event Occur

System Message Queue

GetMessage() TranslateMessage() Dispatch Message()

GetMessage() TranslateMessage() Dispatch Message()

GetMessage() TranslateMessage() Dispatch Message()

WndProc() WndProc() WndProc()

DefWndProc() DefWndProc() DefWndProc() Thread1 Hook Thread2 Hook Thread3 Hook

System Dispatcher

Trang 11

Nó mô tả đơn giản hóa quá trình xử lý thông điệp.Thông điệp có thể bắt nguồn từ nhiều cách khác nhau,

sơ đồ sau đây sẽ giải thích chi tiết hơn về vòng lặpthông điệp và chỉ ra cách thông điệp được đặt vàohàng đợi như thế nào:

Thông điệp không chỉ phát xuất từ sự kiện phầncứng, cũng có thể có thông điệp của chương trình phátxuất từ một chương trình đang chạy Các threads có thểgởi dữ liệu trở về sau và về trước bằng cách gởithông điệp Thông điệp có thể gởi vào hàng đợi bằnghàm PostMessage() , hoặc chúng có thể được gởi trựctiếp cho vòng lặp thông điệp để xử lý ngay lập tứcbằng hàm SendMessage()

Hardware Events

Message Sent

From Other Threads

System Dispatcher System Message Queue

Thread Message Queue

WndProc() Message Loop

PostMessage() TranslateMessage()

SentMessage()

SentMessage() (To Another Thread)

Other threads PostMessage() Other threads PostMessage()

Trang 12

4 - Xử lý thông điệp:

Việc xử lý thông điệp là yếu tố chính làm cho cácứng dụng Windows vận hành được Hệ thống và các ứngdụng khác sinh ra các thông điệp cho mọi sự kiện xuấthiện trong hệ thống thông điệp của Windows sẽ chophép Windows chạy đa nhiệm trong một thời điểm.Windows 95 và Windows NT mở rộng khả năng của versionWindows trước bằng việc cấp phát cho mỗi dòng xử lý(thread) hay mỗi tiến trình (proccess) một hàng đợi thôngđiệp riêng Trong version Windows cũ thì tất cả ứng dụngđều dùng chung một hàng đợi thông điệp, vì thế để cácứng dụng khác xử lý thông điệp, ứng dụng phải trảquyền điều khiển về cho Windows mỗi khi nó có thể VớiWindows 95 và Windows NT, điều này không còn nữa

Windows sinh ra thông điệp cho mọi sự kiện phần cứng,

ví dụ như người dùng nhấn một phím hoặc di chuyểnchuột Nó gởi thông điệp đến hàng đợi thông điệp củathread thích hợp, nếu thông điệp được dành cho nhiềuthread thì nó cũng được đưa vào các hàng đợi của cácthread đó

Một thông điệp trên thực tế là một cấu trúc dữliệu như sau:

typedef struct tagMSG {

HWND hwd; // handle cửa sổ UINT message; //số chỉ định loạimessage

WPARAM wParam; //được chuyển choWndProc()

LPARAM wParam; //được chuyển cho WndProc() DWORD time; //số mili giây từ lúcbắt đầu

POINT pt; //cấu trúc điểm POINT}

Trang 13

III - GIAO DIỆN THIẾT BỊ ĐỒ HỌA GDI

(GRAPHIC DEVICE INTERFACE):

1 - Khái niệm:

Windows là một hệ điều hành đa nhiệm (multitasking)trong đó các ứng dụng giao tiếp với user thông qua mộthay nhiều giao diện Để truy xuất các giao diện thì chươngtrình ứng dụng phải sử dụng các hàm Giao diện chươngtrình ứng dụng API là tập các lệnh mà một ứng dụngsử dụng để yêu cầu và tiến hành các dịch vụ cấpthấp được thi hành bởi Windows

Giao diện thiết bị đồ họa GDI (Graphic Device Interface)là một phần của API có nhiệm vụ duy trì sự độc lập củaWindows đối với các thiết bị đồ họa (cho phép Windowslàm việc với nhiều thiết bị đồ họa khác nhau) WindowsGDI là một thư viện bao gồm một số hàm giúp kếtxuất đồ họa (graphic output) lên màn hình, máy in…GDI sẽtạo ra: điểm, đường kẻ, hình dạng (shape: chữ nhật,tròn…), chữ văn bản

2 - Device Context:

Ngữ cảnh thiết bị DC (Device Context) là một phầnquan trọng của GDI Windows Một DC là một cấu trúc dữliệu dài khoảng 800 bytes được Windows duy trì có nhiệmvụ lo lưu giữ những thông tin cần thiết mà ứng dụng sẽcần đến khi phải hiển thị kết xuất lên một thiết bị vậtlý GDI không bao giờ cho phép chương trình làm việc trựctiếp với một DC mà GDI phân phối cho chương trình mộthandle để nhận dạng một DC cụ thể Tất cả các hàmAPI; GDI đều nhận thông số đầu tiên là một handle – hdc

DC là một công cụ chứa các thuộc tính vẽ, DC chophép kết nối logic một chương trình về một thiết bị cụthể nào đó Ngoài ra do Windows là một hệ điều hành

đa nhiệm nên các chương trình không thể truy xuất trựctiếp các thiết bị vật lý để tránh xung đột Thay vàođó, chương trình Windows phải sử dụng kết nối logic do DCđại diện Nghĩa là tất cả các chương trình cách tiếp cậnnày để GDI có thể giải quyết tranh chấp khi 2 chương

Trang 14

trình yêu cầu dùng cùng một thiết bị nên DC còn có vaitrò làm permission slip DC lưu trữ thông tin liên quan đếnmặt bằng vẽ và những khả năng của nó Trước khi sửdụng bất kỳ hàm vẽ GDI nào thì điều phải tạo một DCcho thiết bị, và khi sử dụng xong thì phải trả nó về choWindows nhằm đảm bảo cho hoạt động của hệ thốngđược thông suốt bởi vì số lượng DC mà Windows quản lýlà có giới hạn.

DC ở Win16: Ngữ cảnh thiết bị (DC) là một nối kếtgiữa một ứng dụng Windows, một driver thiết bị và mộtthiết bị đầu ra (output device) Windows duy trì một cachegồm 5 DC đặc biệt cho hoạt động hệ thống Ứng dụngphải giải phóng các DC này sau khi sử dụng

Luồng thông tin từ ứng dụng Windows qua DC và devicedriver tới thiết bị đầu ra:

Truy xuất thiết bị đầu ra (Accessing Output Devices): Bấtkỳ ứng dụng Windows nào cũng có thể sử dụng hàmGDI để truy xuất một thiết bị đầu ra GDI chuyển các gọiđộc lập thiết bị từ ứng dụng tới driver thiết bị Rồidriver thiết bị thông dịch các gọi đó vào trong sự hoạtđộng độc lập thiết bị

Những đặc tính của DC mô tả các đối tượng vẽ đượcchọn (pens và brushes), font được chọn và màu của nó,cách thức mà đối tượng được vẽ (hay ánh xạ) tới thiết

bị, vùng trên thiết bị có sẵn cho output (vùng xén) vànhững thông tin quan trọng khác Cấu trúc chứa nhữngđặc tính DC được gọi là khối dữ liệu DC

Windows

Applicatio

n

GDIDevice Context

DeviceDriver OutputDevice

DeviceDriver

OutputDeviceOutputDevice

Trang 15

3 - Chế dộ ánh xạ (mapping mode):

Để duy trì sự độc lập thiết bị, GDI tạo ra output ởkhông gian luận lý và ánh xạ nó lên màn hình Chế độánh xạ cho biết mối quan hệ giữa không gian luận lý vànhững pixel trên thiết bị

Có tới 8 chế độ ánh xạ khác nhau nhưng chúng tôichỉ quan tâm tới chế độ ánh xạ MM_TEXT vì đây là chếđộ ánh xạ mặc định Trong chế độ này một đơn vị luậnlý được ánh xạ tới một pixel trên thiết bị hay màn hình.Như vậy đơn vị tính luận lý là pixel và các tọa độ x, ycũng được tính theo pixel, trị x tăng khi qua phải và giảmkhi qua trái, trị y tăng khi đi xuống và giảm khi đi lên.Origin của hệ thống tọa độ là góc trái-trên (upper-left)của màn hình

4 - Hệ thống tọa độ windows:

Windows sử dụng các hệ thống tọa độ khác nhau tùytheo hoàn cảnh như:

Hệ toạ độ thiết bị (Device coordinate system)

- Hệ toạ độ toàn màn hình (Full screen coordinatesystem)

- Hệ toạ độ vùng client (Client area coordinate system)

- Hệ toạ độ toàn cửa sổ (Whole window coordinatesystem)

- Hệ toạ độ logic (Logical coordinate system)

Trong phạm vi ứng dụng của đề tài chúng tôi chỉquan tâm đến các hệ toạ độ :

a) Full screen coordinate system:

Là hệ thống tọa độ thiết bị liên quan tới trọn mànhình Tọa độ màn hình được tính theo pixel và chọn tọa độ(0,0) làm góc upper-left của màn hình Hệ thống này sửdụng khi liên quan đến trọn màn hình trên tọa độ màn

Trang 16

hình Thường vị trí của một đối tượng như con nháy hoặccon trỏ hoặc cửa sổ so với góc upper-left của màn hìnhthì dùng hệ tọa độ này.

b) Client area coordinate system:

Cũng là hệ tọa độ thiết bị, nó khác với hệ tọa độtrọn màn hình ở origin của hệ tọa độ Tọa độ trọn mànhình là tương đối so với upper-left của màn hình còn tọađộ vùng client là tương đối so với upper-left của vùngclient Tọa độ này cũng tính theo device unit (pixel) giống nhưtọa độ màn hình

Hàm ClientToScreen để chuyển tọa độ vùng client quatọa độ trọn màn hình

Hàm ScreenToClient chuyển tọa độ trọn màn hình quatọa độ vùng client

c) Whole window coordinate system:

Gần giống hệ tọa độ vùng client, là tương đối so vớigóc upper-left của cửa sổ, được sử dụng khi vẽ vùngnonclient của cửa sổ

Dùng hàm DPtoLP để chuyển tọa độ thiết bị sang hệtọa độ logic

Dùng hàm LPtoDP để chuyển tọa độ logic sang hệ tọađộ thiết bị

Như vậy điều quan trọng trong việc tính toán sử dụnghệ tọa độ là phải kiểm soát được việc sử dụng các hệtọa độ một cách đồng bộ bởi vì việc chuyển đổi giữacác hệ tọa độ đã được cung cấp bởi các hàm nêutrên

Trang 17

5 - Viewport và window:

Mapping mode cho biết ánh xạ tọa độ logic và nhữngkích thước được cung cấp khi gọi các hàm GDI qua hệthống tọa độ thiết bị gắn liền với DC Tức là mappingmode quyết định GDI ánh xạ việc ánh xạ một window (tọađộ logic) qua một viewport (tọa độ thiết bị) Viewport nghĩalà một vùng hình chữ nhật của hệ thống tọa độ thiết

bị được định nghĩa bởi một DC còn window khi sử dụng đểqui chiếu GDI mapping mode là một hình chữ nhật của hệthống tọa độ logic được định nghĩa bởi một DC

Công thức để chuyển đổi một hệ tọa độ window(logic) qua một hệ tọa độ viewport (thiết bị):

xviewport = (xwindow - xwindowOrg)(xviewportExt / xwindowExt) + xviewportOrg

yviewport = (ywindow - ywindowOrg)(yviewportExt / ywindowExt) + yviewportOrg

Công thức sử dụng 2 điểm cho biết extent của mộtvùng theo tọa độ logic (xwindowExt,ywindowExt) và củamột vùng theo hệ tọa độ thiết bị(xviewportExt,yviewportExt)

Tỉ lệ của (viewpot extent / window extent) là hệ sốscaling dùng để dịch đơn vị logic qua đơn vị thiết bị

Việc chuyển đổi ngược lại tương tự bằng các biếnđổi công thức trên

IV - CỬA SỔ TRONG WINDOWS:

Cửa sổ là khái niệm cơ bản trong giao diện GDI củaWindows, nó là một kiến trúc chuẩn mực để từ đó xây

Trang 18

dựng nên các đối tượng khác như: cửa sổ chính của ứngdụng (main frame); text box; edit control; button; combo box;menu; scroll bar; nói chung là toàn bộ những công cụtạo nên giao diện GDI đều có thể gọi là cửa sổ Cũngcó thể xem cửa sổ như vùng chữ nhật màn hình mà nơiđó ứng dụng in ra các kết xuất và nhận các dữ liệutừ người dùng.

Windows quản lý tất cả cửa sổ hiện có trong hệthống bằng cách gán cho mỗi cửa sổ một handle (trênthực tế nó là một số nguyên)ø, ta chỉ cần có đượchandle cửa sổ thì có thể thao tác mọi thứ trên cửa sổđó

Một cửa sổ chia sẻ màn hình với các cửa sổ khác,kể cả các cửa sổ của ứng dụng khác Chỉ có mộtcửa sổ trong một thời điểm có thể nhận dữ liệu nhậptừ người dùng Người dùng có thể dùng chuột, bànphím, hay các thiết bị nhập khác để tương tác với cửasổ này và ứng dụng sở hữu nó

1 - Các loại cửa sổ:

Windows cung cấp nhiều kiểu cửa sổ khác nhau đểcó thể kết hợp hình thành nên các hình thức cửa sổkhác nhau Các kiểu được sử dụng trong hàmCreateWindow khi cửa sổ được tạo

Một số kiểu cửa sổ sau:

- Cửa sổ chồng lên nhau (Overlapped windows hay level window): là cửa sổ không bao giờ có cửa sổ chamẹ

top Cửa sổ bị sở hữu (Owned windows): là kiểu đặcbiệt, được sở hữu bởi một cửa sổ bị chồng

- Cửa sổ pop-up: là kiểu đặc biệt của cửa sổoverlapped nhưng có thể có hoặc không title bar

- Cửa sổ con: là cửa sổ xác định vùng client củacửa sổ cha mẹ, được sử dụng để chia vùng client củacửa sổ cha mẹ ra thành các vùng chức năng khác nhau.Một ứng dụng dùng hàm ShowWindow để cho thấy hay chedấu một cửa sổ con Mỗi cửa sổ con phải có một cửa

Trang 19

sổ cha mẹ Cửa sổ cha mẹ nhường một phần trong vùngcủa nó cho cửa sổ con và cửa sổ con sẽ nhận tất cảcác tác động từ bên ngoài vào vùng này Một cửa sổcon có thể có nhiều cửa sổ con khác và mỗi cửa sổcon đều có cho riêng nó một handle riêng để giao dịchkhi gởi thông điệp cho cửa sổ cha mẹ Mỗi cửa sổ conlà một cửa sổ độc lập, nó nhận tác động bên ngoàicủa riêng nó và các thông điệp khác Những input gởicho cửa sổ con được đi trực tiếp tới cửa sổ con và khôngchuyển qua cửa sổ cha mẹ ngoại trừ trường hợp cửa sổcon bị hàm EnabledWindow cho disabled Trong trường hợpnày thì Windows chuyển bất kỳ input nào tới cửa sổ conđó cho cửa sổ cha mẹ của nó Điều này cho phép cửasổ cha mẹ kiểm tra được input và làm cho cửa sổ con ởtrạng thái enabled nếu nó thấy điều đó là cần thiết.Những hoạt động của cửa sổ cha mẹ cũng ảnhhưởng đến cửa sổ con như sau:

- Shown: Cửa sổ cha mẹ sẽ được hiển thị trước cửasổ con

- Hidden: Cửa sổ cha mẹ sẽ bị che sau cửa sổ con.Cửa sổ con sẽ được nhìn thấy (hết bị che) (visible) chỉ khicửa sổ cha mẹ được nhìn thấy

- Destroyed: Cửa sổ cha mẹ bị huỷ sau cửa sổ con

- Moved: Cửa sổ con bị di chuyển cùng với vùng clientcủa cửa sổ cha mẹ Cửa sổ con đáp ứng cho việc tô vẽsau khi di chuyển

- Gia tăng kích thước hay ở trạng thái kích thước cựcđại: tô vẽ bất kỳ phần nào của cửa sổ cha mẹ mà đãđược phơi bày ra như là kết quả của kích thước tăng lêncủa vùng client

Windows không tự động xén (clip) một cửa sổ con rakhỏi vùng client của cửa sổ cha mẹ Điều này nghĩa làcửa sổ cha mẹ vẽ lên trên cửa sổ con nếu nếu nótiến hành bất kỳ sự tô vẽ nào trong cùng vị trí với vịtrí của cửa sổ con Windows chỉ xén cửa sổ con ra khỏivùng client của cửa sổ cha mẹ nếu cửa sổ cha mẹ cókiểu WS_CLIPCHILDREN Nếu cửa sổ con bị xén thì cửa sổ

Trang 20

cha mẹ không thể tô vẽ lên nó Một cửa sổ con cóthể chồng lên các cửa sổ con khác trong cùng vùngclient Cửa sổ anh em (cùng cha mẹ) có thể tô vẽ trongmỗi vùng client của các cửa sổ khác trừ khi một cửasổ con có kiểu WS_CLIPSIBLINGS Nếu ứng dụng xác địnhkiểu này cho một cửa sổ con thì bất kỳ phần nào củacửa sổ anh em của cửa sổ con đó nằm trong cửa sổnày đều bị xén Nếu một cửa sổ có kiểuWS_CLIPCHILDREN hoặc WS_CLIPSIBLINGS thì một mất mátnhỏ trong sự thực hiện (performance) xảy ra Mỗi cửa sổchiếm tài nguyên hệ thống bởi vậy ứng dụng sẽkhông sử dụng các cửa sổ con một cách bừa bãi Đểhoạt động tối ưu một ứng dụng cần chia luận lý cửa sổchính của nó trong thủ tục cửa sổ của cửa sổ chính cònhơn là dùng các cửa sổ con.

2 - Thủ tục cửa sổ (Window Procedures):

Một thủ tục cửa sổ xử lý tất cả những thông điệpđược gởi tới tất cả các cửa sổ trong lớp được đưa ra.Windows gởi các thông điệp tới thủ tục cửa sổ khi nónhận input từ user có ý định chuyển cho cửa sổ được đưa

ra hay khi nó cần thủ tục để thực hiện một vài hànhđộng trên cửa sổ của nó như việc tô vẽ lại bên trongvùng client

Thủ tục cửa sổ nhận các kiểu thông điệp như: nhậpvào từ bàn phím, chuột; yêu cầu tiêu đề cửa sổ;tường thuật sự thay đổi gây ra bởi cửa sổ khác (như thayđổi file WIN.INI); cơ hội sửa đổi đáp ứng hệ thống tiêuchuẩn đến những hoạt động chắc chắn (như điều chỉnhmenu trước lúc hiển thị); yêu cầu thực hiện một vàihành động trên cửa sổ hay vùng client của nó (cậpnhật vùng client); thông tin về tình trạng của nó trongmối quan hệ với các cửa sổ khác (truy xuấ nhất địnhthất bại của nó tới bàn phím hay trở thành cửa sổ hoạtđộng)

Một thủ tục cửa sổ nhận hầu hết các thông điệplà từ Windows nhưng nó cũng có thể nhận thông điệptừ các cửa sổ khác gồm cả những cửa sổ nó sởhữu Những thông điệp này có thể là những yêu cầu

Trang 21

về thông tin hay thông báo mà một sư kiện được đưa rađã xảy ra trong một cửa sổ khác Một thủ tục cửa sổtiếp tục nhận thông điệp fừ hệ thống và có thể chấpnhận những cửa sổ khác trong hệ thống cho đến khi thủtục cửa sổ, thủ tục cửa sổ của một cửa sổ cha mẹ hayhệ thống hủy cửa sổ Ngay cả khi cửa sổ ở trong quátrình đang bị hủy, thủ tục cửa sổ nhận những thôngđiệp thêm vào đưa tới nó cơ hội để tiến hành bất kỳnhiệm vụ làm sạch (cleanup) nào trước lúc kết thúc.Những thông điệp này gồm WM_ , WM_DESTROY,WM_QUERYENDSESSION và WM_ENDSESSION Nhưng khi cửasổ bị hủy thì không có thêm thông điệp nào được đưatới thủ tục cho cửa sổ cụ thể đó Nếu có nhiều hơnmột cửa sổ của lớp, tuy nhiên, thủ tục cửa sổ tiếp tụcnhận thông điệp cho những cửa sổ khác cho đến khicũng chính chúng bị hủy Một thủ tục cửa sổ chỉ rõlàm thế nào tất cả cửa sổ của một cửa sổ đưa rathực sự có hành vi bằng cách đáp ứng những gì cáccửa sổ tạo ra những lệnh từ user hay hệ thống Thủ tụccửa sổ phải kiểm tra những thông điệp mà nó nhậntừ hệ thống và quyết định bất kỳ hành động gì sẽdiễn ra Thủ tục cửa sổ cũng có thể chọn không đápứng một thông điệp được đưa ra Nếu không đáp ứngthủ tục phải chuyển thông điệp tới hàm DefWindowProcđể đưa cho hệ thống cơ hội để đáp ứng Hàm này thựchiện hành động có sẵn trên cơ sở thông điệp được đưa

ra và những thông số của nó Nhiều thông điệp (đặcbiệt là thông điệp vùng non-client) phải được xử lý vìthế DefWindowProc được yêu cầu trong tất cả các thủ tụccửa sổ

Thủ tục cửa sổ cũng nhận các thông điệp mà thựcsự đã dự định được xử lý bởi hệ thống Những thôngđiệp vùng-nonclient thông báo cho thủ tục biết user thựchiện một vài hành động trong vùng client của cửa sổhoặc một vài thông tin về cửa sổ được yêu cầu bởihệ thống để thực hiện một hành động Mặc dùWindows chuyển những thông điệp này tới thủ tục cửasổ thì thủ tục sẽ chuyển chúng cho hàm DefWindowProcvà không cố gắng xử lý chúng Ở trường hợp này thủ

Trang 22

tục cửa sổ phải phớt lờ thông điệp hay trả về khôngchuyển nó tới DefWindowProc.

3) Thông điệp cửa sổ:

Một thông điệp cửa sổ là một tập những giá trịmà Windows gởi tới thủ tục cửa sổ để cung cấp inputcho cửa sổ hay yêu cầu cửa sổ thực hiện một vài hànhđộng Windows tính đến một sự thay đổi rộng khắp nhữngthông điệp mà nó hay ứng dụng của nó có thể gởi tớithủ tục cửa sổ Hầu hết những thông điệp được gởitới cửa sổ như là kết quả của hàm đưa ra đang đượcthực thi hay như là kết quả của input từ user Mỗi thôngđiệp gồm 4 giá trị: một handle xác định cửa sổ, mộtdanh hiệu thông điệp, một giá trị thông điệp-đặc biệt16-bit và một giá trị thông điệp-đặc biệt 32-bit Nhữnggiá trị này được chuyển tới thủ tục cửa sổ như lànhững thông số riêng lẻ Rồi thủ tục cửa sổ kiểm tradanh hiệu thông điệp để quyết định những đáp ứng gìphải làm và làm thế nào để thông dịch giá trị 16-bitvà 32-bit

Cú pháp thủ tục cửa sổ:

- LONG FAR PASCAL WndProc(hwnd, wMsg, wParam, lParam)

WORD wParam;

DWORD lParam;

Các thông số:

hwnd cho biết cửa sổ nhận thông điệp

wMsg loại thông điệp

wParam thông tin thông điệp-đặc biệt thêmvào 16-bit

lParam thông tin thông điệp-đặc biệt thêmvào 32-bit

Hàm trả về giá trị 32-bit cho biết kết quả xử lýthông điệp

Trang 23

4 - Default window procedure:

Hàm DefWindowProc là phần xử lý thông điệp cósẵn cho những thủ tục cửa sổ không hay không thể truyxuất một vài thông điệp được gởi tới cho chúng Hầuhết các thủ tục cửa sổ thì hàm DefWindowProc thực hiệnhầu hết, nếu không muốn nói là tất cả, việc xử lýthông điệp vùng client Đây là các thông điệp biểuhiện những hành động được thực hiện trên các phầnkhác của cửa sổ hơn là vùng client

5 - Vấn đề tô vẽ màn hình:

Khi một cửa sổ bị di chuyển thì Windows tự động saochép nội dung của vùng client tới vị trí mới Điều nàytiết kiệm thời gian bởi vì một cửa sổ không phải tínhtoán lại và vẽ lại nội dung của vùng client như là phầncủa sự di chuyển Nếu cửa sổ di chuyển hay thay đổi kíchthước thì Windows chỉ sao chép phần lớn vùng client trướcđó khi nó cần điền vị trí mới Nếu cửa sổ gia tăng kíchthước thì Windows sao chép toàn bộ vùng client và gởithông báo WM_PAINT tới cửa sổ để điền vào trong vùngđược phơi bày mới hơn Khi cửa sổ bị di chuyển thì Windowscho rằng nội dung của vùng client vẫn hợp lệ và có thểđược sao chép không cần thay dổi tới vị trí mới Tuynhiên với một vài cửa sổ thì nội dung của vùng clientkhông còn hợp lệ sau khi di chuyển đặc biệt là nếu dichuyển luôn sự thay đổi kích thước Để tô vẽ lại toànbộ vùng client thay cho sao chép nội dung trước đó mỗilần một cửa sổ thay đổi kích thước thì một cửa sổ sẽxác định kiểu CS_VREDRAW và trong lớp cửa sổ

Để quản lý hiển thị màn hình, Windows tiến hànhnhiều hoạt động ảnh hưởng tới nội dung của vùng client.Nếu Windows di chuyển, định kích thước hay thay đổi bềmặt màn hình, sự thay đổi có thể ảnh hưởng cửa sổđược đưa ra Nếu vậy, Windows đánh dấu vùng bị thay đổibằng hoạt động sẵn sàng cho việc cập nhật và ở cơhội tiếp theo nó gởi thông điệp WM_PAINT tới cửa sổ vìthế nó có thể cập nhật cửa sổ trong vùng cần cậpnhật Nếu một cửa sổ vẽ trong vùng client của nó thìnó phải gọi BeginPaint để lấy handle của ngữ cảnh màn

Trang 24

hình, phải cập nhật vùng bị thay đổi như đã định nghĩabởi vùng cập nhật và cuối cùng nó phải gọi EndPaintđể hoàn tất công việc Một cửa sổ có thể vẽ trongvùng client của nó bất kỳ lúc nào tức là ngoài thờiđiểm mà nó đáp ứng thông điệp WM_PAINT chỉ cần nólấy ngữ cảnh màn hình cho vùng client trước lúc nó tiếnhành vẽ.

Thông điệp WM_PAINT: là một yêu cầu của Windowstới một cửa sổ để cập nhật màn hình cửa nó Windowsgởi WM_PAINT bất cứ khi nào cần vẽ một phần lại cửasổ Khi cửa sổ nhận thông điệp WM_PAINT thì nó sẽ lấyvùng cập nhật bằng hàm BeginPaint và nó sẽ tiếnhành bất kỳ hoạt động gì cần thiết để cập nhật phầnđó của vùng client

InvalidateRect và InvalidateRgn thực sự không sinh rathông điệp WM_PAINT Windows tích luỹ những thay đổiđược tạo ra bởi các hàm này và những thay đổi củariêng nó trong lúc một cửa sổ xử lý những thông điệpkhác trong hàng thông điệp của nó Làm trễ WM_PAINTlàm cho cửa sổ xử lý tất cả những thay đổi cùng mộtlúc thay vì cập nhật những những mẫu nhỏ trong nhữngbước riêng lẻ làm lãng phí thời gian

Để chỉ thị Windows gởi thông điệp WM_PAINT mộtứng dụng có thể sử dụng UpdateWindow, hàm này gởithông điệp trực tiếp tới cửa sổ, bất chấp những thôngđiệp khác trong hàng thông điệp của ứng dụng.UpdateWindow được sử dụng khi một cửa sổ cần cậpnhật vùng client của nó ngay lập tức (chẳng hạn chỉngay sau cửa sổ được tạo) Khi một cửa sổ nhậnWM_PAINT nó phải gọi BeginPaint để lấy ngữ cảnh mànhình cho vùng client và lấy thông tin khác như vùng cậpnhật và background bị xóa hay không Windows tự độngchọn vùng cập nhật như là vùng xén của ngữ cảnhmàn hình GDI huỷ bỏ (xén) những gì được vẽ bên ngoàivùng xén chỉ những gì ở bên trong vùng cập nhật làthực sự nhìn thấy được BeginPaint xóa vùng cập nhật đểngăn chặn vùng giống nhau từ việc sinh ra các thông

Trang 25

điệp WM_PAINT đến sau Sau khi vẽ xong Windows phải gọihàm EndPaint để giải phóng DC.

Vùng cập nhật: Một vùng cập nhật xác định phầncủa vùng client được đánh dấu cho việc vẽ cho thôngđiệp WM_PAINT kế tiếp Mục đích của vùng cập nhật làđể lưu các ứng dụng thời điểm nó đưa ra để vẽ toànbộ nội dung của vùng client Nếu chỉ có phần mà cầnvẽ được cộng vào vùng cập nhật thì chỉ có phần đóđược vẽ

Hàm InvalidateRect và InvalidateRgn cộng một hình chữnhật hay một vùng vào vùng cập nhật Hình chữ nhậthay vùng phải được đưa ra ở trong tọa độ client Vùng cậpnhật bản thân nó được định nghĩa trong tọa độ client.Windows cộng những vùng và hình chữ nhật của chínhnó vào một vùng cập nhật của cửa sổ sau khi nhữnghoạt động như di chuyển, định kích thước và cuộn cửasổ

Hàm ValidateRect và ValidateRgn xóa một hình chữnhật hay một vùng ra khỏi vùng cập nhật Những hàmnày được sử dụng điển hình khi cửa sổ đã cập nhậtmột phần đặc biệt của màn hình trong vùng cập nhậttrước khi nhận thông điệp WM_PAINT

Hàm GetUpdateRect lấy hình chữ nhật nhỏ nhất baolấy toàn bộ vùng cập nhật Hàm GetUpdateRgn lấyvùng cập nhật chính nó Những hàm này có thể đượcsử dụng để tính toán kích thước hiện hành của vùngcập nhật để quyết định những công việc vẽ nào đượcyêu cầu

V – CHƯƠNG TRÌNH WINDOWS TIẾP NHẬN THÔNG ĐIỆP CHUỘT:

Giới thiệu dòng chảy dữ liệu thông điệp nhập từ con chuột:

Hardware event queue

Device driverMouse DispatchMessage()GetMessage()

WindowProc()

DefWindowProc()

Hook chainVirtual &

Scan code

Trang 26

1 - Mouse:

Khi mouse báo vị trí của mình (vị trí cursor) và có tácđộng lên mouse thì một tín hiệu được phát đi từ mousegây ra một ngắt quãng, mouse driver giải quyết ngắtquãng này

2 - Mouse device driver:

Khi Windows khởi động thì mouse driver tự động nạpvào và kiểm tra xem có chuột hay không Nếu có thìWindows gọi driver cung cấp một thủ tục để báo cáo cácbiến cố xảy ra trên chuột Khi có một mouse event thìdriver thông báo cho Windows biết Nếu event là di chuyểnmouse thì ưu tiên đáp ứng vị trí con trỏ di chuyển ngay lúcngắt Còn lại tất cả các event khác đều được đưa vàohardware event queue

3 - Hardware event queue:

Các mouse event được đưa vào hardware event queuechờ giao cho message loop của chương trình giải quyết Queunày là một vùng đệm có thể chứa tối đa 120 event.Những event trong queue chưa thuộc một chương trình cụthể nào cho tới khi nó được tiếp nhận bởi hàmGetMessage() Điều này đảm bảo cho hệ thống hoạt độngđúng đắn Sau đó là vòng lặp GetMessage()

Trang 27

4 - GetMessage() loop:

GetMessage() loop đưa các thông điệp vào xử lý.GetMessage() sẽ quyết định chương trình nào sẽ tiếp nhậnthông điệp bằng cách xem chương trình nào sở hữu cửasổ mà con trỏ chuột nằm trên đó Tùy theo vị trí củacon trỏ mà phát sinh hai loại thông điệp: thông điệpvùng client và thông điệp vùng non-client Muốn biếtcursor ở vùng nào thì GetMessage() chuyển đi một thôngđiệp WM_NCHITTEST cho thủ tục cửa sổ Hàm GetMessage()dựa vào cơ chế pull-model để đọc thông tin tình huốngtrong queue và lại dựa vào push-model để biết vị trí củacursor Tức là GetMessage() sẽ gọi thủ tục cửa sổ như làmột chương trình thường trú vậy GetMessage() sử dụnghàm SendMessage() để gọi thủ tục cửa sổ Trị trả vềnằm trong phạm vi của thông điệp WM_NCHITTEST màGetMessage() gởi cho thủ tục cửa sổ của ta WM_NCHITTESTlà thông điệp đến đầu tiên trong hàng loạt thông điệpmà mouse phát ra Nó yêu cầu thủ tục cửa sổ nhậndiện vị trí cursor Đa số chương trình chuyển thông điệpnày cho DefWindowProc() lo tìm vị trí cursor và cung cấp mộthit-test code như là trị trả về

Khi DefWindowProc() trả về kết quả khác HTCLIENT,HTERROR, HTNOWHERE, HTTRANSPARENT thì cursor nằm trênvùng non-client thì Windows sẽ phát đi thông điệp non-client

Còn khi DefWindows trả về kết quả HTCLIENT thì cursornằm trên vùng client và những thông điệp do Windowsphát đi lúc này thì sẽ được trình ứng dụng xử lý

Hàm SendMessage() sẽ sử dụng mã hit-test code đểquyết định xem loại thông điệp chuột nào mà cho phátsinh Khi hit-test code bằng HTCLIENT thì một thông điệpvùng client sẽ được phát sinh còn tất cả các hit-test codekhác sẽ phát sinh ra những thông điệp chuột vùng non-client

Trước khi SendMessage() trả về một thông điệp chuộtcho chương trình của ta thì có một việc mà hàm này phảithi hành: nó phải bảo đảm là hình dáng cursor phù hợp

vị trí hiện thời của mouse Muốn thế nó phải gởi đi một

Trang 28

thông điệp khác cho thủ tục cửa sổ WM_GETCURSOR.Tương tự như thông điệp WM_NCHITTEST đa số chương trìnhphớt lờ thông điệp này và giao cho DefWindowProc() thựchiện Mã hit-test code được cho ở trong byte thấp củathông số lParam để cho DefWindowProc() biết mà thiết đặthình dáng của con trỏ.

Hai thông điệp WM_NCHITTEST và WM_SETCURSOR baogiờ cũng đi trước một thông điệp chuột Vì Windows phảitìm ra xem vị trí cursor hiện ở trong vùng client hay vùngnon-client để phát ra thông điệp vùng client hay thôngđiệp vùng non-client một cách thích hợp Một khi đã đượcnhận diện thì Windows phải đảm bảo là người sử dụngnhận được hình dáng cursor thích hợp

Windows cho phép đặt message hook để thay đổi dòngchảy các thông điệp Một WH_GETMESSAGE hook có thểthay đổi dòng chảy của bất cứ thông điệp chuột củavùng client hoặc vùng non-client Khi GetMessage() sẵn sàngđem một thông điệp vào chương trình của ta thì nó sẽ gọihook xem có thay đổi gì không trước khi thông điệp đượcchuyển cho chương trình

Khi GetMessage() đã đưa thông điệp vào chương trìnhrồi thì thông điệp sẽ được trao trực tiếp cho thủ tục cửasổ thích hợp bởi hàm DispatchMessage() Bây giờ thôngđiệp đã nằm trong thủ tục cửa sổ

5 - Thủ tục cửa sổ:

Hơn 20 thông điệp của Windows về chuột (trừWM_NCHITTEST) thì có 10 thông điệp thuộc vùng non-client

do DefWindowProc() giải quyết Hai thông số wParam, lParamcủa thủ tục cửa sổ sẽ cho biết thông tin về thôngđiệp Trị của hai thông số lParam và wParam đều tương tựnhau cho các thông điệp chuột trên vùng client

Trị của thông số lParam chứa vị trí cursor theo tọa độcủa vùng client Tọa độ này cho origin về góc upper-leftcủa vùng client với đơn vị tính là pixel Trị x nằm ở wordthấp còn y nằm ở word cao của lParam

Trang 29

Trị của wParam là một lô cờ hiệu mô tả trạng tháicủa các nút chuột cũng như trạng thái các nút <Ctrl>,

<Shift>

6 – DefWindowProc():

Đối với chuột thì DefWindowProc() không quan tâm đếnnhững thông điệp thuộc vùng client mà chỉ quan tâmđến những thông điệp thuộc vùng non-client

DefWindowProc() có nhiệm vụ cung cấp một giao diệnchung cho bàn phím và con chuột bằng cách dịch phầnnhập liệu từ bàn phím hoặc con chuột thành các lệnhhệ thống (system command) và cho hiện lên như cácthông điệp WM_SYSCOMMAND Cuối cùng DefWindowProc()giải quyết các thông điệp WM_NCHITTEST vàWM_SETCURSOR cung cấp trước cho các thông điệp chuộtkhác

Trang 30

Chöông 2:

TÌM HIEÅU VEÀ

HOOKS

Trang 31

Hook là một cơ chế cực mạnh cho phép ta cài đặt mộtthủ tục để điều khiển hoặc chận hứng các thông điệptrước khi các thông điệp này tới được nơi tiếp nhận.

Hay nói một cách khác hook là một điểm trong kỹthuật message-handling hệ thống, nơi mà một ứng dụngcó thể đặt một thủ tục để quản lý sự lưu thông củacác thông điệp trong hệ thống và xử lý một kiểuthông báo nào đó trước khi chúng tới được thủ tục cửasổ đích

Do có khả năng can thiệp mạnh nên hook có xuhướng làm chậm lại hệ thống vì chúng làm tăng sốlượng các hoạt động của hệ thống đối với mỗi thôngđiệp Chỉ đặt hook khi thực sự cần thiết và dỡ bỏchúng khi không cần đến

1 - Chuỗi hook:

Hệ thống cho phép nhiều kiểu hook khác nhau: mỗikiểu cung cấp việc truy xuất tới một khía cạnh khác nhaucủa kỹ thuật message-handling Chẳng hạn, một ứng dụngcó thể sử dụng hook WM_MOUSE để quản lý nhữngthông điệp chuột trong luồng thông điệp

Hệ thống duy trì một chuỗi hook riêng lẻ đối vớimỗi kiểu hook Một chuỗi hook là một danh sách cácpointer chỉ tới các hàm callback application-defined đặcbiệt mà những hàm này gọi các thủ tục hook Khi mộtthông điệp xảy ra là nó đã được tổ chức với một kiểuhook cụ thể, hệ thống chuyển thông điệp tới mỗi thủtục hook có mặt trong chuỗi hook, theo trật tự cái nọ saucái kia Hoạt động của một thủ tục hook có thể phụthuộc vào kiểu hook mà nó liên quan Các thủ tục hookcho một vài kiểu hook có thể chỉ quản lý những thôngđiệp; những cái khác có thể thay đổi những thông điệphay dừng sự phát triển của nó trong chuỗi, ngăn chặnchúng tìm tới thủ tục hook kế tiếp hay cửa sổ cuối cùng(đích)

2 – Thủ tục hook:

Để có được sự tiện lợi của một loại hook chi tiết,người lập trình cung cấp một thủ tục hook và sử dụng

Trang 32

hàm SetWindowsHookEx để đặt nó vào trong chuỗi hook.

Một thủ tục hook có cú pháp:

- LRESULT CALLBACK HookProc (

Int nCode, WPARAM wParam, LPARAM lParam

);

HookProc là một placeholder cho một ứng dụng đã

được định nghĩa trước

Thông số nCode là một mã hook phụ thuộc vào kiểu

hook; mỗi kiểu có một tập các đặc tính các mã hook

Những giá trị của thông số wParam và lParam phụ thuộc

vào mã hook, nhưng điển hình thì chúng chứa thông tin vềmột thông điệp được send hay được post Hàm

SetWindowsHookEx luôn luôn đặt một thủ tục hook ở

đầu một chuỗi hook Khi một sự kiện xảy ra mà sự kiệnnày được quản lý bởi một kiểu hook cụ thể thì hệthống gọi thủ tục ở đầu chuỗi hook đã được tổ chức.Mỗi thủ tục hook trong chuỗi quyết định nên chuyển haykhông chuyển sự kiện tới thủ tục tiếp theo Một thủ tụchook chuyển một sự kiện tới thủ tục tiếp theo bằng

cách gọi hàm CallNextHookEx Chú ý rằng những thủ

tục hook dành cho các kiểu hook chỉ có thể quản lý cácthông điệp, hệ thống chuyển thông điệp tới mỗi thủtục hook, chứ không dính dáng gì đến có hay không một

thủ tục cụ thể gọi CallNextHookEx Một thủ tục hook có

thể toàn cục, quản lý những thông điệp đối với tất cảcác thread trong hệ thống hay nó có thể là thread cụthể, quản lý các thông điệp cho chỉ một thread riêngbiệt Một thủ tục hook toàn cục có thể được gọi trongngữ cảnh của bất kỳ ứng dụng nào, bởi thế thủ tụcphải ở trong một module DLL riêng lẻ Một thủ tục hookloại thread cụ thể chỉ được gọi trong ngữ cảnh của threadđã được tổ chức Nếu một ứng dụng đặt một thủ tụchook cho một trong các thread của riêng nó thì thủ tụchook có thể ở trong cả module giống nhau như quãng nghĩgiữa các mã ứng dụng hoặc trong một DLL Nếu ứngdụng đặt một thủ tục hook cho một thread của một ứng

Trang 33

dụng khác thì thủ tục phải ở trong một DLL Chú ý chỉsử dụng hook toàn cục cho mục đích debug còn không thìnên tránh không sử dụng Hook toàn cục có thể gâytổn hại cho hoạt động của hệ thống và gây nên xungđột với những ứng dụng khác có cùng kiểu hook toàncục.

3 – Các loại hook:

Một loại hook làm cho một ứng dụng có thể quản lýmột mặt khác nhau của kỹ thuật message-handling hệthống

Bao gồm các loại hook sau đây:

- WH_CALLWNDPROC hook quản lý các thông điệptrước lúc hệ thống gởi chúng tới cửa sổ đích

- WH_CALLWNDPROCRET hook quản lý các thông điệpsau khi chúng được xử lý bởi thủ tục cửa sổ đích

- WH_CBT hook nhận những thông báo có ích tớiứng dụng huấn luyện trên cơ sở tính toán (CBT)

- WH_DEBUG hook có ích cho việc debug những thủtục hook khác

- WH_FOREGROUNDIDLE hook sẽ được gọi khi threadforeground của ứng dụng sẽ trở thành không dùngđến Hook này có ích cho hoạt động những nhiệm vụ(task) độ ưu tiên thấp trong thời gian không được dùngđến

- WH_GETMESSAGE hook quản lý các thông điệpđược post tới hàng thông điệp

- WH_JOURNALPLAYBACK hook post những thông điệpđược ghi trước đó bởi thủ tục hookWH_JOURNALRECORD

- WH_JOURNALRECORD hook ghi những thông điệp đầuvào được post tới hàng thông điệp hệ thống Hooknày có ích cho việc ghi các macro

- WH_KEYBOARD hook quản lý các thông điệpkeystroke

Trang 34

- WH_KEYBOARD_LL Windows NT: hook quản lý nhữngsự kiện nhập vào từ keyboard mức thấp.

- WH_MOUSE hook quản lý các thông điệp chuột

- WH_MOUSE_LL Windows NT: hook quản lý những sựkiện đầu vào chuột mức thấp

- WH_MSGFILTER hook quản lý các thông điệp đượckết sinh như là một kết quả cuả sự kiện đầu vào ởtrong dialog box, message box, menu hay scroll bar

- WH_SHELL hook quản lý các thông điệp nhậnthông báo hữu ích để shell các ứng dụng

- WH_SYSMSGFILTER đặt một ứng dụng các thôngđiệp được kết sinh như là kết quả của một sự kiệnđầu vào ở trong dialog box, message box, menu hay scrollbar Thủ tục hook quản lý những thông điệp này chotất cả các ứng dụng trong hệ thống

4 – Sử dụng hook:

a) Cài đặt hook:

Đặt một thủ tục hook bằng cách gọi hàm

SetWindowsHookEx đặc tả kiểu hook gọi thủ tục, thủ tục

có phải được tổ chức với tất cả các thread hay chỉđược tổ chức với một thread cụ thể và một pointer chỉtới một điểm vào thủ tục Phải đặt một thủ tục hooktoàn cục vào một DLL riêng biệt từ ứng dụng cài đặtthủ tục hook Ứng dụng cài đặt phải có handle chỉ tớimodule DLL trước khi nó có thể đặt thủ tục hook Hàm

LoadLibrary khi được đưa tên của DLL sẽ trả handle cho

module DLL Sau khi có handle, có thể gọi hàm

GetProcAddress để lấy lại địa chỉ của thủ tục hook.

Cuối cùng sử dụng hàm SetWindowsHookEx để đặt địa

chỉ hook vào trong chuỗi hook dành riêng

SetWindowsHookEx chuyển handle module, một pointer chỉ

tới điểm vào thủ tục hook và cho danh hiệu thread, chỉ rarằng thủ tục hook phải được tổ chức với tất cả cácthread trong hệ thống

Ví dụ minh họa:

Trang 35

HOOKPROC hkprcSysMsg;

static HINSTANCE hinstDLL;

static HHOOK hhookSysMsg;

b) Giải phóng hook:

Có thể giải phóng một procedure loại thread cụ thểtức xóa địa chỉ của nó khỏi chuỗi hook bằng cách gọi

hàm UnhookWindowsHookEx nhưng hàm này không trả

tự do cho DLL chứa thủ tục hook Đây là lý do mà thủ tụchook toàn cục được gọi trong ngữ cảnh quá trình của mỗiứng dụng trong hệ thống, gây nên một gọi tuyệt đối

tới hàm LoadLibrary cho tất cả các quá trình đó Bởi vì một gọi tới hàm FreeLibrary không thể được tạo ra cho

một quá trình khác, rồi thì không có cách nào để giảiphóng cho DLL Hệ thống cuối cùng giải phóng DLL saukhi tất cả các quá trình nối hoàn toàn với DLL đã kết

thúc hay gọi FreeLibrary và tất cả các quá trình đã gọi

thủ tục hook lại tiếp tục quá trình xử lý bên ngoài DLL.Một phương pháp lựa chọn cho việc đặt thủ tục toàn cụclà cung cấp một hàm cài đặt trong DLL, cùng với thủtục hook Với phương pháp này, ứng dụng cài đặt khôngcần handle chỉ tới module DLL Bằng cách nối với DLL,ứng dụng gia tăng việc truy xuất tới hàm cài đặt Hàmcài đặt có thể cung cấp handle module DLL và những chi

tiết khác ở trong cái gọi tới SetWindowsHookEx DLL

cũng có thể chứa một hàm giải phóng thủ tục hooktoàn cục; ứng dụng có thể gọi hàm giải phóng hooknày khi kết thúc

5 – Hook trong Windows 3.x:

Hook là một điểm trong kỹ thuật message-handlingcủa Windows mà một ứng dụng có thể sử dụng để làmtăng khả năng truy xuất tới dòng thông điệp Windows

Trang 36

cung cấp nhiều kiểu hook khác nhau, mỗi kiểu cho phéptruy xuất tới một kiểu thông điệp cụ thể hay một vùngcác thông điệp Để có được một hook cụ thể thì mộtứng dụng có thể cài đặt một hàm lọc (filter function) đểxử lý những thông điệp được tổ chức với hook Mộthàm lọc xử lý những thông điệp trước khi chúng đếnthủ tục cửa sổ đích.

Chuỗi hàm lọc (Filter-Function Chain):

Một chuỗi hàm lọc là một loạt những hàm lọc họhàng cho một hook hệ thống cụ thể Một ứng dụngchuyển một hàm lọc cho một hook hệ thống bằng cáchgọi hàm SetWindowsHook Mỗi lần gọi thì cộng thêm mộthàm lọc mới vào đầu của chuỗi Bất cứ khi nào mộtứng dụng chyển địa chỉ một hàm lọc cho hook hệ thốngnó phải giữ vùng nhớ cho địa chỉ hàm lọc kế tiếp trongchuỗi SetWindowsHook cài một hàm hook vào chuỗi hookvà trả về handle của hook Khi mỗi hàm lọc hoàn thànhnhiệm vụ nó phải gọi hàm DefHookProc, hàm này sửdụng địa chỉ được lưu trong vị trí được giữ bởi ứng dụngđể truy xuất hàm lọc kế tiếp trong chuỗi Để xóa mộthàm lọc trong chuỗi lọc một ứng dụng phải gọi hàmUnhookWindowsHook với thông số là kiểu hook và mộtcon trỏ chỉ tới hàm

Sau đây là các hook cửa sổ tiêu chuẩn:

WH_CALLWNDPROC Cài đặt lọc cửa sổ

WH_CBT Cài đặt lọc computer-basedtraining (CBT)

WH_DEBUG Cài đặt lọc debug

WH_GETMESSAGE Cài đặt lọc thông điệp (chỉ

Trang 37

WH_HARDWARE Cài đặt lọc thông điệp-phần

WH_JOURNALPLAYBACK Cài đặt lọc journaling playbackWH_JOURNALRECORD Cài đặt lọc journaling record WH_KEYBOARD Cài đặt lọc bàn phím

WH_MOUSE Cài đặt lọc thông điệp chuộtWH_MSGFILTER Cài đặt lọc thông điệp

WH_SYSMSGFILTER Cài đặt lọc thông điệp trêntoàn hệ thống

Trong đó hook WH_CALLWNDPROC và WH_GETMESSAGEảnh hưởng hoạt động của hệ thống, chỉ sử dụng đểdebug

Để cài đặt một hàm lọc thì ứng dụng phải trải qua 4bước:

1 - Export hàm trong file DEF

2 - Lấy địa chỉ hàm bằng cách dùng hàmGetProcAddress (MakeProcInstance chỉ được sử dụng khi hàmlọc không ở trong một DLL)

3 - Gọi SetWindowsHook , xác định kiểu hàm hook vàđịa chỉ của hàm (được trả về bởi GetProcAddress)

4 - Lưu giá trị trả về từ SetWindowsHook trong vị tríđược giữ Giá trị này là handle của hàm lọc trước

Những hàm cho hook toàn hệ thống phải được chovào trong một DLL

Như vậy qua những lý thuyết về hook trong môitrường Win32 hay trong môi trường Win16 cho chúng ta cónhận xét: dùng kỹ thuật hook cho phép ta đặt một thủtục để theo dõi, điều khiển và xử lý các thông điệpcủa hệ thống Windows theo ý của ta trước lúc thôngđiệp đó đến được cửa sổ đích Tuy nhiên kỹ thuật hook

ở trong môi trường Win32 mạnh hơn, nó có thể cho phép

ta thực hiện được các công việc có vai trò tương tự nhưkỹ thuật override trong Win16

6 - Giới thiệu một số hàm có liên quan đến hook:

a) CallMsgFilter:

- Cú pháp:

Trang 38

BOOL CallMsgFilter(lpmsg, nCode)

MSG FAR* lpmsg;

int nCode;

- CallMsgFilter chuyển thông điệp đưa ra và mã tớihàm lọc thông điệp hiện hành Hàm lọc thông điệp làmột hàm đặc tả ứng dụng kiểm tra và sửa đổi tất cảcác thông điệp Một ứng dụng xác định hàm bằngcách sử dụng hàm SetWindowsHook

- Giá trị trả về: chỉ ra trạng thái của quá trình xửlý thông điệp Trả về 0 nếu thông điệp được xử lý vàkhác 0 nếu thông điệp không được xử lý

- Chú ý: hàm CallMsgFilter thường được gọi bởiWindows để cho các ứng dụng kiểm tra và điều khiểnluồng thông điệp trong suốt quá trình xử lý nội ở trongmenu, scroll bar hay khi di chuyển hoặc làm thay đổi kíchthước một cửa sổ

- Thông số:

Trang 39

idHook Kiểu của hook được cài đặt Thông số này

gồm các kiểu hook như đã trình bày ở phầnlý thuyết nêu trên

hkprc Địa chỉ procedure-instance của thủ tục hookapplication-defined được cài đặt

hinst Instance của module chứa hàm hook

htask Nhiệm vụ cho hook được cài đặt Nếu NULL thì

hàm hook được cài đặt có tầm vực hệ thốngvà có thể được gọi ở trong ngữ cảnh củabất kỳ quá trình nào hay nhiệm vụ nào ởtrong hệ thống

- Giá trị trả về: giá trị trả về là handle của hookđược cài đặt nếu hàm thành công Ứng dụng hay thưviện phải sử dụng handle này để xác định hook khi nógọi hàm CallNextHookeEx và UnhookWindowsHookEx Giá trịtrả về là NULL nếu có lỗi

c) Hàm gỡ bỏ một hàm hook UnhookWindowsHookEx:

- Thông số:

hhook Chỉ ra hàm hook được dỡ bỏ Đây là giá trịđược trả về bởi hàm

SetWindowsHookExIdentifies khi hàm hook được cài đặt

- Chú ý: Hàm UnhookWindowsHookEx phải được sửdụng trong sự kiết hợp với hàm SetWindowsHookEx

d) Hàm gọi hook kế tiếp trong hook-chain

CallNextHookEx:

- Cú pháp:

LRESULT CallNextHookEx(hHook, nCode, wParam, lParam)

Trang 40

hHook Chỉ định hook handle

nCode Chỉ định hook code để gởi đến hook kế tiếp

Hàm xử lý hook dùng giá trị này để chỉđịnh xử lý thông điệp được gởi từ hook thếnào

wParam Chỉ định 16 bits thông tin mở rộng của thôngđiệp

lParam Chỉ định 32 bits thông tin mở rộng của thôngđiệp

- Giá trị trả về: Giá trị trả về là kết quả của quátrình xử lý và tùy thuộc vào thông số nCode

Ngày đăng: 17/04/2018, 08:28

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w