0

スレッド内のリストボックスに項目を追加できる必要があります。コードは以下のとおりです。

1. ref class Work
2. {
3. public:
4.  static void RecieveThread()
5.      {
6.      while (true)
7.      {
8.          ZeroMemory(cID, 64);
9.          ZeroMemory(message, 256);
10.         if(recv(sConnect, message, 256, NULL) != SOCKET_ERROR && recv(sConnect, cID, 64, NULL) != SOCKET_ERROR)
11.         {
12.             ID = atoi(cID);
13.             String^ meep = gcnew String(message);
14.             lbxMessages->Items->Add(meep);
15.             check = 1;
16.         }
17.     }
18. }
19. };


Error: a nonstatic member reference must be relative to a specific objectオンラインでエラーが表示され14.
ます それを可能にする方法はありますか? そのスレッドの外で使用しようとするとString^ meep; 、何も含まれないためです。スレッド内ではなくスレッド内で使用すると、完璧に機能します。そのメッセージをリストボックスに追加できる必要があります。誰かが助けてくれれば幸いです。

4

2 に答える 2

0

1つの方法は、ParameterizedThreadStartデリゲートでSystem :: Threadを使用することです。これにより、オブジェクト(この場合はlbxMessages)を渡すことができます。

ParameterizedThreadStart^ threadCallback;
threadCallback = gcnew ParameterizedThreadStart(&Work::ReceiveThread);
Thread^ recvThread = gcnew Thread( threadCallback );
recvThread->Start( lbxMessages );

スレッドを実行するための静的メソッド:

static void RecieveThread(Object^ state)
{
    ListBox^ lbxMessages = (ListBox^)state;
    //...code
}

だが.. 。別の問題があります。ListBoxがWin32コントロールであるとすると、コントロールは、作成されたスレッドからのみ変更できます。したがって、ListBoxアイテムを挿入するたびに、UIのスレッドから挿入する必要があります。1つの方法は、SynchronizationContextオブジェクトを使用することです。

 // Start the thread
 array<Object^>^ args = gcnew array<Object^>(2){
    lbxMessages,
    SynchronizationContext::Current
 }
 recvThread->Start( args);

スレッドメソッドは次のようになります。

static void RecieveThread(Object^ state)
{
  array<Object^>^ args = (array<Object^>^)state;
  ListBox^ lbxMessages = (ListBox^)args[0];
  SynchronizationContext^ ctx = (SynchronizationContext^)args[1];
  //...code
     String^ meep = gcnew String(message);
     ctx->Send(gcnew SendOrPostCallback(&Work::SafeListBoxInsert),
               gcnew array<Object^>(2){lbxMessages, meep}
     );
}

UIのスレッドから別のメソッドを呼び出して、変更を加える必要があります。

ref class Work{
  //...other methods
  static void SafeListBoxInsert(Object^ state)
  {
    array<Object^>^ args = (array<Object^>^)state;
    ListBox^ lst = (ListBox^) args[0];
    String^ item = (String^) args[1];
    lst->Items->Add(item);
  }
}
于 2012-12-20T09:01:06.607 に答える
0

lbxMessages がどのように定義されているかは示されていませんが、同じクラスの非静的データ メンバーであると仮定します。その場合は、アクセスするオブジェクトを指定する必要がありますlbxMessages。最も簡単な方法は、RecieveThread メソッドを非静的に切り替えることです。そうすれば、this->lbxMessages.

どのウィンドウ ツールキットを使用しているかはわかりませんが、コントロールを編集するには、おそらく UI スレッドに戻る必要があります。

于 2012-12-20T08:58:03.397 に答える