哈囉,經過十一期的講解之後,本期就要為ScreenSaver Maker做下一個完結了, 感謝各位的光臨與支持,作者將所有的教學文件壓縮成一個Zip檔放在下載區, 有興趣的可以把它下載回去,方便離線閱讀,不囉唆,繼續我們的講解吧!
上回講解完了由左至右的表現方法,不知道各位有沒有想通其原理,接下來的三種 特效的顯示方法其實也就可以推出來了,例如由右至左的表現方法,其實它的算式與 由左至右完全相同,差別只在於開始的基準點而已,但是由於最後一次的StretchBlt 會可能因為環境造成失敗的原因,所以當執行由右至左的特效時,可能會發生下面這樣 的繪圖狀態
1.
    

2.
    

3.
    

4.
    

5.
    

像這種情況,就應該做特別的處理,否則都會變成很不自然的情形,在ver0.91都已經做了修正, 再建議你們一次,把程式中寫檔的註解拿掉,觀察值的變化,這樣會比較容易看懂的, 接下來的由上至下或由下至上,其原理就沒有什麼值得解說的了,差別只在於X與Y的立場互 換而已。搞懂上面的原理,接下來的亂數填入就單純多了,看一下程式碼
Case RANDOM_BLOCK
     i% = (rndFlag(loopNo) - 1) Mod 7 + 1
     j% = ((rndFlag(loopNo) - 1) \ 7) + 1
     
     StretchBlt Me.hdc, DestLeft + (DestWidth / 7) * (i% - 1) - 2, DestTop + (DestHeight / 7) * (j% - 1) - 2, (DestWidth / 7) + 2, (DestHeight / 7) + 2, picPreView.hdc, (SrcWidth / 7) * (i% - 1) - 2 + SrcLeft, (SrcHeight / 7) * (j% - 1) - 2 + SrcTop, (SrcWidth / 7) + 2, (SrcHeight / 7) + 2, SRCCOPY
     
     loopNo = loopNo + 1
     If loopNo > EffectTime Then
        Me.AutoRedraw = True
        StretchBlt Me.hdc, DestLeft, DestTop, DestWidth, DestHeight, picPreView.hdc, SrcLeft, SrcTop, SrcWidth, SrcHeight, SRCCOPY
        Me.Refresh

        overFlag = True
        picPreView.AutoRedraw = False
        Me.AutoRedraw = False
     Else
        tmrShow.Enabled = True
        Exit Sub
     End If

在程式執行亂數填入的特效前,程式會先呼叫GetRandomArray(在GetEffectTime), 在變數rndFlag裡填入1~49(7*7)的亂數,進入特效處理後,再依序取出陣列中的亂數值, 算出它在7*7陣列中的座標,再算出在這個位置的X,Y座標,就可以正確的繪出, 計算的原理其實和前面的處理一樣,只不過這次X,Y都會變化而已,為了紋路的處理, 一樣做了計算補償的動作,雖然這次的計算方式不會有上面產生空白的問題,不過 還是更正了一點計算不周詳的地方。不過對程式沒有太大影響。
最後是我最頭痛的地方,對於這種左上-右下的表現方式,我完全完全完全不知道 別的程式是怎麼做的,所以推演出來的演算法效率算不算好,或者有沒有更方便的方 法,老實說,我一點把握都沒有...,各位如果也沒有更好的方法的話...就姑且聽聽吧
首先,我們想像整張圖被切成n*n的矩陣,那麼,如果要達成左上-右下的特效表現的話, 我們就要這樣描繪圖型
1.
 

2.
  
 

3.
   
  
 

4.....以此類推

由上面的圖型可以推出一個定論
1.(1,1)
2.(2,1),(2-1,1+1)
3,(3,1),(3-1,1+1),(3-2,1+2)
也就是目前執行的次數,就是X的起始座標,Y的起始座標為1,然後X依次遞減至1,Y則依次 遞增,這樣一次次的描繪就可以展現出左上-右下的表現了,接者,在描繪到最右邊時,如果依 據這個公式繼續算下去的話,會發生超出螢幕範圍的無效繪圖動作,你可以想像一下,如果依 據這個公式去向一個5*5的矩陣作左上-右下的特效,那麼會計算發生這種情形
1.(1,1)
2.(2,1),(2-1,1+1)
3,(3,1),(3-1,1+1),(3-2,1+2)
4.(4,1),(4-1,1+1),(4-2,1+2),(4-3,1+3)
5.(5,1),(5-1,1+1),(5-2,1+2),(5-3,1+3),(5-4,1+4)
6.(6,1),(6-1,1+1).....
以這個公式來計算,一個n*n的陣列,要完全描繪到每一個地方,需要n*2次才可以, 但是其中也會因此產生n*n個無效的計算值,因此程式要判斷這一點, 把無效的繪圖動作直接跳過,這樣才不會擔誤太多系統的時間(相差近一倍之多喔!),當然, 你也可以直接判斷目前執行的次數,直接設定X,Y的起始值,那也是可以的,不過作者比較懶, 就這樣帶過囉!至於Ver0.9與Ver0.91的差別...,作者太混了!Ver0.9有很多設錯的值,起始值 等等...有些變數的值都搞錯了,造成一些無效的繪圖動作,這些都在一一比對後,於Ver0.91修 正了,至於右上-左下的原理也是相同的,只要將其規則推出來,就可以做出來了。

Ver1.0 Update:
在Ver1.0的正式版本裡,我又陸續的加入了水平展開等的特效,不過明眼人一看的話就明白了, 其實我只是運用由上至下等相同原理,利用不同的繪製程序來達到各種新的展示方式而已, 所以這一點我不會再另加說明,其它可以做的特效其實還很多,端看你的想像力而已,多試試吧

後記:
在程式裡有一段很長的Mark,當然,想也知道不是註解,HWINDOW和VWINDOW其實是類似百葉窗 切換的轉場特效,這是利用花色遮罩作出的變化,其實,在轉場特效利用花色的搭配及dwRop 的變換,可以做出更豐富有趣的轉場效果,但是,作者在嘗試這一段時,卻發生了莫名其妙的 錯誤,一直找不到問題所在,因此暫時將這一段功能取消了,說實在,VB有時候真的讓人覺 得莫名其妙,我之前其實試做了不下十個的轉場特效,但是,有些處理,竟然在Win31的效率 會比在Win95好?不蓋你,之前作者為了工作需要,有一段時間是以VB3.0寫程式的,後來實在 找不到問題所在,只好刪選到只剩這幾個看起來比較有效率的處理。
當然,作者的學藝不精也是原因之一就是了,不過,如果各位有興趣多嘗試其它的特效, 又不知道如何推演圖型的演算法的話,作者倒是可以提供你一個好方法,在3rd Party中, 有一個自VB3.0時代就在研發VBX的公司叫做Pegasus ,這個公司推出許多和影像處理相關的控制項,其中有一組是和特效處理相關的 控制項,叫做FX Tools,它提供了Image、Label、TextBox等高達百種以上的特效處理、 非常的好用,只不過缺點是-它要錢,而且在它的版權宣告裡有提及元件散發的條件, 其中,可供使用者自行製作的螢幕保護程式是不被允許包含它們的元件的 (這是在FX Tools4.0看到的,目前出到5.x Gold,不過,大概還是有這個限制吧, 但如果是已經做好,固定型式的螢幕保護程式則不在限制之內) ,還有,GIF的格式是有版權的,如果你想載入GIF檔,必須跟他們申請過,得到一組 GifPassword才得以讓你的控制項載入GIF圖檔...
僅管如此,這個控制項仍然是很好用的,如果你只是想研究,又沒有什麼商業用途的需要, 它免費的體驗版仍然提供了很完整的功能,可以讓你好好的把玩一般,喔!只不過,體驗版中 ,你每放一個元件,它的Mark也就跟者出現一次,有點煩了就是了....其它還有一些 元件也都很好用,多看一看會找到意想不到的好東西喔!
O.K.~~Screen Saver Maker的VB教學文件就先到此告一段落了,Ver1.0的改版正在進行中, 如果有新的版本完成,我會丟上來給大家的,如果有問題的話,歡迎EMail給我一起討論

回到VB教學教室