On This Page
advertisement

This page is part of the ORA Technical Notes series. it is not necessary for most users to read, understand, or retain the information on this help page. It is provided for power users and other people who are interested in (mostly technical) details.

ORA's implementation is constantly changing and the details in this Technical Note may not be up-to-date.

Introduction

ORA's Auto Type facility sends keystrokes to the target application. One of the challenges of implementing ORA's Auto Type feature is the requirement to switch from the browser window to a window owned by the target application. Microsoft Windows provides a system call for this task, SetForegroundWindow. Unfortunately, using that system call effectively is not simple.

For practical and security reasons, SetForegroundWindow will not switch to the target window unless certain conditions are met. Those conditions are described in the documentation for SetForegroundWindow. As far as I can tell, those conditions have not changed much over the years. However, the results of using SetForegroundWindow vary. What works under Windows 10 is not guaranteed to work under Windows 11. That may be due to Microsoft Windows changes or by browser software changes, and likely both.

One of the enabling conditions described by Microsoft is The process was started by the foreground process.

OraHost appears to meet that condition: OraHost is a process that is started by the current browser, and the current browser owns the foreground window when an ORA user clicks an Auto Type button to start the Auto Type process. Browsers use several processes to isolate one tab from another and to isolate any specific tab to the main browser process. That means it may not be strictly true that the OraHost process was started by the process associated with the foreground window. Both may be sub-processes of the browser's main process or some other sub-processes.

For one reason or another, when OraHost does nothing more than call SetForegroundWindow, the results are unreliable. Sometimes, and under certain conditions, the call succeeds. Sometimes, and under different conditions, the call fails.

In versions of OraHost prior to v1.65, when SetForegroundWindow failed, keystrokes intended for the target window were sent to the browser window. That happened because the SetForegroundWindow result code did not seem reliable. Sometimes, when it reported a failure, the target window was actually brought to the foreground and Auto Type would work as expected. Because the success/failure result of the SetForegroundWindow function was not reliable, OraHost would send the keystrokes even when the result indicated a failure.

As of OraHost v1.65, OraHost (1) uses tricks to influence the SetForegroundWindow outcome, and (2) uses a new method to determine if SetForegroundWindow succeeded or failed.

Tricks

Over time, other developers have learned tricks where steps taken before calling SetForegroundWindow influence the outcome. OraHost now uses three attempts to switch to the target window.

  1. First attempt:
    1. Call SetForegroundWindow
    2. Wait for 10ms
    3. Call GetForegroundWindow to determine if the SetForegroundWindow call succeeded

    If this attempt succeeds, OraHost does not follow the additional steps and proceeds with sending the user-specified keystrokes to the target window.

  2. Second attempt:
    1. Send virtual keyboard events WM_KEYDOWN and WM_KEYUP to press and release the Alt key
    2. Wait for 10ms
    3. Call SetForegroundWindow
    4. Wait for 10ms
    5. Call GetForegroundWindow to determine if the SetForegroundWindow call succeeded

    This trick--pressing Alt before calling SetForegroundWindow--seems to convince Windows that the process calling SetForegroundWindow has the right to switch the focus to a different window. There is a possible negative consequence: the browser may respond to the initial Alt key WM_KEYDOWN and WM_KEYUP. In testing, this was not an issue, but there are multiple browsers and they change frequently.

    Testing revealed that when this trick succeeded, setting the foreground window for the next use of Auto Type succeeded using the simple approach described in #1 above. That minimizes the impact of any Alt key side-effect because it is only used once per browser session.

    If this attempt succeeds, OraHost does not follow the additional steps and proceeds with sending the user-specified keystrokes to the target window.

  3. Third attempt:
    1. Send a virtual keyboard event WM_KEYDOWN to press the Alt key
    2. Wait for 10ms
    3. Call SetForegroundWindow
    4. Send virtual keyboard events WM_KEYDOWN and WM_KEYUP to press and release the Alt key
    5. Wait for 10ms
    6. Call GetForegroundWindow to determine if the SetForegroundWindow call succeeded

    This trick--sending a WM_KEYDOWN for Alt without sending a WM_KEYUP before calling SetForegroundWindow--seems to convince Windows that the process calling SetForegroundWindow has the right to switch the focus to a different window. From the perspective of the operating system, the SetForegroundWindow call occurs while the Alt key is held down. Why does that help? Who knows!?!

    There is a possible negative consequence: the browser may respond to the Alt WM_KEYDOWN and the target application's window gets a WM_KEYDOWN and WM_KEYUP for the Alt key. The WM_KEYDOWN and WM_KEYUP are sent to the target window to prevent the target application from reacting to the user's keystrokes as if the Alt key was held down.

    Testing revealed that when this trick succeeded, setting the foreground window for the next use of Auto Type succeeded using the simple approach described in #1 above. That minimizes the impact of any Alt key side-effect because it is only used once per browser session.

    If this attempt succeeds, OraHost proceeds with sending the user-specified keystrokes to the target window.

Success or Failure

As of OraHost version 1.65, to determine whether SetForegroundWindow succeeded or not, OraHost delays 10ms after calling SetForegroundWindow, then uses GetForegroundWindow to determine if the target window is now the foreground window. That method seems to be reliable, and so, if none of the attempts described above succeed, OraHost displays an error message and does not send the user-specified keystrokes to the target window. That is a significant improvement for OraHost users compared to prior versions.