如何用C++检测当前选中的活动界面是否启用输入功能
Alright, let's break down how to check if the currently focused window/control accepts text input using C++ on Windows 7 (and most modern Windows versions, for that matter). First, let's align with the behavior you observed:
Observed Behavior Recap
- When focused on a non-input web page, pressing Space scrolls the page downward.
- When focused on an input-enabled control (like
inputelements,textarea, text/code editors, or search bars), pressing Space inserts a space character. - When on the desktop (all windows minimized), pressing alphanumeric keys triggers a system beep instead of typing.
How to Check for Input-Capable Active Controls in C++
To solve this, we'll rely on Windows API functions—since this is Windows-specific behavior, native system calls are our best bet. Here's a step-by-step approach:
Step 1: Get the Focused Control's Handle
First, we need to grab the handle (HWND) of the currently focused window or control using GetFocus(). This function returns nullptr if no control is focused (like when the desktop is active).
Step 2: Validate if the Control Accepts Input
There are a few reliable ways to check this:
- Check standard control class names: Many input controls have well-known class names, such as
EDIT(single-line text inputs),RichEdit20W(rich text editors), orTEXTAREA(web browser text areas). - Check for read-only status: Even if a control is an edit type, it might be read-only. Use
GetWindowLongPtr()to fetch its style flags and check ifES_READONLYis set. - Use UI Automation for web/complex controls: For modern browsers or custom UI elements, the Windows UI Automation API lets you inspect accessibility properties (like whether an element supports the
ValuePattern, which signals input capability).
Example Code Snippet
Here's a basic implementation that covers standard Windows controls:
#include <windows.h> #include <string> #include <iostream> bool IsInputCapableControl(HWND hwnd) { if (hwnd == nullptr) { // No focused control (e.g., desktop is active) return false; } // Fetch the window's class name wchar_t className[256]; GetClassNameW(hwnd, className, sizeof(className)/sizeof(wchar_t)); std::wstring classStr(className); // List of common input-capable control classes const std::wstring inputClasses[] = {L"EDIT", L"RichEdit20W", L"RichEdit50W", L"TEXTAREA", L"ComboBox"}; for (const auto& cls : inputClasses) { if (classStr == cls) { // Ensure the control isn't read-only LONG style = GetWindowLongPtr(hwnd, GWL_STYLE); if (!(style & ES_READONLY)) { return true; } } } // For web browsers/custom controls, use UI Automation to check ValuePattern support // (Requires linking to UIAutomation.lib and additional setup) return false; } int main() { HWND focusedHwnd = GetFocus(); bool canInput = IsInputCapableControl(focusedHwnd); if (canInput) { std::cout << "Active control accepts text input." << std::endl; } else { std::cout << "Active control doesn't accept input (or desktop is active)." << std::endl; } return 0; }
Key Notes
- Desktop case: When the desktop is active,
GetFocus()returnsnullptr, so our function returnsfalse—matching the beep-on-key-press behavior. - Web browsers: Modern browsers like Chrome/Firefox use custom input controls, so the above code won't detect them. For these, use the Windows UI Automation API to inspect if the element supports input via accessibility patterns.
- Custom controls: Some apps use unique input controls—you may need to add their class names to the list or use UI Automation for broader coverage.
内容的提问来源于stack exchange,提问作者javabhai

