Page 1 of 1

Peer-To-Peer Chat - Advanced! Rate Topic: -----

#1 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 944
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Post icon  Posted 08 May 2011 - 11:52 AM

Due to how popular my C# peer-to-peer chat tutorial was I decided to do a VB.NET version. The approach that I'm taking requires that you have two computers on a local area network, or you could have one computer and use virtual machines. Basically, you can only run one peer on a single computer.

I've seen many P2P chat systems around the web that use a client/server approach using TCP (Transmission Control Protocol). I'm going to take a pure peer-to-peer approach using UDP (User Datagram Protocol). In this system there is no server, each of the peers is equal to any other peer. Just a quick background on TCP and UDP. TCP and UDP are part of the TCP/IP protocol suite for networking. TCP is a connection based protocol where you need a connection between hosts. UDP is a connectionless protocol where a sender just sends out data and doesn't care if it is received or not.

To get started create a new Windows Forms application called PeerToPeerChat. Right click the Form1.cs that was generated and select Rename. Change the name of this form to ChatForm.vb. When it asks if you want to change the instances of the form in code say yes. I also added in a very simple form to log in a user. Right click the PeerToPeerChat project in the Solution Explorer and select Add|Windows Form. Name this new form LoginForm. Onto the form I dragged a Label, Text Box, and Button. My finished form in the designer looked like this.

Attached Image

The Text Box I named tbUserName and the Button btnOK. I set the MaximumLength property of tbUserName to 32 as you don't want very long user names and the Text property of btnOK to OK. Now, open up the code for LoginForm and change it to the following. Sorry for the C# accent here, I know I'm not using VB-ish names.

Public Class LoginForm

    Private user As String

    Public ReadOnly Property UserName() As String
        Get
            UserName = user
        End Get
    End Property

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        AddHandler btnOK.Click, AddressOf btnOK_Click
        AddHandler Me.FormClosing, AddressOf LoginForm_Closing

    End Sub

    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        user = tbUserName.Text.Trim()

        If (String.IsNullOrEmpty(user)) Then
            MessageBox.Show("Please enter a user name up to 32 characters.");
            Exit Sub
        End If

        RemoveHandler Me.FormClosing, AddressOf LoginForm_Closing
        Me.Close()

    End Sub

    Private Sub LoginForm_Closing(ByVal sender As System.Object, ByVal e As System.EventArgs)
        user = ""
    End Sub

End Class



The first thing I did was add a field, user and a public read only property, UserName to expose its value. This is one way of getting data from one form to another. It is safer than making a field public, in the sense that a public field can be assigned to outside of the form but a public read only property can't. In the constructor I wired handlers for the FormClosing event of the form and the Click event of btnOK.

In the handler for the Click event I set the user field to the Text property of tbUserName and remove the leading and trailing spaces using the Trim method. I then check to see if that value is null or empty. If it is I display a message box stating to enter a user name up to 32 characters and return out of the method. I then unsubscribe from the FormClosing event. I do that because if the user closes the form any way other than clicking the OK button I will set the userName field to the empty string. In the ChatForm if the userName is the empty string I will exit the application. I then finally close the form because we are done with it.

As I mentioned, in the FormClosing event handler I set the userName field to the empty string. This is a cancelable event. If you were to set the Cancel property of e to true the event would be canceled an the form wouldn't close.

Now let's turn our attention to the ChatForm. It is a rather basic form as well as this isn't a full featured chat program, just a rather basic one that sends messages between peers. It can be expanded to include many other feature that I won't be going into in this tutorial. The controls that I added are a Rich Text Box, a Text Box, and a Button. My finished form looked like the following in the designer.

Attached Image

I first made the form bigger. The Rich Text Box takes up most of the form. I set the following properties: (Name) to rtbChat, BackColor property of it to White, ReadOnly to True, TabIndex to 2, and TabStop to False. Under the Rich Text Box I added the Text Box and the Button. I lined things up to make it look fairly nice. I set the (Name) property of the Text Box to tbSend, the TabStop property to 0, and the MaximumLength property to 968. I chose the value for a specific reason. I will be broadcasting the sender's user name and their message so I wanted to limit the size of the message being sent to about 1024 bytes. The idea was to keep packets at a reasonable length. The Button I set the (Name) property to btnSend, TabStop property to 1, and the Text property to Send.

Now the interesting part, coding the actual chat peer. Open the code view for ChatForm. The first thing you are going to want to do is add in a few using statements. You will want them for System.Net, System.Net.Sockets, System.Threading, and System.Text namespaces to bring classes into scope.

Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text



The first two are for network related things as you probably guessed. The third may not be so obvious. To receive messages you will want to use a separate thread or your GUI will become unresponsive. That is why that is there. The last is for encoding data from a string to an array of bytes and from an array of bytes to a string. Now you will want to add a few fields to the class. Add in these fields.

    Delegate Sub AddMessage(ByRef message As String)

    Private userName As String
    Private Const port As Integer = 54545
    Private Const broadcastAddress As String = "255.255.255.255"

    Private receivingClient As UdpClient
    Private sendingClient As UdpClient

    Private receivingThread As Thread



I declared a delegate that will be used to add another peer's message to rtbChat. This is because you can't modify the GUI from a separate thread. I'm not going totally into multithreading. I'd suggest reading up on it if it interests you. I'm just going to say that delegates are a way of calling a method without needing to know the name of that method. They are like function pointers in C/C++. Again, something that would be interesting to research.

You will want to keep track of the user's user name so there is a field for that, userName. There are then two constants, port and broadcastAddress. port is the port that we will be sending and receiving with. There are a total of 65,436 ports available. Ports 1 to 1024 are what are called well known ports and aren't allowed for use. I chose a rather strange number arbitrarily. I was tempted to choose 611, for obvious reasons, but that is part of the well known ports and can't be used. Instead I went with 54545, can you figure out why? The other constant, broadcastAddress, is an IPv4 TCP/IP address in the form of a string. This address is one of many special TCP/IP addresses. Data sent to this address is routed to all local hosts on a LAN. In this way a user's message will be sent to all peers on the network that are listening for messages. If they aren't listening the message will be ignored by them. This is where UDP differs from TCP. In TCP you must make a connection to a remote host. Data is then sent between the hosts using this connection. This address also isn't routed by a router externally so the data send won't be sent out over the Internet, it will stay on the local network.

The next two fields are UdpClient fields: receivingClient and sendingClient. The first will be used to receive messages and the second will be used to send them. The last field is receivingThread and is a Thread field. This field will be a separate thread that will run in the background listening for messages. When a message is received it will add the message to chat, including messages you send.

In the constructor of the form I wired a few event handlers. For the Load event of the form and the Click event of btnSend. Change constructor to the following.

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        AddHandler Me.Load, AddressOf ChatForm_Load
        AddHandler btnSend.Click, AddressOf btnSend_Click

    End Sub



From the Load event handler I called two methods that I wrote InitializeSender and InitializeReceiver. Add in the following code under the constructor.

    Private Sub ChatForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Me.Hide()

        Using loginForm As New LoginForm
            loginForm.ShowDialog()

            If (String.IsNullOrEmpty(loginForm.UserName)) Then
                Me.Close()
            Else
                userName = loginForm.UserName
                Me.Show()
            End If

            tbSend.Focus()

            InitializeSender()
            InitializeReceiver()

        End Using
    End Sub

    Private Sub InitializeSender()
        sendingClient = New UdpClient(broadcastAddress, port)
        sendingClient.EnableBroadcast = True
    End Sub

    Private Sub InitializeReceiver()
        receivingClient = New UdpClient(port)

        Dim start As ThreadStart = New ThreadStart(AddressOf Receiver)
        receivingThread = New Thread(start)
        receivingThread.IsBackground = True
        receivingThread.Start()
    End Sub



In the event handler I first hide the form to display the login form. In a using statement I create a new LoginForm. What this does is dispose of the form right away when we are done with it. It's always nice to clean up after yourself when you can. I call the ShowDialog method on the form to display it in modal form, the user has to finish with the form before continuing. The next step is to check if there is a value in the UserName property of the form. If there isn't the user closed the login form and I close the chat form. Otherwise I set the userName field to the UserName property of the login form and show the chat form. I then set focus on the text box for entering messages and call the methods to initialize the UdpClient fields.

The InitializeSender method is rather simple. I create a UdpClient and tell it to send on the broadcast address, 255.255.255.255 and to the port defined earlier. I also set the EnableBroadcast property to true so that it will broadcast it's data to all machines on the local area network.
The InitializeReceiver method does a little more work. To receive you don't care who is sending the data, you just want to receive it. So I create the a UdpClient that listens in on the port defined earlier. The next step is to create and start a new thread. I create a ThreadStart object that is set to a method called Receiver that I haven't written yet. I set the receivingThread field to be a new thread passing in the ThreadStart I just created. I set the IsBackground property to true so the thread is executed in the background and then start the thread calling the Start method. I really recommend if you have problems with that to research threads more thoroughly.

The next thing I'm going to add is the logic for sending a message to the other clients. That is done in the Click handler of btnSend. Add in this handler.

    Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        tbSend.Text = tbSend.Text.TrimEnd()

        If (Not String.IsNullOrEmpty(tbSend.Text)) Then
            Dim toSend As String = userName + ":" + vbNewLine + tbSend.Text
            Dim data() As Byte = Encoding.ASCII.GetBytes(toSend)
            sendingClient.Send(data, data.Length)
            tbSend.Text = ""
        End If

        tbSend.Focus()
    End Sub



The first thing I do is remove any trailing spaces from the textbox, no point in sending them over the network. I then check to see if that is not null or empty. No need to send a blank line over the network either. I next create a string that holds the user's name and the trimmed message. To send data over the network I create an array of bytes that represents the string just created. Then I call the Send method of sendingClient to actually send the data over the network. I set the Text property of the text box back to the empty string and set it to be focused as well.

Next is the Receiver method and a method with the signature of the delegate created earlier to add incoming text. Add in the following two methods.

    Private Sub Receiver()
        Dim endPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, port)
        Dim messageDelegate As AddMessage = AddressOf MessageReceived

        While (True)
            Dim data() As Byte
            data = receivingClient.Receive(endPoint)
            Dim message As String = Encoding.ASCII.GetString(data)
            Invoke(messageDelegate, message)
        End While
    End Sub

    Private Sub MessageReceived(ByRef message As String)
        rtbChat.Text += message + vbNewLine
    End Sub



The first thing I do in the Receiver method is to create an IPEndPoint. This is used to define an IPAddress and Port to listen on. I use IPAddress.Any saying to listen to any incoming connection on the port. I then create an AddMessage delegate setting it to be the method MessageReceived. I would recommend researching delegates if this is hard to understand. There is then an infinite loop that will check for incoming data. This is why I had to use threads, otherwise your application would become unresponsive. The call to Receive is a blocking call. Nothing will happen until it receives data. It requires a ref parameter that is the IPEndpoint and returns an array of bytes. I then decode the array of bytes into a string. I then Invoke the delegate and pass in the message as a parameter to the delegate. The MessageReceived method just adds the message and a new line to rtbChat's Text property.

Well, that is a lot to digest and is a rather basic P2P chat program. There are many things that can be added to it but it is a good starting point.

Is This A Good Question/Topic? 3
  • +

Replies To: Peer-To-Peer Chat - Advanced!

#2 Jordi C  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 37
  • Joined: 11-January 11

Posted 14 May 2011 - 08:39 AM

It's really nice, altough I think there's something wrong with the connection.
I tried it and it sends for my pc ofcourse, but when someone else sends a message, I can't receive it.
Was This Post Helpful? 0
  • +
  • -

#3 MikeScof  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 15-September 11

Posted 16 September 2011 - 03:06 PM

what address and port should I use to go over internet?
Was This Post Helpful? 0
  • +
  • -

#4 DimitriV  Icon User is offline

  • They don't think it be like it is, but it do
  • member icon

Reputation: 583
  • View blog
  • Posts: 2,738
  • Joined: 24-July 11

Posted 16 September 2011 - 05:25 PM

Ude your global IP address and any port above the well-known port numbers (sixofeleven posted them in this tutorial).
Was This Post Helpful? 0
  • +
  • -

#5 GCMTech  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 13-December 11

Posted 13 December 2011 - 05:12 PM

Thanks for posting this, it is exactly what I am looking for. However, I am getting an error (see attached screen shot). It is not allowing multiple connections to the same port. Or at least that's how I understand it.

Any help will be appreciated.

GCMTech

Attached image(s)

  • Attached Image

Was This Post Helpful? 0
  • +
  • -

#6 digitaldevelopment  Icon User is offline

  • D.I.C Head

Reputation: 9
  • View blog
  • Posts: 168
  • Joined: 30-April 12

Posted 16 May 2012 - 04:48 AM

View PostGCMTech, on 14 December 2011 - 01:12 AM, said:

Thanks for posting this, it is exactly what I am looking for. However, I am getting an error (see attached screen shot). It is not allowing multiple connections to the same port. Or at least that's how I understand it.

Any help will be appreciated.

GCMTech

that happens if you do not properly close the thread (not your fault, the code must do so) and the way to solve it is to open taskmanager and end the process (which is mostly the same name as the programm itself)
at least that works for me. once I found a better solution I'll let you know

best regards, DigitalDevelopment
Was This Post Helpful? 0
  • +
  • -

#7 OmitZz  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 36
  • Joined: 04-May 12

Posted 28 June 2012 - 09:53 PM

I am having trouble getting it to work with my internet IP address instead of 255.255.255.255
I read on another topic that that would allow it to be used online between users on other computers else where. With the changed IP, the message is no longer being loaded into the rich text box after I click send. Any help?
Was This Post Helpful? 0
  • +
  • -

#8 MLG xANXIOUSx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 31-October 12

Posted 31 October 2012 - 09:23 PM

View PostGCMTech, on 13 December 2011 - 05:12 PM, said:

Thanks for posting this, it is exactly what I am looking for. However, I am getting an error (see attached screen shot). It is not allowing multiple connections to the same port. Or at least that's how I understand it.

Any help will be appreciated.

GCMTech

you've gotta bind your socket to the endpoint so the application knows that it's the only app that can use that port number a reason why I don't really use UDP client instead I use Socket for both sending and receiving

Private Sub Receive()
dim ReceiveEndPoint as new IPEndPoint(IPAddress.Parse(IPAddress.Any.Tostring), 8000)
dim ReceiveSocket as new socket(Addressfamily.Internetwork, SocketType.DGram, ProtocolType.UDP)
dim ReceiveByte(36000) as Byte

try
ReceiveSocket.Bind(SendEndPoint)
ReceiveSocket.EnableBroadcast = True
ReceiveByte = asciiencoding.Ascii.getbytes(textbox1.text)
ReceiveSocket.SendTo(ReceiveByte, ReceiveEndPoint)

Catch

End Try

End Sub
that's just an example of what you could do don't forgot to create a separate thread one each for sending and receiving information that way the program doesn't hang up while it's waiting for network packets

Dim ReceiveThread as Threading.Thread

ReceiveThread = new threading.thread(addressof Receive)
ReceiveThread.isBackground = True
ReceiveThread.start()

View PostMLG xANXIOUSx, on 31 October 2012 - 09:20 PM, said:

View PostGCMTech, on 13 December 2011 - 05:12 PM, said:

Thanks for posting this, it is exactly what I am looking for. However, I am getting an error (see attached screen shot). It is not allowing multiple connections to the same port. Or at least that's how I understand it.

Any help will be appreciated.

GCMTech

you've gotta bind your socket to the endpoint so the application knows that it's the only app that can use that port number a reason why I don't really use UDP client instead I use Socket for both sending and receiving

Private Sub Receive()
dim ReceiveEndPoint as new IPEndPoint(IPAddress.Parse(IPAddress.Any.Tostring), 8000)
dim ReceiveSocket as new socket(Addressfamily.Internetwork, SocketType.DGram, ProtocolType.UDP)
dim ReceiveByte(36000) as Byte

try
ReceiveSocket.Bind(ReceiveEndPoint)
ReceiveSocket.EnableBroadcast = True
ReceiveByte = asciiencoding.Ascii.getbytes(textbox1.text)
ReceiveSocket.SendTo(ReceiveByte, ReceiveEndPoint)

Catch

End Try

End Sub
that's just an example of what you could do don't forgot to create a separate thread one each for sending and receiving information that way the program doesn't hang up while it's waiting for network packets

Dim ReceiveThread as Threading.Thread

ReceiveThread = new threading.thread(addressof Receive)
ReceiveThread.isBackground = True
ReceiveThread.start()


View PostMLG xANXIOUSx, on 31 October 2012 - 09:21 PM, said:

View PostGCMTech, on 13 December 2011 - 05:12 PM, said:

Thanks for posting this, it is exactly what I am looking for. However, I am getting an error (see attached screen shot). It is not allowing multiple connections to the same port. Or at least that's how I understand it.

Any help will be appreciated.

GCMTech

you've gotta bind your socket to the endpoint so the application knows that it's the only app that can use that port number a reason why I don't really use UDP client instead I use Socket for both sending and receiving

Private Sub Receive()
dim ReceiveEndPoint as new IPEndPoint(IPAddress.Parse(IPAddress.Any.Tostring), 8000)
dim ReceiveSocket as new socket(Addressfamily.Internetwork, SocketType.DGram, ProtocolType.UDP)
dim ReceiveByte(36000) as Byte

try
ReceiveSocket.Bind(SendEndPoint)
ReceiveSocket.EnableBroadcast = True
ReceiveByte = asciiencoding.Ascii.getbytes(textbox1.text)
ReceiveSocket.ReceiveFrom(ReceiveByte, ReceiveEndPoint)

Catch

End Try

End Sub
that's just an example of what you could do don't forgot to create a separate thread one each for sending and receiving information that way the program doesn't hang up while it's waiting for network packets

Dim ReceiveThread as Threading.Thread

ReceiveThread = new threading.thread(addressof Receive)
ReceiveThread.isBackground = True
ReceiveThread.start()

View PostMLG xANXIOUSx, on 31 October 2012 - 09:20 PM, said:

View PostGCMTech, on 13 December 2011 - 05:12 PM, said:

Thanks for posting this, it is exactly what I am looking for. However, I am getting an error (see attached screen shot). It is not allowing multiple connections to the same port. Or at least that's how I understand it.

Any help will be appreciated.

GCMTech

you've gotta bind your socket to the endpoint so the application knows that it's the only app that can use that port number a reason why I don't really use UDP client instead I use Socket for both sending and receiving

Private Sub Receive()
dim ReceiveEndPoint as new IPEndPoint(IPAddress.Parse(IPAddress.Any.Tostring), 8000)
dim ReceiveSocket as new socket(Addressfamily.Internetwork, SocketType.DGram, ProtocolType.UDP)
dim ReceiveByte(36000) as Byte

try
ReceiveSocket.Bind(ReceiveEndPoint)
ReceiveSocket.EnableBroadcast = True
ReceiveByte = asciiencoding.Ascii.getbytes(textbox1.text)
ReceiveSocket.SendTo(ReceiveByte, ReceiveEndPoint)

Catch

End Try

End Sub
that's just an example of what you could do don't forgot to create a separate thread one each for sending and receiving information that way the program doesn't hang up while it's waiting for network packets

Dim ReceiveThread as Threading.Thread

ReceiveThread = new threading.thread(addressof Receive)
ReceiveThread.isBackground = True
ReceiveThread.start()

sorry I had a lot of typos in this one in the above code wherever you see Send I meant to put receive
Was This Post Helpful? 0
  • +
  • -

#9 Unmei  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 16-October 12

Posted 09 November 2012 - 06:19 AM

I did your tutorial and it was really helpful to understand some things since i'm tooooootally new at this,
but i had an error when i wanted to send a message it gave the error.
There are 2 problems, 1 i couldn't receive the username (but maybe that may a stupid fault) and 2 the SendingClient.Send didn't include any data when it was send.
Can you maybe help me with this problem?
This is the error:
[img]http://img15.imagesh...9417/faulte.png[img]

Unmei
Was This Post Helpful? 0
  • +
  • -

#10 DotNetDevil  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 15-October 12

Posted 14 December 2012 - 04:05 PM

its taken me ages to work out how to connect peers :@

extremely good tutorial!!! very simple and straight to the point

below is code to generate all needed ip addresses if u want to connect to certain peers. this is my code so you may want to change parts.

Imports System.IO
Imports System.Net
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'tells you who i am as soon as app starts
MsgBox("301 rules!", MsgBoxStyle.Critical)
End Sub
Private Sub btnIP_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIP.Click
'get internet ip
Dim WC As New WebClient
txtInternetIP.Text = WC.DownloadString("http://automation.whatismyip.com/n09230945.asp")
'get mac ip
txtMac.Text = Dns.GetHostEntry(Dns.GetHostName).AddressList(0).ToString()
'get ipv4
Dim tmpHostName As String = System.Net.Dns.GetHostName()
txtIPv4.Text = Dns.GetHostByName(tmpHostName).AddressList(0).ToString()
End Sub
End Class

'on my app i used...
'3 textboxes, one button.

'textboxes are named with "txt" at the start (ie txtInternetIP and so on)

'1 button named "btnIP".


find me on facebook @ htd systems
Was This Post Helpful? 0
  • +
  • -

#11 DotNetDevil  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 15-October 12

Posted 14 December 2012 - 04:10 PM

View PostOmitZz, on 28 June 2012 - 09:53 PM, said:

I am having trouble getting it to work with my internet IP address instead of 255.255.255.255
I read on another topic that that would allow it to be used online between users on other computers else where. With the changed IP, the message is no longer being loaded into the rich text box after I click send. Any help?


dont use your internet ip that you find on "whatsmyip.com"!!!
open command prompt, type "ipconfig /all" and press enter...

look for where it says ipv4 and use that ip address to connect.

reason for this trouble is that browsers may use a different gateway to conect to the internet. you need the systems ip address only (true ip address)

:)

your welcome lol

www.htd-systems-development.webs.com
code samples and help also available upon request
Was This Post Helpful? 0
  • +
  • -

#12 HeaveNDenieD  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 26-October 11

Posted 11 February 2013 - 09:39 PM

Method 'Private Sub LoginForm_closing(sender As Object, e As System.EventArgs)' does not have the same signature as delegate 'Delegate Sub FormClosingEventHandler(sender As Object, e As System.Windows.Forms.FormClosingEventArgs)'.
Was This Post Helpful? 0
  • +
  • -

#13 nichj99  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 10-July 14

Posted 10 July 2014 - 10:07 PM

I've just stumbled upon this thread (and realize its old!) and am new to VB, and I could very well be WAY off with my coding here so please tell me if this is the case...

I've got the messenger aspect of it running OK - how would I add a function to notify of a new message.

I'm guessing something like



    [Private Sub MessageReceived(ByRef message As String)
        rtbChat.Text += message + vbNewLine

If MessageReceived = true then Form1.Show()

        End If
    End Sub]




It does not accept the above if statement.

In form1 my code is like an MSN messenger popup in the bottom right.


[Public Class Form1

    Dim i As Integer = 0

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Location = New Point( _
        Screen.PrimaryScreen.Bounds.Width - 200, _
        Screen.PrimaryScreen.Bounds.Height)
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If Me.Opacity = 0 Then Me.Close()

        If i = 200 Then
            Me.Opacity -= 0.02
        End If

        If Not Me.Location.Y = Screen.PrimaryScreen.WorkingArea.Height - 100 Then
            Me.Location = New Point(Me.Location.X, Me.Location.Y = 2)
        End If

        If Not i = 200 Then i += 1
    End Sub 

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1