Public WithEvents ACADApp As AcadApplication Sub Example_AcadApplication_Events().[r]
Trang 1LÀM VIỆC VỚI CÁC SỰ KIỆN
7 Trong chương này
Khái niệm về các sự kiện trong AutoCAD
Chỉ dẫn xây dựng bộ xử
lý sự kiện
Xử lý sự kiện ở mức ứng dụng
Xử lý sự kiện ở mức bản
vẽ
Xử lý sự kiện ở mức đối tượng
Các sự kiện chẳng hạn như thông báo hoặc thông điệp của AutoCAD, dùng để thông báo tới người dùng về trạng thái hiện tại của phiên làm việc hoặc
để cảnh báo cho người dùng về những gì đã xảy ra
Ví dụ, khi mở bản vẽ thì sự kiện BeginOpen được gọi, sự kiện này chứa tên bản vẽ AutoCAD được mở;
còn khi đóng bản vẽ, sẽ có một sự kiện khác được gọi Khi có được những thông tin này ta có thể xây dựng được chương trình giúp xác định được thời gian người dùng dành cho một bản vẽ nào đó
Trang 21 Khái niệm về các sự kiện trong AutoCAD
Trong AutoCAD có 3 loại sự kiện:
Các sự kiện ở mức ứng dụng sẽ đáp ứng lại những thay đổi trong ứng dụng AutoCAD và môi trường của nó bao gồm: mở, lưu, đóng và in các bản vẽ, tạo bản vẽ mới, sử dụng dòng lệnh, tải hoặc dỡ bỏ ứng dụng ARX và AutoLISP, thay đổi các biến hệ thống và thay đổi đối với cửa sổ của ứng dụng
Các sự kiện ở mức bản vẽ sẽ đáp ứng lại những thay đổi đối với từng bản vẽ hoặc những gì bên trong nó bao gồm: thêm, xoá hoặc thay đổi các đối tượng, kích hoạt trình đơn tắt, thay đổi trong tập lựa chọn, thay đổi đối với cửa sổ vẽ và quá trình tái tạo bản vẽ Ngoài ra cũng có một số các sự kiện ở mức này đáp ứng lại với việc mở, đóng và in một bản vẽ, tải hoặc dỡ bỏ các ứng dụng ARX và AutoLISP từ bản vẽ
Các sự kiện ở mức đối tượng đáp ứng lại các thay đổi của một đối tượng cụ thể Hiện tại chỉ có một sự kiện duy nhất ở mức này, nó được gọi mỗi khi đối tượng bị thay đổi
Các hàm đáp ứng lại các sự kiện được gọi là bộ xử lý sự kiện và được thực hiện một cách tự động mỗi khi sự kiện tương ứng được gọi Các thông tin chứa trong các sự kiện, ví dụ như tên bản vẽ trong sự kiện BeginOpen, được chuyển vào bộ xử lý sự kiện thông qua các tham số
2 Chỉ dẫn xây dựng bộ xử lý sự kiện
Điều quan trọng cần lưu ý là các sự kiện chỉ đơn giản cung cấp các thông tin dựa trên trạng thái hoặc các hoạt động diễn ra trong AutoCAD Mặc dù bộ xử lý sự kiện
có thể được viết để đáp ứng lại các sự kiện đó, nhưng AutoCAD lại nằm bên trong quá trình xử lý khi các bộ xử lý sự kiện được gọi Do đó các bộ xử lý sự kiện thường có những hạn chế về những tác vụ có thể thực hiện được nhằm đảm bảo sự
an toàn cho các thao tác tác động đến AutoCAD và cơ sở dữ liệu
Không nên dựa vào trình tự của các sự kiện
Khi viết các bộ xử lý sự kiện ta không nên dựa vào trình tự xảy ra của các sự kiện như theo mình suy nghĩ Ví dụ: khi sử dụng lệnh OPEN, sự kiện BeginCommand, BeginOpen, EndOpen và EndCommand sẽ đều được thực hiện Tuy nhiên, chúng có thể không xảy ra theo trật tự đó Trình tự sự kiện duy nhất có thể sử dụng một cách an toàn là sự kiện Begin sẽ xảy ra trước sự kiện End tương ứng Trong ví dụ trước, sự kiện có thể được xảy ra theo trình
tự sau: BeginCommand – BeginOpen – EndCommand – EndOpen hoặc BeginCommand – EndCommand – BeginOpen – EndOpen
Không nên dựa vào trình tự của các thao tác xử lý
Nếu ta xoá đối tượng 1 và tiếp theo là đốí tượng 2, không nên cho rằng sự kiện ObjectErased cho đối tượng 1 phát sinh trước rồi sau đó cho đối tượng
2, vì thực tế, ta có thể sẽ nhận được sự kiện của đối tượng 2 trước
Không nên dùng các hàm tương tác trong bộ xử lý sự kiện
Trang 3
Cố gắng thực hiện một hàm tương tác trong bộ xử lý sự kiện có thể dẫn đến nhiều rắc rối khá nghiêm trọng, vì AutoCAD có thể vẫn tiếp tục thực hiện một câu lệnh nào đó vào thời điểm mà sự kiện bắt đầu Vì vậy, nên tránh sử dụng các phương thức đòi hỏi phải nhập dữ liệu, ví dụ như GetPoint, GetEntity, GetKeyword… cũng như các thao tác chọn đối tượng và phương thức SendCommand trong bất cứ bộ xử lý sự kiện nào
Không nên gọi hộp thoại trong bộ xử lý sự kiện Hộp thoại được coi là hàm tương tác, có thể cản trở các thao tác đang sử dụng trong AutoCAD Tuy nhiên các hộp thông báo hoặc cảnh báo được coi
là không có sự tương tác do đó có thể sử dụng một cách an toàn
Ta có thể ghi dữ liệu vào cơ sở dữ liệu của bất cứ đối tượng nào ngoại trừ đối tượng phát sinh sự kiện
Một cách hiển nhiên là bất cứ đối tượng nào làm phát sinh một sự kiện đang được xử lý có thể vẫn được mở để sử dụng trong AutoCAD và các thao tác vẫn đang được tiến hành Do đó nên tránh việc ghi bất cứ thông tin nào cho đối tượng từ bộ xử lý sự kiện của chính đối tượng đó Tuy nhiên, ta vẫn có thế đọc thông tin một cách an toàn từ đối tượng phát sinh sự kiện Ví dụ: ta
có một sàn nhà được lát gạch và đã có bộ xử lý sự kiện được đính kèm với đường biên sàn nhà Nếu ta thay đổi kích thước của sàn nhà thì bộ xử lý sự kiện sẽ tự động cộng hoặc trừ các viên gạch để phủ kín diện tích sàn mới
Bộ xử lý sự kiện sẽ vẫn có thể đọc diện tích mới của đường biên nhưng nó không thể thay đổi được bất cứ thứ gì trên biên đó
Không nên thực hiện bất cứ thao tác nào từ bộ xử lý sự kiện mà sẽ làm phát sinh chính sự kiện đó
Nếu ta thực hiện cùng một thao tác trong bộ xử lý sự kiện mà sẽ làm phát sinh sự kiện đó thì sẽ tạo ra một vòng lặp vô hạn Ví dụ người dùng không nên cố gắng mở một bản vẽ bên trong sự kiện BeginOpen, nếu không AutoCAD sẽ tiếp tục mở thêm nhiều bản vẽ khác cho tới khi đạt đến số lượng bản vẽ được mở lớn nhất
Lưu ý rằng không có sự kiện nào được thực hiện khi AutoCAD đang hiển thị hộp thoại kiểu Modal1
3 Xử lý sự kiện ở mức ứng dụng
Các sự kiện ở mức ứng dụng không duy trì liên tục trong AutoCAD VBA, tức là chúng không được phép hoạt động một cách tự động khi tải một dự án VBA Do vậy, các sự kiện này cần được kích hoạt đối với VBA và tất cả các điều khiển ActiveX Automation
cả các hộp thoại hiển thị trước nó ở trong cùng một ứng dụng Chỉ những hộp thoại khác ứng dụng hoặc những hộp thoại được gọi từ bản thân hộp thoại modal mới có thể nhận được các tương tác từ phía người dùng
Trang 4Một khi sự kiện ở mức ứng dụng được kích hoạt, có rất nhiều sự kiện mà ta có thể
sử dụng, bao gồm:
kích hoạt
hoạt
khi nó hoàn thành
biểu thức LISP
đã có
bản vẽ
kết thúc
một bản vẽ
có
dừng lại
chuyển hoặc thay đổi kích thước
Trang 53.1 Kích hoạt sự kiện ở mức ứng dụng
Trước khi sử dụng sự kiện ở mức ứng dụng người dùng phải tạo ra một lớp mới và khai báo một đối tượng có kiểu là AcadApplication cùng với các sự kiện Ví dụ, giả
sử có một lớp mới được tạo ra gọi là EventClasssModule, lớp mới này chứa các khai báo của ứng dụng với từ khoá của VBA là WithEvents
Để tạo một lớp mới và khai báo đối tượng Application với các sự kiện:
1 Trong VBA IDE, để thêm một lớp: Insert ClassModule
2 Chọn lớp mới được tạo trong cửa sổ Project
3 Đổi tên của lớp trong cửa sổ Properties thành EventClassModule
4 Mở cửa sổ Code của lớp bằng cách bấm phím F7 hoặc lựa chọn: View Code
5 Trong cửa sổ Code của lớp thêm dòng lệnh sau:
Public WithEvents App As AcadApplication
Sau khi một đối tượng đã được khai báo với các sự kiện, nó sẽ xuất hiện trong hộp danh sách Object của lớp và người dùng có thể viết các thủ tục sự kiện cho đối tượng mới trong lớp (Khi lựa chọn một đối tượng mới trong hộp Object, các sự kiện có hiệu lực đối với đối tượng đó đều có trong hộp danh sách Procedure)
Tuy nhiên, trước khi các thủ tục được thực hiện ta phải kết nối những đối tượng được khai báo trong lớp với đối tượng Application Dưới đây là đoạn mã mà ta có thể chèn vào bất cứ môđun nào để thực hiện việc kết nối trên
Để kết nối đối tượng được khai báo với đối tượng Application
1 Trong cửa sổ Code của môđun chính, thêm dòng lệnh sau trong phần khai báo:
Dim X as New EventClassModule
2 Trong cùng cửa sổ đó thêm vào thủ tục:
Sub InitializEvent() Set X.App= ThisDrawing.Application End Sub
3 Trong phần mã của môđun chính, thêm lời gọi thủ tục InitalizeApp
Call InitializEvents
Khi thủ tục InitializEvents được thực hiện thì đối tượng App trong lớp sẽ trỏ đến một đối tượng Application nhất định và bất cứ thủ tục sự kiện nào trong lớp sẽ chạy khi sự kiện đó xảy ra
Lời nhắc tiếp tục khi một bản vẽ được thả vào AutoCAD
Ví dụ này chặn lại quá trình tải khi một tệp đã được kéo và thả vào AutoCAD Khi
đó, sẽ có hộp thoại thông báo gồm tên tệp, các nút lệnh Yes/No/Cancel cho phép người dùng quyết định xem có tiếp tục tải tệp đó nữa hay không Nếu người dùng lựa chọn thoát khỏi thao tác, quyết định đó sẽ được thực hiện nhờ việc trả về thông
số Cancel của sự kiện BeginFileDrop và tệp đó sẽ không được tải
Public WithEvents ACADApp As AcadApplication Sub Example_AcadApplication_Events()
Trang 6’ Ví dụ này khởi tạo biến toàn cục (ACADApp)
’ biến này sẽ được sử dụng để chặn sự kiện AcadApplication
’ Chạy thủ tục này trước tiên!
’ Có thể gọi được ứng dụng từ đối tượng ThisDocument,
’ nhưng yêu cầu có bản vẽ đang mở
’ nên bản vẽ sẽ được lấy được từ hệ thống Set ACADApp = GetObject(, "AutoCAD.Application") End Sub
Private Sub ACADApp_BeginTệpDrop _
(ByVal FileName As String, Cancel As Boolean)
’ Ví dụ này chặn sự kiện BeginFileDrop của ứng dụng
’ Sự kiện này được bắt đầu khi một bản vẽ được kéo vào AutoCAD
’ Để bắt đầu cho ví dụ này:
’ 1) Phải chạy ví dụ khởi tạo trước, trong ví dụ này biến
’ toàn cục là ACADApp đã được liên kết với sự kiện này
’ 2) Kéo một tệp bản vẽ AutoCAD vào chương trình AutoCAD
’ từ Windows Desktop hoặc từ Windows Explorer
’ Sử dụng biến "Cancel" để dừng việc tải tệp
’ và biến "TệpName" để thông báo cho người dùng
’ tệp nào sắp được thả vào
If MsgBox("AutoCAD is about to load " & FileName & vbCrLf _
& "Do you want to continue loading this file?", _ vbYesNoCancel + vbQuestion) <> vbYes Then
Cancel = True End If
End Sub
4 Xử lý sự kiện ở mức bản vẽ
Các sự kiện ở mức bản vẽ luôn duy trì liên tục trong VBA của AutoCAD, nghĩa là chúng sẽ được tự động kích hoạt khi tải một dự án VBA Tuy nhiên, chúng không được kích hoạt đối với bất cứ điều khiển nào khác, chẳng hạn như VB Do đó các sự kiện ở mức bản vẽ cần được kích hoạt đối với tất cả các điều khiển ActiveX Automation khác
Mỗi khi một sự kiện ở mức bản vẽ được kích hoạt, ta có nhiều sự kiện để sử dụng, bao gồm:
hoàn thành
bản vẽ
biểu thức LISP
vẽ
Trang 7BeginRightClick Sau khi người dùng nhấp chuột phải lên cửa sổ bản vẽ
bản vẽ
và trước khi trình đơn tắt xuất hiện ở dạng Command
và trước khi trình đơn tắt xuất hiện ở dạng Default
và trước khi trình đơn tắt xuất hiện ở dạng Edit
và trước khi trình đơn tắt xuất hiện ở dạng Grip
và trước khi trình đơn tắt xuất hiện ở dạng Osnap
kích cỡ
4.1 Kích hoạt sự kiện trong các môi trường ngoài VBA
Trước khi sử dụng sự kiện ở mức bản vẽ trong môi trường VB hoặc các môi trường khác ngoài VBA, ta cần tạo ra một lớp mới và khai báo đối tượng với kiểu là AcadDocument cùng với các sự kiện Ví dụ: giả sử đã tạo một lớp mới có tên là EventClassModule, lớp mới này chứa các khai báo của ứng dụng theo từ khoá WithEvents của VBA
Để tạo một lớp mới và khai báo đối tượng Document với các sự kiện:
1 Trong VBA IDE, thêm một lớp: Insert ClassModule