Solved

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

Posted on 2004-04-25
4
621 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
  • 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

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…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

895 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now