2014年4月21日 星期一

Visual Lisp 輸入 含對話盒程式例子


   這是一個有對話盒的 Visual Lisp 程式例子,簡單說,這是一個讓使用者可以輸入密碼,程式核對後確認是否通過的密碼對話盒,為了變點花樣,程式讓使用者可以輸入三次錯誤密碼的機會,超過三次便拒絕輸入。
    先然看看 DCL 檔案內容,就叫它 Password.DCL

PassWord : dialog {
            key = "password";
            label = "輸入密碼" ;
            : boxed_column{
                    spacer_1;
                :edit_box {
                        key = "edbox_pw";
                        label = "密碼:";
                        edit_width = 20;
                        password_char = "*";
                }
                spacer_1;
        }
            spacer_1;
        ok_cancel;
}

先從簡單的講
spacer_1;                對話盒內空一行
ok_cancel;              標準的確定與取消按鈕
:boxed_column{  }  劃出方框,無標題 (通常將相關聯之元件綁到一起)
:edit_box{ }             編輯盒 (是的,就是 Windows 中讓人輸入的方框)

再來於 { } 元件內特性定義,如 edit_box
        key = "edbox_pw";        元件關鍵字,供程式辨認
        label = "密碼:";            顯示予使用者之提示
        edit_width = 20;             編輯框之寬度
       password_char = "*";     密碼輸入使用,定義 "*" 元為顯示之符號 (輸入密碼的標準動作)
  另外注意末端 ; { } 成對等小細節。

那麼 ok_cancel; 的性質呢 ? 它是預設的按鈕,會顯示 "確定" "取消" 兩個按鈕,"確定" key = "accept"; "取消" key = "cancel"

DCL 檔案最前頭
PassWord : dialog {
                key = "password";
                label = "輸入密碼" ;

PassWord Lisp 呼叫辨認的
key = "password";         當然就是整個對話盒的關鍵字
label = "輸入密碼" ;       整個對話框的 TITLE

執行前 VLIDE  提供預覽功能,工具 / 介面工具(I) / 預覽編輯器的 DCL(E)



就可以看到對話盒樣子 (很陽春吧)



OK,再來看 LISP 程式碼部分

(defun C:Password( / dcl_ID)
    ; 載入對話盒
    (setq dcl_ID (load_dialog "password.dcl"))
    (if( not (new_dialog "PassWord" dcl_ID))
        (progn
            (alert "PassWord 對話盒無法載入!")
            (exit)
        )  
    )
    ; nCount 計算錯誤之次數
    ; sPw 正確之密碼
    (setq nCount 0
          sPW "Hello World")
    ; 設定對話方框輸入後之動作 (檢查密碼)
    (action_tile "accept" "(CheckPW)")
    (action_tile "cancel" "(done_dialog 0)")
    ; 啟動對話盒

    (start_dialog)
    (unload_dialog dcl_ID)

    (gc)
)
; 檢查密碼對話盒函數
(defun CheckPW ( / input)
     (setq input (get_tile "edbox_pw"))
     (if (= input sPW)
         (progn
             (alert "密碼正確")
             (done_dialog 1) ; 關閉對話盒
         )  
         (progn
             (setq nCount (1+ nCount))
             (set_tile "password" (strcat "密碼錯誤 "
                                          (itoa nCount)
                                          " "))
             (alert (strcat "密碼錯誤!\n輸入密碼為:" input))
             (if (>= nCount 3) ; 錯誤三次封鎖對話盒
                 (progn
                     (alert "密碼錯誤 3 \n拒絕接受輸入")
                     (mode_tile "accept" 1)
                     (mode_tile "edbox_pw" 1)
                 )  
             )
         )  
     )  
)

    標準呼叫程序就不說了,來看看
(action_tile "accept" "(CheckPW)")
(action_tile "cancel" "(done_dialog 0)")

    (action_tile) 函數即是設定對話盒受到 "刺激" 後之反應,(action_tile "accept" "(CheckPW)") 便是按下 "確定" 按鈕後要產生之反應,是的,就是執行 (CheckPW) 函數檢查密碼,(action_tile "cancel" "(done_dialog 0)"),按下 "取消" 後便關閉對話盒,並傳回失敗之訊息 0

    (CheckPW) 是自訂函數,執行檢查動作之函數,每次按下 "確定" 便執行一次,函數執行首先取得編輯盒中之文字,並儲存於 input 之變數中
(setq input (get_tile "edbox_pw"))

若輸入之密碼與內存之密碼相符 (sPW, "Hello Wrold"),顯示密碼正確,再跳出對話盒 (done_dialog 1) 傳回正確訊息。
(alert "密碼正確")
(done_dialog 1)



若錯誤,則先將錯誤次數累加一次 (nCount 是整體變數)
(setq nCount (1+ nCount))

再來,將錯誤次數顯示在以 "password" 為關鍵字之元件,是什麼呢?,回頭查查 DCL 之定義,就是整個對話盒的標題
(set_tile "password" (strcat "密碼錯誤 "
                                          (itoa nCount)
                                          " "))
 
並提出訊息告訴使用者密碼錯誤,並將錯誤之密碼提示與使用者。
(alert (strcat "密碼錯誤!\n輸入密碼為:" input))


最後檢查錯誤是否超過三次
(if (>= nCount 3)
….
)
若超過,先提示使用者錯誤已超過三次,無法再輸入。
(alert "密碼錯誤 3 \n拒絕接受輸入") 




      並將 "密碼" 編輯盒與 "確定" 之按鈕鎖住 (無法使用),只能按下 "取消" 按鈕。
(mode_tile "accept" 1)
(mode_tile "edbox_pw" 1)
(注意,參數 1 才是 disable)




這雖然是個小小小程式,但是 DCL 輸入該說的東西已有十之七八了。

沒有留言:

張貼留言