Ch
ng Tám - T t o Object
ươ
ự ạ
c đ n gi t k các Forms r i vi t codes đ x lý các Events ờ ậ ế ế ế ồ ể ử , ta l p trình VB6 b ng cách thi ộ ng đ c các l i ích sau ể ể ữ ư ệ ế ượ ợ T tr ằ ừ ướ ế c a nh ng controls trên Form khi Users click m t Button hay Listbox, .v.v.. ữ ủ Nói chung, cách y cũng h u hi u đ tri n khai, nh ng n u ta có th h ể ưở đây thì càng t t h n n a: ấ ố ơ ữ
ệ ượ c đây trong m t d án khác ộ ự đâu ấ ừ ố c code đã vi c m t l ộ ỗ ớ ề ự ộ ự ằ 1. 2. 3. 4. Dùng l t tr i đ ế ướ ạ ượ D nh n di n đ i (error) phát xu t t ễ ậ D tri n khai m t d án l n b ng cách phân ph i ra thành nhi u d án nh ỏ ễ ể D b o trì ễ ả
i code, n u đ y nguyên xi con là lý t Vi c y đ c g i là ng. Reusability. Nói ạ ế ỗ ầ ệ ấ ượ ọ ưở c i đ object code, đó là code đã đ ể ậ ự ạ ượ th t s là khi ta ch c n dùng ỉ ầ c ượ compiled ử ạ ơ ế source code. Vì h cho phép User s a source code là t o c ả ộ ầ ữ ấ ể i ph i debug m t l n n a. ộ ự ể ệ ủ ự ề ệ ố ớ ờ ạ ạ ượ ễ ả ố M i l n dùng l cho đúng ra, dùng l r i, t c là hoàn toàn không đ ng đ n ụ ồ ứ h i cho bugs xu t hi n, r i l ồ ạ ộ S thách đ chính c a vi c tri n khai m t d án ph n m m l n là th c hi n đúng th i h n (on ệ ự c các time), không l m c tiêu y, ta ph i tri n khai nhanh và làm sao cho ch ầ tài khóa (within budget) và d b o trì (ease of maintenance). Mu n đ t đ ng trình ít có bugs, d b o trì. ố ễ ả ươ ụ ể ấ ả
ng bi d b n đ ng ra t ế ượ ả ụ ạ ứ ệ ổ ứ ệ ch c m t đám c ộ ờ ẩ t bao nhiêu chuy n ph i làm: t ệ , ti p tân, ho t náo viên ..v.v.. N u ch m t mình b n lo th t không bi ạ ễ ế ướ ự ế ế ậ ớ ả ệ ấ ờ thì không ai qua đ ẽ ả ễ ạ ệ ạ ề ả ệ c bác Sáu Đ t, và bác đã nh n l ượ ẽ ạ ớ ụ ư ủ ễ ể ặ ườ ạ ự i đàn. Anh T Thông có ng ư ụ ườ ủ ệ ch c cái đám c ư ế ệ ạ ổ ứ ặ ỗ ễ ắ ỗ ừ Gi i. Th t ng t ử ưở ả danh sách quan khách, thi p m i, m th c, xe c , ch p hình, quay phim, văn ngh cho đ n th t c ủ ụ ộ ụ ế nghi l ế t làm sao nh cho h t. ỉ ộ Cũng may là nhà hàng s đ m trách luôn c vi c in n thi p m i, ban nh c văn ngh và c ho t ạ ạ i mua quà cáp, lo v náo viên. Th t c nghi l ủ ụ ậ ờ . Bác cũng s liên l c v i M c s ch l ti p tân, xe c và th t c, nghi l ờ đ d n ch nhà th và ộ ỗ ễ ủ ụ ế i b n làm ch ti m hình, nên anh i gi s p đ t ng t chuông và ng ườ ừơ ặ ắ ướ i nh n trách nhi m m n ng i lo ch p hình, quay phim. Nh th vi c b n t ệ ậ nay rút l ặ i ch còn so n danh sách quan khách, các bài di n văn, s p ch ng i và d n ch cho c p ỉ ồ ạ v ch ng m i đi h ớ ợ ồ ướ ạ ng tu n trăng m t. ưở ậ ầ
ạ ả ề ệ ắ ố i n y t ườ ầ ự ữ ư ạ lo quy t đ nh m i chi ti ọ ế ị ạ ể ấ ở ủ ọ ầ ắ ả ườ th uầ c a b n. Ch c b n đã l u ý r ng cái thí d t ỉ ủ ạ ầ ọ ố ư ữ i th u giúp ch c đám ụ ổ ứ ườ ắ ạ ớ ờ ữ ư ầ ự ể ầ ấ ọ ớ ằ ả x a đ n nay. S dĩ b n c m th y trách nhi m t ch c không n ng n vì nhà hàng, bác Sáu Đ t và anh T Thông ặ ổ ứ ấ ở t c a lo gánh vác các khâu r c r i. Cái hay t đây là nh ng ng ế ủ ự ế ủ nh ng gì c n ph i làm trong khâu c a h . Ch khi nào c n l m, h m i liên l c đ l y ý ki n c a ữ b n. H gi ng nh nh ng ng i ạ c ố ướ ầ đ . Qu th t, đó là cách các qu n tr viên nh ng công trình đã làm t ở i n y cho th y nói chung mu n tri n khai d án l n nào ta c n ph i nh nh ng ng ữ ừ ư ế ả ậ ả ị
i chuy n l p trình, ph i chi ta có th t ề ầ ả i nói trên thì t ư ổ ứ ầ ố ể t quá. Th t ra, không ph i các lý thuy t gia ph n m m ề ư ố ch c cách tri n khai d án ph n m m gi ng ự ế ườ ể ổ ứ ậ ể ự ệ ậ ướ ệ ấ ụ ệ ượ ở ạ ướ ợ ươ ụ ệ ỉ c đây, nh ng đ th c hi n đ ng ti n, d ng c thích h p. Ch trong vòng 15 năm tr l ấ ả i ta c n tri n khai các c vi c y ng ể ầ ệ ấ i đây, vi c y m i tr nên c th qua ụ ể ớ ở ệ ấ ư ữ ậ tr l Bây gi ờ ở ạ ch c cái đám c nh t không nghĩ đ n chuy n y tr ế ph các Operating Systems tinh vi, nh t là dùng Windows, và các ngôn ng l p trình nh Eiffel, SmallTalk, C++ .v.v..
L p trình theo h ng đ i t ng (Object Oriented Programming) ậ ướ ố ượ
ướ ậ ầ ộ ậ ộ ng trình, g i là ng là thi ọ Objects sao cho m i b ph n có th t ể ự ỗ ộ b n s h i th thì các ề ố ạ ờ ậ ắ ng trình có th đ m trách vai trò c a m t th u không? ng đ i t ố ượ ậ ẽ ạ ẽ ỏ ươ t k các b ph n ph n m m c a ủ ế ế ư ộ lo li u công tác c a nó gi ng nh m t ủ ệ ừ Sub hay Function mà b n đã t ng ộ ế ể ả ủ ạ ượ ệ c công tác (Subs và Functions) gì mà còn ch u trách nhi m ầ ị Nói m t cách nôm na, l p trình theo h ch ng vi Ng ể luôn c m i th v t d ng c n thi t (data) cho vi c y n a. ươ i ườ th uầ ngoài đ i v y. Ch c có l t đ x lý t ng giai đo n trong ch ế ể ử ừ i th u ch ng nh ng có th làm đ ẳ ữ ầ ườ ứ ậ ụ ả ọ ế ầ ệ ấ ữ
ị ộ ồ ng, khi ta dùng Objects ít khi giám th chúng, ng c l ộ ệ ườ ấ ị t. Có m t cách đ nh nghĩa khác cho Object là m t Object g m có data structure và các Subs/Functions làm vi c trên các data y. Thông th ượ ạ ế i n u khi có s c gì thì ta mu n chúng báo cáo cho ta bi ố ự ố ế
ẫ ấ ộ ể ư ằ ữ qu n lý các items hi n th bên trong nó. Ta bi ế ị ự ả t item nào v a m i đ ớ ượ ỏ ừ ế ằ ủ ộ ọ ế ộ ộ ể ủ ư ự ố ự ự ầ ế t trong VB6 ch ng h n, nó cũng là m t Class. Th ẳ ạ ộ ườ ng ụ Trong VB6, các Forms, Controls hay ActiveX là nh ng Objects mà ta v n dùng lâu nay. L y thí d t listbox List1 đang có nh Listbox. M t Listbox t c selected b ng cách bao nhiêu items b ng cách h i List1.ListCount. Ta bi h i List1.ListIndex. Ta thêm m t item vào listbox b ng cách g i method AddItem c a List1, ..v.v.. ằ ỏ Nói cho đúng ra, Object là m t th c th c a m t Class. N u Listbox là m t Class thì List1, List2 là ộ các th c th c a Listbox. Cũng gi ng nh Bà T Cháo Lòng và Dì Sáu Bánh T m là các th c th ể ư ể ủ c a Class Đ u B p. ầ ủ Ngay c m t form tên frmMyForm mà ta vi ế ả ộ ng ta dùng th ng frmMyForm nh sau: th ườ ư ẳ
frmMyForm.Show
ng h p n y th t ra frmMyForm tuy là m t Class nh ng đ c dùng y nh m t Object. ợ ườ ượ ư ầ ộ ư ộ ư ậ ể ạ ố ộ ụ Trong tr Ch n u mu n, ta có th t o ra hai, ba Objects c a Class frmMyForm cùng m t lúc nh trong thí d ủ ớ ế sau:
Dim firstForm As frmMyForm Dim secondForm As frmMyForm Set firstForm = New frmMyForm Set secondForm = New frmMyForm firstForm.Show secondForm.Show
ủ ữ ụ Set... = New... ằ ủ ượ ọ ư ố instances c a Class frmMyForm. Class gi ng nh cái khuôn y. Ch c b n đã đ ý th y trong VB6 ố ư ữ ắ ạ ể ấ ấ ẫ ộ ề ễ ạ ọ
ể ể ủ ể ộ ể ọ ủ Events, t c là báo cho ta bi ứ ệ ố ủ ể ổ ợ ẳ ạ ứ ứ ư Trong thí d trên ta declare firstForm và secondForm là nh ng Objects c a Class frmMyForm. Sau đó ta làm nên (instantiate) các Objects firstForm và secondForm b ng statements firstForm và secondForm còn đ c g i là các khuôn, còn Objects gi ng nh nh ng cái bánh làm t ừ ắ Class và Object l n l n nhau. Đ u n y cũng không quan tr ng, mi n là b n n m t dùng hai t ầ ừ ừ v ng ý nghĩa c a chúng. ủ ữ ợ Class mà ta có th tri n khai và instantiate các Objects c a nó khi dùng. M t Class VB6 có y m tr ữ Subs và Functions mà ta có th g i. Ngoài ra Class trong VB6 có ch a ứ data riêng c a nó, có nh ng ư t khi chuy n gì xãy ra bên trong nó. Cũng gi ng nh còn có th Raise ế ể Event Click c a CommandButton, khi User clicks lên button thì nó Raise Event Click đ cho ta x lý ử trong Sub myCommandButton_Click(), ch ng h n. Classtrong VB6 không có h tr Visual components, t c là không có ch a nh ng controls nh TextBox, Label .v.v.. Tuy nhiên, ta có th l y ể ấ nh ng control có s n t bên ngoài r i đ a cho Object c a Class dùng. ữ ồ ư ẵ ừ ữ ủ
chúng ta hãy b t đ u vi t m t Class. B n hãy m m t Project m i lo i Standard EXE ờ ắ ầ ở ộ ế ạ ạ ộ ớ Bây gi Visual Basic. Sau đó dùng Menu Command ch n ọ Add Class Module:
Khi Add Class Module dialog hi n ra ch n ọ Class Module và click Open. ệ
ạ ẽ ấ ắ ộ ớ B n s th y m ra m t khung tr ng và Project Explorer v i Properties Window. Trong Properties Window, hãy s a Name property c a Class thành clsBox nh d i đây: ư ướ ở ử ủ
K đó đánh vào nh ng dòng code d ữ ế ướ i đây, trong đó có bi u di n cách dùng Class clsBox. ể ể
Option Explicit Private mX As Integer Private mY As Integer Private mWidth As Integer
Private mHeight As Integer
Public Property Let X(ByVal vValue As Integer) mX = vValue End Property
Public Property Get X() As Integer X = mX End Property
Public Property Let Y(ByVal vValue As Integer) mY = vValue End Property
Public Property Get Y() As Integer Y = mY End Property
Public Property Let Width(ByVal vValue As Integer) mWidth = vValue End Property
Public Property Get Width() As Integer Width = mWidth End Property
Public Property Let Height(ByVal vValue As Integer) mHeight = vValue End Property
Public Property Get Height() As Integer Height = mHeight End Property
Public Sub DrawBox(Canvas As Object) Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), , B End Sub
Public Sub ClearBox(Canvas As Object) Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), Canvas.BackColor, B End Sub
ẽ ỗ ừ Th t ra ta có th ề ướ ọ ộ clsBox. M i Box ậ ể
đây ta c ý declare chúng ẽ ố i d ng mX, mY, mWidth và mHeight. Khi ta mu n thay đ i các tr s c a chúng, ta s ế ướ ạ ộ t code nh bình th ư ư ng trình ươ Property Let ụ ạ ư ộ ọ ẽ ấ đây vValue đ ượ ấ ở đây ử ổ ệ ầ ư ế ộ ở c assigned cho mX (i.e. mX = vValue ), cái Private variable ẳ t thêm code trong Property Let X đ nó làm gì cũng đ c. ượ ể ạ ạ ế ế ộ ẳ ổ c hi n th tr l Class clsBox có 4 Properties: X, Y, Width và Height. Ta s instantiate m t Box t ộ có t a đ (X,Y) và kích th c chi u r ng và chi u cao (width, height) c a nó. ủ ề ộ dùng Public statement đ declare các bi n X, Y, Width và Height. Nh ng ư ở ế ể ố là Private, d ổ ị ố ủ ng (thí d : myBox.X = 80 ). Nh ng khi ch dùng cùng m t cách vi ườ x lý assignment statement y, nó s execute m t lo i method (gi ng nh Sub) g i là ố ử X (vValue). Ta th y c a X. Nh th công vi c n y cũng ch ng khác gì s a đ i m t Public variable X. Tuy nhiên, ủ ta có th vi ể ể ế t k m t Label, m i l n b n dùng Property Window đ edit Font size, B n có nh trong khi thi ỗ ầ ớ forcolor hay backcolor thì ch ng nh ng các properties y c a Label thay đ i, mà k t qu c a s ả ủ ự ế ị ở ạ ớ ị ố ớ ủ i v i tr s m i c a thay đ i đ ữ c có hi u l c ngay l p t c, nghĩa là Label đ ậ ứ ấ ủ ượ ổ ượ ệ ự ể
ả ả ị ố ả i, khi ta dùng property X c a Object myBox, không ph i ta ch đ c tr s thôi mà còn c l ượ ạ ả ỉ ọ i, Property cho ta c h i đ execute m t method ơ ộ ể ạ ộ ỗ ọ ế ị ố ể ị ố ọ ộ ố ả ậ ớ property. Đó là vì trong method Property có c code b o Label redisplay. Ng ủ Property Get X. Nói tóm l execute c cái method t tr s variable y. m i khi User đ c hay vi Thí d nh n u ta mu n ki m soát đ ch ch p nh n tr s t a đ X m i khi nó không ph i là s ố âm. Ta s s a Property Let X l ấ ể ỉ ấ i nh sau: ư ụ ư ế ẽ ử ạ
Public Property Let X(ByVal vValue As Integer) If (vValue >= 0) Then mX = vValue End If End Property
ố ộ ấ ộ ố ấ ng, thì ta ph i dùng ệ ớ Object, thay vì Data type thông th ườ ả
ụ ủ ớ ọ Property có th là ể Read Only hay Write Only. N u mu n m t Property là Read Only thì ta không ế cung c p Property Let. N u mu n m t Property là Write Only thì ta không cung c p Property Get. ế Ngoài ra n u làm vi c v i Property Set, ế thay vì Property Let. Thí d ta cho clsBox m t Property m i, g i là Font dùng object c a class stdFont c a VB6. Trong ộ clsBox ta declare m t Private variable mFont và vi t m t ủ ộ Property Set Font nh sau: ư ế ộ
Private mFont As StdFont Public Property Set Font(ByVal newFont As StdFont) Set mFont = newFont End Property
Ta s dùng property Font c a myBox (thu c Class clsBox) nh sau: ủ ư ẽ ộ
' Declare an object of Class StdFont of VB6 Dim myFont As StdFont Set myFont = New StdFont myFont.Name = "Arial" myFont.Bold = True Dim myBox As clsBox Set myBox = New clsBox Set myBox.Font = myFont ' Call the Property Set method
ư ẽ ộ ẵ ư ủ ư ế i m t chút đ nh n m t Optional draw color nh sau: Class clsBox có hai Public Subs, DrawBox và ClearBox. ClearBox cũng v m t box nh DrawBox, nh ng nó dùng BackColor c a màn nh (canvas), nên coi nh xóa cái box có s n. Do đó, n u mu n, ố b n có th s a Sub DrawBox l ậ ạ ể ử ả ộ ư ể ạ ộ
Public Sub DrawBox(Canvas As Object, Optional fColor As Long) If IsMissing(fColor) Then Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), , B Else Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), fColor, B End If End Sub
IsMissing. N u fColor là c tested b ng function ụ ượ ế ằ ệ ng trình dùng đ test clsBox, m i khi ta refer đ n m t object thu c class ủ ế ộ ộ ỗ ươ ẽ ể ủ ư ị ướ i Trong thí d trên, Optional parameter fColor đ BackColor c a canvas thì ta s có hi u qu c a ClearBox. ả ủ ẽ ủ Trong form chính c a ch ể clsBox, IDE Intellisense s hi n th các Properties và Subs/Functions c a clsBox nh trong hình d đây:
Draw thì m t Box đ ầ ộ ượ ọ ộ ươ c Width, Height, r i đ c v ra ngay trên form. Ch ng trình n y, m i khi ta click nút ỗ ồ ượ ẽ c instantiate, cho t a đ X,Y và ữ Me trong code nói đ n chính cái form ế Trong ch kích th ướ frmClass.
ng trình thú v h n, khi user clicks nút trái ể ươ ị ơ Animate, ta s cho m t box màu đ ch y t ộ ỏ ạ ừ ẽ
ẽ ẽ ộ ộ ỏ ả Ở ể ấ ố ừ Đ cho ch qua ph i. ả Khi user clicks nút Two Boxes ta s v hai boxes, h p trong màu xanh, h p ngoài màu đ , và cho chúng ch y t ạ ừ clsBox cũng đ c, và dĩ nhiên m i box có m t b properties v i giá tr riêng c a nó. đây ta bi u di n cho th y mình mu n instantiate bao nhiêu boxes t ỗ trái sang ph i. ượ ễ ộ ộ ủ ớ ị
ể ế ố ủ ủ ộ
t code đ m i khi Sub DrawBox executes thì ể ỗ ế Ta có th l p trình đ cho Object báo cáo program ch c a nó khi có m t bi n c (Event) xãy ra bên ể ậ trong Class. Ta th declare m t Event tên Draw trong clsBox, và vi ử Class s Raise m t event Draw. ộ ộ ẽ
Public Event Draw(X As Integer, Y As Integer) Public Sub DrawBox(Canvas As Object, Optional fColor As Long) If IsMissing(fColor) Then Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), , B Else Canvas.Line (mX, mY)-(mX + mWidth, mY + mHeight), fColor, B End If RaiseEvent Draw(mX, mY) End Sub
, trong frmClass thay vì ch declare Dim myBox as clsBox, ta s declare Private WithEvents ờ ẽ ỉ
ẽ ế ể ế t code đ handle Event Draw c a myBox, t c là ta cung c p code cho ủ đây ta ch hi n th m t s đi p báo cáo ổ ợ ấ ị ộ ứ ệ ứ ỉ ể Ở Bây gi myBox as clsBox. Ngay sau đó, ch ữ myBox s hi n ra trong danh sách các Object có h tr Event ẽ ệ c a frmClass. K đó ta s vi ủ Private Sub myBox_Draw (X as Integer, Y as Integer). m t h p v a đ c v đâu. ộ ộ ừ ượ ẽ ở
ạ ẽ ấ ộ i đây. Khi ch y program, m i l n m t clsBox object executes Sub DrawBox ta s th y frmClass display ỗ ầ m t message gi ng nh d ư ướ ộ ố
ớ ớ ằ ố ng t ươ ủ ụ ả ộ ủ ủ bên trong m t Class, n u Class y đ c giao cho m t Object có th Raise Events (thí d nh ộ ế ể ộ ụ ư ể ể ể ấ
c giao cho m t Textbox khi form t codes n y trong m t Class đã đ i đây ta vi ụ ướ ượ ầ ộ ộ Nh r ng, ta declare m t Object v i WithEvents khi ta mu n handle các Events c a nó. Trong thí d ủ nh v y, ngay c trên frmClass là ch c a myBox và nó handles Event Draw c a myBox. T ự ư ậ ấ ượ ở TextBox, ListBox, Timer .v.v..), b n cũng có th declare Object y WithEvents đ nó có th handle ạ Events c a Object. ủ Trong thí d d ế chính g i Sub InitObject đ đ a cho Object m t TextBox: ể ư ọ ộ
Private WithEvents mTextBox As TextBox
Public Sub InitObject(givenTextBox As TextBox) Set mTextBox = givenTextBox End Sub
Private Sub mTextBox_KeyPress(KeyAscii As Integer) ' Place your code here to handle this event within the Class Object End Sub