i have simple form without border and without title bar. There is only single label on it showing stopwatch. I need form to be movable by clicking mouse anywhere on form and then drag.
I solved that, but the problem is when i click on form on spot occupied by label, form will not move. In another words, i need Label only to be seen, not having any other function. How do i make label click through?
There is already an answer for this in this site, but that was in C#, so I repeat that answer here but translated in VB.NET. If you think that this is useful don't esitate the upvote that answer also....
The important thing to note here is the handling of the mousedown also for the Label1 and not only for the form
Public Class Form1
<DllImportAttribute("user32.dll")> _
Public Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As Integer, lParam As Integer) As Integer
End Function
<DllImportAttribute("user32.dll")> Public Shared Function ReleaseCapture() As Boolean
End Function
Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles MyBase.MouseDown, Label1.MouseDown
Const WM_NCLBUTTONDOWN As Integer = &HA1
Const HT_CAPTION As Integer = &H2
If e.Button = MouseButtons.Left Then
ReleaseCapture()
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0)
End If
End Sub
End Class
Hello I have some example source to make form moveable
Public Class Form1
Dim drag As Boolean
Dim mousex As Integer
Dim mousey As Integer Private Sub
Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown drag = True
mousex = Windows.Forms.Cursor.Position.X - Me.Left
mousey = Windows.Forms.Cursor.Position.Y - Me.Top
End Sub Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If drag Then
Me.Top = Windows.Forms.Cursor.Position.Y - mousey
Me.Left = Windows.Forms.Cursor.Position.X - mousex
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles
Me.MouseUp`enter code here`
I hope this can help you
Cheers :)
Public Class Form1
Dim drag As Boolean
Dim mousex As Integer
Dim mousey As Integer
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseDown, Label1.MouseDown
drag = True
mousex = Windows.Forms.Cursor.Position.X - Me.Left
mousey = Windows.Forms.Cursor.Position.Y - Me.Top
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseUp, Label1.MouseUp
drag = False
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove, Label1.MouseMove
If drag Then
Me.Top = Windows.Forms.Cursor.Position.Y - mousey
Me.Left = Windows.Forms.Cursor.Position.X - mousex
End If
End Sub
End Class
Related
I've created a small borderless form using vb .net. The form contains three square buttons. The size of the form is (93, 31). All good during the design of the form, but when I run the program the size of the form gets increased to somewhat like (98,34). I even switched between true and false for the autosize property of the form to check if it was the cause of the problem but that dint help.
How do I stop the form from resizing?
EDIT:
I made the form borderless by setting the form's FormBorderStyle property to None
Here's the code
Public Class OSD_Dialog
Dim drag As Boolean
Dim mousex As Integer
Dim mousey As Integer
' The folllowing three subs are helpfull in making the form dragable
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
drag = True
mousex = Windows.Forms.Cursor.Position.X - Me.Left
mousey = Windows.Forms.Cursor.Position.Y - Me.Top
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If drag Then
Me.Top = Windows.Forms.Cursor.Position.Y - mousey
Me.Left = Windows.Forms.Cursor.Position.X - mousex
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
drag = False
End Sub
'The following sub is helpful in creating an outline on the border of the form
Protected Overrides Sub OnPaintBackground(ByVal e As PaintEventArgs)
MyBase.OnPaintBackground(e)
Dim rect As New Rectangle(0, 0, Me.ClientSize.Width - 1, Me.ClientSize.Height - 1)
e.Graphics.DrawRectangle(Pens.White, rect)
End Sub
Private Sub OSD_Dialog_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.TopMost = True
Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.BackColor = Color.Red
TransparencyKey = BackColor
End Sub
Add this to your Form_Load event:
Me.Size = New Size(93, 31)
Also ensure you have set AutoScaleMode to 'None' in design time
I am trying to have a button, when clicked, creates a new picturebox control. So that everytime I click it, it adds another new picturebox control. These pictureboxes will all have the same functions like being able to move them around and draw on them. But the button only makes one and no more after that with the following code. What am I missing?
Public Class Form1
Dim xpos As New Integer
Dim ypos As New Integer
Dim pos As New Point
Dim x As Integer
Dim y As Integer
Dim canvas As New PictureBox
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer = 0
i = i + 1
canvas.Name = "canvas" & i
canvas.BackColor = Color.White
canvas.BorderStyle = BorderStyle.FixedSingle
canvas.Image = Nothing
canvas.Height = TextBox1.Text
canvas.Width = TextBox2.Text
AddHandler canvas.MouseDown, AddressOf PictureBox1_MouseDown
AddHandler canvas.MouseMove, AddressOf PictureBox1_MouseMove
Controls.Add(canvas)
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
xpos = Cursor.Position.X - canvas.Location.X
ypos = Cursor.Position.Y - canvas.Location.Y
End Sub
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
canvas.Location = pos
End If
End Sub
Private Sub PictureBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
Dim canvas As New PictureBox
You have multiple bugs in your code but this is the most serious one. The As New syntax ensures that you'll always create a PictureBox object, but it will only ever be one object. And of course, one variable cannot keep track of multiple picture boxes.
What you need to do is create a new one ever time the button is clicked. It is generally a good idea to keep track of the picture boxes you create. So correct code looks like:
Dim canvases As New List(Of PictureBox)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim canvas = New PictureBox
canvases.Add(canvas)
canvas.Name = "canvas" & canvases.Count.ToString()
'' etc...
End Sub
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim canvas = DirectCast(sender, PictureBox)
xpos = Cursor.Position.X - canvas.Location.X
ypos = Cursor.Position.Y - canvas.Location.Y
End Sub
Note how the sender argument gives you a reference back to the picture box object that's being moused. Do the same thing in any other event handlers.
Increasing the counter whenever a new canvas is created:
Public Class Form1
Dim counter As New Integer
...
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
counter += 1
canvas.Name = "canvas" & counter.ToString()
...
Accessing the canvas that the mouse is currently moving over:
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = Windows.Forms.MouseButtons.Left Then
pos = MousePosition
pos.X = pos.X - xpos
pos.Y = pos.Y - ypos
DirectCast(sender, PictureBox).Location = pos
End If
End Sub
I have a form without borders that I would like the user to be able to move. I have not been able to find anything that would allow me to do so.
Is it possible to move a window with the border set to None?
Introduce a Boolean variable which holds the state if the form is currently dragged and variables which hold the starting point of the drag. Then OnMove move the form accordingly. As this has already been answered elsewhere, I just copy&paste it here.
Class Form1
Private IsFormBeingDragged As Boolean = False
Private MouseDownX As Integer
Private MouseDownY As Integer
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
If e.Button = MouseButtons.Left Then
IsFormBeingDragged = True
MouseDownX = e.X
MouseDownY = e.Y
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseUp
If e.Button = MouseButtons.Left Then
IsFormBeingDragged = False
End If
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove
If IsFormBeingDragged Then
Dim temp As Point = New Point()
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
stolen from http://www.dreamincode.net/forums/topic/59643-moving-form-with-formborderstyle-none/
All 'simple' VB answers made my form jump all over the place with multiple screens. So i derived this from same answer in C# and it works like a charm :
Public Const WM_NCLBUTTONDOWN As Integer = 161
Public Const HT_CAPTION As Integer = 2
then
<DllImport("User32")> Private Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As Integer, lParam As Integer) As Integer
End Function
<DllImport("User32")> Private Shared Function ReleaseCapture() As Boolean
End Function
and finally
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
If (e.Button = MouseButtons.Left) Then
ReleaseCapture()
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0)
End If
End Sub
Dim offSetX As Integer
Dim offSetY As Integer
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Location = New Point(Cursor.Position.X - offSetX, Cursor.Position.Y - offSetY)
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
offSetX = PointToClient(Cursor.Position).X
offSetY = PointToClient(Cursor.Position).Y
Timer1.Enabled = True
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
Timer1.Enabled = False
End Sub
This is slightly scruffy way of doing it xD
Hope it helps though =]
Another way of doing this is to handle the WM_NCHITTEST message . This allows you to have parts of your form respond to mouse events as the title bar, borders, etc. would for a window with borders. For example, if you have a label on your form and you return HTCAPTION in the WM_NCHITTEST handler, you will be able to move the form by dragging this label just as you can move a regular window by dragging on its title bar. See this Stack Overflow question for example code.
I used to use VB 6.0 and now I'm switching to .net and I'm finding lots of things have changed. Back in the day, I used to store graphics assets in pictureboxes, make them invisible, and then bitblt them to the form / screen / canvas when I needed to. This was a nice, tidy way of doing it but now I'm trying to do the same thing in VB.NET and it wont work.
If the picturebox is on screen and visible, everything works perfectly, however making the picturebox invisible or moving it offscreen messes up the graphics that bitblt draws. I can successfully load a bitmap that's stored externally, but what I wanted to know was, what is the best way to store graphics (bitmap) assets inside a VB.NET application for use with bitblt?
for reference, here is a code snippet:
#Region " Members "
Public mouseX As Integer
Public mouseY As Integer
Public srcGraphics As Graphics
Public TargetGraphics As Graphics
Public srcHdc As IntPtr
Public targetHdc As IntPtr
Public srcSize As Size
Private blnShowWheel As Boolean
#End Region
#Region " Internals "
Const SRCCOPY As Integer = &HCC0020
' Wraping things up
Private Sub MyBitBlt(ByVal SourceGraphics As Graphics, ByVal TargetHDC As IntPtr, ByVal width As Integer, ByVal Height As Integer)
' Creating a DeviceContext to capture from
Dim SourceHDC As IntPtr = SourceGraphics.GetHdc
' Blitting (Copying) the data
BitBlt(TargetHDC, 0, 0, width, Height, SourceHDC, 0, 0, SRCCOPY)
' Releasing the Device context used
SourceGraphics.ReleaseHdc(SourceHDC)
End Sub
Private Sub MyBitBlt(ByVal SourceHDC As IntPtr, ByVal TargetHDC As IntPtr, ByVal width As Integer, ByVal Height As Integer, ByVal PosX As Integer, ByVal PosY As Integer)
' Copying data to a specific position on the target Device Context
BitBlt(TargetHDC, PosX, PosY, width, Height, SourceHDC, 0, 0, SRCCOPY)
End Sub
' Cleanning Up
' Before Destroying this class, dispose of objects to reclaim memory
Protected Overrides Sub Finalize()
DisposeObjects()
MyBase.Finalize()
End Sub
' Disposing of objects
Private Sub DisposeObjects()
TargetGraphics.Dispose()
srcGraphics.Dispose()
End Sub
#End Region
Private Sub cmdExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExit.Click
Finalize()
End
End Sub
Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Finalize()
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Width = 800
Me.Height = 600
Me.Left = (Screen.PrimaryScreen.Bounds.Width - Me.Width) / 2
Me.Top = (Screen.PrimaryScreen.Bounds.Height - Me.Height) / 2
srcSize = picColourWheel.Size
End Sub
Private Sub frmMain_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
srcGraphics = picColourWheel.CreateGraphics
TargetGraphics = Me.CreateGraphics
srcHdc = srcGraphics.GetHdc
targetHdc = TargetGraphics.GetHdc
If Not blnShowWheel = True Then
blnShowWheel = True
Else
blnShowWheel = False
End If
If blnShowWheel = True Then
MyBitBlt(srcHdc, targetHdc, srcSize.Width, srcSize.Height, mouseX - (srcSize.Width / 2), mouseY - (srcSize.Height / 2))
Else
Me.Refresh()
End If
srcGraphics.ReleaseHdc(srcHdc)
TargetGraphics.ReleaseHdc(targetHdc)
End Sub
Private Sub frmMain_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
mouseX = e.X
mouseY = e.Y
End Sub
In Solution Explorer, Right Click the Project --> Add --> Existing Item --> Select Image.
Select newly added Image entry in Solution Explorer.
Down below in the Properties Pane, change "Build Action" to "Embedded Resource".
Now the image will be embedded in the application, and you can draw it like this:
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim bmp As New Bitmap(Me.GetType, "Smiley1.jpg") ' <-- Exactly as it appears in Solution Explorer (it IS cAsE-sEnSiTiVe!)
Using G As Graphics = Me.CreateGraphics
G.DrawImage(bmp, New Point(25, 25))
End Using
End Sub
End Class
I know this would work If I wasn't using a web browser filling up my form.
Dim drag As Boolean
Dim mousex As Integer
Dim mousey As Integer
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
'--- Alter the return value of WM_NCHITTEST when the ALT key is down
If m.Msg = &H84 AndAlso (Control.ModifierKeys And Keys.Alt) <> 0 Then
'--- Turn HTCLIENT into HTCAPTION
If m.Result = 1 Then m.Result = 2
End If
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
drag = True
mousex = Windows.Forms.Cursor.Position.X - Me.Left
mousey = Windows.Forms.Cursor.Position.Y - Me.Top
End If
Timer1.Enabled = True
Timer1.Interval = 2500
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If drag Then
Me.Top = Windows.Forms.Cursor.Position.Y - mousey
Me.Left = Windows.Forms.Cursor.Position.X - mousex
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
Timer1.Enabled = False
drag = False
End Sub
However I found a program for Windows that has that Linux Alt+Drag window functionality called AltWindowDrag I know I can use Process.Start to run the program as I did below...
Process.Start(Application.StartupPath & "\AltWindowDrag\AltWindowDrag.exe")
However the problem with this is when I close my app, AltWindowDrag is still running. Anyway I can have AltWindowDrag close when my form closes?
Any help would be greatly appreciated.
EDIT!
A dude on another forum helped me out with this, so for others that are experiencing the same problem. Here's the code.
Dim proc As Process
Private Sub btnStart_Click(sender As System.Object, e As System.EventArgs) Handles btnStart.Click
proc = Process.Start(Application.StartupPath & "\AltWindowDrag\AltWindowDrag.exe")
End Sub
Private Sub Form1_FormClosing(sender As System.Object, e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
If Not proc Is Nothing Then
If Not proc.HasExited Then
proc.Kill()
End If
End If
End Sub
It is a pretty simple trick, Windows asks your app what was clicked when the mouse goes down. You can simply lie and tell it that the caption bar was clicked instead of the client area. Which makes Windows automatically move the window when you move the mouse. Paste this code into your form class:
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
MyBase.WndProc(m)
'--- Alter the return value of WM_NCHITTEST when the ALT key is down
If m.Msg = &H84 AndAlso (Control.ModifierKeys And Keys.Alt) <> 0 Then
'--- Turn HTCLIENT into HTCAPTION
If m.Result = 1 Then m.Result = 2
End If
End Sub