Win32API | ウィンドウを常に最背面に表示する | HSP

Win32API | ウィンドウを常に最背面に表示する | HSP

最前面に表示したいなら SetWindowPos 関数 で HWND_TOPMOST を指定すればよいのですが、ちょっと訳あって常に一番後ろに表示したくなって、困ってしまいました (^^;
HWND_NOTOPMOST という、それっぽい定数を見つけたのですが、なぜかこれを指定しても上手く動いてくれなかったので、ちょっと遠回りしてやりました。

ソースコード

#include "user32.as"

// 定数
/* ウィンドウメッセージ */
#define WM_WINDOWPOSCHANGING 0x0046

/* その他 */
#define HWND_BOTTOM 0x0001

#define SWP_NOSIZE     0x0001
#define SWP_NOMOVE     0x0002
#define SWP_SHOWWINDOW 0x0040

// 
// メイン
// 

oncmd gosub *OnWindowPosChanging, WM_WINDOWPOSCHANGING
SetWindowPos hwnd, HWND_BOTTOM, 0, 0, 0, 0, (SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE)

stop

// 
// ウィンドウサイズ・位置・Z オーダーが変更された時
// 
*OnWindowPosChanging

dupptr windowPos, lParam, 28, 4

windowPos.1 = HWND_BOTTOM // windowPos.hwndInsertAfter = HWND_BOTTOM

return

※終了時はウィンドウを (最前面には出てこないが) アクティブ化し、[Alt]+[F4]キーで終了してください。 

説明

起動時は普通に SetWindowPos し、Z オーダーが変更された (ウィンドウメッセージ WM_WINDOWPOSCHANGING が送られてきた) 時に lParam が示している WINDOWPOS 構造体 で位置を指定して、Z オーダーを維持します。
はじめ、WM_WINDOWPOSCHANGING でなく WM_ACTIVATE でやろうとしたのですが、思い通りの挙動をしてくれなかったので色々試してみたところ、以下のような順番でメッセージが送られていました。

// クライアント領域をクリックしてアクティブ化
/* 押し下げ時 */
WM_WINDOWPOSCHANGING
WM_ACTIVATE

// 非クライアント領域 (タイトルバー) をクリックしてアクティブ化
/* 押し下げ時 */
WM_WINDOWPOSCHANGING
WM_ACTIVATE
/* 押し上げ時 */
WM_WINDOWPOSCHANGING

基本的にはクリック場所によらず WM_ACTIVATE が後に行われるようですが、タイトルバーを押し上げた時に強制的に WM_WINDOWPOSCHANGING が呼ばれるらしく、ACTIVATE のほうで処理してしまうと再び Zオーダーが変えられてしまうようです (^^;


ちなみに C でやる場合には、ウィンドウプロシージャ内で以下のようにしてください。
(HSP と C の両方が読める人なら問題ないと思うけど、念のため)

case WM_WINDOWPOSCHANGING: 
((LPWINDOWPOS)lp)->hwndInsertAfter = HWND_BOTTOM; 

雑談

何で最背面ウィンドウを出したくなったかと言いますと、自分的に すっごい良いソフトウェアのアイデアが浮かびまして、それを作るために必要だったのです。
まあ、くだらないといえばくだらない代物なんですけど、久しぶりにワクワクしながらプログラムを書いています (^^
ではまたいつか~ ノシ


「Win32API | ウィンドウを常に最背面に表示する | HSP」への2件のフィードバック

  1. なんと最背面に表示とはとても斬新ですね!
    どんなものができてくるのか、お楽しみです^^

  2. > フェルミウム湾さん
    ありがとうございます (^^
    頑張ります!!

コメントは受け付けていません。