2008-09-09 7 views
4

Hat jemand implementiert Lightbox-Stil Hintergrund Dimmen auf einem modalen Dialogfeld in einer MFC/nicht .net App.
Ich denke, das Verfahren so etwas wie sein müßte:Lightbox-Stil-Dialoge in MFC-App

Schritte:

  1. Get Dialog Eltern HWND oder CWnd *

  2. die rect des übergeordneten Fensters holen und ein Overlay ziehen mit eine Lichtdurchlässigkeit über das Fenster

  3. der Dialog es modales Zeichenprogramm, zB DoModal()
zu erlauben

Gibt es vorhandene Bibliotheken/Frameworks, um dies zu tun, oder was ist der beste Weg, um ein transparentes Overlay in MFC zu löschen?
bearbeiten Hier ist ein Mock-up von dem, was ich versuche, wenn Sie nicht wissen, zu erreichen, was Leuchtkasten Stil "bedeutet
Einige App:
alt text

mit einem Leuchtkasten Dialogfeld
alt text

Antwort

4

Hier ist, was ich Links auf Brians * habe basierend
zunächst eine Dialogressource mit den Eigenschaften erstellen:

  • Grenze FALSCH
  • 3D schauen FALSCH
  • Client Rand FALSCH
  • Popup-Stil
  • statischer Rand FALSCH
  • Transparent TRUE
  • Titelleiste FALSCH

und Sie sollten mit einem Dialogfenster ohne Rahmen oder irgendetwas, nur ein graues Feld landen. überschreiben Sie die Funktion Anlegen wie folgt aussehen:

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

dann eine kleine schwarze Bitmap in einem Bildbearbeitungsprogramm (zB 48x48) und importieren Sie es als eine Bitmap-Ressource (in diesem Beispiel IDB_BITMAP1)
Überschreibung der WM_ERASEBKGND Nachricht erstellen mit:

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

instanziieren im DoModal des gewünschten Dialog erstellen wie ein modales Dialog dhauf dem Stapel (oder Heap, wenn gewünscht), nennt es manuell anlegen, zeigen Sie sie dann Dialog über die Oberseite der es tatsächlich modalen erstellen:

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

und dies führt zu etwas genau wie mein Mock-up über

* Es gibt immer noch Orte für Verbesserungen, wie es zu tun, ohne ein Dialogfeld zu erstellen und einige andere allgemeine Aufräumarbeiten.

2

Ich denke, Sie müssen nur ein Fenster erstellen und die Transparenz festlegen. Es gibt eine MFC CGlassDialog sample on CodeProject, die Ihnen helfen könnte. Es gibt auch eine article wie man das mit den Win32 APIs macht.

+0

das sieht aus wie ich suche. Ich probiere es aus und melde mich zurück :) – geocoin