あの機能はどこいったと探すのが使いづらいと感じたり、UACはやっぱり邪魔くさいと思いつつ、それでもVistaに触る日々が続きます。さて、何かWindows Vistaの新機能を試せるものはないかと探していたところ、DWMが関数1つから使えてお手軽そうでした。

前回もお見せしたスクリーンショットは、Windows Aeroを使い、しかも半透明ガラス効果が有効になっています。タイトルバーや枠が半透明で後ろが透けているのが分かると思います。この処理は、クライアント領域まで食い込ませられます。それに使うのが今回使うDwmExtendFrameIntoClientArea関数です。

ABのウィンドウアプリケーションのプロジェクトで、Createイベントに次の処理を追加します。

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
	SetClassLongPtr(hMainWnd, GCL_HBRBACKGROUND, 0)

	Dim m As MARGINS
	m.cxLeftWidth = 20
	m.cxRightWidth = 20
	m.cyTopHeight = 20
	m.cyBottomHeight = 20
	Dim ret = DwmExtendFrameIntoClientArea(hMainWnd, m)
End Sub

さらに次のグローバルな宣言を追加します。

Type MARGINS
	cxLeftWidth As Long
	cxRightWidth As Long
	cyTopHeight As Long
	cyBottomHeight As Long
End Type

Declare Function DwmExtendFrameIntoClientArea Lib "dwmapi" (
	hwnd As HWND, ByRef marginset As MARGINS) As HRESULT

すると、こうなります。クライアント領域へもガラス効果が侵食している様子

真ん中が完全に透けているのは、SetClassLongPtrでウィンドウ背景のブラシをなくしているからだと思います。最初、SetWindowLongPtrを行わないでいたら、ガラス効果のクライアント領域への侵食も起こらずうまくいかないのはなぜだろうと悩みました。

MARGINS型変数では上下左右どれくらい食い込ませるか指定しており、ウィンドウハンドルと共に DwmExtendFrameIntoClientAreaを呼び出しています。本来はDWMが有効かどうか調べたり、Vistaより前のWindowsに対応するためdwmapi.dllを動的リンクしたりなどといったことをしなければなりませんが、面倒だしサンプルということで無視しました。実用時には考慮しないといけません。

いずれかのメンバに負の値を指定すると全体にガラス効果が適用されるようです。

Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
	SetClassLongPtr(hMainWnd, GCL_HBRBACKGROUND, 0)

	Dim m As MARGINS
	m.cxLeftWidth = -1
	m.cxRightWidth = 0
	m.cyTopHeight = 0
	m.cyBottomHeight = 0
	Dim ret = DwmExtendFrameIntoClientArea(hMainWnd, m)
End Sub

ウィンドウ全体にガラス効果が適用された様子うまく使えば、UIデザインの幅を広げるのに使えるかもしれません。現状ではまだまだシェアの低いVistaユーザくらいにしかわかってもらえないのがやや悲しいところですが。

スポンサード リンク

この記事のカテゴリ