15

現在アクティブなウィンドウの選択されたテキストに対してユーザー定義のアクションを実行できるPythonを使用して、ウィンドウ用の単純なオープン ソース ユーティリティを作成しようとしています。ユーティリティは、事前定義されたキーボード ショートカットを使用してアクティブにする必要があります。

使用法は、次の例で部分的に概説されています。

  1. ユーザーがマウスまたはキーボードを使用して (任意のアプリケーション ウィンドウで) テキストを選択します。
  2. ユーザーが事前定義されたキーボード ショートカットを押したとき
  3. 選択したテキストは、ユーティリティによって取得されるか、クリップボードにコピーされます (どちらの方法でも問題ありません)。
  4. 選択したテキストに対して、キーボード ショートカットに依存するアクションが実行されます。

私を困惑させるのはステップ 3です。アクティブなウィンドウから選択したテキストを取得する方法。これは、すべてのアプリケーションで機能するはずです。

pywin32モジュールを使用しています。

回答とヒントをお寄せいただきありがとうございます。

更新#1

このタスクを達成するには、次の 2 つの方法があることがわかりました。

  1. アクティブなウィンドウを見つけて、メッセージ/キーストローク (Ctrl-C) をウィンドウに送信して、選択したテキストをクリップボードにコピーします。次に、ユーティリティは、クリップボード関連の関数を使用してテキストにアクセスすることで、テキストを操作できます。
  2. アクティブなウィンドウを見つけて、選択したテキストを (クリップボードにコピーせずに) 直接取得します。これは、最初のアプローチよりも難しいようです。

出発点として:

Anurag Unyal が返信で指摘したように、アクティブなウィンドウ ID を取得します。

または、次のコードでウィンドウ オブジェクトを取得します。

import win32ui
wnd = win32ui.GetForegroundWindow()
print wnd.GetWindowText()
4

4 に答える 4

2

以下のコードは、単純なテキスト ボックスでのみ機能します (VB6 で実行し、Python に移植しました)。

編集:python 2.6でのみテストされました

from ctypes import *
import win32gui
import win32api
import win32con


user32 = windll.user32
kernel32 = windll.kernel32

class RECT(Structure):
 _fields_ = [
     ("left", c_ulong),
     ("top", c_ulong),
     ("right", c_ulong),
     ("bottom", c_ulong)
 ]

class GUITHREADINFO(Structure):
 _fields_ = [
     ("cbSize", c_ulong),
     ("flags", c_ulong),
     ("hwndActive", c_ulong),
     ("hwndFocus", c_ulong),
     ("hwndCapture", c_ulong),
     ("hwndMenuOwner", c_ulong),
     ("hwndMoveSize", c_ulong),
     ("hwndCaret", c_ulong),
     ("rcCaret", RECT)
 ]



def get_selected_text_from_front_window(): # As String
    ''' vb6 to python translation '''

    gui = GUITHREADINFO(cbSize=sizeof(GUITHREADINFO))
    txt=''
    ast_Clipboard_Obj=None
    Last_Clipboard_Temp = -1


    user32.GetGUIThreadInfo(0, byref(gui))

    txt = GetCaretWindowText(gui.hwndCaret, True)

    '''
    if Txt = "" Then
        LastClipboardClip = ""
        Last_Clipboard_Obj = GetClipboard
        Last_Clipboard_Temp = LastClipboardFormat
        SendKeys "^(c)"
        GetClipboard
        Txt = LastClipboardClip
        if LastClipboardClip <> "" Then Txt = LastClipboardClip
        RestoreClipboard Last_Clipboard_Obj, Last_Clipboard_Temp
        print "clbrd: " + Txt
    End If
    '''    
    return txt



def GetCaretWindowText(hWndCaret, Selected = False): # As String

    startpos =0
    endpos =0

    txt = ""

    if hWndCaret:

        buf_size = 1 + win32gui.SendMessage(hWndCaret, win32con.WM_GETTEXTLENGTH, 0, 0)
        if buf_size:
            buffer = win32gui.PyMakeBuffer(buf_size)
            win32gui.SendMessage(hWndCaret, win32con.WM_GETTEXT, buf_size, buffer)
            txt = buffer[:buf_size]

        if Selected and buf_size:
            selinfo  = win32gui.SendMessage(hWndCaret, win32con.EM_GETSEL, 0, 0)
            endpos   = win32api.HIWORD(selinfo)
            startpos = win32api.LOWORD(selinfo)
            return txt[startpos: endpos]

    return txt

if __name__ == '__main__':
    print get_selected_text_from_front_window()
于 2011-09-23T23:40:01.163 に答える
1

Ctrl-C メソッドを使用する方がはるかに優れています。テキストの直接フェッチは、エディット コントロールのようなものでは機能しますが、アプリケーションが独自のウィンドウに直接描画したテキストを取得するには役に立ちません。

于 2009-06-17T20:58:12.357 に答える
1

些細なことではありませんが、ここが出発点です

import win32gui
hwnd = win32gui.GetForegroundWindow()
print win32gui.GetWindowText(hwnd)

フォーカスのある子ウィンドウを取得するにはFindWindow、を使用する必要があるかもしれませんFindWindowEx

編集: また、さまざまなウィンドウに関する情報を取得する方法を確認するために spy++ を使用して実験している間、hwnd、ウィンドウ クラスなどを参照してください。

基本的に、C/C++/C#で例を見つけることができれば、それをpywin32に相当するものに変換することは難しくないので、ある意味ではwin32 API固有の質問です

于 2009-06-17T14:52:30.647 に答える