Giới thiệu
Đối với các ứng dụng đồ họa như: vẽ, xử lý văn bản, xử lý bảng tính, … thì nhận, xử lý các sự kiện chuột và bàn phím là rất cần thiết. Nếu ứng dụng xử lý tốt các sự kiện này, giúp cho người dùng sử dụng hết các tính năng mà ứng dụng cung cấp cũng như tạo sự tiện dụng, nhanh chóng, tăng năng suất khi làm việc.
Xử lý sự kiện với thư viện BGI
Sự kiện chuột
Thư viện BGI cung cấp sẵn 1 số phương thức để có thể thao tác với chuột và bàn phím. Đơn giản nhất như bộ đôi:
int mousex() int mousey()
Cả hai phương thức này trả về tọa độ của chuột trên khung cửa sổ ứng dụng tại thời điểm hàm này được gọi. Khi vị trí của chuột nằm ngoài khung ứng dụng thì việc gọi hàm này sẽ xảy ra 2 trường hợp:
- Nếu chuột chưa từng di chuyển vào phạm vi cửa sổ ứng dụng - giá trị trả về là 0
- Nếu chuột đã từng ở trong phạm vi cửa sổ ứng dụng và sau đó di chuyển ra ngoài, giá trị trả về là tọa độ lần cuối cùng của chuột trong cửa sổ ứng dụng.
Đoạn chương trình sau mô tả cách lấy tọa độ chuột di chuyển và in ra màn hình:
#include <stdio.h> #include "graphics.h" #pragma comment(lib, "graphics.lib") int main() { int gd = DETECT, gm; initgraph(&gd, &gm, ""); while (true) { printf("Current mouse position: (%d, %d)\n", mousex(), mousey()); } getch(); closegraph(); return 0; }
Thư viện BGI nhận các loại sự kiện chuột như:
WM_MOUSEMOVE
WM_LBUTTONDBLCLK
WM_LBUTTONDOWN
WM_LBUTTONUP
WM_MBUTTONDBLCLK
WM_MBUTTONDOWN
WM_MBUTTONUP
WM_RBUTTONDBLCLK
WM_RBUTTONDOWN
WM_RBUTTONUP
Trong đó RBUTTON
là chuột phải, LBUTTON
là chuột trái và MBUTTON
là chuột giữa.
Các loại sự kiện chuột ở trên sẽ giúp ta dễ dàng thao tác với các hàm sau:
ismouseclick
bool ismouseclick(int kind);
Trả về true
khi có sự kiện click xảy ra mà chưa được xử lý, ngược lại là false
.
getmouseclick
void getmouseclick(int kind, int& x, int& y);
Gán x
và y
là giá trị tọa độ chuột tại thời điểm được click và đánh dấu đã xử lý 1 sự kiện click. Nếu tại thời điểm gọi hàm mà không còn sự kiện click nào xảy ra thì giá trị của x
và y
là -1. Hàm này thường được dùng chung với hàm ismouseclick
để xử lý sự kiện 1 cách linh hoạt hơn.
Đoạn mã sau minh họa cách sử dụng của 2 hàm này:
#include <stdio.h> #include "graphics.h" #pragma comment(lib, "graphics.lib") int main() { int gd = DETECT, gm; initgraph(&gd, &gm, ""); while (true) { if (ismouseclick(WM_LBUTTONDOWN)) { int x, y; getmouseclick(WM_LBUTTONDOWN, x, y); printf("Current mouse position: (%d, %d)\n", x, y); } } closegraph(); return 0; }
clearmouseclick
void clearmouseclick(int kind);
Hủy các sự kiện chuột tùy thuộc vào loại sự kiện được truyền vào tham số, sau khi thực hiện xong hàm này thì giá trị của ismouseclick
sẽ được reset về false
.
registermousehandler
Hầu hết các sự kiện chuột đều có thể giải quyết bằng cách sử dụng bộ đôi ismouseclick
và getmouseclick
. Ngoài ra còn có thể nhận sự kiện chuột thông qua việc đăng ký hàm xử lý chuột với thư viện qua hàm:
void registermousehandler(int kind, void h(int, int));
Hàm này nhận 2 tham số, tham số đầu tiên là loại sự kiện (đã trình bày ở trên) và tham số thứ hai là con trỏ hàm đến hàm xử lý sự kiện mong muốn. Xét đoạn chương trình sau:
#include <stdio.h> #include "graphics.h" #pragma comment(lib, "graphics.lib") void mouseMoveHandler(int x, int y) { printf("Current mouse position: (%d, %d)\n", x, y); } int main() { int gd = DETECT, gm; initgraph(&gd, &gm, ""); registermousehandler(WM_MOUSEMOVE, mouseMoveHandler); getch(); closegraph(); return 0; }
Tạo hàm mouseMoveHandler
, nhiệm vụ của nó là nhận sự kiện chuột bao gồm tọa độ (x, y)
và tiến hành xử lý sự kiện đó - ở đây chỉ đơn giản là in ra tọa độ. Và tại lời gọi hàm registermousehandler
tiến hành đăng ký hàm mouseMoveHandler
với thư viện. Như vậy mỗi khi có sự kiện chuột di chuyển trên cửa sổ ứng dụng thì hàm mouseMoveHandler
sẽ được gọi.
Có thể áp dụng tương tự cho các sự kiện khác như: WM_LBUTTONDBLCLK
, WM_LBUTTONDOWN
, WM_LBUTTONUP
, ...
Sự kiện phím
Tương tự như với chuột, thư viện BGI cung cấp các hàm sau để xử lý sự kiện phím:
getch
int getch();
Trả về mã ASCII của ký tự vừa được nhấn, nếu có 1 ký tự đặc biệt được nhất ví dụ như: HOME
, UP
, DOWN
, … thì lần đầu tiên hàm getch()
sẽ trả về giá trị 0. Lần thứ 2 sẽ trả về 1 trong các mã sau:
KEY_HOME
KEY_UP
KEY_PGUP
KEY_LEFT
KEY_CENTER
KEY_RIGHT
KEY_END
KEY_DOWN
KEY_PGDN
KEY_INSERT
KEY_DELETE
KEY_F1
KEY_F2
KEY_F3
KEY_F4
KEY_F5
KEY_F6
KEY_F7
KEY_F8
KEY_F9
kbhit
int kbhit();
Kiểm tra xem tại thời điểm gọi hàm có sự kiện phím nào chưa được xử lý không, trả về 0 không có sự kiện nào xảy ra.
Đoạn chương trình sau minh họa cách lấy các sự kiện phím:
#include <stdio.h> #include "graphics.h" #pragma comment(lib, "graphics.lib") int main() { int gd = DETECT, gm; initgraph(&gd, &gm, ""); while (true) { if (kbhit()) { char key = getch(); if (!key) { key = getch(); printf("# Special key pressed - Code: %d\n", key); } else printf("- Key '%c' is pressed\n", key); } } closegraph(); return 0; }