[Ngôn ngữ Avenue #10] Liên kết ứng dụng với Avenue

0
2964
ArcView cung cấp một số giải pháp để có thể tương tác đến các ứng dụng khác ngoài ứng dụng ArcView như Visual Basic, Excel, Access, Word. Ta cũng có thể gọi các hàm của các thư viện liên kết động DLL để thực thi trong ứng dụng ArcView. Hai trong số các giải pháp sẽ học trong chương này là: Giải pháp trao đổi dữ liệu động (Dynamic Data Exchange – DDE) và giải pháp gọi hàm trong các thư viện liên kết động (Dynamic Link Libraries – DLL).

 

1. TRAO ĐỔI DỮ LIỆU ĐỘNG

Microsoft hỗ trợ một kỹ thuật client/server gọi là trao đổi dữ liệu động (DDE). Được hỗ trợ trên hệ điều hành Microsoft Windows, DDE có khả năng cho phép hai ứng dụng nói chuyện với nhau bằng cách trao đổi dữ liệu một cách liên tục và tự động . ArcView cũng hỗ trợ DDE và có khả năng giao tiếp với các ứng dụng khác cũng hỗ trợ DDE như Visual basic, Excel, Access và Lotus.
DDE có một giới hạn đó là các ứng dụng trao đổi dữ liệu với nhau phải chạy trên cùng một máy, DDE không hỗ trợ mạng.
Khi hai ứng dụng tương tác với nhau nó được gọi là một hội thoại. Một ứng dụng là Server và ứng dụng còn lại là Client. Cuộc hội thoại sẽ được nhận diện bằng hai thông tin: tên ứng dụng của Server (application name) và tên chủ đề (topic name). Nếu muốn thiết lập một cuộc hội thoại với ứng dụng ArcView, ta sẽ phải chỉ định tên của ứng dụng là ‘ArcView’ và tên chủ đề là ‘System’. ArcView chỉ có duy nhất một tên chủ đề và nó được gọi là system. Nếu muốn thiết lập cuộc hội thoại với Excel chẳng hạn, thì Excel có rất nhiều tên chủ đề bao gồm cả tên chủ đề là ‘System’ và các tên chủ đề khác cho các spreadsheet. Nếu muốn thiết lập cuộc hội thoại với Form của Visual Basic thì Form phải cung cấp tên của ứng dụng và tên của chủ đề.
Một cuộc hội thoại DDE đôi khi còn được gọi là một liên kết, bởi vì hai ứng dụng được liên kết với nhau để trao đổi dữ liệu giữa chúng. DDE hỗ trợ ba kiểu liên kết: tự động (automatic), thủ công (manual) và thông báo (notify).
  • Liên kết tự động (Automatic Link): ứng dụng Server sẽ tự động cập nhật bất cứ khi nào dữ liệu nguồn trên server thay đổi. Ví dụ khi liên kết giữa một điều khiển của Visual Basic như Textbox với một hàng hoặc cột trên một trang Excel, DDE sẽ tự động cập nhật Textbox bất cứ khi nào dữ liệu trên ô của Excel thay đổi.
  • Liên kết thông báo (Notify Link): Ứng dụng Server sẽ thông báo cho Client biết khi dữ liệu thay đổi, nhưng Client cần phải yêu cầu dữ liệu mới từ Server.
  • Liên kết thủ công (Manual Link): dữ liệu sẽ không thay đổi một cách tự động, Client phải yêu cầu dữ liệu mới từ Server.
ArcView chỉ hỗ trợ duy nhất kiểu liên kết này, do đó nên định nghĩa chính xác trong ứng dụng muốn liên kết với ArcView như Visual basic chẳng hạn thuộc tính LinkMode điều khiển liên kết là ‘Manual’.
Có ba cách để tương tác với một cuộc hội thoại DDE là: execute, request và poke. Với yêu cầu execute, client yêu cầu server thực hiện một số chức năng thông qua chuỗi ký tự mà nó gởi đến server. Chuỗi ký tự mà client gửi cho server là chuẩn trong ngôn ngữ lệnh của server. Nếu có một kết nối đến ArcView Server, lệnh được gửi sẽ theo định dạng chuẩn của Avenue. Với yêu cầu request, client sẽ yêu cầu server trả về giá trị của một đối tượng. Với yêu cầu poke, client gởi thông tin đến một đối tượng của server.
Với những server khác nhau cũng như với những topic khác nhau thì có những phương thức khác nhau để chỉ định một đối tượng. Trong Excel, nếu có một client nói chuyện với spreadsheet, ta có thể chỉ định các đối tượng sử dụng phương thức Row/Column. Nếu có một client nói chuyện với ArcView chỉ định đối tượng là một Avenue script.

Xây dựng tương tác giữa ArcView và Visual Basic

Tạo một ứng dụng tương tác giữa ArcView và Visual Basic. Trong đó ArcView sẽ thực hiện những việc sau:
  • Gọi ứng dụng Visual Basic xuất hiện.
  • Thiết lập cuộc hội thoại giữa ArcView và Visual Basic trong đó ArcView là client và Visual Basic là server.
  • Chuyển danh sách các tên trường trong bảng đang kích hoạt sang listbox của Visual Basic
  • Kết thúc hội thoại.
Visual Basic sẽ thực hiện các việc sau khi người dùng chọn một trường trong listbox:
  • Thiết lập cuộc hội thoại giữa Visual Basic và ArcView, bây giờ ArcView là server và Visual Basic là client
  • Gửi một yêu cầu Avenue để lấy kiểu, độ rộng, bí danh và trạng thái hiển thị của trường.
  • Nếu bấm nút OK, các giá trị trong form Visual Basic sẽ được thiết lập ngược trở lại cho trường của ArcView.
Đầu tiên cần viết một Script để mở form của Visual Basic và chuyển tên các trường sang listbox. Đặt tên nó là “Lien ket Visual Basic”
Khởi tạo hội thoại
aDDE = DDEClient.Make(“FIELDDEF”, “transfer”)
Trong đó: FIELDDEF là tên của ứng dụng Visual Basic, transfer là tên chủ đề. Tên này được gán trong thuộc tính LinkTopic của Form Visual Basic.
Thực hiện kiểm tra việc thiết lập hội thoại có thành công hay không, nếu không thành công thì gọi thực thi ứng dụng Visual Basic và sau đó thử thiết lập lại.
if (aDDE.HasError) then
system.Execute(“C: \Ditagis\VB\FIELDDEF.exe”)
aDDE = DDEClient.Make(“FIELDDEF”, “transfer”)
if (aDDE.HasError) then
aDDE = DDEClient.Make(“FIELDDEF”, “transfer”)
end
end
Nếu việc thiết lập hội thoại không thành công thì thông báo lỗi và thoát.
if (aDDE.HasError ) then
Msgbox.Info(“Loi ket noi”, “Thong bao”)
Return nil
end
Ngược lại lấy tên các trường và chuyển cho Visual Basic
theVtab = av.GetActiveDoc.GetVtab ‘ lưu ý Doc hiện hành là Table cần lấy tên các trường
theFields = theVtab.GetFields
if (theFields.Count = 0) then
Msgbox.Info(“Không tồn tại trường trong bảng”, “Thong bao”)
else
for each f in theFields
aDDE.Execute(f.GetName)
end
end
Gán Script này vào sự kiện Click của một button nào đó trên giao diện của bảng.
Tiếp theo cần tạo Form cho Visual Basic. Trên Form có các đối tượng trong bảng sau, hãy đặt tên và gán các thuôc tính cho đúng như bảng bên dưới.
Thêm dòng khai báo các hằng sau vào phần General Declarations

Const NONE = 0, MANUAL = 2

Thêm đoạn mã sau vào sự kiện LinkExecute của Form. Đoạn mã này sẽ thêm các tên trường được gửi bằng lệnh Execute của ArcView ở trên vào list box của Form. Biến CmdStr chứa chuỗi dữ liệu mà ArcView gửi qua.
Private Sub Fiorm_LinkExecute(CmdStr As String, Cancel As Integer)
lstFields.AddItem CmdStr
End Sub
Thêm đoạn mã sau vào sự kiện Click của Listbox. Khi chọn một trường, Visual Basic sẽ lấy các giá trị về kiểu, độ rộng, bí danh và trạng thái hiển thị của trường tương ứng bên ArcView. Lệnh LinkRequest sẽ đặt kết quả này vào các đối tượng tương ứng của Visual Basic. Lưu ý là check box không có thuộc tính Link vì vậy nó được thay thế bằng một label ẩn và giá trị của Label sẽ tham chiếu đến check box.
Private Sub lstFields_Click()
if lblFldType.LinkMode = NONE then
lblFldType.LinkTopic = “ArcView|System”
lblFldType.LinkMode = MANUAL
lblFldWidth.LinkTopic = “ArcView|System”
lblFldWidth.LinkMode = MANUAL
txtFldAlias.LinkTopic = “ArcView|System”
txtFldAlias.LinkMode = MANUAL
txtFldVisible.LinkTopic = “ArcView|System”
txtFldVisible.LinkMode = MANUAL
end if
 
lblFldType.LinkItem = “av.GetactiveDoc.GetVtab.FindField(“”” &
lstFields & “””).GetType”
lblFldType.LinkRequest
 
lblFldWidth.LinkItem = “av.GetactiveDoc.GetVtab.FindField(“”” &
lstFields & “””).GetWidth”
lblFldWidth.LinkRequest
 
txtFldAlias.LinkItem = “av.GetactiveDoc.GetVtab.FindField(“”” &
lstFields & “””).GetAlias”
txtFldAlias.LinkRequest
 
txtFldVisible.LinkItem = “if (av.GetactiveDoc.GetVtab.FindField(“”” &
lstFields & “””).IsVisible) then return 1 else return 0 end”
txtFldVisible.LinkRequest
 
cbxFldVisible.Value = txtFldVisible.Text
 
if lblFldType.Caption= “nil” then ‘ bảng bên ArcView đóng
Unload Form1
End
end if
End Sub

 Thêm đoạn mã sau vào sự kiện Click của nút OK, Khi kích chuột trên nút OK, Form Visual Basic sẽ gửi cho ArcView một Script để cập nhật lại bí danh và trạng thái hiển thị của trường được chọn dựa trên giá trị trong hộp thoại Alias và check box Visible của Visual Basic.

Private Sub cmdOK_Click()
Dim state as string
if txtFldAlias.LinkMode = NONE then
txtFldAlias.LinkTopic = “ArcView|System”
txtFldAlias.LinkMode = MANUAL
end if
cmd = “av.GetActiveDoc.GetVtab.FindField(””” & lstFields
& “””).SetAlias(“”” & txtFldAlias & “””)
if cbxFldVisible.Value = 0 then
state = “false”
else
state = “true”
end if
cmd = cmd & “av.GetActiveDoc.GetVtab.FindField(“”” & lstFields
& “””).SetVisible(“ & state & “)”
txtFld.Alias.LinkExecute cmd
End Sub
 Thêm đoạn mã sau vào sự kiện Unload của Form. Đoạn mã này có tác dụng đóng kết nối DDE
Private Sub Form_Unload (Cancel As Integer)
lblFldType.LinkMode = NONE
lblFldWidth.LinkMode = NONE
txtFldAlias.LinkMode = NONE
txtFldVisible.LinkMode = NONE
End Sub
Thêm đoạn mã đóng Form vào sự kiện Click của nút Cancel
Private Sub cmdCancel_Click()
Unload Form1
End
End Sub

2. THÊM CHỨC NĂNG VÀO AVENUE THÔNG QUA THƯ VIỆN LIÊN KẾT ĐỘNG DLL

Avenue đã cung cấp rất nhiều lớp và nhiều yêu cầu cho lập trình, tuy nhiên nếu ứng dụng đòi hỏi một số hàm mà Avenue không có, thì việc sử dụng thư viện liên kết động DLL sẽ giúp thêm được các hàm cần thiết vào ứng dụng ArcView. Thư viện liên kết động là một modul thực thi chứa các hàm của các ứng dụng khác có thể thực thi một nhiệm vụ nào đó. DLL được liên kết như một ứng dụng trong thời gian thực thi chương trình chứ không phải trong thời gian biên dịch như các thư viện tĩnh.
DLL được cung cấp từ nhiều nguồn khác nhau, dùng các DLL có sẵn trong hệ điều hành Windows hoặc cũng có thể tự viết một DLL bằng ngôn ngữ C chẳng hạn và dùng nó cùng với ArcView. Tuy nhiên do DLL được cung cấp từ nhiều nguồn khác nhau nên có một số DLL sẽ không dùng được với ArcView.
Các hàm trong DLL được gọi trực tiếp từ Avenue. Hai lớp DLL và DLLProc trong Avenue hỗ trợ việc nạp một DLL và gọi các hàm chức năng của DLL.
Các hàm chức năng DLL được gọi bằng cách tạo ra một hiện thực của lớp DLL, sau đó tạo ra một hiện thực của DLLProc cho mỗi hàm hoặc thủ tục trong DLL muốn gọi. Khi đối tượng DLL được tạo ra, các hàm trong DLL sẽ được nạp vào trong bộ nhớ và ở trạng thái sẵn sàng để sử dụng. Khi đối tượng DLL bị huỷ, các hàm trong DLL sẽ được xoá khỏi bộ nhớ.
Các hàm gọi trong DLL có thể yêu cầu nhiều kiểu đối số khác nhau và trả về các kiểu khác nhau. Các đối số vào và ra được chỉ định khi tạo hiện thực DLLProc. ArcView hỗ trợ một vài kiểu đối số để tạo hiện thực DLLProc. Tương ứng với từng yêu cầu của hàm mà ta có thể gửi các đối số theo giá trị hoặc theo tham chiếu.
Với các đối số giá trị, ArcView cung cấp các hằng kiểu sau:
  • DLLPROC_TYPE_INT16 DLLPROC_TYPE_INT32 DLLPROC_TYPE_FLOAT
  • DLLPROC_TYPE_POINTER
Với các đối số tham chiếu, ArcView cung cấp các hằng kiểu sau:
  • DLLPROC_TYPE_PINT16, DLLPROC_TYPE_PINT32, DLLPROC_TYPE_PFLOAT
  • DLLPROC_TYPE_STR
Giả sử đã xây dựng nên một thư viện liên kết động DLL có tên là math.dll, thư viện này chứa các hàm tính toán số học và đặt tại “C: \Ditagis\math.dll”. Đoạn script sau sẽ giúp gọi hàm cộng hai số trong thư viện động math.dll trên.
Trước tiên phải khởi tạo một hiện thực của lớp DLL
mathDLL = DLL.Make(“C: \Ditagis\math.dll”.AsFileName)
Tiếp theo tạo một hiện thực của lớp DLLProc để nạp hàm cần thực hiện, trong trường hợp này sử dụng hàm AddLongs có trong thư viện trên.
add = DLLProc.Make(mathDLL, “AddLongs”, #DLLPROC_TYPE_INT32,
{#DLLPROC_TYPE_INT32, #DLLPROC_TYPE_INT32})
 Yêu cầu Make sử dụng bốn đối số, đối số thứ nhất là đối tượng DLL, đối số thứ hai là tên hàm cần tạo. Lưu ý, phải nhập tên hàm AddLongs giống như tên hàm trong DLL về chữ hoa lần chữ thường. Đối số thứ ba là hằng kiểu của kết quả trả về, đối số thứ tư là danh sách các hằng kiểu tương ứng của các đối số thuộc hàm cần tạo ra yêu cầu.
Gửi yêu cầu Call đến đối tượng DLLProc là add để gọi hàm thực thi, cộng hai số 300 và 200.
x = add.Call({300, 200})
In kết quả ra màn hình
Msgbox.Info(“Kết quả là: ” x.Asstring, “Kết quả”)
  Tạo DLL bằng Microsoft Visual C++
Ví dụ sau sẽ tạo ra một thư viện liên kết động math.dll sử dụng ở trên.
Để tạo một DLL bằng Microsoft Visual C++, cần phải tạo ra 3 tệp tin sau: math.def, math.h và math.cpp.
Nội dung của tệp tin math.def
EXPORTS
AddLongs
Nội dung của tệp tin math.h
 #ifndef _FUNDLL_
long _FUNDLLLIB_ addLongs(long a, long b);
#endif
 Nội dung của math.cpp
#define _FUNDLL_
#include "t.h"
#include <windows.h>
long AddLongs(long a, long b)
{
return a+b;
}
Tiếp theo khởi động chương trình Microsoft Visual C++

 Chọn mục New trong menu File trên trình thực đơn.

Chọn tab Projects và chọn mục Win32 Dynamic-Link Library, nhập tên math vào hộp thoại Project Name và chỉ định vị trí thư mục cần lưu trong hộp thoại Location, ở đây ta chọn “C: \WinNT\Temp”. Bấm OK để tiếp tục.

Đánh dấu chọn vào mục “An empty DLL project” và bấm nút Finish.
Từ menu Project, chọn mục Add To Project và chọn mục Files

Chỉ định đến vị trí lưu 3 tệp tin math.def, math.h và math.cpp. Thêm 3 tệp tin này vào Project.
Bấm phím F7 để biên dịch tệp tin math.dll. Tệp tin này được lưu trong thư mục Debug. Tương ứng với đường dẫn trên là “C: \WinNT\Temp\math\debug\math.dll”.
Bây giờ, hoàn toàn có thể chép tệp tin này đến vị trí mong muốn và dùng các lệnh Avenue ở trên để gọi các hàm chức năng do ta xây dựng trong DLL này.

Các yêu cầu thường sử dụng với lớp DLLProc

Các yêu cầu thường sử dụng với lớp DLL

Các yêu cầu thường được sử dụng với DDEClient

Nguồn:”Bài giảng Lập trình Avenue – GV Nguyễn Văn Xanh – Đại học công nghệ thông tin”

Previous article[Ngôn ngữ Avenue #9] Lập trình giao diện với Avenue
Next article[Ngôn ngữ Avenue #11] Kết nối dữ liệu với Avenue

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Website này sử dụng Akismet để hạn chế spam. Tìm hiểu bình luận của bạn được duyệt như thế nào.