Pergunta

Alguém implementou o escurecimento de fundo no estilo Lightbox em uma caixa de diálogo modal em um aplicativo MFC/não .net.
Acho que o procedimento teria que ser algo como:

passos:

  1. Obtenha o pai da caixa de diálogo HWND ou CWnd*

  2. Obtenha o reto da janela pai e desenhe uma sobreposição com translucidez sobre essa janela

  3. permitir que a caixa de diálogo execute sua rotina de desenho modal, por exemplo, DoModal()

Existem bibliotecas/estruturas existentes para fazer isso ou qual é a melhor maneira de eliminar uma sobreposição translúcida no MFC?
editar Aqui está uma maquete do que estou tentando alcançar se você não sabe o que significa 'estilo lightbox'
Algum aplicativo:
alt text

com uma caixa de diálogo lightbox
alt text

Foi útil?

Solução

Aqui está o que eu fiz* com base nos links de Brian
Primeiro crie um recurso de diálogo com as propriedades:

  • fronteira FALSO
  • Aparência 3D FALSO
  • borda do cliente FALSO
  • Estilo pop-up
  • borda estática FALSO
  • Transparente verdadeiro
  • Barra de titulo FALSO

e você deve acabar com uma janela de diálogo sem moldura nem nada, apenas uma caixa cinza.substitua a função Create para ficar assim:

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

em seguida, crie um pequeno bitmap preto em um editor de imagens (digamos 48x48) e importe-o como um recurso de bitmap (neste exemplo IDB_BITMAP1)
substitua a mensagem WM_ERASEBKGND por:

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

Instancie-o no DoModal da caixa de diálogo desejada, crie-o como uma caixa de diálogo Modal, ou seja,na pilha (ou heap, se desejar), chame-o de Criar manualmente, mostre-o e crie sua caixa de diálogo modal real por cima dela:

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

e isso resulta em algo exatamente como minha simulação acima

*ainda há lugares para melhorias, como fazer isso sem criar uma caixa de diálogo para começar e algumas outras arrumações gerais.

Outras dicas

Acho que você só precisa criar uma janela e definir a transparência.Existe um MFC Amostra CGlassDialog no CodeProject isso pode ajudá-lo.Há também um artigo sobre como fazer isso com as APIs Win32.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top