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
• Ví dụ
• 0x0001 WM_CREATE • 0x0002 WM_DESTROY• 0x0003 WM_MOVE• 0x0005 WM_SIZE• 0x0012 WM_QUIT
Trang 6Lập trình trên Windows
Hardware inputHardware
Hệ điều hành Windows
Ứng dụng A
Nhận và xử lý
Ứng dụng B
Nhận và xử lýMessage loop
Message loopSystem
Application 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)
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
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 • System.Windows.Forms
• System.Drawing• [System.Core]
• Bước 2: using các namespace
using System.Windows.Forms;using System.Drawing;
• 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{
staticvoid Main(){
Form form = new Form();
form.Text = “First Application”;Application.Run(form);
staticvoid Main(){
Form form = newForm();
form.Text = “First Application”;
}
Trang 19Dùng Form, Không thừa kế
class Program{
static void Main() {
Form form = new Form();form.Text = "WinForm";
form.BackColor = Color.Green;form.Width = 300;
form.Height = 300;
form.MaximizeBox = false;form.Cursor = Cursors.Hand;
form.StartPosition = FormStartPosition.CenterScreen;Application.Run(form);
}}
form.StartPosition = FormStartPosition.CenterScreen;
}}
• Thuộc tính
Trang 20Dùng Form, Không thừa kế
class Program{
static void Main() {
Form form = new Form();form.Text = “WinForm”;form.Click += form_Click;Application.Run(form); }
static void form_Click(object sender, EventArgs e) {
MessageBox.Show("Ban da click vao form");
Trang 21Dùng Form, Không thừa kế
class Program{
static void Main() {
Form form = new Form();form.Text = "WinForm";
Button button = new Button();button.Text = "OK";
button.Location = new Point(100, 100);
button.Click += new EventHandler(button_Click);form.Controls.Add(button);
Application.Run(form); }
static void button_Click(object sender, EventArgs e) {
MessageBox.Show("Ban da click vao nut OK"); }
staticvoid Main() {
Form form = newForm();form.Text = "WinForm";
Button button = newButton();button.Text = "OK";
button.Location = newPoint(100, 100);
button.Click += newEventHandler(button_Click);form.Controls.Add(button);
Application.Run(form); }
static void button_Click(object sender, EventArgs e) {
MessageBox.Show("Ban da click vao nut OK"); }
• Thêm control vào form
Trang 22Dùng form bằng cách kế thừa
class MainForm:Form{
private Button button; public MainForm()
{
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);
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);
}}
}
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
class MainForm:Form{
public MainForm() {
this.Text = "WinForm"; this.Click += form_Click;}
void form_Click(object sender, EventArgs e) {
MessageBox.Show("Ban da click vao form"); }
void form_Click(object sender, EventArgs e) {
}
Trang 25Dùng form bằng cách kế thừa
class MainForm:Form{
public MainForm() {
this.Text = "WinForm";}
protected override void OnClick(EventArgs e) {
this.Text = "WinForm";}
protected overridevoid OnClick(EventArgs e) {
MessageBox.Show("Ban da click vao form"); }
• 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ầnHiển thị theo loại
PropertiesEvents
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 39• 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 41public 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 static event EventHandler LeaveThreadModal; public static event ThreadExceptionEventHandler
public static event EventHandler LeaveThreadModal; public static event ThreadExceptionEventHandler
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 vòng lặp
• EnableVisualStyles() các control sẽ vẽ với kiểu visual nếu
control và hệ điều hành hỗ trợ
• Restart() dừng ứng dụng và Tự động restart lại
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 45private Button btnClose;public MainForm()
btnClose = new Button();…
btnClose.Click += btnClose_Click;this.Controls.Add(btnClose);
private btnClose_Click(object sender, EventArgs e){
private btnClose_Click(object sender, EventArgs e){
}
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 exe3.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ệc6.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 48DialogResult Show(string text, string caption,
MessageBoxIcon icon,
MessageBoxDefaultButton defaultButton, MessageBoxOptions options);
•System.Windows.FormsAssembly
Trang 49Lớp MessageBox
• Các Enumerations
• MessageBoxButtons• MessageBoxIcon
• MessageBoxDefaultButton• MessageBoxOptions
YesNo,
RetryCancel}
public enum MessageBoxButtons{
OK,
OKCancel,
AbortRetryIgnore, YesNoCancel,
YesNo,
RetryCancel}
public enum MessageBoxIcon{
Asterisk = 0x40, Error = 0x10,
Exclamation = 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 50RtlReading = 0x100000,
ServiceNotification = 0x200000}
public enum MessageBoxOptions{
DefaultDesktopOnly = 0x20000, RightAlign = 0x80000,
RtlReading = 0x100000,
ServiceNotification = 0x200000}
Trang 51Cancel, Abort, Retry, Ignore, Yes,
No}
public enum DialogResult{
None, OK,
Cancel, Abort, Retry, Ignore, Yes,
No}
Trang 52Lớp Form
Trang 53• System.Windows.Form (System.Windows.Form.dll)
Trang 54Properties
Trang 55Properties
Trang 56Events
Trang 57Events
Trang 58• Controls• Modal
class MyForm : Form{
public MyForm() {
this.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 62Một số vấn đề liên quan đến Form
• Nút OK và Cancel• Cách 1
private void btnOK_Click(object sender, EventArgs e){
private void btnCancel_Click(object sender, EventArgs e)
private void btnOK_Click(object sender, EventArgs e){
private void btnCancel_Click(object sender, EventArgs e)
this.Close();}
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
DialogResult res = dlg.DialogResult;if (res == DialogResult.OK)
DialogResult res = dlg.DialogResult;if (res == DialogResult.OK)
if (dlg.ShowDialog() == DialogResult.OK){
if (dlg.ShowDialog() == DialogResult.OK){