Search…

Xử Lý Sự Kiện Chuột và Phím với Borland Graphics Interface - BGI

22/09/20205 min read
Giới thiệu cách lập trình để xử lý sự kiện chuột cũng như bàn phím thông qua thư viện Borland Graphics Interface – BGI bằng C/C++.

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 xy 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 xy 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 ismouseclickgetmouseclick. 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;
}
IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024