CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Dec 2010
    Posts
    907

    How do I make this code work for std::string type?

    Code:
    class GetSettingsVisitor {
      public:
        HWND dlg_;
        int lastItem_;
        std::wstring lastItemName_;
        GetSettingsVisitor(HWND dlg) : dlg_(dlg) {}
        bool operator()(char const * group, bool & b, char const * name, bool v, char const * title, int id)
          {
            lastItem_ = WindowId(id);
            lastItemName_ = _towchar(title);
            HWND t = ::FindWindowEx(dlg_, 0, WC_BUTTON, _towchar(group));
            if (t == 0) t = dlg_;
            HWND i = ::GetDlgItem(t, WindowId(id));
            assert(i != 0);
            b = (::IsDlgButtonChecked(t, WindowId(id)) != 0);
            return true;
          }
        
        bool operator()(char const * group, float & b, char const * name, float v, char const * title, int id)
          {
            lastItem_ = WindowId(id);
            lastItemName_ = _towchar(title);
            HWND t = ::FindWindowEx(dlg_, 0, WC_BUTTON, _towchar(group));
            if (t == 0) t = dlg_;
            HWND i = ::GetDlgItem(t, WindowId(id));
            assert(i != 0);
            MCHAR text[512];
            ::GetWindowText(i, text, 512);
            text[511] = 0;
            if (swscanf(text, L"%f", &b) != 1) {
              return false;
            }
            //  there's a minimum and maximum value for floats
            if (b < 1e-3 || b > 1e3) {
              return false;
            }
            return true;
          }
    	
    	bool operator()(char const * group, int & b, char const * name, int v, char const * title, int id)
          {
            lastItem_ = WindowId(id);
            lastItemName_ = _towchar(title);
            HWND t = ::FindWindowEx(dlg_, 0, WC_BUTTON, _towchar(group));
            if (t == 0) t = dlg_;
            HWND i = ::GetDlgItem(t, WindowId(id));
            assert(i != 0);
            MCHAR text[512];
            ::GetWindowText(i, (text), 512);
            text[511] = 0;
            return swscanf(text, L"%d", &b) == 1;
          }
    
    	// todo Fill to adapt str controls
    	bool operator()(char const* group, std::string& str, char const* name, std::string v, char const* title, int id)
    	{
    		lastItem_ = WindowId(id);
            lastItemName_ = _towchar(title);
            HWND t = ::FindWindowEx(dlg_, 0, WC_BUTTON, _towchar(group));
            if (t == 0) t = dlg_;
            HWND i = ::GetDlgItem(t, WindowId(id));
            assert(i != 0);
            MCHAR text[512];
            ::GetWindowText(i, (text), 512);
            text[511] = 0;
            return swscanf(text, L"%s", str.c_str()) == 1;
    	}
        
    };
    Code:
    template<typename Visitor> bool Visit(Settings & s, Visitor & v)
    {
      return
          v("Geometry", s.exportNormal_, "normals", true, "Export Normals", 1) &&
          v("Geometry", s.exportTangent_, "tangents", false, "Export Tangents", 2) &&
          v("Geometry", s.exportColor_, "colors", false, "Vertex Colors as Diffuse", 3) &&
          v("Geometry", s.exportUv_, "uvChannels", 1, "Num UV Channels", 4) &&
          v("Geometry", s.flipV_, "flipV", false, "Flip V Channel", 9) &&
          v("Geometry", s.flipTangent_, "flipTangent", false, "Flip Tangent Channel", 14) &&
          v("Geometry", s.yUp_, "yUp", true, "Make Y Up", 10) &&
          v("Geometry", s.rightHanded_, "rightHanded", true, "Export Right-handed Mesh", 11) &&
          v("Geometry", s.flipWinding_, "flipWinding", false, "Flip Winding", 13) &&
    	  v("Geometry", s.scaleNumer_, "scaleNumer", 1.0f, "Scale Numerator", 5) &&
          v("Geometry", s.scaleDenom_, "scaleDenom", 1.0f, "Scale Denominator", 6) &&
          v("Materials", s.exportMaterial_, "materials", true, "Export Materials", 20) &&
    	  v("Materials", s.fullPath_, "fullPath", false, "Full Texture Path", 21) &&
          v("Materials", s.ignoreUntextured_, "ignoreUntextured", false, "Ignore Untextured", 24) &&
    	  v("Animation", s.exportSkinning_, "exportSkinning", false, "Export Skinning", 7) &&
          v("Animation", s.exportAnimation_, "exportAnimation", false, "Export Animation", 40) &&
    	  v("Animation", s.useMaxTicks_, "useMaxTicks", false, "Use 3dsMax Ticks", 41) &&
          v("Animation", s.firstFrame_, "firstFrame", 0, "First Frame", IDC_FIRSTFRAME) &&
          v("Animation", s.numFrames_, "numFrames", 100, "Num. Frames", IDC_NUMFRAMES) && 
    	  v("Animation", (std::string) s.animationName_, "animationName", (std::string)"\0", "Animation Name", IDC_ANIMATIONNAME) &&
          v("Misc", s.exportHidden_, "hidden", true, "Export Hidden", 61) &&
          v("Misc", s.exportCompressed_, "exportCompressed", false, "Export Compressed", 12) &&
          v("Misc", s.exportBinary_, "exportBinary", false, "Export Binary", 8) &&
          true;
    }
    The type std::string has a value of null when trying to retrieve its value
    from the edit control.
    v("Animation", (std::string) s.animationName_, "animationName", (std::string)"\0", "Animation Name", IDC_ANIMATIONNAME)

    Thanks
    Jack

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: How do I make this code work for std::string type?

    you're never actually filling in the string str in that function.

  3. #3
    Join Date
    Dec 2010
    Posts
    907

    Re: How do I make this code work for std::string type?

    Is there a workaround that?
    Hopefully positive...
    Thanks
    Jack

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: How do I make this code work for std::string type?

    well yes... fill in the string...

    you have code to swscanf the string contents ( str.c_str() ), but you're not ever initialising str, or copying anything into it. I can't tell you what to do since I have no idea what you would like to have stored in there.

  5. #5
    Join Date
    Dec 2010
    Posts
    907

    Re: How do I make this code work for std::string type?

    This is a plugin program for 3ds max, in which there is a dialog popped up when the user
    enters the export function, there is a edit control which allows the user to enter the name
    of the animation. I'd like to store this entered string into my xml file, which is obtained
    thru this GetSettingsVisitor function.
    I have tried to initialize the string by simply adding this line
    str = "test";
    before the return statement of the
    overrided operator method, but nothing yet has come out of it.
    Did I omit something as well?
    Thanks
    Jack

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: How do I make this code work for std::string type?

    Quote Originally Posted by lucky6969b View Post
    The type std::string has a value of null when trying to retrieve its value
    from the edit control.
    v("Animation", (std::string) s.animationName_, "animationName", (std::string)"\0", "Animation Name", IDC_ANIMATIONNAME)
    What is s.animationName_?
    Why are you C-style casting to a std::string?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  7. #7
    Join Date
    Dec 2010
    Posts
    907

    Re: How do I make this code work for std::string type?

    s.animationName_ is a std::string?
    Do I use (MCHAR*)& instead of std::string&?
    Thanks
    Jack

  8. #8
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: How do I make this code work for std::string type?

    Quote Originally Posted by lucky6969b View Post
    s.animationName_ is a std::string?
    Do I use (MCHAR*)& instead of std::string&?
    Thanks
    Jack
    So what did you think that this would achieve?
    Code:
    (std::string) s.animationName_
    If s.animationName_ is a std::string and the function you are calling asks for a std::string& as a parameter, how do you call it? Let's take out all the noise from the example. How do you call foo in the code below, such that it writes to the variable str?
    Code:
    #include <string>
    
    void foo(std::string& in)
    {
        in = "test";
    }
    
    int main()
    {
        std::string str;
        // ?
    }
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  9. #9
    Join Date
    Dec 2010
    Posts
    907

    Re: How do I make this code work for std::string type?

    I would do something like this.

    Code:
    #include <string>
    #include <iostream>
    
    using namespace std;
     
    
    void foo(std::string& in)
    {
        in = "test";
    }
    
    int main()
    {
        std::string str;
        foo(str);
        cout << str << endl;
    }
    Do I do something like this?
    std::string a("");
    v("Animation", s.animationName_, "animationName", a, "Animation Name", IDC_ANIMATIONNAME)
    The only thing is that it only records the first letter I enter in the edit control.
    Thanks
    Jack
    Last edited by lucky6969b; January 19th, 2014 at 01:58 AM.

  10. #10
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: How do I make this code work for std::string type?

    Quote Originally Posted by lucky6969b View Post
    I would do something like this.

    Code:
    #include <string>
    #include <iostream>
    
    using namespace std;
     
    
    void foo(std::string& in)
    {
        in = "test";
    }
    
    int main()
    {
        std::string str;
        foo(str);
        cout << str << endl;
    }
    Right, so there is no need for C-style casts.
    Quote Originally Posted by lucky6969b View Post
    Do I do something like this?
    std::string a("");
    v("Animation", s.animationName_, "animationName", a, "Animation Name", IDC_ANIMATIONNAME)
    Actually, since the function takes the 4th argument (std::string) by value, you don't need to make a local variable for it; you can pass a temporary object.
    Code:
    v("Animation", s.animationName_, "animationName", std::string(), "Animation Name", IDC_ANIMATIONNAME)
    This default constructs a temporary std::string, which is then passed to the function as the fourth argument.
    Quote Originally Posted by lucky6969b View Post
    The only thing is that it only records the first letter I enter in the edit control.
    Thanks
    Jack
    Now that you are calling the function correctly (as far as I can tell), you can debug what goes on inside the function. Set a break point and step through each line of the function. Check the value of each variable in the watch window.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  11. #11
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How do I make this code work for std::string type?

    Quote Originally Posted by lucky6969b View Post
    The only thing is that it only records the first letter I enter in the edit control.
    Code:
    return swscanf(text, L"%s", str.c_str())
    str is a std::string, which is based on a char*. Why are you using functions that work with wide strings?? Are you familiar with the differences between string types?

    That is probably why you see only the first character. A null-terminated "traditional" wide string looks like this in memory (assume the string is "abc"):
    Code:
    "a\0b\0c\0\0"
    A null byte comes after every character. So what do you think will happen if you feed this into a std::string? The std::string stops at the byte after the 'a'.

    There is std::string and there is std::wstring which is based on 16-bit characters. Don't mix the two together.

    Also, it's strange that you're using a visitor pattern, yet your class contains redundancies. Isn't the use of design patterns (and just general good class design) remove or greatly reduce the number of redundancies in your code? I'm speaking of the operator(), where the only difference between all of them is a few lines. They all start off with the same boilerplate code, and then only differ slightly afterwards. This is where usage of the template design pattern would be beneficial.

    In general, when you find yourself copying and pasting the same code over and over again, take a look carefully at the design.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; January 19th, 2014 at 11:38 AM.

  12. #12
    Join Date
    Dec 2010
    Posts
    907

    Re: How do I make this code work for std::string type?

    Hi, I've got something working now.
    I forget about wide strings now, and concentrate on normal ASCII strings.
    But how do I convert a wide string to a normal string
    Code:
     char anAnim[100];
     strcpy(anAnim,"Anim-");	   
     strcat(anAnim,(*ptr)->GetName());
     ptree& anim = stick(animSet, anAnim, (DWORD) 0);
    Here GetName() returns a w_tchar*, I'd like to convert it into a char*
    Thanks
    Jack

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449

    Re: How do I make this code work for std::string type?

    Quote Originally Posted by lucky6969b View Post
    Here GetName() returns a w_tchar*, I'd like to convert it into a char*
    Use WideCharToMultiByte. However, make sure you first write a simple main() program that calls this function correctly and successfully. It is one of the easiest functions to get wrong (since it is 'C' based, and there is no checking for memory overwrites if your buffers are too small or give the wrong parameters).

    Regards,

    Paul McKenzie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured