[VB.NET] Moving the window using an image box?
-
Sunday, August 15, 2010 12:07 AMI'm trying to make a custom GUI and I made the title bar on MS paint and have it all setup all i need it the code snippit to make the window move when the image is draged to different places. Help please!
All Replies
-
Sunday, August 15, 2010 9:02 AM
In VB6 I mostly used the Sendmessage API to move a form with the mouse as it is a simple call, the only real difference is the mouse up is detected after the sendmessage call.
In VB.net the API declares are different so I had to search for an example myself to even try it in VB10. So here is using a picture box to move the form, which seems to work just fine like it did for me in VB6.
If anyone has a better pure .net way to do this I am all ears. Going from VB6 to VB10 is a whole different world!
Public Class Form1 Private Declare Function SendMessageW Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr Private Declare Sub ReleaseCapture Lib "User32.dll" () 'Releases the mouse capture from a window in the current thread and restores normal mouse input processing. Private Const WM_NCLBUTTONDOWN As Integer = &HA1 ' the window message [look it up ;) ] Private Const HT_CAPTION As Integer = 2 ' Hit_Test: title bar (Caption) Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown If e.Button = Windows.Forms.MouseButtons.Left Then ' ignore if not left mouse button ReleaseCapture() 'Release mouse capture/restore normal mouse input processing SendMessageW(Me.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0) ' move this form (Me.hWnd) ' [ Detect "MouseUp" here, not in PictureBox1_MouseUp ;) ] End If End Sub End Class- Proposed As Answer by Chao KuoModerator Wednesday, August 18, 2010 1:45 PM
- Marked As Answer by Chao KuoModerator Friday, August 20, 2010 7:05 AM
-
Sunday, August 15, 2010 9:07 AM
You cannot do it while you see the code for that custom Gui before your nose.
How would you think we could do it.
As soon as you make something custom then you are mostly at your own, these forums handle problems which arise with general programming.
But you can try it by explaining better how you made that custom Gui, made the title bar with MS Paint and how you did the setup.
Success
Cor -
Sunday, August 15, 2010 1:19 PM
You could do it by checking where the mouse is in the mouseDown event, and changing the Forms location in the mouse Move event - but it's a bit complicated.
You can do it by messing with the windows messages that the form receives. You can intercept windows messages by overriding WndProc. Messages are the low-level way that windows tells a form what the user has been doing, or to ask the form to do something. In .Net the messages are often turned into Form events. So you get a low level message saying "the left mouse button just went down", and .Net converts it to the MouseDown event.
We want to intercept the WM_NCHITTEST message - non-client hit test. This message sends to the form the location of the mouse, and the form sends back a value telling windows what sort of bit of the form that point is over. It's like "Hey form, here's a point, what do you have at that point?". So if the point is over the title bar, the form should send back HT_CAPTION to say "that point is on my caption".
By overriding WndProc you can filter the messages and change the result. So - we can intercept the WM_NCHITTEST message, see what the form is currently going to send back, and if it is HT_CLIENT which means "the mouse is over the client area of the form", AND the point is actually over the custom title bar, then you change the result to HT_CAPTION:
Public Class Form1 Private awfulTitleBarBounds As Rectangle Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None End Sub Protected Overrides Sub OnResize(ByVal e As System.EventArgs) awfulTitleBarBounds = New Rectangle(10, 10, Me.ClientSize.Width - 20, 30) MyBase.OnResize(e) End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) e.Graphics.FillRectangle(Brushes.SeaGreen, awfulTitleBarBounds) TextRenderer.DrawText(e.Graphics, "Awful Title Bar", New Font("Comic Sans MS", 12), awfulTitleBarBounds, Color.Magenta, Color.Transparent, TextFormatFlags.Left) End Sub Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) MyBase.WndProc(m) If m.Msg = &H84 AndAlso m.Result = New IntPtr(1) Then Dim loc As Point = Me.PointToClient(New Point(m.LParam.ToInt32 And &HFFFF, m.LParam.ToInt32 >> 16)) If awfulTitleBarBounds.Contains(loc) Then m.Result = New IntPtr(2) End If End Sub Private Sub Form1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick ' have some way to close it Me.Close() End Sub End Class
All you need is the WndProc bit, the rest is just for the demo. Instead of using awfulTitleBarBounds you need to use a rectangle that defines the bounds of your title bar.
The magic values I used are:
WM_NCHITTEST = &H84
HT_CAPTION = 2
HT_CLIENT = 1
LParam contains the point in screen co-ordinates - the lo word contains X, the hi word contains Y.

