• Thứ Hai, 17/08/2009 10:25 (GMT+7)

    Cách tạo menu động?

    Câu hỏi :
    Cách tạo menu động cấp 1, 2 lấy từ cơ sở dữ liệu Access hoặc SQL 2005? Ví dụ có bảng menuchinh gồm các trường (id, tieudechinh, vitri), bảng menucap2 gồm các trường (id, tieudephu, vitri). 
     

    Trả lời :
    Để giải quyết việc tạo menu động như bạn yêu cầu, cần trang bị 2 kiến thức chính:

     - Kiến thức về các hàm API Windows để quản lý menu như GetMenu(), DeleteMenu(), InsertMenuItem(), CreatePopupMenu()... Thông tin cụ thể và chi tiết về cách dùng các hàm này được trình bày trong CD MSDN của Microsoft.

     - Kiến thức về việc truy xuất dữ liệu trong database, thí dụ kiến thức về việc dùng các đối tượng trong thư viện cấp cao ADO để truy xuất database.

     Ý tưởng của việc tạo menu động từ thông tin trong database có thể tóm tắt như sau:
     - Tạo 1 menu trống cho Form ứng dụng.
     - Đọc vào danh sách các record của bảng menuchinh theo thứ tự của field vitri (phải có giá trị liên tục từ 0 trở lên).
     - Lặp thêm từng menu pop-up theo thông tin của record trong danh sách, đọc vào danh sách các record của bảng menucap2 có cùng giá trị ID như phần tử menu chính hiện hành, lặp thêm từng option theo thông tin của record trong danh sách.

     Qui trình viết ứng dụng tạo menu động cụ thể sẽ phụ thuộc nhiều vào môi trường lập trình, vào ngôn ngữ lập trình được dùng. Ở đây chúng tôi xin giới thiệu qui trình điển hình để viết ứng dụng tạo menu động theo yêu cầu của bạn bằng môi trường VB 6.0. Giả sử bạn đã tạo sẵn 2 bảng menuchinh và menucap2 với nội dung theo yêu cầu và chứa chúng trong file Access c:\YourDB.mdb:

     1. Chạy VB 6.0, tạo Project ứng dụng mới theo dạng "Standard EXE". Đây là Project quản lý ứng dụng đơn giản nhất, có 1 Form trống ban đầu.

     2. Sau khi Form ứng dụng hiển thị, chọn menu Tool.Menu Editor để mở cửa sổ soạn menu cho Form. Hãy tạo 1 menubar chỉ chứa 1 menu ban đầu (thí dụ Caption=File, Name=mnuFile) rồi đóng cửa sổ soạn menu lại. Mục đích của bước này là tạo 1 menu tĩnh ban đầu cho Form chỉ chứa 1 menu pop-up trống. Việc hiệu chỉnh thông tin về menu sẽ được lập trình động trong bước kế tiếp.

     3. Chọn menu Project.References để hiển thị cửa sổ References, duyệt tìm và chọn mục "Microsoft ActiveX Data Objects 2.x Library" và chọn button Ok để thêm các đối tượng ADO của thư viện này vào Project ứng dụng.

     4. Chọn menu View.Code để mở cửa sổ soạn code của chương trình rồi nhập đoạn chương trình sau đây:
     
     'khai báo các hàm API cần dùng
     Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
     Private Declare Function CreatePopupMenu Lib "user32" () As Long
     Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
     Private Declare Function InsertMenuItem Lib "user32" Alias "InsertMenuItemA" (ByVal hMenu As Long, ByVal un As Long, ByVal bool As Boolean, ByRef lpcMenuItemInfo As MENUITEMINFO) As Long
     'khai báo kiểu cần dùng
     Private Type MENUITEMINFO
     cbSize As Long
     fMask As Long
     fType As Long
     fState As Long
     wID As Long
     hSubMenu As Long
     hbmpChecked As Long
     hbmpUnchecked As Long
     dwItemData As Long
     dwTypeData As String
     cch As Long
     End Type
     
     'khai báo hằng cần dùng
     Const MF_STRING = &H0
     Const MIIM_STRING = &H40
     Const MIIM_SUBMENU = &H4
     Const MIIM_ID = &H2
     Const MIIM_TYPE = &H10
     Const MIIM_DATA = &H20
     Const MF_BYPOSITION = &H400
     
     'Khai báo các biến cần dùng
     Dim MII As MENUITEMINFO
     Dim Connection1 As ADODB.Connection
     Dim Command1 As ADODB.Command
     Dim RecordSet1 As ADODB.Recordset
     Dim RecordSet2 As ADODB.Recordset
     
     'thủ tục khởi động Form ứng dụng
     Private Sub Form_Load()
     Dim hMenu As Long
     Dim hSubMenu As Long
     'xác định menubar của Form
     hMenu = GetMenu(Me.hwnd)
     'xóa menu pop-up đã có
     kq = DeleteMenu(hMenu, 0, MF_BYPOSITION)
     Dim MyConString As String
     MyConString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = c:\YourDB.mdb"
     'Tạo connection tới database
     Set Connection1 = New ADODB.Connection
     Connection1.Open MyConString
     'Tạo command làm việc với database
     Set Command1 = New ADODB.Command
     Command1.ActiveConnection = Connection1
     'tạo danh sách menu cấp 1 theo thứ tự vị trí
     Command1.CommandText = "select * from menuchinh order by vitri ASC"
     Set RecordSet1 = Command1.Execute()
     'lặp thêm động từng menu pop-up trong danh sách
     While Not RecordSet1.EOF()
     'xây dựng thông tin về menu pop-up cần tạo
     MII.cbSize = Len(MII)
     MII.dwTypeData = RecordSet1.Fields("tieudechinh").Value
     MII.cch = LenB(MII.dwTypeData)
     MII.hSubMenu = CreatePopupMenu()
     MII.fMask = MIIM_ID Or MIIM_STRING Or MIIM_SUBMENU
     'thêm menu pop-up này
     ret = InsertMenuItem(hMenu, RecordSet1.Fields("vitri").Value, MF_BYPOSITION, MII)
     hSubMenu = MII.hSubMenu
     'tạo danh sách menu cấp 2 của menu pop-up hiện hành theo thứ tự vị trí
     Command1.CommandText = "select * from menucap2 where ID=" & RecordSet1.Fields("ID").Value & " order by vitri ASC"
     Set RecordSet2 = Command1.Execute()
     'lặp thêm động từng menu item trong danh sách
     While Not RecordSet2.EOF()
     'xây dựng thông tin về menu item cần tạo
     MII.cbSize = Len(MII)
     MII.dwTypeData = RecordSet2.Fields("tieudephu").Value
     MII.cch = LenB(MII.dwTypeData)
     MII.fMask = MIIM_STRING
     'thêm menu item này
     ret = InsertMenuItem(hSubMenu, RecordSet2.Fields("vitri").Value, MF_BYPOSITION, MII)
     'di chuyển đến item kế tiếp
     RecordSet2.MoveNext
     Wend
     'di chuyển đến menu pop-up kế tiếp
     RecordSet1.MoveNext
     Wend
     'đóng các đối tượng đã dùng lại
     RecordSet1.Close
     RecordSet2.Close
     Connection1.Close
     End Sub

     5. Chạy chương trình và kiểm tra kết quả xem menu được tạo ra đúng theo đặc tả trong database hay không? Lưu ý rằng đoạn code trên mới chỉ tạo động được menubar chứ chưa liên kết thủ tục xử lý sự kiện cho từng option menu. 
     
    Chuyên mục: Lập trình