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. General Programming
  3. C / C++ / MFC
  4. Simple GDI Problem

Simple GDI Problem

Scheduled Pinned Locked Moved C / C++ / MFC
tutorialgraphicsdebugginghelpquestion
5 Posts 3 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.
  • L Offline
    L Offline
    LighthouseJ
    wrote on last edited by
    #1

    I have an SDI application, and I'm operating in the OnPaint handler for WM_PAINT messages in my CChildView derived from CWnd. In the CChildView class, I have 2 pointers to class objects I made derived from CObList which are initialized to NULL when the view is constructed. When I open the file, data is read in and one or both lists may be filled with items. Here is some example code: void CChildView::OnPaint() {   CPaintDC dc(this); // device context for paintingif (files != NULL) {   if (files != NULL {     char * lpszText = new char[32];     sprintf (lpszText, "Files: %u", files->GetCount());     int nTextHeight = dc.DrawText(lpszText, -1, CRect(10, 30, 100, 100), DT_LEFT | DT_SINGLELINE);     MessageBox(_T("files detected"), NULL, MB_OK);     delete[] lpszText;   } else { dc.DrawText(_T("Files: 0"), CRect(10, 30, 100, 100), DT_LEFT); } } Now, what happens is when I start the app, I am told there are no files which is right. When I open the file, the code runs through and I see the MessageBox displayed but the text that should have been drawn in the line above it doesn't show up on the screen. However, if I were to put a breakpoint on the sprintf line, start the program, load a file, it would break on the line and I were to press F5 to continue executing, the result of DrawText would show up on the screen fine and the message box would pop up too. I've tried to see if I'm doing something wrong or if I'm not doing something I should here and on other GDI tutorial sites but I can't figure out why this behavior exists. Can someone please set me straight?

    A J 2 Replies Last reply
    0
    • L LighthouseJ

      I have an SDI application, and I'm operating in the OnPaint handler for WM_PAINT messages in my CChildView derived from CWnd. In the CChildView class, I have 2 pointers to class objects I made derived from CObList which are initialized to NULL when the view is constructed. When I open the file, data is read in and one or both lists may be filled with items. Here is some example code: void CChildView::OnPaint() {   CPaintDC dc(this); // device context for paintingif (files != NULL) {   if (files != NULL {     char * lpszText = new char[32];     sprintf (lpszText, "Files: %u", files->GetCount());     int nTextHeight = dc.DrawText(lpszText, -1, CRect(10, 30, 100, 100), DT_LEFT | DT_SINGLELINE);     MessageBox(_T("files detected"), NULL, MB_OK);     delete[] lpszText;   } else { dc.DrawText(_T("Files: 0"), CRect(10, 30, 100, 100), DT_LEFT); } } Now, what happens is when I start the app, I am told there are no files which is right. When I open the file, the code runs through and I see the MessageBox displayed but the text that should have been drawn in the line above it doesn't show up on the screen. However, if I were to put a breakpoint on the sprintf line, start the program, load a file, it would break on the line and I were to press F5 to continue executing, the result of DrawText would show up on the screen fine and the message box would pop up too. I've tried to see if I'm doing something wrong or if I'm not doing something I should here and on other GDI tutorial sites but I can't figure out why this behavior exists. Can someone please set me straight?

      A Offline
      A Offline
      Anton Mikhalyov
      wrote on last edited by
      #2

      If you need solution of problem, use CDC* pDC = GetDC(); instead of CPaintDC dc(this);

      L 1 Reply Last reply
      0
      • L LighthouseJ

        I have an SDI application, and I'm operating in the OnPaint handler for WM_PAINT messages in my CChildView derived from CWnd. In the CChildView class, I have 2 pointers to class objects I made derived from CObList which are initialized to NULL when the view is constructed. When I open the file, data is read in and one or both lists may be filled with items. Here is some example code: void CChildView::OnPaint() {   CPaintDC dc(this); // device context for paintingif (files != NULL) {   if (files != NULL {     char * lpszText = new char[32];     sprintf (lpszText, "Files: %u", files->GetCount());     int nTextHeight = dc.DrawText(lpszText, -1, CRect(10, 30, 100, 100), DT_LEFT | DT_SINGLELINE);     MessageBox(_T("files detected"), NULL, MB_OK);     delete[] lpszText;   } else { dc.DrawText(_T("Files: 0"), CRect(10, 30, 100, 100), DT_LEFT); } } Now, what happens is when I start the app, I am told there are no files which is right. When I open the file, the code runs through and I see the MessageBox displayed but the text that should have been drawn in the line above it doesn't show up on the screen. However, if I were to put a breakpoint on the sprintf line, start the program, load a file, it would break on the line and I were to press F5 to continue executing, the result of DrawText would show up on the screen fine and the message box would pop up too. I've tried to see if I'm doing something wrong or if I'm not doing something I should here and on other GDI tutorial sites but I can't figure out why this behavior exists. Can someone please set me straight?

        J Offline
        J Offline
        Jose Lamas Rios
        wrote on last edited by
        #3

        The problem is that the area in which you are drawing is not 'invalidated'. Breaking into the debugger has the side-effect of invalidating the entire window and that's why it works fine after that. Whenever you change the info, which by the way should be in your document instead of your view, you need to make the view invalidate the area that needs to be updated. Take a look at this post[^] for more details on how to orchestrate the interaction between the document and its views. Also, instead of this:

        char * lpszText = new char[32];
          sprintf (lpszText, "Files: %u", files->GetCount());
          int nTextHeight = dc.DrawText(lpszText, [...] );
          delete[] lpszText;

        I suggest this:

        CString sText;
          sText.Format("Files: %u", files->GetCount());
          int nTextHeight = dc.DrawText(sText, [...] );

        It's cleaner, you don't need to worry about how much space to allocate, and you don't risk forgetting to free it. -- jlr http://jlamas.blogspot.com/[^]

        L 1 Reply Last reply
        0
        • A Anton Mikhalyov

          If you need solution of problem, use CDC* pDC = GetDC(); instead of CPaintDC dc(this);

          L Offline
          L Offline
          LighthouseJ
          wrote on last edited by
          #4

          I was reading about GDI and I believe that's the old way and I figured using CPaintDC was used for a reason. I'll check it out, thanks for the tip.

          1 Reply Last reply
          0
          • J Jose Lamas Rios

            The problem is that the area in which you are drawing is not 'invalidated'. Breaking into the debugger has the side-effect of invalidating the entire window and that's why it works fine after that. Whenever you change the info, which by the way should be in your document instead of your view, you need to make the view invalidate the area that needs to be updated. Take a look at this post[^] for more details on how to orchestrate the interaction between the document and its views. Also, instead of this:

            char * lpszText = new char[32];
              sprintf (lpszText, "Files: %u", files->GetCount());
              int nTextHeight = dc.DrawText(lpszText, [...] );
              delete[] lpszText;

            I suggest this:

            CString sText;
              sText.Format("Files: %u", files->GetCount());
              int nTextHeight = dc.DrawText(sText, [...] );

            It's cleaner, you don't need to worry about how much space to allocate, and you don't risk forgetting to free it. -- jlr http://jlamas.blogspot.com/[^]

            L Offline
            L Offline
            LighthouseJ
            wrote on last edited by
            #5

            I think I was doing the second way but I must have changed to C-Style strings for some reason, I don't know. I'm using CString's practically everywhere else. I'll take some time and read that link, thanks a lot. edit: I just invalidated the view when the data is changed and it worked like a charm, many thanks. Practically that entire post was very informative, good call.

            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