起動時にフルスクリーンで実行される win32 アプリケーションがあります。アプリケーションには、ポップアップ ダイアログを呼び出すボタンがいくつかあります。
ユーザーがポップアップを閉じない限り、デスクトップ全体 (ポップアップを除く) を透明な黒にする方法はありますか? 私が話しているのは、Windows 7 UAC ポップアップとそれが引き起こす背景に似ています。
フルスクリーンのウィンドウアプリで同様のことを行うことは可能ですか?
これを行うことは可能です…一種。おそらく、この効果をシミュレートできます。ユーザーは実行中の他のアプリケーションと対話できるため、実際には UAC ダイアログとは異なります。アプリケーションで利用できる「システム モーダル」などの概念はありません。もちろん、それは設計によるものです。ただし、デスクトップの残りの部分を暗くし、アプリのダイアログ ボックスにフォーカスを強制する "ライト ボックス" を表示することはできます。
私がそれを行う方法は、他のすべてのウィンドウの上に位置し、画面全体を覆う巨大なレイヤード ウィンドウを作成し、それを黒で塗りつぶし、必要に応じて不透明度を設定することです。次に、(MessageBox 関数を呼び出すか、DialogBox 関数を使用して独自のカスタム ダイアログの 1 つを表示することによって) モーダル ダイアログを表示する前に、ライト ボックス ウィンドウを表示します。最後に、ユーザーがモーダル ダイアログを閉じた後、ライト ボックス ウィンドウを破棄します。
ここにいくつかのサンプルコードがあります。簡潔にするために、エラー チェックは省略されています。この混乱を 1 つまたは複数のクラスにラップするなど、他の優れたスタイルも同様です。
INT_PTR ShowLightBoxedDialog(HINSTANCE hInstance,
LPCTSTR pDlgTemplate,
HWND hwndParent,
DLGPROC pDlgProc,
BYTE opacityLevel)
{
const TCHAR szLightBoxClass[] = TEXT("LightBoxWndClass");
// Register the light box window class.
static bool lightBoxRegistered = false;
if (!lightBoxRegistered)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(wcex);
wcex.style = CS_NOCLOSE | CS_SAVEBITS;
wcex.lpfnWndProc = LightBoxWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hIconSm = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szLightBoxClass;
RegisterClassEx(&wcex);
lightBoxRegistered = true;
}
// Create and display the light box window.
HWND hwndLightBox = CreateWindowEx(WS_EX_NOACTIVATE | WS_EX_LAYERED,
szLightBoxClass,
NULL,
WS_POPUPWINDOW,
0, 0, 0, 0,
hwndParent,
NULL,
hInstance,
NULL);
SetLayeredWindowAttributes(hwndLightBox, 0, opacityLevel, LWA_ALPHA);
SetWindowPos(hwndLightBox,
HWND_TOP,
GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN),
SWP_SHOWWINDOW);
// Display the modal dialog box (as you normally would).
// NOTE: The dialog box won't appear centered on the screen.
// For that, you will need to write centering code in response
// to the WM_INITDIALOG message in the dialog procedure.
INT_PTR result = DialogBox(hInstance, pDlgTemplate, hwndLightBox, pDlgProc);
//
// For demonstration purposes, I used the following code:
// INT_PTR result = MessageBox(hwndLightBox,
// TEXT("OH NOEZ!\n\nYour system is kaput! Abandon þe all hope."),
// NULL,
// MB_ABORTRETRYIGNORE | MB_ICONERROR);
// Destroy the light box window.
DestroyWindow(hwndLightBox);
// Return the result of the modal dialog box.
return result;
}
基本的に、私が行ったことはDialogBox 関数のラッパーを作成したことに気付くでしょう。これは、「ライト ボックス」効果のあるダイアログ ボックスが必要なときにいつでも使用できます。すべて同じパラメータ (最初の 4 つ) を取り、最後に「ライト ボックス」効果に使用する不透明度レベルを指定できる追加のパラメータが追加されています。150 ~ 200 の範囲がおそらく適切です。当然、何かを選んでハードコードすることもできますが、私はハードコードされた値に対する深刻なアレルギーに苦しんでいます。とにかく、この関数をどこからでも呼び出すのは非常に簡単です。
ShowLightBoxedDialog(hInstance, /* your application instance */
MAKEINTRESOURCE(IDD_SAMPLE), /* your dialog template */
hWnd, /* parent window for dialog */
SampleWndProc, /* ptr to dialog procedure */
175); /* light box opacity level */
このコードは、モーダル ダイアログが Windows で既にどのように機能するかを利用しているため、ユーザーはダイアログ ボックスを閉じるまで、アプリケーションの他の部分と対話することはできません。また、「ライト ボックス」ウィンドウは他のすべての上に配置されるため、すべてのマウス クリックが消費され、他のアプリケーションにフォーカスを設定できなくなります。Altしかし、 +のようなものを使用して回避するのは簡単Tabです。
したがって、これはセキュリティ機能ではありません。それは単なる視覚効果です!
また、これはばかげた視覚効果にすぎないため、ユーザーにとってイライラする可能性があります。実際に使用することはお勧めしません。しかし今、あなたはそれを行う方法を知っています。そのような力を責任を持って行使するなど。