-
January 16th, 2014, 06:38 AM
#1
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
-
January 16th, 2014, 08:07 AM
#2
Re: How do I make this code work for std::string type?
you're never actually filling in the string str in that function.
-
January 16th, 2014, 08:10 AM
#3
Re: How do I make this code work for std::string type?
Is there a workaround that?
Hopefully positive...
Thanks
Jack
-
January 17th, 2014, 07:38 AM
#4
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.
-
January 17th, 2014, 08:26 AM
#5
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
-
January 17th, 2014, 09:47 AM
#6
Re: How do I make this code work for std::string type?
Originally Posted by lucky6969b
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
-
January 18th, 2014, 01:01 AM
#7
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
-
January 18th, 2014, 08:59 AM
#8
Re: How do I make this code work for std::string type?
Originally Posted by lucky6969b
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
-
January 19th, 2014, 12:36 AM
#9
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.
-
January 19th, 2014, 05:59 AM
#10
Re: How do I make this code work for std::string type?
Originally Posted by lucky6969b
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.
Originally Posted by lucky6969b
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.
Originally Posted by lucky6969b
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
-
January 19th, 2014, 11:35 AM
#11
Re: How do I make this code work for std::string type?
Originally Posted by lucky6969b
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"):
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.
-
January 19th, 2014, 06:51 PM
#12
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
-
January 19th, 2014, 08:25 PM
#13
Re: How do I make this code work for std::string type?
Originally Posted by lucky6969b
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|