You never clear the results variable. The results variable always gets added to, because results = results & Chr(Asc(Mid(Password, i, 1)) + 3), which means, results is equal to results and the return of these nested functions, every time it's called (I'm not going to go into variable scope here). When the button is clicked, you need to have it set results = "" before the for loop.
A few pointers and critique here (if you are one of those people who can't stand criticism, stop reading, your answer is above).
Point 1
Indent Your Code
I know that on small projects, it's no big deal... but when you get into larger bigger projects, if you don't indent your code for clarity, YOU WILL get lost in it. Indenting is a necessary part of programming and debugging, and regardless of project size, should still be adhered to. Ideally, The code should be:
For i = 1 To Len(Password)
Result = Result & Chr(Asc(Mid(Password, i, 1)) + 3)
Next
If Text1.Text = "" Then
MsgBox "Please key in your password"
Else
Text2.Text = Result
End If
Point 2
Code Placement
You test if the textbox is empty,
After you perform the operation on the textbox...(you encrypt the data in the textbox, AND THEN, you test if it's empty or not...You should test it first, because even though the for loop doesn't care if the textbox is empty, if it was different scenario, where it wrote it to a database or used it in some other means, you could encounter some problems.
Point 3
vbnullstring
You'll make your VB code run a LOT faster by replacing "" with vbnullstring where applicable. "" is still considered a sting (an empty string), where vbnullstring is a special character. 1 or 2 times probably won't make a difference, but again, on big applications you can see some serious speed increase on timestamps of running code if you make this minor adjustment, and stick to it now. It operates the same for the most part, with the exception that it's a lot faster. I don't always do it, but it's something that's really good to know and a practice that's really good to be in.