3

時々、夜、ベッドで映画を見たり、オンラインでテレビ番組を見たりするのが好きです。私のコンピュータは私の机のすぐそばにあるので、これは便利です。そのため、モニターの 1 つを回転させ、他の画面を無効にして、マウスを上に引っ張るだけです。次の日にデスクに戻ったときに機能しない方法でケーブルを再配線しないと、キーボードが届きません。映画を見ていると、友達が私に話しかけてくることがあります。私は、飛び上がったり、モニターを回転させたり、マウスを後ろに動かしたり、椅子に座ったりせずに話しかけられるようにしたいと考えています。

私がやりたいのは、マウスで使用するオンスクリーン キーボードを作成することですが、T9 電話のキーパッド スタイルで、(うまくいけば) クリック数とマウスの移動量を最小限に抑え、ターゲットを逃します。私はすでに言語に精通しているので、Python でこれを行いたいと思っていますが、どこから始めればよいかわかりません。

よくわからないことの 1 つは、チャット ウィンドウからフォーカスを奪わずにオンスクリーン キーボードをクリックする方法です。これは達成できますか?または、アプリケーションは、最後にフォーカスされたウィンドウで最後にフォーカスされたコントロールを記憶し、それにキーストロークを送信できますか?

また、このウィンドウ管理とキーストロークの送信を行うために外部ライブラリが必要ですか?

ヘルプは大歓迎です。そのようなものが (任意の言語で) 既に存在する場合は、それを教えていただければ幸いです。

私は間違いなくそれをオープンソースにして、私がそれを開発した場合、ここにプロジェクトへのリンクを投稿します.

4

1 に答える 1

3

約 12 年前、私は Windows 用のプログラムを作成しました。このプログラムは、トレイに置かれ、特定のウィンドウがフォーカスされたときにキーストロークを送信します。私はもうコードを持っていません。詳細をすべて忘れてしまいました。

それでも、プロセスは次のように機能します。

GUI で Python を使用している場合は、おそらく PyQT または wxPython を使用することをお勧めします。どちらのライブラリも、GUI アプリの作成を容易にします (ただし、Windows API を直接使用することはできます)。

しかし、私だったら、GUI プログラミングを延期し、PythonWin を使用します。その GUI ツール (ソース内の多くの例) を使用Windowして、イベント処理を行うための単純なダイアログ (これも ) を作成します。

アプリケーションがウィンドウを選択するには、おそらくいくつかの方法がありtargetます。仮想キーボード ウィンドウはおそらく (マウス イベントを受け取るために) フォーカスを盗む必要がありますが、その場合、どのウィンドウにキーストロークを送信するかを知る必要があります。

  • ダイアログにドロップダウン コントロールを配置して、ターゲット ウィンドウを選択できます (ターゲットを選択するために、各ウィンドウのタイトルを簡単に取得できます)。
  • ウィンドウがフォーカスを取得すると (トラップできるイベントがあり、 のようなものがWM_FOCUSあります)、フォーカスを持っていた最後のウィンドウを照会するか、フォーカスを持っているウィンドウのタブを保持し、最後に気付いたウィンドウを使用することができます。

いずれの場合も、ターゲット ウィンドウへのハンドルを取得したら、 を使用SendMessageしてキーストロークをターゲット ウィンドウに送信できます。最初は通常のキーストロークを中継するだけで、後でマウス クリックのキャプチャについて心配することをお勧めします。

編集キーストロークを別のウィンドウに送信するために、これをまとめることができました。

import win32ui
import win32con
import time
from ctypes import *

PUL = POINTER(c_ulong)
class KeyBdInput(Structure):
    _fields_ = [("wVk", c_ushort),
                ("wScan", c_ushort),
                ("dwFlags", c_ulong),
                ("time", c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(Structure):
    _fields_ = [("uMsg", c_ulong),
                ("wParamL", c_short),
                ("wParamH", c_ushort)]

class MouseInput(Structure):
    _fields_ = [("dx", c_long),
                ("dy", c_long),
                ("mouseData", c_ulong),
                ("dwFlags", c_ulong),
                ("time",c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(Structure):
    _fields_ = [("type", c_ulong),
                ("ii", Input_I)]

def send_char(char):
    FInputs = Input * 1
    extra = c_ulong(0)
    ii_ = Input_I()
    KEYEVENTF_UNICODE = 0x4
    ii_.ki = KeyBdInput( 0, ord(char), KEYEVENTF_UNICODE, 0, pointer(extra) )
    x = FInputs( ( 1, ii_ ) )
    windll.user32.SendInput(1, pointer(x), sizeof(x[0]))

if __name__ == '__main__':
    wnd = win32ui.FindWindow(None, '* Untitled - Notepad2 (Administrator)')
    type_this = 'jaraco'
    wnd.SetFocus()
    wnd.SetForegroundWindow()
    for char in type_this:
        send_char(char)

PostMessage 手法がうまく機能しないことがわかりました (まったく機能しませんでした)。

最後にアクティブだったウィンドウの特定に関するこの記事も見つけました。

于 2010-07-03T14:35:30.303 に答える