Giáo trình thực hành Lập trình hướng đối tượng - Bài thực hành số 11.3: Xây dựng Owner-drawn control và ứng dụng dùng nó

Trang 1  
MÔN : LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG  
Bài thực hành số 11.3 : Xây dựng Owner-drawn control và ứng dụng dùng nó  
I. Mục tiêu :  
ƒ
Giúp SV làm quen với cách thức xây dựng 1 Owner-drawn control giải quyết chức năng  
₫ặc thù của mình bằng cách thừa kế ₫iều khiển ₫ã có sẵn có cùng tính năng nhưng giao  
diện chưa phù hợp với nhu cầu riêng.  
II. Nội dung :  
Xây dựng button HeartButton, nó là Button nhưng bộ mặt không phải là hình chữ nhật có  
₫ường viền thông thường mà là một trái tim màu ₫ỏ tươi.  
ƒ
III. Chuẩn ₫ầu ra :  
Sinh viên nắm vững và xây dựng thành thạo các Owner-drawn Control có chức năng ₫ặc  
thù cũng như xây dựng ứng dụng dùng lại các Owner-drawn Control.  
ƒ
IV. Qui trình :  
IV.1 Xây dựng Owner-drawn control  
1. Chạy VS .Net, chọn menu File.Open.Project ₫ể hiển thị cửa sổ duyệt file. Duyệt và tìm file  
*.sln quản lý Project "Windows Control Library" có sẵn từ bài thực hành 9.2 ₫ể mở lại Project  
này.  
2. Quan sát cây Project, chúng ta ₫ã thấy có mục LoginControl.cs quản lý user control ₫ã xây  
dựng từ bài thực hành 9.1, mục MyTextBox.cs quản lý inherited control ₫ã xây dựng từ bài  
thực hành 9.2. Ấn phải chuột vào gốc của cây Project trong cửa sổ "Solution Explorer", chọn  
option Add.User Control ₫ể tạo mới 1 User Control, nhập tên là HeartButton.cs rồi click  
button Add ₫ể tạo mới nó.  
3. Lúc này control mới chỉ là 1 vùng hình chữ nhật trống. Dời chuột về mục HeartButton.cs  
trong cửa sổ Project, ấn phải chuột trên nó rồi chọn option "View Code" ₫ể hiển thị cửa sổ  
soạn mã nguồn cho HeartButton control.  
4. Hiệu chỉnh lại lệnh ₫ịnh nghĩa class HeartButton ₫ể thừa kế class Button (thay vì UserControl  
như mặc ₫ịnh). Nội dung chi tiết của class HeartButton như sau :  
namespace MyUserControls {  
public partial class HeartButton : Button {  
public HeartButton() {  
InitializeComponent();  
}
//hàm kiểm tra 1 pixel ảnh có trùng màu qui ₫ịnh không  
bool Equal(Byte[] pbase, int idx, Color key)  
{
if (pbase[idx] != key.B) return false;  
if (pbase[idx+1] != key.G) return false;  
if (pbase[idx+2] != key.R) return false;  
if (pbase[idx+3] != key.A) return false;  
return true;  
}
//hàm chuyển ảnh bitmap thành Region ₫ược qui ₫ịnh bởi ₫ường viền của ảnh  
Region ConvertB2R(Bitmap bitmap, Color Key)  
{
// Dim modeFlag As Boolean = (mode = TransparencyMode.ColorKeyOpaque)  
Trang 2  
GraphicsUnit unit = GraphicsUnit.Pixel;  
RectangleF boundsF = bitmap.GetBounds(ref unit);  
Rectangle bounds = new Rectangle((int)boundsF.Left, (int)boundsF.Top,  
(int)boundsF.Width, (int)boundsF.Height);  
//get access to the raw bits of the image  
BitmapData bitmapData = bitmap.LockBits(bounds, ImageLockMode.ReadOnly,  
PixelFormat.Format32bppArgb);  
//Get the address of the first line.  
IntPtr ptr = bitmapData.Scan0;  
//Declare an array to hold the bytes of the bitmap.  
//This code is specific to a bitmap with 24 bits per pixels.  
int bytes = Math.Abs(bitmapData.Stride) * bitmap.Height;  
byte[] pbase = new byte[bytes];  
//Copy the RGB values into the array.  
System.Runtime.InteropServices.Marshal.Copy(ptr, pbase, 0, bytes);  
//avoid property accessors in the for  
int yMax = (int)boundsF.Height;  
int xMax = (int)boundsF.Width;  
//to store all the little rectangles in  
GraphicsPath path = new GraphicsPath();  
int isrow = 0;  
int idx = 0;  
int x, y;  
for (y = 0; y <= yMax - 1; y++)  
{
idx = isrow;  
for (x = 0; x <= xMax - 1; x++)  
{
//is this transparent? if ((yes, just go on with the loop  
if (Equal(pbase, idx, Key))  
{
idx = idx + 4;  
continue;  
}
//store where the scan starts  
int x0 = x;  
//not transparent - scan until we find the next transparent byte  
while (x < xMax && (!Equal(pbase, idx, Key)))  
{
x = x + 1;  
idx = idx + 4;  
}
//add the rectangle we have found to the path  
path.AddRectangle(new Rectangle(x0, y, x - x0, 1));  
}
//jump to the next line  
isrow = isrow + bitmapData.Stride;  
}
//now create the region from all the rectangles  
Region region = new Region(path);  
//clean up  
Trang 3  
path.Dispose();  
bitmap.UnlockBits(bitmapData);  
return region;  
}
//tác vụ vẽ bộ mặt giao diện của Button  
protected override void OnPaint(PaintEventArgs e) {  
//tạo ₫ối tượng image gốc chứa ảnh trái tim màu ₫ỏ  
Bitmap bm = (Bitmap)Bitmap.FromFile("d:\\bgbutton.bmp");  
//tạo ₫ối tượng image chứa ảnh trái tim màu ₫ỏ theo kich thuoc cua Control  
Bitmap newBitmap = new Bitmap(ClientSize.Width, ClientSize.Height);  
Graphics g = Graphics.FromImage(newBitmap);  
g.DrawImage(bm, new Rectangle(0, 0, newBitmap.Width, newBitmap.Height), new  
Rectangle(1, 1, bm.Width-2, bm.Height-2), GraphicsUnit.Pixel);  
//xác ₫ịnh ₫ối tượng vẽ của Button  
g = e.Graphics;  
//vẽ inage gốc theo chế ₫ộ zoom vào button  
g.DrawImage(newBitmap, 0, 0);  
Color col = newBitmap.GetPixel(1, 1);  
this.Region = ConvertB2R(newBitmap, col);  
//this.BackgroundImage = bm;  
//this.FormBorderStyle = FormBorderStyle.None;  
//₫ịnh nghĩa ₫ối tượng miêu tả cách thức hiển thị chuỗi  
StringFormat format1 = new StringFormat(StringFormatFlags.NoClip);  
format1.Alignment = StringAlignment.Center;  
//vẽ chuỗi caption của button  
g.DrawString(this.Text, this.Font, Brushes.White, this.Width / 2, this.Height / 3,  
format1);  
}
}
}
5. Chọn menu Build.Build Solution ₫ể dịch và tạo file thư viện chứa các user control. Nếu có lỗi  
thì sữa và dịch lại. Lưu ý khi máy báo lỗi ở hàng lệnh this.AutoScaleMode = ... thì hãy chú  
thích hàng lệnh này hay xóa nó luôn cũng ₫ược.  
6. Nếu dịch thành công, file thư viện có tên là MyUserControls.dll sẽ ₫ược tạo ra trong thư mục  
con Debug (hay Release tùy chế ₫ộ dịch) trong thư mục chứa Project. Ta nên copy file này  
vào thư mục chung chứa các file thư viện ₫ể sau này dùng tiện lợi hơn.  
IV.2 Xây dựng ứng dụng dùng Owner-drawn Control  
Trong chương 5, chúng ta ₫ã xây dựng chương trình giải phương trình bậc 2 dùng giao diện ₫ồ  
họa trực quan. Chúng ta ₫ã dùng 3 textbox ₫ể nhập liệu và 1 button ₫ể khởi ₫ộng việc giải  
phương trình và hiển thị kết quả. Bây giờ chúng ta hãy hiệu chỉnh lại chương trình giải phương  
trình bậc 2 ₫ể dùng 3 ₫ối tượng MyTextBox và 1 ₫ối tượng HeartButton.  
1. Nhân bản thư mục VCGPTB2 (có ₫ược trong bài thực hành 5.1) thành thư mục mới tên là  
UseHeartButton.  
2. Chạy VS .Net, chọn menu File.Open.Project ₫ể hiển thị cửa sổ duyệt file. Duyệt và tìm file  
VCGPTB2.sln trong thư mục UseHeartButton ₫ể mở lại Project này.  
3. Dời chuột về mục Form1.cs của cây Project trong cửa sổ "Solution Explorer", ấn kép chuột vào  
nó ₫ể hiển thị lại cửa sổ thiết kế trực quan cho Form chương trình.  
4. Chọn và xóa 3 textbox và button có sẵn.  
Trang 4  
5. Nếu cửa sổ ToolBox chưa hiển thị chi tiết, chọn menu View.Toolbox ₫ể hiển thị nó (thường  
nằm ở bên trái màn hình). Click chuột vào button  
(Auto Hide) nằm ở góc trên phải cửa sổ  
ToolBox ₫ể chuyển nó về chế ₫ộ hiển thị thường trực. Dời chuột về nhóm Components trong  
cửa sổ Toolbox, ấn phải chuột trên nó ₫ể hiển thị menu lệnh, chọn option "Choose Items". Khi  
cửa sổ "Choose Toolbox Items" hiển thị, click chuột vào button Browse ₫ể hiển thị cửa sổ  
duyệt tìm file, hãy duyệt tìm ₫ến thư mục chứa file MyUserControls.dll vừa xây dựng ₫ược  
trong phần ₫ầu của bài thực hành, chọn file dll rồi click button OK ₫ể "add" các usercontrol  
trong thư viện này vào nhóm Components của cửa sổ Toolbox của Project ứng dụng.  
6. Duyệt tìm phần tử MyTextBox (thường ở cuối nhóm Components), chọn nó, dời chuột về bên  
phải Label “Nhập a:” và vẽ nó với kích thước mong muốn. Vào cửa sổ thuộc tính của ₫ối tượng  
MyTextBox vừa vẽ, ₫ặt thuộc tính (Name) = txtA, thuộc tính ValidateFor = NumReal ₫ể nó  
hoạt ₫ộng ở chế ₫ộ nhập số thực.  
7. Lặp lại bước 6 hai lần ₫ể tạo thêm 2 ₫ối tượng MyTextBox khác, các MyTextBox tạo mới lần  
lượt có thuộc tính (Name) = txtB, txtC còn thuộc tính ValidateFor = NumReal.  
Đối với các ₫ối tượng giống nhau, ta có thể dùng kỹ thuật Copy-Paste ₫ể nhân bản vô tính  
chúng cho dễ dàng.  
8. Duyệt tìm phần tử HeartButton (thường ở cuối nhóm Components), chọn nó, dời chuột về  
ngay dưới MyTextBox txtC và vẽ nó với kích thước mong muốn. Vào cửa sổ thuộc tính của ₫ối  
tượng HeartButton vừa vẽ, ₫ặt thuộc tính (Name) = btnStart, thuộc tính Text = “Bắt ₫ầu  
giải”.  
Sau khi thiết kế xong, form ứng dụng có dạng sau :  
9. Chọn lại button ₫ể hiển thị cửa sổ thuộc tính của nó, click icon  
₫ể hiển thị danh sách các  
sự kiện của ₫ối tượng HeartButton, duyệt tìm sự kiện quan tâm (Click), click chuột vào dấu  
bên phải sự kiện Click ₫ể máy hiển thị danh sách các hàm xử lý ₫ã có, chọn lại hàm xử lý  
có tên là btnStart().  
10. Chọn menu Debug.Start Debugging ₫ể dịch và chạy ứng dụng. Hãy thử nhập từng bộ ba  
(a,b,c) của phương trình bậc 2 rồi ấn button "Bắt ₫ầu giải" ₫ể giải và xem kết quả.  
pdf 4 trang myanh 18920 Free
Bạn đang xem tài liệu "Giáo trình thực hành Lập trình hướng đối tượng - Bài thực hành số 11.3: Xây dựng Owner-drawn control và ứng dụng dùng nó", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfgiao_trinh_thuc_hanh_lap_trinh_huong_doi_tuong_bai_thuc_hanh.pdf