0

起動時にフルスクリーンで実行される win32 アプリケーションがあります。アプリケーションには、ポップアップ ダイアログを呼び出すボタンがいくつかあります。

ユーザーがポップアップを閉じない限り、デスクトップ全体 (ポップアップを除く) を透明な黒にする方法はありますか? 私が話しているのは、Windows 7 UAC ポップアップとそれが引き起こす背景に似ています。

フルスクリーンのウィンドウアプリで同様のことを行うことは可能ですか?

4

1 に答える 1

2

これを行うことは可能です…一種。おそらく、この効果をシミュレートできます。ユーザーは実行中の他のアプリケーションと対話できるため、実際には 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です。
したがって、これはセキュリティ機能ではありません。それは単なる視覚効果です!

また、これはばかげた視覚効果にすぎないため、ユーザーにとってイライラする可能性があります。実際に使用することはお勧めしません。しかし今、あなたはそれを行う方法を知っています。そのような力を責任を持って行使するなど。

于 2013-04-19T23:59:15.320 に答える