In Visual Basic 6, a form had a
Moveable property. In the .NET Framework, this property no longer exists. This was possibly removed because restricting a user from moving a form is considered a bad UI design or maybe they just didn't get around to it. Regardless of whether it is a good idea to do something or not, I believe it should at least be possible.
My personal, and potentially controversial, reason for needing this feature is that I like most applications on my PC to fill the screen. Unfortunately, too often the developer has coded the application to remember its size and position but not whether it was last maximized or not. As such I have developed the habit of resizing a window to fill the screen without maximizing it. This, maybe bad, habit has found its way into some of the software I have developed. I often size the main window of an application to fill the screen working area but unlike a maximized window, an accidental click and drag can move the window out of place and putting back is a hassle.
I use a .NET class library that I have developed with a class that inherits from
System.Windows.Forms.Form and includes all the extra behaviour that I ever use in any application I build. I have extracted the code snippets responsible for implementing the
Moveable property so that you can easily integrate it into any existing code you have without needing to inherit from my class.
Using the code
Whether you inherit from an extended form or you paste the code directly into a form with the rest of your code, it is very easy to use. Simply set the
False to disable both mouse dragging and the Move option on the system menu. Ideally you would set this in the
Sub New method or in the
Load event. You can set the property with the form designer too. The code is designed so that you can toggle the
Moveable property at any point during run-time.
Friend Class Form1
Public Sub New()
Me.Moveable = False
Points of Interest
The resulting code for the
ImmoveableForm is really quite simple as you can see in the source. Unfortunately for me, reaching this stage was not quite so straightforward. I have never written a Windows application in C/C++ or any language that requires accessing the Windows API directly so I spent a lot of time wading through the mass of API documentation provided by the MSDN Library. Once I had discovered that the only reliable way to achieve an immoveable form was to intercept window messages I was on my way to serious progress.
Disabling dragging the window caption was quite straightforward, as was ignoring selection of the Move item on the system menu. Actually preventing a selection of the Move menu item in the first place was interesting. My first thought was to delete the Move menu item from the system menu but the Windows standard tends to be greying and disabling menu items. Deleting also makes it difficult to restore the menu when the
Moveable property changes from
True without disturbing any other potential system menu changes made by this class or a subclass.
There were some problems with setting the Move menu item to disabled from within
Moveable property handler. The call to disable the menu seemed to be completely ignored and a quick Google confirmed that I wasn't the only person having trouble with this. In the end I found that the answer was to trap the
WM_INITMENUPOPUP window message for the system menu and make the call to disable the Move menu there. It took a while to find the documentation for the
WM_INITMENUPOPUP message because it is oddly located under Keyboard Accelerators section in the Platform SDK documentation rather than the Menus section.