I wrote the following procedure to move and dock a borderless window:
Public Class frmNavigation
Inherits Form
'Declarations to allow form movement on mouse down
Private IsFormBeingDragged As Boolean = False
Private MouseDownX As Integer
Private MouseDownY As Integer
Dim Xs As Integer
Dim Ys As Integer
Dim DockScale As Integer
Private Sub frmNavigation_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
'This procedure allows the user to move the form when the
'mouse button is down. The form does not have borders, so it
'needs to be coded to move.
If e.Button = MouseButtons.Left Then
IsFormBeingDragged = True
MouseDownX = e.X
MouseDownY = e.Y
End If
End Sub
Private Sub frmNavigation_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseUp
'This procedure allows the user to move the form when the
'mouse button is up. The form does not have borders, so it
'needs to be coded to move.
If e.Button = MouseButtons.Left Then
IsFormBeingDragged = False
End If
End Sub
Private Sub frmNavigation_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove
'This procedure allows the user to move the form when the
'mouse button is dragging the form. The form does not have borders, so it
'needs to be coded to move.
Dim curScreen As Screen
curScreen = Screen.PrimaryScreen 'curScreen = Screen.AllScreens(0)
Dim height As Integer = curScreen.Bounds.Height
Dim width As Integer = curScreen.Bounds.Width
width = curScreen.WorkingArea.Width
height = curScreen.WorkingArea.Height
If IsFormBeingDragged Then
Dim temp As System.Drawing.Point = New System.Drawing.Point()
Xs = MouseDownX
Ys = MouseDownY
temp.X = Me.Location.X + (e.X - MouseDownX)
temp.Y = Me.Location.Y + (e.Y - MouseDownY)
Me.Location = temp
temp = Nothing
End If
End Sub
End Class
So far, this works as designed, it moves the form without any issue whatsoever. The issue starts when I add code to dock the form under the mouse move event as:
Private Sub frmNavigation_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove
'This procedure allows the user to move the form when the
'mouse button is dragging the form. The form does not have borders, so it
'needs to be coded to move.
Dim curScreen As Screen
curScreen = Screen.PrimaryScreen 'curScreen = Screen.AllScreens(0)
Dim height As Integer = curScreen.Bounds.Height
Dim width As Integer = curScreen.Bounds.Width
width = curScreen.WorkingArea.Width
height = curScreen.WorkingArea.Height
If IsFormBeingDragged Then
Dim temp As System.Drawing.Point = New System.Drawing.Point()
Xs = MouseDownX
Ys = MouseDownY
temp.X = Me.Location.X + (e.X - MouseDownX)
temp.Y = Me.Location.Y + (e.Y - MouseDownY)
Me.Location = temp
temp = Nothing
End If
If IsFormBeingDragged = True And e.Button = MouseButtons.Left Then
'if the drag flag is true and left mouse button is pressed...
'set Top side docking
If Me.Top + (MouseDownY - Ys) < DockScale Then
Me.Top = 0
Exit Sub
End If
'set bottom side docking
If Me.Top + (MouseDownY - Ys) + Me.Height > (height - DockScale) Then
Me.Top = height - Me.Height
Exit Sub
End If
'move the form finally
Me.Left = Me.Left + (MouseDownX - Xs)
Me.Top = Me.Top + (e.Y - Ys)
End If
End Sub
When I add the code for docking and I try to move the form, it moves and it docks, but it flickers like crazy when holding the mouse down and moving. I can't see why this happens, is the first time I dabble with something like this, so I am not sure where I am going wrong.
In your block of code with the dock check, the first "If" block sets to location of the form based on the mouse position, then later, in the 2nd and 3rd "If" block, sets the position based on docking. This is causing the to form move around twice one each mouse movement. You need some kind of flag that indicates that the form is in a docked state and then not move the form at all while this flag is set.
From what I see you should first check if form is docked and then set proper location for it.
Just like this you first set location, then you set Top, so form is moved twice and it flickers...
I faced a problem similar to this and it turned out to be caused by the form's TransparencyKey.
Try deleting the set color.
Related
Hi i have make small program when you hold Shift+Control and after you drag the mouse draw nice Rectangle when release the keys finish
this working very well in windows and some game also when it's full screen :) !
2 Problem i try to solve it
1) some game take the mouse and lock in center the problem it's you cant move the mouse where you like always it's in center
i try in time to use
Me.Cursor = New Cursor(Cursor.Current.Handle)
Cursor.Position = New Point(Control.MousePosition.X, Control.MousePosition.Y)
2) some game ignore the keys control+shift i try to put something like
control+shift+A for example but this don't work
GetKeyPress(Keys.ShiftKey) AndAlso GetKeyPress(Keys.ControlKey) AndAlso GetKeyPress(Keys.A)
the only i see to work its the HotKey but i want get stage when Up Down and i don't know how
<Runtime.InteropServices.DllImport("User32.dll")>
Public Shared Function RegisterHotKey(ByVal hwnd As IntPtr,
ByVal id As Integer, ByVal fsModifiers As Integer,
ByVal vk As Integer) As Integer
End Function
here full code copy paste and run it , to make your test
Dim timerUpdate As New Timer
Private Const KEY_DOWN As Integer = &H8000
Private Declare Function GetKeyPress Lib "user32" Alias "GetAsyncKeyState" (ByVal key As Integer) As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'form Setting transparent and hide
Me.TransparencyKey = Color.Black
Me.BackColor = Color.Black
Me.FormBorderStyle = FormBorderStyle.None
Me.Opacity = 0.0
Me.TopMost = True
'Timer
timerUpdate.Interval = 1
timerUpdate.Enabled = True
AddHandler timerUpdate.Tick, AddressOf timerUpdate_Tick
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
'paint rectangle to border red
Dim size = 2
Dim RedPen As New Pen(Color.Red, size)
Dim rect As New Rectangle(size, size, Me.ClientSize.Width - size * 2, Me.ClientSize.Height - size * 2)
e.Graphics.DrawRectangle(RedPen, rect)
End Sub
Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize
'Refresh for drawing update
Me.Refresh()
End Sub
Private Sub timerUpdate_Tick(sender As Object, e As EventArgs)
Dim key_shift As Integer = GetKeyPress(Keys.ShiftKey) AndAlso GetKeyPress(Keys.ControlKey)
Static key_shift_down As Boolean = False
Static mousePosKeep As New Point()
Static mousePosLast As New Point()
If GetKeyPress(Keys.ShiftKey) AndAlso GetKeyPress(Keys.ControlKey) = KEY_DOWN Then
If (Not key_shift_down) Then
'keep mouse position
mousePosKeep.X = Control.MousePosition.X
mousePosKeep.Y = Control.MousePosition.Y
'Move Form to mouse
Me.Left = mousePosKeep.X
Me.Top = mousePosKeep.Y
'Set Key Shift To True
key_shift_down = True
'Make Form Vissible
Me.Opacity = 1.0
'this help the form to show in game when it's full screen
'If call again make top the form And you can see it !!! :)
Me.TopMost = True
Console.WriteLine("key Shift+Controls Press Down")
End If
'Draw rectangle on mouse move
'Move Size Form Left , Width
If (Control.MousePosition.X - mousePosKeep.X) > -1 Then
Me.Left = mousePosKeep.X
Me.Width = (Control.MousePosition.X - mousePosKeep.X)
Else
Me.Left = Control.MousePosition.X
Me.Width = (mousePosKeep.X - Control.MousePosition.X)
End If
'Move Size Form Top , Height
If (Control.MousePosition.Y - mousePosKeep.Y) > -1 Then
Me.Top = mousePosKeep.Y
Me.Height = Control.MousePosition.Y - mousePosKeep.Y
Else
Me.Top = Control.MousePosition.Y
Me.Height = mousePosKeep.Y - Control.MousePosition.Y
End If
Console.WriteLine("Key Shift+Controls is Down")
Else
If key_shift_down = True Then
'hide form finish when shift up
Me.Opacity = 0.0
'nake shift to false
key_shift_down = False
'Do your stuff when finish
'
'
Console.WriteLine("Key Shift+Controls Press Up")
End If
'Draw Small Point To see where is the mouse when mouse is move
If (mousePosLast.X <> Control.MousePosition.X And mousePosLast.Y <> Control.MousePosition.Y) Then
mousePosLast.X = Control.MousePosition.X
mousePosLast.Y = Control.MousePosition.Y
Me.Width = 5
Me.Height = 5
Me.Opacity = 1.0
Me.TopMost = True
Me.Left = Control.MousePosition.X
Me.Top = Control.MousePosition.Y
Me.Cursor = Cursors.Cross
Console.WriteLine("Key Shift+Controls Up")
Else
Me.Opacity = 0.0
End If
End If
End Sub
thank you
EDIT:
So now my form location is established as per ZackRyan's answer but I still can't get it to move back to original location after it slides left.
This is the code I expect to move the form to original location
Private Sub Label7_Click(sender As Object, e As EventArgs) Handles Label7.Click
Me.Close()
'Testing.StartPosition.CenterScreen
For MoveLeft = Form2.Location.X To 30 Step 1
Form2.Left = MoveLeft
Form2.Refresh()
Threading.Thread.Sleep(0)
Next
End Sub
This is the original location:
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim xLoc = Me.Location.X
Dim yLoc = Me.Location.Y
Me.Location = New Point(xLoc, yLoc)
End Sub
------------------------------------------//--------------------------------------------------
I'm creating a windows app where a form moves to the left smoothly, all ok with this. My problem is bringing it back to it's initial position.
The form is loaded with default position set to CenterScreen I then use the following to move it to the left:
Private Sub Label3_Click(sender As Object, e As EventArgs) Handles Label3.Click
For MoveLeft = FormStartPosition.CenterScreen To 18 Step 1
Me.Left -= MoveLeft
Me.Refresh()
Threading.Thread.Sleep(1)
Next
To make it go back I'm trying the inverse:
Private Sub Label9_Click(sender As Object, e As EventArgs) Handles Label9.Click
For MoveLeft = FormStartPosition.CenterScreen To 18 Step 1
Me.Left = MoveLeft
Me.Refresh()
Threading.Thread.Sleep(1)
Next
This only works partially. The form moves to the right which is what is required, but instead of moving from the current position to CenterScreen, if moves completely at the bottom of the page.
I basically need it to return to its original center screen position smoothly.
Simply store the form's position(on form load) in some variables...
E.g.
Dim xLoc = MyForm.Location.X
Dim yLoc = MyForm.Location.Y
'Or
Dim xLoc = MyForm.Bounds.Left
Dim yLoc = MyForm.Bounds.Top
'or
Dim loc As Point = MyForm.Location
then use it as follows :
MyForm.Location = New Point(xLoc,yLoc)
'or
MyForm.Location = New Point(loc)
And one last thing , i really don't find your code fascinating enough to slide in a form .. You can easily use a Timer for that :
Dim Withevents tmr As New Forms.Timer
Dim myXLocation as integr
Private sub Btn_Click()
Tmr.start()
Private sub tmr_Tick()
myXloc= myXloc+ 1
MyForm.Location=New Point(myXloc,yloc)
If myXloc>= 190 Then 'change 190 to whatever u want :)
Tmr.Stop()
End if
I am new to programming. Can anybody help me with creating line/shape in picturebox with grips on the line/shape. Like we do it in CAD softwares.
And i want to know how to create a line on mouse click until another mouse click event occurs.
Public Class Form1
Dim isDrag As Boolean = False
Dim theRectangle As New Rectangle(New Point(0, 0), New Size(0, 0))
Dim startPoint As Point
Dim IsDimension As Boolean = False
Dim LineLocationStPoint As Point = Nothing
Dim LineLocationEndPoint As Point = Nothing
Dim cnt As Integer = 0
Dim LineArray As New ArrayList
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim fd As OpenFileDialog = New OpenFileDialog()
Dim strFileName As String
fd.Title = "Open File Dialog"
fd.Filter = "(*.PDF;*.DWG;*.TIFF;*.TIF)|*.PDF;*.DWG;*.TIFF;*.TIF|All files (*.*)|*.*"
fd.FilterIndex = 2
fd.RestoreDirectory = True
If fd.ShowDialog() = DialogResult.OK Then
strFileName = fd.FileName
'ShowFileInWebBrowser(WebBrowser1, strFileName)
PictureBox1.Load(strFileName)
End If
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If (e.Button = MouseButtons.Right) Then
isDrag = True
End If
Dim control As Control = CType(sender, Control)
startPoint = control.PointToScreen(New Point(e.X, e.Y))
If (e.Button = MouseButtons.Left) Then
IsDimension = True
LineLocationStPoint = e.Location
LineArray.Add(e.Location)
End If
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If (isDrag) Then
ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
FrameStyle.Dashed)
Dim endPoint As Point = CType(sender, Control).PointToScreen(New Point(e.X, e.Y))
Dim width As Integer = endPoint.X - startPoint.X
Dim height As Integer = endPoint.Y - startPoint.Y
theRectangle = New Rectangle(startPoint.X, startPoint.Y, _
width, height)
ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
FrameStyle.Dashed)
End If
If IsDimension Then
LineLocationEndPoint = e.Location
Dim g As Graphics = PictureBox1.CreateGraphics()
g.DrawLine(Pens.Red, LineLocationStPoint, e.Location)
g.Dispose()
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
If IsDimension Then
PictureBox1.Refresh()
ElseIf isDrag Then
' If the MouseUp event occurs, the user is not dragging.
isDrag = False
' Draw the rectangle to be evaluated. Set a dashed frame style
' using the FrameStyle enumeration.
ControlPaint.DrawReversibleFrame(theRectangle, Me.BackColor, _
FrameStyle.Dashed)
' Find out which controls intersect the rectangle and change their color.
' The method uses the RectangleToScreen method to convert the
' Control's client coordinates to screen coordinates.
Dim i As Integer
Dim controlRectangle As Rectangle
For i = 0 To Controls.Count - 1
controlRectangle = Controls(i).RectangleToScreen _
(Controls(i).ClientRectangle)
If controlRectangle.IntersectsWith(theRectangle) Then
Controls(i).BackColor = Color.BurlyWood
End If
Next
' Reset the rectangle.
theRectangle = New Rectangle(0, 0, 0, 0)
End If
End Sub
But it creates the line continuously from selected point. Whereas I want to create a line only for showing user the path of line. And i have implemented selection rectangle an right click button
Procedure for working:
Toolbar will contain line and Area
Open a file(image file)
click on line button of toolbar
*Come to picturebox
*click on one point of screen
*dynamic line starts drawing on screen (line will be from the 1st clicked point to where ever mouse mouse)
*when user clicks the next time the line is created.
click area of toolbar
*come back to picturebox
*operation same like line but when user clicks third point on picture box a shaded rectangle should appear.
http://www.vb-helper.com/howto_2005_line_control.html
For those who want to implement line with resizing grip in it.
For adding re sizable line you need to add a customized control of your own. Use this custom control and add/use it in form for further use.
Thanks everyone for helping
I have a picture box that will be showing an image. I want the user to be able to click, drag, and mouse up to a rectangle on the image. Like "I want to do something using this rectangle I drew here on this picture". If they click again, I want the previous rectangle to disappear and they start over or when I click a button to clear the highlighting rectangle they drew.
So I did find some good starting code from the msdn example about creating a zoom in rubber band rectangle that I edited a bit below, but I'm having some issues with:
Public bHaveMouse As Boolean
Public ptOriginal As Point
Public ptLast As Point
Public rect As Rectangle
Public b_Redraw As Boolean = False
' and Normalize the points and draw the reversible frame.
Private Sub MyDrawReversibleRectangle(ByVal p1 As Point, ByVal p2 As Point)
Try
'clear
' Convert the points to screen coordinates.
p1 = PointToScreen(p1)
p2 = PointToScreen(p2)
' Normalize the rectangle.
If (p1.X < p2.X) Then
rect.X = p1.X
rect.Width = p2.X - p1.X
Else
rect.X = p2.X
rect.Width = p1.X - p2.X
End If
If (p1.Y < p2.Y) Then
rect.Y = p1.Y
rect.Height = p2.Y - p1.Y
Else
rect.Y = p2.Y
rect.Height = p1.Y - p2.Y
End If
If rect.Width > pbZoneImage.Width Then
rect.Width = pbZoneImage.Width
End If
If rect.Height > pbZoneImage.Height Then
rect.Height = pbZoneImage.Height
End If
' Draw the reversible frame.
ControlPaint.DrawReversibleFrame(rect, Color.Red, FrameStyle.Thick)
Catch ex As Exception
End Try
End Sub
Private Sub pbZoneImage_MouseDown(sender As Object, e As MouseEventArgs) Handles pbZoneImage.MouseDown
If e.Button <> Windows.Forms.MouseButtons.Left Then
Exit Sub
End If
Try
' Make a note that we "have the mouse".
bHaveMouse = True
' Store the "starting point" for this rubber-band rectangle.
If b_Redraw Then
If (ptLast.X <> -1) Then
' Dim ptCurrent As Point
'ptCurrent.X = e.X
'ptCurrent.Y = e.Y
MyDrawReversibleRectangle(ptOriginal, ptLast)
End If
' Set flags to know that there is no "previous" line to reverse.
ptLast.X = -1
ptLast.Y = -1
ptOriginal.X = -1
ptOriginal.Y = -1
End If
ptOriginal.X = e.X
ptOriginal.Y = e.Y
' Special value lets us know that no previous
' rectangle needs to be erased.
ptLast.X = -1
ptLast.Y = -1
Catch ex As Exception
End Try
End Sub
Private Sub pbZoneImage_MouseMove(sender As Object, e As MouseEventArgs) Handles pbZoneImage.MouseMove
Dim ptCurrent As Point
ptCurrent.X = e.X
ptCurrent.Y = e.Y
' If we "have the mouse", then we draw our lines.
If (bHaveMouse) Then
' If we have drawn previously, draw again in
' that spot to remove the lines.
If (ptLast.X <> -1) Then
MyDrawReversibleRectangle(ptOriginal, ptLast)
End If
' Update last point.
ptLast = ptCurrent
' Draw new lines.
MyDrawReversibleRectangle(ptOriginal, ptCurrent)
End If
End Sub
Private Sub pbZoneImage_MouseUp(sender As Object, e As MouseEventArgs) Handles pbZoneImage.MouseUp
'Try
' ' Set internal flag to know we no longer "have the mouse".
bHaveMouse = False
End Sub
My Problem: Sometimes when drawing it doesn't remove the previously drawn rectangle, or if I hover over certain buttons (like the exit button) the rectangles disappear! I want they to stay so that I can record the start and end point of the rectangle for other programs. I want them to disappear when I hit my clear rectangle button, but I feel like I am getting confused on something that should be very simple.
Another issue is I'm trying to keep the rectangle from spilling outside the picture box (Pbzoneimage). But it does, and changes color.
Where did I go wrong? Is there is a better way to draw this altogether?
You need two bitmaps, one for the picturebox (img) and one to clear it and draw the rectangle(imgClone).
Private mouse_Down As Point
Private img As Bitmap
Private imgClone As Bitmap
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
img = My.Resources..... 'or you can load the image from file
PictureBox1.Image = img 'with this every time you invalidate it draws img to picturebox
imgClone = CType(PictureBox1.Image.Clone, Bitmap)
End Sub
Private Sub PictureBox1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
mouse_Down = e.Location
End Sub
Private Sub PictureBox1_MouseMove(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If e.Button = MouseButtons.Left And e.Location <> mouse_Down Then
DrawRectangle(e.Location)
End If
End Sub
Private Sub DrawRectangle(ByVal pnt As Point)
Dim g As Graphics
g = Graphics.FromImage(img)
g.DrawImage(imgClone, 0, 0) 'we are clearing img with imgClone. imgClone contains the original image without the rectangles
If pnt.X = mouse_Down.X Or pnt.Y = mouse_Down.Y Then
g.DrawLine(Pens.Firebrick, mouse_Down.X, mouse_Down.Y, pnt.X, pnt.Y)
Else
g.DrawRectangle(Pens.Firebrick, Math.Min(mouse_Down.X, pnt.X), Math.Min(mouse_Down.Y, pnt.Y),
Math.Abs(mouse_Down.X - pnt.X), Math.Abs(mouse_Down.Y - pnt.Y))
End If
g.Dispose()
PictureBox1.Invalidate() 'draw img to picturebox
End Sub
If you need to clear the picturebox:
Dim g As Graphics
g = Graphics.FromImage(img)
g.DrawImage(imgClone, 0, 0)
g.Dispose()
PictureBox1.Invalidate()
valter
I want to drag any label that is created in VB form. Is that possible if use a code to create a label?
For example: I have 20 labels and they are all different names. Is there a code that can let me drag any label I click on with the cursor I used that code it works but it only drags those labels that I created earlier but if I use a code to create labels is there a way to drag those:
code for dragging 1 label
code for click and drag 1 label only that was added in edit view
Private Sub obj1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) 'varocarbas
' Check if the mouse is down
If Go = True Then
' Set the mouse position
HoldLeft = (Control.MousePosition.X - Me.Left)
HoldTop = (Control.MousePosition.Y - Me.Top)
' Find where the mouse was clicked ONE TIME
If TopSet = False Then
OffTop = HoldTop - sender.Top
' Once the position is held, flip the switch
' so that it doesn't keep trying to find the position
TopSet = True
End If
If LeftSet = False Then
OffLeft = HoldLeft - sender.Left
' Once the position is held, flip the switch
' so that it doesn't keep trying to find the position
LeftSet = True
End If
' Set the position of the object
sender.Left = HoldLeft - OffLeft
sender.Top = HoldTop - OffTop
End If
End Sub
code for creating labels on form
Public Class Form1
Dim counter As Integer = 1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim lbl As New Label
lbl.Name = "Label" & counter
lbl.Size = New Size(80, 20)
lbl.Location = New Point(80, counter * 22)
lbl.Text = TextBox1.Text
AddHandler lbl.MouseMove, AddressOf obj1_MouseMove 'varocarbas
Me.Controls.Add(lbl)
counter += 1
End Sub
End Class
I want to drag created labels. Is that possible?
When creating controls at runtime, additionally to populate the properties, you have to associate the corresponding methods to all the events you want. If you want to add obj1_MouseMove to lbl you would have to write:
AddHandler lbl.MouseMove, AddressOf obj1_MouseMove
And remove the Handles obj1.MouseMove bit from the method declaration.