Iczelion’s Tutorial Win32 ASM Tutorial 7 : Mouse Input
Nhp liu thông qua thiết b chut
Chúng ta s tìm hiu làm thế nào ca s ng dng tiếp nhn và phn hi thông đip được
phát sinh t thiết b chut trong th tc x lý WinProc ca ca s. Chương trình ví d s
đợi nút trái chut được click và hin th mt chui text ngay ti đim click chut trong
vùng client.
Thiết b chut
Trong mt môi trường giao tiếp đồ ha, vic s dng thiết b định v chut là hết
sc cn thiết. Nh thiết b chut ta có th di chuyn đến mt đim bt kì trên khung màn
hình và thc hin thao tác kích các nút chut. Đối vi mt s ng dng đồ ha không quá
phc tp thì công c để thc hin ch yếu là chut, riêng đối vi các ng dng đòi hi s
phc tp khi v thì người ta dùng bút v.
Vi Windows thì thiết b chut là mt thành phn quan trng, nếu chúng ta b thiết
b chut thì vn khi động bình thường và các chương trình vn có th chy được. Tuy
nhiên khi đó ta s lúng túng nhiu khi x lý các ng dng trc quan tương tác vi người
dùng theo ta độ hay định v.
Cũng tương t như bàn phím, thiết b chut cũng được dùng để nhp d liu t
người dùng vào ng dng nhưng d liu đây không phi là văn bn như khi nhp t bàn
phím mà là các thao tác v hay x lý các đối tượng đồ ha.
X lý các thông đip t thiết b chut
Các thông đip được to t chut rt khác vi thông đip ca bàn phím, mt th
tc ca s s nhn thông đip chut bt c khi nào thiết b chut di chuyn qua ca s
hay kích vào trong ca s, thm chí c trong trường hp ca s không được kích hot hay
không nhn được s quan tâm. Windows định nghĩa 21 thông đip được phát sinh t thiết
b chut. Trong s đó có đến 11 thông đip không liên quan đến vùng làm vic (client
area). Nhng thông đip không phi vùng làm vic (nonclient-area messages) thường
được các ng dng b qua không x lý.
Thông đip chut trong vùng làm vic
Khi con tr chut di chuyn vào vùng làm vic ca mt ca s, th tc ca s ca
nó s nhn được thông đip WM_MOUSEMOVE. Bng sau mô t các thao tác làm vic
vi thiết b chut và các thông đip phát sinh t nó.
Nút Nhn Th Nhn đúp
Trái WM_LBUTTONDOWN WM_LBUTTONUP WM_LBUTTONDBLCLK
Gia WM_MBUTTONDOWN WM_MBUTTONUP WM_MBUTTONDBLCLK
Phi WM_RBUTTONDOWN WM_MBUTTONUP WM_RBUTTONDBLCLK
Người dch: Benina (REA TEAM) Trang 1
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 7 : Mouse Input
Th tc ca s ca ng dng s nhn được thông đip ca nút chut gia nếu máy tính
cài thiết b chut có 3 nút. Tương t như vy vi thông đip thiết b chut phi, chúng ta
cn có thiết b chut dùng 2 nút. Để nhn được thông đip kích đúp thiết b chut th tc
ca s phi khai báo nhn thông đip này.
Wndclass.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
Trong thông đip phát sinh t thiết b chut thì tham s lParam s cha v trí ca thiết b
chut, 16 byte thp s cha giá tr ta độ x, còn 16 byte cao s cha giá tr ta độ ca y.
Để ly ra hai giá tr này ta có th dùng macro là LOWORDHIWORD.
Giá tr wParam s cho biết trng thái ca nút nhn, phím Shift, và phím Ctrl. Chúng ta
có th kim tra các trng thái này bng cách dùng bit mt n được định nghĩa trước trong
WINUSER.H. Các mt n này đưc bt đầu bng tin t MK_xxx (Mouse Key)
MK_LBUTTON Nút chut trái nhn
MK_MBUTTON Nút chut gia nhn
MK_RBUTTON Nút chut phi nhn
MK_SHIFT Phím Shift được nhn
MK_CONTROL Phím Ctrl được nhn
Ví d khi nhn được thông đip WM_LBUTTONDOWN chúng ta mun kim tra xem
phím Ctrlđược nhn hay không bng cách so giá tr wParam vi mt n
MK_CONTROL.
...
if (wParam & MK_CONTROL)
{
/* Có gi• phím control */
}
else
{
/* Không gi• phím control */
}
Như chúng ta đã biết khi di chuyn thiết b chut qua vùng làm vic thì thông đip
WM_MOUSEMOVE s được gi đến cho th tc ca s đó. Nhưng Windows không
phát sinh thông đip này cho tng pixel trên màn hình mà tu thuc vào thông s phn
cng ca thiết b chut được cài đặt và tc độ làm vic ca nó.
Khi chúng ta kích nút chut trái vào vùng làm vic ca mt ca s không kích hot
(inactive window) thì Windows s kích hot ca s này tc là ca s va đưc kích hot
active, sau đó truyn thông đip WM_LBUTTONDOWN vào th tc WndProc ca ca
s. Khi mt ca s nhn được thông đip WM_XXXDOWN thì không nht thiết phi
nhn được thông đip WM_XXXUP hay ngược li. Điu này được gii thích như sau,
Người dch: Benina (REA TEAM) Trang 2
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 7 : Mouse Input
khi người dùng kích trái vào mt ca s và gi luôn nút chut va kích ri kéo thiết b
chut đến mt vùng thuc phm vi ca ca s khác mi th. Khi đó ca s đầu tiên s
nhn được thông đip nhn chut WM_LBUTTONDOWN và ca s th hai s nhn
được thông đip nh thiết b chut WM_LBUTTONUP. Tuy nhiên tình hung trên s
không xut hin vi hai trường hp ngoi l sau:
Th tc WndProc ca mt ca s đang thc hin vic bt gi thiết b chut
(mouse capture), đối vi tình trng này thì ca s tiếp tc nhn được thông đip
chut cho dù con tr chut có di chuyn ra ngoài vùng làm vic ca ca s. Kiu
này thường xut hin trong các ng dng v hay thao tác đối tượng đồ ha, ví d
khi ta v mt đường thng dài và kéo ra ngoài vùng làm vic ca ca s, thì khi đó
ca s v s bt gi to độ ca thiết b chut để to đường thng và có th cho
thanh cun cun theo.
Nếu xut hin hp thông tin trng thái (model) ca h thng, thì không có chương
trình nào khác nhn được thông đip ca thiết b chut. Hp thoi trng thái h
thng và hp thoi trng thái ca ng dng ngăn cn vic chuyn qua ca s khác
trong mt ng khi nó chưa gii quyết xong hay vn còn trng thái kích hot
(active).
Thông đip ca thiết b chut ngoài vùng làm vic
Vi các thông đip ca thiết b chut va tìm hiu trong phn trước đều được phát
sinh khi thiết b chut nm trong vùng làm vic ca ca s. Khi di chuyn con tr chut
ra khi vùng làm vic ca ca s nhưng vn trong phm vi ca ca s thì khi đó các
thông đip ca thiết b chut s được phát sinh dng thông đip ca thiết b chut ngoài
vùng làm vic (nonclient-area). Ngoài vùng làm vic ca mt ca s là ca s thanh tiêu
đề, thc đơn, và thanh cun ca ca s.
Nói chung vi các thông đip ca thiết b chut phát sinh t ngoài vùng làm vic
thì chúng ta không quan tâm lm, thay vào đó ta giao phó cho hàm mc định x lý là
DefWindowProc thc hin. Điu này cũng ging như là thông đip bàn phím h thng
mà ta đã tìm hiu trong các phn trước.
Cũng tương t như thông đip xut phát t vùng làm vic, các thông đip ngoài
vùng làm vic được định nghĩa vi t NC vào sau du "_", ta có bng mô t các thông
đip phát sinh t ngoài vùng làm vic như sau.
Nút Nhn Th Nhn đúp
Trái WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK
Gia WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK
Phi WM_RBUTTONDOWN WM_NCRBUTTONDOWN WM_NCRBUTTONDBLCLK
Người dch: Benina (REA TEAM) Trang 3
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 7 : Mouse Input
Các tham s lParamwParam cũng hơi khác so vi các thông đip thiết b chut phát
sinh trong vùng làm vic. Vi tham s lParam ca thông đip phát sinh t ngoài vùng
làm vic s ch ra v trí ngoài vùng làm vic nơi mà thiết b chut di chuyn hay kéo ti.
V trí này được định danh bi các giá tr định nghĩa trong WINUSER.H được bt đầu vi
HT (viết tt cho hit-test).
Ta độ màn hình và ta độ vùng làm vic
Tham s lParam s cha ta độ x 16 byte thp và ta độ y 16 byte cao. Tuy nhiên,
đây là ta độ màn hình, không phi là ta độ vùng làm vic ging như thông đip phát
sinh t vùng làm vic. Do đó chúng ta phi chuyn v ta độ vùng làm vic để x lý tiếp
nếu cn.
Để chuyn t ta độ màn hình sang ta độ làm vic hay ngược li t ta độ làm vic sang
ta độ màn hình ta dùng hai hàm tương ng được Windows cung cp như sau :
ScreenToClient(hwnd,&pt);
ClientToScreen(hwnd,&pt);
pt là biết cu trúc POINT, hai hàm trên s nhn tham chiếu đến biến pt do đó sau khi gi
hàm ta s được giá tr pt tương ng ta độ mi.
Người dch: Benina (REA TEAM) Trang 4
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)
Iczelion’s Tutorial Win32 ASM Tutorial 7 : Mouse Input
Ví d
.386
.model flat,stdcall
option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include windows.inc
include user32.inc
include kernel32.inc
include gdi32.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib
.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
MouseClick db 0 ; 0=no click yet
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hitpoint POINT <>
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMainproc hInst:HINSTANCE,hPrevInst:HINSTANCE,
CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
INVOKE ShowWindow, hwnd,SW_SHOWNORMAL
Người dch: Benina (REA TEAM) Trang 5
Tng hp và hiu chnh: NhatPhuongLe (VNCERT TEAM)