I previously wrote this article in my blog, Think Big!.
What is that?
Today, we are talking about how to move a
form without its title bar.
You might have noticed that some
applications with fancy UIs do not allow the user to move the window from its
title bar. Honestly, some hide the overall title bar from the user. An example
of these applications is Microsoft Windows Media Player -when in skin mode,- and
Microsoft Windows Live Messenger. Both applications allow you to drag their
windows using the client area not the title bar.
In this lesson, you
will learn how to do this trick to move the form without its title bar.
At the end of this lesson, a sample application is available for
download. It is a simple application with an outstanding UI illustrates how to
move the form using its client area.
Theoretically, you cannot drag any form without its
title bar. However, we can simulate the dragging process which implies clicking
with the left mouse button on the title bar and moving the cursor without
releasing the left mouse button.
You can simulate this process using the
SendMessage() function. This function is used to send a specific message (you
can say command/order) to a specific object -specified by its handle.- This
specific message can be attached with another messages (commands) to produce a
new command. For example, in our lesson we will attach the message
WM_NCLBUTTONDOWN with the message HTCAPTION to simulate the left mouse button
clicking on the caption (title bar) of a window (form.) Honestly,
every object is a window. Every button -even the Close button- is a window, the
menu item is a window, the status bar is a window, and the tooltip is another
The definition of SendMessage() is as following:
This function takes four arguments:
The handle of the object (window.) to send the
message to. Can be set to a window handle, HWND_DESKTOP (to send the message to
the desktop,) HWND_BROADCAST (to send the message to all windows.)
The primary message that will be sent.
A secondary message to be attached to the
primary message. Set to 0 to indicate NULL.
Another message that can be attached to the
primary message. Set to 0 to indicate NULL. If wParam was not set, you cannot
The return value of this function depends on the message
sent. In our example, the function may return 0 if succeeded, or non-zero if
It is worth mentioning that, in our example, another function
must be called before SendMessage(); it is the ReleaseCapture() function. This
function releases the mouse capture from a window (object) and restores the
normal mouse processing.
A window (object) that has captured the mouse
receives all mouse input. Therefore, calling the ReleaseCapture() allows our
form to release this mouse input (left-clicking) simulated.
ReleaseCapture() function is very simple; its definition is as following:
This function returns TRUE if succeeded, or FALSE otherwise.
Now, we are going to put things together and
mix them up.
The first step is to hide the title bar of the form. This
can be done through the FormBorderStyle property of the form. You can set this
property to FormBorderStyle.None to hide the toolbar and borders of the form.
The next step to take is to create the PInvoke methods for the
functions. Here is the full code:
static extern int SendMessage(
static extern bool
const uint WM_NCLBUTTONDOWN = 0xA1; // 161
uint HTCAPTION = 2;
Again and again, PInvoke stands
for Platform Invocation; it is the CLR service allows .NET to call unmanaged
code. This service requires special changes to the PInvoke method. Also,
specific rules applied when PInvoking an unmanaged function.
The last code
demonstrates the PInvoke methods for the functions, and the constants required.
The last step is to add the implementation code required to the MouseDown
event of any control that you wish to allow the user to drag the form from. For
instance, you can add the code to the MouseDown event of a PictureBox control
that will act as the new and fancy title bar. In addition, you can add the code
to the form's MouseDown event to allow the user to drag the form from any point
of its client area.
The following code demonstrates how to allow the user to
drag the form from its client area:
private void MainForm_MouseDown(object sender, MouseEventArgs e)|
Releasing the mouse capture to allow the form to receive the
// Ordering the form
// Simulating left mouse
button clicking on the title bar
SendMessage(this.Handle, // Form
WM_NCLBUTTONDOWN, // Simulating the click
HTCAPTION, // Attaching
it to the title bar
0); // No further options
It is better to check the return
value of every call to determine whether the operation succeeded or failed.
Jesus! A problem occurred!
It is wonderful to allow the
user to drag the form from its client area. But, what if the user tried to drag
the form from a label on the client area? It will not be dragged.
overcome this situation, you can add the same code to the MouseDown event of the
label. In this case, for better code maintenance and to avoid code repetition,
you can define a method that contains the code, and call it from the MouseDown
event of every control that you need to allow the user to drag the form from
such as a label or a PictureBox. Another solution is to create a single
MouseDown event handler for all controls that you are interested in.
Well! What's next?
You can use this technique when
creating applications with hot skins to allow the user to drag the form from its
client area or from a specific control like a PictureBox that acts as the new
hot title bar.
It is worth mentioning that you would better follow the
guidelines when interoperating with unmanaged code. For example, PInvoke methods
and constants should be declared inside an internal class called -in our
example- SafeNativeMethods. In addition, it is better creating a wrapper method
for the PInvoke methods. For example, instead of calling many functions to drag
the form, you can create a single function named -for instance- MoveForm() that
acts as a wrapper for the PInvoke methods. And that results in code that is more
readable and easier to maintain. Plus, it prevents code repetition.
information about the functions, consult the MSDN documentation:
WOW! A code sample!
Along with the article a very simple
sample illustrates moving a form using its client area.