参照するすべての API 関数には、ターゲット ウィンドウに何らかのメッセージを送信 (!) するという共通点があります。UpdateWindow は、WM_PAINT を送信する必要があるため、おそらく最も明白です。メッセージを「送信」し、キューに投稿しないことにも注意してください (UpdateWindow の場合、MSDN のドキュメントではこれを明示的に呼び出していますが、それ以外の場合はあまり明白ではない可能性があります)。
また、一部のコメントで言及されているように、ウィンドウにはスレッド アフィニティがあることに注意してください。とりわけ、これは、そのウィンドウへのメッセージが 1 つのスレッドでのみ受信/ディスパッチされることを意味します。別のスレッドのウィンドウにメッセージを送信した場合、オペレーティング システムは、そのメッセージをいつディスパッチするか (つまり、ウィンドウ プロシージャを呼び出すか) を決定するタスクを残されます。これ (着信送信メッセージのディスパッチ) は、ランダム メッセージでウィンドウ プロシージャを安全に呼び出すことができる特定の API 呼び出し中にのみ発生します。関連する時間は、GetMessage と PeekMessage* の間です。
そのため、ウィンドウ所有スレッド (UI スレッドとも呼ばれます) がメッセージを正常にポンピングしている場合、着信送信メッセージも迅速にディスパッチされます。ただし、あなたの質問からは、UI スレッドが現在ビジーであるようです。次に、2 番目のスレッドが上記の関数の 1 つを呼び出すと、最初のスレッドが送信されたメッセージをディスパッチする機会を提供するまでブロックされます。
他の人が言ったように、通常はユーザー インターフェイス コードを 1 つの専用 UI スレッドに保持することをお勧めします (例外はありますが、常にそうであるように、ルールは証明されています)。また、ウィンドウを所有するスレッドが常にメッセージに応答できるようにすることは、(優れたユーザー エクスペリエンスのために) 絶対に必要です。UI スレッドも一部の同期オブジェクトを待機する必要がある場合は、MsgWaitForMultipleObjects が役立つことがあります。
*リストは完全ではない可能性があります。