Hello and welcome to my article. I would like to cover another frequently asked question on the CodeGuru forums. I usually find all my ideas from forum questions and make note of them to write about because I do not frequent the forums as much as I would like to these days.
Enough rambling… Today, I want to show you two unique ways to move a form without a border. A borderless form has a title bar to assist in dragging the window around and I hate it so much when an application's forms do not have borders, yet do not allow for them to be moved because sometimes they can get in the way of other work.
With today's little project, I will show you how to move a borderless form with the use of the Windows API as well as a much easier way without the need for any APIs.
Start Visual Basic and create a new Windows Forms project. Add one more form to your project, so that you have two forms. Make both forms borderless by setting the FormBorderStyle property to None. On Form 1, add a Button object to the form and give it a caption of "Next Form".
Before we delve into the code, let me give you some background on the need for the Windows APi here. I guess "need" is not really the correct word to use, but you will understand the method in my madness afterwards.
We normally need the API because, with borderless forms, people expect every object to be able to move the form around. In my modest opinion, it rounds the application off. Sometimes as well, the tiny borderless form is so cluttered with objects that to find the exact dragable spot can become tedious.
What Is the API?
The Windows API is a set of several hundred functions and subroutines that are located in a set of files called Dynamic Link Libraries (DLLs). You can make a function from the Windows API available to your Visual Basic program by declaring the function to be callable from your program. You then can use the Windows API function as you would any built-in Visual Basic function or a function that you have written yourself.
The DllImport attribute provides the information needed to call a function exported from an unmanaged DLL. As a minimum requirement, you must supply the name of the DLL containing the entry point.
Now, let's get started with the first form!
Add the following Namespace to Form 1:
Add the necessary Windows Constants:
Public Const WM_NCLBUTTONDOWN As Integer = &HA1 Public Const HT_CAPTION As Integer = &H2
These two Windows constants determine whether the left mouse button has been pressed as well as substituting a normal form's title bar.
Add the Windows API declarations:
<DllImportAttribute("user32.dll")> _ Public Shared Function SendMessage(ByVal hWnd As IntPtr, _ ByVal Msg As Integer, ByVal wParam As Integer, _ ByVal lParam As Integer) As Integer End Function <DllImportAttribute("user32.dll")> _ Public Shared Function ReleaseCapture() As Boolean End Function
The SendMessage API sends a system message to the operating system. This message can be anything, even as small as a mouse click. ReleaseCapture releases the lock; a click determines when the mouse button has been pressed down.
Add the last piece of code to make the form move:
Private Sub Form1_MouseDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles Me.MouseDown If e.Button = Windows.Forms.MouseButtons.Left Then ReleaseCapture() SendMessage(Handle, WM_NCLBUTTONDOWN, _ HT_CAPTION, 0) End If End Sub
A simple test is done to determine what button has been pressed and then sends the Windows message to drag the window. Add the next code to navigate to Form 2:
Private Sub Button1_Click(sender As Object, _ e As EventArgs) Handles Button1.Click Dim f2 As New Form2 f2.Show() End Sub
Add the following code to Form 2:
Private mouse_offset As Point Private Sub Form2_MouseClick(sender As Object, _ e As MouseEventArgs) Handles Me.MouseClick If e.Button = Windows.Forms.MouseButtons.Left Then MessageBox.Show("Test Left") Else MessageBox.Show("Test Right") End If End Sub Private Sub Form2_MouseDown(sender As Object, _ e As MouseEventArgs) Handles Me.MouseDown mouse_offset = New Point(-e.X, -e.Y) End Sub Private Sub Form2_MouseMove(sender As Object, _ e As MouseEventArgs) Handles Me.MouseMove If e.Button = System.Windows.Forms.MouseButtons.Left Then Dim mousePos As Point = Control.MousePosition mousePos.Offset(mouse_offset.X, mouse_offset.Y) Location = mousePos End If End Sub
This code is actually pretty straightforward. You simply need to keep track of your starting point and continuously keep track of where the mouse pointer currently is. I have included sample code for this project.
Thank you for reading my article! Until next time, this is me signing off!