none
visual 2010 C++ form serialport 問題 part3 RRS feed

  • 問題

  • 我想嘗試看看用DataReceived 去接serialport的資料

    所以我看了之前版大貼給我的文
    http://www.dotblogs.com.tw/billchung/archive/2012/01/30/67096.aspx

    我在想辦法把內文裡這段,轉成C++ 我才能測試

    private void comport_DataReceived(Object sender, SerialDataReceivedEventArgs e)
    {
        if ((sender as SerialPort).BytesToRead > 0)
        {
            try
            {
                Byte[] buffer = new Byte[1024];
                Int32 length = (sender as SerialPort).Read(buffer, 0, buffer.Length);
                Array.Resize(ref buffer, length);
                Display d = new Display(DisplayText);
                this.Invoke(d, new Object[] { buffer });
            }
            catch (TimeoutException timeoutEx)
            {
                //以下這邊請自行撰寫你想要的例外處理
            }
            catch (Exception ex)
            {
                //以下這邊請自行撰寫你想要的例外處理
            }
        }
    }

    BTW

    1.我已經有成功用while迴圈的方式做到我要的功能,但我是用比較不安全的方式跳過UI顯現的
    2.內建backgroundWorker的部分,也有成功了,但因為我在backgroundWorker1_RunWorkerCompleted裡

    用了while迴圈,所以整個畫面會卡在那,但程式是正常執行的,但我不確定會不會影響到其他地方

    或者是說,我應該用while迴圈包
    this->backgroundWorker1->RunWorkerAsync();才對


    所以..想知道真正的委派怎麼寫..

    我摸良心= =
    我真的很盡力轉,也很認真查資料,後面那兩段委派的部分我不太懂他意思

    也不知道怎麼轉,而且還不知道前面轉的對還錯

    另外MSDN那一邊的範例,我有用他的範例用正常委派的方式顯示出字在textbox上

    我現在的問題就是要『怎麼用委派的方式 把serialport抓的資料顯示出來』

    這一點我想法轉不過來

    如果版大覺得我還是沒耐心看完,我承認自己底子沒打好..
    請求協助..感謝耐心看完..

    private:
    static void DataReceivedHandler(Object^ sender,SerialDataReceivedEventArgs^ e)
        {
    int size = 1024;
    SerialPort^ port;
    if ( port->BytesToRead>0 )
    {
    try
    {
    array<unsigned char>^ managedBuf = gcnew array<unsigned char>(size);
    Int32 length = port->Read(managedBuf, 0, size);
    Array::Resize(managedBuf, size);
    //Display d = new Display(DisplayText);<------------------------------
    //this.Invoke(d, new Object[] { buffer });<-----------------------------
    }
    catch (TimeoutException^)
    {
    ;//以下這邊請自行撰寫你想要的例外處理
    }
    catch (Exception^)
    {
    ;//以下這邊請自行撰寫你想要的例外處理
    }
    }











    • 已編輯 Ervin6285 2014年10月14日 下午 06:54
    2014年10月14日 下午 04:28

解答

  • http://msdn.microsoft.com/zh-tw/library/c320cx3h.aspx

    請看如何在 C++/CLI 使用事件就是了.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 Ervin6285 2014年10月18日 下午 04:45
    2014年10月16日 下午 12:48

所有回覆

  • 我在 visual 2010 C++ form Threading 要如何寫?? 貼給你的 MSDN 文件連結不就有說在 C++ 怎麼做跨執行緒委派了嗎 ?


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年10月15日 上午 07:43
  • (1)
    恩恩 我這樣問好了

    這是上面的部分delegate void SetTextDelegate(String^ text);

    這是下面的部分
    SetTextDelegate^ d = gcnew SetTextDelegate(this, &Form1::SetText);

    this->Invoke(d, gcnew array<Object^> { text });

    因為我不懂這兩行的意思,
    單純把程式貼上是可以顯示他的範例結果
    我要怎麼改寫成顯示"數值"

    (2)
    2.內建backgroundWorker的部分,成功了,但因為我在backgroundWorker1_RunWorkerCompleted裡

    用了while迴圈,所以整個畫面會卡在那,但程式是正常執行的,但我不確定會不會影響到其他地方

    或者是說,我應該用while迴圈包
    this->backgroundWorker1->RunWorkerAsync();才對嗎?

    2014年10月15日 下午 01:46
  • (1) 把數值轉成 string 再傳進來不就行了 ?

    (2) BackgroundWorker 的 RunWorkerCompleted 事件委派函式已經回到 UI 執行緒, 所以你在這裡用迴圈會影響 UI 的回應

    一般迴圈只會用在 DoWork 事件委派函式內. (因為 DoWork 委派函式才是在另一個執行緒執行)

    補充: 參考 http://www.sourcecodester.com/tutorials/cc/6583/c-tutorial-using-backgroundworker-component-ccli.html


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。




    2014年10月15日 下午 02:09
  • (1)我想先釐清一下我的理解有沒有錯

    1-1 delegate void SetTextDelegate(String^ text); //這句是在宣告SetTextDelegate是一個委派的函數?

    1-2 SetTextDelegate^ d = gcnew SetTextDelegate(this, &Form1::SetText);//這行是在說,建立一個委派的實體物件d,而這個d就指向了SetText這個位址?

    1-3 this->Invoke(d, gcnew array<Object^> { text }); //那這行裡的gcnew array<Object^> { text } 是什麼意思?

    ----------------------------------------------------------------------------------------------------------------------
    (2)


    我一開始以為,可以這樣寫.. 
    delegate void SetTextDelegate(); <---------------不過當然是錯了,因為這樣不符合委派的宣告方式 

    private: System::Void button8_Click(System::Object^  sender, System::EventArgs^  e) {
    thr2 = gcnew Thread(gcnew ThreadStart(this, &Form1::testb));
    thr2->Start();
     //Form1::CheckForIllegalCrossThreadCalls = false;
    }

    private:void testb(void)
    {
    this->SetText1();<---------------------我單純的想執行一個迴圈去讀取資料
    }

    private:void SetText1()
    {
    unsigned char k[16];
    while(1)
    {
    if(this->MyserialPort->IsOpen)
    {
     // Reset the text in the result label.
     this->textBox1->Text = String::Empty;
    try
    {
     for(int j=0; j<16; j++)
     {
      k[j] =this->MyserialPort->ReadByte();
     }
     this->textBox5->Text = System::Convert::ToString(k[0]);
     this->textBox6->Text = System::Convert::ToString(k[1]);
     this->textBox7->Text = System::Convert::ToString(k[2]);
     this->textBox8->Text = System::Convert::ToString(k[3]);
     this->textBox9->Text = System::Convert::ToString(k[4]);
     this->textBox10->Text = System::Convert::ToString(k[5]);
     this->textBox11->Text = System::Convert::ToString(k[6]);
     this->textBox12->Text = System::Convert::ToString(k[7]);
     this->textBox13->Text = System::Convert::ToString(k[8]);
     this->textBox14->Text = System::Convert::ToString(k[9]);
     this->textBox15->Text = System::Convert::ToString(k[10]);
     this->textBox16->Text = System::Convert::ToString(k[11]);
     this->textBox17->Text = System::Convert::ToString(k[12]);
     this->textBox18->Text = System::Convert::ToString(k[13]);
     this->textBox19->Text = System::Convert::ToString(k[14]);
     this->textBox20->Text = System::Convert::ToString(k[15]);
     // this->progressBar2->Value = 100;
    }
    catch(TimeoutException^)
    {
    this->textBox1->Text="Timeout Exception";
    }
      }
    }

    }

    以上是我目前的情況,我該怎麼做修改才正確呢?

    ----------------------------------------------------------------------------------------------------------------------

    (3)

    BackgroundWorker 的 RunWorkerCompleted 事件委派函式已經回到 UI 執行緒,原來如此這樣我懂了

    但在這我想問一下
    backgroundWorker1->RunWorkerAsync(); 因為我沒有在RunWorkerAsync();裡輸入數值

    他就直接去執行了RunWorkerCompleted 而不是DoWork

    所以我必須輸入一個數值在RunWorkerAsync(10);<---像這樣,才能觸發DoWork嗎?

    謝謝你耐心看完~

    2014年10月16日 上午 06:03
  • (1-1)  宣告一個委派型別

    (1-2) 宣告一個型別為 SetTextDelegate 的變數, 並將其函式指標指向本執行個體的 Form1::SetText 方法

    (1-3) 因為 Invoke 方法有兩個參數, 其中第二的參數 Object[] 就等於要傳送 SetText 方法的參數使用.

    (2) 請參考

    如何:定義和使用委派 (C++/CLI)

    delegate (C++ 元件擴充功能)

    (3) 你有將某個方法委派給 DoWork 事件嗎 ?

    如何:在 C++/CLI 中使用事件


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年10月16日 上午 09:20
  • (1-1)&(1-2)&(1-3)嗯嗯好的,那這部分我懂了 感謝~

    (2)
    如何:定義和使用委派(C++/CLI)這網頁我打不開 

    我有再做修改,編譯沒有問題,但我一執行,就會跑出類型 "System.StackOverflowException' 的未處理例外狀況發生於 serialports test.exe" 的錯誤,我不知道哪裡打錯了
    ---------------------------------------------------------------------------------------------------------------------
    上面部分如下

    delegate void SetTextDelegate1();

    public: void SetText1()
    {
        SetTextDelegate1^ s= gcnew SetTextDelegate1(this,&Form1::SetText1);
    s->Invoke();

    unsigned char k[16];

    while(1)
    {
    if(this->MyserialPort->IsOpen)
    {
     // Reset the text in the result label.
     this->textBox1->Text = String::Empty;
    try
    {
     for(int j=0; j<16; j++)
     {
      k[j] =this->MyserialPort->ReadByte();
     }
     this->textBox5->Text = System::Convert::ToString(k[0]);
     this->textBox6->Text = System::Convert::ToString(k[1]);
     this->textBox7->Text = System::Convert::ToString(k[2]);
     this->textBox8->Text = System::Convert::ToString(k[3]);
     this->textBox9->Text = System::Convert::ToString(k[4]);
     this->textBox10->Text = System::Convert::ToString(k[5]);
     this->textBox11->Text = System::Convert::ToString(k[6]);
     this->textBox12->Text = System::Convert::ToString(k[7]);
     this->textBox13->Text = System::Convert::ToString(k[8]);
     this->textBox14->Text = System::Convert::ToString(k[9]);
     this->textBox15->Text = System::Convert::ToString(k[10]);
     this->textBox16->Text = System::Convert::ToString(k[11]);
     this->textBox17->Text = System::Convert::ToString(k[12]);
     this->textBox18->Text = System::Convert::ToString(k[13]);
     this->textBox19->Text = System::Convert::ToString(k[14]);
     this->textBox20->Text = System::Convert::ToString(k[15]);
     // this->progressBar2->Value = 100;
    }
    catch(TimeoutException^)
    {
    this->textBox1->Text="Timeout Exception";
    }
      }
    }

    }

    ---------------------------------------------------------------------------------------------------------------------

    下面部分

    private: System::Void button8_Click(System::Object^  sender, System::EventArgs^  e) {
    this->thr2 = gcnew Thread(gcnew ThreadStart(this, &Form1::testb));
    this->thr2->Start();
     //Form1::CheckForIllegalCrossThreadCalls = false;
    }

    private:void testb(void)
    {
         this->SetText1();  
    }

    ---------------------------------------------------------------------------------------------------------------------
    (3)我不懂你的意思,我是直接將要執行的code放進去DoWork,像下面這樣

    private: System::Void backgroundWorker1_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e) 
    {
      unsigned char k[16];
    while(1)
    {
    if(this->MyserialPort->IsOpen)
    {
     // Reset the text in the result label.
     this->textBox1->Text = String::Empty;
    try
    {
     for(int j=0; j<16; j++)
     {
      k[j] =this->MyserialPort->ReadByte();
     }
     this->textBox5->Text = System::Convert::ToString(k[0]);
     this->textBox6->Text = System::Convert::ToString(k[1]);
     this->textBox7->Text = System::Convert::ToString(k[2]);
     this->textBox8->Text = System::Convert::ToString(k[3]);
     this->textBox9->Text = System::Convert::ToString(k[4]);
     this->textBox10->Text = System::Convert::ToString(k[5]);
     this->textBox11->Text = System::Convert::ToString(k[6]);
     this->textBox12->Text = System::Convert::ToString(k[7]);
     this->textBox13->Text = System::Convert::ToString(k[8]);
     this->textBox14->Text = System::Convert::ToString(k[9]);
     this->textBox15->Text = System::Convert::ToString(k[10]);
     this->textBox16->Text = System::Convert::ToString(k[11]);
     this->textBox17->Text = System::Convert::ToString(k[12]);
     this->textBox18->Text = System::Convert::ToString(k[13]);
     this->textBox19->Text = System::Convert::ToString(k[14]);
     this->textBox20->Text = System::Convert::ToString(k[15]);
     // this->progressBar2->Value = 100;
    }
    catch(TimeoutException^)
    {
    this->textBox1->Text="Timeout Exception";
    }
      }
    }
    }

    謝謝你耐心看完~

    2014年10月16日 下午 12:38
  • http://msdn.microsoft.com/zh-tw/library/c320cx3h.aspx

    請看如何在 C++/CLI 使用事件就是了.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    • 已標示為解答 Ervin6285 2014年10月18日 下午 04:45
    2014年10月16日 下午 12:48
  • 恩恩 我再嘗試看看 謝謝版大
    2014年10月18日 下午 04:45