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. Clear text from a device context.

Clear text from a device context.

Scheduled Pinned Locked Moved C / C++ / MFC
question
24 Posts 5 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 Mr Simple

    Hi, Unfortunately I could not get this to work either. Do you have any other ideas? This is being run on Win CE by the way. I didn't put the transparency stuff in the last post, but it comes just before the text is printed. A global region is made in the constructor with bits missing (missing bits are therefore transparent). The images are loaded into a CBitmap array. In OnPaint; To display the BMP; Create CDC from DC CDC select object (global/main region) CDC select object (bitmap) TransparentBlt to DC; TransparentBlt(dc.GetSafeHdc(), 0, 0, floatingBMP.bmWidth, floatingBMP.bmHeight, myCDC->GetSafeHdc(), 0, 0, floatingBMP.bmWidth, floatingBMP.bmHeight, 0x00ff00);// Transparency = lime green, altho this doesnt matter as the region has already been created to take this into account; After this is the DrawText code which has already been show. Any ideas? Thanks MS.

    M Offline
    M Offline
    Mark Salsbery
    wrote on last edited by
    #14

    Without knowing what's not working...

    Mr Simple wrote:

    Create CDC from DC

    How are you doing this? It should be a memory DC created with CDC::CreateCompatibleDC().

    Mr Simple wrote:

    CDC select object (global/main region)

    What's the purpose of the region - for clipping? Why select it into the source DC? That looks suspicious...I would try commenting the region stuff out and see what happens. Are you handling WM_ERASEBKGND? If so, what are you doing there? What do you want to see and what is happening that is wrong? Mark

    Mark Salsbery Microsoft MVP - Visual C++ :java:

    M 1 Reply Last reply
    0
    • M Mark Salsbery

      Without knowing what's not working...

      Mr Simple wrote:

      Create CDC from DC

      How are you doing this? It should be a memory DC created with CDC::CreateCompatibleDC().

      Mr Simple wrote:

      CDC select object (global/main region)

      What's the purpose of the region - for clipping? Why select it into the source DC? That looks suspicious...I would try commenting the region stuff out and see what happens. Are you handling WM_ERASEBKGND? If so, what are you doing there? What do you want to see and what is happening that is wrong? Mark

      Mark Salsbery Microsoft MVP - Visual C++ :java:

      M Offline
      M Offline
      Mr Simple
      wrote on last edited by
      #15

      Hi, I am using CreateCompatibleDC; CPaintDC dc(this); // device context for painting CDC *floatCDC = new CDC; floatCDC->CreateCompatibleDC(&dc); I have removed the region code, and can report having it there made no difference to my application. I had read about it in a 'funky shaped window' article and assumed I needed it, obviously I was wrong :-) I am not handling WM_ERASEBKGND. What I want to see is text moving on a transparent background. I have manged this to a degree, however when the text is moved, the old text remains underneath the new text. I think part of the problem is that I am drawing over the old text with a transparent image, so the old text is still visible. Any other ideas? Thank you for your time! MS

      M 1 Reply Last reply
      0
      • M Mr Simple

        Hi, I am using CreateCompatibleDC; CPaintDC dc(this); // device context for painting CDC *floatCDC = new CDC; floatCDC->CreateCompatibleDC(&dc); I have removed the region code, and can report having it there made no difference to my application. I had read about it in a 'funky shaped window' article and assumed I needed it, obviously I was wrong :-) I am not handling WM_ERASEBKGND. What I want to see is text moving on a transparent background. I have manged this to a degree, however when the text is moved, the old text remains underneath the new text. I think part of the problem is that I am drawing over the old text with a transparent image, so the old text is still visible. Any other ideas? Thank you for your time! MS

        M Offline
        M Offline
        Mark Salsbery
        wrote on last edited by
        #16

        Here's a working example, moving text with a timer across a bitmap background. This is implemented on a simple dialog with just an ok button.  The same code would work in a CWnd-derived class - In that case, WM_CREATE/OnCreate would be used instead of OnInitDialog()...

        #pragma once

        #include <atlimage.h>

        // CMovingTextDialog dialog

        class CMovingTextDialog : public CDialog
        {
            DECLARE_DYNAMIC(CMovingTextDialog)

        public:
            CMovingTextDialog(CWnd* pParent = NULL);   // standard constructor
            virtual ~CMovingTextDialog();

        // Dialog Data
            enum { IDD = IDD_DIALOG2 }; //<-- Use the correct dialog resource ID here!

        protected:
            virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

        DECLARE_MESSAGE_MAP()
        public:
            virtual BOOL OnInitDialog();
        protected:
            virtual void OnOK();
        public:
            CImage BkImage;
            UINT_PTR MoveTimer;
            CString TextStr;
            CSize TextSize;
            CRect TextRect;

        afx_msg void OnPaint();
            afx_msg BOOL OnEraseBkgnd(CDC* pDC);
            afx_msg void OnTimer(UINT_PTR nIDEvent);

        };

        // MovingTextDialog.cpp : implementation file
        //

        #include "stdafx.h"
        #include "MFCTester.h"
        #include "MovingTextDialog.h"

        // CMovingTextDialog dialog

        IMPLEMENT_DYNAMIC(CMovingTextDialog, CDialog)

        CMovingTextDialog::CMovingTextDialog(CWnd* pParent /*=NULL*/)
            : CDialog(CMovingTextDialog::IDD, pParent)
        {
            BkImage.Load(_T("e:\\test.bmp")); //<-- load your own bmp/jpg/tiff here!
            MoveTimer = 0;
            TextStr = _T("Moving Text");
            TextSize.cx = TextSize.cy = 0;
            TextRect.SetRect(0,0,0,0);
        }

        CMovingTextDialog::~CMovingTextDialog()
        {
        }

        void CMovingTextDialog::DoDataExchange(CDataExchange* pDX)
        {
            CDialog::DoDataExchange(pDX);
        }

        BEGIN_MESSAGE_MAP(CMovingTextDialog, CDialog)
            ON_WM_PAINT()
            ON_WM_ERASEBKGND()
            ON_WM_TIMER()
        END_MESSAGE_MAP()

        // CMovingTextDialog message handlers

        BOOL CMovingTextDialog::OnInitDialog()
        {
            CDialog::OnInitDialog();

        MoveTimer = ::SetTimer(*this, (UINT_PTR)12345, 10, NULL);

        return TRUE;&n

        M 1 Reply Last reply
        0
        • M Mark Salsbery

          Here's a working example, moving text with a timer across a bitmap background. This is implemented on a simple dialog with just an ok button.  The same code would work in a CWnd-derived class - In that case, WM_CREATE/OnCreate would be used instead of OnInitDialog()...

          #pragma once

          #include <atlimage.h>

          // CMovingTextDialog dialog

          class CMovingTextDialog : public CDialog
          {
              DECLARE_DYNAMIC(CMovingTextDialog)

          public:
              CMovingTextDialog(CWnd* pParent = NULL);   // standard constructor
              virtual ~CMovingTextDialog();

          // Dialog Data
              enum { IDD = IDD_DIALOG2 }; //<-- Use the correct dialog resource ID here!

          protected:
              virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

          DECLARE_MESSAGE_MAP()
          public:
              virtual BOOL OnInitDialog();
          protected:
              virtual void OnOK();
          public:
              CImage BkImage;
              UINT_PTR MoveTimer;
              CString TextStr;
              CSize TextSize;
              CRect TextRect;

          afx_msg void OnPaint();
              afx_msg BOOL OnEraseBkgnd(CDC* pDC);
              afx_msg void OnTimer(UINT_PTR nIDEvent);

          };

          // MovingTextDialog.cpp : implementation file
          //

          #include "stdafx.h"
          #include "MFCTester.h"
          #include "MovingTextDialog.h"

          // CMovingTextDialog dialog

          IMPLEMENT_DYNAMIC(CMovingTextDialog, CDialog)

          CMovingTextDialog::CMovingTextDialog(CWnd* pParent /*=NULL*/)
              : CDialog(CMovingTextDialog::IDD, pParent)
          {
              BkImage.Load(_T("e:\\test.bmp")); //<-- load your own bmp/jpg/tiff here!
              MoveTimer = 0;
              TextStr = _T("Moving Text");
              TextSize.cx = TextSize.cy = 0;
              TextRect.SetRect(0,0,0,0);
          }

          CMovingTextDialog::~CMovingTextDialog()
          {
          }

          void CMovingTextDialog::DoDataExchange(CDataExchange* pDX)
          {
              CDialog::DoDataExchange(pDX);
          }

          BEGIN_MESSAGE_MAP(CMovingTextDialog, CDialog)
              ON_WM_PAINT()
              ON_WM_ERASEBKGND()
              ON_WM_TIMER()
          END_MESSAGE_MAP()

          // CMovingTextDialog message handlers

          BOOL CMovingTextDialog::OnInitDialog()
          {
              CDialog::OnInitDialog();

          MoveTimer = ::SetTimer(*this, (UINT_PTR)12345, 10, NULL);

          return TRUE;&n

          M Offline
          M Offline
          Mr Simple
          wrote on last edited by
          #17

          Hello, The only major difference is that I am not using CImage, as I need to be able to TransparentBlt which I have been told there are problems with on WinCE. I converted your code closer to my existing (using CBitmap, transparency, removing erase bkground) and it worked great. Then I made my existing code practically idential, and it still didn't work :-( The only thing I can find different is the way I create the window. I have a method in the class called "CreateFloaterWnd" (parent as parameter) which loads the bitmap, gets it's size, then calls CWnd::CreateEx, positioning itself relative to the parent's X/Y location. I will try to convert it to use a dialog and see what happens. I still dont understand how this could be the problem though. Thank you very much for your effort!! MS.

          M 1 Reply Last reply
          0
          • M Mr Simple

            Hello, The only major difference is that I am not using CImage, as I need to be able to TransparentBlt which I have been told there are problems with on WinCE. I converted your code closer to my existing (using CBitmap, transparency, removing erase bkground) and it worked great. Then I made my existing code practically idential, and it still didn't work :-( The only thing I can find different is the way I create the window. I have a method in the class called "CreateFloaterWnd" (parent as parameter) which loads the bitmap, gets it's size, then calls CWnd::CreateEx, positioning itself relative to the parent's X/Y location. I will try to convert it to use a dialog and see what happens. I still dont understand how this could be the problem though. Thank you very much for your effort!! MS.

            M Offline
            M Offline
            Mark Salsbery
            wrote on last edited by
            #18

            Hmmm I don't know about WinCE unfortunately. CImage wraps a little GDI+ for loading and saving, and also wraps a HBITMAP/DIBSection, which works with TransparentBlt() just fine (in fact, the class has a TransparentBlt() method). Again, I'm not sure about WinCE compatibility though. If you have a little project that doesn't work that I can test on regular Windows I'll check it out. Good luck :) Mark

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            M 1 Reply Last reply
            0
            • M Mark Salsbery

              Hmmm I don't know about WinCE unfortunately. CImage wraps a little GDI+ for loading and saving, and also wraps a HBITMAP/DIBSection, which works with TransparentBlt() just fine (in fact, the class has a TransparentBlt() method). Again, I'm not sure about WinCE compatibility though. If you have a little project that doesn't work that I can test on regular Windows I'll check it out. Good luck :) Mark

              Mark Salsbery Microsoft MVP - Visual C++ :java:

              M Offline
              M Offline
              Mr Simple
              wrote on last edited by
              #19

              Hi, Everything in normal windows can be done in CE, sometimes you just need to go about it a bit differently. I have cut out everything from my project and managed to write a non-working class if you are interested. I wont have access to CE again until monday so wont be able to test the dialog thing yet. Below is the code, it is very simple as you can probably see. Just call the .CreateTransparent(this); and you should get a nice streak down the form. Once again, thanks for your help! MS. The .H; class CNotWorking : public CWnd { public: CNotWorking(void); ~CNotWorking(void); void CreateTransparent(CWnd *pParent); DECLARE_MESSAGE_MAP() afx_msg void OnPaint(); afx_msg void OnTimer(UINT nIDEvent); private: CRect rTextRect; UINT tTicker; }; ////////// And the .CPP; BEGIN_MESSAGE_MAP(CNotWorking, CWnd) ON_WM_PAINT() ON_WM_TIMER() END_MESSAGE_MAP() CNotWorking::CNotWorking(void) { rTextRect.SetRect(0, 0, 40, 20); tTicker = 0; } CNotWorking::~CNotWorking(void) { } void CNotWorking::CreateTransparent(CWnd *pParent) { // Create & flag as existing. CWnd::CreateEx(NULL, NULL, _T("Transparent"), WS_CHILD, 20, 20, 500, 500, pParent->GetSafeHwnd(), NULL); tTicker = ::SetTimer(*this, (UINT_PTR)12345, 20, NULL); ShowWindow(SW_SHOW); } void CNotWorking::OnPaint() { CPaintDC dc(this); // device context for painting dc.SetBkMode(TRANSPARENT); CString textStr = "test"; dc.DrawText(textStr, &rTextRect, DT_LEFT | DT_TOP); } void CNotWorking::OnTimer(UINT nIDEvent) { InvalidateRect(rTextRect); rTextRect.OffsetRect(0, 2); UpdateWindow(); CWnd::OnTimer(nIDEvent); }

              M 1 Reply Last reply
              0
              • M Mr Simple

                Hi, Everything in normal windows can be done in CE, sometimes you just need to go about it a bit differently. I have cut out everything from my project and managed to write a non-working class if you are interested. I wont have access to CE again until monday so wont be able to test the dialog thing yet. Below is the code, it is very simple as you can probably see. Just call the .CreateTransparent(this); and you should get a nice streak down the form. Once again, thanks for your help! MS. The .H; class CNotWorking : public CWnd { public: CNotWorking(void); ~CNotWorking(void); void CreateTransparent(CWnd *pParent); DECLARE_MESSAGE_MAP() afx_msg void OnPaint(); afx_msg void OnTimer(UINT nIDEvent); private: CRect rTextRect; UINT tTicker; }; ////////// And the .CPP; BEGIN_MESSAGE_MAP(CNotWorking, CWnd) ON_WM_PAINT() ON_WM_TIMER() END_MESSAGE_MAP() CNotWorking::CNotWorking(void) { rTextRect.SetRect(0, 0, 40, 20); tTicker = 0; } CNotWorking::~CNotWorking(void) { } void CNotWorking::CreateTransparent(CWnd *pParent) { // Create & flag as existing. CWnd::CreateEx(NULL, NULL, _T("Transparent"), WS_CHILD, 20, 20, 500, 500, pParent->GetSafeHwnd(), NULL); tTicker = ::SetTimer(*this, (UINT_PTR)12345, 20, NULL); ShowWindow(SW_SHOW); } void CNotWorking::OnPaint() { CPaintDC dc(this); // device context for painting dc.SetBkMode(TRANSPARENT); CString textStr = "test"; dc.DrawText(textStr, &rTextRect, DT_LEFT | DT_TOP); } void CNotWorking::OnTimer(UINT nIDEvent) { InvalidateRect(rTextRect); rTextRect.OffsetRect(0, 2); UpdateWindow(); CWnd::OnTimer(nIDEvent); }

                M Offline
                M Offline
                Mark Salsbery
                wrote on last edited by
                #20

                Your code works for me. In OnTimer(), I had to change InvalidateRect(rTextRect); to InvalidateRect(&rTextRect); Mark

                Mark Salsbery Microsoft MVP - Visual C++ :java:

                M 1 Reply Last reply
                0
                • M Mark Salsbery

                  Your code works for me. In OnTimer(), I had to change InvalidateRect(rTextRect); to InvalidateRect(&rTextRect); Mark

                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                  M Offline
                  M Offline
                  Mr Simple
                  wrote on last edited by
                  #21

                  Mark Salsbery wrote:

                  Your code works for me.

                  Really??? :wtf: I have tried both but I still get the smudge either way (I have only tested on XP).

                  M 1 Reply Last reply
                  0
                  • M Mr Simple

                    Mark Salsbery wrote:

                    Your code works for me.

                    Really??? :wtf: I have tried both but I still get the smudge either way (I have only tested on XP).

                    M Offline
                    M Offline
                    Mark Salsbery
                    wrote on last edited by
                    #22

                    Yes, really :) The change I made wasn't even necessary, since CRect has a LPRECT operator. I'm testing on Vista. Is it leaving a trail of pixels or does the entire text get left behind on previous draws? Mark

                    Mark Salsbery Microsoft MVP - Visual C++ :java:

                    M 1 Reply Last reply
                    0
                    • M Mark Salsbery

                      Yes, really :) The change I made wasn't even necessary, since CRect has a LPRECT operator. I'm testing on Vista. Is it leaving a trail of pixels or does the entire text get left behind on previous draws? Mark

                      Mark Salsbery Microsoft MVP - Visual C++ :java:

                      M Offline
                      M Offline
                      Mr Simple
                      wrote on last edited by
                      #23

                      The entire text gets left behind (in the image below I have used 'rTextRect.OffsetRect(0, 20);' to space them out a bit to show this). http://i19.tinypic.com/8a4gh2w.jpg Thanks MS.

                      M 1 Reply Last reply
                      0
                      • M Mr Simple

                        The entire text gets left behind (in the image below I have used 'rTextRect.OffsetRect(0, 20);' to space them out a bit to show this). http://i19.tinypic.com/8a4gh2w.jpg Thanks MS.

                        M Offline
                        M Offline
                        Mark Salsbery
                        wrote on last edited by
                        #24

                        Hmm that shouldn't happen :) WM_ERASEBKGND should redraw the background for the invalidated rect when the CPaintDC is created (during the internal call to BeginPaint(). Can you add a WM_ERASEBKGND that calls the base class method? Then in that handler, maybe draw a rectangle at the textrect. Mark

                        Mark Salsbery Microsoft MVP - Visual C++ :java:

                        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