Pythonで2つのウィンドウを前面表示しアクティブにしたい

# やりたいこと
Windows10でPythonを使って、2つのウィンドウを一度アクティブ化し、
`Alt+Tab`で2つのウィンドウを行き来して、コピペ等の作業を自動化したい。

# 環境
* Windows10
* Python 3.9.7
* pywin32やpyautoguiはインストール済とする

# 案1(win32gui.SetWindowPos)
以下を参考に

https://blog.goo.ne.jp/masaki_goo_2006/e/6ddf4977ba01dd11d6be256c17cc2ccf

https://office54.net/python/app/windows-foreground-active

```python:forground.py
import win32gui
import win32con

hwnd = win32gui.FindWindow(None, '(無題)1 - sakura 2.3.2.0  ')
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)
hwnd = win32gui.FindWindow(None, 'Book1 - Excel')
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)
win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)
```
前面に出てきた！
`HWND_TOPMOST`の後に`HWND_NOTOPMOST`をすぐ呼ぶ事で固定を解除したうえで前面に持ってこれた。

## 問題発生
アクティブ化せずに本当にただ前面に表示させただけなので、肝心の`Alt+Tab`をしたときに1つ目と2つ目に使いたいウィンドウがいない。
これでは意味がない。
> `SetWindowPos`の後に強制的にウィンドウ内でクリックイベントを発生させてアクティブ化させよう。

みたいなのが結構あったけど、なんかいまいちしっくりこない…。
ということでこの案は不採用。

# 案2(win32gui.SetForegroundWindow)
実は調べてて先に出てきたのがこちらの案
以下を参考に

https://pentan.net/python-windowactive/

```python:forground.py
import win32gui

hwnd = win32gui.FindWindow(None, '(無題)1 - sakura 2.3.2.0  ')
win32gui.SetForegroundWindow(hwnd)

hwnd = win32gui.FindWindow(None, 'Book1 - Excel')
win32gui.SetForegroundWindow(hwnd)
```
こんな感じにしてみる。

## 問題発生
残念ながらこちらでも問題発生。
前面に表示され、アクティブ化されたのは1つ目のウィンドウだけで、
なぜか2つ目のウィンドウは前面に表示されず、タスクバーで点滅しているのみという謎の現象になってしまった。
さらに2回目の`SetForegroundWindow`呼び出し時に以下のようなエラーも出ている。
`pywintypes.error: (0, 'SetForegroundWindow', 'No error message is available')`

## 解決策
いろいろ試行錯誤したり調べたりしていると、Stack overflowで同様の現象を発見

https://stackoverflow.com/a/15503675

なんと、`SetForegroundWindow`の前に`Altキー`の押下を呼べば大丈夫とのこと。
んなアホな。と思いつつ修正し実行してみる。

```python:forground.py
import win32gui
import win32com.client

hwnd = win32gui.FindWindow(None, '(無題)1 - sakura 2.3.2.0  ')
win32gui.SetForegroundWindow(hwnd)

hwnd = win32gui.FindWindow(None, 'Book1 - Excel')
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys('%')
win32gui.SetForegroundWindow(hwnd)
```
できてるー！
エラーもでなくなってるし、`Alt+Tab`で2つのウィンドウの行き来ができる！
目的は達成されました。

なぜなのか。そういう仕様？そういう仕組み？~~おまじないと思っておけばいい？~~
もしわかる人は教え…と思ったけど聞いても理解できないかもな…。

# もう少し改造
画面名完全一致じゃなくて、部分一致とかにしたいなー。とか、
どうせ自動化処理で`pyautogui`使うし`Altキー`押下も`pyautogui`でいいや。とか考えて、
以下も参考にし

https://www.programcreek.com/python/example/10639/win32gui.EnumWindows

https://teratail.com/questions/188610

最終的にできたものがこちら

```python:forground.py
import pyautogui as pgui
import win32gui

targetWindows = ['(無題)1', 'Book1']

pgui.press('alt')
def forground(hwnd, title):
    name = win32gui.GetWindowText(hwnd)
    if name.find(title) >= 0:
        win32gui.SetForegroundWindow(hwnd)
        # return False # 列挙終了しちゃうと2つ目が取得できないので終了させない
    return True

for window in targetWindows:
    win32gui.EnumWindows(forground, window)

# 以下ループ処理等でpgui.hotkey('alt','tab')をして
# 画面を交互に切り替えてコピペしたりする。
```

すっきり収まった感がありますね。
満足！

# 最後に
`Altキー`押下の部分、試しに`Shiftキー`とかにもしてみましたが、それでも問題なく動く事を確認しました。
何かのキーが押下されれば正常に動かせるようになる、ということなのでしょうか。

あとは、`SetForegroundWindow`自体非推奨という記事もちらほらありました。
確証を得られるソースは見つけられませんでしたが、
自分で使うお遊び程度のスクリプトなのでヨシ！とします。
以上です。