How to simulate a HOLD keydown event using pywin32? - python

I am trying to get this piece of python code to work on windows:
import win32process, win32con, win32gui, win32api, time
HWND = win32gui.GetActiveWindow()
win32api.PostMessage(HWND, win32con.WM_KEYDOWN, win32con.VK_SPACE, 0)
time.sleep(6)
win32api.PostMessage(HWND, win32con.WM_KEYUP, win32con.VK_SPACE, 0)
It is supposed to simulate someone holding down the space key, but it does not work and does not provide any sort of error message. I believe I may be doing something wrong with HWND, but I am not sure if that is the case.. I would like the event to be sent to any active window that I select to choose.
Can you help?
Solved my problem by using ctypes and the user32.keybd_event method.
ctypes.windll.user32.keybd_event(hexx[key], 0, 0, 0) #Key is down
ctypes.windll.user32.keybd_event(hexx[key], 0, 0x0002, 0) #Key is up

Related

simulate a mouse-click without moving cursor

I'm looking to create a bot for a game I play, where he also created a bot by another company where he does things in background mode and without moving the user's cursor, so he tried to use their same method, in this case, a " bot vision" and click background on it
import win32gui, win32api, win32con
def click_game_window():
game_window_name = 'GAME'
game_hwnd = win32gui.FindWindow(None, game_window_name)
click(game_hwnd)
def click(hwnd):
lParam = win32api.MAKELONG(935, 821)
win32api.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, lParam)
win32api.SendMessage(hwnd, win32con.WM_LBUTTONUP, None, lParam)
so I did that, but it is not clicking in the game, I tested it in other windows like NOTEPAD, but it still didn't work, anyone can help me, PLEASE?

Unable to click inside of a game window with pyautogui/win32api/pydirectinput

I can click on the window, but it doesn't move my character, or interact with anything in game. I've tried moving the mouse around, i've tried doing keyboard inputs, full screen, windowed, etc. I've also tried using screenshots with pyautogui, but no luck. The game i'm trying to use it with was initially released in 2000. Non coding wise i've tried running it as admin, running in windows xp sp 2-3 compatibility mode, disabling desktop composition, etc.
win32api code:
import win32api, win32con
import time
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
# click(573, 841)
# time.sleep(1)
# click(289, 342)
# time.sleep(1)
time.sleep(5)
click(319, 399)
x = win32api.GetCursorPos()
print(x)
error:
win32api.SetCursorPos((x,y)) pywintypes.error: (0, 'SetCursorPos', 'No error message is available')
pyautogui/pydirect input:
import pyautogui
import pydirectinput as p
import time
icon = pyautogui.locateCenterOnScreen('./icon.png', confidence=0.9)
p.click(icon[0], icon[1])
time.sleep(2)
p.press('enter')
this code doesn't throw an error, it completes normally without actually clicking in the game window
First, make sure you are running your script as admin, sometimes if you don't Windows will prevent mouse movement.
Also, try doing this:
def click(x,y):
win32api.SetCursorPos((x, y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)
time.sleep(.01)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0
You have to give it a little bit of time to click or else Python will do it too quickly and the game won't register it.

Why is pyAutoGui not clicking in certain windows

I'm trying to make a python program to Automate the setup of a new computer. I used pyAutoGui to click on the Install button when prompted but it wont click on the button. It detects the image "Install.png" because it breaks the while loop when Adobe prompts to install. I tested it in paint and if I change the Install.png image to something on paint I can visually see it clicks. I tried the mouse library, moving it to the coordinates and then clicking, double- tripleClick, MouseDown -> sleep -> MouseUp, just MouseDown -> MouseUp, sending enter with pyAutogui, sending enter with shell, using subprocess and some other stuff. Nothing seems to work on the popup window Adobe gives. I printed the coordinates and they come out fine (I used DisplayMouseInfo to see of the coordinates were correct) I even hard coded the coordinates but it doesnt click install. Any answers would be appreciated, here is how it looks.
import os
import shutil
import subprocess
import psutil
import pyautogui as pg
import time
global path
path = os.getcwd()
def adobe_install():
adobe_setup_path = os.path.join(path, "Adobe.exe")
adobe_cmd = str("start " + adobe_setup_path)
os.system(adobe_cmd)
while pg.locateCenterOnScreen('Install.png', confidence=0.9) == None:
wait
time.sleep(2)
clk= pg.locateCenterOnScreen('Install.png', confidence=0.9)
pg.click(clk.x, clk.y)
EDIT
I tried the following
Install is just the a screenshot of the install button and the coordinates it prints (clk.x ; clk.y) are correct
import os
import shutil
import subprocess
import pyautogui as pg
import time
import pathlib
import winreg
import win32con
import win32gui
def adobe_install():
adobe_setup_path = os.path.join(path, "Adobe.exe")
adobe_cmd = str("start " + adobe_setup_path)
os.system(adobe_cmd)
while pg.locateCenterOnScreen('Install.png', confidence=0.9) == None:
wait
results = []
top_windows = []
win32gui.EnumWindows(windowEnumerationHandler, top_windows)
for i in top_windows:
if "Adobe Acrobat Reader DC (Continuous) - Setup" in i[1]:
print(i)
win32gui.ShowWindow(i[0],5)
win32gui.SetForegroundWindow(i[0])
bring_to_front(i[0])
break
time.sleep(2)
clk= pg.locateCenterOnScreen('Install.png', confidence=0.9)
print(clk.x)
print(clk.y)
pg.click(clk.x, clk.y)
pg.leftClick(x=clk.x, y=clk.y)
pg.typewrite(['enter'], interval=1)
adobe_install()
I tried clicking, left clicking, and pressing enter. I tested the in other windows like Paint and word and the clicking and they all did indeed click or send "Enter"
This is the error I recieved
File "C:\Users\***\documents\ict\software\New_comp.py", line 77, in adobe_install
bring_to_front(i[0])
File "C:\Users\***\documents\ict\software\New_comp.py", line 41, in bring_to_front
win32gui.SetWindowPos(HWND, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
pywintypes.error: (5, 'SetWindowPos', 'Access is denied.')
Try bringing the window to front & activate it. But you need to put in the window handler
import win32gui
import win32con
def bringTOfront(HWND):
win32gui.ShowWindow(HWND, win32con.SW_RESTORE)
win32gui.SetWindowPos(HWND, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
win32gui.SetWindowPos(HWND, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)
win32gui.SetWindowPos(HWND, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_SHOWWINDOW + win32con.SWP_NOMOVE + win32con.SWP_NOSIZE)

Simulating mouse click using python and win32api

I am trying to simulate a mouse left click on a window (Samsung Flow) but unfortunately it is not working. When I try on a google chrome window it works, but I have tried on Paint and on Samsung Flow but it does not work. Here is my code:
import win32api
import win32con
import time
import random
def enumHandler(hwnd, lParam):
if win32gui.IsWindowVisible(hwnd):
# if 'Stack Overflow' in win32gui.GetWindowText(hwnd):
if 'Samsung Flow' in win32gui.GetWindowText(hwnd):
print(win32gui.GetWindowText(hwnd))
for _ in range(50):
l_param = win32api.MAKELONG(random.randint(10, 500), random.randint(10, 500))
win32gui.PostMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, l_param)
time.sleep(0.1)
win32gui.PostMessage(hwnd, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, l_param)
time.sleep(0.1)
win32gui.EnumWindows(enumHandler, None)
I know that it detects the window as I am printing the detected text, but I do not know why it only work on the Chrome window.
Update
I have tried the following code, to search two windows notepad and browser:
import win32gui
import win32api
import win32con
import time
def enumHandler(hwnd, lParam):
if win32gui.IsWindowVisible(hwnd):
# if 'Notepad' in win32gui.GetWindowText(hwnd):
if 'Stack Overflow' in win32gui.GetWindowText(hwnd):
print(win32gui.GetWindowText(hwnd))
win32gui.SetForegroundWindow(hwnd)
win32api.SendMessage(hwnd, win32con.WM_CHAR, ord("c"), 0)
time.sleep(0.1)
win32gui.EnumWindows(enumHandler, None)
And the result was:
when using on the browser (searching for Stack Overflow window), the window came to foreground and printed the letter c
when using the notepad the window came to foreground but the letter was not printed! and I have no idea why.
Well, I found the problem.
With the example trying to send the letter C to notepad and the chrome browser I assumed that the first hwnd is the right one BUT in some cases, you have to interact with a child window. A window may have more than one child window, so, I will post a code here where you can find the window to interact with.
import win32gui
import win32con
import win32api
import time
def send_char(hwnd, lparam):
s = win32gui.GetWindowText(hwnd)
print("child_hwnd: %d txt: %s" % (hwnd, s))
win32api.PostMessage(hwnd, win32con.WM_CHAR, ord('c'), 0)
time.sleep(5)
return 1
def main():
main_app = 'Untitled - Notepad'
hwnd = win32gui.FindWindow(None, main_app)
if hwnd:
win32gui.EnumChildWindows(hwnd, send_char, None)
main()
With that you can find the child window that you should send the messages to (the code print the window id and name, send the character and wait 5 seconds, so when you notice the character on your window just get the last printed window id and use it instead of the parent window).
I hope it help someone facing the same problem.

Simulating controller dpad button being held down with Python evdev

I'm trying to simulate holding down a DPad button on a controller using Python evdev.
So far I've managed to successfully press a button like so:
import os
import time
from evdev import uinput, ecodes as e, list_devices, InputDevice, ff
dev = InputDevice(str(os.path.realpath("/dev/input/by-id/usb-Sony_Interactive_Entertainment_Wireless_Controller-if03-event-joystick")))
dev.write(e.EV_ABS, e.ABS_HAT0X, 1)
dev.write(e.EV_ABS, e.ABS_HAT0X, 0)
dev.write(e.EV_SYN, 0, 0)
but haven't been able to successfully have the application I'm simulating the input for detect the button held for any amount of time. What I've tried is this (and a couple variations on this)
...
dev.write(e.EV_ABS, e.ABS_HAT0X, 2) # evdev docs say 2 is for holding
dev.write(e.EV_SYN, 0, 0)
time.sleep(2)
dev.write(e.EV_ABS, e.ABS_HAT0X, 0)
dev.write(e.EV_SYN, 0, 0)
What am I doing wrong?

Categories

Resources