2010-10-31 18 views
5

Ana pencereden oluşan ve zaman zaman kalıcı iletişim kutularını içeren oldukça standart bir MFC uygulamasına sahibim. Hepimizin bildiği gibi, kapalı olana kadar kalıcı bir iletişimin dışında hiçbir şey yapılamaz.MFC - kip iletişimini gösterirken ana pencereyi karart

Dolayısıyla güzel bir UI özelliği görsel kalıcı iletişim ile bitene kadar bunu kullanamaz belirtmek için, iletişim kutusunun arkasında ana pencerenin geri kalanını "dim" etmektir. Bazı web uygulamaları ve java/mac uygulamaları bunu yapar, ancak geleneksel C++/MFC uygulamasında bunu hiç görmedim. Platform için sıra dışı olsa bile, bir denemek istiyorum.

Bu nasıl yapılabilir?

// pMainFrame is available as a pointer to the CWnd of the main window 
CMyDialog dialog; 
dialog.DoModal(); // invoke modal dialog; returns after dialog closed 

herhangi DoModal (önce soluk pencereyi) ve daha sonra restore olması için kolay bir yol var mı: Bu desende kullanılan uygulama çeşitli modal diyaloglar var? Güncellenmiş MFC'nin yardımcı olabilecek herhangi bir özelliği olması durumunda Visual Studio 2010 kullanıyorum.

Düzenleme: Øystein en Yanıta göre bir çözüm gönderdiniz, ama üzerinde artırabilir durumda herkes bir ödül başlıyorum - özellikle/içerisinde tamamen sona ermesi pürüzsüz solgunlaşmasıyla.

+0

? İstenen davranışların ekran görüntüsünü sağlayabilir misiniz? –

+0

Bunu Google Görseller'de bulduğunuzda, sayfanın geri kalanını bir diyalog etrafında kararan bir web sayfasıdır: http://www.irritatedvowel.com/pub/blog/UsingBlurBehindDialogsinSilverlight3Beta_13306/image.png - bunun gibi bir diyalog açıkken bir uygulamanın ana penceresini karartmak. – AshleysBrain

cevap

14

Karartmak istediğiniz pencerenin üzerinde tamamen siyah başka bir pencere oluşturabilir ve siyah pencerenin opaklığını SetLayeredWindowAttributes ile ayarlayabilirsiniz. Tabii ki siyah olmak zorunda değil ama sanırım en iyi karartma rengi.

DÜZENLEME: - Ben genellikle doğrudan Windows API kullanabilirsiniz, ancak bir MFC geliştirici değilim unutmayın ben birlikte bir örnek kesmek. Yine de iyi görünüyor. Here bir macun macudur. Kendinizi solmaya vb. Eklemekten çekinmeyin. Ayrıca, tüm bu ekranı karartır, bu davranışı istemiyorsanız, karartma penceremi yeniden boyutlandırmak zorunda kalacaksınız. Kod açıklamalarına bakın.

/********************************************************************************************** 

    MFC screen dim test 
     :: oystein   :: November 2010 

    Creates a simple window - click it to toggle whether a translucent black "dimmer" window 
    is shown. The dimmer-window covers the entire screen, but the taskbar ("superbar" in 
    Windows 7) will jump on top of it if clicked - it seems. Simple suggestions to fix that 
    are welcome. 

    Should work on Windows 2000 and later. 

    Disclaimer: This is my first MFC program ever, so if anything seems wrong, it probably is. 
    I have previously only coded with pure Win32 API, and hacked this together using online 
    tutorials. Code provided "as-is" with no guarantees - I can not be held responsible for 
    anything bad that happens if you run this program. 

***********************************************************************************************/ 

#include "stdafx.h" 

#undef WINVER 
#define WINVER 0x500 // Windows 2000 & above, because of layered windows 


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
// 
//      Black window used to dim everything else 
// 
class CDimWnd : public CFrameWnd 
{    
public: 
    CDimWnd() 
    { 
     // Get screen res into rect 
     RECT rc; 
     GetDesktopWindow()->GetWindowRect(&rc); 

     CreateEx(WS_EX_LAYERED |  // Layered window for translucency 
       WS_EX_TRANSPARENT | // Click through 
       WS_EX_TOPMOST |  // Always on top 
       WS_EX_TOOLWINDOW,  // Do not appear in taskbar & similar 
       NULL, TEXT(""), 
       WS_POPUP,    // No frame/borders - though there is 
             // still some border left - we'll remove 
             // it with regions 

       0, 0, rc.right + 10, rc.bottom + 10, // Make the window 10px larger 
                 // than screen resolution in both 
                 // directions - it is still positioned 
                 // at 0,0 
       NULL, NULL); 

     // Grab a part of the window the size of the desktop - but 5px into it 
     // Because the window is larger than the desktop res, the borders are removed 
     CRgn rgn;       
     rgn.CreateRectRgn(rc.left + 5, rc.top + 5, rc.right + 5, rc.bottom + 5); 
     SetWindowRgn((HRGN)rgn, FALSE); 
     rgn.Detach();        

     // We have to reposition window - (0,0) of window has not changed 
     SetWindowPos(NULL, -5, -5, 0, 0, SWP_NOSIZE | SWP_NOZORDER);   

     // This is where we set the opacity of the window: 0-255 
     SetLayeredWindowAttributes(RGB(0,0,0), 150, LWA_ALPHA);      
    } 
    void Close() 
    { 
     CFrameWnd::OnClose(); 
    } 
    BOOL CDimWnd::OnEraseBkgnd(CDC* pDC); // Set BKG color 
    DECLARE_MESSAGE_MAP() 
}; 

BOOL CDimWnd::OnEraseBkgnd(CDC* pDC) 
{ 
    // Set brush to desired background color 
    CBrush backBrush(RGB(0, 0, 0)); 

    // Save old brush 
    CBrush* pOldBrush = pDC->SelectObject(&backBrush); 

    CRect rect; 
    pDC->GetClipBox(&rect);  // Erase the area needed 

    pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); 
    pDC->SelectObject(pOldBrush); 
    return TRUE; 
} 

BEGIN_MESSAGE_MAP(CDimWnd, CFrameWnd) 
    ON_WM_ERASEBKGND() 
END_MESSAGE_MAP() 

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 


// Global variable - is screen dimmed? 
bool g_bIsDimmed = false; 


// The main window 
class CMainWnd : public CFrameWnd 
{  
    // Contains a CDimWnd - I'm not sure if this is the "MFC way" of doing things 
    CDimWnd dimmer; 

public: 
    CMainWnd() 
    { 
     Create(NULL, TEXT("Screen dimmer - Press left mouse button on window to toggle"), 
      WS_OVERLAPPEDWINDOW, CRect(50, 50, 400, 250)); 
    } 
    // Left mouse button toggles dimming 
    afx_msg void OnLButtonDown(UINT Flags, CPoint Point) 
    { 
     if(!g_bIsDimmed) 
     { 
      dimmer.ShowWindow(SW_SHOW); 
      dimmer.BringWindowToTop();   
      g_bIsDimmed = true; 
     } 
     else 
     {   
      dimmer.ShowWindow(SW_HIDE);  
      g_bIsDimmed = false; 
     } 
    } 
    DECLARE_MESSAGE_MAP() 
}; 

BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) 
    ON_WM_LBUTTONDOWN() 
END_MESSAGE_MAP() 


// The app 
class CApp : public CWinApp 
{ 
public:   
    virtual BOOL InitInstance(); 
}; 

BOOL CApp::InitInstance() 
{    
    m_pMainWnd = new CMainWnd();    
    m_pMainWnd->ShowWindow(m_nCmdShow);   
    m_pMainWnd->UpdateWindow();   
    return TRUE; 
} 

CApp HelloApp; 


GÜNCELLEME: Ben solmasını işlemek için, sizin için birlikte biraz daha fazla kod kesmek

. Ben hala bir MFC dev değilim ve ben de yapmak için bir şey vermek için kodu "kaba" bir durumda (küçük hata işleme, çok sağlam değil) bıraktım. :) Neyse, işte bunu yapmak için tek yönlü Ben oldukça temiz düşünüyorum, var:

Kullanmak için, ana pencere Daha sonra örneğin kullanılabilir

class CMainFrm : public CFrameWnd 
{  
    CDimWnd* dimmer; 

public: 
    CMainFrm() 
    { 
     // constructor code here ... 
     dimmer = new CDimWnd();   
    } 

// rest of class ... 

}; 

kısan bir pencere ihtiva yapmak Böyle:

dimmer->Show(); 
MessageBox(TEXT("Hello world")); 
dimmer->Hide(); 

Alternatif Orada kod tutmak istiyorsanız kalıcı iletişim kutusunda, yapıcı ve yıkıcı Bu kodu ( Show()/ Hide() aramalar) koymak sanırım. Gönderdiğiniz örnekte olduğu gibi, bir "kapsam" -dim istiyorsanız, bu kod CDimWnd sınıfının kurucusu & yıkıcıya gitmek zorunda kalacaktı ve yalnızca bir dimerin olduğundan emin olmak için statik üye değişkeni gibi bir şeye ihtiyacınız olacaktır. Bir seferde çalışıyor (global değişken kullanmak istemediğiniz sürece).

CDimWnd: - sönük pencerede için

bunu yaptım.h

#define TARGET_OPACITY 70 // Target opacity 0-255 for dimmed window 
#define FADE_TIME 20  // Time between each fade step in milliseconds 
#define FADE_STEP 5  // How much to add to/remove from opacity each fade step 
#define ID_FADE_TIMER 1 

// Call Show() and Hide() to fade in/fade out dimmer. 
// Creates the dimmer window in constructor. 
class CDimWnd : public CFrameWnd 
{   
    bool m_isDimming;  

public: 
    CDimWnd(); 
    void Show(); 
    void Hide();    

protected: 
    BOOL OnEraseBkgnd(CDC* pDC); 
    void OnTimer(UINT_PTR nIDEvent); 
    DECLARE_MESSAGE_MAP() 
}; 

CDimWnd.cpp

#include "stdafx.h" 
#include "CDimWnd.h" 
#include "MainFrm.h" 

BEGIN_MESSAGE_MAP(CDimWnd, CFrameWnd) 
    ON_WM_ERASEBKGND() 
END_MESSAGE_MAP() 

CDimWnd::CDimWnd() 
{ 
    // Get the main frame of the application which we want to dim. 
    CMainFrame* pParent = theApp.pMainFrame; 

    // Don't do anything if the main frame doesn't appear to be there 
    if (pParent != NULL) 
    { 
     // Get the client area of the window to dim. 
     CRect rc; 
     pParent->GetClientRect(&rc); 
     pParent->ClientToScreen(&rc);  // convert to screen coordinates 

     // Do some fudging to fit the client area exactly. 
     // Other applications may not need this if the above client area fits already. 
     rc.top += GetSystemMetrics(SM_CYFRAME); 
     rc.top += GetSystemMetrics(SM_CYCAPTION);   // MFC feature pack seems to include caption in client area 
     rc.left -= GetSystemMetrics(SM_CXBORDER); 
     rc.right += GetSystemMetrics(SM_CXBORDER) + 1; 
     rc.bottom += GetSystemMetrics(SM_CYBORDER) + 1; 

     // Create a layered window for transparency, with no caption/border. 
     CreateEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW, NULL, TEXT(""), 
      WS_POPUP, rc.left, rc.top, rc.Width(), rc.Height(), 
      pParent->GetSafeHwnd(), NULL); 
    } 
} 


void CDimWnd::Show() 
{ 
    // If we are not already dimming, go for it 
    if(!m_isDimming) 
    { 
     // Bring in front of main window. 
     BringWindowToTop(); 

     // Set opacity to 0 
     SetLayeredWindowAttributes(RGB(0,0,0), 0, LWA_ALPHA); 

     // Show the dimmer window 
     ShowWindow(SW_SHOW); 

     // Create timer - the rest is handled in OnTimer() function 
     SetTimer(ID_FADE_TIMER, FADE_TIME, NULL); 
    } 
} 


void CDimWnd::Hide() 
{ 
    // If we are dimming, go for it 
    if(m_isDimming) 
    { 
     // Create timer - the rest is handled in OnTimer() function 
     SetTimer(ID_FADE_TIMER, FADE_TIME, NULL); 
    } 
} 


void CDimWnd::OnTimer(UINT_PTR nIDEvent) 
{ 
    static int fade = 0; 

    if(nIDEvent == ID_FADE_TIMER) 
    { 
     // We are dimming => we want to fade out 
     if(m_isDimming) 
     { 
      if(fade < 0) 
      { 
       // Fading finished - hide window completely, update status & destroy timer 
       fade = 0; 
       ShowWindow(SW_HIDE); 
       KillTimer(nIDEvent); 
       m_isDimming = false; 
      } 
      else 
      { 
       // Set window opacity & update fade counter 
       SetLayeredWindowAttributes(RGB(0,0,0), fade, LWA_ALPHA); 
       fade -= FADE_STEP; 
      } 
     } 
     else 
     // fade in 
     { 
      if(fade > TARGET_OPACITY) 
      { 
       // Fading finished - destroy timer & update status 

       fade = TARGET_OPACITY; // but first, let's be accurate. 
       SetLayeredWindowAttributes(RGB(0,0,0), fade, LWA_ALPHA); 

       KillTimer(nIDEvent); 
       m_isDimming = true;    
      } 
      else 
      { 
       // Set window opacity & update fade counter 
       SetLayeredWindowAttributes(RGB(0,0,0), fade, LWA_ALPHA); 
       fade += FADE_STEP; 
      } 
     } 
    } 
} 


BOOL CDimWnd::OnEraseBkgnd(CDC* pDC) 
{ 
    // Fill with black 
    CBrush backBrush(RGB(0, 0, 0)); 
    CBrush* pOldBrush = pDC->SelectObject(&backBrush); 

    CRect rect; 
    pDC->GetClipBox(&rect);  // Erase the area needed 
    pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); 

    pDC->SelectObject(pOldBrush); 
    return TRUE; 
} 

tamam. Söylediğim gibi, bu durum oldukça hızlı bir şekilde bir araya getirildi ve kaba bir hal aldı, ancak size çalışmak için bir kod vermeli ve MFC'de (sanırım) zamanlayıcıların nasıl kullanıldığı hakkında genel bir fikir. Bu konuda bir şey düşünmek kesinlikle doğru bir insanım değil, ama yine de :)

+0

* Genellikle Windows API'yı doğrudan kullanır * - Gösterir;) MFC'de, pencere oluşturma kurucuya girmez, ancak ayrıdır. Her neyse, bir örneği öksürmek için +1 jsut. – peterchen

+0

Aslında bu özel durum için yapıcıda ilklendirmeyi koymak yararlıdır - daha sonra bir "CDimWnd" bildiren tek bir satırın bir kapsam üzerinde karartılmasını gerektiren "kapsamlı bir pencere dimeri" vardır. – AshleysBrain

3

Oystein'ın cevabını kabul ettim, çünkü bu çözüm beni yönlendirdi, ancak değişiklikimi göndereceğimi düşündüm. Benim için çalışmasını sağlamak için biraz değiştirmem gerekiyordu, bu yüzden başka birine yararlı olabilir.

Kayıt için karartma iyi çalışıyor, ancak umduğum kadar doğal görünmüyor. Diyaloğu sıkça ortaya çıkaran bir uygulamada, karartma ana pencereyi açma ve kapama gibi görünen düzeninde dikkati dağıtır. Uzlaşmak için, aktif diyaloğu nazikçe vurgulayan oldukça ince (yaklaşık% 25 opaklık) karartma yaptım; anlık karartma hala biraz dikkat dağıtıcı, ancak özellikle scoped ne zaman yavaşça solmaya veya yavaşça kaybolur emin değilim.

Ayrıca, bir UI uzmanı değilim, ancak karartma, iletişim kutusunun arkasındaki pencere içeriğiyle daha az ilişkili olduğu izlenimini verdi. Bu, diyalogların bu içeriği doğrudan manipüle etmesine rağmen, uygulamada üzerinde çalıştığım şeyden biraz ayrıldığını hissettirdi. Bu başka bir dikkat dağıtıcı olabilir.

İşte yine geçerli:

CDimWnd.h

// Dim the application main window over a scope. Creates dimmer window in constructor. 
class CDimWnd : public CFrameWnd 
{    
public: 
    CDimWnd(); 
    BOOL OnEraseBkgnd(CDC* pDC); 

    ~CDimWnd(); 

protected: 
    DECLARE_MESSAGE_MAP() 
}; 

CDimWnd.cpp

#include "stdafx.h" 
#include "CDimWnd.h" 
#include "MainFrm.h" 

BEGIN_MESSAGE_MAP(CDimWnd, CFrameWnd) 
    ON_WM_ERASEBKGND() 
END_MESSAGE_MAP() 

// For preventing two dimmer windows ever appearing 
bool is_dimmer_active = false; 

CDimWnd::CDimWnd() 
{ 
    // Get the main frame of the application which we want to dim. 
    CMainFrame* pParent = theApp.pMainFrame; 

    // Don't do anything if the main frame doesn't appear to be there, 
    // or if there is already dimming happening. 
    if (pParent != NULL && !is_dimmer_active) 
    { 
     // Get the client area of the window to dim. 
     CRect rc; 
     pParent->GetClientRect(&rc); 
     pParent->ClientToScreen(&rc);  // convert to screen coordinates 

     // Do some fudging to fit the client area exactly. 
     // Other applications may not need this if the above client area fits already. 
     rc.top += GetSystemMetrics(SM_CYFRAME); 
     rc.top += GetSystemMetrics(SM_CYCAPTION);   // MFC feature pack seems to include caption in client area 
     rc.left -= GetSystemMetrics(SM_CXBORDER); 
     rc.right += GetSystemMetrics(SM_CXBORDER) + 1; 
     rc.bottom += GetSystemMetrics(SM_CYBORDER) + 1; 

     // Create a layered window for transparency, with no caption/border. 
     CreateEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW, NULL, TEXT(""), 
      WS_POPUP, rc.left, rc.top, rc.Width(), rc.Height(), 
      pParent->GetSafeHwnd(), NULL); 

     // Bring in front of main window. 
     BringWindowToTop(); 

     // Apply 25% opacity 
     SetLayeredWindowAttributes(RGB(0,0,0), 64, LWA_ALPHA); 

     // Show the dimmer window 
     ShowWindow(SW_SHOW); 

     is_dimmer_active = true; 
    } 
} 

CDimWnd::~CDimWnd() 
{ 
    is_dimmer_active = false; 
} 

BOOL CDimWnd::OnEraseBkgnd(CDC* pDC) 
{ 
    // Fill with black 
    CBrush backBrush(RGB(0, 0, 0)); 
    CBrush* pOldBrush = pDC->SelectObject(&backBrush); 

    CRect rect; 
    pDC->GetClipBox(&rect);  // Erase the area needed 
    pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); 

    pDC->SelectObject(pOldBrush); 
    return TRUE; 
} 

Kullanımı ölü basittir: CDimWnd onun yapıcı kendini oluşturduğundan, yapmanız gereken tek şeyDialog sınıfının bir üyesi olarakve diyaloğu nereden aradığınız önemli değil, ana pencereyi otomatik olarak kısar.

Ayrıca sistem kalıcı diyaloglar dim bir kapsamda kullanabilirsiniz:

{ 
    CDimWnd dimmer; 
    MessageBox(...); 
} 
+0

Soldurma için, yapıcıda/yıkıcıda, saydamlığı kademeli olarak artıran/azaltan bir zamanlayıcı yapabilirsiniz. Bunu yaparken ayrı bir iş parçacığı istemediğiniz sürece, solgunluk oldukça hızlı olmalıydı. – Oystein

+0

İşte bu, solgun diyalogun görünümünü geciktirmemeliydi. Modal diyalogun Aero fade-in geçişi ile aynı anda gerçekleşmesi mümkün mü? Bir kalıcı diyalog giderse bir zamanlayıcı çalışmaya devam eder mi? – AshleysBrain

+0

Son yorumu iptal et. Bir pencere zamanlayıcısı kaydederseniz, bir onay etkinliği alırsınız. Olay işleyicide solma işlemini yaparsanız, diğer iletişim kutularından bağımsız olarak kaybolur ve herhangi bir şeyin yürütülmesini geciktirmez. – Oystein

2

bunu yaparken karşı koyabilir değil.

Eklenen zamanlayıcılar içeren kodunuz ve bir soluk açma/yavaşlatma uygulanmış. Ayrıca engelleyici blok için siyah yerine orta griyi değiştirdim.

Süreyi artırarak veya hızı artırarak daha yumuşak hale getirmek için solmayı kontrol eden sabitleri ayarlayabilirsiniz. Deney 10Hz oran benim için pürüzsüz olduğunu bana gösterir, ancak soluk ne YMMV İlk başta

// DimWnd.h : header file 
#pragma once 

class CDimWnd : public CFrameWnd 
{ 
public: 
    CDimWnd(class CWnd * pParent); 
    virtual ~CDimWnd(); 
    BOOL OnEraseBkgnd(CDC* pDC); 
    int opacity, opacity_increment; 
protected: 
    DECLARE_MESSAGE_MAP() 

public: 
    afx_msg void OnTimer(UINT_PTR nIDEvent); 
    void fadeOut(); 
}; 

// DimWnd.cpp : implementation file 
// 

#include "stdafx.h" 
#include "dimmer.h" 
#include "DimWnd.h" 
#include "MainFrm.h" 
#include <math.h> 

const int TIMER_ID = 111; 

// For preventing two dimmer windows ever appearing 
bool is_dimmer_active = false; 

// constants to control the fade. 
int ticks_per_second = 1000; // ms 
int start_opacity  = 44; // 20% 
int max_opacity  = 220; // 0->255 
double fade_in_duration = 4; // seconds to fade in (appear) 
double fade_out_duration = 0.2; // seconds to fade out (disappear) 
int rate    = 100; // Timer rate (ms 


CDimWnd::CDimWnd(CWnd * pParent) 
{ 
    // Don't do anything if the main frame doesn't appear to be there, 
    // or if there is already dimming happening. 
    if (pParent != NULL && !is_dimmer_active) 
    { 
     // Get the client area of the window to dim. 
     CRect rc; 
     pParent->GetClientRect(&rc); 
     pParent->ClientToScreen(&rc);  // convert to screen coordinates 

     // Do some fudging to fit the client area exactly. 
     // Other applications may not need this if the above client area fits already. 
     rc.top += GetSystemMetrics(SM_CYFRAME); 
     rc.top += GetSystemMetrics(SM_CYCAPTION);   // MFC feature pack seems to include caption in client area 
     rc.left -= GetSystemMetrics(SM_CXBORDER); 
     rc.right += GetSystemMetrics(SM_CXBORDER) + 1; 
     rc.bottom += GetSystemMetrics(SM_CYBORDER) + 1; 

     // Create a layered window for transparency, with no caption/border. 
     CreateEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW, NULL, TEXT(""), 
      WS_POPUP, rc.left, rc.top, rc.Width(), rc.Height(), 
      pParent->GetSafeHwnd(), NULL); 

     // Bring in front of main window. 
     BringWindowToTop(); 

     // Show the dimmer window 
     ShowWindow(SW_SHOW); 


     double increment_per_second = ((max_opacity - start_opacity)/fade_in_duration); 
     opacity_increment = ceil( increment_per_second/(ticks_per_second/rate)) ; 

     is_dimmer_active = true; 
     opacity = start_opacity; 

     SetLayeredWindowAttributes(RGB(0,0,0), opacity, LWA_ALPHA); 

     SetTimer(TIMER_ID, rate,NULL); 

    } 
} 

CDimWnd::~CDimWnd() 
{ 
    fadeOut(); // fade the window out rather than just disappearing. 
    is_dimmer_active = false; 
} 

void CDimWnd::fadeOut() 
{ 
    // can't use timers as may be in the process of being destroyed so make it quick.. 

    double increment_per_second = ((opacity - start_opacity)/fade_out_duration); 
    opacity_increment = ceil( increment_per_second/(ticks_per_second/rate)) ; 

    while(opacity > start_opacity) 
    { 
     opacity -= opacity_increment; 
     SetLayeredWindowAttributes(RGB(0,0,0), opacity, LWA_ALPHA); 
     Sleep(100); 
    } 
} 

BOOL CDimWnd::OnEraseBkgnd(CDC* pDC) 
{ 
    // Fill with midgray 
    CBrush backBrush(RGB(128,128,128)); 
    CBrush* pOldBrush = pDC->SelectObject(&backBrush); 

    CRect rect; 
    pDC->GetClipBox(&rect);  // Erase the area needed 
    pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY); 

    pDC->SelectObject(pOldBrush); 
    return TRUE; 
} 

BEGIN_MESSAGE_MAP(CDimWnd, CFrameWnd) 
    ON_WM_ERASEBKGND() 
    ON_WM_TIMER() 
END_MESSAGE_MAP() 

void CDimWnd::OnTimer(UINT_PTR nIDEvent) 
{ 
    if (opacity >= max_opacity) 
    { 
     // stop the timer when fade in finished. 
     KillTimer(TIMER_ID); 
     return; 
    } 

    opacity += opacity_increment; 
    SetLayeredWindowAttributes(RGB(0,0,0), opacity, LWA_ALPHA); 

    CFrameWnd::OnTimer(nIDEvent); 
} 
+0

bulabildiğim durumda ben bir örnekle benim cevap güncellenen – Oystein

İlgili konular