Tải bản đầy đủ (.doc) (106 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (398.25 KB, 106 trang )

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
KẾT QUẢ VÀ HƯỚNG PHÁT TRIỂN
97


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ạng
má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ầ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.
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


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 đượ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.


Trang 5

Chöông 1:

TÌM HIEÅU VEÀ
LAÄ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ê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 ngôn ngữ cấp cao, mỗi hàm có một
tê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ập
trì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 trong
máy ở mức thấp từ hàm API trở xuống thuộc phạm vi
củ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ác
hà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àng
và 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 ra
hế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ông
thể xâm nhập, nhưng sẽ rất khó khăn nếu người lập
trì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 qua

một hay nhiều giao diện. Để truy cập các giao diện này
thì các ứng dụng được xây dựng trên môi trường Windows
sẽ sử dụng tập các hàm được gọi là giao diện chương
trình ứng dụng API (Application Program Interface). Chương trình
của người sử dụng có thể gọi tới các hàm API để truy
cậ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 Device
Interface) 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 độc
lập thiết bò (device independent) tức là cho phép Windows
là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 Windows
lưu dưới dạng nhò phân chứa các hàm mà mọi ứng
dụng trên Windows đều có thể sử dụng. Nét đặc trưng
của DLL là nó có thể được sử dụng bởi nhiều ứng dụng
tại cùng một thời điểm hay nói cách khác thư viện liên
kết động có thể cùng một lúc được gọi bởi nhiều
chươ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ạ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


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á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 hoà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:
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ên
Windows luôn luôn gắn liền với những thông điệp. Mọi
hoạt động xảy ra trên một chương trình Windows đều
thô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ên
ngoài vào hệ thống Windows. Một cửa sổ có thể gởi đi
mộ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ện
mang tiền tố WM_ được coi là phần lớn trong ứng dụng
và Windows đã cung cấp các hàm để giải quyết.
- Những control notification: đây là những thông điệp
WM_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ệp
cho 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ên
LPARAM 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ều
cửa sổ. Hàm gọi thủ tục cửa sổ cho cửa sổ và không
trở 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ệ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.
c) Hàm SendDlgItemMessage:
- Cú pháp:


Trang 10
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 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àm
WinMain() 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);
}

Hardware Event Occur

Sau đây là Sơ đồ dòngSystem
thông
điệp:
Message
Queue
System Dispatcher
System Dispatcher

Thread1 Message Queue
Thread1 Hook

Thread2 Message Queue

Thread2 Hook

Thread3 Message Queue

Thread3 Hook


GetMessage()
TranslateMessage()
Dispatch Message()

GetMessage()
TranslateMessage()
Dispatch Message()

GetMessage()
TranslateMessage()
Dispatch Message()

WndProc()

WndProc()

WndProc()

DefWndProc()

DefWndProc()

DefWndProc()


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ặp

thông điệp và chỉ ra cách thông điệp được đặt vào
hàng đợi như thế nào:

Hardware Events
Other threads
PostMessage()

System Message Queue

Message Sent
From Other Threads

Other threads
PostMessage()

System Dispatcher

Thread Message Queue

SentMessage()
(To Another Thread)

PostMessage()

TranslateMessage()
Message Loop
SentMessage()
WndProc()

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().


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 ứ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.
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ển
chuột. Nó gởi thông điệp đến hàng đợi thông điệp của
thread thích hợp, nếu thông điệp được dành cho nhiều
thread thì nó cũng được đưa vào các hàng đợi của các
thread đó.

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;
UINT message;
message
WPARAM wParam;
WndProc()
LPARAM wParam;
DWORD time;
bắt đầu
POINT pt;
}

{
// handle cửa sổ
//số
chỉ
đònh
//được

chuyển

loại
cho

//được chuyển cho WndProc()
//số mili giây từ lúc
//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ột
hay nhiều giao diện. Để truy xuất các giao diện thì chương
trình ứng dụng phải sử dụng các hàm Giao diện chương
trình ứng dụng. API là tập các lệnh mà một ứng dụng
sử dụng để yêu cầu và tiến hành các dòch vụ cấp
thấ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ủa
Windows đối với các thiết bò đồ họa (cho phép Windows
làm việc với nhiều thiết bò đồ họa khác nhau). Windows
GDI là một thư viện bao gồm một số hàm giúp kết
xuấ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ầ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.

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 đó. 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ự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


Trang 14
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 chuyển các gọi
độc lập thiết bò từ ứng dụng tới driver thiết bò. Rồi

driver 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ẽ được
chọ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

Windows
Applicatio
n

Windows
Applicatio

GDI
Device
Context

Device
Driver

Output
Device


Device
Driver

Output
Device

Device
Driver

Output
Device


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ô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 hoàn cảnh như:
Hệ toạ độ thiết bò (Device coordinate system)
-

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

-

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

-

Hệ toạ độ toà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



Trang 16
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.
c) Whole window coordinate system:
Gần giống hệ tọa độ vùng client, là tương đối so với
góc upper-left của cửa sổ, được sử dụng khi vẽ vùng
nonclient của cửa sổ.
d) Logical coordinate:
Hầu hết các hàm GDI sử dụng hệ tọa độ này. Hệ
thống tọa độ logic không phải là hệ thống tọa độ thiết
bò, hệ thống tọa độ logic bao giờ cũng được ánh xạ lên
một hệ thống tọa độ thiết bò. Hệ tọa độ logic có thể
được ánh xạ lên hệ tọa độ toàn màn hình, hệ tọa độ
vùng client hoặc hệ tọa độ toàn 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ụng
hệ 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ữa
các hệ tọa độ đã được cung cấp bởi các hàm nêu
trên.


Trang 17
5 - Viewport và window:
Mapping mode cho biết ánh xạ tọa độ logic và những
kí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à mapping
mode 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óa
là 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
Trong đó:
(xwindow,ywindow) là điểm trên tọa độ logic được
chuyển đổi thành điểm (xviewport,yviewport)
(xwindowOrg,ywindowOrg) và (xviewportOrg,yviewportOrg)
là origin của 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

(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ủa
Windows, 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 ứng
dụ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ũ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 toplevel window): là cửa sổ không bao giờ có cửa sổ cha
mẹ.
- Cửa sổ bò sở hữu (Owned windows): là kiểu đặc
biệ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ủa
cửa sổ cha mẹ, được sử dụng để chia vùng client của
cử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 che
dấ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ùng
củ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òch
khi gởi thông điệp cho cửa sổ cha mẹ. Mỗi cửa sổ con
là một cửa sổ độc lập, nó nhận tác động bên ngoài
của riêng nó và các thông điệp khác. Những input gởi
cho cửa sổ con được đi trực tiếp tới cửa sổ con và không
chuyể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ợp
nà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ửa
sổ 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 ảnh
hưởng đến cửa sổ con như sau:
- Shown: Cửa sổ cha mẹ sẽ được hiển thò trước cửa
sổ 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ỉ khi
cử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 client
củ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ên
của 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ổ


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ù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.
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 có thể nhận thông điệp
từ 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ấp
nhậ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ẹ hay
hệ 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ửa
sổ bò hủy thì không có thêm thông điệp nào được đưa
tới thủ tục cho cửa sổ cụ thể đó. Nếu có nhiều hơn
một cửa sổ của lớp, tuy nhiên, thủ tục cửa sổ tiếp tục
nhận thông điệp cho những cửa sổ khác cho đến khi
cũ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 ra
thực sự có hành vi bằng cách đáp ứng những gì các
cửa sổ tạo ra những lệnh từ user hay hệ thống. Thủ tục
cửa sổ phải kiểm tra những thông điệp mà nó nhận
từ 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 ứng
thủ 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ực
hiệ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 (đặc
biệ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ục
cửa sổ.
Thủ tục cửa sổ cũng nhận các thông điệp mà thực
sự đã 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ực
hiệ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ởi
hệ 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ửa
sổ thì thủ tục sẽ chuyển chúng cho hàm DefWindowProc

và 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ông
chuyể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 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
HWND
WORD
WORD

DWORD

WndProc(hwnd, wMsg, wParam, lParam)
hwnd;
wMsg;
wParam;
lParam;

Các thông số:
hwnd
wMsg
wParam
vào 16-bit
lParam
vào 32-bit

cho biết cửa sổ nhận thông điệp
loại thông điệp
thông tin thông điệp-đặc biệt thêm
thông tin thông điệp-đặc biệt thêm

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ể 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:
Khi một cửa sổ bò di chuyển thì Windows tự động sao
chép nội dung của vùng client tới vò trí mới. Điều này
tiết kiệm thời gian bởi vì một cửa sổ không phải tính
toán lại và vẽ lại nội dung của vùng client như là phần
của sự di chuyển. Nếu cửa sổ di chuyển hay thay đổi kích
thướ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ích
thước thì Windows sao chép toàn bộ vùng client và gởi
thô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ì Windows
cho 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. Tuy
nhiên với một vài cửa sổ thì nội dung của vùng client
không còn hợp lệ sau khi di chuyển đặc biệt là nếu di
chuyển luôn sự thay đổi kích thước. Để tô vẽ lại toàn
bộ vùng client thay cho sao chép nội dung trước đó mỗi
lầ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ành
nhiề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 đổi
bằ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ập
nhậ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óa
bở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ẽ trong
vù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ến
hành vẽ.
Thông điệp WM_PAINT: là một yêu cầu của Windows
tới một cửa sổ để cập nhật màn hình cửa nó. Windows
gởi WM_PAINT bất cứ khi nào cần vẽ một phần lại cửa
sổ. Khi cửa sổ nhận thông điệp WM_PAINT thì nó sẽ lấy
vùng cập nhật bằng hàm BeginPaint và nó sẽ tiến
hà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 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 ngoà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


Trang 25
điệp WM_PAINT đến sau. Sau khi vẽ xong Windows phải gọi
hà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ầ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ẽ toà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 phần đặc biệt của màn hình trong vùng cập nhật
trước khi nhận thông điệp WM_PAINT.
Hàm GetUpdateRect lấy hình chữ nhật nhỏ nhất bao
lấy toàn bộ vùng cập nhật. Hàm GetUpdateRgn lấy
vùng cập nhật chính nó. Những hàm này có thể được
sử dụng để tính toán kích thước hiện hành của vùng
cập nhật để quyết đònh những công việc vẽ nào được
yêu cầu.
V – CHƯƠNG TRÌNH WINDOWS
TIẾP NHẬN THÔNG ĐIỆP
Hardware
event queue
CHUỘT:
Hook
chain
Virtual
&
Giới thiệu dòng chảy dữ liệu thông điệp nhập từ con
Scan code
chuột:
Mouse

Device driver


GetMessage()
DispatchMessage()

WindowProc()

DefWindowProc()


×