Phát triển AutoCAD 9
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ố.
Tóm tắt nội dung tài liệu: Phát triển AutoCAD 9
Phát triển ứng dụng ActiveX và VBA | 203 LÀ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 đó. 204 | Chương 7: Làm việc với các sự kiện 1. 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 Phát triển AutoCAD bằng ActiveX và VBA | 205 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. 1 Hộp thoại kiểu Modal (Modal dialog): là dạng hộp thoại mà sẽ chặn tất cả các tương tác với tất 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. 206 | Chương 7: Làm việc với các sự kiện Mộ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: Sự kiện Tình huống AppActivate Gọi đến ngay trước khi cửa sổ chính của ứng dụng được kích hoạt. AppDeactivate Gọi đến trước khi cửa sổ chính của ứng dụng được bỏ kích hoạt. ARXLoaded Gọi đến khi một ứng dụng ObjectARX được tải vào. ARXUnloaded Gọi đến khi một ứng dụng ObjectARX được dỡ ra. BeginCommand Gọi đến ngay sau một câu lệnh được sử dụng nhưng trước khi nó hoàn thành. BeginTệpDrop Gọi đến khi một tệp bị dỡ ra khỏi ứng dụng. BeginLISP Gọi đến ngay sau khi AutoCAD nhận được yêu cầu tính biểu thức LISP. BeginModal Gọi đến ngay trước khi modal dialog hiện ra. BeginOpen Gọi đến ngay sau khi AutoCAD nhận yêu cầu mở một tệp đã có. BeginPlot Gọi đến ngay sau khi AutoCAD nhận được yêu cầu in một bản vẽ. BeginQuit Gọi đến ngay trước khi một phiên làm việc của AutoCAD kết thúc. BeginSave Gọi đến ngay sau khi AutoCAD nhận được yêu cầu lưu một bản vẽ. EndCommand Gọi đến ngay sau khi một câu lệnh hoàn thành. EndLISP Gọi đến khi hoàn thành tính toán một biểu thức LISP. EndModal Gọi đến ngay sau khi hộp thoại bị đóng. EndOpen Gọi đến ngay sau khi AutoCAD kết thúc mở một bản vẽ đã có. EndPlot Gọi đến ngay sau khi một tài liệu được gửi đến máy in. EndSave Gọi đến ngay sau khi AutoCAD kết thúc lưu một bản vẽ. LISPCancelled Gọi đến ngay sau khi việc tính toán một biểu thức LISP bị dừng lại. NewDrawing Gọi đến trước khi tạo ra một bản vẽ mới. SysVarChanged Gọi đến khi giá trị của một biến hệ thống bị thay đổi WindowChanged Gọi đến khi có sự thay đổi cửa sổ ứng dụng. WindowMovedOrResized Gọi đến ngay sau khi cửa sổ ứng dụng đã được dich chuyển hoặc thay đổi kích thước. Phát triển AutoCAD bằng ActiveX và VBA | 207 3.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() 208 | Chương 7: Làm việc với các sự kiện ’ 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: Sự kiện Tình huống Activate Khi cửa sổ bản vẽ được kích hoạt BeginClose Ngay trước khi một bản vẽ đóng lại BeginCommand Ngay sau khi một câu lệnh được sử dụng và trước khi hoàn thành BeginDoubleClick Sau khi người dùng nhấn đúp lên một đối tượng trong bản vẽ BeginLISP Ngay sau khi AutoCAD nhận được yêu cầu tính một biểu thức LISP BeginPlot Ngay sau khi AutoCAD nhận được yêu cầu in một bản vẽ Phát triển AutoCAD bằng ActiveX và VBA | 209 BeginRightClick Sau khi người dùng nhấp chuột phải lên cửa sổ bản vẽ BeginSave Ngay sau khi AutoCAD nhận được yêu cầu lưu một bản vẽ BeginShortcutMenuCommand Sau khi người dùng nhấn chuột phải lên cửa sổ bản vẽ và trước khi trình đơn tắt xuất hiện ở dạng Command BeginShortcutMenuDefault Sau khi người dùng nhấn chuột phải lên cửa sổ bản vẽ và trước khi trình đơn tắt xuất hiện ở dạng Default BeginShortcutMenuEdit Sau khi người dùng nhấn chuột phải lên cửa sổ bản vẽ và trước khi trình đơn tắt xuất hiện ở dạng Edit BeginShortcutMenuGrip Sau khi người dùng nhấn chuột phải lên cửa sổ bản vẽ và trước khi trình đơn tắt xuất hiện ở dạng Grip BeginShortcutMenuOsnap Sau khi người dùng nhấn chuột phải lên cửa sổ bản vẽ và trước khi trình đơn tắt xuất hiện ở dạng Osnap Deactivate Khi cửa sổ bản vẽ thôi kích hoạt EndCommand Ngay sau khi câu lệnh hoàn thành EndLISP Khi hoàn thành tính toán biểu thức LISP EndPlot Sau khi một bản vẽ được gửi đến máy in EndSave Khi AutoCAD hoàn thành lưu bản vẽ EndShortcutMenu Sau khi trình đơn tắt xuất hiện LayoutSwitched Sau khi người dùng chuyển sang Layout khác LISPCancelled Khi việc tính toán biểu thức LISP bị dừng lại ObjectAdded Khi một đối tượng được thêm vào bản vẽ ObjectErased Khi một đối tượng bị xoá khỏi bản vẽ ObjectModified Khi một đối tượng trong bản vẽ bị sửa SelectionChanged Khi tập lựa chọn đầu tiên hiện tại bị thay đổi WindowChanged Khi có sự thay đổi đối với cửa sổ bản vẽ WindowMovedOrResized Ngay sau khi cửa sổ bản vẽ dịch chuyển hoặc thay đổi 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. 210 | Chương 7: Làm việc với các sự kiện 2 Chọn lớp mới 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 chọn: View Code 5 Trong cửa sổ Code của lớp thêm dòng lệnh sau: Public WithEvents Doc As AcadDocument 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 của 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 Document. 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 Document 1 Trong cửa sổ Code của môđun chính, thêm dòng lệnh sau trong phần các 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.Doc= ThisDrawing End Sub 3 Trong phần mã của môđun chính, thêm lời gọi thủ tục InitalizeApp Call InitializeEvents Khi thủ tục InitializeEvents được thực hiện thì đối tượng Doc trong lớp sẽ trỏ đến một đối tượng Document 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. 4.2. Lập trình trong các môi trường khác VBA Khi sự kiện ở mức bản vẽ đã được cho phép, ta sẽ tìm được biến của lớp Doc có trong hộp danh sách của cửa sổ mã chương trình của ClassModule. Chọn lớp Doc và liệt kê danh sách các sự kiện sẵn có sẽ xuất hiện trong hộp danh sách Procedure. Chỉ cần chọn sự kiện muốn viết xử lý, khung xử lý sẽ được tự động tạo ra. 4.3. Lập trình trong môi trường VBA Như đã đề cập ở trên trong phần trên, các sự kiện ở mức bản vẽ đã được tự động cho phép khi dự án VBA được tải vào. Để viết xử lý sự kiện cho các sự kiện này trong VBA, cần lựa chọn AcadDocument từ hộp danh sách trong cửa sổ Code. Các sự kiện có sẵn trong bản vẽ sẽ xuất hiện trong hộp danh sách Procedure. Chỉ cần lựa chọn sự kiện muốn xử lý, khung xử lý sẽ được tự động tạo ra. Chú ý rằng các xử lý sự kiện giới thiệu ở đây áp dụng cho bản vẽ hiện tại đang được kích hoạt. Để viết xử lý sự kiện cho một bản vẽ nhất định, trước hết thực hiện các Phát triển AutoCAD bằng ActiveX và VBA | 211 bước đã nêu trong phần “Kích hoạt sự kiện trong các môi trường ngoài VBA” trang 209, các thủ tục đó sẽ cho phép ta làm việc với bản vẽ cụ thể. Cập nhật trình đơn tắt với các sự kiện BeginShortcutMenuDefault và EndShortcutMenu Ví dụ này sử dụng bộ xử lý sự kiện cho sự kiện BeginShortcutMenuDefault để thêm chỉ mục “OpenDWG” ngay từ trước cho trình đơn tắt. Sau đó xử lý sự kiện cho EndShortcutMenu sẽ xoá chỉ mục thêm vào để nó không được lưu liên tục trong định dạng trình đơn của người dùng. Private Sub AcadDocument_BeginShortcutMenuDefault _ (ShortcutMenu As AutoCAD.IAcadPopupMenu) On Error Resume Next ’ Thêm chỉ mục cho trình đơn tắt Dim newMenuItem As AcadPopupMenuItem Dim openMacro As String openMacro = Chr(27) + Chr(27) + Chr(95) + "open" + Chr(32) Set newMenuItem = ShortcutMenu.AddMenuItem _ (0, Chr(Asc("&")) _ + "OpenDWG", openMacro) End Sub Private Sub AcadDocument_EndShortcutMenu _ (ShortcutMenu As AutoCAD.IAcadPopupMenu) On Error Resume Next ShortcutMenu.Item("OpenDWG").Delete End Sub 5. Xử lý sự kiện ở mức đối tượng Các sự kiện ở mức đối tượng không thường trực trong AutoCAD VBA. Có nghĩa là chúng sẽ không tự hoạt động khi một dự án VBA được tải vào. Một sự kiện ở mức đối tượng phải được cho phép đối với VBA và tất cả các điều khiển ActiveX Automation khác. Mỗi khi một sự kiện ở mức đối tượng được cho phép, chỉ có một sự kiện sau có thể sử dụng: Sự kiện Tình huống Modified Khi đối tượng trong bản vẽ bị sửa đổi 5.1. Kích hoạt sự kiện ở mức đối tượng Trước khi có thể sử dụng đối tượng ở mức sự kiện, ta cần tạo ra một module lớp mới và khai báo đối tượng với kiểu là AcadObject cùng với các sự kiện. Ví dụ: giả sử đã tạo một mô-đun lớp mới có tên là EventClassModule. Mô-đun 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 mô-đun lớp mới và khai báo một đối tượng Circle với các sự kiện: 1 Trong VBA IDE, thêm một mô-đun lớp: chọn menu Insert ClassModule. 2 Chọn mô-đun lớp mới trong cửa sổ Project 212 | Chương 7: Làm việc với các sự kiện 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 dùng phím tắt F7 hoặc bằng cách lựa chọn menu View Code 5 Trong cửa sổ Code của lớp thêm dòng lệnh sau: Public WithEvents Object As AcadCircle 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 trong mô-đun 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 mô-đun 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 mô-đun lớp với đối tượng Circle. 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 Automation 1 Trong cửa sổ Code của mô-đun chính, thêm dòng lệnh sau trong phần các khai báo: Dim x as New EventClassModule 2 Trong cùng cửa sổ đó, tạo một đường tròn có tên là “MyCircle” và khởi tạo nó với các sự kiện: Sub InitializeEvents() Dim MyCircle As AcadCircle Dim centerPoint(0 To 2) As Double Dim radius As Double centerPoint(0) = 0#: centerPoint(1) = 0#: centerPoint(2) = 0# radius = 5# Set MyCircle = ThisDrawing.ModelSpace.AddCircle(centerPoint,radius) Set X.Object = MyCircle 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 Circle trong mô-đun lớp sẽ trỏ đến một đối tượng Circle đã được tạo và bất cứ thủ tục sự kiện nào trong mô- đun lớp sẽ chạy khi sự kiện đó xảy ra. CHÚ Ý Khi lập trình trong VBA, cần phải cung cấp xử lý sự kiện Modified cho tất cả các đối tượng được cho phép hiệu chỉnh. Nếu không được xử lý, chương trình có thể bị ngắt không theo mong muốn. Hiển thị diện tích của đường đa tuyến kín mỗi khi nó được cập nhật Ví dụ này tạo ra một đường đa tuyến có bề dày cùng với các sự kiện. Bộ xử lý sự kiện cho đường đa tuyến sẽ thể hiện diện tích mới mỗi khi nó bị thay đổi. Để gọi sự kiện này chỉ cần thay đổi kích cỡ của nó trong AutoCAD và lưu ý rằng, phải chạy thủ tục CreatePlineWithEvents trước khi xử lý sự kiện được kích hoạt. Phát triển AutoCAD bằng ActiveX và VBA | 213 Public WithEvents PLine As AcadLWPolyline Sub CreatePLineWithEvents() ’ Ví dụ này sẽ tạo ra đường light weight polyline Dim points(0 To 9) As Double points(0) = 1: points(1) = 1 points(2) = 1: points(3) = 2 points(4) = 2: points(5) = 2 points(6) = 3: points(7) = 3 points(8) = 3: points(9) = 2 Set PLine = ThisDrawing.ModelSpace. _ AddLightWeightPolyline(points) PLine.Closed = True ThisDrawing.Application.ZoomAll End Sub Private Sub PLine_Modified (ByVal pObject As AutoCAD.IAcadObject) ’ Sự kiện này được gọi khi đường polyline bị thay đổi kích thước ’ Nếu đường polyline bị xoá thì sự kiện modified vẫn được gọi ra nên ’ có thể sử dụng bẫy lỗi để tránh đọc dữ liệu từ đối tượng đã bị xoá On Error GoTo ERRORHANDLER MsgBox "The area of " & pObject.ObjectName & " is: "& pObject.Area Exit Sub ERRORHANDLER: MsgBox Err.Description End Sub
File đính kèm:
- phat_trien_autocad_9.pdf