+ Reply to Thread
Results 1 to 16 of 16

Thread: MFC Single Document Interface... drawing?

Hybrid View

  1. #1
    Senior Member
    Join Date
    Jul 2004
    Posts
    799

    Default MFC Single Document Interface... drawing?

    Hi all,

    I'm trying to port my code framework over to be MFC compatible so I can make editors for various programs, and for myself.

    It all works great except for this small, barely significant problem that nothing draws at all.

    Right now, I'm trying to just draw a black rectangle using GDI in the document window, so I've got this cool code:

    Code:
    void CEditorView::OnDraw(CDC* /*pDC*/)
    {
    	CEditorDoc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    
    	CPaintDC dc(this); // device context for painting
    	PAINTSTRUCT aPaint;
    	BeginPaint(&aPaint);
    
    	CBrush aBrush;
    	aBrush.CreateSolidBrush(COLORREF(RGB(0,0,0)));
    
    	CRect aRect;
    	aRect.left=0;
    	aRect.top=0;
    	aRect.right=100;
    	aRect.bottom=100;
    	dc.FillRect(&aRect,&aBrush);
    
    	EndPaint(&aPaint);
    
    
    	// TODO: add draw code for native data here
    }
    Pretty straightforward, I thought, except for the cuteness of taking 60 lines to draw a simple rectangle in GDI. Anyway... no black rectangle! C'mon, this should be pretty easy, right? In the OnDraw, I do a BeginPaint, get the DC and fill a rect.

    At random I've also:

    o Removed the BeginPaint/EndPaint commands
    o Tried using the base FillRect and passing it a pointer to the DC
    o Moved everything into OnPaint instead of OnDraw

    And I always get a nice white clean document with nothing in it whatsoever.

    Are any of you man enough to tell me what I'm doing wrong?

    Thanks a skillion!

  2. #2

    Default

    Bit rusty on MFC now, but I worked on an MFC based game editor for several months so I can share some tips:

    The OnDraw will only get triggered if you 'invalidate' the window contents. For example, to trigger OnDraw on opening the window, try adding Invalidate(FALSE) in the OnInitialUpdate(..) event method. The FALSE parameter tells Windows not to erase the window contents, assuming that you're doing the clearing yourself.. otherwise, use TRUE. Other calls to Invalidate should occur whenever the contents of your window need to be drawn. If you're abstracting your graphics calls in a generic API, a FlipScreen(..) function or similar would be a good place to place your Invalidate call. If you have real-time animations, you might want to consider implementing window's OnTimer method to call Invalidate and enable the timer via the window's SetTimer method.

    Hope that helps.
    Last edited by Sharkbait; 09-05-2005 at 11:17 AM. Reason: typos

  3. #3
    Senior Member
    Join Date
    Feb 2005
    Posts
    1,667

    Default

    If memory serves, you should be able to reduce that to something like:

    Code:
    	CEditorDoc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    
    	CPaintDC dc(this); // device context for painting
    
    	CBrush aBrush( RGB(0,0,0) );
    
    	CRect aRect(0,0,100,100);
    	dc.FillRect(&aRect,&aBrush);
    - The BeginPaint/EndPaint is being handled automatically by the construction/destruction of the CPaintDC.

    - Using the constructor for the CRect makes things a little cleaner.

    - RGB already returns a COLORREF, so no need to cast it.

    - Using the CBrush constructor eliminates the call to CreateSolidBrush.


    I don't know if this will fix your problem, but it might be worth a shot.

  4. #4
    Senior Member
    Join Date
    Jul 2004
    Location
    Sheffield, UK
    Posts
    694

    Default

    Code:
    void CEditorView::OnDraw(CDC* pDC)
    {
            CBrush aBrush( RGB(0,0,0) );
    	CRect aRect(0,0,100,100);
    	pDC->FillRect(&aRect,&aBrush);
    }
    You have a device context passed to OnDraw, why not use it only OnPaint needs for you to create a dc, but all code in this thread should work, find if the function is even being called is the first step, OnSize (resize window) or invalidating manually should force a call as Sharkbait said. IIRC you can get the mfc wizard to create a basic hello world app which creates a window and draws some text using a similar method.. also what is CEditorView derived from ?

  5. #5
    Senior Member
    Join Date
    Mar 2005
    Location
    England
    Posts
    531

    Default

    I think Sharkbait has hit the nail on the head. The function InvalidateRect must be called to force a redraw of the window when something changes.

    If you move the window on and off screen around the area that should have the black rectangle, it should suddenly appear.

  6. #6

    Default

    IIRC, if you are using CPaintDC you dont have to call BeginPaint() and EndPaint() anymore, because CPaintDC does BeginPaint() for you upon construction and EndPaint() upon destruction....

+ Reply to Thread

Posting Permissions

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