MFC App中的灯箱样式对话框
时间:2020-03-05 18:50:00 来源:igfitidea点击:
是否有人在MFC / non .net应用程序的模式对话框中实现了Lightbox样式的背景变暗。
我认为程序必须是这样的:
脚步:
- 获取对话框父级HWND或者CWnd *
- 获取父窗口的矩形并在该窗口上绘制一个具有半透明性的覆盖层
- 允许对话框执行模态绘制例程,例如DoModal()
是否有任何现有的库/框架可以执行此操作,或者在MFC中删除半透明覆盖的最佳方法是什么?
编辑如果我们不知道"灯箱样式"的含义,这是我要实现的目标的模型
一些应用程序:
带有灯箱对话框
解决方案
回答
我认为我们只需要创建一个窗口并设置透明度即可。 CodeProject上有一个MFC CGlassDialog示例,它可能会对我们有所帮助。还有一篇有关如何使用Win32 API进行此操作的文章。
回答
这是我根据Brian的链接所做的*
首先使用以下属性创建对话框资源:
- 边境假
- 3D外观为FALSE
- 客户端FALSE
- 弹出式
- 静态边缘FALSE
- 透明TRUE
- 标题栏FALSE
并且我们应该最终得到一个没有框架或者任何东西的对话框窗口,只是一个灰色框。
覆盖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中实例化它,像模态对话框一样创建它,即在堆栈上(如果需要的话在堆上),将其称为手动创建,显示它,然后在其顶部创建实际的模态对话框:
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; }
这导致了与我上面的模拟完全一样的结果
*仍有改进的地方,例如不做任何对话框就开始做以及其他一些常规的整理工作。