|
Hi,
I've been working with the property grid for a while (I hate that thing) trying to create dynamic, nested objects in runtime; after a bit of work have got it to work. What I did was put ParameterGrids within ParameterGrids, this allowed my Prop Grid to have as many expandable objects within expandable objects as I want. And by using custom type converts I've been able to name them whatever I want. The only issue I'm still faced with that each one of these ParameterGrid Items in the grid has the button which allows the user to edit the collection (like you would see in the designer on, for instance, a tool bar items collection field). This button pops up a dialog which lets the user edit the collection, adding or removing objects. This I do NOT want. Is there a type converter, property macro any other way to disable or remove this collection editing button? Thanks for the help!
|
|
|
|
|
Hello,
I am trying to launch background processes using System.Diagnostic.Process API . It launches every process e.g notepad.exe, all native processes and all windows form base processes. But this unable to launch pure managed GUI less assemblies. Task Manager not showing those assemblies listed in its list as seperate process. Niether exception occure nor any error code returned.
Is there any other way to launch background processes on demand using Process.Start for pure managed assemblies properly visible even for task manager
Regards Usman
|
|
|
|
|
Hello,
I am facing an exception in C++/CLI while dynamically loading assembly which itself an EXE created in C++/CLI managed mode using Assembly.Load. It successfully loads a dll assembly, but fails to load EXE assembly and generates following exception:
An unhandled exception of type 'System.IO.FileLoadException' occurred in TestManager.dll
Could not load file or assembly 'testAssembly, Version=1.0.3836.39802, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Attempt to load an unverifiable executable with fixups (IAT with more than 2 sections or a TLS section.) (Exception from HRESULT: 0x80131019)
Note : TestManager.dll itself managed dll and loaded into another CLR process in CLI and trying to load EXE assembly as seperate process but fails and generates about exception.
Regards
Usman
|
|
|
|
|
Hi,
Please make sure that you have correct version of testAssembly specifed in the manifest for EXE fiel that try to load this assembly. Maybe instead of loading specific version you could specify version 1.0.* which will load latest version of assembly that has Release version 1.0.
Other option is just trigger full recompilation of entire project. This could help if compiler messed-up with version which it automatically assigned.
This error means that you try load incorrect version of assembly testAssemby. CLI will deny load version of assembly other then 1.0.3836.39802 in you case. If your testAssembly has version 1.0.3836.39802 then this error could indicated that one of dependencies that have assembly testAssembly could not be loadede. Navigate through chain of InnerException properties to diagnose which assembly exacly could not be loaded.
Hope this helps.
|
|
|
|
|
I am using C# class library in C++ using C++/CLI mode.
I have declared a class member as follows
gcroot <<jobresults^>> m_objTest;
And the following call gives compilation error
m_myInterface->GetResults(m_objTest);
Error 1 error C2664 :
'cannot convert parameter 1 from 'gcroot<T>' to 'System::IO::Stream ^%'
The following is the prototype of GetResults function in C#
void GetResults(ref JobResults jobRes);
Help me to solve this error.
modified on Monday, June 28, 2010 12:35 AM
|
|
|
|
|
A gcroot is not a System::IO::Stream ^ . You need to convert your object into the correct type required by the function.
It's time for a new signature.
|
|
|
|
|
Before passing it to the by-ref function, you need to use a temp variable. Example:
ref class Derived : Base
{
String^ _s;
public:
Derived(String^ s):_s(s){}
};
void Foo(Derived^% derived)
{
derived = gcnew Derived("From Foo");
}
class Native
{
gcroot<Derived^> _derived;
public:
void Bar()
{
_derived = gcnew Derived("Before");
Derived^ tmp = _derived;
Foo(tmp);
_derived = tmp;
}
};
|
|
|
|
|
Yes Exactly i did the same. So there is no option to pass gcroot object as reference to other function?
|
|
|
|
|
As far as I know, no. Remember that the by-ref language behavior is implemented at runtime by the CLR whereas the gcroot is an unmanaged wrapper class. So unless the callee is a C++/CLI method expecting a gcroot argument, what you want to do is quite impossible (in my opinion anyway).
|
|
|
|
|
Thanks for your information.
|
|
|
|
|
I am creating a custom combobox derived from CComboBox. What I need is to put the image on the arrow button of the combo box. Please help me in this regards.
Thanks
modified on Thursday, June 24, 2010 3:08 AM
|
|
|
|
|
some line of code of what you have done till now would help
modified on Friday, June 25, 2010 7:48 AM
|
|
|
|
|
I am building a program which is to run time-domain simulations. I made a form with a start button which kicks-off the simulation. I now want to make a button to stop the simulation.
I made a boolean which is set to true when the simulation is started, and the simulation runs in a while loop as long as this boolean is true. Then I made a stop button which sets the boolean to false. However, when I click the stop button nothing happens. It seems as if this event is only dealt with after the simulation is ended.
Does anyone have an idea on how to deal with this? Any idea is very welcome!
ATJA
|
|
|
|
|
you should not run your simulation on the main thread, as it blocks the GUI and prevents all interactions (an event handler should last no more than 20 milliseconds).
You need another thread to perform long-wielding calculations; a BackgroundWorker may be handy as you likely want your GUI to be updated while progress is made and new results become available. Look for an example in MSDN.
|
|
|
|
|
Luc,
Thanks for your answer! I'm trying to use a backgroundworker, but I'm having some trouble with getting it to work. I followed the example on MSDN, and first put:
System::ComponentModel::BackgroundWorker^ worker
in the code. Then I try to initialize the worker by:
worker->DoWork += gcnew DoWorkEventHandler(this, &form::worker_doWork);
But now I get an error on this last line while running the program: "Object reference not set to an instance of an object". Any idea what the problem could be?
ATJA
|
|
|
|
|
I guess you'd get that if you don't have executed a worker=gcnew BackgroundWorker somewhere before.
|
|
|
|
|
Thanks, it works now!
However, there is one very strange thing. When I compile the code everything works, but in debug mode nothing happens if I click the button that triggers the backgroundworker events. Any idea what this problem could be?
|
|
|
|
|
Arjen Tjallema wrote: Any idea what this problem could be?
without seeing the relevant code, no.
|
|
|
|
|
That makes sense... Here is the relevant part of my code.
I made a BackgroundWorker called simWorker, and a start and stop button which should, obviously, start and stop my simulation. Starting it works fine when I compile the code, but nothing happens when I run in debug mode. The stop button is not working yet, I'm still finding out how to deal with that.
Hope you can think of something to make this also run in debug mode, that would make life much easier.
Thanks!
namespace uDP2 {
public ref class DPSim : public System::Windows::Forms::Form
{
static clModel^ model = gcnew clModel;
public:
DPSim(clModel^ mdl)
{
InitializeComponent();
model = mdl;
InitializeSimWorker();
}
protected:
~DPSim()
{
if (components)
{
delete components;
}
}
private: System::ComponentModel::IContainer^ components;
protected:
private:
System::ComponentModel::BackgroundWorker^ simWorker;
void InitializeSimWorker(){
simWorker = gcnew BackgroundWorker;
simWorker->DoWork += gcnew DoWorkEventHandler( this, &DPSim::simWorker_DoWork );
}
void simWorker_DoWork( Object^ sender, DoWorkEventArgs^ e ){
BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);
e->Result = simulate(model, worker, e);
}
#pragma region Windows Form Designer generated code
{
}
#pragma endregion
private: clModel^ simulate(clModel^ model, BackgroundWorker^ worker, DoWorkEventArgs^ e){
return model;
}
private: System::Void butStart_Click(System::Object^ sender, System::EventArgs^ e) {
simWorker->RunWorkerAsync(model);
}
private: System::Void butStop_Click(System::Object^ sender, System::EventArgs^ e) {
model->state->modelRunning = Convert::ToInt32(0);
}
};
}
|
|
|
|
|
Hi,
that code is not really OK. I do not know what is the exact cause of your symptoms, however I'll offer some comments that should bring you closer to success:
1.
I would defer all initialization of the simulator till the start button is pressed. You don't need a BGW if no simulation is ordered.
2.
I would then also disable the start button (and enable the stop button) for as long as the simulator is running.
3.
a BGW needs more initialization; have a look at one of the examples, e.g. here[^]. You probably want to include (this is C#, change syntax as required):
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
4.
You should provide a RunWorkerCompleted handler; that is where the results become available, the exceptions of DoWork are available (through e->Error), and the start button could be re-enabled (and the stop button disabled again).
5.
You could use the built-in BGW cancellation mechanism, although having your own could probably be equally good.
6.
FYI: other threads are not allowed to touch GUI parts, however both the ProgressChanged and RunWorkerCompleted handlers run on the main thread (assuming you created the BGW on the main thread), and so are allowed to modify the GUI. Your model might take advantage of that.
7.
a BGW uses a ThreadPool thread, i.e. its thread gets recycled automatically, you don't need to worry about that. Use a new BGW each time! Maybe (your symptom description was a bit cryptic here) together with (1) above, that is what caused your discomfort in compiling/running/debugging.
|
|
|
|
|
Thanks a lot for your comments! I've used them in my code, but the problem with debugging is still not solved.
My start button contains the following code:
simWorker = gcnew BackgroundWorker;
simWorker->WorkerSupportsCancellation = true;
simWorker->WorkerReportsProgress = true;
simWorker->DoWork += gcnew DoWorkEventHandler(this, &uDP2::DPSim::simWorker_DoWork);
simWorker->ProgressChanged += gcnew ProgressChangedEventHandler(this, &uDP2::DPSim::simWorker_ProgressChanged);
simWorker->RunWorkerCompleted += gcnew RunWorkerCompletedEventHandler(this, &uDP2::DPSim::simWorker_RunWorkerCompleted);
butReset->Enabled = false;
butPause->Enabled = true;
butStart->Enabled = false;
simWorker->RunWorkerAsync(model);
When I compile and run the program this works fine, the last line in this code runs the actual model. However, when I step through the code in debug mode the last line seems to be skipped; it passes this line without running the model. I don't have a clue what's going on here, this seems to be very strange to me...
Update:
It seems that the code which updates the data on my Graphical User Interface in each timestep causes the problem. I have an "updateGUI" function which is called in each timestep from the simulation, which is again called by RunWorkerAsync. The updateGUI function contains:
lblTime->Text = Convert::ToString(Math::Round(*model->state->t,2));
txtX->Text = Convert::ToString(Math::Round(model->state->eta[0,0],2));
txtY->Text = Convert::ToString(Math::Round(model->state->eta[1,0],2));
txtPsi->Text = Convert::ToString(Math::Round(model->state->eta[5,0],2));
lblWindDirSim->Text = Convert::ToString(*model->environment->windDir / Math::PI * 180);
If I comment this out the code runs fine in debug mode, otherwise it doesn't. Any idea what the problem could be?
modified on Thursday, June 24, 2010 5:41 AM
|
|
|
|
|
I see two possibilities:
1.
you did not follow my earlier point #6, so the offending code is in DoWork, rather than in the ProgressChanged handler.
2.
that code is throwing an exception; put it all in a try-catch and look at Exception.ToString().
BTW: your RunWorkerCompleted should check e.Error, which would contain any uncaught exception that has occured while the BGW was running.
|
|
|
|
|
Luc,
I found out I did indeed not follow your point #6, I guess I didn't completely understand.
Now it works fine, thanks a lot for all your quick and useful help!!
Regards,
ATJA
|
|
|
|
|
You're welcome.
You may want to read this[^] to know more about GUI and threads.
|
|
|
|
|
That indeed looks interesting for what I'm doing, I'll have a look at it.
Thanks again!
|
|
|
|
|