寫在前面
這是PB案例學習筆記系列文章的第4篇,該系列文章適合具有一定PB基礎的讀者。
透過一個個由淺入深的程式設計實戰案例學習,提高程式設計技巧,以保證小夥伴們能應付公司的各種開發需求。
文章中設計到的原始碼,小凡都上傳到了gitee程式碼倉庫https://gitee.com/xiezhr/pb-project-example.git
需要原始碼的小夥伴們可以自行下載檢視,後續文章涉及到的案例程式碼也都會提交到這個倉庫【pb-project-example】
如果對小夥伴有所幫助,希望能給一個小星星⭐支援一下小凡。
一、小目標
學會使用MultiLineEdit
控制元件以及對檔案操作函式的使用,最終實現一個如下圖所示檔案瀏覽器功能。
二、建立程式的基本框架
① 建立工作區
② 建立應用
③ 建立視窗
以上步驟忘記的小夥伴,請參照第一篇文章,建立應用、視窗與控制元件
④ 建立控制元件
在視窗中建立一個SingleLineEdit
控制元件、一個MultiLineEdit
控制元件和CommandButton
控制元件,各個控制元件的名稱
依次為sle_1
、mle_1
和cb_1
⑤ 儲存視窗
將新建立的視窗儲存為w_main
三、設定各個控制元件的外觀及屬性
控制元件名稱 | 主要屬性 | 值 |
---|---|---|
w_main |
Title |
檔案瀏覽器 |
sle_1 |
Text |
(空) |
cb_1 |
Text 和Default |
開啟 | True |
mle_1 |
Text 和 VScrollBar |
(空)|True |
四、編寫程式碼
① 在按鈕cb_1
控制元件的Clicked
事件中新增如下程式碼
integer li_filenum,li_loops,li_i
long ll_flen,ll_bytes_read,ll_new_pos
string ls_part,ls_total,ls_filename
ls_filename = sle_1.text
if ls_filename = '' or isnull(ls_filename) then
messagebox('提示資訊','請輸入檔名')
return
end if
SetPointer(HourGlass!)
ll_flen = FileLength(ls_filename)
if ll_flen<=0 then
messagebox('提示資訊','無法開啟檔案')
return
end if
li_filenum = FileOpen(ls_filename,StreamMode!,Read!,LockRead!)
if ll_flen >32765 then
if mod(ll_flen,32765) = 0 then
li_loops =ll_flen/32765
else
li_loops = (ll_flen/32765) +1
end if
else
li_loops =1
end if
ll_new_pos =1
for li_i =1 to li_loops
ll_bytes_read = FileRead(li_filenum,ls_part)
ls_total +=ls_part
next
FileClose(li_filenum)
mle_1.text = ls_total
②在開發介面左邊雙擊App
應用物件,在App
的Open
事件中新增如下程式碼
open(w_main)
五、執行程式
我們在E:\workspace\2-PB\pbl\pb-project-example\04FileBrowser\dirtest
目錄下新建xiezhr.txt 檔案
執行程式,然後輸入xiezhr.txt全路徑,點選【開啟】按鈕便可讀出xiezhr.txt檔案內容
六、檔案操作函式
2.1 函式列表
函式名稱 | 描述 |
---|---|
CreateDirectory |
建立一個目錄 |
ChangeDirectory |
改變當前目錄 |
DirectoryExists |
判斷目錄是否存在 |
GetCurrentDirectory |
獲取當前目錄名 |
GetFileOpenName |
獲取開啟檔名 |
GetFileSaveName |
獲取儲存檔名 |
RemoveDirectory |
刪除目錄 |
FileExists |
判斷檔案是否存在 |
FileLength |
獲取檔案長度 |
FileOpen |
開啟檔案 |
FileClose |
關閉檔案 |
FileDelete |
刪除檔案 |
FileCopy |
複製檔案 |
FileMove |
移動檔案 |
FileSeek |
移動檔案指標 |
FileRead |
讀取檔案 |
FileWrite |
寫檔案 |
2.2 函式詳細說明
2.2.1 CreateDirectory 函式
① 語法
CreateDirectory (目錄名稱)
引數:
- 目錄名稱,可以是絕對路徑,如果是絕對路徑,如果是絕對路徑,則在該路徑下建立,否則在專案空間下建立
返回值:Integer
- 1 函式執行成功
- -1 函式執行錯誤。例如:目錄已存在,再呼叫該函式會返回-1
② 功能
建立目錄
注: 如果目錄存在會報錯,所以在建立目錄前一般會判斷該目錄是否存在,不存在再建立
2.2.2 ChangeDirectory 函式
① 語法
ChangeDirectory (目錄名稱)
返回值:Integer
- 1 函式執行成功
- -1 函式執行錯誤
② 功能
改變當前目錄
2.2.3 DirectoryExists 函式
① 語法
DirectoryExists(目錄名稱)
返回值:boolean
- 如果目錄存在,則返回true
- 如果目錄不存在,則返回false
- 引數不符合規範,則返回false
② 功能
判斷某個目錄是否存在
2.2.4 GetCurrentDirectory 函式
① 語法
GetCurrentDirectory ()
返回值:string
- 當前目錄字串
② 功能
獲取當前目錄名
2.2.5 GetFileOpenName 函式
① 語法
GetFileOpenName(title,pathname,filename{,extension{,filter}})
引數:
title
:string型別,指定對話方塊的標題pathname
:string型別變數,用於儲存該對話方塊返回的檔案路徑及檔名filename
:string型別變數,用於儲存該對話方塊返回的檔名extension
:string型別,可選項,使用1到3個字元指定預設的擴充套件檔名filter
:string型別,可選項,其值為檔名掩碼,指定顯示在該對話方塊的列表框中供使用者選擇的檔名滿
足的條件(比如.,.TXT,.EXE等)
返回值:Integer
- 執行成功時返回1
- 當使用者單擊了對話方塊上的“Cancel”按鈕時函式返回0
- 發生錯誤時返回-1
- 如果任何引數的值為NULL ,返回null
② 功能
顯示開啟檔案對話方塊,讓使用者選擇要開啟的檔案
③ 例子
li_Value = GetFileOpenName("開啟檔案", ls_DocName, ls_Named, "rtf", &
"Text Files (*.TXT),*.TXT,"&
+"Doc Files (*.DOC),*.DOC," &
+"rtf files (*.rtf),*.rtf," &
+"all files (*.*),*.*")
If li_Value = -1 Then //開啟檔案錯誤
Beep(2) //響鈴兩聲
MessageBox("提示","檔案開啟錯誤!",Exclamation!) //提示錯誤
Return //返回
Elseif li_Value = 0 Then //使用者取消
Return //直接返回
End If
2.2.6 GetFileSaveName 函式
① 語法
GetFileSaveName(title,pathname,filename{,extension{,filter}})
引數:
title
:string型別,指定對話方塊的標題pathname
:string型別變數,用於儲存該對話方塊返回的檔案路徑及檔名filename
:string型別變數,用於儲存該對話方塊返回的檔名extension
:string型別,可選項,使用1到3個字元指定預設的擴充套件檔名filter
:string型別,可選項,其值為檔名掩碼,指定顯示在該對話方塊的列表框中供使用者選擇的檔名滿
足的條件(比如.,.TXT,.EXE等)
返回值:Integer
- 執行成功時返回1
- 單擊了對話方塊上的“Cancel”按鈕時函式返回0
- 發生錯誤時返回-1
- 如果任何引數的值為NULL,那麼
GetFileSaveName()
函式返回NULL
② 功能
顯示儲存檔案對話方塊,讓使用者選擇要儲存到的檔案。
③ 例子
value = GetFileSaveName("儲存檔案", docname, named, "txt",&
"Text Files (*.TXT),*.TXT,")
If value <> 1 Then //要儲存的檔名沒有正確設定,
Beep(2)
MessageBox("錯誤","設定檔名"+docname+"錯誤!")
return
End If
2.2.7 RemoveDirectory 函式
① 語法
RemoveDirectory(directoryname)
引數:string
directoryname
: 要刪除的目錄名
返回值:Integer
- 1 函式執行成功
- -1 函式執行錯誤
② 功能
刪除目錄
2.2.8 FileExists 函式
① 語法
FileExists ( filename )
引數:string
filename
:指定要檢查存在性的檔案的檔名,其中可以包含路徑
返回值:Boolean
- 指定檔案存在時返回TRUE
- 指定檔案不存在時返回FALSE
- 執行失敗時,返回FALSE
- 引數為null,返回null
② 功能
判斷指定的檔案是否存在。
2.2.9 FileLength 函式
① 語法
FileLength ( filename )
引數:string
filename
:指定要得到其長度的檔案的檔名,其中可以包含路徑
返回值:Long
- 函式執行成功時返回指定檔案的長度(以位元組為單位)。
- 如果指定的檔案不存在,函式返回-1。
- 引數為null,則返回null
2.2.10 FileOpen 函式
① 語法
FileOpen(filename{,filemode{,fileaccess{,filelock{,writemode,
{creator,filetype}}}}})
-
filename:string型別,指定要開啟檔案的名稱,其中可以包含路徑
-
filemode:FileMode列舉型別,可選項,指定檔案開啟方式。有效取值為:(LineMode! - 預設值,行
模式)(StreamMode! - 流模式) -
fileaccess:FileAccess列舉型別,可選項,指定檔案訪問方式。有效取值為:(Read! - 預設值,只
讀方式,這樣開啟的檔案只能進行讀操作;)(Write! - 只寫方式,這樣開啟的檔案只能進行寫操作) -
filelock:FileLock列舉型別,可選項,指定檔案加鎖方式。有效取值為:
-
n LockReadWrite! - 預設值,只有開啟該檔案的使用者能夠訪問該檔案,其它用 戶對該檔案的訪問均被拒
絕; -
n LockRead! - 只有開啟該檔案的使用者能夠讀該檔案,但其它任何使用者均可寫該檔案;
-
n LockWrite! - 只有開啟該檔案的使用者能夠寫該檔案,但其它任何使用者均可讀該檔案
-
n Shared! - 所有使用者均可讀寫該檔案
-
-
writemode:WriteMode列舉型別,可選項,當fileaccess引數指定為Write!時,該引數指定在指定檔案
已經存在時資料的新增方式。
有效取值為:- Append! - 預設值,將資料新增到原檔案尾部;
- Replace! - 覆蓋原有資料
- creator:可選項,用於Macintosh機,使用四個字元的字串指定檔案的建立者。指定該引數後,必須同時
指定filetype引數 - filetype:可選項,用於Macintosh機,使用四個字元的字串指定檔案型別
返回值:Integer
- 執行成功時,返回1
- 執行失敗時,返回-1
- 引數為null時,返回null
② 功能
以指定的讀寫方式開啟指定的檔案,同時返回該檔案的控制代碼。
2.2.11 FileClose 函式
① 語法
FileClose ( fileno )
引數:integer
fileno
:指定要關閉檔案的檔案控制代碼,該控制代碼使用FileOpen()函式開啟檔案時得到
返回值:Integer
- 函式執行成功時返回開啟檔案的控制代碼 檔案操作函式利用該控制代碼完成對檔案的操作
- 發生錯誤時返回-1
- 如果fileno引數的值為NULL,那麼FileClose()函式返回NULL
② 功能
關閉先前用FileOpen()函式開啟的檔案。
2.2.12 FileDelete 函式
① 語法
FileDelete ( filename )
引數:string
filename
:指定要得到其長度的檔案的檔名,其中可以包含路徑
返回值:Boolean
- 函式執行成功時返回TRUE
- 發生錯誤時返回FALSE
- 如果filename引數的值為NULL,那麼FileDelete()函式返回NULL。
② 功能
刪除指定的檔案
2.2.13 FileCopy 函式
① 語法
FileCopy ( Sourcefile, Targetfile{, replace } )
引數:
Sourcefile
:要複製的檔案的名稱的字串Targetfile
: 複製到的檔案的名稱的字串replace
:指定是否替換目標檔案的布林值(true),為true時替換目標檔案,為false時不替換(預設值為false)
返回值:Integer
- 執行成功返回1
- 開啟原始檔出錯-1
- 寫入目標檔案出錯 -2
注:如果沒有為 原始檔 或 目標檔案 指定完全限定的路徑,則該函式將相對於當前目錄工作。如果沒有指定replace引數,則FileCopy函式不會替換目標目錄中與在targetfile引數中指定的名稱相同的檔案(這相當於將replace值設定為false)。
② 功能
複製檔案
③ 例子
將檔案從當前目錄複製到另一個目錄,並將返回值儲存在一個變數中
integer li_FileNum
li_FileNum = FileCopy ("jazz.gif" , &
"C:\emusic\jazz.gif", FALSE)
2.2.14 FileMove 函式
① 語法
FileMove ( Sourcefile,Targetfile)
引數:
Sourcefile
:要移動的檔案的名稱的字串Targetfile
:要移動檔案的位置的名稱的字串
返回值:
- 執行成功 1
- 開啟原始檔出錯 -1
- 寫入目標檔案出錯 -2
注:如果目標目錄中已經存在同名檔案,則無法寫入目標檔案。如果要複製目標檔案,可以使用FileCopy並將replace引數設定為true。
② 功能
將當前檔案移動到另一目錄
③ 例子
將檔案從當前目錄移動到另一個目錄,並將返回值儲存在li_FileNum變數中
integer li_FileNum
li_FileNum = FileMove ("xiezhr.csv", &
"D:/project/xiezhr2024.csv" )
2.2.15 FileSeek函式
① 語法
FileSeek ( fileno, position, origin )
引數:
fileno
:integer型別,指定檔案控制代碼(由FileOpen()函式得到)position
:long型別,指定相對於origin引數指定位置的新位置偏移量,以位元組為單位origin
:SeekType
列舉型別,指定從哪裡開始移動檔案指標,即指標移動的基準。有效取值為:FromBeginning!
- 預設值,從檔案開頭移動指標;FromCurrent!
- 從當前位置移動檔案指標;FromEnd!
- 從檔案結尾處移動檔案指標
返回值:Long
- 函式執行成功時返回指標移動後的指標位置
- 引數為null,則返回null
② 功能
將檔案指標移動到指定位置。讀寫檔案時相應函式會自動移動檔案指標。
2.2.16 FileRead 函式
① 語法
FileRead ( fileno, variable )
引數:
fileno
:integer型別,指定檔案控制代碼(由FileOpen()函式得到)variable
:string或blob型別的變數,用於儲存讀取的資料
返回值:Integer
- 函式執行成功時返回讀取的字元數或位元組數
- 如果在讀取任何字元前讀到了檔案結束符(EOF),則FileRead()函式返回-100
- 指定檔案以行模式開啟時,如果在讀取任何字元之前遇到了回車(CR)或換行(LF)字元,則FileRead()
函式返回0 - 執行錯誤,函式返回-1
② 功能
從指定檔案中讀取資料
2.2.17 FileWrite 函式
① 語法
FileWrite (fileno , variable )
引數:
fileno
:integer型別,指定檔案控制代碼(由FileOpen()
函式得到)variable
:string或blob型別,其值將寫入fileno
引數指定的檔案
返回值:Integer
- 執行成功時返回寫入檔案的字元或位元組數
- 發生錯誤時返回-1
- 任何引數的值為NULL 函式返回NULL
② 功能
向指定檔案中寫資料。
七、MultiLineEdit 控制元件
3.1 常用屬性
屬性 | 描述 |
---|---|
Visible |
預設為 True。當為 False 時,該控制元件在視窗上隱藏 |
Enabled |
預設為 True。當為 False 時,該控制元件不能獲得焦點,使用者不能進行編輯和選 中;控制元件背景為灰色 |
DisplayOnly |
預設為 False。當為 True 時,該控制元件中的文字不能被修改,並且也不能 輸入,但可以選中、複製 |
AutoHScroll |
預設為 True,表示當使用者輸入的內容顯示不下時,可以自動橫向滾動 游標,但是不顯示捲軸 |
HideSelection |
預設為 True,表示只有當單行編輯器獲得焦點時,才高亮顯示選中文 本。建議使用預設值,因為將該屬性設定為 False,沒有獲得焦點時,選中的內容就高亮顯示, 這容易讓使用者造成錯誤 |
RightToLeft |
|
Border |
是否顯示邊框,預設為 True |
Case |
有三個選項, upper 表示使用者輸入的內容中的字母都自動轉換成大寫, down 表示都自動轉換成小寫, any 表示不做轉換 |
Limit |
預設是 0,表示沒有長度限制。可以輸入其他一個數字,表示該單行編輯框中 最多接受使用者輸入的字元個數,最大數字是 32 767 |
HscrollBar |
是否顯示橫向捲軸,預設為 False。當該屬性為 True 時,顯示橫向滾 動條, 某行文字的寬度大於控制元件的寬度, 則捲軸可用, 否則灰色顯示不可用。 當屬性為 False 時,輸入的文字大於控制元件寬度,則自動換行 |
VscrollBar |
是否顯示縱向捲軸,預設為 False。當該屬性為 True 時,顯示縱向滾 動條, 如果文字的高度大於控制元件的高度, 則捲軸可用, 否則灰色顯示不可用。 當屬性為 False 時,輸入的文字大於控制元件高度時,就不允許再增加新的資料行 |
AutoVScroll |
是否在需要時自動顯示縱向捲軸,預設為 False。如果設定為 True, 在當前內容顯示滿控制元件時,增加新的資料行將會出現縱向捲軸 |
IgnoreDefaultButton |
是否忽略 Enter 鍵,預設為 False。如果屬性為 True 並且當前焦 點在多行編輯器中, 這時使用 Enter 鍵則會在多行編輯器中增加一個新行; 如果屬性為 False, 則會觸發視窗上“ Default”按鈕的 Clicked 事件 |
Alignment |
文字的對齊方式,是一個列舉型取值,有 Center!、 Justify!、 Left!、 Right!4 個取值,預設為 Left!。 |
3.2 事件和指令碼
多行編輯器提供了 12 個預設事件,觸發時機和單行編輯器的 12 個事件完全相同 (忘記的小夥伴可以翻一翻前面文章的內容)經常
使用的事件也是 Modified
多行編輯器也提供了很多的函式,和單行編輯器的同名函式的用法及注意事項完全相同,需要注意的是兩個單行編輯器沒有的函式 LineCount
和 LineLength
。這兩個函式經常配合使用,對多行編輯器中的文字逐個字元處理
① LineCount 函式
獲取editname 中資料的實際行數,不管每行後面是否有回車或換行符號
返回值:Integer
- 執行成功,返回正確行數
- 執行錯誤返回-1
editname
為 Null,則返回 Null
② LineLength 函式
可以獲取 editname 中當前游標所在行,包括空格在內的字元數,
返回值:Integer
- 正確執行,返回游標所在行字元數
- 執行錯誤,返回-1
- 當 editname 為 Null 時返回 Null
本期內容到這兒就結束了,希望對你有所幫助。
我們下期再見 ヾ(•ω•`)o (●'◡'●)