Thursday, October 29, 2009

Thủ thuật nhỏ trong VB p7

Trong kỳ này:

1. Kiểm tra việc nhập liệu vào TextBox
2. Chuyển đổi ký tự trong các đối tượng có khả năng hiệu chỉnh (Editbox) thành chữ hoa
3. Bỏ qua một số ký tự khi gõ văn bản trong TextBox

4. Xóa các mục chọn (Item) trong Combo/List Box

5. Làm sao để tắt tính năng Wordwrap của Rich TextBox

6. Thêm một dòng mới vào cuối TextBox đang chứa văn bản

7. Làm sao để Shut down hay Reboot lại Windows ?

8. Làm cho TEXTBOX trở thành read only hoặc cấm người dùng thay đổi nội dung

9. Mở file với chương trình liên kết (associated program)

10. Làm sao để play các file: MID, WAV, AVI ?


1. Kiểm tra việc nhập liệu vào TextBox

Trong chương trình nếu bạn có yêu cầu bắt người dùng phải nhập liệu vào mọi TextBox đang hiện hữu trên một form để thực hiện một việc nào đó, song không phải ai cũng "vâng lời". bạn cần kiểm tra xem người dùng có nhập đầy đủ thông tin vào các TextBox chưa. Để đỡ nhọc công phải kiểm tra từng cái một (thường kiểm tra khi có sự kiện LostFocus), với hàm này bạn chỉ việc chuyển cho nó một tham số là Form chứa các TextBox cần kiểm tra, nó có nhiệm vụ truy tìm những TextBox còn trống và phơi bày ra màn hình bằng bằng một biểu hiện khác thường nào đó.

Hàm này nhận vào một đối số duy nhất là Form (thường là form hiện hành "Me"), sau đó nó sẽ tìm đến tất cả các Textbox có trên form bằng cách sử dụng câu lệnh "For Each Control" nếu có Textbox còn trống thì đổi màu nền BackColor (màu hồng), đồng thời trả về một giá trị kiểu Boolean là True. Không những là TextBox, nếu là ComboBox vẫn bị vòng lặp này chiếu cố.

Để thử hàm này bạn hãy tạo một form, tạo vài chục cái TextBox (tên chi cũng được) và một CommandButton (name: cmdTextEmpty). Gõ vào đoạn Code sau:

Private Sub cmdTestEmpty_Click()

If IsEmpty(Me) Then

MsgBox "Some textboxes are still empty"

End If

End Sub

Function IsEmpty(Frm As Form) As Boolean

Dim tmpControl As Control

On Error Resume Next

IsEmpty = False

For Each tmpControl In Frm.Controls

If Trim(tmpControl.Text) = "" Then

If Err.Number = 0 Then

IsEmpty = True

tmpControl.BackColor = &HFFC0FF 'Màu hồng

End If

Err.Clear

Else

If tmpControl.BackColor = &HFFC0FF Then

tmpControl.BackColor = QBColor(15)'Màu trắng

End If

End If

Next tmpControl

End Function

Nhấn F5 để chạy chương trình. Bây giờ bạn hãy làm cho một TextBox trống (vài cái cũng được), sau đó click vào CommandButton, bạn sẽ thấy các TextBox trống bị đổi màu thành màu hồng. Hãy gõ văn bản vào các TextBox màu hồng đó, sau đó click lên CommandButton lần nữa, bây giờ thì êm rồi, các TextBox đã trở lại bình thường (nền trắng).


2. Chuyển đổi ký tự trong các đối tượng có khả năng hiệu chỉnh (Editbox) thành chữ hoa

Các đối tượng loại này gồm có TextBox, Combobox. Sau đây là các đoạn code dùng để chuyển đổi văn bản hiện hữu trong các Control thành chữ hoa. Dùng cho một số đối tượng:

+ Cho combobox không có drop down

Dim hwndListbox As Integer
Dim childhWnd As Integer

hwndListbox = GetWindow(cbo1.hWnd, GW_CHILD)

childhWnd = GetWindow(hwndListbox, GW_HWNDNEXT)

lStyle = GetWindowLong(childhWnd, GWL_STYLE)

lStyle = lStyle Or ES_UPPERCASE

lRes = SetWindowLong(childhWnd, GWL_STYLE, lStyle)

+ Cho ComboBox có drop down

childhWnd = GetWindow(cbo1.hWnd, gw_child)

lStyle = GetWindowLong(childhWnd, GWL_STYLE)

lStyle = lStyle Or ES_UPPERCASE

lRes = SetWindowLong(childhWnd, GWL_STYLE, lStyle)

+ Cho TextBox

lStyle = GetWindowLong(Txt1.hWnd, GWL_STYLE)

lStyle = lStyle Or ES_UPPERCASE

lRes = SetWindowLong(Txt1.hWnd, GWL_STYLE, lStyle)


3. Bỏ qua một số ký tự khi gõ văn bản trong TextBox

Nếu bạn cần loại bỏ một số ký tự khi người dùng gõ văn bản vào trong một Textbox, thường là các ký tự đặc biệt như: "!@#$%^&*()_+-=" . Sau đây là một giải pháp. Bằng cách dùng liên tục hàm InStr mỗi khi có phím gõ (Sự kiện KeyPress)

Private Sub Text1_KeyPress(KeyAscii As Integer)

Dim sTemplate As String

sTemplate = "!@#$%^&*()_+-="

If InStr(1, sTemplate, Chr(KeyAscii)) > 0 Then

KeyAscii = 0

End If

End Sub


4. Xóa các mục chọn (Item) trong Combo/List Box

Để xóa các Item trong Combo box hay List box, bạn cần phải duyệt ngược, tức là từ (ListCout-1) đến 0. Sau đây là một thí dụ minh họa. Bằng cách dùng vòng lặp For, kèm theo Step -1 để duyệt ngược.

Sub cmdDeleteItems_Click ()

Dim i As Integer

For i = List1.ListCount - 1 To 0 Step -1

If List1.Selected(i) Then

List1.RemoveItem i

End If

Next i

End Sub


5. Làm sao để tắt tính năng Wordwrap của Rich TextBox

Có lần nào bạn bực mình vì không tìm được thuộc tính nào để tắt khả năng Wordwrap của RichTextBox không ? Tức là không cho nó tự cắt dòng văn bản của mình mỗi khi chạm cạnh phải. Tìm cũng không có, chắc Bill quên tạo rồi chăng?

Không hiểu tại sao khi sáng tác ra RichTextBox, Bill không chịu làm luôn cho nó chức năng Wordwrap để cho bà con có thể On/Off khi cần ? Không biết là Bill cố ý hay "lỡ quên" không tạo !?

Thật ra mà nói RichTextBox không có tính năng Wordwrap để dễ dàng sử dụng trên Internet đấy mà. Nhưng suy cho cùng chúng ta có thể nhanh chóng giải tỏa hạn chế này bằng cách gán cho thuộc tính RightMargin của RichTextBox một con số thiệt "bự", ôi chao đừng quá khiêm tốn với số 0 nữa ! Một con số chừng 100.000 cũng được mà, lúc đó thì khả năng Worwrap của nó bị đẩy đi tuốt luốt ở một nơi cách màn hình của bạn gần 400m về phía phải. Với mánh này bạn chỉ thật sự đại bại khi có dòng văn bản dài hơn cỡ đó thôi.

Bạn cũng đừng quên cho hiển thị ScrollBar để người dùng dễ dàng trong việc xem các dòng văn bản "cố ý dài" của bạn.


6. Thêm một dòng mới vào cuối TextBox đang chứa văn bản

Nếu bạn có nhu cầu thêm ngày tháng vào cuối một văn bản sau khi hiệu chỉnh, để biết rõ được ngày cập nhật cuối cùng của một tài liệu nào đó (thường gặp trong các chương trình làm sổ tay, nhật ký... ). Để làm việc này bạn hãy vận dụng các Properties: SelStart, SelText của TextBox.

Sau đây là đoạn code thêm ngày tháng vào cuối văn bản trong TextBox

Dim strNewText As String

With Text1

strNewText = "Updated: " & Date

.SelStart = Len(.Text)

.SelText = vbNewLine & strNewText

End With


7. Làm sao để Shut down hay Reboot lại Windows ?

Trong Visual Basic 32bit. Khai báo hàm API như sau:

Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Boolean

Public Const EWX_SHUTDOWN = 1

Khi sử dụng bạn chỉ việc:

Dim success

success = ExitWindowsEx(EWX_SHUTDOWN, 0)

Nếu thành công, hàm này sẽ trả về True.

+ EWX_REBOOT = 2 sẽ làm cho Windows 9.x Reboot

+ EWX_LOGOFF = 0 để Log off.

Với phiên bản 16bit

Declare Function ExitWindows Lib "user" (ByVal wReturnCode as Long,ByVal dwReserved as Integer) as Integer

Exit Windows:

RetVal% = ExitWindows(0, 0)

Exit & restart Windows:

RetVal% = ExitWindows(&H42, 0)

Exit Windows & restart the system:

RetVal% = ExitWindows(&H43, 0)


8. Làm cho TEXTBOX trở thành read only (cấm người dùng thay đổi nội dung)

Nếu bạn sử dụng Visual Basic 5.0 trở lên thì có thuộc tính Locked, nếu gán là True thì người dùng không thể thay đổi nội dung của TextBox (Read Only).

Có một số ý kiến cho rằng, bạn cần chộp lấy sự kiện KeyPress và KeyDown làm cho chúng thành zero. Tuy nhiên, giải pháp tốt nhất vẫn là hàm Windows API SendMessage.

Global Const WM_USER = &H400
Global Const EM_SETREADONLY = (WM_USER + 31)

Declare Function SendMessage Lib "User" (ByVal hWnd As Integer ByVal wMsg As Integer, ByVal wParam As Integer, lParam As Any) As Long

SendMessage(Text1.hWnd, EM_SETREADONLY, 1, 0)

Cách trên người sử dụng vẫn có thể Copy nội dung. Nếu cần bạn thực sự cần cấm người dùng Copy nội dung, bạn có thể loại bỏ tổ hợp phím Ctrl-C bằng cách "đón đánh" khi xảy ra sự kiện KeyPress.


9. Mở file với chương trình liên kết (associated program)

Hàm Shell() hơi bị bất tiện vì chỉ gọi được chương trình trực tiếp từ file exe. Không giống như Windows, thí dụ như khi double click lên file DOC sẽ mở Microsoft Word, file TXT sẽ mở Notepad. Bạn cũng có thể viết một Module tạo các mối liên kết như vậy trong Visual Basic để dễ dàng trong việc gọi các ứng dụng.

Các khai báo API

#IF WIN32 THEN
Private Declare Function ShellExecute Lib "shell32.dll" Alias _ "ShellExecuteA" ByVal hwnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Private Declare Function GetDesktopWindow Lib "user32" () As Long

#ELSE
Declare Function ShellExecute Lib "SHELL" (ByVal hwnd%, _
ByVal lpszOp$, ByVal lpszFile$, ByVal lpszParams$, _
ByVal lpszDir$, ByVal fsShowCmd%) As Integer

Declare Function GetDesktopWindow Lib "USER" () As Integer
#END IF

Private Const SW_SHOWNORMAL = 1

Hàm phục vụ việc khởi động

Function StartDoc(DocName As String) As Long

Dim Scr_hDC As Long

Scr_hDC = GetDesktopWindow()

StartDoc = ShellExecute(Scr_hDC, "Open", _
DocName, "", "C:\", SW_SHOWNORMAL)

End Function

Kiểm chứng chương trình

Private Sub Form_Click()

Dim r As Long

r = StartDoc("c:\mydoc\myletter.doc")

Debug.Print "Return code from Startdoc: "; r

End Sub

10. Làm sao để Play các file: MID, WAV ?

Bằng cách sử dụng MCI của Windows

Declare Function mciExecute Lib "MMSystem" (ByVal FileName as String) As Integer

Private Sub Form1_Click ()

iResult = mciExecute("Play c:\windows\mkmyday.wav")

End Sub

Tương tự như vậy, bạn có thể dùng cách này để Play một file MIDI. Còn đây là cách Play một file AVI

Private Declare Function mciExecute Lib "WINMM.DLL" (ByVal lpstrCommand as String) as Long

Private Sub Form_Click()

iResult = mciExecute("Play E:\Luu\AVI\Search.avi")

End Sub

Nếu muốn ngừng, đơn giản bạn chỉ cần thay từ Play thành Stop là được.

No comments:

Post a Comment