176 Lập trình Windows với MFC Microsoft Visual C++ 6.0 Lê Ngọc Thạn h lntmail@yahoo.com2 Giả sử cần thực hiện ứng dụng sau:
12.7 ẤN ĐỊNH MỘT SỐ TÍNH NĂNG CỦA WINDOWS:
Môi trường windows cho phép người dùng ấn định một số tính năng tiện ích như chế độ tự động ngắt nguồn, tắt máy,…. Các tính năng này có thể được cài đặt thông qua chương trình tiện ích hoặc lập trình tự động với hàm sau:
182 Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.comBOOL SystemParametersInfo ( BOOL SystemParametersInfo (
UINT uiAction, // Số hiệu của chức năng cần thực hiện UINT uiParam, // Ấn định tùy thuộc uiAction
PVOID pvParam, // Con trỏ vùng đệm, tùy thuộc uiAction UINT fWinIni // Đề nghị cập nhật user profile. = 0: không. ); Lấy hoặc đặt thông số qui định tính năng tương ứng của hệ thống. Giá trị uiAction có thể là:
SPI_GETLOWPOWERTIMEOUT : Lấy thông số low power timeout SPI_GETPOWEROFFTIMEOUT : Lấy thông số power timeout SPI_GETSCREENSAVETIMEOUT : Lấy thông số S.saver timeout SPI_SETLOWPOWERTIMEOUT : Đặt thông số low power timeout SPI_SETPOWEROFFTIMEOUT : Đặt thông số power timeout SPI_SETSCREENSAVETIMEOUT : Đặt thông số S.saver timeout.
ß Khi uiAction là giá trị có ý nghĩa lấy thông số: uiParam : Có giá trị bằng 0
pvParam : Chỉ đến vùng đệm nhận giá trị thông số hiện hành. ß Khi uiAction là giá trị có ý nghĩa đặt thông số:
uiParam : Giá trị thông số ấn định. pvParam : = NULL
2 Đoạn chương trình sau thực hiện cấm tính năng screen saver: UINT oldStatus;
// Lấy thông số qui định tính năng ScreenSaver, lưu vào oldStatus SystemParametersInfo( SPI_GETSCREENSAVETIMEOUT,
0, &oldStatus, 0 ); // Cấm tính năng ScreenSaver
SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT, 0, NULL, 0 );
… // Các xử lý trong điều kiện ScreenSaver bị cấm
// Trả lại ấn định trước đó cho tính năng ScreenSaver : oldStatus SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT,
oldStatus, NULL, 0 ); 12.8 BẪY (HOOK) MESSAGE (WINDOWS HOOK):
Hook là một khâu trong cơ chế xử lý message của windows mà ứng dụng có thể can thiệp để cài đặt thủ tục xử lý message (hook procedure) trước khi message đó đến được đối tượng xử lý message mà hệ thống điều phối.
Một số vấn đề trong Windows 183
12.8.1 Các kiểu hook (Hook Type):
Hook được phân chia thành các kiểu khác nhau tùy thuộc vào kiểu message được hook. Một số kiểu hook phổ biến như sau:
WH_KEYBOARD : Hook các message liên quan bàn phím. WH_MOUSE : Hook các message liên quan con chuột. WH_CBT : Hook các thao tác trên cửa sổ giao diện. WH_CALLWNDPROCRET : Hook giá trị trả về từ hàm xử lý message
WindowProc có kiểu CWPRETSTRUCT. WH_CALLWNDPROC : Hook các message trước khi message được
chuyển đến thủ tục WindowProc. 12.8.2 Danh sách hook (Hook Chain):
Danh sách hook là danh sách các con trỏ chỉ đến các thủ tục hook. Mỗi kiểu hook có một danh sách hook riêng. Khi một message phát sinh, nó được chuyển đến danh sách hook liên quan; từ thủ tục hook này đến đến thủ tục hook khác. Mỗi thủ tục hook có thể tùy nghi thực hiện các xử lý khác nhau: ghi nhận message, chỉnh sửa message, hoặc ngăn cấm message không để nó đến được thủ tục hook kế tiếp.
12.8.3 Thủ tục hook (Hook Procedure):
Thủ tục hook là chương trình con chuyên dụng cho việc hook loại message liên quan. Chương trình con xử lý hook có khai báo như sau:
LRESULT CALLBACK HookProc ( int nCode, WPARAM wParam,
LPARAM lParam );
Các tham số gửi cho chương trình con này khác nhau theo từng kiểu hook: WH_KEYBOARD – xử lý message bàn phím - KeyboardProc:
code : - HC_ACTION: Message của phím được thực hiện. - HC_NOREMOVE: Message của phím chưa được lấy khỏi
message queue. wParam: Mã phím liên quan.
lParam : - Các bit 0÷15 : Giá trị cho biết số lần gõ phím - Các bit 16÷23 : Mã scan code của phím.
- Bit 29 : Bằng 1 nếu phím Alt được nhấn kèm. WH_MOUSE – xử lý message từ con chuột - MouseProc:
code : - HC_ACTION: Message của chuột được thực hiện. - HC_NOREMOVE: Message của chuột chưa được lấy khỏi
message queue. wParam : Số hiệu message của con chuột
184 Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.comlParam : Con trỏ đến cấu trúc MOUSEHOOKSTRUCT. lParam : Con trỏ đến cấu trúc MOUSEHOOKSTRUCT.
typedef struct tagMOUSEHOOKSTRUCT {
POINT pt; // Vị trí chỉ điểm của con chuột HWND hwnd; // Handle cửa sổ liên quan. UINT wHitTestCode; // Xem (4.2): WM_SETCURSOR ULONG_PTR dwExtraInfo; // Các thông tin bổ sung khác. } MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT; WH_CBT – Xử lý thao tác trên cửa sổ - CBTProc:
Quan hệ giữa các thông số như sau:
Code wParam lParam
HCBT_ACTIVATE ( Kích hoạt cửa sổ )
Handle của cửa sổ Con trỏ cấu trúc chứa thông tin. HCBT_CREATEWND
( Tạo mới cửa sổ )
Handle của cửa sổ. Con trỏ cấu trúc chứa thông tin. HCBT_DESTROYWND
( Hủy bỏ cửa sổ )
Handle của cửa sổ. =NULL HCBT_MINMAX
( Phóng to hay Thu nhỏ cửa sổ )
Handle của cửa sổ. Word thấp chứa thông số hiển thị cửa sổ ( SW_xxx ). HCBT_MOVESIZE
( Di chuyển hoặc thay đổi kích thước cửa sổ )
Handle của cửa sổ. Con trỏ cấu trúc RECT quản lý tọa độ, kích thước mới. 12.8.4 Các dịch vụ liên quan hook:
HHOOK SetWindowsHookEx (
int idHook, // Kiểu hook
HOOKPROC lpfn, // Địa chỉ thủ tục hook
HINSTANCE hMod, // Handle của đơn thể chứa hook DWORD dwThreadId // Số hiệu tiểu trình sử dụng hook
); Cài đặt thủ tục hook vào danh sách hook tương ứng. Hàm trả về handle của thủ tục hook được cài đặt trước thủ tục bị chiếm quyền. dwThreadId : Tiểu trình sử dụng hook; =0: tất cả các tiểu trình.
lpfn : Nếu thủ tục hook sử dụng cho tất cả các tiểu trình thì nên đặt nó trong một tập tin DLL.
Một số vấn đề trong Windows 185
hMod : Handle của ứng dụng hoặc DLL chứa thủ tục hook. LRESULT CallNextHookEx (
HHOOK hhk, // Handle của thủ tục hook chiếm quyền int nCode, // Chuyển giao giá trị các tham số WPARAM wParam, // mà thủ tục hook chiếm quyền LPARAM lParam // nhận được từ hệ thống
); Thực hiện thủ tục hook bị chiếm quyền, giúp ổn định cho windows. BOOL UnhookWindowsHookEx (
HHOOK hhk // Handle của thủ tục hook hủy bỏ. ); Hủy bỏ thủ tục hook trong danh sách hook.
Nếu thủ tục hook được cài trong DLL thì cần sử dụng các hàm sau: HMODULE LoadLibrary (
LPCTSTR lpFileName // Đường dẫn, tên tập tin DLL ); Trả về giá trị handle của DLL.
FARPROC GetProcAddress (
HMODULE hModule, // Handle của DLL chứa thủ tục LPCSTR lpProcName // Tên thủ tục
); Trả về con trỏ của thủ tục tương ứng. 12.8.5 Ứng dụng hook messages của keyboard:
Trong phần này, ta thực hiện ứng dụng hook message của bàn phím. Xử lý hook của ứng dụng bật tiếng beep để thông báo có gõ phím và chuyển message nhận được cho thủ tục xử lý hook đã bị xử lý này chiếm quyền.
Các bước thực hiện như sau:
Dùng MFC Wizard tạo ứng dụng Hook với giao diện chính là dialog. Thực hiện cài đặt các bổ sung cho lớp dialog CHookDlg như sau:
- Trong phần cài đặt, bổ sung biến lưu và hàm xử lý hook:
HHOOK oldHook; // Chứa địa chỉ thủ tục hook bị chiếm quyền LRESULT CALLBACK myHook ( int code, WPARAM wParam,
LPARAM lParam) { MessageBeep( -1 ); // Thực hiện beep để thông tin // Thực hiện thủ tục bị chiếm quyền.
return CallNextHookEx(oldHook, code, wParam, lParam); }
- Hành vi OnInitDialog xử lý cài đặt thủ tục hook: BOOL CHookDlg::OnInitDialog()
186 Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com CDialog::OnInitDialog(); CDialog::OnInitDialog();
oldHook = SetWindowsHookEx (
WH_KEYBOARD, /* Hook messge phím */ myHook, /* Thủ tục hook */ AfxGetInstanceHandle(),
/* Handle tiến trình chứa thủ tục xứ lý hook */ 0 /* Hook tất cả tiến trình */
);
return TRUE; }
- Hành vi OnDestroy hủy bỏ thủ tục hook của ứng dụng: void CHookDlg::OnDestroy()
{ UnhookWindowsHookEx(oldHook); CDialog::OnDestroy(); } Biên dịch và chạy thử ứng dụng. 12.9 Cài đặt chế độ thực hiện ứng dụng tự động: SOFTWARE\Microsoft\Windows\CurrentVersion\Run là thành phần đặc biệt của system registry cho phép tự động thực hiện ứng dụng khi khởi động windows thông qua việc cài đặt các mục có giá trị là chuỗi đường dẫn đến chương trình ứng dụng liên quan. Trong đó:
HKEY_LOCAL_MACHINE\ Áp dụng cho mọi người dùng tại host. HKEY_CURRENT_USER\ Áp dụng cho một người dùng xác định. 2 Ví dụ: Mục MyProg = "C:\Game\mci.exe" cài trong thành phần :
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run cho phép thực hiện tự động chương trình mci.exe khi khởi động windows. THỰC HÀNH:
1. Dùng (12.3) và (12.6), thiết kế ứng dụng audio & video player. Ứng dụng có thể thu nhỏ thành icon trên status area để vừa làm việc vừa nghe nhạc. 2. Cài đặt mục trong RUN cho phép thực hiện tự động một ứng dụng tùy ý. 3. HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\TypedURLs là thành phần chứa các URLs trong IE. Viết ứng dụng xóa một URL bất kỳ.