21. TextBox控制項與RichTextBox控制項
如何利用文字方塊或RichTextBox顯示檔案的內容?
文字方塊或是RichTextBox,都可以作為顯示檔案內容的工具。如果要選用文字方塊作為顯示檔案內容的工具,必須把屬性MultiLine設為True,屬性Scrollbars設為"3 - 兩者皆有",才能使視窗具備捲動的功能。
以下這個範例將會載入AUTOEXEC.BAT檔,並利用一個RichTextBox將檔案的內容顯示在一個可捲動的視窗中︰
Option Explicit Private Sub Form_Load() Dim strF As String `Load a file into a string Open "C:\AUTOEXEC.BAT" For Binary As #1 strF = Space$(LOF(1)) Get #1, , strF Close #1 `Display file in rich text box rtfTest.Text = strF End Sub
圖21-1顯示了程式執行的結果。
圖21-1 以一個RichTextBox控制項顯示AUTOEXEC.BAT的內容 |
在這個例子裡,整個AUTOEXEC.BAT檔的內容以二進位檔案模式被讀入到字串變數裡,等待稍後的處理。採用二進位檔案模式是一個十分有用的技巧,因為不管檔案的內容是什麼,二進位檔案模式會將每一個位元組原封不動地從檔案中讀出,這表示,如果這個檔案有一行以上的資料,那麼每一個換行字元(line feed)和機架返回字元(carriage return)都會包含在字串中。(
第十五章"檔案" 對二進位檔案模式的輸出輸入有更詳盡的討論)。另外,如果讀入的檔案是RTF格式的檔案,你應該把字串指定給RichTextBox控制項的TextRTF屬性,而不是定給Text屬性,這樣,檔案中的格式控制碼就可以被正確的解釋,而顯示出正確的內容。如果不用二進位檔模式讀取檔案的資料,我們有另一種方式可以建立一個含多行資料的字串;你可以把每一個字串串接在一起,在字串與字串之間插入機架返回和換行控制碼,以下這個範例即是利用這種技巧。
Option Explicit Private Sub Form_Load() Dim strA As String, strF As String `Load a file into a string Open "C:\AUTOEXEC.BAT" For Input As #1 Do Until EOF(1) Line Input #1, strA strF = strF & strA & vbCrLf Loop Close #1 `Display file in rich text box rtfTest.Text = strF End Sub
這個範例與上個範例有幾點不同:第一,檔案開啟模式不是二進位檔案模式; 第二,程式中使用一個迴圈一次讀取一行資料,串接成一個字串,而非一次將資料全部讀入。
注意:
在Visual Basic 4以前,你必須自行建立機架返回和換行字元,現在Visual Basic已經提供了內建的常數vbCrLf,你可以在範例中看到。
最後附帶提醒一點,文字方塊控制項所能容納的字元數目大約是64000,較小的檔案如AUTOEXEC.BAT可以用文字方塊控制項來顯示,但筆者建議你用RichTextBox控制項,因為這個控制項使用起來較具彈性。
參考資料:
請參閱本章介紹的 "如何將大於64KB的文字放進文字方塊中?"
如何建立一個簡單的文字編輯器?
如果需要在你的應用程式中加上一個全功能的文字處理器視窗,請考慮使用OLE將一個Microsoft Word物件內嵌在你的程式中; 但如果你需要的只是像WordPad或「記事本」之類簡單的編輯器,那麼TextBox或RichTextBox控制項就應足敷所需了。讓我們用以下這個範例來介紹如何建立一個簡單的文字編輯器。
Option Explicit Private Sub cmdCut_Click() `Cut selected text to clipboard Dim strWork As String Dim Wstart, Wlength `Keep focus on rich text box rtfEdit.SetFocus `Get working parameters strWork = rtfEdit.Text Wstart = rtfEdit.SelStart Wlength = rtfEdit.SelLength `Copy cut text to clipboard Clipboard.SetText Mid$(strWork, Wstart + 1, Wlength) `Cut out text strWork = Left$(strWork, Wstart) + _ Mid$(strWork, Wstart + Wlength + 1) rtfEdit.Text = strWork `Position edit cursor rtfEdit.SelStart = Wstart End Sub Private Sub cmdCopy_Click() `Keep focus on edit box rtfEdit.SetFocus `Copy selected text to clipboard Clipboard.SetText rtfEdit.SelText End Sub Private Sub cmdPaste_Click() `Paste text from clipboard Dim strWork As String, strClip As String Dim Wstart, Wlength `Keep focus on rich text box rtfEdit.SetFocus `Get working parameters strWork = rtfEdit.Text Wstart = rtfEdit.SelStart Wlength = rtfEdit.SelLength `Cut out text, if any, and insert clipboard text strClip = Clipboard.GetText() strWork = Left$(strWork, Wstart) + strClip + _ Mid$(strWork, Wstart + Wlength + 1) rtfEdit.Text = strWork `Position edit cursor rtfEdit.SelStart = Wstart + Len(strClip) End Sub
圖21-2所顯示的是這個文字編輯器執行的情形。
圖21-2 以RichTextBox控制項建立的文字編輯器 |
在本例中,我們使用了一個RichTextBox控制項rtfEdit。首先設定RightMargin屬性值,以便使裡面的文字可以自動折行; 你可以在Form_Load事件程序中加入以下這一行程式碼,這樣,當使用者打字打到方塊邊緣時就會自動折行:
rtfEdit.RightMargin = rtfEdit.Width
接著,設定ScrallBar屬性為"2 - rtfVertical",使方塊可以垂直捲動。
表單上另外還有三個指令按鈕:cmdCut、cmdCopy和cmdPaste。你可以不用這三個指令按鈕因為─
、
─
和
─
在控制項裡就具備了剪下、複製和貼上的功能。程式中的這三個指令按鈕除了模仿這些動作之外,並且也增加了應用程式設計時的彈性。例如,你可能在表單上設計了一個「編輯」功能在主功能表中,這時候就可以把這些程式碼複製到功能表事件程序中,讓表單具有功能表導向的文字編輯功能。
32位元的RichTextBox控制項可接受較大量的資料輸入,支援OLE拖放功能,也支援格式化的本文,另外,RichTextBox控制項更支援了多重字型以及其他許多內嵌的RTF指令(請參閱線上說明)。可以說文字方塊控制項可以做的,它都可以做得更好。
RichTextBox控制項的確比一般的文字方塊制項在功能上強了許多,這樣有誰還會想使用一般文字方塊控制項呢?在32位元軟體的世界裡,文字方塊控制項主要是用來提供簡單的資料輸入功能,但在16位元軟體的世界裡,它卻是唯一的選擇──你必須用它來接收輸入的資料以及顯示檔案的內容。
參考資料:
第三十二章"資料庫" 中的Jot應用程式也使用了RichTextBox作為文字編輯器。
如何偵測被更動的本文?
Change事件是屬於文字方塊控制項和RichTextBox控制項的事件,但使用這個事件來判斷控制項中的本文是否被更動,會有一點小問題需要克服。當控制項所屬的表單被載入時,因預設的本文或初次設定的文字(在設計階段)會被載入控制項中的Text屬性中,因此即使本文未被更動,但是這個載入動作仍會驅動Change事件,這並不是我們所期待的"更動"。
以下這段程式利用兩個Boolean旗標解決了這個問題。在Change事件第一次被驅動時,blnNotFirstFlag變數被設成了True,到了第二次Change事件發生後,blnTextChangeFlag會變成True,這才是使用者第一次真正更動了控制項中本文的時候。由於blnTextChangeFlag變數的範圍涵蓋整個表單,因此,在Form_Unload事件程序中我們才能檢查這個變數的值。當使用者改變了控制項的本文時(blnTextChangeFlag的值為True)表單載出的動作就被中止了。
Option Explicit Private blnTextChangeFlag As Boolean Private Sub Form_Load() rtfEdit.Text = "Edit this stringDear John, How Do I... " blnTextChangeFlag = False End Sub Private Sub Form_Unload(Cancel As Integer) If blnTextChangeFlag = True Then Cancel = True MsgBox "Save changes first", 0, _ "(Testing the Change eventDear John, How Do I... )" End If End Sub Private Sub rtfEdit_Change() Static blnNotFirstFlag As Boolean blnTextChangeFlag = blnNotFirstFlag blnNotFirstFlag = True End Sub
如果要測試這個程式,請在表單中加入一個RichTextbox控制項,取名為rtfEdit。在程式執行時,更改方塊中的文字,然後嘗試關掉表單,看看程式有何反應。
如何將大於64KB的文字資料放進文字方塊控制項中?
在16位元的Visual Basic 4應用程式中,文字方塊控制項所能容納的資料量被限制在64KB以下(事實上,依照字串空間的使用情形,資料量上限可能只有32KB)。你可以把文字資料存放在陣列中,然後指定陣列中的元素給文字方塊控制項的Text屬性,這樣就能夠解決資料量限制的問題。在這種方法裡,陣列中個別元素的資料量限制是64KB,但由於陣列的長度可以很長,因此大量的資料仍然可以存放在陣列中,然後以文字方塊控制項顯示。
在以下的範例中,你所看到的文字方塊控制項雖然只能容納幾行文字,但事實上資料的來源卻是一個很大的動態字串陣列,其總資料量可以遠超過64KB。
圖21-3所顯示的是一個大約66800位元組的文字檔以文字方塊控制項顯示的情形。
圖21-3 以文字方塊控制項顯示一個資料量超過64KB的文字檔 |
要讓本範例能夠執行,請在一張新表單上加入一個文字方塊控制項txtTest和垂直捲軸控制項vsbTest。設定文字方塊的Multiline屬性為True,並設定其ScrollBar屬性為"1-水平捲軸"。垂直捲軸vsbTest用來取代文字方塊控制項內建的垂直捲軸,因此要把它移到文字方塊的右緣。最後,把程式碼加到表單中,把Open陳述式所開啟的檔案改為一個在磁碟中的檔案。
Option Explicit Private Const LINES = 15 Private strA() As String Private Sub Form_Load() Dim intN `Load dynamic string array from large text file Open "C:\WIN32API.TXT" For Input As #1 Len = 1024 Do Until EOF(1) intN = intN + 1 ReDim Preserve strA(intN + LINES) Line Input #1, strA(intN) Loop Close #1 `Set scrollbar properties With vsbTest .Min = 1 .Max = intN .SmallChange = 1 .LargeChange = intN \ 10 End With End Sub Private Sub vsbTest_Change() Dim intI As Integer Dim strTmp As String `Create display string from array elements For intI = vsbTest.Value To vsbTest.Value + LINES strTmp = strTmp + strA(intI) + vbCrLf Next intI txtTest.Text = strTmp End Sub
當表單載入時,整個文字檔被讀進了一個動態的字串陣列中,這個動作可能會花上幾秒鐘,因此在真正的應用程式裡,我們建議在載入檔案時同步進行其他的動作,避免使用者感到不耐煩。
一旦檔案載入了記憶體之後,字串陣列的維度就被用來設定垂直捲軸的屬性,而文字方塊的內容會跟隨著垂直捲軸值的改變而更新。在vsbTest_ Change事件程序中,我們把陣列中的文字一行一行地串接在一起,行與行之間用vbCrLf常數連接著。串接在一起的暫時字串,其內容就被指定給文字方塊控制項的Text屬性。
本範例只顯示檔案的內容,並不對使用者更動的文字作任何處理,如果要把這個範例變成一個文字編輯器,必須加上程式碼來更新變動後的字串陣列,才能讓使用者更動文字方塊中的內容。
如何讓使用者在文字方塊或RichTextBox中選用字型?
要讓使用者選擇字型,選用對話方塊控制項(CommonDialog Control)是最方便的工具。(它也可以讓使用者選擇檔案、顏色以及設定印表機等等)。要使用這個技巧,首先在表單中加入一個文字方塊控制項txtTest,一個指令按鈕控制項cmdFont和一個選用對話方塊dlgFonts,然後在表單中加入這段程式:
Option Explicit Private Sub cmdFont_Click() dlgFonts.Flags = cdlCFScreenFonts dlgFonts.ShowFont With txtTest.Font .Name = dlgFonts.FontName .Bold = dlgFonts.FontBold .Italic = dlgFonts.FontItalic .Size = dlgFonts.FontSize End With End Sub Private Sub Form_Load() txtTest.Text = "ABCDEF abcdef 0123456789" End Sub
Form_Load事件程序只是簡單地把樣本文字載入到文字方塊中,真正負責更改字型的是cmdFont_Click事件程序。我們首先設定選用對話方塊的Flag屬性,使得程式能顯示系統的螢幕字型(請參閱線上說明中其他的Flag值),然後用ShowFont方法叫出對話方塊,再根據使用者在選用對話方塊中的選項來設定文字方塊的字型屬性。
圖21-14和21-5顯示的是字型改變前和改變後的情形,圖21-6即是字型選擇對話方塊。
圖21-4 以預設的字型顯示文字方塊中的本文 |
圖21-5 以使用者選定的字型顯示文字方塊中的本文 |
圖21-6 「字型」對話方塊 |