Báo Cáo Luận Văn Tốt Nghiệp 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 7
III. Giao diện thiết bị đồ họa GDI 11
IV. Cửa sổ trong Windows 15
V. Chương trình Windows tiếp nhận thông điệp chuột 22
CHƯƠNG 2: TÌM HIỂU VỀ HOOK 26
1 - Chuỗi hook 27
2 - Thủ tục hook 27
3 - Các loại hook 28
4 - Sử dụng hook 30
5 - Hook trong Windows 3.x 31
6 - Giới thiệu một số hàm liên quan đến hook 33
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ình Windows 37
III. Cơ chế hoạt động và quản lý bộ nhớ trên Windows 16bits 38
IV. Cơ chế hoạt động và quản lý bộ nhớ trên Windows 32bits 41
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 override 50
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 55
CHƯƠNG 5: PHÂN TÍCH VÀ THIẾT KẾ CHƯƠNG TRÌNH 66
I. Phân tích vấn đề 67
II. Thiết kế chương trình 68
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 quan 92
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.
Trong thời gian làm Luận Án Tốt Nghiệp nhóm sinh viê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ên cứu về
phương thức lập trình trong môi trường Windows và các phương tiện mà Windows
hỗ trợ khi lập trình. Tham khảo và nghiên cứu kỹ thuật override các hàm giao tiếp
của Windows ở chế độ 16 bit và 32 bit. Nghiên cứu cách xử lý các thông điệp trong
Windows và tìm hiểu về cách kết xuất văn bản, về chế độ ánh xạ, vấn đề tọa độ . . .
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 được viết bằng ngôn
ngữ Visual C++ version 1.5 và hướng phát triể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ững nội dung mà chúng tôi đã
nghiên cứu và tìm hiểu được trong 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ần chươ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.
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 4
Chương 1:
TÌM HIỂU VỀ
TÌM HIỂU VỀ
LẬP TRÌNH WINDOWS
LẬP TRÌNH WINDOWS
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 5
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ên bộ hàm API (Application
Programmer Interface), nó có chức năng như các ngắt trong bảng vector ngắt của
DOS, nhưng nó thân thiện hơn ở chỗ cách gọi hàm API giống hệt cách gọi hàm của
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 6
- 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ạp khi Windows khởi động.
- Thư viện liên kết động third party: do các công ty khác tạo ra trên môi trường
Windows, hỗ trợ thêm công tá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ột khối lượng lớn các mã vào trong chương trình
như ở các thư viện thông thường. Nhờ cấu trúc động của DLL nên mọi chương trình
đều có thể truy cập thư viện trong thời gian thực thi. Các hàm API được Windows
giữ dưới dạng hỗn hợp trong một số DLL. Trong quá trình dịch khi gặp lệnh gọi hàm
API từ chương trình ứng dụng thì chương trình dị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át triển của lập trình hướng đối
tượng, và để hỗ trợ cho việc lập trình hướng đối tượng, Microsoft đã cung cấp cho
người lập trình một bộ thư viện các lớp cơ bản để phát triển các ứng dụng hướng đối
tượng gọi là MFC (Microsoft 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ác lớ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 hồn chỉ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ượng của
mình. Mục tiêu chính của MFC là hệ thống hóa các hà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 quan tâ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:
- Giá trị trả về: cho biết kết quả xử lý thông điệp và 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ên
LPARAM lParam; // thông số thông điệp thứ hai
- Hàm PostMessage gởi (đặt) một thông điệp vào trong 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ọi hàm SetMessage hay
PeekMessage.
- Giá trị trả về: trả về khác 0 nếu thành công, ngược lại 0.
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 8
c) Hàm SendDlgItemMessage:
- Cú pháp:
LRESULT 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ới mộ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ệp và 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 ra khỏi hàng đợi bằng cách
điệp và chỉ ra cách thông điệp được đặt vào hàng đợi như thế nào:
Thông điệp không chỉ phát xuất từ sự kiện phần cứng, cũng có thể có thông
điệp của chương trình phát xuấ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ởi thông điệp. Thông điệp có thể gởi
vào hàng đợi bằng hàm PostMessage() , hoặc chúng có thể được gởi trực tiếp cho
vòng lặp thông điệp để xử lý ngay lập tức bằng hàm SendMessage().
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 ứng dụng khác sinh ra các thông điệp cho mọi sự kiện xuất
hiện trong hệ thống thông điệp của Windows sẽ cho phé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 version
Windows 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ới Windows 95 và Windows NT, điều này không còn nữa.
SVTH : Lương Cao Hoài Tâm Lớp TH40
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)
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ần quan 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ệm vụ 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ật lý. GDI không bao giờ cho phép chương trình
làm việc trực tiếp với một DC mà GDI phân phối cho chương trình một handle để
nhận dạng một DC cụ thể. Tất cả các hàm API; GDI đều nhận thông số đầu tiên là
một handle – hdc.
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 11
DC là một công cụ chứa các thuộc tính vẽ, DC cho phép kết nối logic một
chương trình về một thiết bị cụ thể nào đó. Ngồ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ực tiế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ận này để GDI có thể giải
quyết tranh chấp khi 2 chương trình yêu cầu dùng cùng một thiết bị nên DC còn có
vai trò làm permission slip. DC lưu trữ thông tin liên quan đến mặ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 DC
cho thiết bị, và khi sử dụng xong thì phải trả nó về cho Windows 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ết giữa một ứng dụng
Windows, một driver thiết bị và một thiết bị đầu ra (output device). Windows duy trì
một cache gồm 5 DC đặc biệt cho hoạt động hệ thống. Ứng dụng phả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à device driver tới thiết bị đầu
ra:
Truy xuất thiết bị đầu ra (Accessing Output Devices): Bất kỳ ứng dụng
Windows nào cũng có thể sử dụng hàm GDI để truy xuất một thiết bị đầu ra. GDI
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ôi chỉ 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ận
lý đượ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, y cũng được tính theo pixel, trị x tăng khi qua phải và giảm
khi 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ùy theo hồn cảnh như:
Hệ toạ độ thiết bị (Device coordinate system)
- Hệ toạ độ tồn màn hình (Full screen coordinate system)
- Hệ toạ độ vùng client (Client area coordinate system)
- Hệ toạ độ tồn cửa sổ (Whole window coordinate system)
- 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àn hì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 hình. Thường vị trí của một
đối tượng như con nháy hoặc con trỏ hoặc cửa sổ so với góc upper-left của màn hình
thì 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àn hì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ùng client. 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 qua tọa độ trọn màn hình.
Hàm ScreenToClient chuyển tọa độ trọn màn hình qua tọa độ vùng client.
SVTH : Lương Cao Hoài Tâm Lớp TH40
vùng hình chữ nhật window và viewport theo mặc nhiên các điểm này được cho về
(0,0) trên DC mặc nhiên.
Công thức sử dụng 2 điểm cho biết extent của một vùng theo tọa độ logic
(xwindowExt,ywindowExt) và của một vùng theo hệ tọa độ thiết bị
(xviewportExt,yviewportExt).
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 14
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ủa Windows, nó là một kiến
trúc chuẩn mực để từ đó xây dựng nên các đối tượng khác như: cửa sổ chính của ứng
dụng (main frame); text box; edit control; button; combo box; menu; scroll bar;... nói
chung là tồ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ũng
có 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ệu từ 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ên thực tế nó là một số nguyên)ø, ta chỉ cần có được handle 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ột cửa sổ trong một thời điểm có thể nhận dữ liệu nhập từ người
dùng. Người dùng có thể dùng chuột, bàn phím, hay các thiết bị nhập khác để tương
tác với cửa sổ 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àm
CreateWindow 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 top-level window): là cửa sổ
vùng client.
Windows không tự động xén (clip) một cửa sổ con ra khỏ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ỏi vù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ổ 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ùng client. Cửa
sổ anh em (cùng cha mẹ) có thể tô vẽ trong mỗi vùng client của các cửa sổ khác trừ
khi một cửa sổ con có kiểu WS_CLIPSIBLINGS. Nếu ứng dụng xác định kiểu này
cho một cửa sổ con thì bất kỳ phần nào của cử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ểu WS_CLIPCHILDREN hoặc
WS_CLIPSIBLINGS thì một mất mát nhỏ 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òn hơ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 trong vùng client.
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 16
Thủ tục cửa sổ nhận các kiểu thông điệp như: nhập và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êu chuẩn đến những hoạt động chắc
chắn (như điều chỉnh menu trước lúc hiển thị); yêu cầu thực hiện một vài hành động
trên cửa sổ hay vùng client của nó (cập nhật vùng client); thông tin về tình trạng của
nó trong mối quan hệ với các cửa sổ khác (truy xuấ nhất định thấ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ệp là từ Windows nhưng nó cũng
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 input cho 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ững thông điệp mà nó hay ứng dụng
của nó có thể gởi tới thủ tục cửa sổ. Hầu hết những thông điệp được gởi tới cửa sổ
như là kết quả của hàm đưa ra đang được thự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ột danh hiệu thông
điệp, một giá trị thông điệp-đặc biệt 16-bit và một giá trị thông điệp-đặc biệt 32-bit.
Những giá 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 tra danh 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-bit và 32-bit.
Cú pháp thủ tục cửa sổ:
- LONG FAR PASCAL WndProc(hwnd, wMsg, wParam, lParam)
HWND hwnd;
WORD wMsg;
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êm vào 16-bit
lParam thông tin thông điệp-đặc biệt thêm vào 32-bit
Hàm trả về giá trị 32-bit cho biết kết quả xử lý thông điệp
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ể truy xuất một vài thông điệp được gởi tới cho chúng. Hầu hết
các thủ tục cửa sổ thì hàm DefWindowProc thực hiện hầ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ểu hiện những hành
động được thực hiện trên các phần khác của cửa sổ hơn là vùng client.
5 - Vấn đề tô vẽ màn hình:
InvalidateRect và InvalidateRgn thực sự không sinh ra thô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ủa
riêng nó trong lúc một cửa sổ xử lý những thông điệp khác trong hàng thông điệp của
nó. Làm trễ WM_PAINT làm cho cửa sổ xử lý tất cả những thay đổi cùng một lúc
thay vì cập nhật những những mẫu nhỏ trong những bướ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ởi thô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ập nhậ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ận WM_PAINT nó phải gọi BeginPaint để lấy ngữ
cảnh màn hình cho vùng client và lấy thông tin khác như vùng cập nhật và
background bị xóa hay không. Windows tự động chọn vùng cập nhật như là vùng xén
của ngữ cảnh màn hình. GDI huỷ bỏ (xén) những gì được vẽ bên ngồi vù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 điệp WM_PAINT
đến sau. Sau khi vẽ xong Windows phải gọi hàm EndPaint để giải phóng DC.
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 19
Vùng cập nhật: Một vùng cập nhật xác định phần củ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ẽ tồn bộ nội dung của vùng client. Nếu
chỉ có phần mà cần vẽ đượ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ật hay vùng phải được đưa ra ở trong tọa độ client.
Vùng cập nhậ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ính nó vào một vùng cập nhật của cửa sổ sau khi
những hoạt động như di chuyển, định kích thước và cuộn cửa sổ.
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àm này được sử dụng điển hình khi cửa sổ đã cập nhật một
lúc ngắt. Còn lại tất cả các event khác đều được đưa vào hardware event queue.
3 - Hardware event queue:
Các mouse event được đưa vào hardware event queue chờ giao cho message
loop của chương trình giải quyết. Queu nà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àm GetMessage(). Điều này đảm bảo cho hệ thống hoạt động
đúng đắn. Sau đó là vòng lặp GetMessage().
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ận thông điệp bằng cách xem chương trình nào sở hữu cửa
sổ mà con trỏ chuột nằm trên đó. Tùy theo vị trí của con trỏ mà phát sinh hai loại
thông điệp: thông điệp vùng client và thông điệp vùng non-client. Muốn biết cursor ở
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ống
trong queue và lại dựa vào push-model để biết vị trí của cursor. 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ụng
hà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_NCHITTEST là thông điệp đến đầu tiên trong hàng loạt thông điệp mà mouse
phát ra. Nó yêu cầu thủ tục cửa sổ nhận diện vị trí cursor. Đa số chương trình chuyển
thông điệp này cho DefWindowProc() lo tìm vị trí cursor và cung cấp một hit-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ên vùng non-client thì
Windows sẽ phát đi thông điệp non-client.
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 21
Còn khi DefWindows trả về kết quả HTCLIENT thì cursor nằm trên vùng client
và những thông điệp do Windows phá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
này cho origin về góc upper-left của vùng client với đơn vị tính là pixel. Trị x nằm ở
word thấp còn y nằm ở word cao của lParam.
Trị của wParam là một lô cờ hiệu mô tả trạng thái của các nút chuột cũng như
trạng thái các nút <Ctrl>, <Shift>
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 22
6 – DefWindowProc():
Đối với chuột thì DefWindowProc() không quan tâm đến nhữ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ện chung cho bàn phím và
con chuột bằng cách dịch phần nhập liệu từ bàn phím hoặc con chuột thành các lệnh
hệ thống (system command) và cho hiện lên như các thô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ột
khác.
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 23
Chương 2:
TÌM HIỂU VỀ HOOKS
TÌM HIỂU VỀ HOOKS
SVTH : Lương Cao Hoài Tâm Lớp TH40
Báo Cáo Luận Văn Tốt Nghiệp Trang 24
Hook là một cơ chế cực mạnh cho phép ta cài đặt một thủ tục để điều khiển hoặc chận
hứng các thông điệp trướ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ụng có thể đặt một thủ tục để quản lý sự lưu thông của các
thông điệp trong hệ thống và xử lý một kiểu thông báo nào đó trước khi chúng tới
được thủ tục cửa sổ đích.
Do có khả năng can thiệp mạnh nên hook có xu hướ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
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ện nà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 hay không chuyển sự kiện tới thủ tục tiếp theo.
Một thủ tục hook 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ác thô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ể tồ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êng
biệt. Một thủ tục hook tồn cục có thể được gọi trong ngữ cảnh của bất kỳ ứng dụng
nào, bởi thế thủ tục phải ở trong một module DLL riêng lẻ. Một thủ tục hook loạ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ục hook cho một trong các thread của riêng nó thì thủ tục hook 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 ứng dụng đặt một thủ tục hook cho một thread của một ứng dụng
khác thì thủ tục phải ở trong một DLL. Chú ý chỉ sử dụng hook tồn cục cho mục đích
debug còn không thì nên tránh không sử dụng. Hook tồn cục có thể gây tổ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 tồn cụ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ệp trướ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ệp sau 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 tốn (CBT).