Skip to content

Pywinauto backends reference

Module-level reference for the optional pywinauto backend implementations.

📦 Keys backend module

_keys

PywinautoKeysBackend — keystroke injection via pywinauto.keyboard.

Implements :class:~ezxl.gui._protocols.AbstractKeysBackend using pywinauto.keyboard.send_keys rather than Application.SendKeys.

Key notation translation

VBA SendKeys and pywinauto share the same modifier prefixes (^ for Ctrl, % for Alt, + for Shift) and most special-key braces. The only common divergence is {ESCAPE} which pywinauto spells {ESC}. The private :func:_translate_keys function normalises the most frequent VBA patterns to their pywinauto equivalents before injection.

Limitations

  • The wait parameter has no direct equivalent in pywinauto.keyboard. When wait=True (default), a brief synchronous pause (50 ms) is inserted after the keystroke sequence. This is a best-effort approximation and may not be sufficient for slow Excel responses.
  • This backend has no COM dependency and no thread constraint.
Note

pywinauto is an optional dependency. Install it with::

pip install pywinauto

PywinautoKeysBackend

PywinautoKeysBackend(hwnd: int | None = None)

Bases: AbstractKeysBackend

Keystroke injection via pywinauto.keyboard.send_keys.

Translates VBA SendKeys notation to pywinauto notation using :func:_translate_keys, then delegates to pywinauto.keyboard.send_keys.

This backend is a standalone alternative to the COM-based _COMKeysBackend. It does not require an :class:~ezxl.core.ExcelApp instance and carries no COM STA thread constraint.

Parameters:

Name Type Description Default
hwnd int | None

Win32 window handle for the Excel main window. Currently unused — pywinauto.keyboard.send_keys injects keystrokes into the currently focused window. Ensure the Excel window has focus before calling :meth:send_keys. The parameter is accepted for API consistency with the other pywinauto backends and reserved for future use.

None
Example

from ezxl.gui.pywinauto import PywinautoKeysBackend keys = PywinautoKeysBackend() keys.send_keys("^s") # Ctrl+S keys.send_keys("{ESCAPE}") # maps to {ESC} internally keys.send_keys("^{HOME}")

Inject into GUIProxy:

from ezxl import ExcelApp, GUIProxy with ExcelApp(mode="attach") as xl: ... gui = GUIProxy(xl, keys=PywinautoKeysBackend()) ... gui.send_keys("^{HOME}")

send_keys

send_keys(keys: str, wait: bool = True) -> None

Send a keystroke sequence using pywinauto.keyboard.

Translates keys from VBA SendKeys notation to pywinauto notation via :func:_translate_keys, then calls pywinauto.keyboard.send_keys. If wait is True, a brief pause of 50 ms is inserted after injection as a best-effort approximation of the VBA wait=True semantics.

Note

pywinauto.keyboard.send_keys injects keystrokes into the currently focused window. Call window.set_focus() on the Excel window before using this backend if focus cannot be guaranteed.

Parameters:

Name Type Description Default
keys str

Keystroke string in VBA SendKeys notation (e.g. "{ENTER}", "^s" for Ctrl+S, "{ESCAPE}" for Escape).

required
wait bool

If True, insert a 50 ms pause after sending. This is a best-effort approximation; it does not guarantee Excel has finished processing. Defaults to True.

True

Raises:

Type Description
GUIOperationError

If the pywinauto keystroke injection raises an unexpected error.

Example

backend.send_keys("^s") # Ctrl+S backend.send_keys("{ESCAPE}") # → {ESC} internally backend.send_keys("%{F4}", wait=False) # Alt+F4, no pause

📦 Backstage backend module

_backstage

PywinautoBackstageBackend — Excel Backstage (File tab) visual navigation via pywinauto UI Automation with Alt-sequence fallback.

The Backstage is the full-screen overlay opened via the Excel File ribbon tab. Excel does not expose AutomationId on Backstage controls. This backend navigates primarily via UIA direct click (locale-dependent but focus-independent), with an Alt-key sequence fallback for environments where UIA click is unreliable.

Implements :class:~ezxl.gui._protocols.AbstractBackstageNavigator, which covers UIA-driven operations: opening the Options panel, opening the Save As panel without confirming, and the UIA variants of open-file and close-workbook.

Strategy order

  1. Primary — UIA direct click: locate the Button "Onglet Fichier" (or locale equivalent) and click it to open the Backstage, then click the target ListItem inside the resulting List "Fichier" (or locale equivalent). This strategy requires no keyboard focus and is robust against window-focus loss.
  2. Fallback — Alt-sequence: send spec.alt_sequence via pywinauto.keyboard.send_keys. Only attempted when the UIA strategy fails and the spec provides a non-empty sequence.

All actions are flat methods — no object-tree traversal.

Responsibilities

This backend owns UIA-level navigation only. File I/O operations (save, save_as with a path, format-aware SaveAs) belong to :class:~ezxl.gui.win32com.COMBackstageBackend via :class:~ezxl.gui._protocols.AbstractBackstageFileOps. The two backends compose inside :class:~ezxl.gui.GUIProxy with no cross-dependency.

Extensibility

Consumer libraries extend the element registry without modifying ezxl::

from ezxl.gui.pywinauto._backstage import PywinautoBackstageBackend
from ezxl.gui.pywinauto._registry import UIElementSpec

_SAP_ELEMENTS = {"sap_logon": UIElementSpec(key="sap_logon", alt_sequence="%XL")}

class HanaisBackstageBackend(PywinautoBackstageBackend):
    _ELEMENTS = PywinautoBackstageBackend._ELEMENTS | _SAP_ELEMENTS

    def sap_logon(self) -> None:
        self._execute_by_spec(self._get_spec("sap_logon"))
Note

pywinauto is an optional dependency. Install it with::

pip install pywinauto

PywinautoBackstageBackend

PywinautoBackstageBackend(hwnd: int | None = None, locale: str = 'en')

Bases: AbstractBackstageNavigator

Excel Backstage visual navigation via UIA direct click with Alt-sequence fallback.

Implements :class:~ezxl.gui._protocols.AbstractBackstageNavigator using pywinauto. The primary strategy for every action is a UIA direct click — the backend opens the Backstage via Button "Onglet Fichier" (or locale equivalent), then clicks the target ListItem by its localised UIA Name. This approach is focus-independent.

An Alt-sequence fallback is attempted only when the UIA click fails and the element spec carries a non-empty alt_sequence.

This backend does not perform file I/O. Operations that write to disk (save, save_as with an explicit path) belong to :class:~ezxl.gui.win32com.COMBackstageBackend and are exposed through GUIProxy.backstage. This backend is composed alongside it via GUIProxy.backstage_nav.

Parameters:

Name Type Description Default
hwnd int | None

Win32 window handle for the Excel main window. Pass None to auto-detect the first visible Excel instance. Always pass xl.hwnd in production to avoid targeting the wrong window when multiple Excel instances are open.

None
locale str

Locale code used for UIA Name-based searches. Accepted values: "en" (default), "fr".

'en'
Example

backend = PywinautoBackstageBackend(hwnd=xl.hwnd, locale="fr") backend.open_options() # UIA: opens Options panel backend.open_save_as_panel() # UIA: opens Save As panel, leaves open backend.open_file() # UIA: opens Open panel backend.close_workbook() # UIA: clicks Close in Backstage

open_options

open_options() -> None

Navigate to the Excel Options panel via the Backstage.

Raises:

Type Description
GUIOperationError

If the Options panel cannot be reached.

Example

backend.open_options()

open_save_as_panel

open_save_as_panel() -> None

Open the Save As panel in the Backstage without confirming a save.

Clicks the "Enregistrer sous" (or locale equivalent) ListItem and leaves the panel open. Does not write to disk — use GUIProxy.backstage.save_as(path=...) for programmatic saves.

Raises:

Type Description
GUIOperationError

If the panel cannot be reached.

Example

backend.open_save_as_panel()

open_file

open_file() -> None

Open the Open panel via the Backstage.

Raises:

Type Description
GUIOperationError

If the panel cannot be reached.

Example

backend.open_file()

close_workbook

close_workbook() -> None

Close the active workbook via a Backstage UIA click.

Raises:

Type Description
GUIOperationError

If the action cannot be completed.

Example

backend.close_workbook()