是否有人在 MFC/非 .net 应用程序中的模式对话框上实现了 Lightbox 样式背景调暗。
我认为程序必须是这样的:

脚步:

  1. 获取对话框父级 HWND 或 CWnd*

  2. 获取父窗口的矩形并在该窗口上绘制半透明的覆盖层

  3. 允许对话框执行其模式绘制例程,例如 DoModal()

是否有任何现有的库/框架可以执行此操作,或者在 MFC 中删除半透明覆盖层的最佳方法是什么?
编辑 如果您不知道“灯箱风格”的含义,这是我想要实现的目标的模型
一些应用程序:
alt text

带有灯箱对话框
alt text

有帮助吗?

解决方案

这是我根据布莱恩的链接所做的*
首先创建一个具有以下属性的对话框资源:

  • 边界 错误的
  • 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 中实例化它,像模态对话框一样创建它,即在堆栈(或堆,如果需要)上,手动调用它的“创建”,显示它,然后在其顶部创建实际的模式对话框:

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 执行此操作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top