Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin

Tổng quan controls

Control là một thành phần cơ bản trên form

 Có các thành phần

oThuộc tính

oPhương thức

oSự kiện

 Tất cả các control chứa trong namespace:System.Windows.Forms

Một số thuộc tính của control

 Text: mô tả text xuất hiện trên control

 Focus: phương thức chuyển focus vào control

 TabIndex: thứ tự của control nhận focus

o Mặc định được VS.NET thiết lập

 Enable: thiết lập trạng thái truy cập của control

 Visible: ẩn control trên form, có thể dùng phương thức Hide

 Anchor:

o Neo giữ control ở vị trí xác định

o Cho phép control di chuyển theo vị trí

 Size: xác nhận kích thước của control

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 1

Trang 1

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 2

Trang 2

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 3

Trang 3

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 4

Trang 4

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 5

Trang 5

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 6

Trang 6

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 7

Trang 7

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 8

Trang 8

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 9

Trang 9

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin trang 10

Trang 10

Tải về để xem bản đầy đủ

pdf 123 trang duykhanh 7260
Bạn đang xem 10 trang mẫu của tài liệu "Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin

Giáo trình Mô đun Xây dựng ứng dụng Windows - Hệ thống thông tin
 không ? hay một component để tính tổng chi phí, 
 Bussiness Entities : thường được sử dụng như Data Transfer Objects ( DTO ) . Bạn 
có thể sử dụng để truyền dữ liệu giữa các lớp (Presentation và Data Layer). Chúng 
thường là cấu trúc dữ liệu ( DataSets, XML, ) hay các lớp đối tượng đã được tùy 
chỉnh. 
 Ví dụ : tạo 1 class Student lưu trữ các dữ liệu về tên, ngày sinh, ID, lớp. 
 3. Data Layer (DAL) : 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 97 
 Data Access Logic Components : chịu trách nhiệm chính lưu trữ và truy xuất dữ liệu 
từ các nguồn dữ liệu (Data Sources) như XML, file system, Hơn nữa còn tạo thuận 
lợi cho việc dễ cấu hình và bảo trì. 
 Service Agents : giúp bạn gọi và tương tác với các dịch vụ từ bên ngoài một cách 
dễ dàng và đơn giản. 
5.1.2. Mô hình đa tầng 
N-Tier Architecture? 
Kiến trúc N-tier còn được gọi là multi-tier architecture, một phương pháp kiến trúc 
ứng dụng trong phát triển phần mềm. Nó thích hợp cho việc xây dựng các ứng dụng 
lớn, đặc biệt là các ứng dụng doanh nghiệp, các ứng dụng đòi hỏi tính scalability, 
security, fault tolerance, reusability và maintainability. 
Gọi là N-tier điều đó có nghĩa kiến trúc này có thể có 1, 2, 3 hoặc hơn số các layer phụ 
thuộc vào cách phân chia kiến trúc hệ thống. Tuy nhiên 3-Tier vẫn là mẫu phổ biến 
nhất và được định nghĩa cụ thể về trách nhiệm từng tier như sau: 
Tầng Presentation: Chính là Giao diện người dùng, đây chính là phần mềm ứng dụng 
mà người dùng sẽ thấy và tương tác (Có thể là Website hoặc Mobile App, hoặc 
Window app). Khi người dùng nhập thông tin họ cần. Hành động người dùng được xử 
lí đi qua các tầng Logic, tầng Data. 
Tầng Logic: Đây là tầng chứa tất cả những phương pháp xử lý, đọc & ghi dữ liệu trước 
khi đưa đến UI người dùng, nó những gì được cho phép trong ứng dụng của bạn. 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 98 
Tầng Data: Tầng Data là nơi lưu trữ tất cả dữ liệu trong ứng dụng, tại tầng này bạn 
thực hiện các phương thức lưu trữ dữ liệu vào DB, triển khai các giải pháp bảo mật, 
transaction cần thiết. 
5.1.3. Xây dựng lớp xử lý lưu trữ 
Tại sao mình lại xây dựng Data Access trước? Đơn giản là đây là lớp mà ta xử lý bên 
database, làm trước thì design GUI xong chỉ việc bỏ vào sử dụng thôi 
Điều quan trọng đầu tiên, chúng ta cần tạo class DBConnect.cs với nội dung như sau: 
using System.Data.SqlClient; 
namespace DAL_QuanLy 
{ 
 public class DBConnect 
 { 
 protected SqlConnection _conn = new SqlConnection("Data 
Source=ADMINISTRATOR\SQLEXPRESS;Initial Catalog=ThanhVien;Integrated 
Security=True"); 
 } 
} 
Copy 
Chúng ta sẽ tạo SqlConnection và khởi tạo luôn, sau này các class DAL chúng ta chỉ 
cần kế thừa class DBConnect là có thể sử dụng _conn thoải mái ko cần khởi tạo lại. 
Các bạn nhớ sửa lại connection string cho chuẩn bên máy của các bạn nhé. Ở đây vì 
bài tập đơn giản nên ta chịu khó hard-code vậy :D. Chúng ta có nhiều cách khác nhau 
để tránh hard-code nhưng mình sẽ nói sau ở các bài khác. 
Mình sẽ tạo file DAL_ThanhVien.cs (Class file) 
Ở đây mình sẽ làm sẵn luôn 4 methods là: Lấy tất cả, Thêm, Xóa, Sửa nhé 
DAL_ThanhVien.cs: 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 
using System.Data.SqlClient; 
using DTO_QuanLy; 
namespace DAL_QuanLy 
{ 
 public class DAL_ThanhVien : DBConnect 
 { 
 /// 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 99 
 /// Get toàn bộ thành viên 
 /// 
 /// 
 public DataTable getThanhVien() 
 { 
 SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM 
THANHVIEN", _conn); 
 DataTable dtThanhvien = new DataTable(); 
 da.Fill(dtThanhvien); 
 return dtThanhvien; 
 } 
 /// 
 /// Thêm thành viên 
 /// 
 /// 
 /// 
 public bool themThanhVien(DTO_ThanhVien tv) 
 { 
 try 
 { 
 // Ket noi 
 _conn.Open(); 
 // Query string - vì mình để TV_ID là identity (giá trị tự tăng dần) nên ko 
cần fải insert ID 
 string SQL = string.Format("INSERT INTO THANHVIEN(TV_NAME, 
TV_PHONE, TV_EMAIL) VALUES ('{0}', '{1}', '{2}')", tv.THANHVIEN_NAME, 
tv.THANHVIEN_PHONE, tv.THANHVIEN_EMAIL); 
 // Command (mặc định command type = text nên chúng ta khỏi fải làm gì 
nhiều). 
 SqlCommand cmd = new SqlCommand(SQL, _conn); 
 // Query và kiểm tra 
 if (cmd.ExecuteNonQuery() > 0) 
 return true; 
 } 
 catch (Exception e) 
 { 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 100 
 } 
 finally 
 { 
 // Dong ket noi 
 _conn.Close(); 
 } 
 return false; 
 } 
 /// 
 /// Sửa thành viên 
 /// 
 /// 
 /// 
 public bool suaThanhVien(DTO_ThanhVien tv) 
 { 
 try 
 { 
 // Ket noi 
 _conn.Open(); 
 // Query string 
 string SQL = string.Format("UPDATE THANHVIEN SET TV_NAME = 
'{0}', TV_PHONE = '{1}', TV_EMAIL = '{2}' WHERE TV_ID = {3}", 
tv.THANHVIEN_NAME, tv.THANHVIEN_PHONE, tv.THANHVIEN_EMAIL, 
tv.THANHVIEN_ID); 
 // Command (mặc định command type = text nên chúng ta khỏi fải làm gì 
nhiều). 
 SqlCommand cmd = new SqlCommand(SQL, _conn); 
 // Query và kiểm tra 
 if (cmd.ExecuteNonQuery() > 0) 
 return true; 
 } 
 catch (Exception e) 
 { 
 } 
 finally 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 101 
 { 
 // Dong ket noi 
 _conn.Close(); 
 } 
 return false; 
 } 
 /// 
 /// Xóa thành viên 
 /// 
 /// 
 /// 
 public bool xoaThanhVien(int TV_ID) 
 { 
 try 
 { 
 // Ket noi 
 _conn.Open(); 
 // Query string - vì xóa chỉ cần ID nên chúng ta ko cần 1 DTO, ID là đủ 
 string SQL = string.Format("DELETE FROM THANHVIEN WHERE 
TV_ID = {0})", TV_ID); 
 // Command (mặc định command type = text nên chúng ta khỏi fải làm gì 
nhiều). 
 SqlCommand cmd = new SqlCommand(SQL, _conn); 
 // Query và kiểm tra 
 if (cmd.ExecuteNonQuery() > 0) 
 return true; 
 } 
 catch (Exception e) 
 { 
 } 
 finally 
 { 
 // Dong ket noi 
 _conn.Close(); 
 } 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 102 
 return false; 
 } 
 } 
} 
5.1.4. Xây dựng các lớp xử lý nghiệp vụ 
Bước này là bước xử lý business logic (Business layer). 
Ở bước này, ta có thể lấy dữ liệu từ DAL về, xử lý ABC XYZ gì đó rồi trả về lại cho 
GUI sử dụng. Hoặc khi update dữ liệu trên DB, GUI gửi data lên BUS và rồi ta xử lý 
ABC XYZ gì đó cho data của chúng ta, rồi mới insert/update/delete chẳng hạn, 
Vì app mình build là app đơn giản, nên mình chỉ cần gọi lên DAL và trả về tương ứng 
cho GUI xài thui 
Mình sẽ tạo BUS_ThanhVien.cs (Class file): 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 
using DAL_QuanLy; 
using DTO_QuanLy; 
namespace BUS_QuanLy 
{ 
 public class BUS_ThanhVien 
 { 
 DAL_ThanhVien dalThanhVien = new DAL_ThanhVien(); 
 public DataTable getThanhVien() 
 { 
 return dalThanhVien.getThanhVien(); 
 } 
 public bool themThanhVien(DTO_ThanhVien tv) 
 { 
 return dalThanhVien.themThanhVien(tv); 
 } 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 103 
 public bool suaThanhVien(DTO_ThanhVien tv) 
 { 
 return dalThanhVien.suaThanhVien(tv); 
 } 
 public bool xoaThanhVien(int TV_ID) 
 { 
 return dalThanhVien.xoaThanhVien(TV_ID); 
 } 
 } 
} 
Chỉ đơn giản là gọi hàm và trả về thôi 
5.1.5. Hiển thị dữ liệu và thao tác trên màn hình 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 104 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using DTO_QuanLy; 
using BUS_QuanLy; 
namespace GUI_QuanLy 
{ 
 public partial class GUI_ThanhVien : Form 
 { 
 BUS_ThanhVien busTV = new BUS_ThanhVien(); 
 public GUI_ThanhVien() 
 { 
 InitializeComponent(); 
 } 
 private void btnExit_Click(object sender, EventArgs e) 
 { 
 Application.Exit(); 
 } 
 private void btnAdd_Click(object sender, EventArgs e) 
 { 
 if (txtEmail.Text != "" && txtName.Text != "" && txtSDT.Text != "") 
 { 
 // Tạo DTo 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 105 
 DTO_ThanhVien tv = new DTO_ThanhVien(0, txtName.Text, txtSDT.Text, 
txtEmail.Text); // Vì ID tự tăng nên để ID số gì cũng dc 
 // Them 
 if (busTV.themThanhVien(tv)) 
 { 
 MessageBox.Show("Thêm thành công"); 
 dgvTV.DataSource = busTV.getThanhVien(); // refresh datagridview 
 } 
 else 
 { 
 MessageBox.Show("Thêm ko thành công"); 
 } 
 } 
 else 
 { 
 MessageBox.Show("Xin hãy nhập đầy đủ"); 
 } 
 } 
 private void GUI_ThanhVien_Load(object sender, EventArgs e) 
 { 
 dgvTV.DataSource = busTV.getThanhVien(); // get thanh vien 
 } 
 private void btnEdit_Click(object sender, EventArgs e) 
 { 
 // Kiểm tra nếu có chọn table rồi 
 if (dgvTV.SelectedRows.Count > 0) 
 { 
 if (txtEmail.Text != "" && txtName.Text != "" && txtSDT.Text != "") 
 { 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 106 
 // Lấy row hiện tại 
 DataGridViewRow row = dgvTV.SelectedRows[0]; 
 int ID = Convert.ToInt16(row.Cells[0].Value.ToString()); 
 // Tạo DTo 
 DTO_ThanhVien tv = new DTO_ThanhVien(ID, txtName.Text, 
txtSDT.Text, txtEmail.Text); // Vì ID tự tăng nên để ID số gì cũng dc 
 // Sửa 
 if (busTV.suaThanhVien(tv)) 
 { 
 MessageBox.Show("Sửa thành công"); 
 dgvTV.DataSource = busTV.getThanhVien(); // refresh datagridview 
 } 
 else 
 { 
 MessageBox.Show("Sửa ko thành công"); 
 } 
 } 
 else 
 { 
 MessageBox.Show("Xin hãy nhập đầy đủ"); 
 } 
 } 
 else 
 { 
 MessageBox.Show("Hãy chọn thành viên muốn sửa"); 
 } 
 } 
 private void dgvTV_Click(object sender, EventArgs e) 
 { 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 107 
 // Lấy row hiện tại 
 DataGridViewRow row = dgvTV.SelectedRows[0]; 
 // Chuyển giá trị lên form 
 txtName.Text = row.Cells[1].Value.ToString(); 
 txtSDT.Text = row.Cells[2].Value.ToString(); 
 txtEmail.Text = row.Cells[3].Value.ToString(); 
 } 
 private void btnDelete_Click(object sender, EventArgs e) 
 { 
 // Kiểm tra nếu có chọn table rồi 
 if (dgvTV.SelectedRows.Count > 0) 
 { 
 // Lấy row hiện tại 
 DataGridViewRow row = dgvTV.SelectedRows[0]; 
 int ID = Convert.ToInt16(row.Cells[0].Value.ToString()); 
 // Xóa 
 if (busTV.xoaThanhVien(ID)) 
 { 
 MessageBox.Show("Xóa thành công"); 
 dgvTV.DataSource = busTV.getThanhVien(); // refresh datagridview 
 } 
 else 
 { 
 MessageBox.Show("Xóa ko thành công"); 
 } 
 } 
 else 
CHƯƠNG 5. XÂY DỰNG ỨNG DỤNG VỚI MÔ HÌNH ĐA TẦNG 
KHOA CÔNG NGHỆ THÔNG TIN 108 
 { 
 MessageBox.Show("Hãy chọn thành viên muốn xóa"); 
 } 
 } 
 } 
} 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 109 
CHƯƠNG 6. CRYSTAL REPORT 
6.1 Crystal report 
- .NET cung cấp CrystalReport như một phần của Project, chúng ta có thể thêm báo 
cáo (report) bằng cách chọn Project – Add New Item – CrystalReport. 
- CrystalReport cung cấp nhiều hình dạng cho phép hiển thị dữ liệu một cách trực quan 
theo các mẫu được thiết kế sẵn 
6.1.1. Tạo mới report 
Bước 1: Từ một Project có sẵn, click phải chọn Add – New Item – chọn Crystal Report 
Bước 2: Chọn Using the Report Wizard 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 110 
Bước 3: Tạo kết nối với CSDL 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 111 
Bước 4: Chọn kiểu báo cáo 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 112 
Bước 5: Hoàn tất và chỉnh sửa báo cáo 
6.1.2. Sử dụng crystal report để hiển thị report 
- Sau khi thiết kế report thành công, chúng ta có thể tiếp tục thiết kế các report với 
nhiều hình thức khác nhau. Tuy nhiên khi làm việc với C#, điều chúng ta quan tâm là 
làm thế nào để tương tác với các report đã thiết kế với dữ liệu có chọn lọc, hình thức 
chọn lọc từ CSDL nguồn. 
- Trong phần này chúng ta sẽ tìm hiểu cách đọc và trình bày dữ liệu trên Crystal 
Report Viewer bằng các hình thức như: trực tiếp từ DataSet, DataTable, XML v.v 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 113 
6.1.3. Tạo nguồn dữ liệu cho report từ DataSet 
chúng ta sẽ chọn Project Data > ADO.NET DataSets > 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 114 
6.1.4. Tạo nguồn dữ liệu cho report từ nguồn CSDL 
6.1.5. Lọc dữ liệu trên report 
crystalreportviewer.SelectionFomula = "{filed cần lọc} = " + {Điều kiện}; 
ví dụ: 
DataSet _ds = new DataSet(); 
 string _strConnection = "server=.;database=Electronic;User Id 
=sa;Password=sa;"; 
 System.Data.SqlClient.SqlConnection _sqlCon = new 
System.Data.SqlClient.SqlConnection(_strConnection); 
 System.Data.SqlClient.SqlCommand _sqlCom = new 
System.Data.SqlClient.SqlCommand(); 
 _sqlCom.CommandText = "SELECT * FROM [tbl_DanhMucSanPham]"; 
 _sqlCom.Connection = _sqlCon; 
 System.Data.SqlClient.SqlDataAdapter _sqlAdater = new 
System.Data.SqlClient.SqlDataAdapter(_sqlCom); 
 _sqlAdater.Fill(_ds); 
 _sqlAdater.Dispose(); 
 CrystalReport7 _rpt7 = new CrystalReport7(); 
 crystalReportViewer1.ReportSource = _rpt7; 
 crystalReportViewer1.SelectionFormula = "{_dt.DanhMuc_ID} = DM01"; 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 115 
6.1.6. Truyền tham số cho report 
Có tham số: 
6.1.7. Xuất report ra máy in 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 116 
6.1.8. Xuất report ra tập tin 
Crystal Report cho phép xuất dữ liệu từ báo cáo ra các định dạng khác như: Excel, 
Word, PDF, HTML, Text v.v 
Trong trường hợp này chúng ta tìm hiểu cách xuất dữ liệu từ Crystal Report ra PDF và 
Excel. 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 117 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 118 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 119 
6.1.9. Đóng gói project 
Sau khi chúng ta xây dựng được một ứng dụng, để chạy được ứng dụng này trên một máy tính 
khác, hoặc phân phối ứng dụng này đến nhiều người sử dụng khác, chúng ta cần phải đóng 
gói project thành một chương trình cài đặt (Setup hoặc Install). 
Bước 1: Tạo Project mới loại Setup and Deployment – Visual Studio Installer: 
Bước 2: Trong khung liệt kê các kiểu project chọn Setup Wizard, bấm OK: 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 120 
Bước 3: Bấm Next: 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 121 
Bước 4: Bấm Next: 
Bước 5: Bấm nút Add, sau đó tìm đến thư mục chứa file project QuanLySinhvien.sln, bấm 
OK: 
CHƯƠNG 6. CRYSTAL REPORT 
KHOA CÔNG NGHỆ THÔNG TIN 122 
Bước 6: Bấm nút Finish để hoàn tất: 
 KHOA CÔNG NGHỆ THÔNG TIN 123 
TÀI LIỆU THAM KHẢO 
TT Tên tác giả Tên sách – giáo trình NXB Năm XB 
1 
Phạm Hữu Khang C# 2005 – Lập trình cơ sở dữ 
liệu – Tập 4 – Quyển 1 
Lao động 
xã hội 
2009 
2 
Pham Hữu Khang C# 2005 0 Lập trình cơ sở dữ 
liệu Report – Tập 4 – Quyển 2 
Lao động 
xã hội 
2009 
GIÁO TRÌNH 
TÊN HỌC PHẦN 
(LƯU HÀNH NỘI BỘ) 

File đính kèm:

  • pdfgiao_trinh_mo_dun_xay_dung_ung_dung_windows_he_thong_thong_t.pdf