在開啟和關閉視窗時進行資料傳遞
在應用程式中,有時一個任務要分解成幾個部分,由多個視窗來協同完成,這就需要這些視窗之間能夠很好地配合。例如,在檢索大批量資料時,可以提供一個小視窗讓使用者隨時停止資料檢索,並能在該小視窗中顯示檢索的進度。如果在一個視窗中顯示關於職工的簡短描述資訊,使用者雙擊某職工資料時可以顯示該職工的詳細情況,等等,這些例子都涉及視窗之間的協作。本節介紹有關的函數和技巧。
視窗之間的協作有以下幾種可能情況:
l 互相補充性的協作:從視窗提供比主視窗更加詳細的資訊,是對主視窗資訊的補充。
l 控制性的協作:從視窗控制主視窗的進度,通常在主視窗完成需要花費較長時間的操作時提供具有控制功能的從視窗。
l 地位平等的協作:一個任務分割成幾部分,不同部分在不同的視窗中完成。在執行過程中有可能需要參考各個任務的中間結果,所以它們之間應該能夠互動。
上述這些情況在實際應用軟體開發過程中都可能遇到,下面分別以典型例子來介紹。
一、在開啟和關閉視窗時進行資料傳遞
視窗開啟和關閉時進行資料的傳遞是一種基本的並且非常重要的視窗協作手段。可以使用兩個函數和一個對象來完成這些工作。函數OpenWithParm和CloseWithReturn分別用來帶參數開啟視窗和帶參數關閉視窗,這兩個函數傳遞的參數使用對象Message的成員變數儲存。使用它們可以構建多種形式的視窗協作。
函數OpenWithParm具有Open函數的功能,並且還能傳遞參數給要開啟的視窗。該函數的文法如下:
OpenWithParm ( windowvar, parameter {, parent } )
其中windowvar是要開啟的視窗名稱,可以是Window畫板中定義的視窗,也可以是指令碼中定義的視窗變數;parameter是要傳遞的參數,只能是String,Numeric或者PowerObject類型,該參數根據類型儲存在Message的成員變數中傳遞給要開啟的視窗;parent是一個已經開啟的視窗名稱,該視窗要成為windowvar視窗的父視窗。函數執行成功返回1,否則返回-1。如果有參數為NULL則返回NULL。下面是以傳遞參數方式開啟視窗的一些例子。
下面指令碼開啟視窗w_employee,並將“James NewTon”傳遞給該視窗:
OpenWithParm(w_employee, "James NewTon")
下面指令碼在資料視窗的DoubleClicked事件中,把使用者點擊的資料行中的職工社會安全號碼傳遞給w_detail視窗:
String ls_no
If row < 1 Then Return //使用者點擊的不是資料行
ls_no = GetItemString(row, "no") //擷取社會安全號碼
If Not IsNull(Ls_no) And Len(ls_no) > 0 Then
OpenWithParm(w_detail,ls_no)
End If
上面的指令碼首先判斷使用者點擊的是否有效資料行,使用DoubleClicked事件中的參數row是否大於0來判斷,如果大於0則使用者點擊了有效資料行。然後讀取使用者點擊資料行中職工的社會安全號碼,並將社會安全號碼傳遞給w_detail視窗。在視窗w_detail中可以檢索社會安全號碼等於該參數的職工詳細資料,這需要讀取傳遞過來的參數。
對象Message是一個結構類型的全域變數,並有很多的成員變數。在傳遞參數時有三個成員變數用來讀取傳遞的資料,它們是:
l Message.DoubleParm:用來傳遞Numeric類型的資料。
l Message.PowerObjectParm:用來傳遞PowerObject物件類型的資料,像資料視窗、按鍵、列表框和使用者自訂的結構等都可以使用該變數進行傳遞。
l Message.StringParm:用來傳遞String類型的資料。
當使用函數OpenWithParm開啟視窗後,應該在進行其他動作之前首先讀取傳遞過來的參數,以免其他動作修改Message中的成員變數。例如,上述的雙擊資料視窗開啟視窗w_detail後,在該視窗的w_detail中編寫如下指令碼:
String ls_no
ls_no = Mesasge.StringParm //讀取傳過來的參數
dw_1.SetTransObject(SQLCA)
dw_1.Retrieve(ls_no) //以ls_no為參數檢索資料
在前面介紹設定MDI視窗中的工具條時,曾提到在調用通用工具條設定模組時,在功能表項目的Clicked事件中使用函數OpenWithParm(parentwindow)把當前MDI視窗作為參數傳遞。在通用工具條設定模組的開啟事件中編寫如下指令碼:
iw_window = Message.PowerObjectParm
… //其他處理
其中,iw_window為Window類型的執行個體變數,因為在該視窗的很多地方用到iw_window,所以應該定義成執行個體變數。
函數CloseWithReturn的作用是關閉指定的視窗,並且返回參數。該函數的文法格式是:
CloseWithReturn ( windowname, Returnvalue )
其中,windowname是要關閉的視窗的名稱,一般是指令碼所在的視窗的名稱;Returnvalue是要返回的數值,和上述函數OpenWithParm的完全相同。函數正確執行返回1,否則返回-1,當有參數為NULL時返回NULL。
需要注意的是:只要是response類型的視窗,使用該函數就能有效地傳遞參數;該視窗不一定非得是用OpenWithParm開啟的。在開啟該response的視窗中可以讀取傳遞過來的參數。例如,下面的例子中,視窗w_data中有按鈕“檢索學生資料”、“檢索教師資料”和一個資料視窗dw_1;當使用者點擊按鈕“檢索學生資料”或者“檢索教師資料”時,彈出response類型的視窗w_parm;使用者在該視窗中輸入要檢索的學生或教師的姓名,點擊該視窗w_parm上的“確定”按鈕,然後返回到w_data視窗中,以使用者輸入的參數來檢索資料。
在視窗w_data的按鈕“檢索學生資料”的Clicked事件中編寫如下指令碼:
String ls_name
OpenWithParm(w_parm, "student") //開啟視窗w_parm
Ls_name = Message.StringParm //此處在關閉w_parm後繼續執行
If Len(ls_name) > 0 Then Dw_1.Retrieve(ls_name)
在按鈕“檢索教師資料”的Clicked事件中編寫如下指令碼:
String ls_name
OpenWithParm(w_parm, "teacher") //開啟視窗w_parm
Ls_name = Message.StringParm //此處在關閉w_parm後繼續執行
If Len(ls_name) > 0 Then Dw_1.Retrieve(ls_name)
在視窗w_parm的Open事件中編寫指令碼:
If message.StringParm = "student" Then
st_1.text = "請輸入要尋找的學生姓名:"
Else
st_1.text = "請輸入要尋找的教師姓名:"
End If
在w_parm視窗的“確定”按鈕的Clicked事件中編寫如下指令碼:
If Len(Trim(sle_1.text)) <= 0 Then
Beep(2)
MessageBox("提示", "請在編輯框中輸入內容!",STopSign!)
Else
CloseWithReturn(Parent,sle_1.Text)
End If
在w_parm視窗的“取消“按鈕的Clicked事件中編寫如下指令碼:
CloseWithReturn(Parent, " ")
總之,使用CloseWithReturn函數時一定要注意,只有被關閉的視窗是response類型才能有效地擷取返回參數。
另外需要說明的一點是,某些情況下需要直接修改Message成員變數的取值才能正確傳回值。比如,在一個資料視窗中,經常需要在視窗的CloseQuery事件中判斷資料是否已經修改;如果修改,則直接儲存,這時返回是否儲存過資料的相應標記。在CloseQuery事件中使用函數CloseWithReturn不能正確傳回值,只好直接修改Message成員變數的取值了。