Subscribe to The Blog without a good name        RSS Feed
-----

Programming Forray - Form Transparancy - VB

Icon Leave Comment
Visual Basic Code Snippet
Control Form Transparancy with Mouse Movements

So, how many people have used a program that had a window that gradually became more transparant as you moved your mouse farther away from it or took the focuse away from it and put it on another window. I have and I know I always thought it was neat. So I set about on a code adventure, one of those things I do at random times when I suddenly think of something I want to do in some language (Such as MCI in C++ most recently). So here's my forray into this problem and the solution I found. I find it quite neat if I do say so myself.

By the way, I'll be adding this to my about me section, but anything I post on here, code or otherwise, unless otherwise specified, is free for you to do with what you will. I'm not into hording code to be honest, not that I find anything wrong with people not wanting to share their own hard work. It's just that in my opinion, nothing I write, unless i'm paid for it and can't give it to you (even then, i might give you snippets of it), is so important that I can't freely spread the love around. Anyways, Onwards to my coding adventure. Welcome to the world of VB. Also, just to put this forward too, no comments bashing VB. You don't like VB? Fine. I find it to work great in a Windows only environment when you want a quick app or don't want to spend too much time on it. That being said, I give you the holy undefeatable argument for leaving the VB coders alone, "To each his own."

P.S: I know several other languages as well, so take that as an unbiased opinion.

Part 1: How we know where mouse is? (Spelling intentional for laughs)

Well, lucky us. VB has a way for this. We'll need several things. The first of which is to know that our form has certain members which report the top left edge of the window in relation to the entire screen. Why the top left you ask? Well if you're asking that, this tutorial is not yet for you. You should go read up about how a computer screen is organized first. So shoo, it won't take but five minutes. Seriously, it's not rocket science. :)

So, the first thing we need. The two member variables that tell us about our form. They are:

Me.Left
Me.Top



These two are very self explanatory. I don't think I need to spend anytime telling you what they return. Moving on, the next thing we need is a way to tell where the mouse currently is. Luckily for us, we already have them. We need exactly two things to do this. A System.Drawing.Point and a Windows.Forms.Cursor.Position.

If you want to know what a System.Drawing.Point is, then just think of it as a point in a 2D plane. It consists of a pair of ordered X and Y integers that represent the position of a point on said 2D plane. The C++ users among us will know this as a COORD structure from the Windows API.

Windows.Forms.Cursor.Position returns the position of the cursor (even if it isn't in the form) in the form of a System.Drawing.Point. Thus the code we have for these two is.

Dim P as System.Drawing.Point = Windows.Forms.Cursor.Position



To answer your most immediate question, Yes. We absolutely could just ignore this and use Windows.Forms.Cursor.Position.[X|Y] as we pleased. However, for simplicities sake and because it can change at any second, I'll stick with the one value at the time transparancy is determined.

So we're off to a good start. From here we have to determine the distance between the cursor's current position and the form's top left corner. But wait, if we do it this way, won't the form be transparent if they move their mouse inside the form away from the top left corner? Yes! I will discuss a way around that later. For now we're going to get a simple example up and running and then advance it.

Part 2: Bring out the FORTRA...Algebra!

So anyways, let's take a quick minute to revisit our good friend the distance formula. I don't expect anyone to memorize it, but some people have, mostly because it was force feed down their throats...Oh, ranting. Right. Anyways, the distance formula is: SQRT((x2-x1)^2+(y2-y1)^2). Yeah, lovely. So anyways, we have two points, our form and the mouse, and we want the distance between them. So what do we do? Apply our algebraic genius and twist Pythagorean's Theorem around to suit our purposes. Here we go, Distance formula engage.

So what we essentially want to do here is this.

Distance = SQRT(xOffset^2 + yOffset^2)



Now, where do we get xOffset and yOffset? Well let's tackle that now. There are a couple of steps. First, assuming you want to do it this way, I did and so will in this tutorial, but we want to find the middle of the form. That is, the middle position because we want the distance relative to the middle. I choose the middle because well, the top left of the form is a rather lopsided way to find the mouse distance and ends up calculating different depending on left or right side. So onto the code.

To find the middle point, which is representing by two integers, midX and midY, we do the following.

Dim midX as integer = (Me.Left + (Me.Left+Me.Width)) / 2
Dim midY as integer = (Me.Top + (Me.Top+Me.Height)) / 2



So now we have the point we'll be comparing our mouse to. So all we have to do is have a resize event that will change MidX and MidY if our window size is changed. Also we'll need to have an event for Move since Top and Left will change. Now, you may be wondering what we're doing here. Well, I'll tell you. See, We want the middle point of the window. What that boils down to is the middle of the two widths and heights of the form. We can't get the middle of our form explicitly, but we can using the midpoint formula. That is, the left + (the left + the size) /2 is our midpoint. We have to remember that me.width only returns the number of pixels between me.left and the right side of our form, it doesn't give us the farthest right point on our form. So we do that for both X and Y and we have some offsets.

So now we have a way to get our offsets. Let's see that code now.

Dim XOffset As Double, YOffset As Double

XOffset = System.Math.Abs(P.X - MidX)
YOffset = System.Math.Abs(P.Y - MidY)




So let's explain these lines. First we declare our doubles then we use our Absoulte value function and get the Mouse's X - our MidX and our Mouse's Y - our MidY. So now that we have our offsets, we can find our distance and then set our opacity. BTW, for the math people out there, we'll be finding the SQRT and squaring these later. So don't shoot me, I haven't forgotten the distance formula yet...

Part 3: Run Mouse, Run!

So, let's get down to the nitty gritty and get us a simple example going. Let's start with putting up code for everything, including setting the opacity for the form and then I'll explain the new things. Create yourself a new project in VB and create a form, then add a timer with the default interval and make sure enabled is true. Then double click on the timer so that we can get a tick event. After that, let's put this code in our form.

Public Class Form1

    Private MidX As Integer = (Me.Left + (Me.Left + Me.Width)) / 2
    Private MidY As Integer = (Me.Top + (Me.Top + Me.Height)) / 2

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim P As System.Drawing.Point = Windows.Forms.Cursor.Position
        Dim XOffset As Double, YOffset As Double

        XOffset = System.Math.Abs(P.X - MidX)
        YOffset = System.Math.Abs(P.Y - MidY)

        set_opacity(CInt(System.Math.Sqrt(XOffset ^ 2 + YOffset ^ 2)))
    End Sub

    Sub set_opacity(ByVal Num As Integer)
        Dim Opac As Double
        Opac = 1 - (Num / 1000)
        Opac = CDbl(IIf(Opac < 0, 0, Opac))
        Opac = CDbl(IIf(Opac > 1, 1, Opac))
        Me.Opacity = Opac
    End Sub
End Class



So load it up and play around with it. It works quite well. However, do something for me. Move it to the bottom right and then tell me if it changes the opacity. Nope, or at least, it shouldn't. Why is that? Because the Middle of the form has changed positions, yet we haven't updated our MidX or MidY values. So it still thinks that it's in the default starting position, which for VB is the top left of your screen.

First things first though, let me explain opacity. You may be wondering why I divide by 1000. Well, the answer is, you can use any number you want. 1000 was what I choose because it gives us a good range of opacities. The opacity setting on a form can be anywhere from 0, completely opaque, to 1, completely transparent. Therefore, we divide by a number and then subtract 1 from it so we can get a number between 0-1. On the off chance it's either higher than 1 or lower than 0, we just set it to the nearest one. So, onwards to adjusting for a resize and move.

Part 4: You can't fools me...I's toughist ork around....(I've been hitting the warhammer too much)

So now we need two more events. A Me.Move event and a Me.Resize event. You can create both of these using the handy-dandy property/event drop down menu that Visual Studio offers us - :^: .

Anyways, These are two simple events. All you have to do is copy and paste the MidX and MidY formulas into them. Since you already have these formulas, I don't think I need to write the code out again and so move I'll move on to something else. Form Focus. Let's face it, if they leave your form and go do something else, it doesn't really make sense to keep calculating opacity for our form. Instead, it should quietly disappear and sit in the background. Then when it gets focus again, the calculations start and it becomes completely opaque at first. For this we need a GotFocus and LostFocus event. Here's the code.

Timer1.Enabled = true
Timer1.Start()
Me.Opacity = 1



Timer1.Enabled = false
Timer1.Stop()
Me.Opacity = 0.05



I'll note on LostFocus that I use the value .05 because we don't want the form to be completely invisible. The user might want to click on it to give it focus again, or use alt+tab, or use Windows+tab (for Aero users), or use the taskbar. Either way, they all give focus to the window, so we'll leave it slightly visible for those who are mouse addicts (Joking).

Part 6: The Final

This is a simple part. Here's all the code for it. That's all. Enjoy! Look out for more forrays into my programming adventures - I think it's time to do a Python one.


Public Class Form1

    Private MidX As Integer = (Me.Left + (Me.Left + Me.Width)) / 2
    Private MidY As Integer = (Me.Top + (Me.Top + Me.Height)) / 2

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim P As System.Drawing.Point = Windows.Forms.Cursor.Position
        Dim XOffset As Double, YOffset As Double

        XOffset = System.Math.Abs(P.X - MidX)
        YOffset = System.Math.Abs(P.Y - MidY)

        set_opacity(CInt(System.Math.Sqrt(XOffset ^ 2 + YOffset ^ 2)))
    End Sub

    Sub set_opacity(ByVal Num As Integer)
        Dim Opac As Double
        Opac = 1 - (Num / 1000)
        Opac = CDbl(IIf(Opac < 0, 0, Opac))
        Opac = CDbl(IIf(Opac > 1, 1, Opac))
        Me.Opacity = Opac
    End Sub

    Private Sub Form1_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
        Timer1.Enabled = True
        Timer1.Start()
        Me.Opacity = 1
    End Sub

    Private Sub Form1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LostFocus
        Timer1.Enabled = False
        Timer1.Stop()
        Me.Opacity = 0.05
    End Sub

    Private Sub Form1_Move(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Move
        MidX = (Me.Left + (Me.Left + Me.Width)) / 2
        MidY = (Me.Top + (Me.Top + Me.Height)) / 2
    End Sub

    Private Sub Form1_ResizeEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ResizeEnd
        MidX = (Me.Left + (Me.Left + Me.Width)) / 2
        MidY = (Me.Top + (Me.Top + Me.Height)) / 2
    End Sub
End Class




If you feel like using this in a big project, I have one word for you. Module. Enough said. Toodles.

0 Comments On This Entry

 

December 2014

S M T W T F S
 123456
78910111213
14151617181920
21 222324252627
28293031   

Tags

Recent Entries

Search My Blog

0 user(s) viewing

0 Guests
0 member(s)
0 anonymous member(s)