Bài giảng Lập trình trên Windows Chương 3 Lập trình C trên Windows cung cấp cho người học các kiến thức Lập trình C trên Windows, lập trình trên Windows, eventdriven programming model, các bước cơ bản tạo ứng dụng Windows,... Mời các bạn cùng tham khảo.
Trang 1Lập trình Windows
Chương 3 Lập trình C# trên Windows
1
Trang 2Nội dung
• Windows Form
Trang 3Lập trình C# trên
Windows
Trang 4Khái niệm thông điệp ( Message )
• Là một số nguyên được quy ước trước giữa Windows và các ứng dụng (Application)
• Các dữ liệu nhập (từ bàn phím, từ chuột, …) đều được Windows chuyển thành các message và một số thông tin kèm theo message
Trang 6Application
Queue A
Application
Queue B
Trang 7Event-driven programming model
• Message loop (vòng lặp thông điệp)
• Mỗi Application tại một thời điểm có một message loop để lấy các message trong Application Queue về để phân bố cho các cửa sổ (Window) trong Application
• Hàm Window Procedure
• Mỗi cửa sổ (Window) trong Application đều có một hàm Window Procedure để
xử lý các message do message loop nhận về
Trang 8Event-driven programming model
Message queue
Application Message handlers
Trang 9Event-driven programming model
• Ứng dụng phản ứng các sự kiện (nhấn phím, click chuột, ) bằng cách
xử lý các message do Windows gởi đến
• Một ứng dụng Windows điển hình thực hiện một lượng lớn các xử lý
để phản hồi các message nó nhận Và giữa các message nó chờ message kế tiếp đến
• Message queue : Các message được chờ trong message queue cho đến khi chúng được nhận để xử lý
Trang 10Event-driven programming model
• Hàm Main : Tạo một cửa sổ và vào message loop
• Message loop
• Nhận các message và phân bố chúng đến Window Procedure của các cửa sổ
• Message loop kết thúc khi nhận được WM_QUIT (chọn Exit từ menu File, click
lên close button)
• Window Procedure :
• Phần lớn các đoạn mã đặt trong Window Procedure
• Window Procedure xử lý các message gởi đến cửa sổ
• Window Procedure điển hình chứa câu lệnh switch lớn với mỗi case là một
message riêng
• Message handler : Code cung cấp để xử lý message cụ thể
Trang 11Event-driven programming model trong C#
• Message Loop Application.Run()
• Window Form
• Window Procedure WndProc(ref Message m)
•Phần lớn Message handlers được cài đặt sẵn trong các lớp có thể
nhận message (Control, Form, Timer,…) dưới dạng:
protected void OnTenMessage( xxxEventArgs e)
(xxxEventArgs có thể là EventArgs hay các lớp con của EventArgs)
• Mỗi message có một biến event tương ứng
• Các Message handlers mặc nhiên gọi các event tương ứng của message
• Các hàm gán cho event gọi là event handler
Trang 12Event-driven programming model trong C#
Message queue
Application
Message handlers gọi các sự kiện tuơng ứng
Trang 13Tạo ứng dụng Windows Forms từ đầu
Trang 14Các bước cơ bản tạo ứng dụng Windows
Trang 15Các bước cơ bản tạo ứng dụng Windows
• Cách 1: Trực tiếp – thừa kế
• Thiết kế giao diện
• Tạo lớp thừa thừa kế từ lớp Form
• Bố cục các control
• Thiết lập các property cho các control
• Xử lý các thông điệp do Windows gởi đến: bằng cách override các message handler
• Xử lý các nghiệp vụ trên các message handler
Trang 16Các bước cơ bản tạo ứng dụng Windows
• Cách 2: Gián tiếp qua các field event
• Thiết kế giao diện
• Bố cục các control
• Thiết lập các property cho các control
• Bắt các sự kiện: bằng cách viết các event handler
• Xử lý nghiệp vụ trên các event handler
Trang 17Các bước cơ bản để tạo ứng dụng
Windows
• Bước 1: Tạo Empty Project
• File New Project
• Project Type: Visual C# Windows
• Template: Empty Project
• Bước 2: Thêm references
• Click phải lên References Add Reference
• Bước 3: Thêm class file
• Click phải lên project Add Class
• Bước 4: Viết code
• Bước 5: menu Project Property Output type: Windows Application
Trang 18Dùng Form, Không thừa kế
class Program
{
static void Main() {
Form form = new Form();
form.Text = “First Application”;
Application.Run(form);
} }
class Program
{
static void Main() {
Form form = new Form ();
form.Text = “First Application” ;
Application Run(form);
} }
Trang 19form.Cursor = Cursors.Hand;
form.StartPosition = FormStartPosition.CenterScreen;
}
}
• Thuộc tính
Trang 20Dùng Form, Không thừa kế
Trang 21button.Location = new Point(100, 100);
button.Click += new EventHandler(button_Click);
button.Click += new EventHandler (button_Click);
Trang 22button.Location = new Point(100, 100);
button.Click += new EventHandler(button_Click);
this.Text = "WinForm";
button = new Button();
button.Text = "OK";
button.Location = new Point(100, 100);
button.Click += new EventHandler(button_Click);
this.Controls.Add(button);
}
void button_Click(object sender, EventArgs e)
{
Trang 23Dùng form bằng cách kế thừa
class Program {
static void Main() {
MainForm form = new MainForm();
Application.Run(form);
} }
class Program
{ static void Main() {
MainForm form = new MainForm ();
Application Run(form);
} }
Trang 24Dùng form bằng cách kế thừa
• Bắt các sự kiện trên form
• Cách 1: Thông qua field event
Trang 25• Bắt các sự kiện trên form
• Cách 2: Thông Qua override các message handler
Trang 26Tạo ứng dụng
Windows Forms từ
Wizard
Trang 27Tạo ứng dụng bằng Wizard
• Bước 1: Tạo Empty Project
• File New Project
• Project Type: Visual C# Windows
• Template: Windows Forms Application
Trang 28Tạo ứng dụng bằng Wizard
• Các thành phần của cửa sổ thiết kế
Form đang thiết kế
Properties Windows
Solution Windows
Trang 29Tạo ứng dụng bằng Wizard
• Bước 2: Thiết kế giao diện: Kéo các đối tượng từ
Toolbox vào form
Trang 30Tạo ứng dụng bằng Wizard
• Bước 3: Thiết lập các Property cho các đối tượng trên form
thông qua Properties Windows
Object Drop-Down
Hiển thị theo vần
Hiển thị theo loại
Properties Events
Trang 31Tạo ứng dụng bằng Wizard
• Bước 4: Bắt các sự kiện cho các đối tượng trên form từ
Properties Windows
Trang 32Tạo ứng dụng bằng Wizard
• Bước 5: Xử lý nghiệp vụ: viết code cho các event handler
Trang 33Code do Wizard sinh ra
• Lớp Program
Trang 34Code do Wizard sinh ra
• Lớp MainForm
Trang 35Code do Wizard sinh ra
• Phương thức InititiallizeComponent()
Trang 36Tổng quan các đối
tượng trong Windows
Forms
Trang 37Cấu trúc của ứng dụng
• Ứng dụng Windows Forms có 3 phần chính
• Application
• Các Form trong Application
• Các Controls và Components trên Form
Trang 38Lớp Application
Trang 39Khái niệm
• Lớp Application cung cấp các phương thức tĩnh và các property tĩnh để quản lý ứng dụng
• Các phương thức start, stop ứng dụng, xử lý Windows messages
• Các property lấy thông tin về ứng dụng
• Lớp này không thể thừa kế
• Namespace
• System.Windows.Form
• Assembly
• System.Windows.Form (System.Windows.Form.dll)
Trang 40public sealed class Application
{ // Properties
public static string CommonAppDataPath { get; }
public static RegistryKey CommonAppDataRegistry { get; }
public static string CompanyName { get; }
public static CultureInfo CurrentCulture { get; set; }
public static InputLanguage CurrentInputLanguage { get;
set;}
public static string ExecutablePath { get; }
public static string LocalUserAppDataPath { get; }
public static bool MessageLoop { get; }
public static FormCollection OpenForms {get; }
public static string ProductName { get; }
public static string ProductVersion { get; }
public static bool RenderWithVisualStyles { get; }
public static string SafeTopLevelCaptionFormat { get; set; } public static string StartupPath { get; }
public static string UserAppDataPath { get; }
public static RegistryKey UserAppDataRegistry { get; }
public static bool UseWaitCursor { get; set; }
public sealed class Application
{ // Properties
public static string CommonAppDataPath { get; }
public static RegistryKey CommonAppDataRegistry { get; }
public static string CompanyName { get; }
public static CultureInfo CurrentCulture { get; set; }
public static InputLanguage CurrentInputLanguage { get;
set;}
public static string ExecutablePath { get; }
public static string LocalUserAppDataPath { get; }
public static bool MessageLoop { get; }
public static FormCollection OpenForms {get; }
public static string ProductName { get; }
public static string ProductVersion { get; }
public static bool RenderWithVisualStyles { get; }
public static string SafeTopLevelCaptionFormat { get; set; } public static string StartupPath { get; }
public static string UserAppDataPath { get; }
public static RegistryKey UserAppDataRegistry { get; }
public static bool UseWaitCursor { get; set; }
Trang 41Methods
public sealed class Application
{ // Methods
public static void AddMessageFilter(IMessageFilter value);
public static void DoEvents();
public static void EnableVisualStyles();
public static void Exit();
public static void ExitThread();
public static bool FilterMessage(ref Message message);
public static ApartmentState OleRequired();
public static void RaiseIdle(EventArgs e);
public static void RegisterMessageLoop(MessageLoopCallback callback); public static void RemoveMessageFilter(IMessageFilter value);
public static void Restart();
public static void Run();
public static void Run(ApplicationContext context);
public static void Run(Form mainForm);
public static void UnregisterMessageLoop();
public static void SetCompatibleTextRenderingDefault(bool defaultValue); }
public sealed class Application
{ // Methods
public static void AddMessageFilter(IMessageFilter value);
public static void DoEvents();
public static void EnableVisualStyles();
public static void Exit();
public static void ExitThread();
public static bool FilterMessage(ref Message message);
public static ApartmentState OleRequired();
public static void RaiseIdle(EventArgs e);
public static void RegisterMessageLoop(MessageLoopCallback callback); public static void RemoveMessageFilter(IMessageFilter value);
public static void Restart();
public static void Run();
public static void Run(ApplicationContext context);
public static void Run(Form mainForm);
public static void UnregisterMessageLoop();
public static void SetCompatibleTextRenderingDefault(bool defaultValue); }
Trang 42public sealed class Application
{
// Events
public static event EventHandler ApplicationExit;
public static event EventHandler EnterThreadModal;
public static event EventHandler Idle;
public static event EventHandler LeaveThreadModal;
public static event ThreadExceptionEventHandler
public static event EventHandler ApplicationExit;
public static event EventHandler EnterThreadModal;
public static event EventHandler Idle;
public static event EventHandler LeaveThreadModal;
public static event ThreadExceptionEventHandler
ThreadException;
public static event EventHandler ThreadExit;
}
Trang 43Một số phương thức thông dụng
• Run() bắt đầu message loop của ứng dụng
• Exit(Form) dừng message loop
• DoEvents() xử lý các message trong khi chương trình đang trong
Trang 44Một số property thông dụng
• ExecutablePath Đường dẫn đến file exe
• StartupPath Đường dẫn đến thư mục chứa file exe
• UseWaitCursor Hiện cursor dạng Wait
• Event thông dụng
• Idle Xuất hiện khi ứng dụng hoàn thành việc xử lý
Trang 46Bài tập
1 Tìm đường dẫn đến file exe
2 Tìm đường dẫn đến thư mục chứa file exe
3 Shutdown ứng dụng và tự động restart lại
4 Thực hiện những công việc khi ứng dụng rãnh rỗi
5 Hiện Cursor dạng Wait khi ứng dụng đang bận thực thi công việc
6 Xử lý trường hợp một phương thức thực thi mất nhiều thời gian
Trang 47Lớp MessageBox
Trang 48Lớp MessageBox
• Message Box hiện một thông báo hay một hướng dẫn cho user
• Lớp MessageBox chỉ chứa một phương thức tĩnh duy nhất: Show(…)
DialogResult Show(string text, string caption,
MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options);
DialogResult Show(string text, string caption,
MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options);
Namespace
• System.Windows.Forms
Assembly
Trang 49Exclamation = 0x30, Hand = 0x10,
Information = 0x40, None = 0,
Question = 0x20, Stop = 0x10,
Warning = 0x30 }
public enum MessageBoxIcon {
Asterisk = 0x40, Error = 0x10,
Exclamation = 0x30, Hand = 0x10,
Information = 0x40, None = 0,
Question = 0x20, Stop = 0x10,
Warning = 0x30 }
Trang 50Lớp MessageBox
public enum MessageBoxDefaultButton {
Button1 = 0, Button2 = 0x100,
public enum MessageBoxDefaultButton {
Button1 = 0, Button2 = 0x100,
public enum MessageBoxOptions {
DefaultDesktopOnly = 0x20000, RightAlign = 0x80000,
RtlReading = 0x100000, ServiceNotification = 0x200000 }
public enum MessageBoxOptions {
DefaultDesktopOnly = 0x20000, RightAlign = 0x80000,
RtlReading = 0x100000, ServiceNotification = 0x200000 }
Trang 51No }
public enum DialogResult {
None, OK, Cancel, Abort, Retry, Ignore, Yes,
No }
Trang 52Lớp Form
Trang 54Properties
Trang 55Properties
Trang 56Events
Trang 57Events
Trang 58this.ShowInTaskbar = false;
this.Location = new Point(10, 10);
this.Size = new Size(100, 100);
}
class MyForm : Form
{ public MyForm() {
this ShowInTaskbar = false;
this Location = new Point(10, 10);
this Size = new Size(100, 100);
}
Trang 59Lớp Form
Chu trình đời sống của form
Trang 60Một số vấn đề liên quan đến Form
• Tạo custom form
• Click phải lên project trong solution
• Chọn Add Windows Forms
• Cho custom form thừa kế từ lớp Form
• Hiện custom form
• Modal Form
• formName.ShowDialog();
• Modeless Form
• formName.Show ();
Trang 61Một số vấn đề liên quan đến Form
• Nút OK và Cancel
• Trước khi có thể nhận dữ liệu từ Form đang hiển thị, phương thức
ShowDialog() phải trở về, có nghĩa là form phải đóng lại
• Xác định button nào đã nhấn (OK hay Cancel, …) chúng ta dùng property
DialogResult
Trang 62Một số vấn đề liên quan đến Form
Trang 63Một số vấn đề liên quan đến Form
• Khi gọi phương thức Close() thì phương thức ShowDialog() sẽ trả về
DialogResult.Cancel
• Chúng ta có thể trả về các giá trị khác của enum DialogResult
enum DialogResult {
Abort, Cancel, // kết quả mặc nhiên khi gọi Form.Close() Ignore,
No, None,
OK, Retry, Yes}
enum DialogResult {
Abort, Cancel, // kết quả mặc nhiên khi gọi Form.Close() Ignore,
No, None,
OK, Retry, Yes}
Trang 64Một số vấn đề liên quan đến Form
• Kiểm tra giá trị trả về từ phương thức ShowDialog() là cách nhanh nhất
để kiểm tra giá trị của thuộc tính DialogResult
• Hai đoạn mã sau là tương đương
if (dlg.ShowDialog() == DialogResult.OK){
Trang 65- Nút Cancel không được gọi khi phím ESC nhấn
- Nút Enter không được gọi khi phím Enter nhấn
- Khi gán thuộc tính DialogResult thì không cần gọi phương thức Close()
Trang 66Một số vấn đề liên quan đến Form
• Gán phím Enter/ESC cho nút OK/Cancel
• Dùng Designer thiết lập 2 thuộc tính của form: AcceptButton và
CancelButton
private void InitializeComponent() {
… this.AcceptButton = this.btnOK;
this.CancelButton = this.btnCancel;
…
Trang 67Một số vấn đề liên qua đến Form
• Cách 3: (Dùng Designer)
• Thiết lập property DialogResult của nút OK: DialogResult.OK
• Thiết lập property DialogResult của nút Cancel: DialogResult.Cancel
• Trên form
• Thiết lập property AcceptButton: btnOK
• Thiết lập property CancelButton: btnCancel
Trang 68Một số vấn đề liên quan đến Form
this.btnCancel.DialogResult = DialogResult.Cancel;
… this.AcceptButton = this.btnOK;
this.CancelButton = this.btnCancel;
… }
private void InitializeComponent()
{
… this.btnOK.DialogResult = DialogResult.OK;
this.btnCancel.DialogResult = DialogResult.Cancel;
… this.AcceptButton = this.btnOK;
this.CancelButton = this.btnCancel;
… }