Results 1 to 7 of 7

Thread: How to properly handle WM_NC* messages.

  1. #1

    Thread Starter
    Member
    Join Date
    Oct 2002
    Location
    Look out your window.
    Posts
    54

    How to properly handle WM_NC* messages.

    Hey, I've been looking for some information on working with the non-client area, but have been unsuccessful so far. I'm just trying to paint custom window frames, title bar, etc.

    For those who have knowledge in this area, where should I start when doing this? Is there certain messages I should handle before trying to paint? I'm looking for any information, or tips...

    Thanx

  2. #2
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I'm currently messing with the NC messages too. I'm now getting a grip on them, but not enough to explain, sorry.

    I catch WM_NCCALCRECT (terrible!), WM_NCPAINT, WM_NCLBTNDBLCLK and a few others.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Some sample MFC code I use:
    Code:
    void CContentFrameWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
    {
    	RECT& r = lpncsp->rgrc[0];
    	r.top += 15;
    	r.left += 1;
    	r.right -= 1;
    	r.bottom -= 1;
    
    	// ignore the bCalcValidRects parameter, client area remains valid except for now
    	// uncovered parts, but determining that is the OSs job.
    }
    
    UINT CContentFrameWnd::OnNcHitTest(CPoint point)
    {
    	CRect rect;
    	GetWindowRect(&rect);
    	point.x -= rect.left;
    	point.y -= rect.top;
    	
    	if(point.x <= 3)
    	{
    		if(point.y <= 3)
    			return HTTOPLEFT;
    		if(point.y >= rect.Height() - 3)
    			return HTBOTTOMLEFT;
    		return HTLEFT;
    	}
    	if(point.x >= rect.Width() - 3)
    	{
    		if(point.y <= 3)
    			return HTTOPRIGHT;
    		if(point.y >= rect.Height() - 3)
    			return HTBOTTOMRIGHT;
    		return HTRIGHT;
    	}
    
    	if(point.y <= 3)
    		return HTTOP;
    	if(point.y >= rect.Height() - 3)
    		return HTBOTTOM;
    
    	if(point.y < 17)
    		return HTCAPTION;
    
    	return CWnd::OnNcHitTest(point);
    }
    
    void CContentFrameWnd::OnNcPaint()
    {
    	// CWnd::OnNcPaint() shouldn't be called.
    	CRect rect;
    	GetWindowRect(&rect);
    	rect.SetRect(0, 0, rect.Width(), rect.Height());
    	const MSG *pMsg = GetCurrentMessage();
    	CDC *pDC = GetWindowDC();
    	//pDC->SelectClipRgn(CRgn::FromHandle((reinterpret_cast<HRGN>(pMsg->wParam))), RGN_AND);
    	// draw a "window"
    	pDC->DrawEdge(rect, EDGE_RAISED, BF_RECT);
    	rect.DeflateRect(1,1);
    	rect.bottom = 15;
    								// support for gradients only win98 and 2k
    	::DrawCaption(GetSafeHwnd(), pDC->GetSafeHdc(), &rect,
    #if WINVER >= 0x0500
    		DC_GRADIENT |
    #endif
    		DC_TEXT | 
    		// Topics are distinguishable from content because they are drawn with an active
    		// colored title bar. Need to find a better way as CMiniFrameWnd doesn't support this
    		// behaviour.
    		(m_bTopic ? DC_ACTIVE : 0));
    }
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Member
    Join Date
    Oct 2002
    Location
    Look out your window.
    Posts
    54
    Have you tried using GetDCEx() in your WM_NCPAINT message to get a DC with the clipping region? The SDK says to do it that way, but I have yet to get the function to succeed. I've tried getting a DC with it, but without the clipping region... and nothing. I tried using it to get a window DC, but again nothing. However, last night I tried passing DCX_CACHE along with the other parameters... and it worked. Any ideas why it would work with it and not without it?

    I got the WM_NCCALCSIZE message down... that one seemed pretty easy.

    I guess I've been trying to handle WM_NCPAINT, and I could never get DC using GetDCEx()... I just figured there was something that I was missing...

  5. #5
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I have tried it. I won't try it again. As you see I even commented out the line where I adjust the clipping region: it clipped out everything, even when the window needed updating.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  6. #6

    Thread Starter
    Member
    Join Date
    Oct 2002
    Location
    Look out your window.
    Posts
    54
    So you found that it didn't work either... hmmm... that's odd.

  7. #7
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    Is this of any help?

    http://codeguru.earthweb.com/dialog/..._caption.shtml

    It plays with the WM_NCPAINT messages successfully - although in a different context.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width