種架構最大的差別是:誰是程式的「主人」。

架構 Menu 是主體 Form 是主體、Menu 掛在 Form
啟動順序 先執行 Menu 先開主 Form
Menu 顯示位置 dBASE Runtime 主視窗 自己的主 Form
右上角 X 關閉 Runtime Shell 關閉主 Form
可否用 canClose 不行,Menu 沒有 Form 的關閉事件 可以
beforeRelease Runtime 關閉時不保證觸發 Form 正常釋放 Menu 時較可靠
記錄離開時間 通常需要 Timer 心跳 可在 canClose 精確寫入 SQL
控制關閉流程 比較困難 比較完整
適合用途 傳統 dBASE 選單型系統 標準 Windows 應用程式

目前的架構:Menu 為主

dBASE Runtime
└── Menu
    ├── 客戶資料
    ├── 訂單資料
    └── 報表

使用者按右上角 X,關閉的是 Runtime Shell。Menu 本身沒有 canClose,所以很難在最後一刻執行 SQL。

建議架構:主 Form 為主

dBASE Runtime
└── MainForm
    ├── Menu
    ├── Timer
    └── canClose

啟動主 Form:

public gMainForm

gMainForm = new MainForm()
gMainForm.open()

將 Menu 掛到主 Form,再使用:

function FORM_CANCLOSE
   local cSQL

   cSQL = "UPDATE user_session " + ;
          "SET logout_time = CURRENT_TIMESTAMP " + ;
          "WHERE user_id = '" + gcUserID + "'"

   gDatabase.executeSQL(cSQL)

return true

這時使用者按主 Form 的 X

按 X
→ FORM_CANCLOSE
→ 寫入 SQL
→ 關閉 Form
→ 結束程式

如果你不希望看到一般 Form 的灰色工作區,MainForm 可以最大化,讓它看起來仍然像原本的 Menu 系統:

with (this)
   windowState = 2   // 最大化
   text = "管理系統"
endwith

結論:如果需要可靠記錄正常離開時間,採用「主 Form 掛 Menu」比較適合;如果維持「Menu 為主」,則應使用 Timer 心跳方式,因為 Runtime 的 X 不保證通知 Menu。

另種 說法

在 dBASE 中,「先有選單再開啟表單」與「表單直接掛載選單」兩種做法,在架構與實際運作上有很大的差異:

1. 先有選單,再開啟表單(應用程式層級 / Shell 模式)

將選單綁定在主框架 _app.frameWin 上,表單則作為子視窗(MDI Child)開啟。

  • 選單位置:固定在最頂層的主視窗(MDI 框架)上方,不會隨表單切換而消失。

  • 生命週期:選單與主程式同生共死。即使所有表單都關閉,選單依然留在螢幕頂端。

  • 視窗控制:右上角的 是針對整個應用程式。當畫面上沒有任何表單時,可能出現點擊 無反應的狀況(需要靠隱藏主表單或 quit 來處理)。

  • 適用場景:傳統大型 ERP 或多模組系統,一個主選單可以開啟各式各樣的子表單。

2. 在表單上直接掛載選單(表單層級 / Form 模式)

直接將選單物件指派給特定表單的 menuFile 屬性(例如 form.menuFile = "myMenu.mno")。

  • 選單位置:附著在該表單的頂部。表單在哪,選單就在哪。

  • 生命週期:與該表單綁定。表單一關閉,該選單隨之消失。

  • 視窗控制:右上角的 100% 作用在該表單本身,且能穩定觸發表單的 canCloseonClose 事件(非常適合在此寫入 SQL 紀錄)。

  • 適用場景:單一功能視窗、獨立運作的工具程式,或是不同表單需要完全不同選單內容的情況。

關鍵差異對比

特性 先有選單再開啟表單 (_app.frameWin) 表單上直接掛載選單 (form.menuFile)
控制層級 全域(Application Level) 單一視窗(Form Level)
表單關閉時 選單繼續保留 選單隨表單一起關閉
canClose 捕捉 無表單時易失效,需額外處理 100% 穩定捕捉(可順利寫 SQL)
開發難易度 需處理 MDI 架構與全域退出 結構簡單、直覺,程式獨立性高
個人頭像照片

By 伍芳左

MIS, ERP Pro... RHCE Member (7.2)

發佈留言