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
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. MFC CreateCompatibleDC(), Drawtext() no display [Solved]

MFC CreateCompatibleDC(), Drawtext() no display [Solved]

Scheduled Pinned Locked Moved C / C++ / MFC
c++help
15 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.
  • C Chris Losinger

    you need to create a bitmap for your memdc to draw on. see MSDN dox for CDC::CreateCompatibleDC: http://msdn.microsoft.com/en-us/library/kwxzck32.aspx[^] from the dox:

    When a memory device context is created, GDI automatically selects a 1-by-1 monochrome stock bitmap for it. GDI output functions can be used with a memory device context only if a bitmap has been created and selected into that context.

    image processing toolkits | batch image processing

    E Offline
    E Offline
    econy
    wrote on last edited by
    #5

    Thanks, now the test string appeared. But, the client area is black, and show text string in while color only, no change. Please refer to the code:

    void CDrawTextTstDlg::OnTimer(UINT_PTR nIDEvent)
    {
    CDC *pDC;
    CRect tRect;
    CDC MemDC;

    pDC = this->GetDC();
    GetClientRect(&tRect);
    MemDC.CreateCompatibleDC(NULL);

    CBitmap bmp;
    bmp.CreateCompatibleBitmap(&MemDC, tRect.Width(), tRect.Height());
    CBitmap *oldBitmap = MemDC.SelectObject(&bmp);
    MemDC.SetBkMode(TRANSPARENT);

    if (gtest == 0 ){
    MemDC.SetTextColor(RGB(255,255,255));
    MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    MemDC.SetTextColor(RGB(255,0,0));
    MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    }
    else {
    MemDC.SetTextColor(RGB(255,255,255));
    MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    MemDC.SetTextColor(RGB(0,150,0));
    MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);

    }

    pDC->BitBlt(0, 0, tRect.Width(), tRect.Height(), &MemDC,
    0, 0, SRCCOPY);
    m_Seconds++;
    m_TimerEcho.Format(_T("%d: Seconds have passed"), m_Seconds);
    gtest ^= 1;

    MemDC.SelectObject(oldBitmap);
    bmp.DeleteObject();
    MemDC.DeleteDC();
    ReleaseDC(pDC);

    CDialog::OnTimer(nIDEvent);
    }

    C 1 Reply Last reply
    0
    • E econy

      Thanks, now the test string appeared. But, the client area is black, and show text string in while color only, no change. Please refer to the code:

      void CDrawTextTstDlg::OnTimer(UINT_PTR nIDEvent)
      {
      CDC *pDC;
      CRect tRect;
      CDC MemDC;

      pDC = this->GetDC();
      GetClientRect(&tRect);
      MemDC.CreateCompatibleDC(NULL);

      CBitmap bmp;
      bmp.CreateCompatibleBitmap(&MemDC, tRect.Width(), tRect.Height());
      CBitmap *oldBitmap = MemDC.SelectObject(&bmp);
      MemDC.SetBkMode(TRANSPARENT);

      if (gtest == 0 ){
      MemDC.SetTextColor(RGB(255,255,255));
      MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
      MemDC.SetTextColor(RGB(255,0,0));
      MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
      }
      else {
      MemDC.SetTextColor(RGB(255,255,255));
      MemDC.DrawText(_T("TEST"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
      MemDC.SetTextColor(RGB(0,150,0));
      MemDC.DrawText(_T("My Test"),&tRect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);

      }

      pDC->BitBlt(0, 0, tRect.Width(), tRect.Height(), &MemDC,
      0, 0, SRCCOPY);
      m_Seconds++;
      m_TimerEcho.Format(_T("%d: Seconds have passed"), m_Seconds);
      gtest ^= 1;

      MemDC.SelectObject(oldBitmap);
      bmp.DeleteObject();
      MemDC.DeleteDC();
      ReleaseDC(pDC);

      CDialog::OnTimer(nIDEvent);
      }

      C Offline
      C Offline
      Chris Losinger
      wrote on last edited by
      #6

      bmp.CreateCompatibleBitmap(&MemDC, tRect.Width(), tRect.Height());

      instead of MemDC there, use the DC that you used as the source for CreateCompatibleDC. when a memory DC is created, it has a 1x1 pixel monochrome bitmap selected into it. if you create a bitmap compatible with that, you'll get a monochrome bitmap. also, if you want a background color, you'll need to fill the bitmap with that color (CDC::FillSolidRect)

      image processing toolkits | batch image processing

      E 1 Reply Last reply
      0
      • C Chris Losinger

        bmp.CreateCompatibleBitmap(&MemDC, tRect.Width(), tRect.Height());

        instead of MemDC there, use the DC that you used as the source for CreateCompatibleDC. when a memory DC is created, it has a 1x1 pixel monochrome bitmap selected into it. if you create a bitmap compatible with that, you'll get a monochrome bitmap. also, if you want a background color, you'll need to fill the bitmap with that color (CDC::FillSolidRect)

        image processing toolkits | batch image processing

        E Offline
        E Offline
        econy
        wrote on last edited by
        #7

        Thank you very much. Now I can see the Text string color is changing. While, the whole dialog screen is black too, some controls, static texts all disappeared. Do I need to redraw all the controls like DrawText() ? and then BitBlt()? The original dialog screen is white.

        C 1 Reply Last reply
        0
        • E econy

          Thank you very much. Now I can see the Text string color is changing. While, the whole dialog screen is black too, some controls, static texts all disappeared. Do I need to redraw all the controls like DrawText() ? and then BitBlt()? The original dialog screen is white.

          C Offline
          C Offline
          Chris Losinger
          wrote on last edited by
          #8

          whenever i need to draw on a dialog, i put a static 'frame' control in the place where i want to draw. then i get that control's rectangle and limit my drawing to that rect.

          CRect outRect;
          m_myDrawingRectControl.GetWindowRect(outRect);
          ScreenToClient(outRect);

          also, you should only do drawing in your CDialog's OnPaint method. if you need to trigger drawing from a timer, just call CDialog::InvalidateRect() with your control's rectangle (as above). so:

          void CDynamicShowTextDlg::OnTimer(UINT nIDEvent)
          {
          CRect outRect;
          m_myDrawingRectControl.GetWindowRect(outRect);
          ScreenToClient(outRect);

          InvalidateRect(outRect);
          }

          void CDynamicShowTextDlg::OnPaint()
          {
          if (IsIconic())
          {
          ...}
          else
          {
          CRect outRect;
          m_myDrawingRectControl.GetWindowRect(outRect);
          ScreenToClient(outRect);

            CPaintDC dc(this); // device context for painting
          
            ...
          

          do your drawing here.
          use dc as the source for your CreateCompatible* stuff
          ...
          CDialog::OnPaint();
          }

          image processing toolkits | batch image processing

          E 2 Replies Last reply
          0
          • C Chris Losinger

            whenever i need to draw on a dialog, i put a static 'frame' control in the place where i want to draw. then i get that control's rectangle and limit my drawing to that rect.

            CRect outRect;
            m_myDrawingRectControl.GetWindowRect(outRect);
            ScreenToClient(outRect);

            also, you should only do drawing in your CDialog's OnPaint method. if you need to trigger drawing from a timer, just call CDialog::InvalidateRect() with your control's rectangle (as above). so:

            void CDynamicShowTextDlg::OnTimer(UINT nIDEvent)
            {
            CRect outRect;
            m_myDrawingRectControl.GetWindowRect(outRect);
            ScreenToClient(outRect);

            InvalidateRect(outRect);
            }

            void CDynamicShowTextDlg::OnPaint()
            {
            if (IsIconic())
            {
            ...}
            else
            {
            CRect outRect;
            m_myDrawingRectControl.GetWindowRect(outRect);
            ScreenToClient(outRect);

              CPaintDC dc(this); // device context for painting
            
              ...
            

            do your drawing here.
            use dc as the source for your CreateCompatible* stuff
            ...
            CDialog::OnPaint();
            }

            image processing toolkits | batch image processing

            E Offline
            E Offline
            econy
            wrote on last edited by
            #9

            Very very appreciate your help.

            1 Reply Last reply
            0
            • C Chris Losinger

              whenever i need to draw on a dialog, i put a static 'frame' control in the place where i want to draw. then i get that control's rectangle and limit my drawing to that rect.

              CRect outRect;
              m_myDrawingRectControl.GetWindowRect(outRect);
              ScreenToClient(outRect);

              also, you should only do drawing in your CDialog's OnPaint method. if you need to trigger drawing from a timer, just call CDialog::InvalidateRect() with your control's rectangle (as above). so:

              void CDynamicShowTextDlg::OnTimer(UINT nIDEvent)
              {
              CRect outRect;
              m_myDrawingRectControl.GetWindowRect(outRect);
              ScreenToClient(outRect);

              InvalidateRect(outRect);
              }

              void CDynamicShowTextDlg::OnPaint()
              {
              if (IsIconic())
              {
              ...}
              else
              {
              CRect outRect;
              m_myDrawingRectControl.GetWindowRect(outRect);
              ScreenToClient(outRect);

                CPaintDC dc(this); // device context for painting
              
                ...
              

              do your drawing here.
              use dc as the source for your CreateCompatible* stuff
              ...
              CDialog::OnPaint();
              }

              image processing toolkits | batch image processing

              E Offline
              E Offline
              econy
              wrote on last edited by
              #10

              And one more question, even I draw in Timer() function, then WM_PAINT also produced to the system,right?

              C 1 Reply Last reply
              0
              • E econy

                And one more question, even I draw in Timer() function, then WM_PAINT also produced to the system,right?

                C Offline
                C Offline
                Chris Losinger
                wrote on last edited by
                #11

                right.

                image processing toolkits | batch image processing

                E 1 Reply Last reply
                0
                • C Chris Losinger

                  right.

                  image processing toolkits | batch image processing

                  E Offline
                  E Offline
                  econy
                  wrote on last edited by
                  #12

                  Hi, I wrote snippet code to test. first, I put a Static text in the dialog box, from the resource file:

                  IDD_ECHOBUTTONEVENT_DIALOG DIALOGEX 0, 0, 320, 200
                  ...
                  BEGIN
                  ...
                  LTEXT "Static",IDC_STATIC_TXT1,89,59,98,26
                  ...
                  END

                  In Ontimer():

                  CRect outRect;
                  CStatic* pTxt1Static;
                  pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
                  pTxt1Static->GetWindowRect(&outRect);
                  ScreenToClient(&outRect);
                  InvalidateRect(&outRect);
                  UpdateData(FALSE);

                  In OnPaint():

                  if (IsIconic()) {
                  ...
                  }
                  else
                  {
                  CRect outRect;
                  CStatic* pTxt1Static;
                  pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
                  pTxt1Static->GetWindowRect(&outRect);
                  ScreenToClient(&outRect);

                  CPaintDC dc(pTxt1Static); 
                  //dc.SetTextColor(RGB(255,255,255));
                  dc.SetTextColor(RGB(255,0,0));
                  dc.SetBkMode(TRANSPARENT);
                  	
                  dc.DrawText(\_T("My Test"),&outRect,DT\_CENTER|DT\_VCENTER);
                  	
                  CDialogEx::OnPaint();
                  

                  }

                  But, the string "My Test" 's position is not at same position of Static text(IDC_STATIC_TXT1). offset I guess is about 50 to 100 pixel. And if I change CPaintDC dc(pTxt1Static) to CPaintDC dc(this), I got nothing, even I stretch the dialog box to double, triple size. If I don't use ScreenToClient(&outRect) in OnTimer(), and OnPaint(), I can see "My Test" string, but, need to stretch the dialog; I set break point, pTxt1Static->GetWindowRect(&outRect); give : tagRECT = {top=309 bottom=351 left=577 right=724} run to ScreenToClient(&outRect); give: tagRECT = {top=96 bottom=138 left=134 right=281} Could you please help me to see what is the reason?

                  C 2 Replies Last reply
                  0
                  • E econy

                    Hi, I wrote snippet code to test. first, I put a Static text in the dialog box, from the resource file:

                    IDD_ECHOBUTTONEVENT_DIALOG DIALOGEX 0, 0, 320, 200
                    ...
                    BEGIN
                    ...
                    LTEXT "Static",IDC_STATIC_TXT1,89,59,98,26
                    ...
                    END

                    In Ontimer():

                    CRect outRect;
                    CStatic* pTxt1Static;
                    pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
                    pTxt1Static->GetWindowRect(&outRect);
                    ScreenToClient(&outRect);
                    InvalidateRect(&outRect);
                    UpdateData(FALSE);

                    In OnPaint():

                    if (IsIconic()) {
                    ...
                    }
                    else
                    {
                    CRect outRect;
                    CStatic* pTxt1Static;
                    pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
                    pTxt1Static->GetWindowRect(&outRect);
                    ScreenToClient(&outRect);

                    CPaintDC dc(pTxt1Static); 
                    //dc.SetTextColor(RGB(255,255,255));
                    dc.SetTextColor(RGB(255,0,0));
                    dc.SetBkMode(TRANSPARENT);
                    	
                    dc.DrawText(\_T("My Test"),&outRect,DT\_CENTER|DT\_VCENTER);
                    	
                    CDialogEx::OnPaint();
                    

                    }

                    But, the string "My Test" 's position is not at same position of Static text(IDC_STATIC_TXT1). offset I guess is about 50 to 100 pixel. And if I change CPaintDC dc(pTxt1Static) to CPaintDC dc(this), I got nothing, even I stretch the dialog box to double, triple size. If I don't use ScreenToClient(&outRect) in OnTimer(), and OnPaint(), I can see "My Test" string, but, need to stretch the dialog; I set break point, pTxt1Static->GetWindowRect(&outRect); give : tagRECT = {top=309 bottom=351 left=577 right=724} run to ScreenToClient(&outRect); give: tagRECT = {top=96 bottom=138 left=134 right=281} Could you please help me to see what is the reason?

                    C Offline
                    C Offline
                    Chris Losinger
                    wrote on last edited by
                    #13

                    econy wrote:

                    But, the string "My Test" 's position is not at same position of Static text(IDC_STATIC_TXT1).
                    offset I guess is about 50 to 100 pixel.

                    could that be due to the DT_CENTER|DT_VCENTER flags?

                    econy wrote:

                    And if I change CPaintDC dc(pTxt1Static) to CPaintDC dc(this),

                    it should be CPaintDC dc(this). you're painting the dialog, after all, not the static control. also, try making your static control a 'frame' type, not a static text. something like: CONTROL "",IDC_DRAWING_FRAME,"Static",SS_ETCHEDFRAME,12,199,169,66 that gives you a rectangle with no text in it.

                    image processing toolkits | batch image processing

                    1 Reply Last reply
                    0
                    • E econy

                      Hi, I wrote snippet code to test. first, I put a Static text in the dialog box, from the resource file:

                      IDD_ECHOBUTTONEVENT_DIALOG DIALOGEX 0, 0, 320, 200
                      ...
                      BEGIN
                      ...
                      LTEXT "Static",IDC_STATIC_TXT1,89,59,98,26
                      ...
                      END

                      In Ontimer():

                      CRect outRect;
                      CStatic* pTxt1Static;
                      pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
                      pTxt1Static->GetWindowRect(&outRect);
                      ScreenToClient(&outRect);
                      InvalidateRect(&outRect);
                      UpdateData(FALSE);

                      In OnPaint():

                      if (IsIconic()) {
                      ...
                      }
                      else
                      {
                      CRect outRect;
                      CStatic* pTxt1Static;
                      pTxt1Static = (CStatic*)GetDlgItem(IDC_STATIC_TXT1);
                      pTxt1Static->GetWindowRect(&outRect);
                      ScreenToClient(&outRect);

                      CPaintDC dc(pTxt1Static); 
                      //dc.SetTextColor(RGB(255,255,255));
                      dc.SetTextColor(RGB(255,0,0));
                      dc.SetBkMode(TRANSPARENT);
                      	
                      dc.DrawText(\_T("My Test"),&outRect,DT\_CENTER|DT\_VCENTER);
                      	
                      CDialogEx::OnPaint();
                      

                      }

                      But, the string "My Test" 's position is not at same position of Static text(IDC_STATIC_TXT1). offset I guess is about 50 to 100 pixel. And if I change CPaintDC dc(pTxt1Static) to CPaintDC dc(this), I got nothing, even I stretch the dialog box to double, triple size. If I don't use ScreenToClient(&outRect) in OnTimer(), and OnPaint(), I can see "My Test" string, but, need to stretch the dialog; I set break point, pTxt1Static->GetWindowRect(&outRect); give : tagRECT = {top=309 bottom=351 left=577 right=724} run to ScreenToClient(&outRect); give: tagRECT = {top=96 bottom=138 left=134 right=281} Could you please help me to see what is the reason?

                      C Offline
                      C Offline
                      Chris Losinger
                      wrote on last edited by
                      #14

                      also, it is not essential that you use a static control at all. i use them because having an actual control i can move around in the resource dialog editor makes it easy to do the layout of all the other controls. but, if you just want to draw at an arbitrary rectangle and skip the GetWindowRect/ScreenToClient/etc. stuff , you can certainly do that, too.

                      image processing toolkits | batch image processing

                      E 1 Reply Last reply
                      0
                      • C Chris Losinger

                        also, it is not essential that you use a static control at all. i use them because having an actual control i can move around in the resource dialog editor makes it easy to do the layout of all the other controls. but, if you just want to draw at an arbitrary rectangle and skip the GetWindowRect/ScreenToClient/etc. stuff , you can certainly do that, too.

                        image processing toolkits | batch image processing

                        E Offline
                        E Offline
                        econy
                        wrote on last edited by
                        #15

                        Thank you very much.

                        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