CLOSE
PowerBuilder Tips

方法

Windows API の SetWindowPos 関数を利用することで、画面サイズや表示座標を調整することが可能です。
SetWindowPos 関数では、X 軸 (横軸) と Y 軸 (縦軸) だけでなく Z 軸 (奥行き) の調整が可能で、表示する画面を一番手前に表示したいときなどに便利です。
今回は、親ウィンドウから子ウィンドウを呼び出す処理を例に、子ウィンドウに対し「画面を最上位に表示し、フォーカスを離した後も最上位の表示を維持する (常に最前面表示)」動作を実現する方法をご紹介いたします。
なお、本記事の記載例における親ウィンドウと子ウィンドウは下記の役割を持ちます。

  • 親ウィンドウ (呼び出し元)

  • 子ウィンドウを呼び出すための画面です。「子ウィンドウを開く」ボタンを押下すると、子ウィンドウを開く Open 関数を実行します。

  • 子ウィンドウ (呼び出し先)

  • 親ウィンドウから呼び出された側のウィンドウを指します。本記事ではこの子ウィンドウ対して SetWindowPos 関数の設定を適用します。

外部関数を定義する

Windows API の user32.dll の SetWindowPos 関数を Microsoft 社のマニュアルをもとに、[Local External Functions] または [Global External Functions] に外部関数として定義します。
マニュアルに記載された、INT 型 (符号付き 32-bit 整数) と UINT 型 (符号なし 32-bit 整数) は、PowerBuilder ではそれぞれ Long 型と ULong 型に対応します。
なお、アプリケーションの実行プロセスの bit 数 (32-bit / 64-bit) で動作が異なるためご注意ください。
64-bit でアプリケーションを実行すると、第 2 引数に longptr 型を定義しないと SetWindowPos 関数が正常に機能しなくなることを確認しております。
本稿では、まず 32-bit 環境での実装例をご紹介します。

【Global External Functions】

// ==============================================================================
// 外部関数宣言: SetWindowPos (user32.dll)
// 【概要】指定されたウィンドウのサイズ、位置、および Z オーダーを変更する。
// 【引数】
//   - handleW1            (hWnd): 対象となるウィンドウのハンドル
//   - handleW1InsertWhere (hWndInsertAfter): Z オーダーの基準となるウィンドウハンドル、または以下の定数:
//                            0  (HWND_TOP)       : Z オーダーの先頭に配置
//                            1  (HWND_BOTTOM)    : Z オーダーの最後尾に配置
//                            -1 (HWND_TOPMOST)   : 常に最前面に配置 (非アクティブでも手前)
//                            -2 (HWND_NOTOPMOST) : 常に最前面の属性を解除
//   - x                   (X): 新しい左端の XY 座標 (ピクセル単位)
//   - y                   (Y): 新しい上端の XY 座標 (ピクセル単位)
//   - cx                  (cx): 新しい横幅 (ピクセル単位)
//   - cy                  (cy): 新しい高さ (ピクセル単位)
//   - uFlags              (uFlags): ウィンドウのサイズと位置の変更に関するフラグ (組み合わせ可能)
//                            0x0001 (SWP_NOSIZE)     : 現在のサイズを維持 (cx, cy を無視)
//                            0x0002 (SWP_NOMOVE)     : 現在の位置を維持 (x, y を無視)
//                            0x0004 (SWP_NOZORDER)   : 現在の Z オーダーを維持 (handleW1InsertWhere を無視)
//                            0x0010 (SWP_NOACTIVATE) : ウィンドウをアクティブ化しない
//                            0x0040 (SWP_SHOWWINDOW) : ウィンドウを表示する
//                            0x0080 (SWP_HIDEWINDOW) : ウィンドウを非表示にする
// 【戻り値】
//   - 成功時は 0(True)、失敗時は 0 以外 (False) を返却する。
// ==============================================================================
Function long SetWindowPos (long handleW1, long handleW1InsertWhere, long x, long y, long cx, long cy , ulong uFlags) Library "user32.dll"

パラメーターの設定

SetWindowPos 関数に渡すパラメーター (handleW1InsertWhere, uFlags) をグローバル、またはウィンドウのインスタンス変数に定義します。
「画面を最上位に表示し、フォーカスを離した後も最上位の表示を維持する」を動作を実現するため、
第 2 引数 (hWndInsertAfter) を -1 に、第 7 引数 (uFlags) を 64 に設定します。
パラメーターの値ごとの動作の詳細情報ついては、Microsoft 社の公式マニュアルをご参照ください。

【Global Variables】

// SetWindowPos 関数の第 2 引数 (hWndInsertAfter)
// ウィンドウを最上位に表示
Constant Long gl_hWndInsertAfter_HWND_TOP = -1

// SetWindowPos 関数の第 7 引数 (uFlags)
// ウィンドウを表示する
Constant long gul_uFlags_SWP_SHOWWINDOW = 64

SetWindowPos 関数を呼び出す

子ウィンドウ Open イベントでウィンドウの初期化処理を完了してから、カスタムイベントの ue_postopen イベントから SetWindowPos 関数を呼び出します。
SetWindowPos 関数に各パラメーターを以下のように設定することで、「画面を最上位に表示し、フォーカスを離した後も最上位の表示を維持する」動作を実現します。

【子ウィンドウの Open イベント】

// ウィンドウの初期化処理を完了してから、SetWindowPos 関数を呼び出す
This.Post Event ue_postopen()

// 画面を非表示にする。SetWindowPos 関数を実行後 True に再設定し画面表示する
this.Visible = False

【子ウィンドウの ue_postopen イベント】

Long ll_pos_x, ll_pos_y
Long ll_window_width, ll_window_height

// 画面表示位置
ll_pos_x = 200
ll_pos_y = 300
// 画面サイズ
ll_window_width = 800
ll_window_height = 600

// 画面を最上位に表示し、フォーカスを離した後も最上位の表示を維持する
SetWindowPos(Handle(this), gl_hWndInsertAfter_HWND_TOP, ll_pos_x, ll_pos_y, ll_window_width, ll_window_height, gul_uFlags_SWP_SHOWWINDOW)

// Open イベントで非表示 (False) にしていた画面を表示する
this.Visible = True

動作確認

親ウィンドウの「子ウィンドウを開く」ボタンを押下し、子ウィンドウを開きます。

子ウィンドウに対して SetWindowPos 関数の設定が適用され、指定した座標・サイズ、かつ Z 軸の最上位に表示されます。
子ウィンドウから親ウィンドウにフォーカスを移しても、子ウィンドウが背後に隠れることなく、最上位で表示が維持されていることが確認できます。

x instagram facebook youtube