+ Reply to Thread
Results 1 to 16 of 16

Thread: MFC Single Document Interface... drawing?

  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....

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

    Default

    Just wanted to pop back in here and say that the Microsoft Foundation Classes must have be designed by committee, and were never actually used by the designers for programmer.

    Back to my hell now.

  8. #8
    Senior Member
    Join Date
    Sep 2004
    Location
    Netherlands
    Posts
    849

    Default

    MFC, like any framework, works fine as long as you do what the framework wants you to do, but completely breaks down if you don't want to play by the rules. I dropped MFC after I got tired of working around it.

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

    Default

    Well, my whole purpose here is to make something that conforms to what end-users might expect from a windows standard type thingamajig. You know, dialogbars and toolbars and rebars and hebars and nogbars and grommits and pushbuttons and zoids and dwips and gustavs.

    But "work around it," that's the freaking word for it. That hits the nail right on the ol' head! Only 160 lines of code to make it do something you could write, from scratch, in less than 20 lines. My fingers hurt, I'm stabbing at the keyboard so hard, typing this.

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

    Default

    Well, not to be harsh, but if your code sample above is any indication of your knowledge base with MFC you're hardly in a position to criticize it. At least not from the point of view of "lines of code required to do X". At this point you're writing at least 200% more code than you need to.

  11. #11
    Senior Member
    Join Date
    Sep 2004
    Location
    Netherlands
    Posts
    849

    Default

    Of course, MFC isn't the only framework that gives you standard-looking Windows apps. There is also wxWidgets, for example.

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

    Default

    The problem with MFC is that there is too damn much of it , no matter what you do there always seems to be a way or a function to do stuff better/quicker but because there is so much of it you just can't possibly know everything, wxWidgets is probably better for you actually as mahlzeit said as for one it's multiplatform and it mainly concentrates on the GUI rather than the other gibbens, I've been doing MFC for years, but only really just found AfxSetResourceHandle, I need a MSDN brain implant.

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

    Default

    Well, every library has it's issues. wxWidgets is very nice but you have to come to terms with their "sizers" methodology for laying out dialogs which can be downright nightmarish at times.

  14. #14
    Administrator
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,769

    Default

    Quote Originally Posted by mahlzeit
    Of course, MFC isn't the only framework that gives you standard-looking Windows apps. There is also wxWidgets, for example.
    I heard a rumor that you can even use the Windows API to make standard-looking Windows apps. You don’t need to use MFC or any other framework or library.
    James C. Smith - Producer/Lead Programmer - Costume Chaos, Build in Time, Ricochet Infinity, Big Kahuna Reef, CasualCharts.com

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

    Default

    I heard a rumor that you can even use the Windows API to make standard-looking Windows apps. You don’t need to use MFC or any other framework or library.
    Depending on your personal feelings on masochism and level of self loathing, yes, that is a possibility.

    The Win32 API is a possibility but damn, get ready for some pain.

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

    Default

    Quote Originally Posted by Savant
    The Win32 API is a possibility but damn, get ready for some pain.
    It's not that bad. MFC was made to make your lives easier when it came to Windows programming.

    I've always found that stuff i wanted to do in MFC can be done with the standard windows api quite easily(in fact i prefer it). You might end up writing convoluted code like the mfc framework to get it to work correctly though.

    Fact of the matter is, what Raptisoft is trying to do is simple. I guess the problem is a little error somewhere or he need to call 'InvalidateRect' on his window for it to update.

    C# is a joy, but linking it to c++ dll's can be a bit tricky if you're not sure what you're doing.

+ 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