電腦繪圖

Windows本來就是圖文整合的環境,先前的幾章我們只談到文字的輸出和輸入。本章將介紹畫圖程序,告訴您如何在螢幕上畫出直線、方形、圓形等幾何圖形,以及如何遏這些圖形有不同的顏色和花紋等。當然也介紹簡單的圖形輸入;讓使用者用滑鼠畫出圖形。

 

    1. 座標系統的認識
    2. Visual Basic的繪圖程序可以用在圖片方塊或表單上。至於我們可以畫的範圍有多大呢?從A點畫線到B點時,AB的單位又是什麼?

      繪圖的區域

      開啟一個新的專案時,觀察空白表單的幾個屬性:WidthHeightScaleWidthScaleHeight。您會發現WidthScaleWidth大一些,Height又比ScaleHeight大一些。Width就是表單的寬、Height就是表單的高,ScaleWidth則是表單內可以畫圖的寬度、ScaleHeight則是表單內可以畫圖的高度。如下圖的說明:




      10-1 表單的WidthHeightScaleWidthScaleHeight屬性

      圖片方塊也有這四個屬性,Height就是圖片方塊的高、Width就是圖片方塊的寬,把邊框的大小去掉後,內部可以畫圖區域的寬高就是ScaleWidthScaleHeight了。如果把圖片方塊的BorderStyle屬性改為0(沒有框線)ScaleWidth就和Width相同,ScaleHeight也會和Height相同。

      當表單的BorderStyle屬性為0時,ScaleWidthWidth也會相同,ScaleHeight也會和Height相同,但是這時候的表單就沒有標題、功能表和邊框。

      不論您使用表單或圖片方塊繪圖,您可以畫圖之範圍的長寬就是ScaleHeightScaleWidth之間。

      座標的單位

      Visual Basic提供了7種繪圖座標單位,您可以更改ScaleMode屬性的值,改變座標的單位:

      0 1 2 3 4 5 6 7

      意義

      使用者定義 Twip Point Pixel

      (像素)

      字元 英吋 公厘 公分

      Twip是內定的座標單位,Point是印表機印出時一個點的大小,Pixel則是圖檔中一個像點的大小。一個字元的水平大小是120 Twips,垂直大小是240 Twips1英吋則有1440 Twips1英吋相當2.54公分,所以1公分就相當於567 Twips

      1個像點(Pixel)並不是剛好多少個Twips,它會根據螢幕的解析度而改變,我們可以從Screen.TwipsPerPixelX得到1個像點的水平方向有幾個Twips,從Screen.TwipsPerPixelY得到1個像點的垂直方向有幾個Twips

      當您修改ScaleWidthScaleHeight的值時,座標單位就變成0(使用者定義)

      座標系統

      Visual Basic的座標系統的左上角是(0,0),愈往右邊水平座標愈大,愈往下垂直座標愈大。(X,Y)表示水平座標是X,垂直座標是Y

    3. 基本的繪圖程序

Pset

Pset程序可以畫出一個點,用法為Pset(x,y),Colorxy是畫出點的座標,Color則是點的顏色,Color參數可以省略,當您省略Color時,將用ForeColor屬性所指定的顏色畫出。

Pset畫出的點,就是一個像點,所以畫圖時最好將ScaleMode改為3

底下的程式碼可以從(50,50)(100,100)畫出一條線:

Private Sub Form_Paint()

Dim i As Integer

ScaleMode = 3

For i = 50 To 100

PSet (i, i)

Next i

End Sub

Line程序

Line程序的作用為畫出一條直線或方框。用Line(X1,Y1)-(X2,Y2),Color,就可以從(X1,Y1)這個座標點畫出一條直線到(X2,Y2)Color參數是線條的顏色。

底下的程式碼將在表單上畫出大叉叉:

Private Sub Form_Paint()

Dim i As Integer

ScaleMode = 3

Line (0, 0)-(ScaleWidth - 1, ScaleHeight - 1)

Line (0, ScaleHeight - 1)-(ScaleWidth - 1, 0)

End Sub

執行結果如下:

10-2 執行結果(Line1.Vbp)

Line(X1,Y1)-(X2,Y2),Color,B,就可以用(X1,Y1)(X2,Y2)為長方形的兩對角端點,畫出一個方框。例如要在表單的四周畫出一個方框就可以用:

Line (0, 0)-(ScaleWidth - 1, ScaleHeight - 1), ,B

或是

Line (0, ScaleHeight - 1)-(ScaleWidth - 1, 0), ,B

底下的程式碼以座標(100,50)(200,150)為兩對角,往外畫出6個正方形:

Private Sub Form_Paint()

Dim i As Integer

ScaleMode = 3

For i = 0 To 5

Line (100 - i * 10, 50 - i * 10)-(200 + i * 10, 150 + i * 10), , B

Next i

End Sub

10-3 執行結果(Line2.Vbp)

Line(X1,Y1)-(X2,Y2),Color,BF,就可以畫出實心的方框,方框內的顏色由Color參數控制,省略Color參數則由ForeColor屬性決定。

底下的程式碼可以畫出5個實心方框:

Private Sub Form_Paint()

Dim i As Integer

ScaleMode = 3

For i = 0 To 4

Line (20 + i * 30, 20)-(40 + i * 30, 40), , BF

Next i

End Sub

10-4執行結果(Line3.Vbp)

Circle程序

Circle程序可以畫出橢圓形、圓形或弧線。用法為:Circle(X,Y),R,Color,Start,End,Aspect。參數說明如下:

底下的程式碼畫出5個同心圓:

Private Sub Form_Paint()

Dim i As Integer

ScaleMode = 3

For i = 50 To 90 Step 10

Circle (100, 100), i

Next i

End Sub

10-5 執行結果(Circle1.Vbp)

接下來用兩個範例說明Aspect值的用法,第一個範例程式碼用Aspect>0的參數,畫出不同形狀的橢圓形(Circle2.Vbp)

Private Sub Form_Paint()

Dim i As Integer

ScaleMode = 3

For i = 1 To 10

Circle (100, 100), 100, , , , i

Next i

End Sub

第二個範例將Aspect參數變成小於1,就會畫出如下的橢圓形(Circle3.Vbp)

Private Sub Form_Paint()

Dim i As Integer

ScaleMode = 3

For i = 1 To 10

Circle (100, 100), 100, , , , 1 / i

Next i

End Sub

底下的程式碼示範各種畫弧線的方式:

Private Sub Form_Paint()

Const PI = 3.141593

Dim i As Integer

ScaleMode = 3

? Circle (20, 50), 20, , 0, PI / 2

? Circle (80, 50), 20, , 0, PI

? Circle (140, 50), 20, , PI, PI / 2

? Circle (200, 50), 20, , -2 * PI, -PI / 2

? Circle (20, 150), 20, , 0, -PI / 2

Circle (80, 150), 20, , 0, -PI

Circle (140, 150), 20, , -PI, -PI / 2

Circle (200, 150), 20, , -PI * 5 / 4, -PI * 3 / 4

End Sub

結果如下圖:

10-6 執行結果(Circle4.Vbp)

    1. 繪圖程序的相關屬性、程序
    2. QBColor函數

      前一節的繪圖程序,都沒有加上顏色。您可以像設定ForeColor屬性時一樣使用&HFF0000這樣的顏色值,只是不表示每一種顏色的圖形都可以正確的畫出來。如果您的螢幕是全彩(True Color),那麼所有顏色都會顯示出來,如果您的螢幕是256色,那麼大多數的顏色都會變成灰色。

      如果您不是要很多的色彩,螢幕又只設定256色,QBColor函數就是設定顏色的最佳選擇。QBcolor的用法是:QBColor(X)X可以從0~15,也就是可以顯示16種不同的色彩,其中QBColor(0)是黑色,QBColor(15)是白色。

      底下的程式碼可以畫出6個實心方框,由於畫出的次序是由外往內畫的,而且圖形愈畫愈小,所以會產生一層一層的顏色:

      Private Sub Form_Paint()

      Dim i As Integer

      ScaleMode = 3

      For i = 5 To 0 Step -1

      Line (100 - i * 10, 50 - i * 10)-(150 + i * 10, 100 + i * 10), QBColor(i), BF

      Next i

      End Sub

      執行結果如下:

      10-7 執行結果(QBcolor1.Vbp)

      RGB函數

      如果使用全彩就可以用RGB函數設定出所有的顏色,RGB的用法為:RGB(Red,Green,Blue)Red表示紅色,Green是綠色,Blue是藍色。每一種顏色的值是從0~2550表示不含該種顏色,255則是該種顏色全部加入,所以RGB(0,0,0)就是黑色,RGB(255,255,255)就是白色。

      底下用RGB函數和Line程序,將表單以漸層的顏色顯示:

      Private Sub Form_Paint()

      Dim i As Integer

      Dim bytColor As Byte

      ScaleMode = 3

      For i = 1 To ScaleHeight - 2 Step 3

      bytColor = i * 255& \ ScaleHeight

      Line (0, i - 2)-(ScaleWidth - 1, i + 2), RGB(0, 0, bytColor), BF

      Next i

      End Sub

      10-8 執行結果(Rgb1.Vbp)

      DrawWidth

      DrawWidth屬性可以取得或設定畫點的大小,底下的專案以三種不同大小的點在圖片方塊上畫出亂數點,表單設計如下:



    3. 10-9 表單設計(Width1.Vbp)

      屬性值設定如下:

      Name

      Caption

      圖片方塊PictureBox

      picDraw  

      選項鈕OptionButton

      optWidth(0) DrawWidth=1

      選項鈕OptionButton

      optWidth(1) DrawWidth=3

      選項鈕OptionButton

      optWidth(2) DrawWidth=5

      畫出這些亂數點的程式碼如下:

      Private Sub Form_Paint()

      Dim i As Integer

      picDraw.ScaleMode = 3

      picDraw.Cls

      For i = 1 To 100

      picDraw.PSet (Rnd * picDraw.ScaleWidth, Rnd * picDraw.ScaleHeight), QBColor(Int(Rnd * 16))

      Next i

      End Sub

      當使用者點選選項鈕時,就改變picDrawDrawWidth屬性,Refresh程序會使得Visual Basic更新畫面(就是去呼叫Form_Paint)

      Private Sub optWidth_Click(Index As Integer)

      picDraw.DrawWidth = Index * 2 + 1

      Refresh

      End Sub

      執行結果如下:

       

      10-10 執行結果 (Width1.Vbp)

      DrawMode

      Visual Basic提供16DrawMode,我們通常使用的DrawMode值為13,其意義為您指定的顏色為何,就直接用該顏色畫出。底下列出常用的DrawMode值和其意義:

      DrawMode

      意義

      6

      不管您指定的顏色,直接將螢幕的顏色反向

      7

      將您指定的顏色以Xor方式和螢幕的顏色作用後畫出

      10

      將您指定的顏色反向後以Xor方式和螢幕的顏色作用後畫出

      13

      以您指定的顏色直接畫出

      DrawMode值為6710時,您在同一個位置畫兩次就會把原來的像點擦掉,這樣就可以形成動畫的效果。底下就以DrawMode值為10做示範,將表單的DrawMode設定為10DrawWidth設定為3ScaleMode設定為3,然後安排一個計時器,Name屬性為tmrAniInterval屬性為200,再撰寫底下的程式碼:

      Private Sub tmrAni_Timer()

      Static X As Integer

      If X <> 0 Then Circle (X, 20), 5

      X = X + 3

      Circle (X, 20), 5

      If X > ScaleWidth Then tmrAni.Enabled = False

      End Sub

      執行後您將可以看到一個圓圈由左而右緩緩移動。如下所示:

       

      10-11執行結果(Mode.Vbp)

      FillStyle

      我們可以在LineCircle等程序畫出的圖形,指定圖形內部的花紋,花紋的形式由FillStyle屬性決定,花紋的顏色由FillColor屬性設定。FillStyle屬性從07,表示各種不同的花紋,FillStyle的內定值是1,也就是透明的,如果不是1時,您就可以畫出內部有花紋的方形或圓形了,底下的程式碼示範用FillStyle畫出的效果:

      Private Sub Form_Paint()

      Const PI = 3.141593

      Dim i As Integer

      ScaleMode = 3

      For i = 0 To 7

      FillStyle = i

      Line (20 + i * 40, 20)-(50 + i * 40, 50), , B

      Circle (30 + i * 40, 80), 15

      Circle (30 + i * 40, 140), 15, , -PI * 5 / 4, -PI * 3 / 4

      Next i

      End Sub

      10-12 執行結果 (Style.Vbp)

      Point

      Point用來讀取座標點的顏色,使用方法:Point(X,Y)X,Y為讀取顏色點的座標,單位是ScaleMode所設定的。

      CurrentXCurrentY

      CurrentXCurrentY屬性表示目前座標的位置,當您使用PrintLinePsetCircle等程序後都會更改文字CurrentXCurrentY屬性,我們也可以指定CurrentXCurrentY屬性之後再用Print程序輸出到表單上您想要的地方。

      AutoRedraw

      各種畫圖程序所畫出來的圖形,被別的表單覆蓋時就會消失,如果您要保持畫出的圖形,就要將AutoRedraw屬性設定為TrueAutoRedraw是自動重畫的意思,當以畫圖程序畫出的畫面被破壞時,將AutoRedraw屬性設定為True,就會自動把被破壞的部份重新畫出,但是這會消耗掉許多的系統資源。

    4. 互動式繪圖
    5. Mouse的三個事件

      當我們按下滑鼠鈕、移動、然後放開滑鼠鈕,就會產生MouseDownMouseMoveMouseUp三個事件。

      在表單上安排兩個標籤,分別設定Name屬性為lblXlblY,然後撰寫底下的程式碼:

      Private Sub Form_Load()

      ScaleMode = 3

      End Sub

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

      lblX.Caption = X

      lblY.Caption = Y

      End Sub

      執行後,您移動滑鼠時,標籤上就會顯示滑鼠目前的位置。

      如果您要在滑鼠按著時,就畫出點,就可以修改MouseMove程序為:

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

      If Button = 1 Then

      PSet (X, Y)

      End If

      End Sub

      如果可以把這些線條連線就是一個徒手畫的專案了,此時必須在滑鼠被按下時畫出第一點,然後從目前的座標位置畫線到滑鼠移動的位置,程式碼修改如下:

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

      If Button = 1 Then

      PSet (X, Y)

      End If

      End Sub

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

      If Button = 1 Then

      Line (CurrentX, CurrentY)-(X, Y)

      End If

      End Sub

      當滑鼠按下左鍵時Button=1,按下右鍵時Button=2,沒有任何按鍵時Button=0

       

      10-13 執行結果(Mouse1.VbpMouse2.VbpMouse3.Vbp

      上述的程式碼中,從(CurrentX,CurrentY)開始畫線到(X,Y),也可以寫成

      Line –(X,Y)

      畫出方框

      我們只要有兩個對角的座標就可以畫出一個方框,互動式的繪圖中,如果用「讓使用者點第一個位置,然後點第二個位置,再畫出方框」的方式,使用者在操作起來就會非常的不便,因為也許我們已經打消以該點為對角座標畫出方框了,但是它卻無法知道,而當您再點下別的點時,它卻仍畫出方框,所以一般的軟體就以「點選一個對角、拖曳到另一個對角放開滑鼠後畫出方框」的方式,在操作的過程中可以不斷地看到方框的變化,這樣使用者操作起來就會覺得比較安心。

      要使用這種不斷變化的方框,主要的構想就是把原來的方框擦掉,然後移動到新的位置,畫出新的方框。DrawMode可以選擇6710等值,這樣重複畫兩次時原先畫出的線條就會被擦掉。不過選擇710時,如果顏色和背景的作用正好和背景色相同時,就會看不見,所以最佳的選擇是6

      底下就示範畫出方框的專案:開啟一個新專案,表單上不用放置任何控制項,把表單的ScaleMode設定為3

      首先在MouseDown事件發生時,就把DrawMode變更為6,同時畫出最小的方框。當滑鼠移動時,就會把原來的方框擦掉,所以必須用模組層次變數記錄滑鼠的第一次點選位置,以及上一次移動的位置。我們用(X1,Y1)表示第一次點選的位置,(X2,Y2)表示上一次移動的位置。

      Dim X1 As Integer, Y1 As Integer ‘第一次點選的位置

      Dim X2 As Integer, Y2 As Integer ‘上一次點選的位置

      當滑鼠第一次按下時,該位置是「第一次點選的位置」也是「上一次點選的位置」,所以(X1,Y1)(X2,Y2)都要設定在滑鼠按下的位置,MouseDown事件的程式碼如下:

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

      If Button = 1 Then

      DrawMode = 6

      Line (X, Y)-(X, Y), , B

      X1 = X

      X2 = X

      Y1 = Y

      Y2 = Y

      End If

      End Sub

      當滑鼠移動時,我們先清除原來的方框(只要再畫一次就可以了),然後把上一次的位置改成目前滑鼠的位置,再畫出新的方框就可以了。

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

      If Button = 1 Then

      Line (X1, Y1)-(X2, Y2), , B

      X2 = X

      Y2 = Y

      Line (X1, Y1)-(X2, Y2), , B

      End If

      End Sub

      當滑鼠按鈕被放開時,就可以先將原來的方框清除,然後再將DrawMode改為13,用一般的方式畫出方框。

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

      If Button = 1 Then

      Line (X1, Y1)-(X2, Y2), , B

      X2 = X

      Y2 = Y

      DrawMode = 13

      Line (X1, Y1)-(X2, Y2), , B

      End If

      End Sub

      執行結果如下:

      10-14執行結果(Dline.Vbp)

      畫出橢圓形

      我們可以用畫出方框的方式決定橢圓形的大小,也就是畫出內切於長方形的橢圓形。為了方便起見,我們先撰寫Ellispe程序,讓Ellispe(X1,Y1,X2,Y2)可以畫出內切於點(X1,Y1)(X2,Y2)所構成的方形的橢圓形,如下圖所示:

      10-15 Ellispe(x1,y1,x2,y2)畫出的圖形

      由於對角點有兩種可能,所以我們讓X1為較小值X2為較大值,Y1 為較小值Y2為較大值,這樣我們可以用(X2-X1)+1取得方形的寬,(Y2-Y1)+1取得方形的長,令RX= (X2-X1+1)/2RY=(Y2-Y1+1)/2,於是圓心就是(X1+RX,Y1+RY),半徑就是RXRY中較大者,至於縱橫比例就是RY/RX。於是寫成底下的程序:

      Private Sub Ellispe(ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer)

      Dim t As Integer

      Dim r As Single, rx As Single, ry As Single

      If x1 > x2 Then

      t = x1

      x1 = x2

      x2 = t

      End If

      If y1 > y2 Then

      t = y1

      y1 = y2

      y2 = t

      End If

      rx = (x2 - x1 + 1) / 2

      ry = (y2 - y1 + 1) / 2

      If rx > ry Then r = rx Else r = ry

      Circle (x1 + rx, y1 + ry), r, , , , ry / rx

      End Sub

      本程序一旦寫成,就可以模仿畫出方框時的方法畫出最原始的橢圓,在滑鼠第一次按下左鍵時記錄第一點和上一次位置,並設定DrawMode=6

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

      If Button = 1 Then

      DrawMode = 6

      Ellispe X, Y, X, Y

      x1 = X

      x2 = X

      y1 = Y

      y2 = Y

      End If

      End Sub

      至於MouseMove事件和MouseUp事件只要將Line的部份修改成Ellispe就可以了:

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

      If Button = 1 Then

      Ellispe x1, y1, x2, y2

      x2 = X

      y2 = Y

      Ellispe x1, y1, x2, y2

      End If

      End Sub

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

      If Button = 1 Then

      Ellispe x1, y1, x2, y2

      x2 = X

      y2 = Y

      DrawMode = 13

      Ellispe x1, y1, x2, y2

      End If

      End Sub

      執行結果如下:

      10-15 執行結果(DCircle.Vbp)

    6. 綜合範例

畫出SIN的圖形

專案目標:用電腦畫出Y=SIN(X)的圖形

表單設計:將表單的ScaleMode設定為3BackColor設定為白色。

程式設計:

Private Sub Form_Paint()

Dim HLine As Single

Dim X As Single

? HLine = ScaleHeight / 2

? Line (5, 5)-(5, ScaleHeight - 5)

Line (5, HLine)-(ScaleWidth - 5, HLine)

? For X = 0 To 12.56 Step 0.01

Y = Sin(X)

? PSet (5 + X * HLine / 4, 5 + HLine - Y * HLine / 2)

Next X

End Sub

程式解說:

    1. HLine取得X軸座標的垂直位置。
    2. 本兩列程式碼在畫出X軸和Y軸。
    3. X的值從0~12.56(4π)每隔0.01計算一次函數值,Y值只會在±1之間。
    4. X,Y點放大倍率後顯示出來。電腦的座標和數學的座標不同,所以Y的值取負值。
    5. 執行結果:

      10-16執行結果(Demo1.Vbp)

      用*號畫出圓形

      專案目標:用*號在表單上畫出圓形。

      表單設計:將表單的ScaleMode設定為3BackColor設定為白色。

      程式設計:

      Private Sub Form_Paint()

      Dim X As Integer

      Dim Y As Integer

      Dim R As Integer

      Const PI = 3.14

      ? X = ScaleWidth / 2

      Y = ScaleHeight / 2

      ? If X > Y Then R = Y * 0.9 Else R = X * 0.9

      ? For i = 0 To PI * 2 Step 0.1

      ? CurrentX = X + Cos(i) * R

      CurrentY = Y - Sin(i) * R

      Print "*";

      Next i

      End Sub

      程式解說:

    6. 我們把X點和Y點定在表單的中心,並以它為圓心。
    7. 為了讓畫出來的圖形不會超出表單,所以當X大於Y時,半徑就是Y0.9倍,否則半徑就是X0.9倍,也就是說以比較短的來當半徑。
    8. 我們每次計算的角度為0.1弳,從0計算到2PI(也就是計算一個圓周)
    9. 接下來我們就用三角函數計算出圓周上點的位置,將它指定給目前的座標點,然後用Print顯示『*』即可,請參考下圖。
    10. 執行結果:

       

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

      畫圖工具

      專案目標:設計一個簡單的畫圖工具,可以讓使用者徒手畫、畫出直線、方框和橢圓形

      表單設計:安排四個選項鈕,供使用者選擇畫圖的類型,一個圖片方塊供使用者畫圖。



    11. 10-18 表單設計(Demo3.Vbp)

      屬性設定:

    Name

    Caption

    選項鈕OptionButton

    optTool(0) 徒手畫

    選項鈕OptionButton

    optTool(1) 直線

    選項鈕OptionButton

    optTool(2) 方形

    選項鈕OptionButton

    optTool(3) 橢圓形

    圖片方塊PictureBox

    picDraw  

    程式設計:

    ?

    Dim x1 As Integer, y1 As Integer

    Dim x2 As Integer, y2 As Integer

    Dim Tool As Integer

    ?

    Private Sub Ellispe(ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer)

    Dim t As Integer

    Dim r As Single, rx As Single, ry As Single

    If x1 > x2 Then

    t = x1

    x1 = x2

    x2 = t

    End If

    If y1 > y2 Then

    t = y1

    y1 = y2

    y2 = t

    End If

    rx = (x2 - x1 + 1) / 2

    ry = (y2 - y1 + 1) / 2

    If rx > ry Then r = rx Else r = ry

    picDraw.Circle (x1 + rx, y1 + ry), r, , , , ry / rx

    End Sub

    ?

    Private Sub Draw(ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer)

    Select Case Tool

    Case 1

    picDraw.Line (x1, y1)-(x2, y2)

    Case 2

    picDraw.Line (x1, y1)-(x2, y2), , B

    Case 3

    Ellispe x1, y1, x2, y2

    End Select

    End Sub

    ?

    Private Sub optTool_Click(Index As Integer)

    Tool = Index

    End Sub

    ?

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

    If Button = 1 Then

    If Tool <> 0 Then

    picDraw.DrawMode = 6

    Draw X, Y, X, Y

    x1 = X

    x2 = X

    y1 = Y

    y2 = Y

    Else

    picDraw.PSet (X, Y)

    End If

    End If

    End Sub

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

    If Button = 1 Then

    If Tool <> 0 Then

    Draw x1, y1, x2, y2

    x2 = X

    y2 = Y

    Draw x1, y1, x2, y2

    Else

    picDraw.Line -(X, Y)

    End If

    End If

    End Sub

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

    If Button = 1 Then

    If Tool <> 0 Then

    Draw x1, y1, x2, y2

    x2 = X

    y2 = Y

    picDraw.DrawMode = 13

    Draw x1, y1, x2, y2

    End If

    End If

    End Sub

    程式解說:

  1. 我們以先前的互動式繪圖專案為基礎,宣告X1X2Y1Y2這些變數,Tool變數則是使用者選取工具的類別。大部分的程式碼也和先前的專案類似,目的是引導讀者培養從小專案的程式碼修改,逐漸往中大型專案發展的能力。
  2. 這是畫出內切於方形的橢圓形程序,除了最後一列改成從圖片方塊上輸出外,其餘程式碼都相同。
  3. 在這四種Tool中,徒手畫是比較特殊的,其他三者則是比較接近,我們希望Mouse事件中能夠呼叫Draw程序,就能依照Tool的類別畫出圖形。程序中只要用Select Case 敘述區分Tool的類別後,再分別呼叫畫圖的程序就可以了。
  4. 當使用者選取不同工具的選項鈕時,就要改變Tool的值。
  5. 當滑鼠在圖片方塊按下時,也會產生MouseDown事件,此時檢查Tool是否為0,如果不是0,就用畫框的方式處理:包括記錄位置、將DrawMode改為6、畫出最基本的圖形。如果是0,只要畫出一點就可以了。
  6. MouseMove事件也是依據Tool是否為0做不同的處理,如果是0就畫出直線,如果不是0,就清除原先的圖形,再畫出新的圖形。
  7. MouseUp事件只有在Tool不是0時才需要處理。
  8. 執行結果:

     

    10-19 執行結果(Demo3.Vbp)

    統計圖表

    專案目標:讓使用者輸入若干數字資料,然後將這些資料畫成長條圖。

    表單設計:安排兩個命令鈕,供使用者點選,進行繪圖或清除的工作。安排一個下拉式清單方塊,讓使用者輸入資料。安排一個圖片方塊輸出長條圖。




  9. 10-20 表單設計(Demo4.Vbp)

    屬性設定:

    Name

    Caption

    Style

    命令鈕CommandButton

    cmdClear 清除  

    命令鈕CommandButton

    cmdDraw 畫出  

    下拉式清單方塊ComboBox

    cboData   1

    圖片方塊PictureBox

    picDraw    

    程式設計:

    ?

    Private Sub cboData_KeyPress(KeyAscii As Integer)

    If KeyAscii = 13 Then

    cboData.AddItem cboData.Text

    cboData.SelStart = 0

    cboData.SelLength = Len(cboData.Text)

    End If

    End Sub

    ?

    Private Sub cmdClear_Click()

    cboData.Clear

    End Sub

    Private Sub cmdDraw_Click()

    Dim Max As Integer

    Dim LineWidth As Single, LineHeight As Single

    ? picDraw.Cls

    ? LineWidth = picDraw.ScaleWidth / cboData.ListCount

    ? Max = 0

    For i = 0 To cboData.ListCount - 1

    If Val(cboData.List(i)) > Max Then Max = Val(cboData.List(i))

    Next

    LineHeight = picDraw.ScaleHeight / Max

    For i = 0 To cboData.ListCount - 1

    picDraw.Line (i * LineWidth, picDraw.ScaleHeight - LineHeight * Val(cboData.List(i)))- _

    ((i + 1) * LineWidth - 10, picDraw.ScaleHeight), QBColor(i Mod 15), BF

    Next

    End Sub

    程式解說:

  10. 我們使用下拉式清單方塊讓使用者輸入陣列的資料,為了方便使用者的輸入,使用者按下Enter鍵表示將資料輸入,所以在KeyPress事件中檢查是否按下Enter鍵,一旦按下就用AddItem程序將資料輸入List屬性中,同時將輸入區反白,以便下一個資料的輸入。
  11. 當使用者按下「清除」鈕時,將List屬性清除。
  12. 使用者按下「畫出」鈕時,先清除圖片方塊上的圖形。
  13. LineWidth為每一個長條圖的寬,我們用圖片方塊的寬除以資料量求得此值。
  14. 底下的四列程式碼在找出資料中最大的數值,記錄於Max變數中。
  15. 我們將畫出的長條圖中,最大值的高和圖片方塊同高,LineHeight為每一個資料單位的高。
  16. 畫出長條圖,顏色部分我們以QBColor函數取得,BF表示畫出的圖形是實心的方塊。每一個長條圖都是對齊最底端,所以都用ScaleHeight為計算的基準位置。

執行結果:

 

10-21 執行結果 (Demo4.Vbp)

習題

  1. 設計一個專案:畫出Y=X2的圖形。
  2. 設計一個專案:用SinCos函數畫出正五邊形和正八邊形。
  3. 設計一個專案:畫出Cos(x)的圖形。
  4. 設計一個專案:畫出Log(x)的圖形。
  5. 設計一個專案:畫出y=|x+3|-|x-3|的圖形。
  6. 設計一個專案:用Line程序畫出底下兩個圖形。
  7.  

  8. 設計一個專案:用Circle程序畫出底下兩個圖形。
  9.  

  10. 設計一個專案:讓使用者輸入兩組資料,畫出這兩組資料的折線圖。
  11. 修改畫圖工具專案:使其可以選擇畫出圖形的顏色。
  12. 設計一個專案:讓使用者輸入水平和垂直的格數,在圖片方塊上畫出表格。
  13. 設計一個專案:在上一題中,在每一個格子的中央,顯示表格的編號如下:(以水平有5格,垂直有3格為例)。
  14.