Search code examples
pythonmouseeventmousewin32gui

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.

Solution

  • 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.