I was using hot keys, but out of nowhere, they are not working anymore. It's very confusing.
It happened when my friend checked my code through team-viewer. Then it stopped working.
Public Class Form2
Public Const MOD_ALT As Integer = &H1 'Alt key
Public Const WM_HOTKEY As Integer = &H312
<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
<DllImport("User32.dll")> _
Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, _
ByVal id As Integer) As Integer
End Function
Private Sub Form2_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.E)
RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.A)
Me.TopMost = True
Me.ShowInTaskbar = False
Me.TransparencyKey = Me.BackColor
Dim leftpos As Long
Dim toppos As Long
leftpos = (My.Computer.Screen.WorkingArea.Right - 2) - Me.Width
toppos = (My.Computer.Screen.WorkingArea.Bottom - 2) - Me.Height
Me.Location = New Point(leftpos, toppos)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_HOTKEY Then
Dim id As IntPtr = m.WParam
Select Case (id.ToString)
Case "100"
Application.Exit()
Case "200"
Form3.Show()
End Select
End If
MyBase.WndProc(m)
End Sub
Private Sub Form2_FormClosing(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles MyBase.FormClosing
UnregisterHotKey(Me.Handle, 100)
UnregisterHotKey(Me.Handle, 200)
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
If e.KeyCode = Keys.Enter Then
Form3.Show()
Form3.Activate()
End If
End Sub
End Class
i fixed some api function signatures with the help of a good guy IronRazer in dreamincode as per the below
<DllImport("user32.dll", EntryPoint:="RegisterHotKey")> _
Private Shared Function RegisterHotKey(ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll", EntryPoint:="UnregisterHotKey")> _
Private Shared Function UnregisterHotKey(ByVal hWnd As IntPtr, ByVal id As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
and it worked fine.
Related
I'm trying to find to find the size of the cmd.exe window which is started as a child. I like to use this size to resize my form accordingly. For some reason the size returned by DwmGetWindowAttribute is always zero, so I must be doing something wrong here, but I can't find it. Any help will be greatly appreciated.
Kind regards,
Eric
Imports System.Runtime.InteropServices
Public Class Form1
Private WithEvents Tmr As New Timer With {.Interval = 100}
Private Const HWND_BOTTOM As Integer = &H1
Private WithEvents proc As New Process
Public Const DWMWA_EXTENDED_FRAME_BOUNDS As Integer = 9
<DllImport("user32.dll", EntryPoint:="SetParent")>
Private Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="SetWindowPos")>
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("dwmapi.dll")>
Shared Function DwmGetWindowAttribute(ByVal hwnd As IntPtr, ByVal dwAttribute As Integer, ByRef pvAttribute As RECT, ByVal cbAttribute As Integer) As Integer
End Function
Public Structure RECT
Public left, top, right, bottom As Integer
End Structure
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Text = "My title"
proc.EnableRaisingEvents = True
proc.StartInfo.FileName = "cmd"
proc.Start()
Tmr.Start()
End Sub
Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
If SetParent(proc.MainWindowHandle, Panel1.Handle) <> IntPtr.Zero Then
Tmr.Stop()
Dim Width As Integer
Dim Hight As Integer
Dim WindowRect As New RECT
DwmGetWindowAttribute(proc.MainWindowHandle, DWMWA_EXTENDED_FRAME_BOUNDS, WindowRect, Marshal.SizeOf(WindowRect))
Width = WindowRect.right - WindowRect.left
Hight = WindowRect.bottom - WindowRect.top
MessageBox.Show("Hight: " & Hight & " Width: " & Width)
'Me.Size = New Size(Width, Hight)
SetWindowPos(proc.MainWindowHandle, New IntPtr(HWND_BOTTOM), 0, 0, Panel1.ClientSize.Width, Panel1.ClientSize.Height, 0)
End If
End Sub
Private Sub Proc_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles proc.Exited
Invoke(Sub() Close())
End Sub
End Class
After implementing all valuable additions of #Jimi, this is the code that works:
Imports System.Runtime.InteropServices
Public Class Form1
Private WithEvents proc As New Process
Public Const WM_NCLBUTTONDOWN As Long = &HA1
Public Const SW_SHOWMAXIMIZED As UInt32 = 3
Public Const WM_CLOSE = &H10
Public Const DWMWA_EXTENDED_FRAME_BOUNDS As Integer = 9
'Function to set the parent window
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
'Function to set the child window position
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
'Function to allow the child to be maximized
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As IntPtr, ByVal nCmdShow As Int32) As Boolean
'Function to retrieve the initail child size
Private Declare Function DwmGetWindowAttribute Lib "dwmapi" (ByVal hwnd As IntPtr, ByVal dwAttribute As Integer, ByRef pvAttribute As RECT, ByVal cbAttribute As Integer) As Integer
'Function to set focus to the child window
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Long
'Function used to set terminate child window
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
'Rectangle size, used later to resize the form
Public Structure RECT
Public left, top, right, bottom As Integer
End Structure
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Text = "My title"
proc.EnableRaisingEvents = True
proc.StartInfo.FileName = "cmd"
proc.Start()
End Sub
Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Shown
'Wait for 200 ms for the form to load
proc.WaitForExit(200)
Dim WindowRect As New RECT
Dim Width, Hight As Integer
'Retrieve the initial size of the child window
DwmGetWindowAttribute(proc.MainWindowHandle, DWMWA_EXTENDED_FRAME_BOUNDS, WindowRect, Marshal.SizeOf(WindowRect))
Width = WindowRect.right - WindowRect.left
Hight = WindowRect.bottom - WindowRect.top + 23
'Set the form size to the initial size of the child window
Me.Size = New Size(Width, Hight)
'When the child is started, move the child into the panel and maximize it
If SetParent(proc.MainWindowHandle, Panel1.Handle) <> IntPtr.Zero Then
SetWindowPos(proc.MainWindowHandle, IntPtr.Zero, 0, 0, Width, Height, 0)
ShowWindow(proc.MainWindowHandle, SW_SHOWMAXIMIZED)
End If
End Sub
'Exit form when child terminates
Private Sub Proc_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles proc.Exited
Invoke(Sub() Close())
End Sub
'Set focus on child when the form is activated
Private Sub Form1_UnFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
SetForegroundWindow(proc.MainWindowHandle)
End Sub
'Set focus on child when the parent titlebar is clicked
Protected Overrides Sub DefWndProc(ByRef m As System.Windows.Forms.Message)
If CLng(m.Msg) = WM_NCLBUTTONDOWN Then
SetForegroundWindow(proc.MainWindowHandle)
End If
MyBase.DefWndProc(m)
End Sub
'Properly terminate child when the form is closed by the user
Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Closed
SendMessage(proc.MainWindowHandle, WM_CLOSE, 0, 0)
End Sub
End Class
Kind regards,
Eric
I created a simple auto clicker in visual basic using a timer and a couple of buttons.
I assigned keybinds to my start and stop buttons but they only work when the interface is open, and I want to use them while the program is minimized.
How might I go about doing that? Below is some of the more important code for context. If you need more information just let me know.
Declare Sub mouse_event Lib "user32.dll" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dx As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32, v As Integer)
Private Sub frmAutoClicker_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress
If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Z) Then
btnStart.PerformClick()
End If
End Sub
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
mouse_event(&H2, 0, 0, 0, 1)
mouse_event(&H4, 0, 0, 0, 1)
End Sub
You could try SetWindowsHookEx from user32.dll, it'a an aggressive method... but it will work.. (search SetWindowsHookEx in this forum...)
Or you couldtry to add a message filter to the application:
Application.AddMessageFilter
You can use RegisterHotkey to implement VB.NET Detecting Keypress While Minimized.
It is the first step to know the Virtual-Key Codes.
In order to facilitate the test, I set the automatic click limit of Timer1_Tick, which is limited to 50 times.
Sample code:
Imports System.Runtime.InteropServices
Public Class frmAutoClicker
Public Const WM_HOTKEY As Integer = &H312
Public Const VK_1 As Integer = &H5A '0x5A Z key
Dim i As Integer = 0
<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
<DllImport("User32.dll")>
Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr,
ByVal id As Integer) As Integer
End Function
Declare Sub mouse_event Lib "user32.dll" Alias "mouse_event" (ByVal dwFlags As Int32, ByVal dx As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As Int32, v As Integer)
Private Sub frmAutoClicker_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim retVal1 As Boolean = RegisterHotKey(Me.Handle, 10, 0, VK_1)
If retVal1 = False Then
MsgBox("The hotkeys could not be registered!", MsgBoxStyle.Critical)
Application.Exit()
End If
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_HOTKEY Then
Dim id As IntPtr = m.WParam
Select Case (id.ToString)
Case "10"
btnStart.PerformClick()
End Select
End If
MyBase.WndProc(m)
End Sub
Private Sub frmAutoClicker_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
UnregisterHotKey(Me.Handle, 10)
End Sub
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Timer1.Start()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If i > 50 Then
Timer1.Stop()
i = 0
Else
mouse_event(&H2, 0, 0, 0, 1)
mouse_event(&H4, 0, 0, 0, 1)
End If
i = i + 1
End Sub
End Class
Result:
Is there a way to register hotkeys to toggle a form from an invisible(hidden) program? I’ve tired normal methods and they only work when the form is either visible, or the active window. Thank you in advance for any help!
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.KeyPreview = True
Me.ShowInTaskbar = False
Me.ShowIcon = False
Me.Visible = False
End Sub
This is the code that hides the program.
You want to use Global Hotkeys. Just make sure you unregister when the program closes.
From a MSDN article that helped me in the past:
Firstly, you need to know the Virtual-Key Codes.
http://msdn2.microsoft.com/en-us/library/ms927178.aspx You can then
P/Invoke RegisterHotKey/UnregisterHotKey APIs to register/Unregister
the hotkey. Code sample: Register multiple hotkeys such as Alt+D,
Alt+C, etc.
Imports System.Runtime.InteropServices
Public Class Form1
Public Const MOD_ALT As Integer = &H1 'Alt key
Public Const WM_HOTKEY As Integer = &H312
<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
<DllImport("User32.dll")> _
Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, _
ByVal id As Integer) As Integer
End Function
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
RegisterHotKey(Me.Handle, 100, MOD_ALT, Keys.D)
RegisterHotKey(Me.Handle, 200, MOD_ALT, Keys.C)
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_HOTKEY Then
Dim id As IntPtr = m.WParam
Select Case (id.ToString)
Case "100"
MessageBox.Show("You pressed ALT+D key combination")
Case "200"
MessageBox.Show("You pressed ALT+C key combination")
End Select
End If
MyBase.WndProc(m)
End Sub
Private Sub Form1_FormClosing(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.FormClosingEventArgs) _
Handles MyBase.FormClosing
UnregisterHotKey(Me.Handle, 100)
UnregisterHotKey(Me.Handle, 200)
End Sub
End Class
Hello I am trying to use RegisterHeyKeys in VB.NET however I got it to work with 2 hotkeys I tried just adding in the third and it's giving a too many arguments. This is probably something really simple and I'm also a nub so go easy. lol. Any help would be greatly appreciated.
Here is the code so far:
Public Const MOD_CONTROL As Integer = &H11
Public Const MOD_SHIFT As Integer = &H10
Public Const WM_HOTKEY As Integer = &H312
<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
<DllImport("User32.dll")> _
Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, _
ByVal id As Integer) As Integer
End Function
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
RegisterHotKey(Me.Handle, 100, MOD_CONTROL, MOD_SHIFT, Keys.D2)
RegisterHotKey(Me.Handle, 200, MOD_CONTROL, MOD_SHIFT, Keys.D3)
RegisterHotKey(Me.Handle, 300, MOD_CONTROL, MOD_SHIFT, Keys.D4)
End Sub
The problem as I see it is you have added two modifiers MOD_CONTROL and MOD_SHIFT and seperated them with a comma saying that you have five parameters to the function even though it only takes four. Try Oring together your Modifers like this. You also should verify your modifier keys with the Documentation they appear to not be correct.
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
RegisterHotKey(Me.Handle, 100, MOD_CONTROL Or MOD_SHIFT, Keys.D2)
RegisterHotKey(Me.Handle, 200, MOD_CONTROL Or MOD_SHIFT, Keys.D3)
RegisterHotKey(Me.Handle, 300, MOD_CONTROL Or MOD_SHIFT, Keys.D4)
End Sub
From the documentation it states(emphasis mine):
fsModifiers [in]
Type: UINT
The keys that must be pressed in combination with the key specified by the uVirtKey parameter in order to generate the WM_HOTKEY message. The fsModifiers parameter can be a combination of the following values.
Value Meaning
MOD_ALT 0x0001 Either ALT key must be held down.
MOD_CONTROL 0x0002 Either CTRL key must be held down.
MOD_NOREPEAT 0x4000 Changes the hotkey behavior so that the keyboard auto-repeat does not yield multiple hotkey notifications.
Windows Vista and Windows XP/2000: This flag is not supported.
MOD_SHIFT 0x0004 Either SHIFT key must be held down.
MOD_WIN 0x0008 Either WINDOWS key was held down. These keys are labeled with the Windows logo. Keyboard shortcuts
that involve the WINDOWS key are reserved for use by the operating system
Here is a Working example of your program.
Public Const MOD_CONTROL As Integer = &H2
Public Const MOD_SHIFT As Integer = &H4
Public Const WM_HOTKEY As Integer = &H312
<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
<DllImport("User32.dll")> _
Public Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, _
ByVal id As Integer) As Integer
End Function
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
RegisterHotKey(Me.Handle, 100, MOD_CONTROL Or MOD_SHIFT, Keys.D2)
RegisterHotKey(Me.Handle, 200, MOD_CONTROL Or MOD_SHIFT, Keys.D3)
RegisterHotKey(Me.Handle, 300, MOD_CONTROL Or MOD_SHIFT, Keys.D4)
End Sub
Protected Overrides Sub DefWndProc(ByRef m As System.Windows.Forms.Message)
MyBase.DefWndProc(m)
If m.Msg = WM_HOTKEY Then
Select Case CType(m.WParam, Integer)
Case 100
NotifyIcon1.Text = "Hello"
NotifyIcon1.ShowBalloonTip(2000, "", NotifyIcon1.Text, ToolTipIcon.Info)
Case 200
NotifyIcon1.Text = "World"
NotifyIcon1.ShowBalloonTip(2000, "", NotifyIcon1.Text, ToolTipIcon.Info)
Case 300
NotifyIcon1.Visible = False
If Not Visible Then Visible = True
End Select
End If
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Me.Hide()
NotifyIcon1.Icon = Me.Icon
NotifyIcon1.Visible = True
End Sub
i've found this code on the web that allow me to draw a rectangle and keep the Image inside this. But there is a way to make draw this rectangle in all the direction and not only from left to right and top to bottom?
Thank for the help!
Here is the code:
Public Class frmSS
Private Declare Auto Function BitBlt Lib "gdi32.dll" ( _
ByVal hdcDest As IntPtr, _
ByVal nXDest As Integer, _
ByVal nYDest As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Integer, _
ByVal nYSrc As Integer, _
ByVal dwRop As Int32) As Boolean
Private Declare Auto Function GetDC Lib "user32.dll" (ByVal hWnd As IntPtr) As IntPtr
Private Declare Auto Function ReleaseDC Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As IntPtr
Private Sub frmSS_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.Location = New Point(0, 0)
Me.ClientSize = Screen.GetBounds(Me).Size
Me.BackColor = Color.Gray
Me.DoubleBuffered = True
Me.Opacity = 0.4#
Me.Cursor = Cursors.Cross
Me.ShowInTaskbar = False
End Sub
Private isDragging As Boolean = False
Private canDrag As Boolean = True
Private pt_start As Point = Point.Empty
Private pt_end As Point = Point.Empty
Private Sub frmSS_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
If Me.canDrag Then
Me.isDragging = True
Me.pt_start = e.Location
End If
End Sub
Private Sub frmSS_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
If Me.isDragging Then
Me.pt_end = e.Location
Me.Invalidate()
End If
End Sub
Private Sub frmSS_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
If Me.isDragging Then
Me.isDragging = False
Me.canDrag = False
Me.Cursor = Cursors.Default
Dim r As Rectangle = Me.SelectedRectangle
Me.Hide()
Application.DoEvents() 'Make sure everything's good and hidden.
Me.CaptureThisArea(r)
Me.Close()
End If
End Sub
Private ReadOnly Property SelectedRectangle() As Rectangle
Get
With pt_start
If .X >= pt_end.X OrElse .Y >= pt_end.Y Then Return Rectangle.Empty
Return New Rectangle(.X, .Y, pt_end.X - .X, pt_end.Y - .Y)
End With
End Get
End Property
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics = e.Graphics
Using p As New Pen(Color.Black, 3)
p.DashStyle = Drawing2D.DashStyle.Dash
If Me.SelectedRectangle <> Rectangle.Empty Then
g.FillRectangle(Brushes.Red, Me.SelectedRectangle)
g.DrawRectangle(p, Me.SelectedRectangle)
End If
End Using
MyBase.OnPaint(e)
End Sub
Private Sub CaptureThisArea(ByVal area As Rectangle)
Dim bmp As New Bitmap(area.Width, area.Height, Imaging.PixelFormat.Format24bppRgb)
Using g As Graphics = Graphics.FromImage(bmp)
Dim srcDC As IntPtr = GetDC(IntPtr.Zero)
Dim destDC As IntPtr = g.GetHdc()
BitBlt(destDC, 0, 0, area.Width, area.Height, srcDC, area.X, area.Y, 13369376) 'SRCCOPY = 13369376
g.ReleaseHdc(destDC)
ReleaseDC(IntPtr.Zero, srcDC)
End Using
Dim s_dl As New SaveFileDialog()
s_dl.Filter = "Bitmap Images (*.bmp)|*.bmp"
If s_dl.ShowDialog() = DialogResult.Cancel Then Exit Sub
bmp.Save(s_dl.FileName)
MessageBox.Show("File saved!!!")
End Sub
End Class
You need to try to determine the rectangle based on the initial MouseDown point and during the MouseMove, see if the current mouse coordinates need to be adjusted based on minimums and maximums of each X and Y value:
Comment out pt_end and add a dragRect variable:
'\\ Private pt_end As Point = Point.Empty
Private dragRect As Rectangle = Rectangle.Empty
Change your MouseMove event to this:
Private Sub frmSS_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseMove
If Me.isDragging Then
Dim minPoint As New Point(Math.Min(e.Location.X, pt_start.X), _
Math.Min(e.Location.Y, pt_start.Y))
Dim maxPoint As New Point(Math.Max(e.Location.X, pt_start.X), _
Math.Max(e.Location.Y, pt_start.Y))
dragRect = New Rectangle(minPoint, New Size(maxPoint.X - minPoint.X, _
maxPoint.Y - minPoint.Y))
Me.Invalidate()
End If
End Sub
From there, change your code to use dragRect instead of SelectedRectangle, which I commented out.