Yield()函數是一個在
PB程式控制中非常有用的函數,如果能夠合理使用它,一定可使你的程式操作友好很多。
Yield()函數的功能是將控制權轉移給其它繪圖物件,包括非 PowerBuilder對象。該函數檢測訊息佇列,如果有訊息,就把訊息取出。
該函數返回布爾型值,如果在訊息佇列中提取到了訊息,那麼函數返回 TRUE,否則返回 FALSE。。利用該函數可以在執行耗時較長的操作時把控制權轉讓給其它應用。
用法正常情況下, PowerBuilder應用程式在執行一段代碼(比如正在檢索資料或者執行一段迴圈程式)的過程中不響應使用者的操作。對耗時短暫的程式碼片段來說,這種處理方式沒有什麼不妥的地方,但是,如果某個程式碼片段的執行耗時較長(比如在大量資料檢索或迴圈執行的代碼中),應用程式又希望為使用者提供更多的控制權,那麼需要在這段代碼中插入 Yield()函數,讓使用者能夠進行其它操作,比如,允許使用者按下其他視窗的“取消”按扭,而該按扭又改變了某個全域(共用)變數,在 Yield()函數接下來的代碼中便可判斷該全域(共用)變數的值,以決定下一步的操作。應用程式執行
Yield()函數後,如果發現訊息佇列中存在訊息,它將允許對象處理這些訊息,處理之後,繼續 Yield()函數後面代碼的執行。
雖然使用者在檢索時不能做其他的事情,但是當你將 Yield()函數放在 RetrieveRow事件中時,使用者能夠同時運行其他的應用程式。當然,代碼中插入 Yield()函數將降低應用程式的運行效率。
樣本 1.
下面的代碼執行一段耗時較長的過程,在其中我們插入了 Yield()函數,當使用者單擊視窗上的“取消”按鈕時,終止這段代碼的執行,其中使用共用變數 sb_interrupt來指示使用者是否單擊了“取消”按鈕:
integer n
// sb_interrupt是共用變數
sb_interrupt = FALSE
FOR n = 1 to 3000
Yield()
IF sb_interrupt THEN
// sb_interrupt的值在“取消”按鈕的 Clicked事件處理常式中修改
MessageBox("調試 ","使用者中斷 !")
sb_interrupt = FALSE
EXIT
ELSE
... // 其它處理
END IF
NEXT
“取消”按鈕的 Clicked事件處理常式可以寫為: sb_interrupt = TRUE
樣本 2.
在本例當中,程式在互動 頻詼齟翱諭笨梢源淼諞桓齟翱詰氖錄H綣揮衁ield()函數,使用者也可以控制第二個視窗,但在迴圈完成之前不能看到視窗焦點的變化。
integer n
FOR n = 1 to 3000
Yield()
... // Some processing
NEXT
樣本 3.
In this example, a script wants to open a DDE channel with Lotus Notes, whose executable name is stored in the variable mailprogram. If the program isnt running, the script starts it and loops, waiting until the programs startup is finished and it can establish
a DDE channel. The loop includes Yield, so that the computer can spend time actually starting the other program:
time starttime
long hndl
SetPointer(HourGlass!)
//Try to establish a handle; SendMail is the topic.
hndl = OpenChannel("Notes","SendMail")
//If the program is not running, start it
IF hndl $#@60; 1 then
Run(mailprogram, Minimized!)
starttime = Now()
// Wait up to 2 minutes for Notes to load
// and the user to log on.
DO
//Yield control occasionally.
Yield()
//Is Notes active yet?
hndl = OpenChannel("Notes","SendMail")
// If Notes is active.
IF hndl $#@62; 0 THEN EXIT
LOOP Until SecondsAfter(StartTime,Now()) $#@62; 120
// If 2 minutes pass without opening a channel
IF hndl $#@60; 1 THEN
MessageBox("Error", &
"Cant start Notes.", StopSign!)
SetPointer(Arrow!)
RETURN
END IF
END IF