VB .NET - Os novos recursos de desenho do GDI+


Se você usou recursos de controles gráficos em suas aplicações VB6 ao migrar o seu projeto para o VB 2005 vai perceber que muitos recursos não existem mais, pelo menos não da mesma forma como eram usados antes.

No VB6 os objetos Shape, Line , Circle, Point, PaintPicture eram muito simples de usar e permitiam o acesso a recursos gráficos de uma modo direto e simples. Se você conhecia os controles sabe do que eu estou falando...

Como obter o mesmo resultado no VB 2005 ? Quais o novos objetos disponíveis que podem ser usados nestes casos ?

A plataforma .NET traz as classes do pacote GDI+ que permite um eficaz tratamento dos recursos gráficos.

Não existe no entanto uma forma simples e direta de obter os mesmos efeitos que os objetos Line, Shape, Point permitiam no VB6.

Você pode até usar o controle Label para simular algumas das características obtidas com os objetos de desenho do VB6 as classes GDI+ permitem efetuar estas operações.

Os conceitos no VB.NET são novos e desta forma quando mencionamos que vamos desenhar no formulário estaremos desenhando através do objeto Graphics que por sua vez usa o evento Paint do formulário. Assim para desenhar uma linha em um formulário fazemos:

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        ' ----- Desenha uma linha
         e.Graphics
.DrawLine(…)
End Sub

Você também pode criar um objeto Graphics a qualquer hora em qualquer outro evento e método usando o método CreateGraphics:

Dim formCanvas As Graphics = Me.CreateGraphics()
     e.Graphics.DrawLine(…)

' libera o objeto do tipo Graphics.
formCanvas.Dispose()

O lugar mais comum para você colocar o código para desenho é no evento Paint do formulário ou controle no qual você deseja desenhar. Exemplo de evento Paint no formulário:

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint

Você pode usar outros eventos ou métodos também , mas você terá menos problemas deixando a tarefa por conta do sistema do que forçar a tarefa de desenhar em objetos baseados em outros eventos.

O evento Paint fornece parâmetros úteis para ajudá-lo com esta tarefa. Você pode criar seus próprios objetos gráficos, uma técnica que pode ser útil em algumas ocasiões , mas quando desenhar usando o evento Paint você pode simplesmente usar o objeto Graphics passado para o evento. Desta forma você pode referenciar o objeto e.Graphics , ou você pode criar uma referência para ele:

Exemplo:
' Obtendo um objeto graphics para este formulario.
Dim canvas As Graphics = e.Graphics

Como você usa muito o objeto Graphics em um método Paint manter a referência ao objeto simplifica o seu código.

Além do objeto Graphics você usará também com muita frequência os objetos : Colors, Pen e Fonts:

1-) - Objeto Color - Você pode definir cores para desenhar usando o objeto Color de diversas formas. Após criar uma instância da classe Color você pode escolher a cor de uma relação de cores exibidas para o objeto.

Exemplo:
'usando um cor definida para objeto Dim colorBackground As Color = Color.Cornsilk

Você pode também construir suas próprias cores definindo cada componente red, green e blue da cor com valores de 0 até 255:

Exemplo:
Dim colorRed As Color = Color.FromArgb(255, 0, 0)
Dim colorTransparentGreen As Color = Color.FromArgb(127, 0, 255, 0)


2-) Objeto Pen - Este objeto é usado como um parâmetro para muitos métodos de desenho : linhas, elipses, retângulos e polígonos são todos desenhados usando um objeto Pen para definir as linhas usadas para construí-los.

Um objeto Pen básico é composto de uma cor e de uma largura opcional. Se a largura não for definida , o padrão é usar 1 unidade (o modo escala deve estar definido para pixels). Se você definir uma escala diferente , embora a largura continue com o mesmo valor, a aparência deverá ser modificada.

Exemplo:
' ----- Cria objetos Pens.
Dim pen1 As New Pen(Color.Blue)
Dim pen2 As New Pen(colorRed, 25)

3-) Objeto Font - Estes objetos são requeridos sempre que um texto for desenhado na superfície gráfica. Existem diversas formas de definir um novo objeto Font: você pode especificar o seu nome e algumas propriedades como tamanho, ou pode começar com uma fonte já dada e efetuar alterações:

Exemplo:
' -----Cria fontes
Dim font1 As New Font("Arial", 24, FontStyle.Bold Or FontStyle.Italic)
Dim font2 As New Font(Me.Font, FontStyle.Regular

Após repassar estes conceitos básicos sobre os novos recursos de desenho no VB.NET vejamos a seguir como substituir alguns dos controles de desenho usados no VB6:

1- O controle Line

Você pode desenhar linhas em um formulário, no evento Paint, usando o método DrawLine().

Para desenhar uma linha você vai precisar conhecer duas coisas:

Você pode criar um objeto Pen previamente ou pode usar diretamente como argumento do método DrawLine. Na posição final e inicial da linha você pode usar objetos Point - que podem ter sidos criados previamente ou serem usados como argumentos - ou simplesmente usar valores para representar as posições de X e Y do inicio e do fim da linha.

Para desenhar uma linha reta usando os objetos Pen e Point podemos fazer:

Dim p As Pen = New Pen(Color.blue, 3)

Os objetos Point podem ser criados da mesma maneira:

Dim P1 As Point = New Point(20, 20)
Dim P2 As Point = New Point(100, 50)

Exemplo para desenhar a linha :

g.DrawLine(p, P1, P2)

2- O método Cls()

Para limpar uma superfície gráfica , você usa o método Clear() passado como argumento na cor usada para a superfície:

e.Graphics.Clear(Color.White)
3- O método Scale()

Para modificar o sistema de coordenadas na superfície do formulário usamos o método ScaleTransform() do objeto Graphics.

4- O método PSet()

Não há no VB.NET nenhum método que pode ser usado para desenhar um único pixel na superfície gráfica. Podemos simular o efeito usando os métodos DrawLine(), DrawRectangle(), ou FillRectangle() e fornecer coordenadas precisas. Outra forma de desenhar um simples ponto é criar um bitmap representando um ponto e desenhar o bitmap :

	' ----- Desenha um ponto verrmelho
	Dim novoBitmap As New Bitmap(1, 1)
	novoBitmap.SetPixel(0, 0, Color.Red)
	e.Graphics.DrawImageUnscaled(novoBitmap, 15, 15)
	novoBitmap.Dispose()

5- O método Point()

Embora o objeto Graphics não permita consultar a cor individual de um pixel, você pode isto usando o objeto BitMap. O método GetPixel deste objeto retorna a cor do objeto para o pixel especificado

6- O método Circle()

Este método foi substituído pelos métodos DrawEllipse e FillElipse.

7- O método PaintPicture()

Este método foi substituído pelo método DrawImage()

8- Desenhar retângulos e elipses

Para desenhar formas retangulares e elipses podemos usar os métodos DrawRectangle() e DrawEllipse. Se desejar desenhar estas figuras preenchidas deve-se usar os métodos FillRectangle() e FillEllipse().

9- Retângulo com cantos arredondados

Não há um método para desenhar um retângulo com cantos arredondados no VB.NET. Para realizar esta tarefa você deverá usar uma combinação dos métodos DrawLine() e DrawArc().

Desenhando linhas,  retângulos e elipses

Vamos criar uma pequena aplicação no VB 2005 Express  para mostrar como desenhar linhas, retângulos e elipses.

Crie um novo projeto do tipo Windows Application usando a linguagem VB.NET dando o nome de desenhoNet ao projeto.

No formulário principal , form1.vb , inclua os controles : PictureBox, RadioButton , ComboBox e GroupBox conforme a figura abaixo:

A seguir inclua o seguinte código no formulário:

Private primeiroPonto As Point = New Point(-1, -1)

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

' ----- Preenche a lista de cores
For Each nomeCor As String In New String() {"Black", "Red", "Orange", "Yellow", "Green", "Blue", "Indigo", "Violet", "White"}
    cboCorLinha.Items.Add(nomeCor)
    cboCorPreenchimento.Items.Add(nomeCor)
Next nomeCor

cboCorLinha.SelectedIndex = cboCorLinha.Items.IndexOf("Black")
cboCorPreenchimento.SelectedIndex = cboCorLinha.Items.IndexOf("White")

End Sub

Private Sub areaDesenho_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Handles areaDesenho.MouseDown

' ----- definindo objetos para desenho
Dim usarLinha As Pen
Dim usarPreenchimento As Brush
Dim canvas As Graphics
Dim desenharContornos As Rectangle

' ----- Verifica se é o primeiro ou segundo click do mouse
If (primeiroPonto.Equals(New Point(-1, -1))) Then
    ' Primeiro click : registra a localização.
   
primeiroPonto = e.Location
    ' desenha uma marca neste ponto
   
Desenhar(primeiroPonto)
Else
   ' Obtem as duas cores usadas e definidas nas combobox
   
usarLinha = New Pen(Color.FromName(cboCorLinha.Text))
    usarPreenchimento = New SolidBrush(Color.FromName(cboCorPreenchimento.Text))

   'obtem a área para desenhar
   
canvas = areaDesenho.CreateGraphics()

   ' Remove a marca do primeiro ponto.
    Desenhar(primeiroPonto)

   ' Para retangulos e elipses obtem o contorno da área
   desenharContornos = New Rectangle( _
   Math.Min(primeiroPonto.X, e.Location.X), _
   Math.Min(primeiroPonto.Y, e.Location.Y), _
   Math.Abs(primeiroPonto.X - e.Location.X), _
   Math.Abs(primeiroPonto.Y - e.Location.Y))

    '  começa a desenhar
  
If (rdbLinha.Checked = True) Then
         ' ----- Desenha a linha.
        canvas.DrawLine(usarLinha, primeiroPonto, e.Location)
    ElseIf (rdbRetangulo.Checked = True) Then
        ' ----- Desenha o retângulo.
        canvas.FillRectangle(usarPreenchimento, desenharContornos)
        canvas.DrawRectangle(usarLinha, desenharContornos)
     Else
         ' ----- Desenha a elipse.
        canvas.FillEllipse(usarPreenchimento, desenharContornos)
         canvas.DrawEllipse(usarLinha, desenharContornos)
     End If

     ' -----limpa tudo.
    canvas.Dispose()
    usarPreenchimento.Dispose()
    usarLinha.Dispose()
    primeiroPonto = New Point(-1, -1)
 End If
End Sub

Private Sub Desenhar(ByVal centerPoint As Point)
   ' Dado um ponto, desenha um pequeno quadrado no local
   Dim ponto As Point
   Dim preencheArea As Rectangle

   'Determina a área a ser preenchida
   ponto = areaDesenho.PointToScreen(centerPoint)
    preencheArea = New Rectangle(ponto.X - 2, ponto.Y - 2, 5, 5)

   ' Desenha o retangulo. Cyan é o inverso RGB de red
    ControlPaint.FillReversibleRectangle(preencheArea, Color.Cyan)
End Sub

Executando o projeto e efetuando algumas operações de desenho obtemos o seguinte resultado:

Temos que admitir que em alguns aspectos desenhar figuras era muito mais simples no VB6 que no VB.NET.

Pegue o projeto exemplo completo aqui: desenhoNet.zip

Até o próximo artigo .NET...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti