.Net c++ multithreading using form1 generated code

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • lewisms
    New Member
    • Aug 2007
    • 2

    #1

    .Net c++ multithreading using form1 generated code

    Hello all,

    I am quite new to c++/. Net so please don't shoot me down for being a newbie. Any way I am trying to make a simple multithreading program that is just to learn the ideas behind it (before I incorporate them in another program). I just can’t seem to get a non-static call to work in my thread that has access to the Form1 variables and controls I need. I can call a non-static function using another class but then I can seem to get in to link to Form1 without creating a new instance (I don't want that as then it will not really work).

    Below is my code using VC++ Express Edition on win xp pro

    Code:
    #pragma once
    #include "Thread.h"//test header class not used
    #include "stdafx.h"
    #include <process.h>//multi-threading
    #include <stdlib.h>
    #include "windows.h"//windpws commands
    
    //multi-threading
    unsigned __stdcall MyThread1(void * param);
    unsigned tid1; // thread IDs
    HANDLE hMainThread; // thread handles
    HINSTANCE hInst; // instance handle
    HWND hwnd;
    
    //namespace
    using namespace System;
    using namespace System::Windows;
    using namespace System::ComponentModel;
    using namespace System::Collections;
    using namespace System::Windows::Forms;
    using namespace System::Data;
    using namespace System::Drawing;
    #using <System.dll>
    #using <System.Drawing.dll>
    #using <System.Windows.Forms.dll>
    
    namespace Multi_Thread_Test2 {
    
    	#define  __stdcall
    	
    	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 ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Add the constructor code here
    			//
    		}
    	public:
    		/// <summary>
    		/// Clean up any resources being used.
    		/// </summary>
    		~Form1()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    	public: System::Windows::Forms::Button^  Run;
    	public: System::Windows::Forms::ProgressBar^  ProgressBar;
    	
    	public:
    		
    		System::ComponentModel::Container ^components;
    
    #pragma region Windows Form Designer generated code
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->Run = (gcnew System::Windows::Forms::Button());
    			this->ProgressBar = (gcnew System::Windows::Forms::ProgressBar());
    			this->SuspendLayout();
    			// 
    			// Run
    			// 
    			this->Run->Location = System::Drawing::Point(202, 61);
    			this->Run->Name = L"Run";
    			this->Run->Size = System::Drawing::Size(75, 23);
    			this->Run->TabIndex = 0;
    			this->Run->Text = L"Run";
    			this->Run->UseVisualStyleBackColor = true;
    			this->Run->Click += gcnew System::EventHandler(this, &Form1::Run_Click);
    			// 
    			// ProgressBar
    			// 
    			this->ProgressBar->Location = System::Drawing::Point(13, 12);
    			this->ProgressBar->Name = L"ProgressBar";
    			this->ProgressBar->Size = System::Drawing::Size(450, 43);
    			this->ProgressBar->Step = 1;
    			this->ProgressBar->TabIndex = 1;
    			this->ProgressBar->Value = 1;
    			// 
    			// Form1
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(475, 95);
    			this->Controls->Add(this->ProgressBar);
    			this->Controls->Add(this->Run);
    			this->Name = L"Form1";
    			this->Text = L"Form1";
    			this->ResumeLayout(false);
    
    		}
    #pragma endregion
    	private: System::Void Run_Click(System::Object^  sender, System::EventArgs^  e)
    			 {
    				StartThreadFunc();
    			 }
    	public: void UpdateProgressBar()
    			 {
    				int i;
    				for (i=0;i<100;i++)
    				{
    					System::Threading::Thread::Sleep(500);
    					this->ProgressBar->Value = i;
    				}
    			 }
    	public: void StartThreadFunc()
    			{
    			void ( *funcPtr)( ) =   &Multi_Thread_Test2::Form1::UpdateProgressBar; 
    			 hMainThread = (HANDLE) _beginthreadex(NULL, 0, funcPtr, (void *) hwnd, 0, &tid1);
    			}
    	
    	};// end class Form1 definition		
    unsigned __stdcall MyThread1(void * param)//unused function
    			 {	
    				/*int i;
    				for (i=0;i<100;i++)
    				{
    					System::Threading::Thread::Sleep(500);
    					this->ProgressBar->Value = i;
    				}*/
    				/*Form1 MainForm;
    				MainForm.UpdateProgressBar();*/
    				return 0;
    			 }
    
    }//end multi_thread_test2
    What i get as an output is

    Code:
    ------ Rebuild All started: Project: Multi_Thread_Test2, Configuration: Debug Win32 ------
    Deleting intermediate and output files for project 'Multi_Thread_Test2', configuration 'Debug|Win32'
    Compiling...
    stdafx.cpp
    Compiling...
    AssemblyInfo.cpp
    Multi_Thread_Test2.cpp
    c:\documents and settings\lspencer\my documents\visual studio 2005\projects\multi_thread_test2\multi_thread_test2\Form1.h(139) : error C3374: can't take address of 'Multi_Thread_Test2::Form1::UpdateProgressBar' unless creating delegate instance
    c:\documents and settings\lspencer\my documents\visual studio 2005\projects\multi_thread_test2\multi_thread_test2\Form1.h(140) : error C2665: '_beginthreadex' : none of the 2 overloads could convert all the argument types
            C:\Program Files\Microsoft Visual Studio 8\VC\include\process.h(57): could be 'uintptr_t _beginthreadex(void *,unsigned int,unsigned int (__stdcall *)(void *),void *,unsigned int,unsigned int *)'
            C:\Program Files\Microsoft Visual Studio 8\VC\include\process.h(67): or 'uintptr_t _beginthreadex(void *,unsigned int,unsigned int (__clrcall *)(void *),void *,unsigned int,unsigned int *)'
            while trying to match the argument list '(int, int, void (__clrcall *)(void), void *, int, unsigned int *)'
    Generating Code...
    Build log was saved at "file://c:\Documents and Settings\lspencer\My Documents\Visual Studio 2005\Projects\Multi_Thread_Test2\Multi_Thread_Test2\Debug\BuildLog.htm"
    Multi_Thread_Test2 - 2 error(s), 0 warning(s)
    ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
    I now the problem lies with

    Code:
    void ( *funcPtr)( ) =   &Multi_Thread_Test2::Form1::UpdateProgressBar; 
    			 hMainThread = (HANDLE) _beginthreadex(NULL, 0, funcPtr, (void *) hwnd, 0, &tid1);
    All help would be welcome. I have already tried using the CreateThread function to no luck.
  • TRScheel
    Recognized Expert Contributor
    • Apr 2007
    • 638

    #2
    You are creating a native pointer to reference the function. You need to create a managed pointer to use it.

    Managed pointers are declared with ^ instead of *


    I explain it in more detail on this thread:

    Thread Regarding Native/Managed Pointers

    Comment

    • lewisms
      New Member
      • Aug 2007
      • 2

      #3
      i managed to fix it in the end via changing the code to use

      using namespace System::Threadi ng;

      here it is, to help any one else

      Code:
      #pragma once
      
      namespace Multi_Thread_Test2 {
      	
      	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;
      
      	/// <summary>
      	/// Summary for Form1
      	///
      	/// WARNING: If you change the name of this class, you will need to change the
      	///          'Resource File Name' property for the managed resource compiler tool
      	///          associated with all .resx files this class depends on.  Otherwise,
      	///          the designers will not be able to interact properly with localized
      	///          resources associated with this form.
      	/// </summary>
      	public ref class Form1 : public System::Windows::Forms::Form
      	{
      	public:Form1(void)
      		{
      			InitializeComponent();
      		}	
      	public:~Form1()
      		{
      			if (trd->IsAlive)
      				trd->Abort();
      			if (components)
      			{
      				delete components;
      			}
      		}	
      	private: Thread ^trd;
      	public: System::Windows::Forms::Button^  Run;
      	public: System::Windows::Forms::ProgressBar^  ProgressBar;
      	public:	System::ComponentModel::Container ^components;
      	#pragma region Windows Form Designer generated code
      			/// <summary>
      			/// Required method for Designer support - do not modify
      			/// the contents of this method with the code editor.
      			/// </summary>
      			void InitializeComponent(void)
      			{
      				this->Run = (gcnew System::Windows::Forms::Button());
      				this->ProgressBar = (gcnew System::Windows::Forms::ProgressBar());
      				this->SuspendLayout();
      				// 
      				// Run
      				// 
      				this->Run->Location = System::Drawing::Point(202, 61);
      				this->Run->Name = L"Run";
      				this->Run->Size = System::Drawing::Size(75, 23);
      				this->Run->TabIndex = 0;
      				this->Run->Text = L"Run";
      				this->Run->UseVisualStyleBackColor = true;
      				this->Run->Click += gcnew System::EventHandler(this, &Form1::Run_Click);
      				// 
      				// ProgressBar
      				// 
      				this->ProgressBar->Location = System::Drawing::Point(13, 12);
      				this->ProgressBar->Name = L"ProgressBar";
      				this->ProgressBar->Size = System::Drawing::Size(450, 43);
      				this->ProgressBar->Step = 1;
      				this->ProgressBar->TabIndex = 1;
      				this->ProgressBar->Value = 0;
      				// 
      				// Form1
      				// 
      				this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
      				this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
      				this->ClientSize = System::Drawing::Size(475, 95);
      				this->Controls->Add(this->ProgressBar);
      				this->Controls->Add(this->Run);
      				this->Name = L"Form1";
      				this->Text = L"Form1";
      				this->ResumeLayout(false);
      
      			}
      #pragma endregion
      	private: System::Void Run_Click(System::Object^  sender, System::EventArgs^  e)
      			 {
      			
      				StartThreadFunc();
      			 }
      	
      	public:  void UpdateProgressBar()
      			 {
      				int i;
      				for (i=0;i<100;i++)
      				{
      					System::Threading::Thread::Sleep(500);
      					this->ProgressBar->Value = i;
      				}	
      			 }
      	public: void StartThreadFunc()
      			{
      				ThreadStart ^myThreadDelegate = gcnew ThreadStart(this, &Form1::UpdateProgressBar);
      				trd = gcnew Thread(myThreadDelegate);
      				trd->IsBackground = true;
      				trd->Start();
      			}
      
      	};// end class Form1 definition	
      }//end multi_thread_test2
      I tried to use the ^ pointer but i kept getting two linking errors, oh well this method works fine.

      Comment

      Working...