Moving a Form with No Border

Introduction

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.

Our Project

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.

Design

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“.

Code

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.

DLLImport

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!

Form 1

Add the following Namespace to Form 1:

Imports System.Runtime.InteropServices

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

Form 2

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.

Conclusion

Thank you for reading my article! Until next time, this is me signing off!

Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read