Ответы пользователя по тегу Python
  • Как осуществить передачу комбинации клавиш (CTRL+A, etc.) неактивному окну?

    @Perforator Автор вопроса
    Нашёл решение:
    import ctypes, time, win32con, win32api, win32gui
    
    PBYTE256 = ctypes.c_ubyte * 256
    _user32 = ctypes.WinDLL("user32")
    GetKeyboardState = _user32.GetKeyboardState
    SetKeyboardState = _user32.SetKeyboardState
    PostMessage = win32api.PostMessage
    SendMessage = win32gui.SendMessage
    FindWindow = win32gui.FindWindow
    IsWindow = win32gui.IsWindow
    GetCurrentThreadId = win32api.GetCurrentThreadId
    GetWindowThreadProcessId = _user32.GetWindowThreadProcessId #очень важно брать функцию из dll, т.к. питоновский враппер (win32process.GetWindowThreadProcessId) выдаёт неправильные значения
    AttachThreadInput = _user32.AttachThreadInput
    
    MapVirtualKeyA = _user32.MapVirtualKeyA
    MapVirtualKeyW = _user32.MapVirtualKeyW
    
    MakeLong = win32api.MAKELONG
    w = win32con #так короче запись
    
    def PostKeyEx( hwnd, key, shift, specialkey):
        if IsWindow(hwnd):
            
            ThreadId = GetWindowThreadProcessId(hwnd, None)
            
            lparam = MakeLong(0, MapVirtualKeyA(key, 0))
            msg_down=w.WM_KEYDOWN
            msg_up=w.WM_KEYUP
            
            if specialkey:
                lparam = lparam | 0x1000000
                
            if len(shift) > 0: #Если есть модификаторы - используем PostMessage и AttachThreadInput
                pKeyBuffers = PBYTE256()
                pKeyBuffers_old = PBYTE256()
                
                SendMessage(hwnd, w.WM_ACTIVATE, w.WA_ACTIVE, 0)
                AttachThreadInput(GetCurrentThreadId(), ThreadId, True)
                GetKeyboardState( ctypes.byref(pKeyBuffers_old ))
                
                for modkey in shift:
                    if modkey == w.VK_MENU:
                        lparam = lparam | 0x20000000
                        msg_down=w.WM_SYSKEYDOWN
                        msg_up=w.WM_SYSKEYUP
                    pKeyBuffers[modkey] |= 128
        
                SetKeyboardState( ctypes.byref(pKeyBuffers) )
                time.sleep(0.01)
                PostMessage( hwnd, msg_down, key, lparam)
                time.sleep(0.01)
                PostMessage( hwnd, msg_up, key, lparam | 0xC0000000)
                time.sleep(0.01)
                SetKeyboardState( ctypes.byref(pKeyBuffers_old) )
                time.sleep(0.01)
                AttachThreadInput(GetCurrentThreadId(), ThreadId, False)
                
            else: #Если нету модификаторов - используем SendMessage
                SendMessage( hwnd, msg_down, key, lparam)
                SendMessage( hwnd, msg_up, key, lparam | 0xC0000000)
        
    hwnd=FindWindow("Notepad", None)
    PostKeyEx(hwnd,ord('A'),[w.VK_CONTROL],False)
    Ответ написан
    2 комментария