Domanda

Qualcuno ha implementato l'oscuramento dello sfondo in stile Lightbox su una finestra di dialogo modale in un'app MFC/non .net.
Penso che la procedura dovrebbe essere qualcosa del tipo:

passaggi:

  1. Ottieni la finestra di dialogo genitore HWND o CWnd*

  2. Ottieni il rettangolo della finestra principale e disegna una sovrapposizione con una traslucenza su quella finestra

  3. consentire alla finestra di dialogo di eseguire la routine di disegno modale, ad esempio DoModal()

Esistono librerie/framework esistenti per eseguire questa operazione o qual è il modo migliore per rilasciare una sovrapposizione traslucida in MFC?
modificare Ecco un modello di ciò che sto cercando di ottenere se non sai cosa significa "stile lightbox"
Alcune app:
alt text

con una finestra di dialogo lightbox
alt text

È stato utile?

Soluzione

Ecco cosa ho fatto* basandomi sui link di Brian
Per prima cosa crea una risorsa di dialogo con le proprietà:

  • confine FALSO
  • Aspetto 3D FALSO
  • bordo del cliente FALSO
  • Stile popup
  • bordo statico FALSO
  • Trasparente VERO
  • Barra del titolo FALSO

e dovresti ritrovarti con una finestra di dialogo senza cornice o altro, solo una casella grigia.sovrascrivi la funzione Crea per assomigliare a questa:

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

quindi crea una piccola bitmap nera in un editor di immagini (diciamo 48x48) e importala come risorsa bitmap (in questo esempio IDB_BITMAP1)
sovrascrivere il messaggio 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;
}

Creane un'istanza nel DoModal della finestra di dialogo desiderata, creala come una finestra di dialogo modale, ad es.sullo stack (o sull'heap se lo desideri), chiamalo Crea manualmente, mostralo quindi crea la tua finestra di dialogo modale effettiva sopra di essa:

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 questo si traduce in qualcosa esattamente come il mio mock sopra

*ci sono ancora margini di miglioramento, come farlo senza creare una finestra di dialogo per cominciare e qualche altro aggiustamento generale.

Altri suggerimenti

Penso che devi solo creare una finestra e impostare la trasparenza.C'è un MFC Esempio CGlassDialog su CodeProject questo potrebbe aiutarti.C'è anche un articolo su come eseguire questa operazione con le API Win32.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top