|
You haven't hooked event handler for combo box 1. You need to hook event handler for that and do something like:
if(comboBox1->Text == "METAL")
{
this->comboBox2->Items->Clear();
this->comboBox2->Items->AddRange(gcnew cli::array<int>(5) {2, 3, 4, 5, 6});
}
else if(comboBox1->Text = "PLASTIC")
{
this->comboBox2->Items->Clear();
this->comboBox2->Items->AddRange(gcnew cli::array<int>(5) {8, 10, 15});
} You also need to remove code that adds items to combobox2 from InitializeComponent method.
Best wishes,
Navaneeth
|
|
|
|
|
Thanks Navaneeth and Maximilien for your inputs and code!
Haven't yet solved with the given information, by using the Navaneeth code the combobox2 event is not functioning!
private: System::Void comboBox2_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e)
{
if(comboBox1->Text == L"METAL")
{
this->comboBox2->Items->Clear();
this->comboBox2->Items->AddRange(gcnew cli::array< System::Object^ >(5) {L"2", L"3", L"4", L"5", L"6"});
}
else if(comboBox1->Text == L"PLASTIC")
{
this->comboBox2->Items->Clear();
this->comboBox2->Items->AddRange(gcnew cli::array< System::Object^ >(3) {L"8", L"10", L"15"});
}
} Additionally removed the add items code from Combobox2 as suggested by Navaneeth. I think something is still missing in using the code but the logic is correct!.
|
|
|
|
|
As I said in my last post, you still haven't hooked combox1's SelectedIndexChanged event. Hook it and write the code which I provided in that event handler. You don't need to handle second combobox's SelectedIndexChanged .
Best wishes,
Navaneeth
|
|
|
|
|
Wow, you are right! It worked perfectly. Thanks appreciated!
|
|
|
|
|
Problem on charset encoding
obj_db->query("UPDATE PATIENTS_DATA SET FIRST_NAME='flkسؤ' WHERE COD_PATIENT=2 ");
give me a warning:
1>.\globalConfiguration.cpp(151) : warning C4566: character represented by universal-character-name '\u0633' cannot be represented in the current code page (1252)
1>.\globalConfiguration.cpp(151) : warning C4566: character represented by universal-character-name '\u0624' cannot be represented in the current code page (1252)
and the real string in database is flk??
----------edit-----------
here i didn't pointed out the real problem...see my second post
modified on Thursday, October 15, 2009 6:14 AM
|
|
|
|
|
barbetto80 wrote: obj_db->query("UPDATE PATIENTS_DATA SET FIRST_NAME='flkسؤ' WHERE COD_PATIENT=2 ");
You have two Arabic characters at the end of the name, and the compiler is merely warning that the current code page does not support correct representation of them.
|
|
|
|
|
Ok now i pointed out exactly which is my problem ant it's a charset encoding going from std::string to System::String and viceversa:
i query my database and i get the following
string tmp_result_string= // in hexadecimal its value is C2 A3
then i convert using:
String ^LAST_NAME=tmp_result_string.c_str();
when i set last_name_textBox->Text=LAST_NAME;
the visual representation i get in the form is £ which is the ANSII encoding of C2 A3, but what i want is the textbox to display £ which is the utf8 encoding of C2 A3...any help?
tha same problem i have doing the inverted thing getting text from textbox and putting it on database.
modified on Thursday, October 15, 2009 9:22 AM
|
|
|
|
|
ok..i find answer to the problem:
String^ databaseManagedWrapper::unMarshalStringUTF8(string %os) {
char const* buffer = os.c_str();
cli::array<System::Byte>^ a = gcnew cli::array<System::Byte>(os.length());
int i = os.length();
while (i-- > 0) {
a[i] = buffer[i];
}
return System::Text::Encoding::UTF8->GetString(a);
}
now i need the inverse...
string databaseManagedWrapper::MarshalStringUTF8( String ^ s) {
System::Text::UTF8Encoding^ utf8 = gcnew System::Text::UTF8Encoding;
array<Byte>^encodedBytes = utf8->GetBytes(s);
string os="";
for (int i=0;i<encodedBytes->Length;i++) {
os+=encodedBytes[i];
}
return os;
}
modified on Thursday, October 15, 2009 9:19 AM
|
|
|
|
|
System::String is Unicode compatible. You don't need to do any encoding here. Also I think your databaseManagedWrapper::unMarshalStringUTF8 function's implementation is wrong. Here is a version that converts string contains Unicode characters to System::String . std::wstring is used instead of std::string .
String^ UnicodeNativeStringToManagedString(wstring& os)
{
const wchar_t* buffer = os.c_str();
return gcnew String(buffer);
} Here is the function for inverse. You need to work with methods in the Marshal class.
std::wstring UnicodeManagedStringToNative(String^ str)
{
using namespace System::Runtime::InteropServices;
wchar_t* chr = (wchar_t*) Marshal::StringToHGlobalAnsi(str).ToPointer();
std::wstring result(chr);
Marshal::FreeHGlobal(IntPtr(chr));
return result;
}
Best wishes,
Navaneeth
|
|
|
|
|
preamble: i'am using a database that can use UTF8 as best support for multi-language, so i started out from it. UTF8 is a variable-length character encoding for Unicode. The wrapper for the database id written in c++ and uses std::string as variables input method.
Well my problem is that i need a std::string to store to the DB, and not wstring... that's why i create these methods. Maybe i didn't get your help as i see you are creating a wstring...
ps thank you i really appreciate your answer to my various problem in this forum. You are helping me growing up learning and skilling this language
|
|
|
|
|
Well, its easy to convert my code to support std::string . You need char* instead if wchar_t* . Windows uses wchar_t for Unicode and it is 2 bytes wide with UTF-16 encoding. So when programming on windows, it is a better to use wchar_t . wstring is a typedef for basic_string templated using wchar_t .
However, I tried to convert a UTF-8 encoded string to and from managed code. But it never worked until I changed to wstring . Perhaps I may need to investigate more.
Best wishes,
Navaneeth
|
|
|
|
|
I have a function in a wrapper DLL that points to a native function. The native function returns a struct and I am looking for a solution to Marshall the struct to be called by C# Winform app.
The managed function:
M_USB_DEVICE_DESCRIPTOR SXManaged::M_GetDeviceInfo(void)
Where:
M_USB_DEVICE_DESCRIPTOR is a managed struct that is virutally the same as the native struct
SXManaged is the managed class in the wrapper DLL.
Inside the managed function I call the native function:
usb_dd = umc->GetDeviceInfo();
Where:
usb_dd is a native struct variable of type USB_DEVICE_DESCRIPTOR. The members of that are very blittable - bytes and unsigned short.
umc is an object that is a pointer to the native class that holds native function GetDeviceInfo()
I can't leave the return type as a native struct type as it's being called in C#. I've looked as far as I can to try and see how to do this but coming up short.
Any help greatly appreciated.
Al
Jer 29:11
|
|
|
|
|
Native struct and managed struct is different. Your best bet would be to create a managed class with necessary details and fill it with the values from native function. This instance can be consumed from C#.
Best Wishes,
Navaneeth
|
|
|
|
|
The "managed" function shown in the illustration IS from a managed class.
Jer 29:11
|
|
|
|
|
Well, your return type is M_USB_DEVICE_DESCRIPTOR which is a managed type, right? If yes, what is the problem ate you facing in using it from C#?
|
|
|
|
|
Hi,
I have a managed version of the struct on the C# side which is easy because the struct contains primitive members. The issue is marshalling the struct from the managed function to the native function that is called by the managed one.
Jer 29:11
|
|
|
|
|
I am migrating a C++ application to .NET.
In C++ ,I have an template class which uses some ATL library classes
for eg.
template< class T >
class MyBaseClass:
public IConnectionPointContainerImpl<t>,
public IPersistStorageImpl<t>,
public IPersistPropertyBagImpl<t>,
{
}
Now i need to use this call in my new C# .net project where my new .NET call will get derive from above MyBaseClass .
Please let me know how can i archive this ???
Is this possible to use a template class which uses some ATL libraray classes directly in C# ?
`chiman
|
|
|
|
|
There is no straightforward method to use template classes in other CLI languages like C#. This is because of the difference in how C++ templates and CLI generics works. C++ templates will be instantiated at compile time and CLI generics will be on runtime. C++/CLI also supports managed templates, but unfortunately it is not portable to other CLI languages.
If you want to use inheritance, you may need to create managed classes that calls the template class for each known type. Like MyBaseClassInt which use MyBaseClass<int> etc. This will not be the correct method as you will have class explosion when you have several types to be used.
Prefer composition over inheritance. In such case, this can be easily solved by providing a factory class which checks the type and instantiates respective template instance. Any new types can be easily added to the factory method without recompiling the whole application. We are taking the capability of C++/CLI to mix generic and template type parameters. To see how this can be done, consider the following code:
template< class T >
class MyBaseClass:
public IConnectionPointContainerImpl,
public IPersistStorageImpl,
public IPersistPropertyBagImpl,
{
public:
void DoSomething();
};
generic<typename T>
public interface class IManagedBase
{
public:
void DoSomething();
};
template<typename T>
ref class MyBaseClassWrapper : IManagedBase<T>
{
public:
virtual void DoSomething()
{
MyBaseClass<T> native;
native.DoSomething();
}
};
public ref class NativeObjectBuilder
{
public:
generic<typename T> virtual IManagedBase<T> GetBaseObject()
{
if(T::typeid == int::typeid)
return (IManagedBase<T>^) gcnew MyBaseClassWrapper<int>();
else if(T::typeid == double::typeid)
return (IManagedBase<T>^) gcnew MyBaseClassWrapper<double>();
}
}; From C#, you can use it like
NativeObjectBuilder objectBuilder = new NativeObjectBuilder();
IManagedBase<int> ib = objectBuilder.GetBaseObject<int>();
ib.DoSomething(); This trick works well for primitive types. But for other complex types, you may need to write wrappers and use it.
Hope that helps
PS: I wrote this code directly on CP editor and you may get some minor syntax error.
modified on Saturday, October 10, 2009 1:03 AM
|
|
|
|
|
Hi all,
I want convert System::String* str[] to const char* chars[] array for one of mu application!
System::String* str[] is a parameter to function. And this function is called from c#
any have idea how this conversion happens?
|
|
|
|
|
SaveTigers wrote: System::String* str[]
Does that even compile? I don't think you can write System::String* str[] . Do you want to convert managed string to const char* ?
|
|
|
|
|
Hey thanks for reply Navaneeth,
Got it!
I am doing something like this
char *abc[100];
for(int i = 0; i < ss->Count; i++)
{
abc[i] = (char*)(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(ss[i])).ToPointer();
}
the above code is working file where ss is System::String* ss[] as function argument
I spend 2 days to get it working!!!
Now the problem is with System::Double dd[][] I want to convert it to double[][] used in Unmanaged C++
how should I use System::Double dd[][] in managed C++
I am getting this sort of error
error C2440: 'initializing' : cannot convert from 'double __gc *' to
'double'
I tried many permutation but could n0t get through!!
Navaneeth any idea how to do this conversion!
Thanks in advance!
|
|
|
|
|
Ahh you are using old syntax. In the new C++/CLI syntax, System::String* is invalid. Old syntax is obsolete and don't use it if you have a compiler that supports new syntax. Here is how you use 2 * 2 double array in C++/CLI.
array<double, 2>^ doubleArray = gcnew array<double, 2>(2, 2);
doubleArray[0 , 0] = 10;
doubleArray[0 , 1] = 11;
doubleArray[1 , 0] = 12;
doubleArray[1 , 1] = 13;
|
|
|
|
|
Hey thanks Navneeth!
Actually what I am trying to do is...
I have on Static DLL which I am exposing to c# using Managed C++ library, so that I can use it directly, will not have overhead of registering and de-registering (id I develop COM DLL to expose static DLL functionality to C# client)
Now, the problem is I am Passing "System::Double dd[][]" as argument to Managed C++ as a function argument and I want to convert the passed double array to array used in the function(so that I can forward it to Static DLL), However while doing
doubleArray[0 , 0] = dd[0][0];
I am clueless about how to get rid of this error
Can I use this code provided by you
array<double, 2>^ doubleArray = gcnew array<double, 2>(2, 2);
doubleArray[0 , 0] = 10;
doubleArray[0 , 1] = 11;
doubleArray[1 , 0] = 12;
doubleArray[1 , 1] = 13;
or there is any other way to type cast?
Thanks in advance Navneeth!!
|
|
|
|
|
You want to accept managed array as parameter and pass that to a native function that expects a native double array, right? Here is how you do it:
void Function(array<double, 2>^ doubleArray)
{
double nativeArray[2][2];
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
nativeArray[i][j] = doubleArray[i , j];
}
}
} I reiterate, please avoid using the obsolete syntax and use C++/CLI style syntax. Compile with /clr switch rather than /clr:oldsyntax .
|
|
|
|
|