views:

163

answers:

1
Public Class HighlightKey
    Inherits Control
    Private m_fillColor As Color = Color.White
    Private m_opacity As Integer = 100
    Private alpha As Integer
    Private m_image As Image

    Public Sub New()

        SetStyle(ControlStyles.SupportsTransparentBackColor, True)
        SetStyle(ControlStyles.Opaque, True)
        Me.BackColor = Color.Transparent
        Console.WriteLine("new Highlight key ")
    End Sub

    Public Property Image() As Image
        Get
            Return m_image
        End Get
        Set(ByVal value As Image)
            m_image = value
        End Set
    End Property

    Protected Overloads Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or &H20
            Return cp
        End Get
    End Property

    Protected Overloads Overrides Sub OnBackColorChanged(ByVal e As EventArgs)
        If Me.Parent IsNot Nothing Then
            Parent.Invalidate(Me.Bounds, True)
        End If
        MyBase.OnBackColorChanged(e)
    End Sub

    Protected Overloads Overrides Sub OnParentBackColorChanged(ByVal e As EventArgs)
        Me.Invalidate()
        MyBase.OnParentBackColorChanged(e)
    End Sub


    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaintBackground(pevent)
    End Sub

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

        Dim g As Graphics = e.Graphics
        Dim brush As New SolidBrush(Me.ForeColor)
        Dim StringSize As New SizeF

        alpha = (m_opacity * 255) / 100

        If m_image IsNot Nothing Then
            StringSize = g.MeasureString(Me.Text, Me.Font)
            Dim x As Integer = (CInt(Me.m_image.Width) - CInt(StringSize.Width)) / 2
            g.DrawImage(m_image, 0, 0, m_image.Width, m_image.Height)
            g.DrawString(Me.Text, Me.Font, brush, x, 20)
        End If

        brush.Dispose()
        g.Dispose()
        MyBase.OnPaint(e)
    End Sub

    Public Function SetImgOpacity(ByVal imgPic As Image, ByVal imgOpac As Single) As Image


        Dim bmpPic As New Bitmap(imgPic.Width, imgPic.Height)

        Dim gfxPic As Graphics = Graphics.FromImage(bmpPic)

        Dim cmxPic As New ColorMatrix()
        cmxPic.Matrix33 = imgOpac

        Dim iaPic As New ImageAttributes()
        iaPic.SetColorMatrix(cmxPic, ColorMatrixFlag.[Default], ColorAdjustType.Bitmap)

        gfxPic.DrawImage(imgPic, New Rectangle(0, 0, bmpPic.Width, bmpPic.Height), 0, 0, imgPic.Width, imgPic.Height, _
         GraphicsUnit.Pixel, iaPic)

        gfxPic.Dispose()
        Return bmpPic
    End Function

    Private Sub HighlightKey_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LocationChanged
        Me.Refresh()
    End Sub

    Private Sub HighlightKey_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.TextChanged
        Me.Refresh()
    End Sub
End Class

i have created a control as above, this control allows me to import a png with alpha channel and random shape. and then it can display on top of any other control, i.e. textbox, picturebox,etc. and the background should always show what right under it, instead of just show its parent control.

it worked if it's static mode, ie stand still in the form. but when i tried to drag/move it, the control wouldn't render itself properly,and also goes underneath other controls.

can any one give me a hand on this please?

+1  A: 

The background is no longer correct when you move it. The control doesn't know it, you'll have to tell it by calling its Invalidate() method.

It dipping underneath controls is a Z-order problem. That can be difficult to fix if the form contains any nested container controls like Panels, UserControls or GroupBoxes. You can't get it displayed on top of those. But as long as everything has the form as its Parent then calling BringToFront() on the control will make sure that it is always on top.

A more generic solution is a form that overlays the original and has its TransparencyKey property set to its BackColor so that it is completely transparent. Any control you put on that form will always be on top. My code in this thread demonstrates the overlay idea.

If you are creating your own designer, you'll want to read this article.

Hans Passant
Or a layered window.
SLaks
Yes, the form overlay *is* a layered window.
Hans Passant
yes, actually i have already done the overlay solution, why i m doing this again is, I'm using the overlayed form as a highligh key on a touch screen keyboard interface (like iPhone and other touch screen phone's keyboard) and it's causing problem with SendKey.send
You don't need the overlay until you start moving controls. That ought to solve the SendKey problem.
Hans Passant