Double Commander

2.15. Lua 腳本

內容

1. 介紹
2. 所需 DLL
3. Double Commander 函數庫
3.1. DC 庫
3.1.1. DC.ExecuteCommand 使用示例
3.2. 系統庫
3.2.1. SysUtils.FileGetAttr 返回值詳情
3.2.2. SysUtils.FileGetAttr 使用示例
3.2.3. 使用 FindFirst、FindNext 和 FindClose 的示例
3.3. 剪貼板庫
3.3.1. 剪貼板庫使用示例
3.4. 對話框庫
3.4.1. Dialogs.MessageBox 中顯示的按鈕
3.4.2. Dialogs.MessageBox 的窗口樣式
3.4.3. Dialogs.MessageBox 的默認活動按鈕
3.4.4. Dialogs.MessageBox 的返回值
3.4.5. Dialogs.MessageBox 使用示例
3.4.6. Dialogs.InputQuery 使用示例
3.5. UTF-8 庫
3.6. 字符庫
3.7. 操作系統庫
4. 索引

1. 介紹

有關 Lua 腳本程式語言的詳細資訊,請造訪 Lua 網站

Double Commander 可以透過 cm_ExecuteScript 命令執行 Lua 腳本。
腳本參數必須按原樣傳遞,無需跳脫(無需引號或「\」),為此我們需要使用 %"0 變數:例如,對於游標下的檔案使用 %"0%p0 而不是 %p0,對於目前目錄使用 %"0%D 而不是 %D。否則,如果 Double Commander 自動新增引號,它們將作為參數的一部分傳遞,您將不得不考慮這一點。
要取得所有選定檔案的清單,我們可以使用 變數%LU%FU%RU)或內部命令(cm_SaveSelectionToFilecm_SaveFileDetailsToFilecm_CopyFullNamesToClipcm_CopyFileDetailsToClip)。 例如,我們可以使用 %p:在這種情況下,Double Commander 將在一行中傳遞所有選定檔案的名稱,用空格分隔名稱。

也可以使用 Lua 腳本編寫內容外掛,範例可以在程式資料夾中找到(plugins/wdx/scripts)。 Wiki 上有一個專門用於編寫外掛的頁面。 限制:僅支援以下資料類型

上面的清單包含標頭檔中的名稱,在 Lua 腳本中我們必須使用括號中指定的數值。


關於文字編碼

下面描述的所有附加函數都接受 UTF-8 編碼的字串參數並傳回此編碼的字串(LazUtf8.ConvertEncoding 函數除外)。

一些標準 Lua 函式庫中的函數已被 Double Commander 或 Free Pascal/Lazarus 的函數取代(或編寫了新函數),這提供了 UTF-8 支援。

編寫外掛時,我們也應該對文字資料使用 UTF-8(ft_multiplechoiceft_stringft_fulltext)。

儲存腳本時,請使用不帶 BOM 的 UTF-8 編碼。


注意事項

使用 Lua 進行自動化具有很大的可能性,但在某些情況下可能需要注意一些細節。讓我們嘗試在本小節中收集這些內容。

1. 如果啟用了自動重新整理在單獨執行緒中載入檔案清單選項,重新整理功能將非同步工作。同時,腳本在 Double Commander 的主執行緒中執行,因此在某些情況下,所有這些都可能影響您的腳本執行。例如,有時連續執行導航命令可能不起作用(例如,大目錄、慢速磁碟),在這種情況下,請嘗試停用在單獨執行緒中載入檔案清單或尋找替代解決方案。

如果您的腳本在目前面板中建立新檔案或重新命名現有檔案,但隨後未完成並執行一些附加操作(例如,選擇檔案或移動游標),則在某些情況下這些操作將不會生效:並非所有檔案都可能已在面板中,您需要首先呼叫cm_Refresh命令。在所述條件下,cm_Refresh也將非同步執行,Double Commander 可能沒有時間在您的變更後完全重新整理檔案清單。

自動重新整理和在單獨執行緒中載入檔案清單是檔案管理器的便捷功能,因此透過實驗找到了穩定的工作方法,即暫時將控制權返回給程式並允許檔案清單完全重新整理:

DC.ExecuteCommand("cm_Refresh")
i = 10
while i > 0 do
  SysUtils.Sleep(10)
  DC.ExecuteCommand("")
  i = i - 1
end

2. Lua 函數 io.open 使用標準 C 函數 fopen:在文字模式下,此函數在讀取和寫入時可以轉換行尾類型(CRLF、LF 或 CR),這可能導致意外結果。如果您遇到具有不同行尾類型的檔案或正在編寫跨平台腳本,則必須考慮這一點,或者更實際的做法是優先使用二進位模式。

3. 在 Linux 和其他類 Unix 作業系統中,對於檔案屬性對話方塊,呼叫 ContentGetValue 函數時帶有 CONTENT_DELAYIFSLOW 標誌(第四個參數,值為 1),這避免了開啟視窗時的延遲:如果資料檢索緩慢,我們可以透過簡單地新增標誌值檢查並為這些欄位或外掛傳回 nil 來排除這些資料。

4. 如果外掛應該傳回空字串,則傳遞 nil 比傳遞 "" 更快。

2. 所需 DLL

為了能夠解釋 Lua 腳本檔案,我們需要一個 Lua DLL 檔案,Double Commander 支援 5.1 - 5.4 版本。

我們可以使用來自 LuaJIT 專案 的 DLL 檔案。LuaJIT 結合了一個用組合語言編寫的高速直譯器和一個先進的 JIT 編譯器。此外,我們還獲得了 FFI 函式庫,它允許從純 Lua 程式碼中呼叫外部 C 函數和使用 C 資料結構。

Windows 版本的 DC 預設包含 Lua DLL(在 DC 0.9.7 及更高版本中來自 LuaJIT 專案),在其他情況下,我們可以透過套件管理員尋找和安裝它,或者自行編譯。如果我們使用的是 64 位版本的 DC,則 DLL 也必須是 64 位版本。

預設情況下,DC 會在其目錄和系統目錄中尋找名為 lua5.1.dll(Windows)、liblua5.1.so.0(Unix 或 GNU/Linux)或 liblua5.1.dylib(macOS)的檔案。我們可以在 要使用的 Lua 函式庫檔案 參數中變更檔名(和路徑)。

3. Double Commander 函數庫

Double Commander 為我們的 Lua 腳本提供了一些函數庫。

以下是這些函式庫的清單。

函式庫清單
函式庫名稱腳本名稱簡要描述
DCDouble Commander 特定函數
SysUtils各種系統函數
Clipbrd提供外部剪貼簿功能
Dialogs與使用者互動
LazUtf8UTF-8 字串函數
Char取得字元資訊
os與作業系統相關的函數

3.1. DC 函式庫

該函式庫包含 Double Commander 特定的函數。

它在 DC 表中提供了所有函數。

DC 函式庫
函數名稱描述

DC.LogWrite(sMessage, iMsgType, bForce, bLogFile)

向日誌視窗寫入訊息:

  • sMessage : 訊息文字。
  • iMsgType : 訊息類型:0 - 資訊,1 - 成功,2 - 錯誤。
  • bForce : 布林值,如果為 true,則在日誌視窗不可見時會顯示它。
  • bLogFile : 布林值,如果為 true,則也會將訊息寫入日誌檔案。

iPanel = DC.CurrentPanel()

取得活動面板:如果左側面板處於活動狀態則傳回 0,否則傳回 1。

DC.CurrentPanel(iPanel)

設定活動面板:iPanel 等於 0 時為左側面板,等於 1 時為右側面板。

DC.ExecuteCommand(sCommand, Param1, Param2,...,ParamX)

這允許腳本呼叫 Double Commander 的 內部命令

sCommand 是實際的內部命令名稱。

我們可以提供命令支援的任意數量的 Param... 參數。

除了內部命令之外,在腳本中我們還可以使用特殊命令 cm_ExecuteToolBarItem,該命令允許透過識別碼呼叫工具列按鈕(在程式中,此功能提供了為工具列按鈕使用快速鍵的功能)。該命令的使用方式與普通內部命令類似(見下面的範例),並且具有以下參數:

參數 描述
ToolBarID TfrmOptionsToolbar 主工具列的按鈕
TfrmOptionsToolbarMiddle 中間工具列的按鈕
(不存在) 主工具列的按鈕
ToolItemID 識別碼 按鈕的唯一識別碼

唯一識別碼儲存在 ID 標籤中,我們有幾種方式可以取得它:可以在 doublecmd.xml 檔案、工具列備份檔案中找到按鈕,或者簡單地將按鈕複製到剪貼簿並在文字編輯器中貼上其程式碼。

注意:識別碼是自動產生的,不必與程式另一個副本中的類似按鈕的識別碼相符,但如有必要,我們可以手動設定自己的值。

3.1.1. 使用 DC.ExecuteCommand 的範例

在這個範例中,我們編寫了一個簡單的腳本,它將執行以下操作:

  1. 聚焦到右側面板
  2. 關閉所有打開的標籤頁
  3. 切換到特定資料夾
  4. 聚焦到左側面板
  5. 關閉所有打開的標籤頁
  6. 切換到特定資料夾
  7. 打開新標籤頁
  8. 切換到特定資料夾
-- 1. 聚焦到右側面板。
DC.ExecuteCommand("cm_FocusSwap", "side=right")

-- 2. 關閉所有標籤頁。
DC.ExecuteCommand("cm_CloseAllTabs")

-- 3. 切換到特定目錄。
DC.ExecuteCommand("cm_ChangeDir", "E:\\FakeKey\\Documents\\Music")

-- 4. 聚焦到左側面板。
DC.ExecuteCommand("cm_FocusSwap", "side=left")

-- 5. 關閉所有標籤頁。
DC.ExecuteCommand("cm_CloseAllTabs")

-- 6. 切換到特定目錄。
DC.ExecuteCommand("cm_ChangeDir", "C:\\Users\\Public\\Music")

-- 7. 打開新標籤頁。
DC.ExecuteCommand("cm_NewTab")

-- 8. 切換到特定目錄。
DC.ExecuteCommand("cm_ChangeDir", "E:\\VirtualMachines\\ShareFolder")

使用內部命令 cm_ExecuteScript,我們可以配置一個工具欄按鈕來執行我們的腳本。

假設此腳本文件是 E:\scripts\lua\music.lua,我們可以這樣配置按鈕:

從工具欄調用 Lua 腳本

此外,我們還可以使用 Double Commander 內部編輯器來編輯腳本。如果文件名具有 .lua 擴展名,內部編輯器將識別它並提供針對 Lua 語言的語法高亮顯示:

使用內部編輯器進行 Lua 語法高亮顯示

3.2. 系統庫

該庫包含各種系統函數。

它在 SysUtils 表中提供了所有函數。

系統庫
函數名稱描述

SysUtils.Sleep(iMilliseconds)

暫停腳本執行指定的毫秒數 iMilliseconds
指定的時間過後,腳本執行將繼續。

SysUtils.GetTickCount()

返回一個遞增的時鐘滴答計數。它可用於時間測量,但不應假設滴答之間的間隔。

bExists = SysUtils.FileExists(sFileName)

檢查檔案系統中是否存在特定檔案。

如果磁碟上存在名為 sFileName 的檔案,則在 bExists 中返回值 true,否則返回 false

bExists = SysUtils.DirectoryExists(sDirectory)

檢查 sDirectory 是否存在於檔案系統中且確實是一個目錄。

如果是這樣,函數將在 bExists 中返回值 true,否則返回 false

iAttr = SysUtils.FileGetAttr(sFileName)

iAttr 中返回檔案 sFileName 的屬性設定。

有關返回值的詳細說明,請參見此處

Handle, FindData = SysUtils.FindFirst(sPath)

查找與 sPath 匹配的檔案,通常使用萬用字元。

如果未找到檔案,Handle 將為 nil

當至少找到一個項目時,返回的 Handle 可用於後續的 SysUtils.FindNext 呼叫以查找相同模式的其他匹配項。

FindData 表包含找到的檔案或目錄的資訊。

FindData 表的欄位如下:

  • Name : 檔案名(不包括路徑)。
  • Attr : 檔案的屬性(詳細資訊請參見此處)。
  • Size : 檔案大小(以位元組為單位)。
  • Time : 檔案的時間戳(自 1970 年 1 月 1 日以來的秒數)。

Result, FindData = SysUtils.FindNext(Handle)

通過重用先前返回的 Handle,查找由 FindFirst 發起的搜尋序列的下一個匹配項。

如果找到檔案或目錄,返回的 Result 將非空,否則為 nil

SysUtils.FindFirst 相同的注意事項也適用於此處。

備註:最後一次 SysUtils.FindNext 呼叫必須始終跟隨一個使用相同 HandleSysUtils.FindClose 呼叫。否則將導致記憶體洩漏。

SysUtils.FindClose(Handle)

結束一系列 SysUtils.FindFirst/SysUtils.FindNext 呼叫。

釋放這些呼叫使用的任何記憶體。

絕對有必要進行此呼叫,否則可能導致記憶體洩漏。

bResult = SysUtils.CreateDirectory(sDirectory)

創建一系列目錄,sDirectory 是目錄的完整路徑。

如果 sDirectory 已存在或成功創建,則返回 true。如果創建任何部分失敗,則返回 false

bResult = SysUtils.CreateHardLink(sFileName, sLinkName)

為檔案 sFileName 創建硬連結 sLinkName

如果成功則返回 true,否則返回 false

bResult = SysUtils.CreateSymbolicLink(sFileName, sLinkName)

為檔案或目錄 sFileName 創建符號連結 sLinkName

如果成功則返回 true,否則返回 false

sTarget = SysUtils.ReadSymbolicLink(sLinkName, bRecursive)

讀取符號連結 sLinkName 的目標。

如果 bRecursivetrue 且連結指向另一個連結,則遞迴解析直到找到一個有效的非連結檔名。

返回符號連結 sLinkName 指向的路徑,或者在連結無效或指向的檔案不存在且 bRecursivetrue 時返回空字串。

sName = SysUtils.ExtractFileName(sFileName)

從完整路徑的檔名中提取檔名部分。

檔名由最後一個目錄分隔符字元(「/」或「\」)或驅動器字母後的所有字元組成。

sExt = SysUtils.ExtractFileExt(sFileName)

返回檔名的副檔名(最後一個「.」(點)後的所有字元,包括「.」字元)。

sPath = SysUtils.ExtractFilePath(sFileName)

從檔名中提取路徑(包括驅動器字母)。

路徑由最後一個目錄分隔符字元(「/」或「\」)前的所有字元組成,包括目錄分隔符本身。

sDir = SysUtils.ExtractFileDir(sFileName)

僅提取 sFileName 的目錄部分,包括驅動器字母。

目錄名沒有結尾的目錄分隔符,這與 SysUtils.ExtractFilePath 不同。

sDrive = SysUtils.ExtractFileDrive(sFileName)

從檔名中提取驅動器部分。

請注意,某些作業系統不支援驅動器字母。

sName = SysUtils.GetAbsolutePath(sFileName, sBaseDirectory)

返回檔案的絕對(完整)路徑:

  • sFileName : 帶有相對路徑的檔名。
  • sBaseDirectory : 用作 sFileName 基礎目錄的目錄。

如果無法獲取絕對路徑,函數將返回 sFileName 的值。

sName = SysUtils.GetRelativePath(sFileName, sBaseDirectory)

返回相對於指定目錄的檔名:

  • sFileName : 完整(絕對)檔名。
  • sBaseDirectory : 將用作 sFileName 基礎目錄的目錄。

如果 sFileNamesBaseDirectory 包含相同的值,函數將返回空字串("")。如果無法獲取帶有相對路徑的檔名,函數將返回 sFileName 的值。

bResult = SysUtils.MatchesMask(sFileName, sMask, iMaskOptions)

如果 sFileName 與傳遞的遮罩 sMask 匹配,則返回 true

iMaskOptions(可選參數,預設為 0)設置為以下值的總和:

描述
1
區分大小寫
2
忽略重音符號和連字
4
Windows 風格過濾器:「*.*」也匹配沒有副檔名的檔案等。
8
啟用拼音支援(將使用檔案 pinyin.tbl

bResult = SysUtils.MatchesMaskList(sFileName, sMaskList, sSeparator, iMaskOptions)

如果 sFileName 與由 sSeparator(預設為「;」)分隔的傳遞遮罩 sMaskList 中的至少一個匹配,則返回 true

sSeparatoriMaskOptions(見上文)是可選參數。

sTempFileName = SysUtils.GetTempName()

將返回一個用作臨時檔名的檔名(在系統臨時檔案目錄中),類似於 os.tmpname 函數,但檔案將在 Double Commander 關閉時自動刪除的子目錄中創建。
如果函數無法創建唯一名稱,它將返回空字串。

SysUtils.PathDelim

當前作業系統用於分隔完整檔名中目錄名的字元。

在 Unix/Linux 系統中,目錄分隔符將是「/」,在 Windows 中將是「\」。

3.2.1. SysUtils.FileGetAttr 回傳值詳情

FileGetAttr 回傳檔案 sFileName 的屬性設定。

屬性是以下常數的 OR 組合:

SysUtils.FileGetAttr 回傳值中使用的常數
含義
0x00000001
faReadOnly
檔案是唯讀的。
0x00000002
faHidden
檔案是隱藏的。
在 Unix/Linux 中,這表示檔名以點開頭。
0x00000004
faSysFile
檔案是系統檔案。
在 Unix/Linux 中,這表示檔案是字元或區塊裝置,命名管道 (FIFO)。
0x00000008
faVolumeId
磁碟區標籤。
僅適用於 DOS/Windows 上的普通 FAT(非 VFAT 或 FAT32)檔案系統。
0x00000010
faDirectory
檔案是一個目錄。
0x00000020
faArchive
檔案已歸檔。
在 Unix/Linux 中不可能。
0x00000400
faSymLink
檔案是一個符號連結。
注意:如果出現錯誤,將回傳 -1。

請參見下一節中的範例。

3.2.2. SysUtils.FileGetAttr 使用範例

以下腳本是 SysUtils.FileGetAttr 用法的一個範例。

當偵測到參數是目錄時,它將在活動面板中開啟一個新標籤頁並切換到該目錄。

local params = {...}
local iAttr

if #params == 1 then -- 我們至少得到了一個參數?
  iAttr = SysUtils.FileGetAttr(params[1])
  if iAttr > 0 then -- 我們得到了一個有效的屬性?
    if math.floor(iAttr / 0x00000010) % 2 ~= 0 then
      -- 第4位被設定?所以它是一個目錄。
      DC.ExecuteCommand("cm_NewTab")
      DC.ExecuteCommand("cm_ChangeDir", params[1])
    end
  end
end

在上面的例子中,params[1] 是傳遞給腳本的第一個參數。

當使用內部命令 cm_ExecuteScript 時,它將是腳本檔名後傳遞的第一個參數。

因此,在我們的範例中,我們可以像下面這樣設定一個工具列按鈕:

使用 cm_ExecuteScript 的參數

在這個例子中,參數 %"0%p 將被傳遞給腳本。這將代表未加引號的目前活動面板中選取項目的檔名。

3.2.3. 使用 FindFirst、FindNext 和 FindClose 的範例

在以下腳本範例中,我們將掃描參數中接收的目錄內容,並將結果資料儲存到以第二個參數傳遞的檔名的文字檔中。

這將讓我們很好地了解 FindFirstFindNextFindClose 的用法。

local params = {...}

if #params == 2 then -- 我們得到了兩個參數?
  local Result = nil
  local hOutputFile = nil

  hOutputFile = io.output(params[2])

  local Handle, FindData = SysUtils.FindFirst(params[1] .. "\\*")
  if Handle ~= nil then
    repeat
      io.write(FindData.Name .. "\r")
      io.write(FindData.Size .. "\r")
      io.write("---------------\r")

      Result, FindData = SysUtils.FindNext(Handle)
    until Result == nil

    SysUtils.FindClose(Handle)
    io.close(hOutputFile)
  end
end

在上面的例子中,我們需要向腳本傳遞兩個參數:

  1. params[1] - 我們想要內容的目錄
  2. params[2] - 用於儲存結果的輸出檔名

因此,使用內部命令 cm_ExecuteScript 設定工具列按鈕並傳遞參數來完成這一切都是很容易的。

使用 cm_ExecuteScript 的參數

在這個例子中,參數 %"0%Ds 將作為第一個參數傳遞給腳本。這將代表未加引號的活動面板顯示的目錄。

3.3. 剪貼簿庫

Double Commander 可以為我們的 Lua 腳本提供外部剪貼簿功能。

下表給出了相關的函數:

剪貼簿庫
函數名描述

Clipbrd.Clear()

清除剪貼簿的內容。

sVar = Clipbrd.GetAsText()

取得剪貼簿的目前文字內容並將其分配給 sVar。如果剪貼簿不包含文字,函數將回傳一個空字串。

Clipbrd.SetAsText(sVar)

在剪貼簿中儲存 sVar 的文字內容。

Clipbrd.SetAsHtml(sHtml)

將 html 格式的文字 sHtml 加入到剪貼簿 (CF_HTML 剪貼簿格式)。

這些內容將被插入到支援此剪貼簿格式的應用程式中,如 MS Word、LO Writer 等。

使用 Clipbrd.SetAsTextClipbrd.SetAsHtml 儲存資料都是正確的。當我們貼上時,應用程式將使用它支援的最佳格式。

例如,我們可能有以下內容:

  • Clipbrd.SetAsText("歡迎使用 Double Commander!")
  • Clipbrd.SetAsHtml("歡迎使用 <b>Double Commander</b>!")

如果我們切換到記事本嘗試貼上某些內容,它將以純文字形式貼上我們用 Clipbrd.SetAsText 複製的訊息。但如果我們切換到 Microsoft Word 並貼上某些內容,它將貼上第二個,即 Double Commander 以粗體顯示的那個,因為 Microsoft Word 識別並支援該剪貼簿內容類型。

3.3.1. 剪貼簿庫使用範例

以下範例使用了與剪貼簿相關的三個函數:ClearGetAsTextSetAsText

這是一個相對較長的腳本,但它很好地將上面看到的一些函數組合在一起。

它假設我們的活動面板目前位於一個包含許多原始文字檔的目錄中。

它還假設我們目前在剪貼簿中有一個單字,並且它將接收目前活動資料夾作為單一參數。

腳本將掃描目前目錄層級的檔案,並逐一讀取它們的內容,以偵測包含剪貼簿中單字的文字行。

然後,包含至少一行該單字的檔名將被放置到剪貼簿中。

然後,腳本將使用內部命令 cm_LoadSelectionFromClip,包含該單字的檔案將被選取。

此外,在最後,我們將把需要搜尋的原始單字放回剪貼簿中。

local params = {...}
local Result = nil
local iAttr
local bFound = false
local sCompleteFilename = ""
local hInputFile = nil
local sLine = ""
local iPosS
local iPosE
local sFileToSelect = ""
local sSearchString = ""

if #params == 1 then -- 我們得到了參數?
  sSearchString = Clipbrd.GetAsText() -- 取得要搜尋的表示式。
  Clipbrd.Clear() -- 確保剪貼簿中沒有任何內容。
  DC.ExecuteCommand("cm_MarkUnmarkAll") -- 確保沒有選取任何內容。

  -- 讓我們逐一掃描目錄中的所有檔案。
  local Handle, FindData = SysUtils.FindFirst(params[1] .. "\\*")
  if Handle ~= nil then
    repeat
      sCompleteFilename = params[1] .. "\\" .. FindData.Name
      iAttr = SysUtils.FileGetAttr(sCompleteFilename)
      if iAttr > 0 then -- 我們得到了一個有效的屬性?
        -- 我們需要檔案,而不是目錄!
        if math.floor(iAttr / 0x00000010) % 2 == 0 then

          -- 現在讓我們逐行讀取檔案,直到結束或找到。
          hInputFile = io.open(sCompleteFilename, "r")
          bFound = false

          while bFound == false do
            sLine = hInputFile:read()
            if sLine == nil then break end
            iPosS, iPosE = string.find(sLine, sSearchString)
            if iPosS ~= nil then bFound = true end
          end

          if bFound == true then
            sFileToSelect = sFileToSelect .. FindData.Name .. "\n"
          end

          io.close(hInputFile)
        end
      end
      Result, FindData = SysUtils.FindNext(Handle)
    until Result == nil

    SysUtils.FindClose(Handle)
  end

  -- 如果我們找到了什麼,就選取它!
  if sFileToSelect ~= "" then
    Clipbrd.SetAsText(sFileToSelect)
    DC.ExecuteCommand("cm_LoadSelectionFromClip")
  end

  Clipbrd.SetAsText(sSearchString) -- 恢復我們在剪貼簿中的內容。
end

3.4. 對話方塊函式庫

該函式庫允許我們的腳本與使用者互動,顯示訊息、提示輸入答案等。

下表列出了相關函數:

對話方塊函式庫
函數名稱描述

iButton = Dialogs.MessageBox(sMessage, sTitle, iFlags)

顯示一個訊息方塊,提示使用者點擊一個按鈕,該按鈕將由函數返回:

  • sMessage:訊息方塊中的文字。
  • sTitle:訊息方塊的標題。
  • iFlags:常數的位元或值,用於確定顯示的按鈕、視窗樣式和預設按鈕。請參閱下表了解顯示的按鈕視窗樣式預設按鈕
  • iButton:返回值,表示使用者按下的按鈕(請參閱此表)。

bResult, sAnswer = Dialogs.InputQuery(sTitle, sMessage, bMask, sDefault)

顯示一個請求方塊,使用者可以在其中輸入字串:

  • sTitle:請求方塊的標題。
  • sMessage:請求方塊中的文字。
  • bMask:布林值,為 true 時將顯示「星號」以隱藏字元。
  • sDefault:預設建議文字,使用者可根據需要進行修改。
  • bResult:返回布林值,表示使用者是否實際輸入了內容。
  • sAnswer:返回字串,當使用者輸入內容並點擊確定後返回。

sItem, iItem = Dialogs.InputListBox(sTitle, sMessage, aItems, sDefault)

顯示一個對話方塊,允許使用者從項目清單中選擇:

  • sTitle:對話方塊的標題。
  • sMessage:對話方塊中的文字。
  • aItems:一個 Lua 表,表中的每個元素必須是一個字串。
  • sDefault:清單中預設選取的項目。
  • sItem:返回選取的項目作為字串,如果對話方塊被取消則返回 nil
  • iItem:選取項目的索引(從 1 開始計數,符合 Lua 表的習慣)。

3.4.1. Dialogs.MessageBox 中顯示的按鈕

Dialogs.MessageBox 函數顯示的按鈕由以下常數的位元或值控制:

Dialogs.MessageBox 顯示按鈕的 ButFlags 常數
常數值顯示的按鈕,從左到右
0x0000
MB_OK
按鈕 OK
0x0001
MB_OKCANCEL
按鈕 OK 按鈕 CANCEL
0x0002
MB_ABORTRETRYIGNORE
按鈕 ABORT 按鈕 RETRY 按鈕 IGNORE
0x0003
MB_YESNOCANCEL
按鈕 YES 按鈕 NO 按鈕 CANCEL
0x0004
MB_YESNO
按鈕 YES 按鈕 NO
0x0005
MB_RETRYCANCEL
按鈕 RETRY 按鈕 CANCEL

3.4.2. Dialogs.MessageBox 的視窗樣式

Dialogs.MessageBox 函數顯示的視窗樣式由以下常數的位元或值控制:

Dialogs.MessageBox 圖示和樣式的 ButFlags 常數
常數值視窗樣式
0x0040
MB_ICONINFORMATION
圖示 INFORMATION 資訊視窗
0x0030
MB_ICONWARNING
圖示 WARNING 警告視窗
0x0020
MB_ICONQUESTION
圖示 QUESTION 確認視窗
0x0010
MB_ICONERROR
圖示 ERROR 錯誤視窗

3.4.3. Dialogs.MessageBox 的預設活動按鈕

Dialogs.MessageBox 函數顯示的預設活動按鈕由以下常數的位元或值控制:

Dialogs.MessageBox 預設按鈕的 ButFlags 常數
常數值預設按鈕
0x0000
MB_DEFBUTTON1
預設為左側第一個按鈕
0x0100
MB_DEFBUTTON2
預設為左側第二個按鈕
0x0200
MB_DEFBUTTON3
預設為左側第三個按鈕

3.4.4. Dialogs.MessageBox 的返回值

Dialogs.MessageBox 函數返回的數字表示使用者按下的按鈕,如下所示:

Dialogs.MessageBox 按鈕按下時返回的 ButPressed 值
常數值按下的按鈕
0x0000
mrNone
未按下任何按鈕
0x0001
mrOK
結果 OK
0x0002
mrCancel
結果 CANCEL
0x0003
mrAbort
結果 ABORT
0x0004
mrRetry
結果 RETRY
0x0005
mrIgnore
結果 IGNORE
0x0006
mrYes
結果 YES
0x0007
mrNo
結果 NO

注意:如果按下右上角的「x」或按 Esc 關閉視窗,則將返回「取消」按鈕的值。

3.4.5. Dialogs.MessageBox 使用範例

以下是一個使用 Dialogs.MessageBox 的小腳本以及將顯示的結果視窗:

-- 顯示的按鈕
MB_OK = 0x0000
MB_OKCANCEL = 0x0001
MB_ABORTRETRYIGNORE = 0x0002
MB_YESNOCANCEL = 0x0003
MB_YESNO = 0x0004
MB_RETRYCANCEL = 0x0005

-- 視窗樣式
MB_ICONINFORMATION = 0x0040
MB_ICONWARNING = 0x0030
MB_ICONQUESTION = 0x0020
MB_ICONERROR = 0x0010

-- 預設按鈕
MB_DEFBUTTON1 = 0x0000
MB_DEFBUTTON2 = 0x0100
MB_DEFBUTTON3 = 0x0200

-- 返回按下的按鈕
mrNone = 0x0000
mrOK = 0x0001
mrCancel = 0x0002
mrAbort = 0x0003
mrRetry = 0x0004
mrIgnore = 0x0005
mrYes = 0x0006
mrNo = 0x0007

iFlags = MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2
iButton = Dialogs.MessageBox("您想要退出嗎?", "問題", iFlags)

if iButton == mrYes then
  DC.ExecuteCommand("cm_Exit")
end

Dialogs.MessageBox 使用範例

3.4.6. Dialogs.InputQuery 使用範例

以下是一個使用 Dialogs.InputQuery 的小腳本以及將顯示的結果視窗:

bResult, sAnswer = Dialogs.InputQuery("身份驗證", "請輸入您的姓名:", false, "約翰")

if bResult == true then
  Dialogs.MessageBox("您好 " .. sAnswer .. "!", "歡迎!", 0x0040)
end

Dialogs.InputQuery 使用範例

3.5. UTF-8 函式庫

該函式庫提供對 UTF-8 編碼的基本支援。

它在 LazUtf8 表中提供了所有函數。

UTF-8 函式庫
函數名稱描述

iResult = LazUtf8.Pos(SearchText, SourceText, Offset)

在字串中從指定位置開始搜尋子字串。搜尋區分大小寫。

返回子字串 SearchText 在字串 SourceText 中第一次出現的位置,搜尋從位置 Offset(預設為 1)開始。

如果在給定的 Offset 之後 SearchText 未在 SourceText 中出現,則返回零。

LazUtf8.Next(String)

一個疊代器函數,每次呼叫時返回 String 中的下一個字元以及該字元開始位置(以位元組為單位)。

範例:

-- 以 "位置 : 字元" 的形式列印值對
for iPos, sChar in LazUtf8.Next(String) do
  DC.LogWrite(iPos .. " : " .. sChar)
end

sResult = LazUtf8.Copy(String, iIndex, iCount)

複製字串的一部分。

Copy 返回一個字串,該字串是 String 中從位置 iIndex 開始的 iCount 個字元的副本。

如果 iCount 大於字串 String 的長度,則結果將被截斷。如果 iIndex 大於字串 String 的長度,則返回一個空字串。

iResult = LazUtf8.Length(String)

返回字串中 UTF-8 字元的數量。

sResult = LazUtf8.UpperCase(String)

接收一個字串並返回該字串的副本,其中所有小寫字母都已更改為大寫。

sResult = LazUtf8.LowerCase(String)

接收一個字串並返回該字串的副本,其中所有大寫字母都已更改為小寫。

sResult = LazUtf8.ConvertEncoding(String, FromEnc, ToEnc)

String 的編碼從 FromEnc 轉換為 ToEnc

支援的編碼值清單:

  • 預設系統編碼(取決於系統地區設定):"default"。
  • 預設 ANSI(Windows)編碼(取決於系統地區設定):"ansi"。
  • 預設 OEM(DOS)編碼(取決於系統地區設定):"oem"。
  • Unicode:"utf8"、"utf8bom"、"ucs2le"、"ucs2be"。
  • ANSI(Windows):"cp1250"、"cp1251"、"cp1252"、"cp1253"、"cp1254"、"cp1255"、"cp1256"、"cp1257"、"cp1258"。
  • OEM(DOS):"cp437"、"cp850"、"cp852"、"cp865"、"cp866"、"cp874"、"cp932"、"cp936"、"cp949"、"cp950"。
  • ISO 8859:"iso88591"、"iso88592"、"iso88593"、"iso88594"、"iso88595"、"iso88597"、"iso88599"、"iso885910"、"iso885913"、"iso885914"、"iso885915"、"iso885916"。
  • 其他:"macintosh"、"koi8r"、"koi8u"、"koi8ru"。
特殊編碼的含義(範例)。

在 Windows 中(英語或俄語):
  • "default" - cp1252 或 cp1251
  • "ansi" - cp1252 或 cp1251
  • "oem" - cp850 或 cp866
在 Linux 中(英語或俄語):
  • "default" - utf8
  • "ansi" - cp1252 或 cp1251
  • "oem" - cp850 或 cp866

sEnc = LazUtf8.DetectEncoding(String)

返回傳輸文字的編碼值。
支援的編碼清單與 LazUtf8.ConvertEncoding 函數中使用的編碼類似。

3.6. 字元庫

該函式庫包含用於檢查字元是否屬於特定 Unicode 類別的函數,以及取得字元類別的函數。

該函式庫中可用函數的清單:

字元庫
函數名稱描述

iResult = Char.GetUnicodeCategory(Character)

返回字元 Character 的 Unicode 類別,以下值之一:

描述
  字母:
0大寫字母 (Lu)
1小寫字母 (Ll)
2標題字母 (Lt)
3修飾字母 (Lm)
4其他字母 (Lo)
  標記:
5非間距標記 (Mn)
6間距組合標記 (Mc)
7封閉標記 (Me)
  數字:
8十進位數字 (Nd)
9字母數字 (Nl)
10其他數字 (No)
  標點符號:
11連接符標點 (Pc)
12破折號標點 (Pd)
13開標點 (Ps)
14閉標點 (Pe)
15初始標點 (Pi)
16最終標點 (Pf)
17其他標點 (Po)
  符號:
18數學符號 (Sm)
19貨幣符號 (Sc)
20修飾符符號 (Sk)
21其他符號 (So)
  分隔符:
22空格分隔符 (Zs)
23行分隔符 (Zl)
24段落分隔符 (Zp)
  其他:
25控制 (Cc)
26格式 (Cf)
27代理 (Cs)
28專用 (Co)
29未分配 (Cn)

bResult = Char.IsDigit(Character)

如果 Character 字元在 Nd 類別中,則返回 true

bResult = Char.IsLetter(Character)

如果 Character 字元在 LuLlLtLmLo 類別中,則返回 true

bResult = Char.IsLetterOrDigit(Character)

如果 Character 字元在 LuLlLtLmLoNdNl 類別中,則返回 true

bResult = Char.IsLower(Character)

如果 Character 字元在 Ll 類別中,則返回 true

bResult = Char.IsUpper(Character)

如果 Character 字元在 Lu 類別中,則返回 true

此外,這些函數支援使用兩個參數:我們可以指定一個字串和該字串中字元的位置,而不是單個字元。

3.7. 作業系統函式庫

該函式庫包含與 Double Commander 執行所在作業系統相關的函數。

以下是該函式庫中可用函數的清單:

作業系統函式庫
函數名稱描述

iResultCode = os.execute(sCommand)

將執行 sCommand,就像在命令列中輸入一樣,並返回操作的結果代碼。

sCommand 可以是:

  • 終端命令,例如 os.execute("dir > all.txt")
  • 可執行檔,例如 os.execute("C:\\Windows\\System32\\calc.exe")
  • 帶參數的可執行檔:
    os.execute("C:\\Utils\\fsum.exe -md5 test.bin > md5.txt")

sTempFileName = os.tmpname()

將返回一個用作臨時檔名的檔名(在系統的臨時檔案目錄中)。
如果函數無法建立唯一名稱,它將返回空字串。

bResult, sError, iError = os.remove(sFileName)

將刪除名為 sFileName 的檔案或目錄。

如果成功,函數返回 true

如果失敗,函數返回三樣東西:

  1. nil 表示失敗
  2. sError 為錯誤訊息描述
  3. iError 為錯誤代碼編號

bResult, sError, iError = os.rename(sOldName, sNewName)

將用新名稱 sNewName 重新命名檔案 sOldName

注意:如果名為 sNewName 的檔案已存在,它將被取代!

如果成功,函數返回 true

如果失敗,函數返回三樣東西:

  1. nil 表示失敗
  2. sError 為錯誤訊息描述
  3. iError 為錯誤代碼編號

Value = os.getenv(VariableName)

將返回參數中傳遞的變數 VariableNameValue
如果不存在該名稱的變數,它將返回 nil

os.setenv(VariableName, Value)

新增或更改 VariableName 環境變數。如果出現錯誤,函數返回 -1。

os.unsetenv(VariableName)

移除 VariableName 環境變數。如果出現錯誤,函數返回 -1。

4. 索引

DC 函式庫

DC.CurrentPanel
DC.ExecuteCommand
DC.LogWrite


系統函式庫

SysUtils.CreateDirectory
SysUtils.CreateHardLink
SysUtils.CreateSymbolicLink
SysUtils.DirectoryExists
SysUtils.ExtractFileDir
SysUtils.ExtractFileDrive
SysUtils.ExtractFileExt
SysUtils.ExtractFileName
SysUtils.ExtractFilePath
SysUtils.FileExists
SysUtils.FileGetAttr
SysUtils.FindClose
SysUtils.FindFirst
SysUtils.FindNext
SysUtils.GetAbsolutePath
SysUtils.GetRelativePath
SysUtils.GetTempName
SysUtils.GetTickCount
SysUtils.MatchesMask
SysUtils.MatchesMaskList
SysUtils.PathDelim
SysUtils.ReadSymbolicLink
SysUtils.Sleep


剪貼簿函式庫

Clipbrd.Clear
Clipbrd.GetAsText
Clipbrd.SetAsHtml
Clipbrd.SetAsText


對話方塊函式庫

Dialogs.InputListBox
Dialogs.InputQuery
Dialogs.MessageBox


UTF-8 函式庫

LazUtf8.ConvertEncoding
LazUtf8.Copy
LazUtf8.DetectEncoding
LazUtf8.Length
LazUtf8.LowerCase
LazUtf8.Next
LazUtf8.Pos
LazUtf8.UpperCase


字元函式庫

Char.GetUnicodeCategory
Char.IsDigit
Char.IsLetter
Char.IsLetterOrDigit
Char.IsLower
Char.IsUpper


作業系統函式庫

os.execute
os.getenv
os.remove
os.rename
os.setenv
os.tmpname
os.unsetenv


Valid HTML 4.0 Transitional CSS Valid!