Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. What I really wanted in vc.net

What I really wanted in vc.net

Scheduled Pinned Locked Moved The Lounge
csharpc++graphicsjsonquestion
30 Posts 9 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Mark Lenz

    I have been using SaveDC() before I create any new GDI objects and then RestoreDC() when I'm done with them. Example: void DumbControl::OnPaint() { CPaintDC dc(this); int saveDC = dc.SaveDC(); CBrush brush; /*....using GDI object....*/ dc.RestoreDC(saveDC); } I make function calls within the OnPaint() method who take a pointer to the DC and then use GDI objects created within their scope, but those functions don't make a call to SaveDC(). Do I need to call SaveDC() in those functions as well, or am I missing something else? Thanks. Mark Lenz

    T Offline
    T Offline
    Tim Lesher
    wrote on last edited by
    #21

    I make function calls within the OnPaint() method who take a pointer to the DC and then use GDI objects created within their scope, but those functions don't make a call to SaveDC(). That's probably your problem. The path of execution looks like this: 1. Acquire DC 2. Save DC context 3. Call function 4. (in function) create resource 5. (in function) select resource into DC 6. (function returning) delete resource 7. Restore DC context Notice that you're still destroying the objects while they're still selected into the DC. The objects are probably what are leaking. Tim Lesher http://www.lesher.ws

    B M 3 Replies Last reply
    0
    • M Mark Lenz

      Another thing I noticed. It happens in Windows 98, but not in Windows 2000. Mark Lenz

      T Offline
      T Offline
      Tim Lesher
      wrote on last edited by
      #22

      Makes sense--under NT, device contexts aren't allocated in a small heap, as they are under Win 9x. Tim Lesher http://www.lesher.ws

      1 Reply Last reply
      0
      • T Tim Lesher

        I make function calls within the OnPaint() method who take a pointer to the DC and then use GDI objects created within their scope, but those functions don't make a call to SaveDC(). That's probably your problem. The path of execution looks like this: 1. Acquire DC 2. Save DC context 3. Call function 4. (in function) create resource 5. (in function) select resource into DC 6. (function returning) delete resource 7. Restore DC context Notice that you're still destroying the objects while they're still selected into the DC. The objects are probably what are leaking. Tim Lesher http://www.lesher.ws

        B Offline
        B Offline
        Bernhard
        wrote on last edited by
        #23

        hi... i've read your explanations, but there are still some things i don't get.. my normal drawing routine looks something like:

        void CView::OnDraw(CDC *pDC)
        {
        CObjectList::iterator i;

        for (i = m\_ObjList.begin(); i != m\_ObjList.end(); i++)
        	(\*i)->Draw(pDC);
        

        }

        //this is one of the objects i am drawing
        void CDrawObject::Draw(CDC *pDC)
        {
        int i_save = pDC->SaveDC()

        pDC->SelectObject (&cp\_dashdot);
        pDC->SelectObject (&cf\_arial20);
        
            pDC->Rectangle (0, 0, 100, 100);
        
        //Aufräumen
        pDC->RestoreDC (i\_save);
        

        }

        i really like to make the pens and fonts member of the base class of all draw objects.. cause they all use the same font - and pen - settings and then select em into the device contexts.. my problem now is WHEN should i do the things you've told me to. (cause i found out that i am leaking resources.. when drawing more than 1000 objects or so (when printing out.. more than 6 pages,i got the standard font on WIN NT) and if this is a good idea to make this in a base class.. and what would be other ways to share the same font / pen - settings for all objects.. thanks in advance bernhard


        Sometimes I think the surest sign for intelligent life elsewhere in the universe is that none of them ever tried to contact us.

        T 1 Reply Last reply
        0
        • B Bernhard

          hi... i've read your explanations, but there are still some things i don't get.. my normal drawing routine looks something like:

          void CView::OnDraw(CDC *pDC)
          {
          CObjectList::iterator i;

          for (i = m\_ObjList.begin(); i != m\_ObjList.end(); i++)
          	(\*i)->Draw(pDC);
          

          }

          //this is one of the objects i am drawing
          void CDrawObject::Draw(CDC *pDC)
          {
          int i_save = pDC->SaveDC()

          pDC->SelectObject (&cp\_dashdot);
          pDC->SelectObject (&cf\_arial20);
          
              pDC->Rectangle (0, 0, 100, 100);
          
          //Aufräumen
          pDC->RestoreDC (i\_save);
          

          }

          i really like to make the pens and fonts member of the base class of all draw objects.. cause they all use the same font - and pen - settings and then select em into the device contexts.. my problem now is WHEN should i do the things you've told me to. (cause i found out that i am leaking resources.. when drawing more than 1000 objects or so (when printing out.. more than 6 pages,i got the standard font on WIN NT) and if this is a good idea to make this in a base class.. and what would be other ways to share the same font / pen - settings for all objects.. thanks in advance bernhard


          Sometimes I think the surest sign for intelligent life elsewhere in the universe is that none of them ever tried to contact us.

          T Offline
          T Offline
          Tim Lesher
          wrote on last edited by
          #24

          Hmm... if this is all you're doing, I don't see the leak. As long as your objects get selected back out of the DC (which RestoreDC() should be doing), you should be in good shape. Are you sure there aren't any other places where you're leaking? Is it possible that you're destroying CDrawObjects, but not destroying some CGI objects they contain? Tim Lesher http://www.lesher.ws

          B 1 Reply Last reply
          0
          • T Tim Lesher

            Hmm... if this is all you're doing, I don't see the leak. As long as your objects get selected back out of the DC (which RestoreDC() should be doing), you should be in good shape. Are you sure there aren't any other places where you're leaking? Is it possible that you're destroying CDrawObjects, but not destroying some CGI objects they contain? Tim Lesher http://www.lesher.ws

            B Offline
            B Offline
            Bernhard
            wrote on last edited by
            #25

            well.. i was inspecting my code once again.. and there i saw the problem (at least i guess it was the problem):

            CRepDrawFont::CRepDrawFont()
            {
            try
            {
            cf_std[0].CreateFont (...);
            cf_std[1].CreateFont (...);
            cf_std[2].CreateFont (...);
            cf_std[3].CreateFont (...);
            cp_solid.CreatePen (...);
            }
            catch (CResourceException e)
            {
            TCHAR sz_message [256];
            e.GetErrorMessage (sz_message, 256);
            TRACE (sz_message);
            }
            }

            CRepDrawFont::~CRepDrawFont()
            {
            //Added later and now the problem is gone
            cf_std[0].DeleteObject();
            cf_std[1].DeleteObject();
            cf_std[2].DeleteObject();
            cf_std[3].DeleteObject();
            }

            maybe the problem was the array of cfonts.. which cause that the destructor of cfont was never beeing called (?) and so it leaked resources as hell.. and because i made CRepDrawFont a base class of every draw object the whole shista leaked as hell.. well.. thank you for your kind answers.. (i just wanted to know for sure, that my way of painting is not bad in general, cause 50% of my work are grounded on this) bernhard


            Sometimes I think the surest sign for intelligent life elsewhere in the universe is that none of them ever tried to contact us.

            1 Reply Last reply
            0
            • T Todd Smith

              Or use GDI+ which is an object oriented toolkit for GDI by MS.

              Todd Smith

              B Offline
              B Offline
              Bernhard
              wrote on last edited by
              #26

              Todd Smith wrote: Or use GDI+ which is an object oriented toolkit for GDI by MS question: if i use mfc i get dc's to paint all over.. can i paint on a dc with gdi+ ? (if that would work it would really be a possibility cause i've read some docs and it sounds great) thanks in advance bernhard


              Sometimes I think the surest sign for intelligent life elsewhere in the universe is that none of them ever tried to contact us.

              1 Reply Last reply
              0
              • T Tim Lesher

                I make function calls within the OnPaint() method who take a pointer to the DC and then use GDI objects created within their scope, but those functions don't make a call to SaveDC(). That's probably your problem. The path of execution looks like this: 1. Acquire DC 2. Save DC context 3. Call function 4. (in function) create resource 5. (in function) select resource into DC 6. (function returning) delete resource 7. Restore DC context Notice that you're still destroying the objects while they're still selected into the DC. The objects are probably what are leaking. Tim Lesher http://www.lesher.ws

                M Offline
                M Offline
                Mark Lenz
                wrote on last edited by
                #27

                I changed my code so that it saves the DC at the beginning and end of the OnPaint() method and the beginning and end of every function called inside OnPaint() that takes a pointer to the DC. I'm still seeing the same thing. Is there another kind of resource leak that could cause this, or does saving and restoring the DC not work quite right? Thanks for all of your help. This problem has become quite frustrating. Mark Lenz

                1 Reply Last reply
                0
                • T Tim Lesher

                  I make function calls within the OnPaint() method who take a pointer to the DC and then use GDI objects created within their scope, but those functions don't make a call to SaveDC(). That's probably your problem. The path of execution looks like this: 1. Acquire DC 2. Save DC context 3. Call function 4. (in function) create resource 5. (in function) select resource into DC 6. (function returning) delete resource 7. Restore DC context Notice that you're still destroying the objects while they're still selected into the DC. The objects are probably what are leaking. Tim Lesher http://www.lesher.ws

                  M Offline
                  M Offline
                  Mark Lenz
                  wrote on last edited by
                  #28

                  Could it be that I do something like this: void ControlClass::OnPaint() { CPaintDC dc(this); int saveDC = dc.SaveDC(); Brush brushFill; brushFill.CreateSolidBrush(...); dc.SelectObject(brushFill); /*...Use brushFill...*/ brushFill.DeleteObject(); brushFill.CreateSolidBrush(...); dc.SelectObject(brushFill); /*...Use brushFill again...*/ dc.RestoreDC(saveDC); } -Mark Lenz

                  T 1 Reply Last reply
                  0
                  • M Mark Lenz

                    Could it be that I do something like this: void ControlClass::OnPaint() { CPaintDC dc(this); int saveDC = dc.SaveDC(); Brush brushFill; brushFill.CreateSolidBrush(...); dc.SelectObject(brushFill); /*...Use brushFill...*/ brushFill.DeleteObject(); brushFill.CreateSolidBrush(...); dc.SelectObject(brushFill); /*...Use brushFill again...*/ dc.RestoreDC(saveDC); } -Mark Lenz

                    T Offline
                    T Offline
                    Tim Lesher
                    wrote on last edited by
                    #29

                    Certainly! When you think you're deleting brushFill the first time, your're really not--it's still selected into the DC, so the delete will fail. Whenever you delete a GDI object, it MUST NOT be selected into a DC at the time. You're getting around the problem by doing a RestoreDC before the objects go out of scope, but the manual attempt at deletion is breaking the model. You need to select another brush into the DC before deleting the brush--either save the old brush when selecting the new one in, or select in GetStockObject(NULL_BRUSH) before deleting. You and Bernhard are actually seeing almost the same problem. It's leading me to the belief "RestoreDC Considered Harmful", because it's easy to assume that because you're saving and restoring the DC, that you don't have to think about what's selected into the DC at any given time. Hmm... maybe there's an article in that... That's a dangerous assumption, as you can see. Tim Lesher http://www.lesher.ws

                    M 1 Reply Last reply
                    0
                    • T Tim Lesher

                      Certainly! When you think you're deleting brushFill the first time, your're really not--it's still selected into the DC, so the delete will fail. Whenever you delete a GDI object, it MUST NOT be selected into a DC at the time. You're getting around the problem by doing a RestoreDC before the objects go out of scope, but the manual attempt at deletion is breaking the model. You need to select another brush into the DC before deleting the brush--either save the old brush when selecting the new one in, or select in GetStockObject(NULL_BRUSH) before deleting. You and Bernhard are actually seeing almost the same problem. It's leading me to the belief "RestoreDC Considered Harmful", because it's easy to assume that because you're saving and restoring the DC, that you don't have to think about what's selected into the DC at any given time. Hmm... maybe there's an article in that... That's a dangerous assumption, as you can see. Tim Lesher http://www.lesher.ws

                      M Offline
                      M Offline
                      Mark Lenz
                      wrote on last edited by
                      #30

                      Thank you very much. That fixed it. I had a buch of DeleteObject()'s without deselecting the object first. -Mark Lenz

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups