Wednesday, September 28, 2011

Correct handling of WM_NCPAINT message in C/C++

Handling WM_NCPAINT ourselves than passing it to the default window message handler (Default() in MFC and DefWindowProc() in non-MFC application) is to enable us to paint the non-client areas of our window ourselves.

I have done a lot of googling on this matter but the results hadn’t been very helpful to me. But with a series of experimentation and trial-and-errors, I finally got this problem solved by myself.

Handling the message in MFC way

BEGIN_MESSAGE_MAP(YourClass, BaseClass)
    ON_WM_NCACTIVATE()
    ON_WM_ACTIVATE()
END_MESSAGE_MAP(YourClass)

static BOOL bActive;

BOOL YourClass::OnNcActivate(BOOL bActive)
{
    return FALSE; // always return false to enable us to paint
                  // the non-client areas of our window
}

void YourClass::OnActivate(UINT nState, CWnd* pWndOwner, BOOL bMinimized)
{
    bActive = !bMinimized;
    PaintNonClientArea();
}

void YourClass::PaintNonClientArea()
{
    if( bActive )
    {
       // do the active painting code here
       ...
       ...
    }
    else
    {
       // do the inactive painting code here
       ...
       ...
    }   
}

Handling the message in non-MFC way

LRESULT CALLBACK MyWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch( uMsg )
    {
        case WM_NCACTIVATE:
            break;
        case WM_ACTIVATE:
            bActive = wParam!=WA_INACTIVE;
            PaintNonClientArea();
            break;
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }   
    return 0;
}

No comments:

Post a Comment