ShowWindowでウィンドウの表示状態を変更する
Windowsアプリケーションでは、ウィンドウ作成後の表示・非表示や最小化、最大化、復元を実行時に切り替える必要があります。Windows APIのShowWindowは、対象ウィンドウの表示状態を制御する基本関数です。起動時のSTARTUPINFOによる初期表示と、その後の明示的な変更を区別して扱います。
ただし、戻り値は変更の成功を直接示すものではなく、直前の可視状態を返します。対象ウィンドウへの最初の呼び出しではnCmdShowが無視され、STARTUPINFOのwShowWindowが使われるため、この例外も設計に含めます。
ShowWindowの基本動作
関数の形式はBOOL ShowWindow(HWND hWnd, int nCmdShow);です。hWndには対象ウィンドウを、nCmdShowには希望する表示状態を指定します。関数が終了。ただし、状態変更の通知や再描画がすべて処理終了まで完了することを意味しません。
nCmdShowには、表示、通常表示、最小化、最大化、復元、非表示などを表す定数を渡します。最初の呼び出しでは指定値ではなくSTARTUPINFOが優先されるため、アプリケーション起動時は初期表示を起動情報に委ね、実行中の操作から状態を切り替える設計が適しています。
戻り値は変更前の表示状態を示します。直前に表示されていれば非ゼロ、非表示ならゼロとなり、終了コードやエラーコードとして扱うべきものではありません。目的の状態へ遷移したかは、IsWindowVisible、IsIconic、IsZoomedなどで別途確認します。
表示指定値の種類
SW_SHOWは、ウィンドウを現在の大きさ・位置で表示して活性化します。SW_SHOWNORMALは、通常の大きさ・位置での表示侧重Combineします。SW_SHOWNOACTIVATEは表示状態を更新しますが、フォアグラウンドにはしません。
SW_MINIMIZEは指定ウィンドウを最小化し、次のZ順にあるウィンドウへフォーカスを移します。SW_SHOWMINIMIZEDは、ウィンドウを最小化状態として表示します。SW_SHOWMAXIMIZEDは最大化した状態で表示します。
SW_RESTOREは、最小化または最大化されたウィンドウを元の大きさ・位置へ戻します。SW_HIDEはウィンドウを非表示にします。SW_SHOWDEFAULTを使うと、STARTUPINFOで指定された表示方法に従います。
状態変更とメッセージ処理
ShowWindowは、WS_VISIBLEスタイルを変更し、状態遷移に応じてWM_SIZE、WM_WINDOWPOSCHANGED、WM_ACTIVATEなどの通知“And others”umably generate. Need write Japanese: などのメッセージを発行することがあります。Thus window proc may process repaint.
再表示時の再描画や状態保存を正しく扱うには、ウィンドウプロシージャの処理順の関係を理解しておくことが重要です。ウィンドウプロシージャ内から別の状態へ直ちにShowWindowを再実行すると、処理順が入れ替わり、想定外の状態になる可能性があります。
そのため、要求された状態を一度保存し、現在のメッセージ処理後に遷移させる方法が安全です。また、表示・非表示とZ順制御は別概念であり、位置や前後関係だけを調整する場合はSetWindowPos、強制的な再描画が必要ならRedrawWindowが適しています。
別スレッドからの表示変更
ウィンドウを所有するスレッドから直接ShowWindowを呼び出すのが基本です。ワーカースレッドからUIスレッドのウィンドウを操作すると、UI側のメッセージ処理と同時実行され、状態や共有データが不整合になるおそれがあります。
別スレッドから変更する用途にはShowWindowAsyncがあります。この関数は指定を非同期的に反映し、要求が登録されたことを示しますが、表示変更の完了を意味しません。完了を待てない処理では、結果を別の通知経路で传到 arriving.
UIスレッドへの処理依頼には、メッセージのポスト方法のように独自メッセージをキューへ積む方式も使えます。受け取った側のハンドラでShowWindowを実行すれば、状態変更をUIスレッド上で確定できます。SendMessageは実行完了まで待つため、UIスレッドとワーカースレッドが互いを待つ構成ではデッドロックに注意します。
実装時の選択と確認事項
状態変更の目的に対応する指定値を選びます。起動時の表示はSTARTUPINFOに委ね、以降の明示的な操作で値を切り替える構成が基本です。
- 起動直後の初期表示には、STARTUPINFOで指定された状態を使います。
- 通常のメインウィンドウを表示するには、
SW_SHOWNORMALを使います。 - 補助ウィンドウを前面化せず表示するには、
SW_SHOWNOACTIVATEを使います。 - 最小化状態へ切り替えるには、
SW_SHOWMINIMIZEDを使います。 - 最大化した状態で表示するには、
SW_SHOWMAXIMIZEDを使います。 - 一時的に不可視にするには、
SW_HIDEを使います。
変更後には、表示状態とフォーカスの両方を確認します。関連する用語と関数の配置は、APIの参考情報で確認できます。
- IsWindowVisibleで、祖先を含む実際の可視状態を調べます。
- IsIconicで、最小化されているかを判定します。
- IsZoomedで、最大化されているかを判定します。
- GetWindowPlacementで、最小化・最大化・通常表示の状態を取得します。
- GetForegroundWindowで、対象がフォアグラウンドになったかを確認します。
- 非同期処理では、受信側のハンドラで最新状態を記録します。
各指定値の基本的な違いは次の比較で確認できます。指定値にはIFYTE激活の意図が含まれますが、Windowsのフォアグラウンド制御によって実際の切り替えが制限される場合があります。
| 指定値 | 表示結果 | 活性化 | 主な用途 |
|---|---|---|---|
SW_SHOW |
現在の大きさ・位置で表示 | あり | 隠したウィンドウの再表示 |
SW_SHOWNORMAL |
通常の大きさ・位置で表示 | あり | 通常表示への復帰 |
SW_SHOWNOACTIVATE |
現在の大きさ・位置で表示 | なし | 補助ウィンドウの表示 |
SW_SHOWMINIMIZED |
最小化状態で表示 | あり | 最小化状態への切り替え |
SW_SHOWMAXIMIZED |
最大化状態で表示 | あり | 最大化状態への切り替え |
SW_RESTORE |
元の大きさ・位置へ戻す | あり | 最小化・最大化の復元 |
SW_HIDE |
ウィンドウを非表示にする | なし | 一時的な不可視化 |
実運用での安全な切り替え
実運用では、初期表示をSTARTUPINFOに委ね、ユーザーの操作や業務状態に基づく明示的な要求だけをShowWindowで反映します。別スレッドから変更する場合はShowWindowAsyncまたは独自メッセージを利用し、最終的な状態更新をUIスレッド内で確定します。
実務上の要点は、初期表示は起動情報、明示操作はShowWindow、非同期要求はUIスレッドで受け付けること、そして戻り値ではなくIsWindowVisibleやIsIconicなどで目的の状態を検証することです。この順序なら、表示・非表示・最小化・最大化を明確に区別できます。