I've been trying for a really long time now to play an audio file that is like a click with a Timer that clicks at the same time as the mouse clicks as an autoclicker, but I haven't gotten anything to work...
Here is my code:
Private Sub Click_Tick(sender As Object, e As EventArgs) Handles Click.Tick
mouse_event(mouseclickdown, 0, 0, 0, 0)
Dim AudioFile = New MCIPlayer(Me, TextBox3.Text)
AudioFile.Play(AudioPlayMode.Background)
Thread.Sleep(20)
mouse_event(mouseclickup, 0, 0, 0, 0)
End Sub
I used MCI Player that I found from another post, that got the best result so far, but it still doesn't work like I want it to.
I am on Visual Studio 2022 "net6.0-windows" target framework.
Related
I'm trying to get familiar with graphics in vb.net and want to draw just a straight line going from the top left to the bottom right of my form Form1 without using the Form1_Paint method but by using Button1
However, the line is only drawn about a quarter of the way and stops as shown in the picture:
I think I need to increase the Clip of the Graphics Object z and I tried the following but it doesn't work. I also tried decreasing the Clip size and that worked as expected.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
z.Clip.MakeInfinite()
z.DrawLine(pen1, 0, 0, Me.Size.Width, Me.Size.Height)
End Sub
pen1 and z are initialized at the start of the program as follows:
Dim z As Graphics = CreateGraphics()
Dim pen1 = New Pen(Color.Black, 3)
I also tried using different set values for the x2 and y2 but nothing managed to be drawn outside of the box apart from using Form1_paint.
It has nothing to do with the clip, and everything to do with WHEN you called CreateGraphics(). At the point that the graphics was created, the form was not fully initialized and it is using the incorrect size.
When you use CreateGraphics() or create a Pen, you should explicitly Dispose() of them as soon as you're done. This is best accomplished via a Using block:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Using z As Graphics = CreateGraphics()
Using pen1 = New Pen(Color.Black, 3)
z.DrawLine(pen1, 0, 0, Me.ClientSize.Width, Me.ClientSize.Height)
End Using
End Using
End Sub
In general, though, using CreateGraphics() in this manner is almost always the INCORRECT approach. The line drawn this way is TEMPORARY. Minimize the form and restore it and the line will be gone.
something strange is happening in my application and I can't figure out what it is. I am trying to simulate Mouse click and scroll programmatically.
I can successfully perform Mouse click and scroll programmatically, but the problem is that the mouse wheel occurs last.
This is the code:
<DllImport("user32.dll", EntryPoint:="mouse_event")>
Private Shared Sub mouse_event(ByVal dwFlags As UInteger, ByVal dx As
Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo
As UInteger)
End Sub
Flags:
Const MOUSEEVENTF_LEFTDOWN As UInteger = &H2 '0x0002'
Const MOUSEEVENTF_LEFTUP As UInteger = &H4 '0x0004'
Const MOUSEEVENTF_WHEEL As UInteger = &H800
Const MOUSEEVENTF_XDOWN As UInteger = &H80
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
scroll_to_end()
Thread.Sleep(300)
click_perf()
MessageBox.Show("S")
End Sub
Private Sub scroll_to_end()
'Focus panel1'
c_point = New Point(Panel1.Location.X + 1, Panel1.Location.Y + 1)
Cursor.Position = Me.PointToScreen(c_point)
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
'Wait'
Thread.Sleep(150)
'Scroll to the end of the page'
Dim scroll_down As Integer = -(10 * 120) 'Perform 10 scrolls down'
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, scroll_down, 0)
'This is the fix:'
Application.DoEvents()
End Sub
Private Sub click_perf()
'Move mouse diagonally 200px'
c_point.X += 200
c_point.Y += 200
Cursor.Position = Me.PointToScreen(c_point)
'Perform click'
mouse_event(MOUSEEVENTF_LEFTDOWN, c_point.X, c_point.Y, 0, 0)
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
End Sub
When I click button3, I want to focus panel1 then scroll to the end and move mouse 200px diagonally downwards and then simulate click.
What actually happens: Mouse moves to panel1, simulates mouse button down and mouse button up. Then, it moves the mouse diagonally 200px and the messagebox shows up. The scroll didn't even occur and now when I close the messagebox panel1 probably loses the focus and doesn't scroll.
If I remove messagebox.show(""): Mouse moves to panel1 and focuses it just like above. It scrolls to the end, but it performs click before it was scrolled down.
EDIT:
To fix this issue we need to put Application.DoEvents() After WHEEL MOUSE EVENT.
Put this after each UI operation to force it to happen in order
Application.DoEvents()
UI events are handled in a message loop, which looks at a queue of messages and handles them. There is no guarantee that they will be handled in the order they are raised if they are raised around the same time in your code because your code is faster than the loop. Application.DoEvents() will halt your code execution and force the loop to handle all pending messages, thus making them happen in order.
It's generally considered poor practice to use this method, however, on account of its widespread misuse. I think your case for it is a good one and maybe the only I've ever seen.
I'd be interested to see if someone can provide a preferred alternative...
I've made a tool that will continuously click for the user if they decide to have it on with toggle keys etc, it all works fine in ordinary windows e.g google chrome, but when it comes to games it doesn't always work correctly.
(well it does in some games, then others it doesn't)
The code is designed to click fast while holding LButton, then stop when it's let go to act as an autoclicker (user has control of speed) which again works, but when in a game it clicks alot slower than it's suppose to / any other window / app.
I've figured out adding a delay using
Thread.Sleep(200)
fixes the speed of the autoclicker in game, but then it messes up the keybind which results in the autoclicker always clicking even when LButton isnt held / pressed.
Is there anything else that I could use as a delay, or anything else I can do to the code so it works correctly?
I've been trying many different variations and searching online the last few days trying to get it working, but none succeeded.
Here's all the code got to do with autoclicking in my project, i've added some notes to try and explain which part is doing what / speeds the timers are set to.
Imports System.Threading
Public Class Form1
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Integer) As Short
Private Declare Sub mouse_event Lib "user32" (ByVal dwflags As Integer, ByVal dx As Integer, ByVal cbuttons As Integer, ByVal dy As Integer, ByVal dwExtraInfo As Integer)
Private Const mouseclickup = 4
Private Const mouseclickdown = 2
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Timer1 isnt doing the clicking, Timer1 is just listening for LButton
'clicks which is why I have it always on aswell as a low interval.
Timer1.Start()
Timer1.Interval = 1
'LButton is the timer that will do the clicking.
LButton.Interval = 100
End Sub
Private Sub LButton_Tick(sender As Object, e As EventArgs) Handles LButton.Tick
If GetAsyncKeyState(Keys.LButton) Then
mouse_event(mouseclickup, 0, 0, 0, 0)
'Without Thread.Sleep(200) the code works as it's suppose to, clicks
'when LButton is held, stops clicking when LButton is let go,
'although without Thread.Sleep(200) it will not work in all games,
'but with it, it will continuously click even when LButton isn't held.
Thread.Sleep(200)
mouse_event(mouseclickdown, 0, 0, 0, 0)
Else
LButton.Stop()
End If
End Sub
Private Sub Timer1_Tick_1(sender As Object, e As EventArgs) Handles Timer1.Tick
'This is what will listen for the left clicks and also stop the left
'LButton timer if LButton is not held
If GetAsyncKeyState(Keys.LButton) Then
LButton.Start()
Else
LButton.Stop()
End If
End Sub
End Class
Quoting the MSDN documentation, GetAsyncKeyState() determines:
whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call to GetAsyncKeyState.
So when you check the function via If GetAsyncKeyState(Keys.LButton) Then, it will return non-zero at least three times, thus execute the code more than you want (which is what you experience when you add Thread.Sleep(200)).
To check if the key is held down you have to check if the most significant bit is set, which for a Short is 0x8000 in hex and 32768 in decimal.
Checking a bit flag is done by checking (<number> And <bit>) = <bit> - where And is the bitwise And operator.
This would result in your code looking like this:
Const KeyDownBit As Integer = &H8000
Private Sub LButton_Tick(sender As Object, e As EventArgs) Handles LButton.Tick
If (GetAsyncKeyState(Keys.LButton) And KeyDownBit) = KeyDownBit Then
mouse_event(mouseclickup, 0, 0, 0, 0)
Thread.Sleep(200)
mouse_event(mouseclickdown, 0, 0, 0, 0)
Else
LButton.Stop()
End If
End Sub
Private Sub Timer1_Tick_1(sender As Object, e As EventArgs) Handles Timer1.Tick
If (GetAsyncKeyState(Keys.LButton) And KeyDownBit) = KeyDownBit Then
LButton.Start()
Else
LButton.Stop()
End If
End Sub
I'm not sure whether your second timer (Timer1) is actually needed in this case.
So my older sister's high school graduation is coming up soon. She really enjoy's looking at pictures of her friend so I had this idea to make a photo booth style program. At this point, I have the webcam to display on a picturebox, however the click and mouseclick subroutines are not working. Does anyone know why this could be?
Private Sub picCapture_MouseClick(sender As Object, e As MouseEventArgs) Handles picCapture.MouseClick
MsgBox("hi")
End Sub
Dim iHeight As Integer = picCapture.Height
Dim iWidth As Integer = picCapture.Width
hHwnd = capCreateCaptureWindowA(DeviceID.ToString, WS_VISIBLE Or WS_CHILD, 0, 0, 1280, _
1024, picCapture.Handle.ToInt32, 0)
If SendMessage(hHwnd, WM_CAP_DRIVER_CONNECT, DeviceID, 0) Then
SendMessage(hHwnd, WM_CAP_SET_SCALE, True, 0)
SendMessage(hHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0)
'Start previewing the image from the camera
SendMessage(hHwnd, WM_CAP_SET_PREVIEW, True, 0)
SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, picCapture.Width, picCapture.Height, _
SWP_NOMOVE Or SWP_NOZORDER)
Else
' Error connecting to device close window
DestroyWindow(hHwnd)
End If
Any help is appreciated. :)
I am making a program that constantly sends the key "{PRTSC}" and then sets PictureBox1.BackgroundImage = My.Computer.Clipboard.GetImage.
At first it works fine but after a min or two the picturebox goes blank and no error is given.
My code is:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If Not My.Computer.Clipboard.ContainsImage Then
SendKeys.Send("{PRTSC}")
Else
PictureBox1.BackgroundImage = My.Computer.Clipboard.GetImage
My.Computer.Clipboard.Clear()
End If
End Sub
I have tried:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'SendKeys.Send("{PRTSC}")
'If My.Computer.Clipboard.ContainsImage Then PictureBox1.BackgroundImage = My.Computer.Clipboard.GetImage
Dim bounds As New Rectangle
Dim screenshot As System.Drawing.Bitmap
Dim graph As Graphics
bounds = Screen.PrimaryScreen.Bounds
screenshot = New System.Drawing.Bitmap(bounds.Width, bounds.Height) ', System.Drawing.Imaging.PixelFormat.Format32bppRgb)
graph = Graphics.FromImage(screenshot)
graph.CopyFromScreen(0, 0, 0, 0, bounds.Size, CopyPixelOperation.SourceCopy)
PictureBox1.BackgroundImage = screenshot
graph.Dispose()
'screenshot.Save("d:\\dcap.jpg", Imaging.ImageFormat.Bmp)
End Sub
But attempting to dispose the screenshot yields an instant error. I don't know why.
{PRTSC} grabs the active window, when it has focus, and the screen otherwise.
It's a good idea to disable the timer at the beginning of the tick event, and start it at the end. This prevents re-entry, and, depending on the type of timer (there is the timer control, system.timers.timer, and system.threading.timer, each of which is a little different), you may be required to restart the timer each tick event.
It's normal to assign an image to a picturebox image instead of the backgroundimage. If something in the application is assigning a bitmap to picturebox1.image or blanking picturebox1.image, it will overwrite the screen shot in picturebox1.backgroundimage.