• Thứ Ba, 23/09/2008 09:12 (GMT+7)

    Cơ chế hook của Windows

    Câu hỏi :
    Xin hỏi về cơ chế hook của Windows, dùng SetWindowHookEx của VB6. Làm sao biết thông điệp gì được gửi đến? Nếu được xin cho một ví dụ cụ thể.
     

    Trả lời :
    Cơ chế Hook của Windows cho phép người lập trình viết các hàm xử lý sự kiện theo ý riêng của mình rồi đăng ký vào Windows để hàm đó được kích hoạt mỗi khi sự kiện tương ứng xảy ra. Thí dụ để chặn xử lý các thông báo của Windows, bạn có thể viết hàm hook vào sự kiện WH_GETMESSAGE. Để hàm hook có thể hoạt động được ở cấp hệ thống, nghĩa là nó được kích hoạt độc lập với ứng dụng, bạn phải đặt các hàm hook trong file thư viện liên kết động *.dll. Có nhiều ngôn ngữ lập trình cho phép tạo file thư viện liên kết động, nhưng ngôn ngữ Visual C++ là thích hợp nhất.

     Để xử lý hook WH_GETMESSAGE, file thư viện cần có ít nhất 3 hàm chức năng sau đây:
     //1. hàm xử lý hook Message của bạn
     LRESULT CALLBACK GetMesgProc(int nCode, WPARAM wParam, LPARAM lParam) {
     //khai báo biến cần dùng
     PMSG pmsg;
     if (nCode < 0) // không xử lý message
     return CallNextHookEx(hHookGetMsg, nCode, wParam, lParam);
     pmsg = (PMSG)lParam;
     switch (pmsg->message) {
     case WM_ACTIVATE :
     //đoạn code xử lý message tương ứng
     case WM_MOUSEACTIVATE :
     //đoạn code xử lý message tương ứng
     case WM_NCACTIVATE :
     //đoạn code xử lý message tương ứng
     case WM_LBUTTONDOWN :
     //đoạn code xử lý message tương ứng
     case WM_RBUTTONDOWN :
     //đoạn code xử lý message tương ứng
     //các lệnh case miêu tả các thông báo cần xử lý khác
     }
     //trường hợp không phải thông báo cần quan tâm
     return CallNextHookEx(hHookGetMsg, nCode,wParam, lParam);
     }
     
     //2. hàm đăng ký hook message
     void FAR INSTALLHOOKGETMSG(HWND hWnd) {
     hHookGetMsg = SetWindowsHookEx(WH_GETMESSAGE,
     (HOOKPROC)GetMesgProc,hModuleDll, 0);
     if (hHookGetMsg == NULL)
     MessageBox(NULL,"Can't set Hook GetMesgProc","Error",MB_OK);
     }
     
     //3. hàm gỡ đăng ký hook message
     int FAR UNINSTALLHOOKGETMSG(void) {
     return UnhookWindowsHookEx(hHookGetMsg);
     }
     Qui trình điển hình để xây dựng file thư viện liên kết động *.dll bằng môi trường Visual C++ đã được chúng tôi trình bày trong phần trả lời thư bạn đọc trên các số báo trước. Bạn hãy tìm đọc và liên hệ với tòa soạn TGVT để copy file KeyHook.rar và KeyHookDemo.rar chứa các Project C++ miêu tả source code của thư viện liên kết động và ứng dụng sử dụng thư viện đó.

     Tôi muốn viết một chương trình hẹn giờ bằng VB hay Delphi với yêu cầu: có thể truy xuất một bản nhạc khi tới thời gian định trước. Thời gian định trước này có thể được nhập vào với nhiều mốc khác nhau và bản nhạc cũng tùy chọn.

     Để viết ứng dụng theo yêu cầu của bạn, bạn cần giải quyết 2 vấn đề thiết yếu sau:
     1. Làm sao để viết hàm (đoạn code) đọc và chơi 1 file nhạc theo định dạng qui định (wav, mp3, mpg,...). Cách dễ dàng, an toàn nhất trong môi trường VB là dùng đối tượng "Windows Media Player" để đọc và chơi file nhạc theo một định dạng xác định.

     2. Làm sao để kích hoạt đoạn code đọc và chơi file nhạc chạy theo định kỳ. Có nhiều phương pháp khác nhau, thí dụ:
     - Bạn viết chương trình tạo 1 timer theo định kỳ qui định, mỗi lần timer đếm xong (timeout) nó sẽ kích hoạt hàm xử lý, hàm xử lý này chính là hàm đọc và chơi file nhạc mà bạn viết ở bước 1. Như vậy, sau khi ứng dụng của bạn chạy, theo thời gian cứ đúng định kỳ qui định, timer sẽ gọi hàm đọc và chơi file nhạc chạy.

     - Bạn có thể viết ứng dụng đọc và chơi file nhạc bình thường rồi dùng tiện ích "Scheduled Tasks" của Windows để lập lịch chạy ứng dụng này theo yêu cầu của mình.

     Nếu không muốn tốn thời gian và công sức, bạn nên dùng ứng dụng sẵn có của Microsoft "Windows Media Player" để đọc và chơi 1 file nhạc, bạn có thể lập lịch các thời điểm khác nhau, mỗi thời điểm sẽ chơi file nhạc nào thông qua tiện ích "Scheduled Tasks" của Windows như sau:
     - Chạy Control Panel, chạy icon "Scheduled Tasks", nhấn đúp chuột vào icon Add scheduled task để hiển thị cửa sổ "Scheduled Task Wizard", chọn button Next để máy hiển thị cửa sổ kế tiếp.

     - Máy sẽ hiển thị danh sách các ứng dụng có thể chạy, chọn button Browse và duyệt thư mục để tìm ứng dụng cần chạy. Cụ thể trình "Windows Media Player" sẽ nằm trong thư mục "c:\Program files\Windows Media Player\wmplayer.exe".

     - chọn chế độ định giờ (daily,weekly, one time only...). Trong trường hợp của bạn, bạn nên chọn chế độ chạy "one time only", nhập tên nhận dạng cho lần định thì này (thí dụ Lanchay1), chọn button Next để máy hiển thị cửa sổ kế tiếp.

     - Nhập giờ/phút/giây và ngày/tháng/năm của thời điểm cần chạy ứng dụng rồi ấn button Next để máy hiển thị cửa sổ kế tiếp.

     - Nhập password sử dụng Windows của bạn vào rồi ấn button Next để máy hiển thị cửa sổ kế tiếp.

     - đánh dấu chọn checkbox open advanced properties... và ấn button Finish để hiển thị cửa sổ kế tiếp. Dời cursor về textbox Run và thêm thông tin tên file cần chơi vào lệnh Run. Cụ thể hàng lệnh sẽ có dạng sau:
     "c:\Program files\Windows Media Player\wmplayer.exe" /Play "c:\audio\filenhac1.mp3".
     - Cuối cùng nhấn button OK để hoàn thành 1 lần lập lịch chạy ứng dụng tại 1 thời điểm. Lập lại qui trình trên cho từng thời điểm cần chạy khác mà bạn muốn. Sau khi bạn lập lịch xong, cứ đến 1 thời điểm nào đó trong lịch hẹn đã thiết lập, máy sẽ thực hiện hàng lệnh qui định (cụ thể là chạy WMP và chơi đúng file nhạc qui định).
     
    Chuyên mục: Lập trình