![]() |
Drag Window from surface (Form; VB.NET)
I am sure you have seen applications in which you can move the form from any place on the window (not just the title bar). Here is the tutorial on how can we do this. Before we get into the source code, it is necessary to know that how does Windows (Operating System) handles Windows (we call it 'form' in Visual Basic). First of all, get it clear in your mind that whatever Windows does, it does it through APIs (API: Application Programmer's Interface). API is a set of functions which are used by all the Windows applications and services. The developers of Windows Operating System have given us the interface through which we can use the functionality underlying everything in Windows at low level (if we call programming in VB higher level :)). This interface in nothing but a set of functions that do everything and anything. We can also harness the power of APIs, but unfortunately, we do not have access to everything. When we write our code in Visual Basic, though we do not use the API directly, VB manages to call them for us (Abstraction!!). Because the basic architecture of how Windows works remains same, we can hack into this and do things which are possible in Windows but not through VB. We will not get into details of API here but understand this that whenever Windows interacts with your form, it communicates with it through what they call 'messages'. ... Mouse Input Messages ... There are many messages to communicate mouse input events. What we are interested in is the event in which the user presses the left mouse button while the cursor is on the surface of window (and not on any control like textbox). Whenever this happens it is understood by the concerned APIs as an integer '&H1' and the constant used for this by bigbrothers is WM_NCLBUTTONDOWN (we will also use the same name to denote the value &H1). These mouse input messages are sent by Windows to our application so that the necessary action can be taken. Just before they reach the application, we can change them for good or ... ... Hit Codes ... When we move the mouse, the system moves a bitmap corresponding to it on screen to enable us locate the position. Do you know what we call it? A mouse cursor!! This cursor a point (single pixel) called the 'hot spot'. This point it tracked by the system to get the position of the cursor. This position is communicated through what they call hit codes. The hit code in which we are interested is HTCAPTION (value=2) because it refers to that area of our window which we want in this code, and that is, title bar. I am sure, now you are getting what we want to do. When the user presses the left mouse button, we will tell our application that the mouse pointer (hot spot) is on title bar (but actually it may not be there) and therefore the application will do what it does when the left mouse button is pressed and moved when the pointer is in title bar, and that is moving the form. As you can see, we are not doing anything for moving the form, we are just telling our poor application that the mouse is in title bar area and it does rest of the work (Smart work, isn't it?). Now the question arises, how do we tell Windows that the user has clicked the title bar when the user has clicked somewhere else. Guess... We will use the MouseDown event of our form. Simple. To tell our application, we will have to send a 'message' and how to send this message? Using the SendMessage API function. But there is one problem. Our application will take all the mouse events and process it and we want to 'free the mouse' from the clutches of our application temporarily. For this purpose we will use ReleaseCapture API. This will restore normal mouse input processing. Now check the code. The Code Declaration of ReleaseCapture and SendMessage APIs, so that VB can know about their existence and let us use these functions: Private Declare Sub ReleaseCapture Lib "user32" () Private
Declare Sub SendMessage Lib "user32"
Alias "SendMessageA" (ByVal
_ Declaration of constants (we have already discussed their significance): Private Const WM_NCLBUTTONDOWN
As Integer = &HA1 Private Sub frmMain_MouseDown(ByVal
sender As Object,
ByVal e As _ I am sure the story is clear now. If you have any doubts or questions, please contact me at rahul@coder000.com. I will be glad to help you. |