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. DrawText is giving me garbage

DrawText is giving me garbage

Scheduled Pinned Locked Moved C / C++ / MFC
helpc++graphicsxml
14 Posts 3 Posters 1 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.
  • T thebeekeeper

    I was a little confused about that part too. If I don't cast it, I get a compile error: cannont convert from const char* to LPCTSTR. I always thought those were the same thing. Another odd part of this problem is that when I use a standard CListBox, I can correctly add items to it like this:

    USES_CONVERSION;
    CA2CT converted(updates[i]->ToString().c_str());
    m_UpdateBox.AddString(converted)

    Which makes it seem like I'm incorrectly calling DrawText in my subclass because when I add the same text to my list box I get bad data on the display.

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

    thebeekeeper wrote:

    I get a compile error: cannont convert from const char* to LPCTSTR. I always thought those were the same thing.

    That's exactly what I'm talking about :) That's a perfect example why casting away problems is BAD. C++ is a strongly typed language - know your data types! No, LPCTSTR is NOT the same as a char *. Here's the macro breakdown for LPCTSTR: LP = long pointer C = constant T = generic-character-type (wchar_t for Unicode builds, else char) STR = string

    thebeekeeper wrote:

    when I use a standard CListBox, I can correctly add items to it like this:

    Yes, because you're converting the string to the type the listbox is expecting.

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

    T 1 Reply Last reply
    0
    • M Mark Salsbery

      thebeekeeper wrote:

      I get a compile error: cannont convert from const char* to LPCTSTR. I always thought those were the same thing.

      That's exactly what I'm talking about :) That's a perfect example why casting away problems is BAD. C++ is a strongly typed language - know your data types! No, LPCTSTR is NOT the same as a char *. Here's the macro breakdown for LPCTSTR: LP = long pointer C = constant T = generic-character-type (wchar_t for Unicode builds, else char) STR = string

      thebeekeeper wrote:

      when I use a standard CListBox, I can correctly add items to it like this:

      Yes, because you're converting the string to the type the listbox is expecting.

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

      T Offline
      T Offline
      thebeekeeper
      wrote on last edited by
      #6

      Thanks for that tip on data types. I never realized LPCTSTR was just an alias for the generic string type of the build. I guess this is really what I don't understand. CA2CT converts ASCII to wchar_t since this is a Unicode build, right? CListBox::AddItem expects LPCTSTR. But this is actually a LPCWSTR, right? So, why does converting with CA2CT work with the stock CListBox and not my subclass? CListBox::DrawItem has to be calling DrawTextW, which is the same thing I'm calling.

      M 1 Reply Last reply
      0
      • T thebeekeeper

        Thanks for that tip on data types. I never realized LPCTSTR was just an alias for the generic string type of the build. I guess this is really what I don't understand. CA2CT converts ASCII to wchar_t since this is a Unicode build, right? CListBox::AddItem expects LPCTSTR. But this is actually a LPCWSTR, right? So, why does converting with CA2CT work with the stock CListBox and not my subclass? CListBox::DrawItem has to be calling DrawTextW, which is the same thing I'm calling.

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

        thebeekeeper wrote:

        CA2CT converts ASCII to wchar_t since this is a Unicode build, right?

        Right. A is ANSI, T is generic...A2T is ANSI to generic.

        thebeekeeper wrote:

        why does converting with CA2CT work with the stock CListBox and not my subclass?

        Is the source string already a Unicode (wchar_t) string?

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

        T 2 Replies Last reply
        0
        • M Mark Salsbery

          thebeekeeper wrote:

          CA2CT converts ASCII to wchar_t since this is a Unicode build, right?

          Right. A is ANSI, T is generic...A2T is ANSI to generic.

          thebeekeeper wrote:

          why does converting with CA2CT work with the stock CListBox and not my subclass?

          Is the source string already a Unicode (wchar_t) string?

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

          T Offline
          T Offline
          thebeekeeper
          wrote on last edited by
          #8

          No, it's coming out of std::string c_str(), so it's a const char*. There's no way that can be Unicode, right? Also, if I use OutputDebugString, it works after I use the CA2W conversion and looks correct in the output window. So, I've got this:

          USES_CONVERSION;
          CA2W converted(updates[i]->ToString().c_str());
          // CListBox -- looks right
          m_UpdateBox.AddString(converted);
          // CMyListBox -- looks wrong
          m_ProductList.AddString(converted);
          // Output window -- looks right
          OutputDebugString(converted);

          I'm starting to think I'm pulling out bad data in my DrawItem method, but I copied that code from MSDN, so it can't be wrong :omg:

          M 1 Reply Last reply
          0
          • M Mark Salsbery

            thebeekeeper wrote:

            CA2CT converts ASCII to wchar_t since this is a Unicode build, right?

            Right. A is ANSI, T is generic...A2T is ANSI to generic.

            thebeekeeper wrote:

            why does converting with CA2CT work with the stock CListBox and not my subclass?

            Is the source string already a Unicode (wchar_t) string?

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

            T Offline
            T Offline
            thebeekeeper
            wrote on last edited by
            #9

            AHA! I just figured out that I'm doing the conversion correctly (maybe), the problem is I have bad data to convert. I inspected the memory location that lpDrawItemStruct->itemData was pointing to, and it looked like garbage. So, I added a method to my class where I can send text and store it in a vector. Then, in DrawItem I just look in my own vector for strings to draw, and everything works fine. I guess this works for now, but I'd really like to know how to get my string out of itemData so I can use AddString on my list box like a normal person. The only idea that I have right now is that my initial cast in DrawItem is bad.

            LPCTSTR lpszText = (LPCTSTR) lpDrawItemStruct->itemData;

            I don't see how this could be bad since that's exactly what I'm passing to AddString. The strange this is that it works when I pass in a literal with TEXT("..."), but not a converted const char* from string.c_str(). Thanks for your help!

            M 2 Replies Last reply
            0
            • T thebeekeeper

              No, it's coming out of std::string c_str(), so it's a const char*. There's no way that can be Unicode, right? Also, if I use OutputDebugString, it works after I use the CA2W conversion and looks correct in the output window. So, I've got this:

              USES_CONVERSION;
              CA2W converted(updates[i]->ToString().c_str());
              // CListBox -- looks right
              m_UpdateBox.AddString(converted);
              // CMyListBox -- looks wrong
              m_ProductList.AddString(converted);
              // Output window -- looks right
              OutputDebugString(converted);

              I'm starting to think I'm pulling out bad data in my DrawItem method, but I copied that code from MSDN, so it can't be wrong :omg:

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

              thebeekeeper wrote:

              it's coming out of std::string c_str(), so it's a const char*. There's no way that can be Unicode, right?

              Right, but a deeper question is why are you using a string type hardwired to char in a Unicode environment? I recommend using generic string types everywhere in an MFC app. MFC does, so it works out nice when we do. Using all generics makes any code you write compilable in both Unicode and non-Unicode builds, just like MFC. Plus you don't need to do all those string conversions, which are inefficient. If you must use STL strings, you could make your own generic string class:

              typedef std::basic_string<TCHAR, char_traits<TCHAR>,
              allocator<TCHAR>> genericstdstring;

              Use genericstdstring in place of std::string.

              thebeekeeper wrote:

              but I copied that code from MSDN, so it can't be wrong

              Umm...if you say so :)

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

              1 Reply Last reply
              0
              • T thebeekeeper

                AHA! I just figured out that I'm doing the conversion correctly (maybe), the problem is I have bad data to convert. I inspected the memory location that lpDrawItemStruct->itemData was pointing to, and it looked like garbage. So, I added a method to my class where I can send text and store it in a vector. Then, in DrawItem I just look in my own vector for strings to draw, and everything works fine. I guess this works for now, but I'd really like to know how to get my string out of itemData so I can use AddString on my list box like a normal person. The only idea that I have right now is that my initial cast in DrawItem is bad.

                LPCTSTR lpszText = (LPCTSTR) lpDrawItemStruct->itemData;

                I don't see how this could be bad since that's exactly what I'm passing to AddString. The strange this is that it works when I pass in a literal with TEXT("..."), but not a converted const char* from string.c_str(). Thanks for your help!

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

                thebeekeeper wrote:

                The only idea that I have right now is that my initial cast in DrawItem is bad.

                That cast is valid and necessary, since DRAWITEMSTRUCT.itemData is a ULONG_PTR. I'm not sure why you're getting garbage there...

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

                1 Reply Last reply
                0
                • T thebeekeeper

                  AHA! I just figured out that I'm doing the conversion correctly (maybe), the problem is I have bad data to convert. I inspected the memory location that lpDrawItemStruct->itemData was pointing to, and it looked like garbage. So, I added a method to my class where I can send text and store it in a vector. Then, in DrawItem I just look in my own vector for strings to draw, and everything works fine. I guess this works for now, but I'd really like to know how to get my string out of itemData so I can use AddString on my list box like a normal person. The only idea that I have right now is that my initial cast in DrawItem is bad.

                  LPCTSTR lpszText = (LPCTSTR) lpDrawItemStruct->itemData;

                  I don't see how this could be bad since that's exactly what I'm passing to AddString. The strange this is that it works when I pass in a literal with TEXT("..."), but not a converted const char* from string.c_str(). Thanks for your help!

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

                  thebeekeeper wrote:

                  The strange this is that it works when I pass in a literal with TEXT("..."), but not a converted const char* from string.c_str().

                  Ooops I missed that part :) What conversion are you using there? Are you sure that conversion is succeeding? I'm thinking no :)

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

                  T 1 Reply Last reply
                  0
                  • M Mark Salsbery

                    thebeekeeper wrote:

                    The strange this is that it works when I pass in a literal with TEXT("..."), but not a converted const char* from string.c_str().

                    Ooops I missed that part :) What conversion are you using there? Are you sure that conversion is succeeding? I'm thinking no :)

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

                    T Offline
                    T Offline
                    thebeekeeper
                    wrote on last edited by
                    #13

                    I'm using the same CA2W conversion that I use on a const char* from c_str(). And no, it doesn't work, but the strange thing is that it's like the data is going bad when I pass it into CMyList::AddString(). So, if I create a LPCWSTR hello = TEXT("hello") and pass it into CListBox and CMyList::AddString everything works fine. But! If I do a CA2W conversion and pass it into both of those same methods, it works for CListBox, but now for CMyList. X|

                    M 1 Reply Last reply
                    0
                    • T thebeekeeper

                      I'm using the same CA2W conversion that I use on a const char* from c_str(). And no, it doesn't work, but the strange thing is that it's like the data is going bad when I pass it into CMyList::AddString(). So, if I create a LPCWSTR hello = TEXT("hello") and pass it into CListBox and CMyList::AddString everything works fine. But! If I do a CA2W conversion and pass it into both of those same methods, it works for CListBox, but now for CMyList. X|

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

                      thebeekeeper wrote:

                      I'm using the same CA2W conversion

                      Why did you switch to CA2W, when the generic CA2CT was the appropriate conversion? Again, why is the conversion even necessary? Do you really need to use char type strings anywhere? char has been pretty much obsolete for a decade :) Mixing hardwired character types and generic types causes problems like these, which is why I recommend using the generic types.

                      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