Witam.
Stworzyłem sobie główna formę oraz Windows Forms Control Library w której utworzyłem własny przycisk ale do tego przycisku muszę przekazać wskaźnik do stworzonej w C++ klasy. Próbowałem przez konstruktor ale wyrzuca mi błąd
"c:\users\mati2600\desktop\windowsformsa4pplication1\windowsformsapplication1\Form1.h(83): error C3767: 'costam::cosControl': candidate function(s) not accessible"
oczywiście utworzony przeze mnie przycisk został dodany do głównej formy przez References..
Czy ktoś mógł by mi pomóc jak w tym Windows Forms C++ przekazać ten wskaźnik?
"not accessible" - oznacza że próbujesz odwołać się do np prywatnej metody.
No tak wiem o tym z tym że konstruktor jest publiczny jak próbowałem to zrobić za pomocą metody public też ten sam błąd. Niestety nie jest to tak proste.
Pokaż kod.
Tutaj jest kontrolka która stworzyłem:
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
namespace costam {
/// <summary>
/// Summary for cosControl
/// </summary>
public ref class cosControl : public System::Windows::Forms::UserControl
{
private: Napis* temp;
public:
cosControl(Napis* x):temp(x)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~cosControl()
{
if (components)
{
delete components;
}
}
protected:
private: System::Windows::Forms::Label^ label1;
private: System::Windows::Forms::Button^ button1;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// Required designer variable.
/// </summary>
#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>
private:void MarshalString ( String ^ s, std::string& os ) {
using namespace Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
void InitializeComponent(void)
{
this->label1 = (gcnew System::Windows::Forms::Label());
this->button1 = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(140, 68);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(35, 13);
this->label1->TabIndex = 0;
this->label1->Text = L"label1";
//
// button1
//
this->button1->Location = System::Drawing::Point(119, 28);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 1;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &cosControl::button1_Click);
//
// cosControl
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = System::Drawing::Color::Transparent;
this->Controls->Add(this->button1);
this->Controls->Add(this->label1);
this->Name = L"cosControl";
this->Size = System::Drawing::Size(335, 244);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
public: void urzyj(void){
label1->Text="udalo sie";
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
String^ temp2;
MarshalString(temp2,temp->napis);
label1->Text=temp2;
}
};
}
To jest klasa która jest przekazywana:
class Napis{
public:std::string napis;
public:Napis(std::string x){
napis=x;
}
};
A to miejsce użycia tej kontrolki w głównej formie:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Napis* przyklad=new Napis("bla bla bla");
costam::cosControl^ buton=gcnew costam::cosControl(przyklad);
buton->Location=System::Drawing::Point(10,10);
this->Controls->Add(buton);
}
oczywiscie jest to tylko przyklad ale w projekcie dokladnie tak to NIE dziala:)
Nie rozumiem, po co ci ten Napis
, skoro jest tylko opakowaniem na std::string
. Zamiast tego użyj po prostu dotnetowego System::String
bez kombinowania.
Pamiętaj że C++/CLI to nie C#, i klasy zdefiniowane w osobnych plikach nie widzą się nawzajem automatycznie. Trzeba za#include
'ować plik nagłówkowy z deklaracją klasy.
Twoja metoda MarshalString
też jest niepotrzebna.
#include <msclr/marshal_cppstd.h>
String ^s = L"ala ma kota";
std::string os = msclr::interop::marshal_as<std::string>(s);
ps. większy sens ma użycie std::wstring
(jeśli już koniecznie musisz użyć STL-a), bo wstring jest unikodowy tak jak System::String
. przy zwykłym std::string
masz niepotrzebną konwersję w tę i nazad, ze stratą zalet unikodu.