b. Mouse move.
Đối với biến cố Mouse Move, ta cần có sự xử lý một cách đặc biệt hơn. Khi người
dùng di chuyển mouse trong vùng làm việc của World3D, Windows sẽ gởi các thông
điệp MouseMove đến. Trong trường hợp vị trí mouse thay đổi nhanh, thì số lượng các
biến cố gởi đến World3D là liên tục nhau. Nếu ta xử lý tất cả các biến cố này khi kéo đối tượng hoặc thay đổi vị trí camera sẽ dẫn đến hiện tượng “giật ảnh” do số lần cần
vẽ lại là khá lớn. Trong khi, ta khơng thiết phải xử lý tồn bộ các thay đổi vị trí của mouse, mà chỉ cần khi vị trí mouse đã ổn định. Nghĩa là, ta cần phải loại bỏ một số biến cố gởi đến.
Như vậy, ta cần có một bộ đếm (MouseCounter). Bộ đếm này sẽ được kích hoạt tại lần
đầu tiên World3D nhận được thông điệp. Trong khoảng thời gian bộ đếm này hoạt
động, tất cả các thông điệp MouseMove gởi đến sẽ bị bỏ qua. Và khi bộ đếm kết thúc
thì trình xử lý biến cố mới nhận vị trí cuối cùng của mouse trong vùng làm việc, tính tốn độ lệch so với vị trí trước đó của mouse để có những hành động thích hợp tùy vào trạng thái hiện tại của World3D.
Luận văn tốt nghiệp GVHH: Nguyễn Hữu Hải.
Trong World3D, bộ đếm được hiện thực bằng đối tượng Timer của hệ điều hành. Với khoảng thời gian interval là 200 ms, World3D có thể xử lý các biến cố MouseMove tương đối chính xác với những thay đổi vị trí của mouse mà khơng xảy ra hiện tượng “giật ảnh”.
Mouse Move Event Handler (TWorld3D)
Is Mouse timing? Render Context
is initialized
Restart Mouse Timer No
Yes
Is not initialized
Mouse Timer Event Handler (TWorld3D)
Stop Mouse Timer.
Mouse is captured? Flag wsMouseCaptured No Active Mode Is set Perform Mouse Fly wmMouseFly Send MouseMove to Capturing Object Yes Is not set other (a) (b)
- Fire event OnMouseLeaveObj() - Update ObjectUnderMouse. - Fire event OnMouseEnterObj()
Hình 4-6. Lưu đồ xử lý event MouseMove (a) và MouseTimer (b).
Ta để ý rằng, World3D chỉ xử lý biến cố MouseMove trong trường hợp nó đã được
khởi tạo một render context. Điều này là hoàn tồn hợp lý, vì khi render context chưa
được khởi tạo thì chưa có một đối tượng 3D nào được hiển thị, hay nói một cách khác
World3D chưa được khởi động, chưa sẳn sàng tương tác với người dùng. Ta rất dễ
nhận thấy rằng, hầu hết các trình xử lý biến cố của World3D chỉ làm việc khi render context đã được khởi tạo.
Khác với biến cố MouseDown, ở biến cố này, trình xử lý biến cố của WorldObject phức tạp hơn để cung cấp cơ chế drag-n-drop các đối tượng 3D. Các lớp hậu duệ của WorldObject hầu hết không cần phải viết thêm mã cho việc xử lý biến cố này. Hình sau mơ tả lưu đồ trình xử lý biến cố MouseMove của WorldObject.
Mouse Move Event Handler (TWorldObject)
Object being
dragged? Drag mode
Fire event OnDragObject(dragnow) Mouse displacement Compute Displacement (3D) Call Dragging(Displacement) Drag now Call BeginDrag() No Yes Yes No automatic >= DragThreadHold other manual