SHGetSpecialFolderPath to a System::String^ - string

I'm trying to parse a SHGetSpecialFolderPath into a string, a System::String^ to be precise.
I'm now using this code:
TCHAR appDataPath;
SHGetSpecialFolderPath(0, appDataPath, CSIDL_APPDATA, false);
I've tried things like this, but it doesn't work either:
LPWSTR appDataPath;
SHGetSpecialFolderPath(0, appDataPath, CSIDL_APPDATA, false);
I just want to get a System::String^ like this:
System::String ^ loc_inst = appDataPath + "\\inst\\info.xml";

I don't think C++/CLI can automatically concatenate char arrays and assign them to a string handle. I think you need to instantiate a new System::String object like this:
System::String^ loc_inst = gcnew System::String(appDataPath);
loc_inst.Append("\\inst\\info.xml");
Or you could use a StringBuilder, but if you want to make a new String object I think you've got to use gcnew and a constructor.
Keep in mind that appDataPath is not a String but a char array that you have previously allocated. However, System::String allows you to pass in char arrays in one of its constructors.

Related

C++ override quotes

Ok, so I'm using C++ to make a library that'd help me to print lines into a console.
So, I want to override " "(quote operators) to create an std::string instead of the string literal, to make it easier for me to append other data types to that string I want to output.
I've seen this done before in the wxWidgets with their wxString, but I have no idea how I can do that myself.
Is that possible and how would I go about doing it?
I've already tried using this code, but with no luck:
class PString{
std::string operator""(const char* text, std::size_t len) {
return std::string(text, len);
}
};
I get this error:
error: expected suffix identifier
std::string operator""(const char* text, std::size_t len) {
^~
which, I'd assume, want me to add a suffix after the "", but I don't want that. I want to only use ""(quotes).
Thanks!
You can't use "" without defining a suffix. "" is a const char* by itself either with a prefix (like L"", u"", U"", u8"", R"()") or followed by suffixes like (""s, ""sv, ...) which can be overloaded.
The way that wxString works is set and implicit constructor wxString::wxString(const char*); so that when you pass "some string" into a function it is essentially the same as wxString("some string").
Overriding operator ""X yields string literals as the other answer.

How would I populate a vector with all the elements from a List of type system string while converting it to std::string?

I am trying to understand lambda functions better and would like some example of how I could add to a vector while converting System.String^ to std::string with such a Lambda example (If I am able to).
My current foreach:
List<String^>^ names = //Returning 'System.String' List from C#
for each (System::String^ name in names)
{
std::string convertedString = msclr::interop::marshal_as< std::string >(name);
nameObjects.push_back(MyObject(convertedString, "test"));
}
But I would like to extend it to something like this (My best guess but I am missing the logic to convert each element of "names" to a single string, this is where a Lambda would help me):
std::vector<nameObjects> testObjects{ std::begin(msclr::interop::marshal_as< std::string >(names)), std::end(msclr::interop::marshal_as< std::string >(names)) };
Alright, I figured out a way to make this work...it requires using the obscure cliext classes.
First, create a cliext::vector, there is an overload with takes an IEnumerator.
cliext::vector<String^> v_names(names);
Now, you can use cliext::transform() (not std::transform) to do STL-style iteration, and create MyObject instances with a lambda
std::vector<MyObject> testObjects;
cliext::transform(v_names.begin(), v_names.end(), std::back_inserter(testObjects), [](String^ name)
{
std::string convertedString = msclr::interop::marshal_as< std::string >(name);
return MyObject(convertedString, "test");
});

Changing the text of a C++ CLI label

I am trying to change the text of a label in a C++ CLI program. I need to take a value the the user entered in a textbox, insert that into a short string, then change a label to that string. I have no problem constructing the string, but I am having trouble setting the label to the new string. Here is my code...
std::string v1str = "Phase A: ";
v1str.append(vt2); //vt2 is type str::string
v1str.append(" Vac");
label->Text = v1str;
This is the error message that I'm getting...
Why am I not allowed to pass v1str as the label text setter? How can I pass the string I've constructed to the label text setter?
Label::Text has a type of System::String^, which is a managed .Net string object. You cannot assign a std:string to a System::String^ directly becuase they are different types.
You can convert a std::string to a System::String. However you most likely just want to use the System::String type directly:
System::String^ v1str = "Phase A: ";
v1st += vt2; // or maybe gcnew System::String(vt2.c_str());
v1str += " Vac";
label->Text = v1str;
C++/CLI is not C++, you can't use std::string in there. But you can use C++ within C++/CLI, and convert std::string to and from System::String
//In C++/CLI form:
#include <vcclr.h>
System::String^ clr_sting = "clr_sting";
//convert strings from CLI to C++
pin_ptr<const wchar_t> cpp_string = PtrToStringChars(clr_sting);
//convert strings from C++ to CLI
System::String^ str = gcnew System::String(cpp_string);
//or
std::string std_string = "std_string";
System::String^ str2 = gcnew System::String(std_string.c_str());

How to convert string to LPSTR in WinAPI function which stores output in string

I am trying to store some contents into a string variable by passing it as a parameter in various types of Windows API functions which accepts variable like char *.
For example, my code is:-
std::string myString;
GetCurrentDirectoryA( MAX_PATH, myString );
Now how do I convert the string variable to LPSTR in this case.
Please see, this function is not meant for passing the contents of string as input, but the function stores some contents into string variable after execution. So, myString.c_str( ) is ruled out.
Edit: I have a workaround solution of removing the concept of string and replacing it with something like
char myString[ MAX_PATH ];
but that is not my objective. I want to make use of string. Is there any way possible?
Also casting like
GetCurrentDirectoryA( MAX_PATH, ( LPSTR ) myString );
is not working.
Thanks in advance for the help.
Usually, people rewrite the Windows functions they need to be std::string friendly, like this:
std::string GetCurrentDirectoryA()
{
char buffer[MAX_PATH];
GetCurrentDirectoryA( MAX_PATH, buffer );
return std::string(buffer);
}
or this for wide char support:
std::wstring GetCurrentDirectoryW()
{
wchar_t buffer[MAX_PATH];
GetCurrentDirectoryW( MAX_PATH, buffer );
return std::wstring(buffer);
}
LPTSTR is defined as TCHAR*, so actually it is just an ordinary C-string, BUT it depends on whether you are working with ASCII or with Unicode in your code. So do
LPTSTR lpStr = new TCHAR[256];
ZeroMemory(lpStr, 256);
//fill the string using i.e. _tcscpy
const char* cpy = myString.c_str();
_tcscpy (lpStr, cpy);
//use lpStr
See here for a reference on _tcscpy and this thread.
Typically, I would read the data into a TCHAR and then copy it into my std::string. That's the simplest way.

How to convert String^ to String in C++ CLI?

Whenever I try to directly assign a String variable to another String variable I get error found no suitable conversation.
So is there a way to convert String^ pointer to a non-pointer struct String ?
I want :
System::String a = System::String('X',256);
I don't want :
System::String^ a = %System::String('X',256);
No, there is not, because as Hans pointed out in a comment, System::String is immutable. You cannot assign it. You can only associate a handle with an entirely new System::String object.
BTW
System::String^ a = %System::String('X',256);
is incorrect, it should be
System::String^ a = gcnew System::String('X',256);
Use System::String a('X', 256);.

Resources