window visual styles...

lidds

Junior Contributor
Joined
Nov 9, 2004
Messages
210
I'm currently writing a program in vb.net on xp pro, but I have seen various pieces of software that when installed have there own visual styles, even if the program is intalled on xp or 2000. Could someone tell me how to apply these types of visual styles to my application so the style is kept between operating sytems? Also where I could download these styles from? And how I apply them to my application?

Cheers

Simon
 
If you want controls that use your own graphics, you must make your own controls. The easiest, but not necessarily best, way to do this is with the UserControl. Add a UserControl to your project, and program the whole control yourself. Have fun. There may be other ways to do this, perhaps owner drawn windows controls, but... with simple things like buttons its easier to draw five pictures for different states of your control and show the text in a transparent label and show the correct image when certain events are raised.
 
I don't think that transparent labels and five images are really the right way to go. It is better to program a user control as it is much more versitile, can use less programming space if used a few times in the project and can be easily transfered from project to project without having to re-invent the wheel every time.

Here's an example of a bitmap button user control that inherits a button. It has three public properities for down, norm and over images that work in conjunction with the mouse. It also converts the image to gray scale when it is disabled. This control only took a few hours to program. I know it's probably a bit advanced for a beginner, but this example will accelerate the learning curve in a positive way.

I hope that this will help you guys out.

Visual Basic:
Imports System.Drawing
Imports System.Drawing.Imaging

Public Class BitmapButton
    Inherits System.Windows.Forms.Button

#Region " Windows Form Designer generated code "

    'UserControl overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container()
    End Sub

#End Region

    Private _imgNorm As Image
    Private _imgOver As Image
    Private _imgDown As Image
    Private overMouse As Boolean = False
    Private downMouse As Boolean = False

#Region " New Sub"

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call
        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        SetStyle(ControlStyles.DoubleBuffer, True)
        SetStyle(ControlStyles.ResizeRedraw, True)
        MyBase.BackColor = System.Drawing.SystemColors.Control
    End Sub

#End Region

#Region " Public Properities"

    Public Property ImageNorm() As Image
        Get
            Return _imgNorm
        End Get
        Set(ByVal Value As Image)
            _imgNorm = Value
            Me.Invalidate()
        End Set
    End Property

    Public Property ImageOver() As Image
        Get
            Return _imgOver
        End Get
        Set(ByVal Value As Image)
            _imgOver = Value
            Me.Invalidate()
        End Set
    End Property

    Public Property ImageDown() As Image
        Get
            Return _imgDown
        End Get
        Set(ByVal Value As Image)
            _imgDown = Value
            Me.Invalidate()
        End Set
    End Property

#End Region

#Region " Protected Overrides Subs"

#Region " OnPaint Sub"

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        'check background image
        If MyBase.BackgroundImage Is Nothing Then
            If Not MyBase.BackColor.ToArgb = Color.Transparent.ToArgb Then
                e.Graphics.FillRectangle(New SolidBrush(MyBase.BackColor), 0, 0, MyBase.Width, MyBase.Height)
            End If

        Else 'paint background image
            Dim i As Integer
            If MyBase.BackgroundImage.Width < MyBase.Width Then
                For i = 0 To MyBase.Width - 1 Step MyBase.BackgroundImage.Width
                    e.Graphics.DrawImage(MyBase.BackgroundImage, i, 0)
                Next
            Else : e.Graphics.DrawImage(MyBase.BackgroundImage, 0, 0)
            End If
            If MyBase.BackgroundImage.Height < MyBase.Height Then
                For i = 0 To MyBase.Height - 1 Step MyBase.BackgroundImage.Height
                    e.Graphics.DrawImage(MyBase.BackgroundImage, 0, i)
                Next
            Else : e.Graphics.DrawImage(MyBase.BackgroundImage, 0, 0)
            End If
        End If

        If _imgNorm Is Nothing Then
            e.Graphics.DrawEllipse(New Pen(MyBase.ForeColor, 1), 0, 0, MyBase.Width - 1, MyBase.Height - 1)
            Dim noImage As String = "   No" & vbCrLf & "Images"
            Dim txtSize As SizeF = e.Graphics.MeasureString(noImage, MyBase.Font)
            e.Graphics.DrawString(noImage, MyBase.Font, New SolidBrush(MyBase.ForeColor), CInt((MyBase.Width - txtSize.Width) / 2), CInt((MyBase.Height - txtSize.Height) / 2))
            Exit Sub

        ElseIf Not _imgNorm Is Nothing Then

            If MyBase.Enabled Then
                If overMouse = False And downMouse = False Then
                    e.Graphics.DrawImage(_imgNorm, 0, 0)
                ElseIf overMouse = True And downMouse = False Then
                    If Not _imgOver Is Nothing Then
                        e.Graphics.DrawImage(_imgOver, 0, 0)
                    Else : e.Graphics.DrawImage(_imgNorm, 0, 0)
                    End If
                ElseIf overMouse = True And downMouse = True Then
                    If Not _imgDown Is Nothing Then
                        e.Graphics.DrawImage(_imgDown, 0, 0)
                    Else : e.Graphics.DrawImage(_imgNorm, 0, 0)
                    End If
                Else : e.Graphics.DrawImage(_imgNorm, 0, 0)
                End If

            ElseIf Not MyBase.Enabled Then
                e.Graphics.DrawImage(convert2Grayscale(_imgNorm), 0, 0)
            End If
        End If

        If Not MyBase.Text = Nothing Then

            'measure text
            Dim txtSize As SizeF
            txtSize = e.Graphics.MeasureString(MyBase.Text, MyBase.Font)

            'set strFormat
            Dim strFormat As New StringFormat()
            Select Case MyBase.TextAlign
                Case ContentAlignment.BottomLeft, ContentAlignment.MiddleLeft, ContentAlignment.TopLeft
                    strFormat.Alignment = StringAlignment.Near
                Case ContentAlignment.BottomCenter, ContentAlignment.MiddleCenter, ContentAlignment.TopCenter
                    strFormat.Alignment = StringAlignment.Center
                Case ContentAlignment.BottomRight, ContentAlignment.MiddleRight, ContentAlignment.TopRight
                    strFormat.Alignment = StringAlignment.Far
            End Select

            Dim rectF As RectangleF
            rectF.X = 0
            rectF.Width = MyBase.Width
            rectF.Height = MyBase.Height

            Dim txtLinesReqd, txtHeightReqd, txtWidth, i As Integer
            Dim txtWidths() As String
            If txtSize.Width > rectF.Width Then
                txtLinesReqd = CInt(Math.Ceiling(txtSize.Width / rectF.Width))
                txtHeightReqd = txtLinesReqd * txtSize.Height
                txtWidths = Split(MyBase.Text, Environment.NewLine)
                For i = 0 To txtWidths.GetUpperBound(0)
                    If txtWidths(i).Length > txtWidth Then
                        txtWidth = txtWidths(i).Length
                    End If
                Next
            Else
                txtHeightReqd = txtSize.Height
                txtWidth = txtsize.Width
            End If

            'find rectF.Y
            Select Case MyBase.TextAlign
                Case ContentAlignment.TopCenter, ContentAlignment.TopLeft, ContentAlignment.TopRight
                    rectF.Y = 0
                Case ContentAlignment.MiddleCenter, ContentAlignment.MiddleLeft, ContentAlignment.MiddleRight
                    rectF.Y = CInt((MyBase.Height - txtHeightReqd) / 2)
                Case ContentAlignment.BottomCenter, ContentAlignment.BottomLeft, ContentAlignment.BottomRight
                    rectF.Y = MyBase.Height - txtHeightReqd
            End Select

            Dim txtBrush As SolidBrush
            If MyBase.Enabled Then
                txtBrush = New SolidBrush(MyBase.ForeColor)

                If overMouse = False And downMouse = False Then 'image norm
                    e.Graphics.DrawString(MyBase.Text, MyBase.Font, txtBrush, rectF, strFormat)
                ElseIf overMouse = True And downMouse = False Then 'image over
                    e.Graphics.DrawString(MyBase.Text, MyBase.Font, txtBrush, rectF, strFormat)
                ElseIf overMouse = True And downMouse = True Then 'image down
                    rectF.X += 1
                    rectF.Y += 1
                    e.Graphics.DrawString(MyBase.Text, MyBase.Font, txtBrush, rectF, strFormat)
                End If

            Else 'disabled gray image
                txtBrush = New SolidBrush(Color.Gray)
                e.Graphics.DrawString(MyBase.Text, MyBase.Font, txtBrush, rectF, strFormat)
            End If

            If Not txtBrush Is Nothing Then txtBrush.Dispose()
        End If
    End Sub

#End Region
continued on next post...
 
Last edited:
continuation:
Visual Basic:
#Region " convert2Grayscale Function"

    Private Function convert2Grayscale(ByVal bmp As Bitmap) As Bitmap
        Dim gScale, x, y As Integer
        Dim grayBmp As New Bitmap(bmp)

        For y = 0 To grayBmp.Height - 1
            For x = 0 To grayBmp.Width - 1
                If Not grayBmp.GetPixel(x, y).ToArgb = 0 Then
                    With grayBmp.GetPixel(x, y)
                        'convert to gray scale
                        gScale = 0.3 * .R + 0.5 * .G + 0.2 * .B
                    End With
                    'set black to dim gray and whites to Gainsboro
                    If grayBmp.GetPixel(x, y).B < 20 Then
                        grayBmp.SetPixel(x, y, Color.DimGray)
                    ElseIf grayBmp.GetPixel(x, y).B > 240 Then
                        grayBmp.SetPixel(x, y, Color.Gainsboro)
                    Else : grayBmp.SetPixel(x, y, Color.FromArgb(255, gScale, gScale, gScale))
                    End If
                End If
            Next
        Next
        Return grayBmp
    End Function
#End Region

#Region " OnSizeChanged Sub"

    Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
        Me.Refresh()
        MyBase.OnSizeChanged(New EventArgs())
    End Sub
#End Region

#Region " OnGotFocus Sub"

    Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
        overMouse = True
        downMouse = False
        Me.Invalidate()
        MyBase.OnGotFocus(e)
    End Sub
#End Region

#Region " OnLostFocus Sub"

    Protected Overrides Sub OnLostFocus(ByVal e As System.EventArgs)
        overMouse = False
        downMouse = False
        Me.Invalidate()
        MyBase.OnLostFocus(e)
    End Sub
#End Region

#End Region

#Region " Protected Overrides Mouse Events"

    Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
        If _imgNorm Is Nothing Then Exit Sub
        Me.overMouse = False
        Me.downMouse = False
        Me.Invalidate()
        MyBase.OnMouseLeave(e)
    End Sub

    Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
        If _imgNorm Is Nothing Then Exit Sub
        Me.overMouse = True
        Me.downMouse = False
        Me.Invalidate()
        MyBase.OnMouseEnter(e)
    End Sub

    Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
        If _imgNorm Is Nothing Then Exit Sub
        Me.overMouse = True
        Me.downMouse = True
        Me.Invalidate()
        MyBase.OnMouseDown(e)
    End Sub

    Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
        If _imgNorm Is Nothing Then Exit Sub
        Me.overMouse = True
        Me.downMouse = False
        Me.Invalidate()
        MyBase.OnMouseUp(e)
    End Sub
#End Region

End Class
 
Here's a customized button control in C#. I use it if I want images on an XP style button...Has anyone tried to put an image on an XP button... it takes soo long to draw. This control has 3 built in styles, Windows Xp style, Xp Eggplant and Xp something else, and it's really lightweight. I like it.
 

Attachments

Back
Top