【问题标题】:How to get the value of the textbox that has keyboard focus?如何获取具有键盘焦点的文本框的值?
【发布时间】:2021-01-01 18:13:48
【问题描述】:

我想检索用户正在输入的文本框的值

到目前为止,我已经得到了这段代码,它可以输出我拥有键盘焦点的元素中所写的内容。 但是,它只适用于记事本的文本区域,当我尝试在其他应用程序上使用它时,它会打印诸如“Chrome Legacy Window”之类的内容

from ctypes import windll, create_unicode_buffer
import win32gui
import win32con
import time

def getForegroundWindowTitle():
    hWnd = windll.user32.GetForegroundWindow()
    length = windll.user32.GetWindowTextLengthW(hWnd)
    buf = create_unicode_buffer(length + 1)
    windll.user32.GetWindowTextW(hWnd, buf, length + 1)
    
    if buf.value:
        return buf.value
    else:
        return None

time.sleep(3)
windowHandle = win32gui.FindWindow(None, getForegroundWindowTitle())
childwindowHandle = win32gui.FindWindowEx(windowHandle, None, win32gui.GetFocus(), None)
buff = create_unicode_buffer(4096)
win32gui.SendMessage(childwindowHandle, win32con.WM_GETTEXT, 4096, buff) #0x000D
print(buff.value)

【问题讨论】:

  • 为此使用 UI 自动化:docs.microsoft.com/en-us/windows/win32/winauto/… 与 python,我想你可以使用这个:
  • 我忘记了链接github.com/pywinauto/pywinauto
  • 我设法用 pywinauto ``` from pywinauto.application import Application import time app = Application(backend="uia").start('notepad.exe') time.sleep 获得了一个文本框的值(3) print(app["*Sans titre\xa0- Bloc-notes"]["EDIT"].get_value()) ```但是我还是需要指定元素("Edit")
  • 使用 Windows SDK 中的检查工具检查 UI 自动化树和每个元素支持的 UIA 模式

标签: python winapi ctypes pywin32


【解决方案1】:

您可以使用IUIAutomation::GetFocusedElement 检索具有输入焦点的当前 UI 自动化元素,然后获取值模式。

这是一个 C++ 中的 win32 示例,您可以随意在 Python 中转换它:

#include <Windows.h>
#include <iostream>
#include <UIAutomation.h>
BOOL main()
{
    HRESULT hr;
    CoInitialize(0);
    Sleep(2000);
    IUIAutomation* pClientUIA;
    hr = CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER, IID_IUIAutomation, reinterpret_cast<void**>(&pClientUIA));
    if (S_OK != hr)
    {
        printf("CoCreateInstance error: %d\n", GetLastError());
        return FALSE;
    }

    IUIAutomationElement* pFocusedElement;
    hr = pClientUIA->GetFocusedElement(&pFocusedElement);
    if (S_OK != hr)
    {
        printf("GetFocusedElement error: %d\n", GetLastError());
        return FALSE;
    }

    IValueProvider* pValueProvider;
    hr = pFocusedElement->GetCurrentPattern(UIA_ValuePatternId, reinterpret_cast<IUnknown**> (&pValueProvider));
    if (S_OK != hr)
    {
        printf("GetCurrentPattern error: %d\n", GetLastError());
        return FALSE;
    }

    BSTR text;
    hr = pValueProvider->get_Value(&text);
    if (S_OK != hr)
    {
        printf("get_Value error: %d\n", GetLastError());
        return FALSE;
    }
    wprintf(L"%s\n", text);
    SysFreeString(text);

    CoUninitialize();
}

结果:

【讨论】:

  • 您的代码是否可以在任何地方使用?我是用 C# 制作的(python 似乎太有限了),但它只适用于几个文本框(Edge 上的任何地方,Chrome 搜索栏中的任何地方,仅此而已)
  • 它不支持所有类型的控件。支持IValueProvidercontrol type可以工作,如UIA_EditControlTypeIdUIA_DocumentControlTypeId
  • 您可以使用inspect.exe查看控件类型。
  • 您可能需要为不同类型的控件编写不同的方法。顺便说一句,您无法获取哪些文本框的值?
  • 我无法解决 AutomationElement.FocusedElement 无法正常工作的问题,所以我终于按照你的暗示在 C++ 中做到了。感谢您的帮助!
猜你喜欢
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多