有新增的功能,理所當然也要有移除的功能,當你按下移除鍵時, 我就會呼叫RemovePictureData來處理,我們這一次就從移除的程式碼開始看
Private Sub cmdRemove_Click()
If lstAddData.ListCount > 0 Then
   If MsgBox("要移除這個圖檔嗎?", 36, "系統訊息") = vbYes Then
      Call RemovePictureData
   End If
End If
End Sub

Private Sub RemovePictureData()
'Check Remove List Item,If Select = False then Exit Sub
'Else Check The Select Item,If Select Then Remove Item and Reset then ProFile Data
'When Remove Over,ReSort then ProFile Data,Check Picture SUM
'Set Control Enabled eq False,Call LoadProFile Default,Set File Update Value
 
If lstAddData.ListIndex < 0 Then
   MsgBox "請指定要移除的資料項", 48, "系統錯誤"
   Exit Sub
End If

'移除、整理ProFile的資料
'略

If PictureSUM <> 0 Then
   lstAddData.ListIndex = 0
   picName$ = lstAddData.Text
   Call Picture_PreView
Else
   picName$ = ""
   prePicName$ = ""
   imgPreView.Picture = LoadPicture()
   imgPreView.Move imgBackGround.Left + 2, imgBackGround.Top + 2
   imgPreView.Width = imgBackGround.Width - 4
   imgPreView.Height = imgBackGround.Height - 4
End If

Call SetControlEnabled(False)
SetControlFlag = False
Call StopMusic
Call LoadProFileSet("Default")
ProFileUpdate = False
LoadFileUpdate = True
End Sub

首先我們先Check lstAddData.ListCount,看使用者有沒有加入任何的資料, 如果沒有的話,當然也就什麼都不用做囉。在呼叫RemovePictureData前,再確定一下使用 者是否真的要將圖檔資料移除。
在RemovePictureData,我們先檢查使用者有沒有選取任何資料,只要查一下ListIndex屬性就可以 知道了,沒有選取任何資料項的話,則顯示訊息請使用者選取要移除的資料,
我本來想這樣解釋的,但是,我用ListIndex來檢查,其實是沒有用,而且是錯誤的方法, 如果你選取了一個資料項,再點選一次(按下Ctrl鍵),這時該資料項應該處於未點選的狀態, 但是,ListIndex還會是你點選的那一個資料項喔!所以,這個檢查就毫無意義了! 不過,這不會讓程式有問題的,只不過多做了一些白工而已,但是,這種錯誤還是要極力避免的喔!
接下來我們就要移除、整理ProFile的資料,只要有被點選的資料項,我們就把它移除,並把ProFile的資料清除, 再將ProFile整理一遍,把空白的資料項往前遞補。然後我們再Check一下剩下的資料項總數(PictureSUM)
如果還有資料的話,就將資料項設定至第一筆,呼叫Picture_PreView預覽圖片,否則的話就將imgPreView的資料清空, 相關參數也清除,接下來將設定資料的控制項Disable,再呼叫StopMusic停止音樂及LoadProFileSet載入預設值資料, 最後因為這一個SPM檔移除後已經造成檔案的變動了,所以要記得將LoadFileUpdate設為True。ProFileUpdate這個變數則是 用來Check目前編輯的這一筆ProFile資料有沒有經過變動,等一下講解的時候你就了解了。
再多解釋一下下
1.在ProFile這個陣列的移除整理的過程並沒有什麼不對,完全可以達到所要的結果, 但~是,我不知道各位在這種情形下會怎麼整理,可是我覺得這種寫法實在是~好‧爛!又長又爛, 好像某樣東東一樣,所以我建議各位可以想一想還有沒有更好的方法,來取代一下這個實在不怎麼讓 我滿意的程式....
2.在後面的處理,其實都是之後才加上去的,所以可能會讓你有點一頭霧水,看了後面的講解後再 回頭看一遍會比較容易了解的,StopMusic則等到後面一點的時候,再和PlayMusic一起講解

接下來使用者要做的就是設定他的ProFile的資料了,在平常的時候,我是將所有與設定相關的控制項Disable 的,因為在控制項的資料變動的時候我都作了一些設定什麼的,為了方便管理使用者的使用狀況,所以在沒有點 選要修改的資料項的時候,我把控制項Disable,比較容易掌握狀態。至於會不會有使用者覺得不好用, 這就很難講了,這就得自己拿捏了。
這個部份我寫成了一段副程式SetControlEnabled來作,內容很簡單,就是依傳入的參數Enable或Disable 該控制項而已,程式中我設定了一個變數SetControlFlag來儲存目前控制項的狀態,後面會用到,不過你可以把它 一起寫到SetControlEnabled裡,我當初沒有注意到,把它寫在外面了,後來還因此忘記設定發生一些錯誤, 自己多注意一下。

接下來我們來看一下lstAddData_MouseDown這個程序,這裡作的處理就是看使用者點選了資料項, 要設定ProFile的處理。

Private Sub lstAddData_MouseDown(Button As Integer, Shift As Integer, X As Single, y As Single)

'Check ProFile Update,If Update And Selct Item Change then Ask User Cancel ,If No then Exit
'Else,Load PorFile Data ,Set Control Object Value
'If Button is Right then Show PopUpMoenu

If (Button And 1) And lstAddData.ListCount > 0 Then
   
   If lstAddData.Selected(lstAddData.ListIndex) = True Then
      If lstAddData.ListIndex = SetProFileNo - 1 Then Exit Sub
      If ProFileUpdate = True Then
         If MsgBox("你目前所做的設定並沒有儲存,要放棄嗎?", vbYesNo Or vbQuestion, "系統訊息") = vbNo Then
            lstAddData.Selected(lstAddData.ListIndex) = False
            lstAddData.ListIndex = SetProFileNo - 1
            lstAddData.Selected(SetProFileNo - 1) = True
            Exit Sub
         End If
      End If
   
      picName$ = lstAddData.Text

      Call Picture_PreView
      Call StopMusic
   

      If SetControlFlag = False Then Call SetControlEnabled(True)
      SetControlFlag = True
      SetProFileNo = lstAddData.ListIndex + 1
      
      If CheckProFileData() = NoProFileData Then
         Call LoadProFileSet("Default")
      Else
         Call LoadProFileSet("ProFile")
      End If
      ProFileUpdate = False
   Else
      If SetControlFlag = True Then Call SetControlEnabled(False)
      SetControlFlag = False
   End If
   
ElseIf Button And 2 Then
   '略
End If

End Sub

一開始先檢查lstAddData裡有沒有資料及目前Select的屬性,如果資料資料沒被點選就將控制項 Disable,接下來檢查目前按下的這一筆資料是否和目前編輯的是同一筆資料,這裡使用SetProfileNo 這個變數來判斷,如果是同一筆就沒有必要再載入一次資料了。接下來檢查ProfileUpdate這個變數, 檢查剛剛有沒有去變動到上一筆資料,如果有,詢問使用者是否要放棄剛才的變更,如果使用者不放棄, 便將ListIndex及Select屬性設回上一筆的狀態,接下來再取得這一筆資料的圖檔名, 使用Picture_PreView預覽圖檔,再呼叫StopMusic停止音樂,接者Check一下SetControlFlag確定一下 目前控制項是否Enable,沒有的話就呼叫SetControlEnabled,再將SetProfileNo及ProfileUpdate 設為目前的筆數、未變更的狀態。 SPM檔案如果沒有編輯過的話,我就會載入Default的設定,不見得每個人都有空做一堆設定嘛! 因此一些基本的設定就先幫使用者設定好吧!這裡用CheckProfileData及LoadProfileSet來做
Private Function CheckProFileData() As Integer
'Check ProFile Data
If ProFile(SetProFileNo).DelayTime <> 0 Then
   CheckProFileData = FindProFileData
Else
   CheckProFileData = NoProFileData
End If

End Function


Private Sub LoadProFileSet(LoadType As String)
Dim i As Integer
'Load ProFile Data and Check Type,Set the Control Object's Value
'If LoadFileUpdate eq False then Save The Status
'When Load Over,Restore the Value to LoadFileUpdate

If LoadFileUpdate = False Then i% = 1

Select Case LoadType
Case "Default"
     '略

Case "ProFile"
     '略
End Select

If i% = 1 Then LoadFileUpdate = False
End Sub

這裡作的就很簡單了,如果是沒有設定過的資料ProFile的資料就是空白的,所以你只要對一個絕對不會是空 值的變數檢查一下就行了,再將結果傳回去,依結果呼叫LoadProfileSet,如果是"Default"則載入初始的設定值, 否則就載入ProFile內的設定資料,要注意的是,我在資料項的內容變更的時候,會改變LoadFileUpdate的設定, 但是如果只是瀏覽資料的話就不應該改變這個值,所以我先把LoadfileUpdate暫存於i變數中, 資料載入完成後再讀回來。接下來就更簡單了,只要在各控制項變更的時候記得將ProFileUpdate 及LoadFileUpdate設為True就行了,如果使用者要儲存時再將控制項的值存入Profile內就行了, 儲存完後別忘了將ProfileUpdate設回去。

Ver1.0 Update:
在使用了一陣子Screen Saver Maker後,我突然發覺一件事,設定雖然好用,但是每一個都要設定的話... 那可要花上不少的時間耶!有些圖,Default的設定方式並不合,所以還是要去做變動,前前後後,常常花了 我不少時間,因此,我再新增一個功能,套用設定值,以其中一個圖片設定為基準,讓使用者一次將設定值 套用到所有的圖片上,那我們就可以省下不少設定的時間了! 程式是以目前設定的這一個圖檔為套用的標準,因此如果使用者變更過圖檔設定的話,我們就必需請它 儲存過設定值後,才可以進行套用設定值的動作,我們再把套用設定的視窗叫出來,程式如下

Private Sub cmdSetToAll_Click()
If ProFileUpdate = True Then
   MsgBox "要將設定值套用到所有的設定圖檔,請先將目前的設定值儲存", vbOKOnly Or vbInformation, Me.Caption
   Exit Sub
End If

frmSetToAll.Show 1
End Sub
接者,在套用設定的視窗就單純多了,只要在使用者按下確定時,用For迴圈掃一遍ProFile設定檔, 將選定的值套用進去,這樣子就可以了,在UnLoad Form時,別忘了,設定檔已經改變了, 記得把LoadFileUpdate設定為True
Private Sub cmdOK_Click()
'Check check box checked.if checked,then set Profile(SetProfileNo).xxxx to all Profile

Dim i As Integer

If chkDelayTime.Value = vbChecked Then
   '略
If chkMidi.Value = vbChecked Then
   '略
If chkWave.Value = vbChecked Then
   '略
If chkFullPicture.Value = vbChecked Then
   '略
If chkEffect.Value = vbChecked Then
   '略
LoadFileUpdate = True
Unload Me
End Sub
又是後記....
再強調一次,這個程式完全是依我的品味設定出來的,有很多地方都還有很大的修改空間, 像現在講解的這一段,在上面一段詢問使用者要不要放棄已變更的設定的處理, 我剛開始是依者一個想法做的-使用者可能不小心按錯了,但是我後來自己在測試的時候,遇到的情形卻 常常是-設定完了,但是忘記儲存就繼續設定下一筆了,這種時候是不是改詢問要不要儲存,會不會比較好呢? 這也不一定,因為這些其實都是非常主觀的,我們只能自己推論這樣的作法適不適合使用者,依你自己的判斷來作作看, 也許你可以有更好的作法
至於文字對話盒和檔案對話盒的部份我就先跳過了,強烈建議你們用VB提供的Common Dialog Control就 好了,免得浪費時間,有現成的工具當然是用現成的好囉!我只是....想作一個....有背景的... 檔案對話盒,結果這個看起來好像挺簡單的東東卻小錯誤連連,好不容易才搞定....
試聽的功能(PlayMusic、StopMusic)下回再講解囉! 如果對教學內容有任何意見的話,歡迎EMail 給我一起討論,謝謝!
回到VB教學教室