I'm trying to make a program to click with keyboard like in Osu!.
I've tried SendKeys(), RaiseMouseEvent() and OnMouseClick(). Now I'm trying this and can't get anything to work.
The error I keep getting is:
PInvoke restriction: cannot return variants.
Public Class Form1
Dim onn As Boolean = False
Declare Function mc Lib "user32.dll" Alias "mouse_event" (flag, x, y, button, extra)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If Not onn Then
Button1.Text = "Off"
Label1.Text = "Status: On"
onn = True
ElseIf onn Then
Button1.Text = "On"
Label1.Text = "Status: Off"
onn = False
End If
End Sub
Private Sub Form1_KeyPress1(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
If onn And (e.KeyChar = "Z" Or e.KeyChar = "X" Or e.KeyChar = "z" Or e.KeyChar = "x") Then
mc(&H2, 0, 0, 0, 0)
mc(&H4, 0, 0, 0, 0)
End If
End Sub
End Class
This examples clicks where the mouse currently is when the feature is in the "onn" state:
Public Class Form1
Private onn As Boolean = False
Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Integer, _
ByVal dx As Integer, ByVal dy As Integer, ByVal cButtons As Integer, _
ByVal dwExtraInfo As Integer)
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.KeyPreview = True
Button1.Text = "Off"
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
onn = Not onn
Button1.Text = IIf(onn, "On", "Off")
End Sub
Private Sub Form1_KeyPress1(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
If onn Then
Select Case e.KeyChar
Case "Z", "z", "X", "x"
mouse_event(&H2, 0, 0, 0, 0)
mouse_event(&H4, 0, 0, 0, 0)
End Select
End If
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Debug.Print("Button2")
End Sub
Private Sub Button3_Click(sender As Object, e As System.EventArgs) Handles Button3.Click
Debug.Print("Button3")
End Sub
End Class
Public Class Iconform
Public Declare Auto Function SetCursorPos Lib "User32.dll" (ByVal X As Integer, ByVal Y As Integer) As Long
Public Declare Auto Function GetCursorPos Lib "User32.dll" (ByRef lpPoint As Point) As Long
Public Declare Sub mouse_event Lib "user32" Alias "mouse_event" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Public Const MOUSEEVENTF_LEFTDOWN = &H2 ' left button down
Public Const MOUSEEVENTF_LEFTUP = &H4 ' left button up
Public Const MOUSEEVENTF_MIDDLEDOWN = &H20 ' middle button down
Public Const MOUSEEVENTF_MIDDLEUP = &H40 ' middle button up
Public Const MOUSEEVENTF_RIGHTDOWN = &H8 ' right button down
Public Const MOUSEEVENTF_RIGHTUP = &H10 ' right button up
Private Sub NotifyIcon1_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.Click
SettingsForm.Show()
End Sub
Private Sub OptionsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OptionsToolStripMenuItem.Click
SettingsForm.Show()
End Sub
Private Sub CloseToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CloseToolStripMenuItem.Click
Me.Close()
End Sub
Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
Dim bHandled As Boolean = False
Dim xPos As Integer = Windows.Forms.Cursor.Position.X.ToString
Dim zPos As Integer = Windows.Forms.Cursor.Position.Y.ToString
Select Case e.KeyCode
Case Keys.Right
Windows.Forms.Cursor.Position = New Point(xPos + 10, zPos)
Case Keys.Left
Windows.Forms.Cursor.Position = New Point(xPos - 10, zPos)
Case Keys.Down
Windows.Forms.Cursor.Position = New Point(xPos, zPos + 10)
Case Keys.Up
Windows.Forms.Cursor.Position = New Point(xPos, zPos - 10)
Case Keys.D
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
End Select
End Sub
End Class
Try using the PerformClick() method:
Button1.PerformClick()
In your code it could be like:
If onn And (e.KeyChar = "Z" Or e.KeyChar = "X" Or e.KeyChar = "z" Or e.KeyChar = "x") Then
Button1.PerformClick()
End If
Related
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:
I have a program that has 4 functions. When form is minimized I am showing the NotifyIcon and hiding the form in taskbar.
Private Sub FrmMain_Resize(sender As Object, e As EventArgs) Handles Me.Resize
If Me.WindowState = FormWindowState.Minimized Then
NotifyIcon1.Visible = True
NotifyIcon1.Icon = SystemIcons.Application
NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info
NotifyIcon1.BalloonTipTitle = "Some Text"
NotifyIcon1.BalloonTipText = "Some Text"
NotifyIcon1.ShowBalloonTip(1000)
Me.ShowInTaskbar = False
End If
End Sub
Private Sub NotifyIcon1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
Me.ShowInTaskbar = True
Me.WindowState = FormWindowState.Normal
NotifyIcon1.Visible = False
End Sub
Even the program is hidden, I still want to execute the 4 functions using hot keys. I found this but it works only when I am not hiding the form in taskbar.
Public Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
Public Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer) As Integer
Public Const WM_HOTKEY As Integer = &H312
Private Enum KeyModifier
None = 0
Alt = &H1
Control = &H2
Shift = &H4
Winkey = &H8
End Enum
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_HOTKEY Then
If m.WParam = 1001 Then
btnFunction1.PerformClick()
ElseIf m.WParam = 1002 Then
btnFunction2.PerformClick()
ElseIf m.WParam = 1003 Then
btnFunction3.PerformClick()
ElseIf m.WParam = 1004 Then
btnFunction4.PerformClick()
End If
End If
MyBase.WndProc(m)
End Sub
Private Sub FrmMain_Closed(sender As Object, e As EventArgs) Handles Me.Closed
Call UnregisterHotKey(Me.Handle, 1001)
Call UnregisterHotKey(Me.Handle, 1002)
Call UnregisterHotKey(Me.Handle, 1003)
Call UnregisterHotKey(Me.Handle, 1004)
End Sub
Private Sub FrmClient_Load(sender As Object, e As EventArgs) Handles MyBase.Load
NotifyIcon1.Text = Me.Text
Call RegisterHotKey(Me.Handle, 1001, KeyModifier.Alt, Keys.F1)
Call RegisterHotKey(Me.Handle, 1002, KeyModifier.Alt, Keys.F2)
Call RegisterHotKey(Me.Handle, 1003, KeyModifier.Alt, Keys.F3)
Call RegisterHotKey(Me.Handle, 1004, KeyModifier.Alt, Keys.F4)
End Sub
Is there a way to use the RegisterHotKey even the form ShowInTaskbar is set to False?
I'm making a program for recording audio.
Code:
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Function record Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Integer, ByVal hwndCallback As Integer) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
record("open new Type waveaudio Alias recon", "", 0, 0)
record("record recon", "", 0, 0)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
record("save recon c:\mic.wav", "", 0, 0)
record("close recon", "", 0, 0)
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
My.Computer.Audio.Play("c:\mic.wav", AudioPlayMode.Background)
End Sub
End Class
Error occurs on line My.Computer.Audio.Play("c:\mic.wav", AudioPlayMode.Background):
FileNotFoundException was unhandled
Please be sure a sound file exists at the specified location.
This works For me try it and see
Public Class Form1
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Integer, ByVal hwndCallback As Integer) As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Button1.Enabled = False
Button2.Enabled = True
mciSendString("open new Type waveaudio Alias recsound", "", 0, 0)
mciSendString("record recsound", "", 0, 0)
Label1.Text = "Recording..."
Label1.Visible = True
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Button1.Enabled = True
Button2.Enabled = False
Button3.Enabled = True
mciSendString("save recsound c:\recsound.wav", "", 0, 0)
mciSendString("close recsound", "", 0, 0)
MsgBox("File Created: C:\recsound.wav")
Label1.Text = "Stopped..."
Label1.Visible = False
My.Computer.Audio.Stop()
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Label1.Text = "Playing..."
Label1.Visible = True
My.Computer.Audio.Play("c:\recsound.wav", AudioPlayMode.Background)
End Sub
End Class
I'm creating an "autoclicker" for use in video games that left clicks my mouse repeatedly at the push of a button. I want to have hotkeys set up that work globally without the autoclicker window being in focus. For some reason, only the hotkey that is meant to stop the clicking is currently functioning (F2). The F1 key is supposed to start the clicking, but currently the only way to start it is by pressing the Start button on the form manually. The code seems to throw an error when attempting to be deployed to version 4.0 of the .NET framework, but setting it to 3.5 solves this issue. I've included my entire code below because I can't figure out why the F1 hotkey is not functioning despite the F2 hotkey working flawlessly. Thanks for your time. A good portion of this code I came up with by looking at examples of other peoples' work, and I only understand it to a certain extent. I hope my code is formatted correctly because I'm new to this site and I don't exactly understand how to paste it correctly. Thanks for your help in advance, I really appreciate it.
Public Class Form1
Private Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vkey As Long) As Integer
Private Declare Sub mouse_event Lib "user32.dll" (ByVal dwflags As Long, ByVal dx As Long, ByVal cbuttons As Long, ByVal dy As Long, ByVal dwExtraInfo As Long)
Dim hotkey1 As Boolean
Dim hotkey2 As Boolean
Private Const mouseclickup = 4
Private Const mouseclickdown = 2
Dim Test As Integer
Dim Interval As Integer
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Click.Start()
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
Click.Stop()
End Sub
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
Test = Test + 1
Counter.Text = Test
End Sub
Private Sub Click_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Click.Tick
Interval = CInt(timeTextbox.Text)
Click.Interval = Interval
mouse_event(mouseclickdown, 0, 0, 0, 0)
mouse_event(mouseclickup, 0, 0, 0, 0)
hotkey1 = GetAsyncKeyState(Keys.F1)
If hotkey1 = True Then
btnStart.PerformClick()
End If
hotkey2 = GetAsyncKeyState(Keys.F2)
If hotkey2 = True Then
btnStop.PerformClick()
End If
End Sub
Private Sub timeTextbox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timeTextbox.TextChanged
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
KeyPreview = True
End Sub
End Class
Your declarations were for VB6. The data types need to be changed for VB.Net as shown below.
Also, you need two independent timers. One for detecting the keypress, which has to run at a high rate. And another for doing the actual clicking, whose rate is determined by your TextBox value.
Public Class Form1
Private Const MOUSEEVENTF_LEFTDOWN As Integer = &H2
Private Const MOUSEEVENTF_LEFTUP As Integer = &H4
Private Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As System.Windows.Forms.Keys) As Short
Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Integer, _
ByVal dx As Integer, ByVal dy As Integer, ByVal cButtons As Integer, _
ByVal dwExtraInfo As Integer)
Private WithEvents KeyTimer As New Timer
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
KeyTimer.Interval = 50
KeyTimer.Start()
Click.Enabled = False
End Sub
Private Sub KeyTimer_Tick(sender As Object, e As System.EventArgs) Handles KeyTimer.Tick
If IsKeyDown(Keys.F1) Then
Click.Start()
ElseIf IsKeyDown(Keys.F2) Then
Click.Stop()
End If
End Sub
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
Static Test As Integer
Test = Test + 1
Counter.Text = Test
End Sub
Private Sub timeTextbox_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timeTextbox.TextChanged
Dim Interval As Integer
If Integer.TryParse(timeTextbox.Text, Interval) Then
Click.Interval = Interval
End If
End Sub
Private Sub Click_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Click.Tick
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
End Sub
Private Function IsKeyDown(ByVal key As System.Windows.Forms.Keys) As Boolean
Return ((GetAsyncKeyState(key) And &H8000) = &H8000)
End Function
End Class
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.