Диалоговые окна в стиле лайтбокса в приложении MFC
-
09-06-2019 - |
Вопрос
Кто-нибудь реализовал затемнение фона в стиле Lightbox в модальном диалоговом окне в приложении MFC/non .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;
}
и это к чему-то приводит точно как мой макет выше
*есть еще места для улучшений, например, сделать это без создания диалогового окна и некоторые другие общие настройки.
Другие советы
Я думаю, вам просто нужно создать окно и установить прозрачность.Есть МФЦ. Пример CGlassDialog в CodeProject это может вам помочь.Существует также статья о том, как это сделать с помощью API Win32.