Dostęp do klasy Form1 (C++\CLI)

0

Witam wszystkich, uczę się C++\CLI (Windows Form) i trafiłem na dziwny problem.
Przy próbie dostępu do "obiektu Formy" z zewnętrznej funkcji wyskakuje mi error 'Form1' : undeclared identifier ?? .
Oto kod programu:

#pragma once

void Aktualizuj()
{
	Form1^ forma = gcnew Form1;
	forma->progressBar1->Value = 100;
}

namespace Program {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <summary>
	/// Summary for Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();

			//
			//TODO: Add the constructor code here
			//
		}


		// koniec

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  button1;
	protected: 
	public: System::Windows::Forms::ProgressBar^  progressBar1;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		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->button1 = (gcnew System::Windows::Forms::Button());
			this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
			this->SuspendLayout();
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(177, 205);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(217, 30);
			this->button1->TabIndex = 0;
			this->button1->Text = L"button1";
			this->button1->UseVisualStyleBackColor = true;
			this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
			// 
			// progressBar1
			// 
			this->progressBar1->Location = System::Drawing::Point(52, 81);
			this->progressBar1->Name = L"progressBar1";
			this->progressBar1->Size = System::Drawing::Size(476, 35);
			this->progressBar1->TabIndex = 1;
			this->progressBar1->Value = 1;
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(560, 291);
			this->Controls->Add(this->progressBar1);
			this->Controls->Add(this->button1);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->ResumeLayout(false);

		}
#pragma endregion
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
			 {
				 Aktualizuj(); // powinien zaktualizowac się progressbar
			 }
	};



}

error:

1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(5): error C2065: 'Form1' : undeclared identifier
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(5): error C2065: 'forma' : undeclared identifier
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(5): error C2061: syntax error : identifier 'Form1'
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(6): error C2065: 'forma' : undeclared identifier
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(6): error C2227: left of '->progressBar1' must point to class/struct/union/generic type
1>          type is ''unknown-type''
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(6): error C2227: left of '->Value' must point to class/struct/union/generic type

W czym tkwi problem?

0

Nie jestem pewien czy to to, ale wydaje mi się, że może być problem w tym, że klasa Form1 jest dopiero w przestrzeni nazw, a ty probujesz zadeklarować 'forma' powyżej. Sprobuj zadeklarować poniżej przestrzeni nazw i w funkcji dodać

void Aktualizuj()
{
        Program::Form1^ forma = gcnew Form1;
        forma->progressBar1->Value = 100;
}
0

Niestety, nic nie pomogło.

0

A co teraz pisze kompilator?

Btw zajrzyj do mojego tematu, jak umiesz pomóc bylbym wdzięczny
http://4programmers.net/Forum/C_i_C++/182272-problem_z_kompilacja

0

C++/CLI pod tym względem działa jak C++ a nie jak C#. żeby typ z innego pliku był widoczny, musi być inkludowany plik nagłówkowy z deklaracją odpowiedniej klasy.

#include "Form1.h"
0

Ale tutaj odbywa się wszystko w jednym pliku (Funkcja Aktualizuj() jak i Klasa Form1 znajduje sie w tym samym pliku form1.h)

Znalazłem podobny problem na forum i spróbowałem tak:

#pragma once

void Aktualizuj(Form1^ forma = gcnew Form1)
{
		forma->progressBar1->Value = 100;
}

namespace Program {


	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	/// <summary>
	/// Summary for Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();

			//
			//TODO: Add the constructor code here
			//
		}


		// koniec

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::Button^  button1;
	protected: 
	public: System::Windows::Forms::ProgressBar^  progressBar1;

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		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->button1 = (gcnew System::Windows::Forms::Button());
			this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
			this->SuspendLayout();
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(177, 205);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(217, 30);
			this->button1->TabIndex = 0;
			this->button1->Text = L"button1";
			this->button1->UseVisualStyleBackColor = true;
			this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
			// 
			// progressBar1
			// 
			this->progressBar1->Location = System::Drawing::Point(52, 81);
			this->progressBar1->Name = L"progressBar1";
			this->progressBar1->Size = System::Drawing::Size(476, 35);
			this->progressBar1->TabIndex = 1;
			this->progressBar1->Value = 1;
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(560, 291);
			this->Controls->Add(this->progressBar1);
			this->Controls->Add(this->button1);
			this->Name = L"Form1";
			this->Text = L"Form1";
			this->ResumeLayout(false);

		}
#pragma endregion
	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
			 {
				 Aktualizuj(this); // powinien zaktualizowac się progressbar
			 }
	};



}


ale nadal są errory:

1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(4): error C2065: 'Form1' : undeclared identifier
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(4): error C2065: 'forma' : undeclared identifier
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(4): error C2061: syntax error : identifier 'Form1'
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(5): error C2448: 'Aktualizuj' : function-style initializer appears to be a function definition
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(101): error C3861: 'Aktualizuj': identifier not found

Dlaczego co nie zrobię to zawsze wywala "error C2065: 'Form1' : undeclared identifier" ??

0

@up, ale tutaj to wszystko jest w jednym pliku, więc nie potrzeba dodawać pliku nagłówkowego w którym się aktualnie znajdujemy
Poprawiłem Ci kod

#pragma once

namespace Program {
 
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
 
        /// <summary>
        /// Summary for Form1
        /// </summary>

        public ref class Form1 : public System::Windows::Forms::Form
        {
        public:
                Form1(void)
                {
                        InitializeComponent();
 
                        //
                        //TODO: Add the constructor code here
                        //
                }
 
 
                // koniec
 
        protected:
                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~Form1()
                {
                        if (components)
                        {
                                delete components;
                        }
                }
        private: System::Windows::Forms::Button^  button1;
        public: System::Windows::Forms::ProgressBar^  progressBar1;
		public: System::Windows::Forms::Label^  label1;
		public: 

        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                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->button1 = (gcnew System::Windows::Forms::Button());
					this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
					this->label1 = (gcnew System::Windows::Forms::Label());
					this->SuspendLayout();
					// 
					// button1
					// 
					this->button1->Location = System::Drawing::Point(177, 205);
					this->button1->Name = L"button1";
					this->button1->Size = System::Drawing::Size(217, 30);
					this->button1->TabIndex = 0;
					this->button1->Text = L"Aktualizuj";
					this->button1->UseVisualStyleBackColor = true;
					this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
					// 
					// progressBar1
					// 
					this->progressBar1->Location = System::Drawing::Point(52, 81);
					this->progressBar1->Name = L"progressBar1";
					this->progressBar1->Size = System::Drawing::Size(476, 35);
					this->progressBar1->TabIndex = 1;
					this->progressBar1->Value = 1;
					// 
					// label1
					// 
					this->label1->AutoSize = true;
					this->label1->Location = System::Drawing::Point(199, 155);
					this->label1->Name = L"label1";
					this->label1->Size = System::Drawing::Size(35, 13);
					this->label1->TabIndex = 2;
					this->label1->Text = L"Tu jest jakiś napis";
					this->label1->Click += gcnew System::EventHandler(this, &Form1::label1_Click);
					// 
					// Form1
					// 
					this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
					this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
					this->ClientSize = System::Drawing::Size(560, 291);
					this->Controls->Add(this->label1);
					this->Controls->Add(this->progressBar1);
					this->Controls->Add(this->button1);
					this->Name = L"Form1";
					this->Text = L"Form1";
					this->ResumeLayout(false);
					this->PerformLayout();

				}
#pragma endregion
		void Aktualizuj()
		{
			if(progressBar1->Value + 10 >= 100)
				progressBar1->Value = 100;
			else
				progressBar1->Value += 10;
			label1->Text = L"zmiana napisu";
		}
        
		private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
                         {
                                 Aktualizuj(); // powinien zaktualizowac się progressbar
                         }
		private: System::Void label1_Click(System::Object^  sender, System::EventArgs^  e) {
				 }
		};
 
 
 
}

Jakbyś próbował zadeklarować funkcję Aktualizuj przed przestrzenią nazw, to kompilator mówi, że Form1 nie nalezy do przestrzeni nazw Program, z drugiej strony, jak funkcję definiujesz pod przestrzenią nazw, to pluć będzie o to, że Aktualizuj jest niezainicjalizowane, dlatego wpakuj funkcję jako metodę klasy Form1 i wszystko będzie działało tak jak chcesz. poza tym, tworzyłeś w funkcji Aktualizuj za każdym razem nowy obiekt a nowy obiekt ma na początku wartość 1 i potem nie zostawała ona wyświetlana

0

Doskonale zdaję sobie sprawę, że jak funkcja Aktualizuj() jest wewnątrz klasy Form1 to wszystko działa.
Problem tkwi w tym co zrobić żeby działało jak funkcja Aktualizuj jest poza klasą Form1
....
Proszę o pomoc :)

0

Funkcję aktualizuj wyrzucić do odzielnego pliku w deklaracji rzucić parametr który będzie wskaźnikiem do tej klasy Aktualizuj(Program::Form1*), a w wywołaniu po wciśnięciu button1_Click wywołać funkcję przez Aktualizuj(this);
Ale musisz wtedy dodać plik z definicją funkcji tak jak powiedział Azarien.

0

Plik Form1.h:

#pragma once
#include "funkcje.h"
 
namespace Program {
 
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
        /// <summary>
        /// Summary for Form1
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
 
        public:
                Form1(void)
                {
                        InitializeComponent();
 
                        //
                        //TODO: Add the constructor code here
                        //
                }
 
 
                // koniec
 
        protected:
                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~Form1()
                {
                        if (components)
                        {
                                delete components;
                        }
                }
        private: System::Windows::Forms::Button^  button1;
        protected: 
        public: System::Windows::Forms::ProgressBar^  progressBar1;
 
        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                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->button1 = (gcnew System::Windows::Forms::Button());
                        this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
                        this->SuspendLayout();
                        // 
                        // button1
                        // 
                        this->button1->Location = System::Drawing::Point(177, 205);
                        this->button1->Name = L"button1";
                        this->button1->Size = System::Drawing::Size(217, 30);
                        this->button1->TabIndex = 0;
                        this->button1->Text = L"button1";
                        this->button1->UseVisualStyleBackColor = true;
                        this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
                        // 
                        // progressBar1
                        // 
                        this->progressBar1->Location = System::Drawing::Point(52, 81);
                        this->progressBar1->Name = L"progressBar1";
                        this->progressBar1->Size = System::Drawing::Size(476, 35);
                        this->progressBar1->TabIndex = 1;
                        this->progressBar1->Value = 1;
                        // 
                        // Form1
                        // 
                        this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
                        this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
                        this->ClientSize = System::Drawing::Size(560, 291);
                        this->Controls->Add(this->progressBar1);
                        this->Controls->Add(this->button1);
                        this->Name = L"Form1";
                        this->Text = L"Form1";
                        this->ResumeLayout(false);
 
                }
#pragma endregion
 
        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
                         {
                                 Aktualizuj(this); // powinien zaktualizowac się progressbar
                         }
        };
 
 
}

Plik funkcje.h:

#include "Form1.h"
 
void Aktualizuj(Program::Form1*)
{
//Form1^ forma = gcnew Form1
//forma->progressBar1->Value = 100;
}

error:

1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\funkcje.h(3): error C2653: 'Program' : is not a class or namespace name
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\funkcje.h(3): error C2065: 'Form1' : undeclared identifier
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\funkcje.h(3): error C2059: syntax error : ')'
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\funkcje.h(4): error C2143: syntax error : missing ';' before '{'
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\funkcje.h(4): error C2447: '{' : missing function header (old-style formal list?)
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(97): error C3861: 'Aktualizuj': identifier not found

Ale musisz wtedy dodać plik z definicją funkcji tak jak powiedział Azarien.
Czyli #include "Form1" tak?

0

Trochę się głubię w środowisku .NET framework dlatego tak długo się zastanawiałem nad rozwiązaniem

#pragma once

namespace Program {
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
        /// <summary>
        /// Summary for Form1
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
 
        public:
                Form1(void)
                {
                        InitializeComponent();
 
                        //
                        //TODO: Add the constructor code here
                        //
                }
 
 
                // koniec
 
        protected:
                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~Form1()
                {
                        if (components)
                        {
                                delete components;
                        }
                }
        public: System::Windows::Forms::Button^  button1;
        protected: 
        public: System::Windows::Forms::ProgressBar^  progressBar1;
 
        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                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->button1 = (gcnew System::Windows::Forms::Button());
                        this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
                        this->SuspendLayout();
                        // 
                        // button1
                        // 
                        this->button1->Location = System::Drawing::Point(177, 205);
                        this->button1->Name = L"button1";
                        this->button1->Size = System::Drawing::Size(217, 30);
                        this->button1->TabIndex = 0;
                        this->button1->Text = L"button1";
                        this->button1->UseVisualStyleBackColor = true;
                        this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
                        // 
                        // progressBar1
                        // 
                        this->progressBar1->Location = System::Drawing::Point(52, 81);
                        this->progressBar1->Name = L"progressBar1";
                        this->progressBar1->Size = System::Drawing::Size(476, 35);
                        this->progressBar1->TabIndex = 1;
                        this->progressBar1->Value = 1;
                        // 
                        // Form1
                        // 
                        this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
                        this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
                        this->ClientSize = System::Drawing::Size(560, 291);
                        this->Controls->Add(this->progressBar1);
                        this->Controls->Add(this->button1);
                        this->Name = L"Form1";
                        this->Text = L"Form1";
                        this->ResumeLayout(false);
 
                }
#pragma endregion
 
        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e);
                         
        };
}

void Ak(Program::Form1^ form)
{
	form->progressBar1->Value = 100;
	form->button1->Text = L"Zakoncz";
}

System::Void Program::Form1::button1_Click(System::Object^  sender, System::EventArgs^  e)
{
	if(progressBar1->Value == 100)
	{
		Close();
	}
	Ak(this);
}

Nie potrzeba było oddzielnego pliku, tylko w klasie zostawić deklarację funkcji natomiast definicję dać nieco niżej.

0

Datex, czy tam piotrek11737 (po cholerę wczoraj zarejestrowałeś drugie konto?), nie licz na dalszą pomoc z naszej strony, mija się ona z celem. Nie znasz nawet tak elementarnych podstaw jak include czy sposób definicji zmiennych i ich widoczność, umiesz wyłącznie wklikać progressbara na formę i wklejać otrzymane/znalezione kody na pałę. Nie próbujesz zrozumieć co robisz, po każdą kolejną linijkę kodu przychodzisz na forum. Tak się nie da, nie będziemy za Ciebie całego programu pisać.

0

MJay, NIE wyciągaj metody poza definicję klasy, umieść deklarację funkcji ak przed klasą. Ciało powinno znaleźć się w oddzielnym pliku C++. Chyba wiesz jakie konsekwencje dla linkera ma wielokrotne zdefiniowanie tej samej funkcji (poprzez włączanie tego samego nagłówka w wielu plikach)?

0

Ale jest w tym samym pliku nagłówkowym, więc nie wiem o co Ci chodzi.
Tutaj autor chciał aby funkcja Aktualizuj znalazła się poza przestrzenią nazw, przynajmniej ja tak wywnioskowałem.
Definicja funkcji poza przestrzenią nazw tak czy siak nie obciąży linkera. Pomysł z umieszczniem definicji poza plik nagłówkowy już mi z głowy wypadł.

Jakby definicja funkcja miała być w środku klasy, to zapętlisz się sam z predefinicjami klasy, funkcji i przestrzeni nazw, żeby wszystko działało jak należy.

0
MJay napisał(a)

Trochę się głubię w środowisku .NET framework dlatego tak długo się zastanawiałem nad rozwiązaniem

#pragma once

namespace Program {
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
        /// <summary>
        /// Summary for Form1
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
 
        public:
                Form1(void)
                {
                        InitializeComponent();
 
                        //
                        //TODO: Add the constructor code here
                        //
                }
 
 
                // koniec
 
        protected:
                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~Form1()
                {
                        if (components)
                        {
                                delete components;
                        }
                }
        public: System::Windows::Forms::Button^  button1;
        protected: 
        public: System::Windows::Forms::ProgressBar^  progressBar1;
 
        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                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->button1 = (gcnew System::Windows::Forms::Button());
                        this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
                        this->SuspendLayout();
                        // 
                        // button1
                        // 
                        this->button1->Location = System::Drawing::Point(177, 205);
                        this->button1->Name = L"button1";
                        this->button1->Size = System::Drawing::Size(217, 30);
                        this->button1->TabIndex = 0;
                        this->button1->Text = L"button1";
                        this->button1->UseVisualStyleBackColor = true;
                        this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
                        // 
                        // progressBar1
                        // 
                        this->progressBar1->Location = System::Drawing::Point(52, 81);
                        this->progressBar1->Name = L"progressBar1";
                        this->progressBar1->Size = System::Drawing::Size(476, 35);
                        this->progressBar1->TabIndex = 1;
                        this->progressBar1->Value = 1;
                        // 
                        // Form1
                        // 
                        this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
                        this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
                        this->ClientSize = System::Drawing::Size(560, 291);
                        this->Controls->Add(this->progressBar1);
                        this->Controls->Add(this->button1);
                        this->Name = L"Form1";
                        this->Text = L"Form1";
                        this->ResumeLayout(false);
 
                }
#pragma endregion
 
        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e);
                         
        };
}

void Ak(Program::Form1^ form)
{
	form->progressBar1->Value = 100;
	form->button1->Text = L"Zakoncz";
}

System::Void Program::Form1::button1_Click(System::Object^  sender, System::EventArgs^  e)
{
	if(progressBar1->Value == 100)
	{
		Close();
	}
	Ak(this);
}

Nie potrzeba było oddzielnego pliku, tylko w klasie zostawić deklarację funkcji natomiast definicję dać nieco niżej.

Działa - Dzięki

0
MJay napisał(a)

Ale jest w tym samym pliku nagłówkowym, więc nie wiem o co Ci chodzi.

TO może pora nauczyć się C++?

MJay napisał(a)

Definicja funkcji poza przestrzenią nazw tak czy siak nie obciąży linkera.

Przestrzenie nazw nie istnieją dla linkera, to tylko dekoracja nazw, lukier składniowy na poziomie kodu źródłowego.

MJay napisał(a)

Jakby definicja funkcja miała być w środku klasy, to zapętlisz się sam z predefinicjami klasy, funkcji i przestrzeni nazw, żeby wszystko działało jak należy.

Jak odpowiednio zapiszesz to niczego nie zapętlisz.

Podstawy C++:

  • pliki nagłówkowe istnieją tylko na poziomie preprocesora
  • preprocesor przechodzi po plikach przeznaczonych do kompilacji i wkleja zawartość plików wskazanych przez #include
  • wyjście preprocesora trafia do kompilatora
  • kompilator nie jest świadomy istnienia plików nagłówkowych, dla niego to treść wewnątrz .cpp
  • jeżeli teraz Form1.h będzie włączone w więcej niż jednym pliku .cpp to ciało zostanie skompilowane wielokrotnie
  • bez modyfikatorów static/inline każda kopia będzie widoczna dla innych jednostek kompilacji
  • otrzymasz bład linkera multiple definition bo nie będzie wiedział, które ciało jest właściwe.

Demonstracja problemu:

  • tworzymy z szablonu aplikację WinForms, nazywamy go ładnie, np. dupa
  • dodajemy nowy plik zuo.cpp, wpisujemy kolejno #include "stdafx.h" i #include <form1.h>
  • w form1.h wpisujemy na końcu void katastrofa(dupa::Form1 ^) {}
  • wygląda tak jak u Ciebie, MJay?
  • error LNK2005: "void __clrcall katastrofa(class dupa::Form1 ^)" (?katastrofa@@$$FYMXP$AAVForm1@dupa@@@Z) already defined

Demonstracja rozwiązania, bez jakoby "zapętlania":

  • przenosimy funkcję katastrofa do nowego pliku katastrofa.cpp zaczynającego się jak zuo.cpp
  • Przed za otwierającym Form.h #pragma once wstawiamy (w realnym programie powinno się to dać w oddzielny plik nagłówkowy):
namespace dupa {
	ref class Form1;
}

void katastrofa(dupa::Form1^);
  • mamy deklarację poprzedzającą klasy w przestrzeni Form1 i deklarację poprzedzającą globalnej funkcji korzystającej z Form1
  • próbujemy skompilować i... działa.

Nie ma "zapętlenia", jest tylko prawidłowo zapisana deklaracja, zgodnie z podstawami C++. Jak masz zaśmiecać forum bzdurnymi odpowiedzialmi, które nawet nie mają prawa się skompilować w realnym projekcie to lepiej nie pisz wcale. Autor wątku niech wykona tę listę kroków, może zrozumie rozwiązanie swojego problemu.

0

Wykorzystując wasze wypowiedzi zrobiłem tak:

#pragma once
#include <urlmon.h>
#include <iostream>
#pragma comment (lib, "urlmon.lib")

namespace DownloderTest {
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
        /// <summary>
        /// Summary for Form1
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
 
        public:
                Form1(void)
                {
                        InitializeComponent();
 
                        //
                        //TODO: Add the constructor code here
                        //
                }
 
 
                // koniec
 
        protected:
                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~Form1()
                {
                        if (components)
                        {
                                delete components;
                        }
                }
        public: System::Windows::Forms::Button^  button1;
        protected: 
        public: System::Windows::Forms::ProgressBar^  progressBar1;
 
        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                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->button1 = (gcnew System::Windows::Forms::Button());
					this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
					this->SuspendLayout();
					// 
					// button1
					// 
					this->button1->Location = System::Drawing::Point(177, 205);
					this->button1->Name = L"button1";
					this->button1->Size = System::Drawing::Size(217, 30);
					this->button1->TabIndex = 0;
					this->button1->Text = L"button1";
					this->button1->UseVisualStyleBackColor = true;
					this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
					// 
					// progressBar1
					// 
					this->progressBar1->Location = System::Drawing::Point(52, 81);
					this->progressBar1->Name = L"progressBar1";
					this->progressBar1->Size = System::Drawing::Size(476, 35);
					this->progressBar1->TabIndex = 1;
					this->progressBar1->Value = 1;
					// 
					// Form1
					// 
					this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
					this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
					this->ClientSize = System::Drawing::Size(560, 291);
					this->Controls->Add(this->progressBar1);
					this->Controls->Add(this->button1);
					this->Name = L"Form1";
					this->Text = L"Form1";
					this->ResumeLayout(false);

				}
#pragma endregion
 
        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e);
 
        };
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
class MyCallback: public IBindStatusCallback
{
public:
MyCallback(DownloderTest::Form1^ form) { }

~MyCallback() { }

// This one is called by URLDownloadToFile
STDMETHOD(OnProgress)(/* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR wszStatusText)
{
DownloderTest::Form1^ form;
form->progressBar1->Maximum = ulProgressMax;
form->progressBar1->Value = ulProgress;
return S_OK;
}

// The rest don't do anything...
STDMETHOD(OnStartBinding)(/* [in] */ DWORD dwReserved, /* [in] */ IBinding __RPC_FAR *pib)
{ return E_NOTIMPL; }

STDMETHOD(GetPriority)(/* [out] */ LONG __RPC_FAR *pnPriority)
{ return E_NOTIMPL; }

STDMETHOD(OnLowResource)(/* [in] */ DWORD reserved)
{ return E_NOTIMPL; }

STDMETHOD(OnStopBinding)(/* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError)
{ return E_NOTIMPL; }

STDMETHOD(GetBindInfo)(/* [out] */ DWORD __RPC_FAR *grfBINDF, /* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
{ return E_NOTIMPL; }

STDMETHOD(OnDataAvailable)(/* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC __RPC_FAR *pformatetc, /* [in] */ STGMEDIUM __RPC_FAR *pstgmed)
{ return E_NOTIMPL; }

STDMETHOD(OnObjectAvailable)(/* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown __RPC_FAR *punk)
{ return E_NOTIMPL; }

// IUnknown stuff
STDMETHOD_(ULONG,AddRef)()
{ return 0; }

STDMETHOD_(ULONG,Release)()
{ return 0; }

STDMETHOD(QueryInterface)(/* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{ return E_NOTIMPL; }
};
////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
System::Void DownloderTest::Form1::button1_Click(System::Object^  sender, System::EventArgs^  e)
{
		MyCallback pCallback(this);
		URLDownloadToFile(NULL, L"http://www.domena.pl/zjecie.jpg", L"c:\\zdjecie.jpg", 0, &pCallback);
        
}


Program skompilował się poprawnie:

1>------ Build started: Project: DownloderTest, Configuration: Debug Win32 ------
1>  DownloderTest.cpp
1>  DownloderTest.vcxproj -> C:\Users\datex\documents\visual studio 2010\Projects\DownloderTest\Debug\DownloderTest.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Ale jest problem po kliknięciu w button wywala błąd:
"An unhandled exception of type 'System.NullReferenceException' occurred in DownloderTest.exe

Additional information: Object reference not set to an instance of an object."

Screen: user image

Czego to jest wina ??

0

Cały problem z Tobą, nie masz za grosz podstaw. Zmienna lokalna pCallback przestaje istnieć zaraz po wyjściu z metody a chcesz żeby było używane później. Uczyń ją składową klasy:

        public ref class Form1 : public System::Windows::Forms::Form
        {
        protected:
                 MyCallback pCallback;
        public:
                Form1(void) : pCallback(this)

Jeżeli pobieranie następuje w oddzielnym wątku to będziesz zmuszony użyć metody Invoke, bez niej poleci wyjątek, zajrzysz do dokumentacji (albo wrzucisz wyjątek w Google) to się dowiesz co zrobić dalej.

0
#pragma once
#include <urlmon.h>
#include <iostream>
#pragma comment (lib, "urlmon.lib")

namespace DownloderTest {
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
        /// <summary>
        /// Summary for Form1
        /// </summary>
        public ref class Form1 : public System::Windows::Forms::Form
        {
	protected:
                 MyCallback pCallback;
        public:
                Form1(void) : pCallback(this)
 
        public:
                Form1(void)
                {
                        InitializeComponent();
 
                        //
                        //TODO: Add the constructor code here
                        //
                }
 
 
                // koniec
 
        protected:
                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~Form1()
                {
                        if (components)
                        {
                                delete components;
                        }
                }
        public: System::Windows::Forms::Button^  button1;
        protected: 
        public: System::Windows::Forms::ProgressBar^  progressBar1;
 
        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                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->button1 = (gcnew System::Windows::Forms::Button());
					this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
					this->SuspendLayout();
					// 
					// button1
					// 
					this->button1->Location = System::Drawing::Point(177, 205);
					this->button1->Name = L"button1";
					this->button1->Size = System::Drawing::Size(217, 30);
					this->button1->TabIndex = 0;
					this->button1->Text = L"button1";
					this->button1->UseVisualStyleBackColor = true;
					this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
					// 
					// progressBar1
					// 
					this->progressBar1->Location = System::Drawing::Point(52, 81);
					this->progressBar1->Name = L"progressBar1";
					this->progressBar1->Size = System::Drawing::Size(476, 35);
					this->progressBar1->TabIndex = 1;
					this->progressBar1->Value = 1;
					// 
					// Form1
					// 
					this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
					this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
					this->ClientSize = System::Drawing::Size(560, 291);
					this->Controls->Add(this->progressBar1);
					this->Controls->Add(this->button1);
					this->Name = L"Form1";
					this->Text = L"Form1";
					this->ResumeLayout(false);

				}
#pragma endregion
 
        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e);
 
        };
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
class MyCallback: public IBindStatusCallback
{
public:
MyCallback(DownloderTest::Form1^ form) { }

~MyCallback() { }

// This one is called by URLDownloadToFile
STDMETHOD(OnProgress)(/* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR wszStatusText)
{
DownloderTest::Form1^ form;
form->progressBar1->Maximum = ulProgressMax;
form->progressBar1->Value = ulProgress;
return S_OK;
}

// The rest don't do anything...
STDMETHOD(OnStartBinding)(/* [in] */ DWORD dwReserved, /* [in] */ IBinding __RPC_FAR *pib)
{ return E_NOTIMPL; }

STDMETHOD(GetPriority)(/* [out] */ LONG __RPC_FAR *pnPriority)
{ return E_NOTIMPL; }

STDMETHOD(OnLowResource)(/* [in] */ DWORD reserved)
{ return E_NOTIMPL; }

STDMETHOD(OnStopBinding)(/* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError)
{ return E_NOTIMPL; }

STDMETHOD(GetBindInfo)(/* [out] */ DWORD __RPC_FAR *grfBINDF, /* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
{ return E_NOTIMPL; }

STDMETHOD(OnDataAvailable)(/* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC __RPC_FAR *pformatetc, /* [in] */ STGMEDIUM __RPC_FAR *pstgmed)
{ return E_NOTIMPL; }

STDMETHOD(OnObjectAvailable)(/* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown __RPC_FAR *punk)
{ return E_NOTIMPL; }

// IUnknown stuff
STDMETHOD_(ULONG,AddRef)()
{ return 0; }

STDMETHOD_(ULONG,Release)()
{ return 0; }

STDMETHOD(QueryInterface)(/* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{ return E_NOTIMPL; }
};
////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
System::Void DownloderTest::Form1::button1_Click(System::Object^  sender, System::EventArgs^  e)
{
		
		URLDownloadToFile(NULL, L"http://www.wp.pl/i/ivar/layout/200812/WP.gif", L"c:\\zdjecie.jpg", 0, &pCallback);
        
}

error:

1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(19): error C2146: syntax error : missing ';' before identifier 'pCallback'
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(19): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(19): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(21): warning C4355: 'this' : used in base member initializer list
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(23): error C2612: trailing 'public' illegal in base/member initializer list
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(23): error C2614: 'DownloderTest::Form1' : illegal member initialization: 'pCallback' is not a base or member
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(23): error C2143: syntax error : missing ';' before 'public'
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(25): error C2143: syntax error : missing ';' before '{'
1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(108): fatal error C1903: unable to recover from previous error(s); stopping compilation

Zrobiłem tak jak pisales
: D i co powiesz na to ?

0

...że jesteś głupi. Deklaracje poprzedzające, referencje itd. przerabialiśmy w poprzednich wątkach i właśnie w tym. Spojrzałem w kod callbacka:

DownloderTest::Form1^ form;
form->progressBar1->Maximum = ulProgressMax;
form->progressBar1->Value = ulProgress;

Skąd form na nic nie wskazuje, to jest ta null-referencja. Referencję do formy przekazaną do konstruktora całkowicie olewasz, rozumiesz w ogóle po co Azarien radził Ci to przekazywać? Słuchaj, wszystko co potrzebne już było napisane w poprzednich wątkach i w tym. Dopiero co w tym wątku podaliśmy jak rozwiązywać problemy z kolejnością, Ty bezmyślnie przylatujesz z identycznym problemem bo nie dałem całego kodu po rearanżacji. Naprawdę mamy ten program pisać za Ciebie? Nie umiesz, nie rozumiesz, nie chcesz zrozumieć, chcesz przeklejać kawałki kodu, tak się nie da.

0

Jakbym potrafił to bym napisał...
Czy tak trudno zamiast tych kilkunastu wątków na forum odpowiedzieć jednym konkretnym?
Przedstawiłem Wam cały kod programu, nie bez powodu - po to aby ktoś poprawił błędy i wstawił działający kod...
Nie chcecie tego zrobić za free? Dobra wiec kto zrobi i za ile ? : D

0
Datex napisał(a)

Jakbym potrafił to bym napisał...

To się naucz, wszystko potrzebne już zostało powiedziane.

Datex napisał(a)

Czy tak trudno zamiast tych kilkunastu wątków na forum odpowiedzieć jednym konkretnym?

TRUDNO SKORO Z DWÓCH KONT ZAKŁADASZ KILKA WĄTKÓW O JEDNYM PROGRAMIE!

Przerób przykład z dupą, potem weź to, prawidłowo "rozmieszczone" i z dodaną referencją:

#pragma once

#include <vcclr.h>
#include <urlmon.h>
#pragma comment (lib, "urlmon.lib")

namespace dupa 
{
	ref class Form1;
};

void katastrofa(dupa::Form1 ^);

class MyCallback: public IBindStatusCallback
{
	gcroot<dupa::Form1 ^> form1;
public:
	MyCallback(dupa::Form1^ form) : form1(form) { }
 
~MyCallback() { }
 
// This one is called by URLDownloadToFile
STDMETHOD(OnProgress)(/* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR wszStatusText)
{
	katastrofa(form1);
	return S_OK;
}
 
// The rest don't do anything...
STDMETHOD(OnStartBinding)(/* [in] */ DWORD dwReserved, /* [in] */ IBinding __RPC_FAR *pib)
{ return E_NOTIMPL; }
 
STDMETHOD(GetPriority)(/* [out] */ LONG __RPC_FAR *pnPriority)
{ return E_NOTIMPL; }
 
STDMETHOD(OnLowResource)(/* [in] */ DWORD reserved)
{ return E_NOTIMPL; }
 
STDMETHOD(OnStopBinding)(/* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError)
{ return E_NOTIMPL; }
 
STDMETHOD(GetBindInfo)(/* [out] */ DWORD __RPC_FAR *grfBINDF, /* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
{ return E_NOTIMPL; }
 
STDMETHOD(OnDataAvailable)(/* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC __RPC_FAR *pformatetc, /* [in] */ STGMEDIUM __RPC_FAR *pstgmed)
{ return E_NOTIMPL; }
 
STDMETHOD(OnObjectAvailable)(/* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown __RPC_FAR *punk)
{ return E_NOTIMPL; }
 
// IUnknown stuff
STDMETHOD_(ULONG,AddRef)()
{ return 0; }
 
STDMETHOD_(ULONG,Release)()
{ return 0; }
 
STDMETHOD(QueryInterface)(/* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{ return E_NOTIMPL; }
};

namespace dupa {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <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();
			//
			//TODO: Add the constructor code here
			//
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}

	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		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->components = gcnew System::ComponentModel::Container();
			this->Size = System::Drawing::Size(300,300);
			this->Text = L"Form1";
			this->Padding = System::Windows::Forms::Padding(0);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
		}
#pragma endregion
	};
}

Jeśli nie chcesz robić oddzielnego pliku na katastrofę to wstaw na koniec form1.h:

inline void katastrofa(dupa::Form1 ^form)
{
	;
}

Tandetne jak reszta programu, ale zadziała.

We właściwościach plików .cpp zmień "Compile with Common Language Runtime support" na "Common Language Runtime support (/clr)". Dalej radź sobie sam, gdzie wstawić grzebanie w formie to chyba się domyślisz?

0

okej, dzięki
Tylko takie pytanie gdzie teraz zadeklarować zmienną "pCallbackę do funkcji URLDownloadToFile(NULL, L"http://domena.pl/plik.rar", L"c:\plik.rar", 0, &pCallback); ?
W konstruktorze czy lokalnie w AkcjiPrzycisku?

0

Nie za bardzo ogarniam to co napisałeś ^^. Wiem zawracam Ci dupę ale musisz mi jeszcze wytłumaczyć to i owo.

STDMETHOD(OnProgress)(/* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR wszStatusText)
{
        katastrofa(form1); // parametr form1 przekazywany jest do funkcji katastrofa
        return S_OK;
}

funkcja katastrofa:

inline void katastrofa(DownloderTest ::Form1 ^form)
{
 // jak tutaj mam zaktualizować progressbar wykorzystując zmienne ulProgress,  ulProgressMax ?
}

Zrobiłem progressbar i przycisk:

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
 {
      URLDownloadToFile(NULL, L"http://domena.pl/plik.rar", L"c:\\plik.rar", 0, &pCallback); // gdzie ma byc zalozona zmienna  "pCallback"?

}

Skończmy ten temat raz na zawsze : D
Z góry dzięki

0

Przecież, cholera, pisałem żeby nie deklarować w metodzie? Zapomniałem, że rzeczy natywne powinno się przez wskaźnik trzymać, czyli mała modyfikacja tego, co dostałeś kilka postów temu:

    protected:
             MyCallback *pCallback;
    public:
             Form1(void)
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
			pCallback = new MyCallback(this);
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
			delete pCallback;
		}

Używasz tej składowej, cała filozofia.

0

Jak masz aktualizować? No człowieku a jak to robiłeś wcześniej? Tutaj po prostu masz formę podaną przez argument zamiast zmiennej lokalnej... MYŚL do jasnej cholery.

0

Teraz wygląda to tak juz wszystko powinno śmigać ale pojawił się nieoczekiwany błąd

1>c:\users\datex\documents\visual studio 2010\projects\downlodertest\downlodertest\Form1.h(150): error C2664: 'URLDownloadToFileW' : cannot convert parameter 5 from 'cli::interior_ptr<Type>' to 'LPBINDSTATUSCALLBACK'
1>          with
1>          [
1>              Type=MyCallback *
1>          ]
1>          Cannot convert a managed type to an unmanaged type
#pragma once:
 #include <vcclr.h>
#include <urlmon.h>
#pragma comment (lib, "urlmon.lib")
 
namespace DownloderTest 
{
        ref class Form1;
};
 
void katastrofa(DownloderTest::Form1 ^, int wartosc);
 
class MyCallback: public IBindStatusCallback
{
       gcroot<DownloderTest::Form1 ^> form1;
	   public:
			MyCallback(DownloderTest::Form1^ form) : form1(form) { }
 
~MyCallback() { }
 
// This one is called by URLDownloadToFile
STDMETHOD(OnProgress)(/* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR wszStatusText)
{
        katastrofa(form1,ulProgress); // Przekazywanie parametru form i wartosci
        return S_OK;
}
 
// The rest don't do anything...
STDMETHOD(OnStartBinding)(/* [in] */ DWORD dwReserved, /* [in] */ IBinding __RPC_FAR *pib)
{ return E_NOTIMPL; }
 
STDMETHOD(GetPriority)(/* [out] */ LONG __RPC_FAR *pnPriority)
{ return E_NOTIMPL; }
 
STDMETHOD(OnLowResource)(/* [in] */ DWORD reserved)
{ return E_NOTIMPL; }
 
STDMETHOD(OnStopBinding)(/* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError)
{ return E_NOTIMPL; }
 
STDMETHOD(GetBindInfo)(/* [out] */ DWORD __RPC_FAR *grfBINDF, /* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
{ return E_NOTIMPL; }
 
STDMETHOD(OnDataAvailable)(/* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC __RPC_FAR *pformatetc, /* [in] */ STGMEDIUM __RPC_FAR *pstgmed)
{ return E_NOTIMPL; }
 
STDMETHOD(OnObjectAvailable)(/* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown __RPC_FAR *punk)
{ return E_NOTIMPL; }
 
// IUnknown stuff
STDMETHOD_(ULONG,AddRef)()
{ return 0; }
 
STDMETHOD_(ULONG,Release)()
{ return 0; }
 
STDMETHOD(QueryInterface)(/* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{ return E_NOTIMPL; }
};
 
namespace DownloderTest {
 
        using namespace System;
        using namespace System::ComponentModel;
        using namespace System::Collections;
        using namespace System::Windows::Forms;
        using namespace System::Data;
        using namespace System::Drawing;
 
        /// <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
        {
	protected:
             MyCallback *pCallback;
    public:
             Form1(void)
                {
                        InitializeComponent();
                        //
                        //TODO: Add the constructor code here
                        //
                        pCallback = new MyCallback(this);
                }
 
        protected:
                /// <summary>
                /// Clean up any resources being used.
                /// </summary>
                ~Form1()
                {
                        if (components)
                        {
                                delete components;
                        }
                        delete pCallback;
                }
		public: System::Windows::Forms::ProgressBar^  progressBar1;
		protected: 
		private: System::Windows::Forms::Button^  button1;

        private:
                /// <summary>
                /// Required designer variable.
                /// </summary>
                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->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
					this->button1 = (gcnew System::Windows::Forms::Button());
					this->SuspendLayout();
					this->progressBar1->Location = System::Drawing::Point(66, 63);
					this->progressBar1->Name = L"progressBar1";
					this->progressBar1->Size = System::Drawing::Size(406, 38);
					this->progressBar1->TabIndex = 0;
					this->progressBar1->Value = 1;
					this->button1->Location = System::Drawing::Point(167, 126);
					this->button1->Name = L"button1";
					this->button1->Size = System::Drawing::Size(197, 32);
					this->button1->TabIndex = 1;
					this->button1->Text = L"button1";
					this->button1->UseVisualStyleBackColor = true;
					this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
					this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
					this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
					this->ClientSize = System::Drawing::Size(526, 184);
					this->Controls->Add(this->button1);
					this->Controls->Add(this->progressBar1);
					this->Name = L"Form1";
					this->Text = L"Form1";
					this->ResumeLayout(false);

				}
#pragma endregion
		private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
				 {
					 URLDownloadToFile(NULL, L"http://domena.pl/plik.rar", L"c:\\plik.rar", 0, &pCallback);
				 }
		};
}
inline void katastrofa(DownloderTest ::Form1 ^form, int wartosc)
{
   form->progressBar1->Value = wartosc;     
}
0

Problem był tutaj:

 URLDownloadToFile(NULL, L"http://domena.pl/plik.rar", L"c:\\plik.rar", 0, &pCallback); 

trzeba zmienić "&pCallback" na "pCallback"

Dzięki wszystkim za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1