In most of the cases, it's trickier for background messages than just FindWindow and PostMessage, also sometimes requires keybd_event and SendMessage.
First, it's necessary to pick just the right handle, and often to find it again after every few commands. For example, in MS Excel or Notepad++ menu and contents have different handles. Finding them by caption or by process often picks the wrong top-level window. win32gui.WindowFromPoint usually catches the correct nested handle well (if it's visible).
Second, there are inconsistencies in how different programs react on messages:
Basic keys including Enter and Arrows:
Have not found an application which ignores them, but in many cases it was necessary to send a mouse click first to mimic focus.
PostMessage with WM_KEYUP and WM_KEYDOWN often produce letter twice, but for VK_RETURN just once. WM_CHAR is good for upper case symbols.
Some applications like Chrome can work on background, but under very specific setup.
Mouse clicks:
They were quite reliable with
win32api.PostMessage(hwnd, WM_LBUTTONDOWN, 1, make_lparam(cx, cy))
# sleep(200)
win32api.PostMessage(hwnd, WM_LBUTTONUP, 0, make_lparam(cx, cy))
Programs may have background redraw disabled, but still catch them correctly - it may require more than one click to notice any feedback. There were some cases like SourceTree when sleep delay was necessary.
Hotkeys like Ctrl+a:
keybd_event(VK_LCONTROL, 0, KEYEVENTF_KEYDOWN, 0)
PostMessage(hwnd, WM_KEYDOWN, code('a'), 0)
PostMessage(hwnd, WM_KEYUP, code('a'), 0)
keybd_event(VK_LCONTROL, 0, KEYEVENTF_KEYUP, 0)
Chrome ignores without focus, Notepad and Firefox react simultaneously with another focused window.
Excel does something, but not the hotkey. Firefox ignores the very same command when focused.
I once did a test tool specifically for these experiments (and updated it recently), it may be quite helpful to check under every specific use case. Should simplify at least the finding handle and win32gui.WindowFromPoint part.