MFC アプリのライトボックス スタイル ダイアログ
-
09-06-2019 - |
質問
MFC/非 .net アプリのモーダル ダイアログ ボックスにライトボックス スタイルの背景の調光を実装した人はいますか。
手順は次のようなものになると思います。
手順:
ダイアログの親 HWND または CWnd を取得*
親ウィンドウの四角形を取得し、そのウィンドウ上に半透明のオーバーレイを描画します。
- ダイアログがモーダル描画ルーチンを実行できるようにします (DoModal() など)。
これを行うための既存のライブラリ/フレームワークはありますか、または MFC で半透明のオーバーレイをドロップする最良の方法は何ですか?
編集 「ライトボックス スタイル」の意味がわからない場合は、これが私が達成しようとしていることのモックアップです。
いくつかのアプリ:
ライトボックスダイアログボックスあり
解決
ブライアンのリンクに基づいて私がやったことは次のとおりです*
まず、次のプロパティを使用してダイアログ リソースを作成します。
- 国境 間違い
- 3D の外観 間違い
- クライアントエッジ 間違い
- ポップアップスタイル
- 静的エッジ 間違い
- 透明 真実
- タイトルバー 間違い
すると、フレームも何もなく、ただ灰色のボックスだけが表示されたダイアログ ウィンドウが表示されるはずです。Create 関数を次のようにオーバーライドします。
BOOL LightBoxDlg::Create(UINT nIDTemplate, CWnd* pParentWnd)
{
if(!CDialog::Create(nIDTemplate, pParentWnd))
return false;
RECT rect;
RECT size;
GetParent()->GetWindowRect(&rect);
size.top = 0;
size.left = 0;
size.right = rect.right - rect.left;
size.bottom = rect.bottom - rect.top;
SetWindowPos(m_pParentWnd,rect.left,rect.top,size.right,size.bottom,NULL);
HWND hWnd=m_hWnd;
SetWindowLong (hWnd , GWL_EXSTYLE ,GetWindowLong (hWnd , GWL_EXSTYLE ) | WS_EX_LAYERED ) ;
typedef DWORD (WINAPI *PSLWA)(HWND, DWORD, BYTE, DWORD);
PSLWA pSetLayeredWindowAttributes;
HMODULE hDLL = LoadLibrary (_T("user32"));
pSetLayeredWindowAttributes =
(PSLWA) GetProcAddress(hDLL,"SetLayeredWindowAttributes");
if (pSetLayeredWindowAttributes != NULL)
{
/*
* Second parameter RGB(255,255,255) sets the colorkey
* to white LWA_COLORKEY flag indicates that color key
* is valid LWA_ALPHA indicates that ALphablend parameter
* is valid - here 100 is used
*/
pSetLayeredWindowAttributes (hWnd,
RGB(255,255,255), 100, LWA_COLORKEY|LWA_ALPHA);
}
return true;
}
次に、イメージ エディタで小さな黒いビットマップ (たとえば 48x48) を作成し、それをビットマップ リソース (この例では IDB_BITMAP1) としてインポートします。
WM_ERASEBKGND メッセージを次のようにオーバーライドします。
BOOL LightBoxDlg::OnEraseBkgnd(CDC* pDC)
{
BOOL bRet = CDialog::OnEraseBkgnd(pDC);
RECT rect;
RECT size;
m_pParentWnd->GetWindowRect(&rect);
size.top = 0;
size.left = 0;
size.right = rect.right - rect.left;
size.bottom = rect.bottom - rect.top;
CBitmap cbmp;
cbmp.LoadBitmapW(IDB_BITMAP1);
BITMAP bmp;
cbmp.GetBitmap(&bmp);
CDC memDc;
memDc.CreateCompatibleDC(pDC);
memDc.SelectObject(&cbmp);
pDC->StretchBlt(0,0,size.right,size.bottom,&memDc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
return bRet;
}
目的のダイアログの DoModal でインスタンス化します。モーダル ダイアログのように作成します。スタック (または必要に応じてヒープ) 上で、手動で Create を呼び出して表示し、その上に実際のモーダル ダイアログを作成します。
INT_PTR CAboutDlg::DoModal()
{
LightBoxDlg Dlg(m_pParentWnd);//make sure to pass in the parent of the new dialog
Dlg.Create(LightBoxDlg::IDD);
Dlg.ShowWindow(SW_SHOW);
BOOL ret = CDialog::DoModal();
Dlg.ShowWindow(SW_HIDE);
return ret;
}
そしてこれは何かをもたらします その通り 上の私のモックアップのように
*最初からダイアログ ボックスを作成せずに実行したり、その他の一般的な整理を行うなど、改善の余地はまだあります。
他のヒント
ウィンドウを作成して透明度を設定するだけだと思います。MFCもあるよ CodeProject の CGlassDialog サンプル それはあなたを助けるかもしれません。もあります。 記事 Win32 API を使用してこれを行う方法について説明します。