Having been a Borland C++ chappie over the years, I've basically created my own RS232 object and dumped it in a seperate Thread, which then directly calls a static function in the forms thread, which then updates the the main forms bit & bobs.
Problems occured when the RS232 object starts pummeling data into the function before it is cleared etc, and then all goes bonkers!
I obviously had broken the cardinal rule "Thou shalt not interact with a control's properties from a thread other than the one that created the control."
In comes VC++ Express and a serialPort object, written by someone who knows what they are doing...
To cut to the chase:
I need to pass the recieved buffer of the serialPort object back to the form on which it was created, when I try the following:
private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {String^ myString;
myString = serialPort1->ReadExisting() ;
RichTextBox1->AppendText(myString);
}
I just get the message
"An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
Additional information: Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on."
I've looked at the BackgroundWorker component, but from the examples, (which all seem to be in VB) find it really difficult to translate over to C++. Also using express from BCB4 feels like I'm learning it all again from scratch.
Any help would be great, Thanks in advance.
David

Updating a form from a serialport component.
NemanjaTheLost
Hello Juha.
Do you know how to create event handlers for events raised by a Windows Form or component
Eg. do you know how to set a Label's Text when the user clicks a button
moobah
Paying attention to the case got it complied and run. However, I got a lot of words "data". Ok, my problems are most likely my background, unfamiliarity of the system and the framework and my unability to find or understand the help. For the uninitiated, a line of code about event handler does not help much without the big picture and a (even a skeleton of) working application... But I really find this more difficult in my 25 years of programming to get a "serial device hello world" program to run than about any other system.
This is what the application should be doing. Sounds simple enough an a conference table:
when a character arrives, examine it and the buffer content;
if not enough data yet
store the character in buffer
else
figure out the device status from the buffer content and update the status form;
On the form, click some buttons, control data gets sent.
Can you please show (or point me to a document showing) how to receive a character and pass it to a thread that has access to the main form (writing wou be nice, too...)
(I understand Im asking basic things, but perhaps you can get an insight to a veteran programmers mind here. In my other thread, I ask about the buffer. In old days (and embedded world today) I would write something like static char buffer[xx] to get a storage space for the buffer. Now I am in a stange object orineted NET framework, and I don't even know these fundamental issues, like where global buffers are placed. Somehow, I have a feeling that there should be none...)
Thank you for your insight!
Juha
ndhuy
Are you having trouble declaring the delegate or using it
Have you used the qsort/bsearch function before
cyn_atl
This does not work. The line
RichTextBox1->AppendText(myString);
does not compile (undeclared identifier), even thoug there is earlier VC++ generated line
private: System::Windows::Forms::RichTextBox^ richTextBox1;
There is discussion about the issue at
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=22421&SiteID=1
where Anthny Wong shows how to do this in C#, but this .NET newbie can't translate the solution to C++.
I am really frustrated, please help! Visual programming is advertised to be easy. If that is true, my serial hello world would be here after two days or so!
Zappos
Are you using a beta of Visual C++ Somebody mentioned that the beta docs didn't have a C++ code example for BackgroundWorker (this has since changed for the final release, http://msdn2.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx has an example in VB/C#/C++).
In the meantime, richTextBox has an Invoke method which you can use to make cross thread calls to a delegate of your choice. This requires you to know how to create and use delegates.
jdegaetani
Yes, that is the delightful part in visual programming:
private: System::Void button1_Click_1(System::Object^ sender, System::EventArgs^ e) {
if (label1->Text == "B")
label1->Text = "A";
else
label1->Text = "B";
}
Building user interfaces just can't become easier than this! The problem with serial ports is that the event handlers run in a different thread. At a serial port event, the labels and other controls of the GUI are not accessible. I just can't figure out how to raise an event in one thread and pass data to it from another thread, nor have I found an beginner's explanation. I understand the idea of what is going on, but can't handle the issue myself, at least not in my first real life VC++ program. :-(
In http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=22421&SiteID=1 Anthony shows hw to handle the issue in C#, but I just can't translate the solution to C++, can't find a good enough explanation of the concept and correct syntax, and my two books and two days of reading helps and searching the net hasn't got me any closer to solution.
Frustrated,
Juha
scottportraits
Please note that C++ is case sensitive. That is the declaration is richTextBox1 but you are trying to use RichTextBox1. The "R" should be in small case.
Hope this is what is causing the error!
Thanks, Ayman Shoukry VC++ TeamROBSR
I've updated this thread because it seems I've solved the problem! :)
My solution was to replace this line:
pDelegate->Invoke("Invoked");
with these three lines:
System::IAsyncResult^ invokeResult;
invokeResult = GlobalObjects::myForm->textBox1->BeginInvoke(pDelegate, "Invoke");
GlobalObjects::myForm->textBox1->EndInvoke(invokeResult);
/Johannes
MyNameisMud
I've also a problems with threads. I've a callback function locked to the midiInOpen function.
In that function I want to set a TextBox in my Form1. This is a simplified example:
[code]
delegate void MyDelegate(String^ _str);
void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
if(GlobalObjects::myForm->textBox1->InvokeRequired){
gcnew MyDelegate(GlobalObjects::myForm->textBox1, &TextBox::Text::set);pDelegate->Invoke("Invoked");
}
//if else}//callback function
[/code]
Maybe you say this code will work but still I got this error-message:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
Additional information: Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on.
HELP!