【问题标题】:How to detect whether the focused window is an Edit 'type' control?如何检测焦点窗口是否是编辑'类型'控件?
【发布时间】:2016-04-28 02:16:06
【问题描述】:

如何检测焦点窗口是否是 Edit 'type' 控件?我知道的一种方法是使用Microsoft Active Accessibility,看起来使用这种方法需要付出很多努力。

还有其他更简单的方法吗?

我的用例是:当编辑控件获得焦点时,存储 hwnd

// Callback set by SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, NULL, (WINEVENTPROC)&winEventProc, 0, 0, WINEVENT_SKIPOWNPROCESS);
void CALLBACK KeyboardComponent::winEventProc(HWINEVENTHOOK hWinEventHook, DWORD  event, HWND hwnd, LONG idObject,
    LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
    // if hwnd == "Edit Control" store hwnd to send key input events

    // One technique but not comprehensive
    TCHAR wndClassName[255];
    GetClassName(hwnd, wndClassName, 255);

    if (_tcsicmp(wndClassName, _T("edit")) == 0)
        targetEdit = hwnd;

    // Class names I am receiving are subclassed or new window classes that look and operate like Edit controls.
    // Ie when clicking the Firefox address bar I get: MozillaWindowClass
    // Ie when clicking the Chrome address bar I get:  Chrome_WidgetWin_1
}

【问题讨论】:

  • 代码有什么问题?使用 Windows API 可以查看窗口类名称,这正是您正在做的事情。
  • 我必须否决这个问题,因为,如果我想要 EDIT 课程并获得 EDIT 课程,这就是我想要的。 OP 无法理解并非所有看起来都是编辑控件的控件都是“编辑”类。
  • 我不认为你真的明白你在这里做什么。谁说控件甚至是窗口化的。您已经找到了正确的解决方案,即 UI 自动化。别跑了。
  • 你打算用你想存储的hwnd做什么?

标签: c++ winapi


【解决方案1】:

Active Accessibility 是正确的解决方案。您可以使用AccessibleObjectFromEvent() 为触发winEventProc 钩子的HWND 获取IAccessible 接口,然后检查IAccessible::AccRole 属性中的ROLE_SYSTEM_TEXT

ROLE_SYSTEM_TEXT
该对象表示允许编辑或被指定为只读的可选文本。

例如:

// Callback set by SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, NULL, (WINEVENTPROC)&winEventProc, 0, 0, WINEVENT_SKIPOWNPROCESS);
void CALLBACK KeyboardComponent::winEventProc(HWINEVENTHOOK hWinEventHook, DWORD  event, HWND hwnd, LONG idObject,
    LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
    IAccessible* pAcc = NULL;
    VARIANT varChild;
    HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);  
    if ((hr == S_OK) && (pAcc != NULL))
    {
        VARIANT varRole;
        hr = pAcc->get_accRole(varChild, &varRole);
        if ((hr == S_OK) && (varRole.vt == VT_I4) && (varRole.lVal == ROLE_SYSTEM_TEXT))
        {
            // ... 
        }
        pAcc->Release();
    }
}

【讨论】:

    【解决方案2】:

    为了获得可靠的结果,请尝试使用RealGetWindowClass,它应该处理窗口被子类化的情况。如果您不在乎,请使用普通的GetClassName

    如果您想要处理不是从标准 Edit 类派生的控件,当然这些都不起作用。

    【讨论】:

      【解决方案3】:

      您可以使用此代码来了解焦点窗口是否为编辑控件

      CWnd* pControl; 
      pControl = this->GetFocus();
      
      if(pControl->IsKindOf(RUNTIME_CLASS(CEdit))){
            //----
             -----
             ----//
      }
      

      获取更多详情Here

      Cwnd 转换为HWND

      pControl->GetSafeHwnd();
      

      【讨论】:

      • 这仅在您使用 MFC 并且相关编辑被子类化时才有效
      • ...以及您自己程序中的控件。鉴于此人正在编写无障碍客户端,这三件事都不是。
      猜你喜欢
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-20
      相关资源
      最近更新 更多