Pregunta

¿Alguien ha implementado la atenuación de fondo estilo Lightbox en un cuadro de diálogo modal en una aplicación MFC/no .net?
Creo que el procedimiento tendría que ser algo como:

pasos:

  1. Obtener diálogo padre HWND o CWnd*

  2. Obtenga el recto de la ventana principal y dibuje una superposición con translucidez sobre esa ventana

  3. permitir que el diálogo haga su rutina de dibujo modal, por ejemplo DoModal()

¿Existen bibliotecas/marcos para hacer esto, o cuál es la mejor manera de colocar una superposición translúcida en MFC?
editar Aquí hay una maqueta de lo que estoy tratando de lograr si no sabes lo que significa "estilo de caja de luz".
Alguna aplicación:
alt text

con un cuadro de diálogo de caja de luz
alt text

¿Fue útil?

Solución

Esto es lo que hice* según los enlaces de Brian
Primero cree un recurso de diálogo con las propiedades:

  • borde FALSO
  • mirada 3D FALSO
  • borde del cliente FALSO
  • estilo emergente
  • borde estático FALSO
  • Transparente VERDADERO
  • Barra de título FALSO

y deberías terminar con una ventana de diálogo sin marco ni nada, solo un cuadro gris.anule la función Crear para que se vea así:

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;
}

luego cree un pequeño mapa de bits negro en un editor de imágenes (digamos 48x48) e impórtelo como un recurso de mapa de bits (en este ejemplo IDB_BITMAP1)
anule el mensaje WM_ERASEBKGND con:

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;
}

Cree una instancia en el DoModal del cuadro de diálogo deseado, créelo como un cuadro de diálogo modal, es decir.en la pila (o montón si lo desea), llámelo Crear manualmente, muéstrelo y luego cree su cuadro de diálogo modal real encima:

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;
}

y esto resulta en algo exactamente como mi maqueta arriba

*Todavía hay cosas que mejorar, como hacerlo sin crear un cuadro de diálogo para empezar y algunas otras correcciones generales.

Otros consejos

Creo que sólo necesitas crear una ventana y configurar la transparencia.Hay un MFC Muestra de CglassDialog en CodeProject eso podría ayudarte.También hay un artículo sobre cómo hacer esto con las API de Win32.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top