2017-05-01 1 views
0

나는 win32api.GetAsyncKeyState(key)을 사용하여 작업하고 있지만 모듈이 설치되어 있지 않으면 지원을 추가하고 싶습니다.ctypes를 사용하여 키 누르기 쿼리 <code>win32api</code>을 사용하지 않고 키보드의 각 키를 쿼리하고 싶습니다.

지금까지 완전한 스레드 코드를 찾았습니다. 고유 한 스레드가 필요 했으므로 약간 헤비급으로 보이고 1600 가지가 넘는 별도의 함수가 필요합니다. 수정 자와 상관없이 각 키를 catch하고 싶습니다. (키당 14 가지 가능한 조합이 있음).

내가 발견 한 코드는 누구나 대안을 제시하거나 수정 자 문제를 해결할 수 있습니까?

import ctypes 
import ctypes.wintypes 
import win32con 


class GlobalHotKeys(object): 
    """ 
    Register a key using the register() method, or using the @register decorator 
    Use listen() to start the message pump 

    Example: 

    from globalhotkeys import GlobalHotKeys 

    @GlobalHotKeys.register(GlobalHotKeys.VK_F1) 
    def hello_world(): 
     print 'Hello World' 

    GlobalHotKeys.listen() 
    """ 

    key_mapping = [] 
    user32 = ctypes.windll.user32 

    MOD_ALT = win32con.MOD_ALT 
    MOD_CTRL = win32con.MOD_CONTROL 
    MOD_CONTROL = win32con.MOD_CONTROL 
    MOD_SHIFT = win32con.MOD_SHIFT 
    MOD_WIN = win32con.MOD_WIN 

    @classmethod 
    def register(cls, vk, modifier=0, func=None): 
     """ 
     vk is a windows virtual key code 
     - can use ord('X') for A-Z, and 0-1 (note uppercase letter only) 
     - or win32con.VK_* constants 
     - for full list of VKs see: http://msdn.microsoft.com/en-us/library/dd375731.aspx 

     modifier is a win32con.MOD_* constant 

     func is the function to run. If False then break out of the message loop 
     """ 

     # Called as a decorator? 
     if func is None: 
      def register_decorator(f): 
       cls.register(vk, modifier, f) 
       return f 
      return register_decorator 
     else: 
      cls.key_mapping.append((vk, modifier, func)) 


    @classmethod 
    def listen(cls): 
     """ 
     Start the message pump 
     """ 

     for index, (vk, modifiers, func) in enumerate(cls.key_mapping): 
      if not cls.user32.RegisterHotKey(None, index, modifiers, vk): 
       raise Exception('Unable to register hot key: ' + str(vk) + ' error code is: ' + str(ctypes.windll.kernel32.GetLastError())) 

     try: 
      msg = ctypes.wintypes.MSG() 
      i = 0 

      while cls.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0: 
       if msg.message == win32con.WM_HOTKEY: 
        (vk, modifiers, func) = cls.key_mapping[msg.wParam] 
        if not func: 
         break 
        func() 

       cls.user32.TranslateMessage(ctypes.byref(msg)) 
       cls.user32.DispatchMessageA(ctypes.byref(msg)) 


     finally: 
      for index, (vk, modifiers, func) in enumerate(cls.key_mapping): 
       cls.user32.UnregisterHotKey(None, index) 


    @classmethod 
    def _include_defined_vks(cls): 
     for item in win32con.__dict__: 
      item = str(item) 
      if item[:3] == 'VK_': 
       setattr(cls, item, win32con.__dict__[item]) 


    @classmethod 
    def _include_alpha_numeric_vks(cls): 
     for key_code in (list (range(ord('A'), ord('Z') + 1)) + list(range(ord('0'), ord('9') + 1))): 
      setattr(cls, 'VK_' + chr(key_code), key_code) 

GlobalHotKeys._include_defined_vks() 
GlobalHotKeys._include_alpha_numeric_vks() 

a를 읽는 데 사용되는 것입니다 방법의 예입니다 :는 Microsoft 정보를 읽으려고 할 때 매우 간단한 대답 밝혀졌다

@GlobalHotKeys.register(ord('A')) 
def a(): 
    print 'a' 
@GlobalHotKeys.register(ord('A'), GlobalHotKeys.MOD_SHIFT) 
def a_shift(): 
    print 'shift + a' 
@GlobalHotKeys.register(ord('A'), GlobalHotKeys.MOD_CONTROL | GlobalHotKeys.MOD_SHIFT) 
def a_ctrl_shift(): 
    print 'ctrl + shift + a' 
... 

GlobalHotKeys.listen() 

답변

0

, 나는 마침내 우연히 발견 GetKeyState 함수의 경우

ctypes.windll.user32.GetKeyState(key) 

상태는 0을 누르면, 그리고 누르면 그래서 True/False 결과를 얻을, 60000처럼 뭔가 증가하지 1, > 1 확인하는 트릭을 할 것으로 할 수있다.

GetAsyncKeyState 또한 다소 효과가 있지만 때로는 음수가되고 때로는 그렇지 않으므로 대안을 사용하는 것이 가장 좋을 것이라고 생각했습니다.

관련 문제