功能表

當您把專案的功能逐漸擴充之後,就會發現表單上安排的控制項愈來愈多,尤其是命令鈕愈來愈多,造成設計上的困擾。這時候大部分的應用軟體都會運用功能表,因為如果使用一大堆的命令鈕將會讓使用者無所適從。

功能表相當於分類的命令鈕,它可以執行使用者選取的命令。本章將介紹功能表的編輯、屬性、用法以及其他和功能表有關的課題。

    1. 編輯功能表

使用功能表編輯器

功能表由「主選項」和「選項」所組成,以下圖的功能表為例,我們通常會稱呼它為「形狀功能表」,「形狀」就是主選項;在形狀功能表裡有「矩形」、「正方形」、「橢圓形」、「圓形」、「圓角矩形」、「圓角正方形」等選項。不過在Visual Basic裡,不論是「形狀」這個主選項還是「矩形」這個選項或者其他的選項,都是一個功能表控制項(Menu控制項)。我們想要有下面的功能表該如何編輯呢?

12-1功能表範例

雖然功能表也是一種控制項,但是功能表控制項和其它的控制項有些不同。在工具箱中並沒有功能表控制項的圖示可以選取,想要擁有功能表必須使用功能表編輯器編輯,要用功能表編輯器就點選 鈕或從Visual Basic功能表中點選「工具」、「功能表編輯器」。您將可以看到下面的對話方塊:

12-2 功能表編輯器

在功能表範例中,「形狀」是功能表控制項的標題(Caption屬性),底下的選項如:「矩形」、「正方形」也都是功能表控制項的標題。功能表控制項並不會像其他的控制項會給一個預設的屬性值,所以在功能表編輯器中,「名稱」這一欄您一定要輸入,因為「名稱」就是Name屬性。

我們就從「形狀」主選項開始輸入,首先在標題欄中輸入「形狀」,然後在名稱欄中輸入「mnuShape」,這樣形狀主選項就完成了。輸入完畢按「下一個」鈕,就可以繼續輸入下一個功能表選項。

接下來輸入「矩形」這個選項:在標題欄中輸入「矩形」,然後在名稱欄中輸入「mnuRectangle」,由於「矩形」是屬於「形狀」底下的一個選項,所以必須按 鈕使它產生...的圖示,表示「矩形」的層級在「形狀」之下。

 

12-3 功能表編輯過程

按下「下一個」按鈕,就可以接著輸入「正方形」這個選項,然後輸入「橢圓形」這個選項,它們的Caption屬性和Name屬性如下表所示。您可以按照下面的屬性表,使用功能表編輯器,輸入整個功能表,最後按下「確定」鈕,就可以在表單上看到圖12-1的功能表了。

 

整個功能表的屬性如下:

Name

Caption

功能表Menu

mnuShape 形狀

功能表Menu

mnuRectangle 矩形

功能表Menu

mnuSquare 正方形

功能表Menu

mnuOval 橢圓形

功能表Menu

mnuCircle 圓形

功能表Menu

mnuRoundRectangle 圓角矩形

功能表Menu

mnuRoundedSquare 圓角正方形

功能表編輯器的按鈕

在「功能表編輯器」裡,有許多的按鈕,明瞭這些按鈕的用法,可以使您更方便的編輯功能表,底下說明個按鈕的功能:

功能表與程式碼的連結

當使用者點選某一個功能表時,就會產生Click事件。本專案希望使用者選取「形狀」功能表內不同的選項時,表單上的形狀就跟著改變。Shape控制項的Shape就是如同功能表上所顯示的六種形狀,我們在使用者點選該形狀時,改變Shape控制項的Shape屬性,形狀就會改變了。

使用者點選「形狀」、「矩形」時,產生mnuRectangle_Click事件,此時我們要把Shape控制項(NameshpItem)的形狀改為矩形,您可以將Shape屬性設定為0,或者像下列的程式碼使用內定的常數。

Private Sub mnuRetangle_Click()

shpItem.Shape = vbShapeRectangle

End Sub

使用者點選「形狀」、「正方形」時,產生mnuSquare_Click事件,此時我們要把Shape控制項的形狀改為正方形,您可以將Shape屬性設定為1,或者像下列的程式碼使用內定的常數。

Private Sub mnuSquare_Click()

shpItem.Shape = vbShapeSquare

End Sub

使用者點選其他形狀時,都會產生Click事件,我們也使用內定常數改變Shape控制項的形狀,程式碼如下:

Private Sub mnuOval_Click()

shpItem.Shape = vbShapeOval

End Sub

Private Sub mnuCircle_Click()

shpItem.Shape = vbShapeCircle

End Sub

Private Sub mnuRoundedRectangle_Click()

shpItem.Shape = vbShapeRoundedRectangle

End Sub

Private Sub mnuRoundedSquare_Click()

shpItem.Shape = vbShapeRoundedSquare

End Sub

執行結果如下:

 

12-4 執行結果 (Menu1.Vbp)

    1. 子功能表
    2. 認識子功能表

      下一層級的功能表就是它的上一層級功能表的子功能表。功能表的選項裡,有一個往右的箭號時,當游標移動到這個選項時,就會出現下一層級的功能表,我們稱為子功能表。


    3. 12-5 子功能表(Menu2.Vbp)

      在編輯功能表時,每一次按下 鈕,功能表的層級就會往下一級。當我們編輯好下一層級的功能表時,不需要任何程式碼。當游標移動到具有下一層級的選項時就會自動出現子功能表。

      快捷鍵

      請注意圖12-5的功能表,主選項「顏色[C]」的C字底下有底線,表示使用者可以按下Alt + C 選取顏色功能表。「前景顏色[F]」的F字底下也有底線,表示使用者可以按下Alt + C 選取「顏色」後,再按下F鍵,就可以選取「前景顏色[F]」這個選項。我們稱這種按鍵方式為快捷鍵。

      要讓功能表具有快捷鍵,輸入標題時,就必須在快捷鍵的前方加上「&」。例如您看到的「顏色[C]」,實際上的標題是「顏色[&C]」。而「前景顏色[F]」,實際上的標題是「前景顏色[&F]」。

      如果您需要顯示&符號,而不是要使用快捷鍵,就要用兩個&。例如您輸入「&&HFFFFFF」,所顯示的標題是「&HFFFFFF」。

      使用者不會因為按下Alt + F就直接選取「前景顏色」,因為Alt +快捷鍵只適用於最上層的功能表(主選項)

      Menu控制項陣列

      12-5的子功能表部份,我們使用控制項陣列的方式設計,功能表的控制項陣列就是在索引(Index)項目裡填上數字。底下列出整個功能表的屬性,其中Name屬性欄中有括號者表示Index屬性。

      Name

      Caption

      功能表Menu

      mnuColor 顏色[&C]

      功能表Menu

      mnuForeColor 前景顏色[&F]

      功能表Menu

      mnuColorItem(1) ……藍色&&H800000

      功能表Menu

      mnuColorItem(2) ……綠色&&H008000

      功能表Menu

      mnuColorItem(3) ……青色&&H808000

      功能表Menu

      mnuBackColor 背景顏色[&B]

      另外我們在表單的中央放置一個文字方塊txtTest,並且希望使用者選取顏色選項時,文字方塊內的文字就改變顏色。如果不使用控制項陣列,就得撰寫三個功能表選項的Click事件。但是我們使用功能表控制項陣列,所以程式碼簡化如下:

      Private Sub mnuColorItem_Click(Index As Integer)

      txtDisp.ForeColor = QBColor(Index)

      End Sub

      執行結果如下:

       

      12-6 執行結果(Menu2.Vbp)

      上一層功能表的控制

      這些選項的上一層級的功能表mnuForeColor,仍然具有Click事件,如果您要在顯示子功能表時也同時做一些事情的話,就可以利用上一層功能表的Click事件。

      如下的程式碼,您可以在開啟子功能表(尚未選好)時,將文字方塊內的文字改為「前景顏色」。

      Private Sub mnuForeColor_Click()

      txtDisp.Text = "前景顏色"

      End Sub

      執行結果:

      12-7執行結果 (Menu3.Vbp)

    4. 功能表的屬性

前言

因為每一個功能表選項都是控制項,所以在屬性視窗中也可以找到這些物件,您可以在屬性視窗的物件清單中選取這些物件,然後修改它們的屬性。在功能表編輯器中也包括了這些屬性,但是用中文來表示,屬性視窗中則是使用英文,底下列出功能表編輯器中所用的中文和屬性視窗中的英文對照,以及屬性的說明:

功能表編輯器中

屬性視窗中

說明

標題 Caption 顯示給使用者點選的文字
名稱 (Name) 功能表的名字
索引 Index Index時表示是控制項陣列
核取式 Checked True時,功能表前面會有ˇ記號
啟用 Enabled False時,無法點選且呈現凹陷的字型
快速鍵 ShortCut 設定後,使用者可按下快速鍵直接選取功能表
可看見 Visible False時,該功能表將不可見
具視窗清單 WindowList 用在MDI表單,可以列出所有的視窗標題

分隔線(Caption屬性為 - )

如果要產生如右的功能表分隔線,就在該功能表的Caption屬性裡輸入「-」。一旦功能表為分隔線時,它就不能有子功能表,也不能是最上層的功能表。

核取式(Checked)

我們經常可以在功能表前方看到如右圖的打ˇ的符號,此符號就是由Checked屬性所控制,當功能表的Checked屬性為True時,功能表的前方就會出現打ˇ的符號。您可以在程式碼中使用Checked屬性,也可以在功能表編輯時就設定核取式。

一般而言,如果功能表的Checked屬性為True,表示該項功能表為被選取的狀態,實際上它只是一個提示符號。您可以根據需要,用程式碼針對Checked屬性詮釋其意義。另外,最上一層級的功能表不能使用Checked屬性。

底下就示範用功能表Checked屬性表達Label的三個特性:可見、邊框和立體的。功能表分為三個選項,使用者點選時,就將該選項的Checked屬性改變(本來為True就改成False,本來是False的,就改為True),然後依據是否打ˇ,改變標籤的屬性,例如:「可見」功能表選項打ˇ時,標籤的Visible屬性為True,「可見」功能表選項未打ˇ時,標籤的Visible屬性就設定為False。表單設計如下:


12-8 表單設計 (MenuCheck.Vbp)

屬性值設定如下:

Name

Caption

功能表Menu

mnuLabel 標籤的特性

功能表Menu

mnuVisible 可見

功能表Menu

mnuBorder 有邊框

功能表Menu

mnuSoild 立體的

標籤Label

lblTest 測試標籤

首先設計使用者點選「可見」選項時的程式:使用者點選「可見」時,要改變功能表前方的ˇ記號,我們只要使用Not運算,這樣Checked屬性就會這一次是True,下一次是False了。當「可見」選項前面有ˇ記號時,我們將標籤設定為可見的,當「可見」選項前面沒有ˇ記號時,我們將標籤設定為不可見的,也就是標籤的Visible屬性相當於此功能表的Checked屬性,程式碼如下:

Private Sub mnuVisible_Click()

mnuVisible.Checked = Not mnuVisible.Checked

lblTest.Visible = mnuVisible.Checked

End Sub

其次設計使用者點選「有邊框」選項時的程式:我們控制標籤的BorderStyle屬性,當選項的前面打ˇ時,我們將標籤設定為具有邊框的,也就是BorderStyle=1,當選項的前面沒有ˇ時,我們將標籤設定為沒有邊框的,也就是BorderStyle =0,程式如下:

Private Sub mnuBorder_Click()

mnuBorder.Checked = Not mnuBorder.Checked

If mnuBorder.Checked Then

lblTest.BorderStyle = 1

Else

lblTest.BorderStyle = 0

End If

End Sub

然後設計使用者點選「立體的」時的程式:我們控制標籤的Apperance屬性,當選項的前面打ˇ時,我們將標籤設定為立體的,也就是Apperance=1,當選項的前面沒有ˇ時,我們將標籤設定為平面的,也就是Apperance=0,程式如下:

Private Sub mnuSoild_Click()

mnuSoild.Checked = Not mnuSoild.Checked

If mnuSoild.Checked Then

lblTest.Appearance = 1

Else

lblTest.Appearance = 0

End If

End Sub

執行結果如下:

 

12-9執行結果(MenuCheck.Vbp)

Enabled屬性

本屬性是用來設定功能表選項是否啟用。當Enabled屬性為False時,功能表選項將呈現凹陷的字型,而且使用者無法點選該選項。如右圖所示。

Index屬性

填入Index屬性,功能表就是控制項陣列了。使用功能表控制項陣列,可以簡化程式碼設計或者動態的增減功能表選項。使用Index屬性必須注意下列事項:

Visible屬性

Visible屬性為決定功能表選項是否可見,當Visible屬性為False時,功能表選項就不可見,此時底下的功能表選項會依序遞補。如果該功能表選項的底下具有子功能表,當這個功能表選項的Visible屬性為False時,不但這個選項看不見,連它的子功能表也將無法看見。請看下圖的說明:

12-10 功能表Visible屬性說明

快速鍵(ShortCut屬性)

除了主選項,每一個功能表選項都可以設定快速鍵,當使用者按下快速鍵時,就會立即啟動該功能表的Click事件。

您可以在功能表編輯器中設定快速鍵,當功能表選項中設定好快速鍵時,在功能表選項的右方就會顯示按鍵的方式,如下圖所示:

12-11 設定快速鍵

使用快速鍵的注意事項如下:

    1. 快顯功能表
    2. 當使用者按下滑鼠右鍵時,所呈現的浮動式的功能表我們稱為快顯功能表(Popup Menu),例如在文字方塊中按下右鍵,將可呈現如右的快顯功能表。

      要使用快顯功能表,還是要先編輯功能表,但是必須將此功能表的主選項的Visible屬性設定為False,這樣才不會讓這個功能表顯示在表單上。

      當使用者按下滑鼠右鍵時,被按下鍵的控制項或表單會產生MouseDown事件,我們可以在此事件中,確認使用者按下的滑鼠鈕是否為右鍵,若為右鍵,就用PopupMenu程序將功能表顯示出來,這樣就變成快顯功能表了。

      底下示範的專案,使用者可以按下滑鼠右鍵顯示快顯功能表,當使用者選取功能表上的選項後,就在表單上畫出選擇的圖畫。

      我們使用功能表編輯器編輯一個最上層功能表為不可見的功能表,作為快顯功能表,並且在表單上安排Image控制項陣列,用來存放圖片,由於這些圖片的背景是白色的,所以把表單的背景顏色也改為白色的。表單設計如下:




    3. 12-12表單設計(Popup.Vbp)

      屬性值設定如下:

      Name

      Visible

      Picture

      影像Image

      imgPic(0) False (點陣圖)

      影像Image

      imgPic(1) False (點陣圖)

      影像Image

      imgPic(2) False (點陣圖)

      在表單上看不到功能表,但是本專案具有功能表,它們的屬性值用功能表編輯器編輯如下:

      Name

      Caption

      Visible

      功能表Menu

      mnuPicture 圖片 False

      功能表Menu

      mnuPicItem(0) True

      功能表Menu

      mnuPicItem(1) 青蛙 True

      功能表Menu

      mnuPicItem(2) 猴子 True

      為了在點選功能表選項後,畫出圖片的位置會在原先滑鼠右鍵按下的位置,所以在模組層次宣告底下的變數,紀錄滑鼠右鍵按下的位置:

      Dim ClickX As Single, ClickY As Single

      當表單產生MouseDown事件時,表示滑鼠按鍵已經按下,此時我們就可以從Button參數得知按下的是左鍵還是右鍵,當Button=1時為左鍵,當Button=2時為右鍵。

      我們只要用PopupMenu程序就可以將快顯功能表顯示出來,PopupMenu程序的第一個參數是功能表選項的Name,這個功能表選項必須要有下一層級的功能表選項。程式碼如下:

      Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

      ClickX = X

      ClickY = Y

      If Button = 2 Then

      PopupMenu mnuPicture

      End If

      End Sub

      當使用者點選功能表選項後,就用PaintPicture程序將圖片顯示在表單上。

      Private Sub mnupicItem_Click(Index As Integer)

      PaintPicture imgPic(Index).Picture, ClickX, ClickY

      End Sub

      執行結果如下:

      12-13執行結果(Popup.Vbp)

    4. 綜合範例

多個選項中只有一個成立

專案目標:表單上有一個以亂數出現的直線,製作一個功能表,讓使用者選取直線的樣式,而另一個功能表則可以選擇直線變化的快慢。

表單設計:表單上安排一個計時器控制項、Line控制項和功能表。

12-14表單設計 (Demo1.Vbp)

屬性設計:

Name

Interval

計時器Timer

tmrClock 125

直線Line

linShow  

Name

Caption

Checked

功能表Menu

mnuStyle 形式  

功能表Menu

mnuStyleItem(0) 透明 False

功能表Menu

mnuStyleItem(1) 實線 True

功能表Menu

mnuStyleItem(2) 破折線 False

功能表Menu

mnuStyleItem(3) 點線 False

功能表Menu

mnuStyleItem(4) 破折線-點線 False

功能表Menu

mnuStyleItem(5) 破折線-點線-點線 False

功能表Menu

mnuSpeed 速度  

功能表Menu

mnuSpeedItem(0) 快速 True

功能表Menu

mnuSpeedItem(1) 慢速 False

功能表Menu

mnuSpeedItem(2) 靜止 False

程式設計:

Private Sub mnuStyleItem_Click(Index As Integer)

? mnuStyleItem(linShow.BorderStyle).Checked = False

? linShow.BorderStyle = Index

? mnuStyleItem(linShow.BorderStyle).Checked = True

End Sub

Private Sub mnuSpeedItem_Click(Index As Integer)

? Static LastCheck As Integer

? mnuSpeedItem(LastCheck).Checked = False

LastCheck = Index

mnuSpeedItem(LastCheck).Checked = True

Select Case LastCheck

Case 0

tmrShow.Interval = 125

Case 1

tmrShow.Interval = 250

Case 2

tmrShow.Interval = 0

End Select

End Sub

Private Sub tmrShow_Timer()

linShow.Y1 = Rnd * ScaleHeight

linShow.Y2 = Rnd * ScaleHeight

End Sub

程式解說:

    1. Line控制項就像用Line程序畫圖一樣。Line控制項的X1,Y1,X2,Y2等四個屬性表示端點的座標,當您改變這些屬性值時就會改變Line控制項的位置。BorderStyle屬性則是線條的形式,總共有下列七種:

    BorderStyle的值

    線條

    說明

    0

      透明

    1

      實線

    2

      破折線

    3

      點線

    4

      破折線-點線

    5

      破折線-點線-點線

    6

      內實線

    我們可以看到:BorderStyle屬性為16時,顯示出來的直線是相同的。在功能表設計時就省略了「內實線」這個選項。Line控制項的BorderStyle的內定值為1(實線),所以在屬性設定時,就將功能表選項「實線」的Checked屬性設定為True。當使用者點選樣式的功能表選項時,先將原先的ˇ符號清除。

  1. 因為線條的BorderStyle和功能表陣列是一對一的關係,所以直接將BorderStyle的屬性值指定為功能表的Index值就可以了。
  2. 讓被點選的功能表呈現ˇ的記號。
  3. LastCheck是上一次ˇ記號所在的功能表的Index值,它的初始值是0
  4. 和選取樣式的方法一樣,先將原來的功能表選項的v記號清除,然後將被選取的功能表選項加上v記號。
  5. 由於每一個選項並沒有陣列或函數的對應關係,所以使用Select Case敘述,依照Index值做不同的處理。當Timer控制項的Interval屬性為0時,Timer控制項將不會產生Timer事件。
  6. 執行結果:

     

    12-15執行結果(Demo1.Vbp)

    可以增減的功能表

    專案目標:示範一個可以增加或減少功能表選項的專案。

    表單設計:安排1個文字方塊做為輸入之用,安排1個標籤做為輸出之用。

    12- 16表單設計(Demo2.Vbp)

     

    屬性設定:

    Name

    Caption

    Text

    文字方塊TextBox

    txtMenu

    標籤Label

    lblMsg    

    Name

    Caption

    Enabled

    Visible

    功能表Menu

    mnuAdd 增加 True True

    功能表Menu

    mnuDel 減少 False True

    功能表Menu

    mnuDefine 自訂 True False

    功能表Menu

    mnuUser True True

    程式設計:

    ?

    Dim MenuCount As Integer

    Private Sub mnuAdd_Click()

    ? If txtMenu.Text <> "" Then

    ? If MenuCount = 0 Then

    mnuDel.Enabled = True

    mnuDefine.Visible = True

    Else

    ? Load mnuUser(MenuCount)

    End If

    ? mnuUser(MenuCount).Caption = txtMenu.Text

    MenuCount = MenuCount + 1

    End If

    End Sub

    Private Sub mnuDel_Click()

    MenuCount = MenuCount - 1

    If MenuCount = 0 Then

    mnuDel.Enabled = False

    mnuDefine.Visible = False

    Else

    Unload mnuUser(MenuCount)

    End If

    End Sub

    Private Sub mnuUser_Click(Index As Integer)

    lblMsg.Caption = "您現在選取的是[" & mnuUser(Index).Caption & "]"

    End Sub

    程式解說:

  7. MenuCount為使用者輸入功能表的總數量,在表單設計時,就事先預留了「自訂」這個功能表讓使用者輸入自訂的選項,並且在這個功能表的下一層級預留了mnuUser這個功能表陣列。MenuCount就是紀錄mnuUser的數量,它的初始值是0。當MenuCount0時,就將「自訂」這個功能表隱藏起來。
  8. 使用者必須先在文字方塊內輸入自訂功能表的選項標題,然後按下「增加」,才可以在「自訂」功能表中增加一個選項,所以在此程序中檢查文字方塊的內容,當文字方塊內為空字串時,就不需處理。
  9. 使用者點選「增加」後,就要在「自訂」功能表中增加一個選項,當menuCount0時,表示「自訂」功能表並未顯示出來,所以將功能表顯示出來,並且讓「減少」功能表啟用。
  10. MenuCount不是0時,我們需要用動態的方式載入功能表控制項。
  11. 我們將輸入的文字指定為功能表的標題,並且將MenuCount加一,表示又增加了一個功能表。
  12. 當使用者點選「減少」時,我們將MenuCount減一,使得之後的程式碼MenuCount正好對應要移除功能表的Index值。
  13. MenuCount0時,表示要刪除掉所有自訂的功能表選項,但是因為mnuUser(0)這個功能表是不能被移除的(因為它是在表單設計時,就已經安排的控制項),所以用隱藏的方式將「自訂」這個功能表隱藏起來(也不能只有隱藏mnuUser(0)這個子功能表,因為子功能表至少要有一個選項是可見的)
  14. MenuCount0時,我們將功能表選項以動態的方式移除。
  15. 當使用者點選自訂的功能表選項時,在標籤上顯示訊息。
  16. 執行結果:

    12-17 執行結果(Demo2.Vbp)

    兩種不同的快顯功能表

    專案目標:在一個表單裡,您可以根據目前狀態的不同,以動態的方式改變快顯功能表的選項,也可以製作多個功能表,然後根據需要顯示不同的快顯功能表。本專案示範一個顯示圖片的程式,當滑鼠在圖片之外點選時,顯示「新增圖片」功能表,可以增加新的圖片,當滑鼠在圖片之內點選時,顯示「修改圖片」功能表,可以「刪除」或更換圖片。

    表單設計:表單的BackColor屬性設定為白色,並且安排三個影像放置要顯示的圖片,這些圖片事先處理成背景通透的,存放於光碟的Ch14\Pic目錄裡。安排一個imgClick控制項,設定其Index屬性為0,這樣就可以動態載入此控制項,已做為顯示之用。設計兩組功能表,每一個功能表主選項的Visible都設定成False,這樣就不會顯示在表單的上方。

    12- 17表單設計(Demo3.Vbp)

    屬性設定:

    Name

    Visible

    Picture

    影像Image

    imgPic(0)~imgPic(2) False (點陣圖)

    影像Image

    imgClick(0) False ()

    Name

    Caption

    Visible

    功能表Menu

    mnuAddPicture 增加圖片 False

    功能表Menu

    mnuPicItem(0) True

    功能表Menu

    mnuPicItem(1) 青蛙 True

    功能表Menu

    mnuPicItem(2) 猴子 True

    功能表Menu

    mnuModify 修改圖片 False

    功能表Menu

    mnuDel 刪除 True

    功能表Menu

    mnuPicItem(0) True

    功能表Menu

    mnuPicItem(1) 青蛙 True

    功能表Menu

    mnuPicItem(2) 猴子 True

    程式設計:

    ?

    Dim ClickX As Single, ClickY As Single

    Dim ImageCount As Integer

    Dim ImageIndex As Integer

    ?

    Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

    ClickX = X

    ClickY = Y

    If Button = 2 Then

    PopupMenu mnuAddPicture

    End If

    End Sub

    ?

    Private Sub mnupicItem_Click(Index As Integer)

    ImageCount = ImageCount + 1

    Load imgClick(ImageCount)

    imgClick(ImageCount).Move ClickX, ClickY

    imgClick(ImageCount).Picture = imgPic(Index)

    imgClick(ImageCount).Visible = True

    imgClick(ImageCount).Tag = Index

    imgClick(ImageCount).ZOrder 0

    End Sub

    ?

    Private Sub imgClick_MouseDown(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)

    If Button = 2 Then

    ImageIndex = Index

    mnuChangeItem(0).Enabled = True

    mnuChangeItem(1).Enabled = True

    mnuChangeItem(2).Enabled = True

    mnuChangeItem(imgClick(Index).Tag).Enabled = False

    PopupMenu mnuModify

    End If

    End Sub

    ?

    Private Sub mnuChangeItem_Click(Index As Integer)

    imgClick(ImageIndex).Picture = imgPic(Index)

    imgClick(ImageIndex).Tag = Index

    End Sub

    Private Sub mnuDel_Click()

    imgClick(ImageIndex).Visible = False

    End Sub

    程式解說:

  17. 在表單上按下滑鼠右鍵時,我們將位置記錄於ClickXClickY變數中,在影像上按下滑鼠右鍵時,我們記錄按下影像的Index屬性於ImageIndex變數中。ImageCountimgClick影像控制項載入的數量。
  18. 使用者在表單上按下滑鼠右鍵時,我們顯示「增加圖片」的快顯功能表。
  19. 使用者點選「增加圖片」快顯功能表裡的選項後,就要在表單上顯示圖片,我們以動態的方式載入imgClick控制項,它的Index屬性由ImageCount決定,所以每載入一次就要將ImageCount1。控制項載入後,將它移動到點選位置,使用Move程序就可以將控制項移動到指定的位置。然後設定Picture屬性為選取的圖片,再將Visible屬性設定為True使它顯示出來,為了下一次點選到此控制項時,可以知道Picture屬性裡是哪一張圖片,所以將圖片的編號存入Tag屬性中。最後用Zorder程序將圖片顯示於最上層,Zorder程序有兩種參數值,當參數為1時,將控制項放在最底層,當參數為0時放在最上層。
  20. 當使用者在圖片上(也就是imgClick控制項上)按下滑鼠右鍵時,顯示「修改圖片」快顯功能表。不過在顯示之前,我們先將imgClick控制項的Index屬性記錄於ImageClick中,這樣使用者點選功能表的選項時,我們才知道要對哪一個控制項處理。由於我們可以從Tag屬性得知圖片的編號,所以將mnuChangePic功能表中是目前圖片編號的Enabled屬性設定為False,這樣使用者就不會換成原來的圖片。
  21. 當使用者點選更換圖片的選項時,我們只要將imgClick控制項的Picture屬性換成新的圖片,並且修改Tag屬性就可以了。
  22. 當使用者點選「刪除」時,我們只是將imgClick控制項隱藏起來。

執行結果:

12-18 執行結果(Demo3.Vbp)

習題

  1. 設計如下的功能表。
  2. 設計一個專案:使用光碟片Chap7\Pic裡的圖片,當使用者在功能表中選取圖片名稱時,可以在表單的中央顯示圖片。
  3. 設計一個專案:具有一個「對齊」功能表,裡面有「靠右對齊」、「靠左對齊」「置中對齊」等選項,當使用者點選這些選項時,可以改變表單內的標籤的對齊方式。
  4. 設計一個專案:具有一個「顏色」功能表,裡面有「背景顏色」、「前景顏色」兩個子功能表,這兩個子功能表各有16個選項,分別是QBcolor所定義的顏色名稱,當使用者點選這些選項時,可以改變表單內的文字方塊的顏色(文字方塊的前景顏色是ForeColor屬性、背景顏色是BackColor屬性)。
  5. 設計一個專案:具有一個「執行」功能表,裡面有「變大」、「變小」、「停止」三個選項,表單上安排一個影像控制項載入一幅圖片,當使用者選取「變大」時,圖片逐漸放大,當使用者選取「變小」時,圖片逐漸縮小,當使用者選取「停止」時,則圖片停止放大縮小。
  6. 修改第7章的OnCtrl.vbp專案,增加一個速度功能表,裡面有「快速」、「普通」、「慢速」三個選項,當使用者點選這些選項時,可以改變圖形變化的速度。