Transparency – Performance Issues

hercemer

Newcomer
Joined
Apr 21, 2003
Messages
11
I have written a touch screen overlay program. It is essentially a full screen application with a transparent background, and buttons.

Here is the code I use to set the form to be transparent -
Code:
        Me.TransparencyKey = Color.FromArgb("-9999999")
        Me.BackColor = Color.FromArgb("-9999999")
        Me.TopMost = True

The problem is that the application that runs behind the form is noticeably slower than if the overlay were not running. It redraws slower, menus pull up slower etc…

On fast machines (p4, 1gb RAM, “gaming” video card), it is not as noticeable. But, on an 800mhz, on-board video, 256 mb ram for eg, it is very bad.

Turning video acceleration off makes a big difference, but not enough.

Any others tips/tricks/better ways to do this?

Thanks!
 
hercemer said:
Any others tips/tricks/better ways to do this?

How 'brave' are you. There is the LowLevelMouseProc API that allows you to hook into every action the mouse makes. Note the emphasis on the word EVERY. You'll probably get each individual mousemove as well ;). (more info: http://msdn.microsoft.com/library/d...reference/hookfunctions/lowlevelmouseproc.asp)

Note that incorrect handling of this API will probably render the mouse non-functional, so be carefull with it ;).
The x and y coordinates are part of the MSLLHOOKSTRUCT stored in the lParam of the callback method.

I never used this myself but be sure to read the remarks in the article, it is pretty low level stuff and has some demands/effects on the use of it.
 
Was this meant as a reply to my question?

Wile said:
How 'brave' are you. There is the LowLevelMouseProc API that allows you to hook into every action the mouse makes. Note the emphasis on the word EVERY. You'll probably get each individual mousemove as well ;). (more info: http://msdn.microsoft.com/library/d...reference/hookfunctions/lowlevelmouseproc.asp)

Note that incorrect handling of this API will probably render the mouse non-functional, so be carefull with it ;).
The x and y coordinates are part of the MSLLHOOKSTRUCT stored in the lParam of the callback method.

I never used this myself but be sure to read the remarks in the article, it is pretty low level stuff and has some demands/effects on the use of it.
 
Possibly you could use:
Visual Basic:
Sub Form_Load() etc
    Me.TopMost = True
    Me.Opacity = 0
End Sub
I haven't noticed any type of performance hit with using opacity.
 
Likewise, I haven't noticed this difference. Since you are using layered windows, however, I suppose that this behavior might vary, depending on graphics hardware.
 
Opacity also affects the controls on the form, so that wouldn't work.

Well, the only thing I can think of is going to the source. When you set the background transparent, .net calls a painttransparentbackground function...instead of checking to see if the background is transparent, you could override OnPaintBackground and just paint it transparent. It gets rid of a few if-then statements.

Unfortunately, I haven't been able to get it to work...but here's the code if your interested...

If you comment out the 4th to last line
graphics1.FillRectangle(SystemBrushes.Control, pevent.ClipRectangle)

You'll notice it gives the same effect as a transparent background...but the form still picks up mouse input.

The parent control is always null. The actual painttransparentbackground function uses control1 = me.parentInternal, but this property is not accessible from the form class.


Visual Basic:
Imports System.Drawing.Drawing2D
Imports System.Runtime.InteropServices

Public Class Form1
    Inherits System.Windows.Forms.Form

    <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _
Public Shared Function MapWindowPoints(ByVal hWndFrom As HandleRef, ByVal hWndTo As HandleRef, ByVal pt As Point, ByVal cPoints As Integer) As Integer
    End Function

#Windows Designer Code

 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.TopMost = True
    End Sub


    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
        Dim graphics1 As Graphics = pevent.Graphics
        Dim control1 As Control = Me.Parent

        If (Not control1 Is Nothing) Then
            Dim num1 As Integer = 0
            Dim point1 As New Point(0, 0)

            MapWindowPoints(New HandleRef(Me, Me.Handle), New HandleRef(control1, control1.Handle), point1, 1)

            pevent.ClipRectangle.Offset(point1.X, point1.Y)
            Dim args1 As New PaintEventArgs(graphics1, pevent.ClipRectangle)
            Dim state1 As GraphicsState = graphics1.Save
            Try
                graphics1.TranslateTransform(CType(-point1.X, Single), CType(-point1.Y, Single))
                Me.InvokePaintBackground(control1, args1)
                graphics1.Restore(state1)
                state1 = graphics1.Save
                graphics1.TranslateTransform(CType(-point1.X, Single), CType(-point1.Y, Single))
                Me.InvokePaint(control1, args1)
                Return
            Finally
                graphics1.Restore(state1)
            End Try
        End If
        graphics1.FillRectangle(SystemBrushes.Control, pevent.ClipRectangle)
        graphics1.Dispose()
    End Sub
End Class


I don't know if the performance increase is worth the effort.
 
Last edited:
hercemer said:
Was this meant as a reply to my question?

Yes.

I dont know what kind of system you are working for but looking at those system requirements I had the idea you might be developing for a fixed hardware platform (like ATM machines or something) where changes in the hardware are next to impossible.

In such cases having a completely different approach might solve the problem. The hook I described above lets you look into the mouse actions (I made the assumption that the touchscreen works as a mouse driver ;) ) without using any overlay / graphic mechanism at all.
 
Back
Top