Solved

Need Help with Windows Form updating by thread in VC++ .net

Posted on 2004-04-25
4
636 Views
Last Modified: 2010-04-24
I have been trying to figure out how to create a thread in VC++ .net that will be able to do the job of updating my Windows Form.

For example, this is my current windows form created by VC++ :

#pragma once


namespace MyWindowsForm
{
      using namespace System;
      using namespace System::ComponentModel;
      using namespace System::Collections;
      using namespace System::Windows::Forms;
      using namespace System::Data;
      using namespace System::Drawing;
      public __gc class Form1 : public System::Windows::Forms::Form
      {      
      public:
            Form1(void)
            {
                  InitializeComponent();
            }
 
      protected:
            void Dispose(Boolean disposing)
            {
                  if (disposing && components)
                  {
                        components->Dispose();
                  }
                  __super::Dispose(disposing);
            }
      private: System::Windows::Forms::ListBox *  listBox1;

      private:
            System::ComponentModel::Container * components;
            void InitializeComponent(void)
            {
                  this->listBox1 = new System::Windows::Forms::ListBox();
                  this->SuspendLayout();
                  //
                  // listBox1
                  //
                                                System::Object* __mcTemp__1[] = new System::Object*[1];
                  __mcTemp__1[0] = S"firstElement";
                  this->listBox1->Items->AddRange(__mcTemp__1);
                  this->listBox1->Location = System::Drawing::Point(16, 24);
                  this->listBox1->Name = S"listBox1";
                  this->listBox1->Size = System::Drawing::Size(272, 173);
                  this->listBox1->TabIndex = 0;
                  //
                  // Form1
                  //
                  this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
                  this->ClientSize = System::Drawing::Size(448, 349);
                  this->Controls->Add(this->listBox1);
                  this->Name = S"Form1";
                  this->Text = S"Form1";
                  this->ResumeLayout(false);

            }      
      };
}
========================================================================

What I want to do is that, I want to create a thread that will be able to update the listBox1 while not freezing up the windows form. I have tried using __beginthread but it seems that the compiler does not like that for some reason..
Has anyone done something simliar and can tell me what kind of thread i should use here so that I can update the listBox1 WITHIN the thread.
And, how do I pass the "System::Object* __mcTemp__1[]" pointer? The inline declaration is really confusing me.
Is there a way I can just update the listBox1 the same way as if i were doing it in C#?? (ie, listBox1.Items.Add...)

I am going to put a 500 points on this question because i have been looking around and testing for a while without any luck.. I hope someone can give me some hint or direction on how to complete this task.








0
Comment
Question by:lordiano
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 10911669
Paste this code to Managed C++ Windows form application, Form1.h file (call it ManagedCThread, main form is called Form1):

#pragma once


namespace ManagedCThread
{
    using namespace System;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    using namespace System::Threading;

    public __gc class Form1 : public System::Windows::Forms::Form
    {  
    public:
        Form1(void)
        {
            InitializeComponent();

            m_pThread = NULL;
            m_DelegateAddString = new DelegateAddString(this, AddString);
        }
 
    protected:
        void Dispose(Boolean disposing)
        {
            if (disposing && components)
            {
                components->Dispose();
            }
            __super::Dispose(disposing);
        }
    private: System::Windows::Forms::Button *  btnStartThread;
    private: System::Windows::Forms::ListBox *  listBox1;
    private: System::Windows::Forms::Button *  btnStopThread;

    private:
        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::Container * components;

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        void InitializeComponent(void)
        {
            this->btnStartThread = new System::Windows::Forms::Button();
            this->listBox1 = new System::Windows::Forms::ListBox();
            this->btnStopThread = new System::Windows::Forms::Button();
            this->SuspendLayout();
            //
            // btnStartThread
            //
            this->btnStartThread->Location = System::Drawing::Point(400, 32);
            this->btnStartThread->Name = S"btnStartThread";
            this->btnStartThread->Size = System::Drawing::Size(120, 32);
            this->btnStartThread->TabIndex = 0;
            this->btnStartThread->Text = S"Start Thread";
            this->btnStartThread->Click += new System::EventHandler(this, btnStartThread_Click);
            //
            // listBox1
            //
            this->listBox1->ItemHeight = 16;
            this->listBox1->Location = System::Drawing::Point(24, 16);
            this->listBox1->Name = S"listBox1";
            this->listBox1->Size = System::Drawing::Size(352, 244);
            this->listBox1->TabIndex = 1;
            //
            // btnStopThread
            //
            this->btnStopThread->Location = System::Drawing::Point(400, 96);
            this->btnStopThread->Name = S"btnStopThread";
            this->btnStopThread->Size = System::Drawing::Size(120, 32);
            this->btnStopThread->TabIndex = 2;
            this->btnStopThread->Text = S"Stop Thread";
            this->btnStopThread->Click += new System::EventHandler(this, btnStopThread_Click);
            //
            // Form1
            //
            this->AutoScaleBaseSize = System::Drawing::Size(6, 15);
            this->ClientSize = System::Drawing::Size(536, 285);
            this->Controls->Add(this->btnStopThread);
            this->Controls->Add(this->listBox1);
            this->Controls->Add(this->btnStartThread);
            this->Name = S"Form1";
            this->Text = S"Form1";
            this->ResumeLayout(false);

        }  
    private: System::Void btnStartThread_Click(System::Object *  sender, System::EventArgs *  e)
             {
                 StartThread();
             }

    private: System::Void btnStopThread_Click(System::Object *  sender, System::EventArgs *  e)
             {
                 StopThread();
             }


    private:

        static void ThreadFunction()
        {
            try
            {
                for ( int i = 0; i < 10; i++)
                {
                    String* s = String::Format("Step {0}", __box(i));

                    Object* p[] = new Object*[1];
                    p[0] = s;
                    pMainForm->BeginInvoke(pMainForm->m_DelegateAddString, p);

                    Thread::Sleep(400);
                }
            }
            catch ( Exception* )
            {
            }

        }

        __delegate void DelegateAddString(String* s);

        DelegateAddString* m_DelegateAddString;

        void AddString(String* s)
        {
            listBox1->Items->Add(s);
            listBox1->SelectedIndex = listBox1->Items->Count - 1;
        }

        void StartThread()
        {
            StopThread();

            pMainForm = this;
            ThreadStart* threadDelegate = new ThreadStart(0, ThreadFunction);
            m_pThread = new Thread(threadDelegate);
            m_pThread->IsBackground = true;
            m_pThread->Start();
        }

        void StopThread()
        {
            if ( m_pThread != NULL )
            {
                m_pThread->Abort();
                m_pThread->Join();
                m_pThread = NULL;
            }

        }

        Thread* m_pThread;
        static Form1* pMainForm;

    };
}


0
 

Author Comment

by:lordiano
ID: 10915385
Thanks a lot AlexFM, I am wondering if you can explain something here :

__delegate void DelegateAddString(String* s);
DelegateAddString* m_DelegateAddString;

I asume that DelegateADdString is a function? But I am not so sure why you can make a ptr instance out of it (m_DelegateAddString)

And this line :
m_DelegateAddString = new DelegateAddString(this, AddString);

Which even bothers me more.. since DelegateAddString was defined at taking a String * s, but here its passing the form ptr and AddString function.. I am really lost here.

Thanks again Alex
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10915450
__delegate void DelegateAddString(String* s);
This line defines new type - pointer to function (which is called delegate in .NET) which returns void and has String* parameter.

DelegateAddString* m_DelegateAddString;
This line defines class member of type DelegateAddString.

m_DelegateAddString = new DelegateAddString(this, AddString);
This line initializes m_DelegateAddString with pointer to function AddString of "this" instance of the class.
0
 

Author Comment

by:lordiano
ID: 10915472
Thanks Alex, I think i knwo whats going on now :)
Your help is greatly appreciated..
I am very new to .net and the way thread is created is totally different from java, and c , but at least i am learning something new.
0

Featured Post

[Webinar] Learn How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them. Thursday, July 13, 2017 10:00 A.M. PDT

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question