با سلام
من تو visual c++.net يه dll دارم و با add existing item چند تا (win form(.net به اون اضافه كردم . مي خوام بدونم چطور مي شه مشخص كرد كه با اجراي هر فرماني مثل كليك روي دكمه اي خاص كدوم فرم باز بشه . دستور نمايش فرم چيه؟
Printable View
با سلام
من تو visual c++.net يه dll دارم و با add existing item چند تا (win form(.net به اون اضافه كردم . مي خوام بدونم چطور مي شه مشخص كرد كه با اجراي هر فرماني مثل كليك روي دكمه اي خاص كدوم فرم باز بشه . دستور نمايش فرم چيه؟
باید یه شئ از اون فرم new کنی و اونرو Show و یا ShowDialog کنی:
البته به c# نوشتم. ولی امیدوارم متوجه شده باشی.کد:myForm = new Form1();
myForm.Show();
this.Hide();// in khat panjereye felli ro penhan mikone
ممنون از راهنماييتون
مشكله من اينه كه مي خوام تو dll از فرم هام استفاده كنم و او نها رو showيا hide كنم
وقتي با add existing item به dll فرم اضافه مي كنم كلاسي به صورت
public __gc class winform : public System::Windows::Forms::Form
ساخته مي شه ولي با اينكه هدر اين كلاس رو به dll اضافه مي كنم وقتي myform winform يا myform.show رو تايپ مي كنم نه winform رو مي شناسه و نه my form رو .در واقع من نحوه برقراري ارتباط بين فايل هاي مربوط به فرم (هدر و cpp و كلا سه اي آنها) رو با Dll نمي دونم
سلام.
واقعا متاسفم از اینکه اینقدر جواب دادنم طول کشیده.
خب...
برای ایجاد یه Dll در Net. و استفاده از اون مرحله به مرحله پیش میریم :
نوع پروژه رو CLR و از Template گزینه ClassLibrary رو انتخاب میکنیم. تا اینجا که فکر نمیکنم
مشکلی وجود داشته باشه. در حال حاضر یه کلاس به پروژه اضافه شده.
میخوایم به این Dll یک Form اضافه کنیم که مثلا یه Button داشته باشه. به منوی project میریم و
Add Class رو انتخاب و از Template گزینه WinForm رو در نظر میگیرم. اسمی براش میذاریم و اون رو به
Dll اضافه می کنیم.
formی به Dll اضافه میشه و برای اینکه form مون خالی نباشه یه Button به اون اضافه میکنیم که
مثلا پیغامی رو نمایش بده. مثل همیشه عمل میکنیم. بعد از اضافه کردن کلید به form روی اون 2 بار
کلیک میکنیم و در متود ایجاد شده کد زیر رو اضافه میکنیم :
کارمون با Dll تموم شده . برنامه رو Compile میکنیم و میریم به سراغ پروژه ی بعدی که یه Windows Formکد:
private: System::Void ShowHello_Click(System::Object^ sender, System::EventArgs^ e)
{
MessageBox::Show("Hello!!!!");
}
هست. دوباره مرحله اول رو تکرار میکنیم و به جای Class Library گزینه ی Windows Forms App رو انتخاب
میکنیم. برای اینکه از Dll استفاده کنیم کافیه با استفاده از ماکروی using# اون رو به برنامه اضافه کنیم.
همچنین باید namespace استفاده شده رو به برنامه اضافه کرد:
به form این برنامه هم مثلا یه Button اضافه میکنیم که با کلیک کردن روی اون بشه Form ی که در Dll قرارکد:
#using "MyManagedDll.dll"
using namespace MyManagedDll;
داره رو اجرا کرد :
کافیه برنامه رو اجرا کنیم.کد:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
MyWinForm ^form = gcnew MyWinForm();
form->Show();
}
فقط در اینجا نکته ای وجود داره که نمونه ای براتون گذاشتم در VC2005 نوشته شده و اگه از VC2003 استفاده
میکنین چند تغییر کوچیک در اون باید ایجاد کنین.
برای استفاده از Form ها در خود Dll هم کافیه از اسم Class فورمتون استفاده کنین. البته با استفاده از gcnew.
مثل همین نمونه.
اما در مورد استفاده از Form های MFC قضیه کمی فرق میکنه. چون شما در ManagedCode دارین از کلاس
هایی که مدیریت شده نیستن استفاده میکنین که اگه بخواین در موردشون صحبت کنیم.
امیدوارم مشکل حل شده باشه.
اگه مشکلی پیش اومد اطلاع بدین.
ممنون.
سلام
ممنون كه بلاخره جواب دادين ولي مشكل من حل نشد . مشكل اينه كه من وقتي شبيه كاري كه شما گفتيد با classlib يك dllمي سازم با masseagebox مشكلي نداره ولي من يك dll نوشته شده با vs.net دارم كه به صورت آماده است و بايد يه سري كار روش انجام بدم نمي دنم از چه نوعيه كه با massagebox خطاهاي زير رو مي د ه:
error C2660: 'System::Windows::Forms::Control::Show' : function does not take 1 arguments
error C2653: 'MessageBoxA' : is not a class or namespace name
شايد به هدر خاصي احتياج داره اگه مي دونيد از كدوم هدر براي تعريف massagebox استفاده مي شه منو راهنمايي كنيد.
دوم اينكه من به اين dllآماده همون طور كه گفتيد با addclass چندفرم .net اضافه كردم ولي نمي تونم ازشون تو فايل cpp تعريف شده براي dll ام استفاده كنم چون وقتي مي نويسم(تو cpp نه هدر كلاس)
winform *form1 = new winform();
form1->Show();
در زمان build نه كلاس winformرو مي شناسه نه متد show رو .هرچند من هدر كلاس رو بهش اضافه كردم . اصلا نمي دونم چه طور مي شه از كلاس ها و فرم هاي تعريف شده و اضافه شده به dll در اون استفاده كرد . در ضمن من نمي خوام از اين dll تو همين محيط استفاده كنم استفاده من از اين dllدر اتوكد است كه اونجت چند فرم دارم و مي خوام با صدور هر فرمان يا كليك دكمه اي در فرم اتوكد يكي از فرم هاي تعريف شده در dllفعال بشه . لطفا با توجه به سوال و روشي كه كار كردم پاسخ بدين
كد فايل cpp براي dll:
#include "stdafx.h"
#include "winform.h"
void showform()
}
? winform *form1 =new winform;
? forml->Show();
{
و هدر كلاس winform اضافه شده به dll :
public __gc class winform : public System::Windows::Forms::Form
{
public:
winform(void)
{
InitializeComponent();
}
.
.
.
private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)
{
label1->Text="شما روي دكمه اي كليك كرديد";
}
public:
void examfunc(void)
}
? MessageBox ::Show("test!");
; {
اونجاهايي كه ? گذاشتم خطا داره
مثال كه شما زديد استفاده از فرم در خود فايل cpp يك dllرو در بر نداشت .بلكه تو هدر كلاس روال كليك رو گذاشتين
private: System::Void ShowHello_Click(System::Object^ sender, System::EventArgs^ e)
{
MessageBox::Show("Hello!!!!");
}
در ضمن نحوه كار با استفاده كننده dll و چگونگي استفاده از dll در آن برام فعلأ مهم نيست استفاده كننده اتوكد است كه بحثشو اينجا مطرح نمي كنم
من مي خوام كه تو Dll خودم بتونم با استفاده از پارامترهاي ارسالي از استفاده كننده dll ، فرم هاي خاصي رو نمايش بدم(show) يعني مثلأ اگه 1 از فرستنده ارسال شده فرم اول dll و اگه 2 ارسال شد فرم دوم dll نمايان بشه و اين تعريف نمايش كدام فرم بايد در dll نوشته بشه. اميدوارم با سوال هاي مكرر من و توضيحات نه چندان كامل متوجه منظورم شده با شيد.نتيجه گيري و پاسخ تون رو بر اساس اين دو پست انتهايي من قرار بدين لطفأ
دوباره سلام.
نقل قول:
من مي خوام كه تو Dll خودم بتونم با استفاده از پارامترهاي ارسالي از استفاده كننده dll ، فرم هاي خاصي رو نمايش بدم(show) يعني مثلأ اگه 1 از فرستنده ارسال شده فرم اول dll و اگه 2 ارسال شد فرم دوم dll نمايان بشه و اين تعريف نمايش كدام فرم بايد در dll نوشته بشه.
ببینید شما میتونین یه متود public برای کلاس اصلی Dll تون بنویسین.
فرض کنین که دو فرم به Dll اضافه کردیم. با نامهای WinForm1 و WinForm2 .
میتونیم به این شکل عمل کنیم :
این متود به راحتی در خارج از Dll دردسترس هست. کافیه به آرگومان اون 1 یا 2 بدین تا فرمتون رو ببینین.کد:
// MyManagedDll.h
#pragma once
#include "MyWinForm2.h" --------------Added
#include "MyWinForm.h" --------------Added
using namespace System;
namespace MyManagedDll {
public ref class Class1
{
// TODO: Add your methods for this class here.
public :
void LoadMyForm(int FormNumber)
{
switch (FormNumber)
{
MyWinForm ^myform;
MyWinForm2 ^myform2;
case 1:
myform = gcnew MyWinForm();
myform->Show();
break;
case 2:
myform2 = gcnew MyWinForm2();
myform2->Show();
break;
}
}
};
}
در مورد MessageBox هم شما باید از namespace مناسب استفاده کنین :
با توجه به سوالتون فکر کنم جوابم مناسب باشه.کد:
using namespace System::Windows::Forms;
اگه باز مشکل حل نشد اطلاع بدین.
سلام . خسته نباشيد از راهنماييتون ممنونم
مشكلم با نمايش فرم حل شد تنها اشكالي كه باعث مي شد كلاس ساخته شده براي فرمم تو Dll تعريف نشده باشه اين بود كه قبل از نوشتن نام كلاس بايد اسم namespace ي كه كلاس در اون قرار داشت رو بيارم
مثلا اگه در هدر كلاس winform.h داشته باشيم:
نقل قول:
#using<System.Windows.Forms.dll>
namespace Step01
{
public __gc class winform : public System::Windows::Forms::Form
{
public:
winform(void)
{
InitializeComponent();
}
.
.
.
public:
void examfunc(void)
{
winform *form1 = new winform();
form1->Show();
// MessageBox ::Show("test!");
};
كه massagebox رو نمي شناسه عليرغم وجود using
فايل dll برنامه:
نقل قول:
#include "stdafx.h"
#include "winform.h"
.
.
.
void helloWorld()
{
acutPrintf("\nHello World!");
Step01::winform *myclass=new Step01::winform *****
myclass->label1->Text="sssss";
myclass->examfunc() ;
}
حالا مشكلي كه برام ايجاد شده اينه كه با اين كد هربار كه متد examfunc در dllفراخواني مي شه يه فرم جديد از نوع كلاس winform ساخته ميشه (تعريف examfunc در winform.h) در صورتي كه من مي خوام همون كلاسي كه تغييرات خودمو روش دادم showبشه (myclass در dll) و متد show هم حتما بايد در يك روال فرعي خارج از dll باشه يعني همين طوري كه در كد نوشتم . الان با اينكه من text مربوط به label1 رو در dll تغيير دادم چون با فراخواني examfunc اين تابع در هدر فعال مي شه چيزي كه showمي شه form1 است نه myclass اميدوارم منظورمو متوجه شده باشيد و مثل هميشه راهنامييم كنيد
ممنون.
اول یه خواهش داشتم. برای نمایش کدهاتون از تگ کد استفاده کنین. (علامت # )
ممنون از توجهتون.
ببینین اول نکته ای که وجود داره اینه :
شما در Dll تون (بهتره گفته شه ClassLibrary ) یه Form دارین که در نتیجه اش یه کلاس از این Form.
وقتی شما به کلاس ّForm تون یه Control اضافه میکنین به صورت Private به کلاس اضافه میشه.
و اینکه در خارج از این کلاس و در کلاس دیگه ای (مثلا کلاس اصلی Dll ) بتونین از اون استفاده کنین
باید توسط یه متود یا property دسترسی به اون رو public کنین. اگه نظر من رو بخواین استفاده از
propery بهتر از یه متود public هست. گرچه در ظاهر فرقی با یه متود نداره.
برای استفاده از این keyword در 2003 از property__ استفاده کنین.
میتونین به این شکل عمل کنین :
(این property رو باید در کلاس Form بنویسین)
کد:
public ref class WinForm1 : public System::Windows::Forms::Form
{
public:
WinForm1(void)
{
InitializeComponent();
//
.
.
.
.
//------------------------------------------------------------------
property String^ LabelText
{
String^ get()
{
return label1->Text;
}
void set(String ^strName)
{
label1->Text = strName;
}
}
//------------------------------------------------------------------
.
.
.
الان به راحتی میتونین از این property در کلاس مورد نظرتون استفاده کنین :
(باز مثلا در کلاس اصلی Dll)
در کد بالا یه روش از فراخوانی MessageBox وجود داره.کد:
// ManagedDll.h
#pragma once
#include "WinForm1.h"
using namespace System;
namespace ManagedDll {
public ref class Class1
{
// TODO: Add your methods for this class here.
public:
void LoadMyForm()
{
this->refForm = gcnew WinForm1();
this->refForm->Show();
}
void ChangeLabelText(String ^strName)
{
if ( this->refForm )
this->refForm->LabelText = strName;
else
System::Windows::Forms::MessageBox::Show("Ref Err!");
}
private :
WinForm1 ^refForm;
};
}
برای استفاده از یه namespace به این شکل عمل کنین :
از این کد به جای ماکروی using# استفاده کنین. using و using# با هم تفاوت دارن.کد:using namespace System.Windows.Forms;
(به جای خط اول کدتون)
در مورد سوال دومتون شما باید از کلاس مورد نظرتون نمونه (reference ) بسازین.
اگه شما از کلاس Form چند نمونه ایجاد کنین طبیعی هست که از این From چند نمونه ایجاد بشه.
کدی که شما نوشتین به این صورت هست :
مشخه که از کلاس winform یه نمونه ساختین. ( myclass )کد:Step01::winform *myclass= new Step01::winform
myclass->label1->Text="sssss";
myclass->examfunc();
اما مشکلی که براتون پیش اومد به این دلیل هست :
متود examfunc یه نمونه ی دیگه از کلاس ایجاد میکنه. (form1 ) بنابراین منطقا شما نباید تغییری در form تون ببینین.
(بنابراین بعد از اجرای کد پایین شما دونمونه از کلاس Form دارین نه یکی )
شما متود examfunc رو در کلاس Form ساختین. در صورتی که میتونین به راحتی از کلاس Form تو کلاس اصلی Dll
استفاده کنین. همین کاری که من انجام دادم. هم در کدهای بالا و هم نمونه ی ساده ای از اون در پایین.
البته در کد بالا خط زیر جا مونده :کد:
// ManagedDll.h
#pragma once
#include "WinForm1.h"
using namespace System;
namespace ManagedDll {
public ref class Class1
{
// TODO: Add your methods for this class here.
public:
void LoadMyForm()
{
this->refForm = gcnew WinForm1();
this->refForm->Show();
this->refForm->LabelText = "This is Test!";
}
.
.
.
.
سعی کنین از property استفاده کنین و نمونه کدها رو به دقت بررسی کنین.کد:
private :
WinForm1 ^refForm;
اگه کدها ابهامی داشت یا نیاز به توضیح بیشتر بود و یا مشکلتون حل نشد اطلاع بدین.
ممنون از راهنمايي هاي كامل تون . حتمأ توصيه هاي شما رو در روند كارم اجرا مي كنم
براي نمايش فرم هم تا حدودي مشكلم حل شده . همون طور كه گفتم حتما با يد تابع نمايش فرم هم خارج از dll باشه
به همين دليل براي هر كلاس فرمي كه مي سازم يك تابع showform هم بهش اضافه مي كنم كه اين تابع هدر هر كلاسي فقط شامل كد form1->show ودر dll هرجا لازم بود فرم خاصي رو نمايش بدم يك متغير از جنس كلاس مربوطه مي سازم و تغييرات مورد نظرمو روش اعمل مي كنم سپس اين متغير رو به صورت پارامتري از جنس اون كلاس به تابع showformمي فرستم.
و در dll هم فراخواني به صورت زير را دارم :کد:
void showform(winform *form)
{
form->Show();
// MessageBox ::Show("test!"
};
براي هر class كه مي سازم هم شامل فرم است و هم تابع showform و در dll تنها فرقي كه در هر فراخواني اين تابع داريم تغيير نام كلاس (در كد بالا winform) چون نام namespaceدر تمام كلاس هاي اضافه شده به پروژه يكسان است.کد:
Step01::winform *myclass=new Step01::winform();
myclass->label1->Text="sssss";
myclass->showform(myclass);
به نظر شما من روش درستي رو به كار مي برم ؟
سوال بعدي هم در مورد همون massagebox كه گير سه پيچ داده و به هيچ صورتي كار نمي كنه
من using namespace System.Windows.Forms رو هم امتحان كردم فايده نداشت . براي نشون دادن massageboxهدر خاصي لازم است علاوه بر اين فضاي نام؟
با عرض معذرت از اين همه سوالي كه مي پرسم اگه در مورد تفاوت بين using # و using هم يه توضيح بدين ممنون مي شم.
همونطور که میدونین برای نمایش فرم روشهای مختلفی وجود داره، روشی که شما به کار میبرین
درسته و اتفاقا خیلی هم جالبه. چون تمامی فراخوانی ها در خود Dll انجام میشه. و کافی تنها اسم
یه تابع (در کد دومتون) رو export کنین.
اما در مورد MessageBox لازم نیست از header خاصی استفاده کنین. حتی لازم نیست از namespace
استفاده کنین. با توجه به کدتون من یه نمونه ی کوچیک نوشتم که از MessageBox هم استفاده شده.
(بدون استفاده از namespace )
اگه باز مشکل باقیه ، لطفا error که ایجاد میشه رو بذارین تا بتونیم در موردش صحبت کنیم.کد:
void Load()
{
MyWinForm ^myform = gcnew MyWinForm();
ShowForm(myform);
System::Windows::Forms::MessageBox::Show("Test!!!");
}
با استفاده از using# شما میتونین یه metadata رو به برنامه تون اضافه کنین.
که شکل تعریفش به این صورت هست :
این matadat میتونه MSIL (زبان میانه (IL) ، که تمامی کدها در Net. بعد از کامپایل ابتدایی به این زبان تبدیلکد:#using file [as_friend]
میشن) ، Dll ، exe و یا حتی obj باشه.
اما با استفاده using شما میتونین از یک فضای نام و یا اسمی که در این فضای نام قرار داره استفاده کنین.
به شکل زیر تعریف میشه :
که میتونه به شکلهای زیر استفاده بشه : ( با توجه به تعریف )کد:using namespace [::] [ nested-name-specifier ] namespace-name
مشخصه که چه تفاوتی دارن. به نوع تعریفشون دقت کنین.کد:std::cout (explicitly)
using std::cout (using declaration)
using namespace std (using directive)
بازم از راهنمايي هاي كارسازتون ممنونم
شرمنده اگه زياد سوال مي پرسم چون همون طور كه گفتم تو زمينه vs c++ تازه كارم ولي قبلآ با vb.net كار كردم .
مشكلم با massagebox همواره باقيه و با اينكه به صورت هاي مختلف اونو امتحان كردم بازم خطاهاي زير رو داره:
کد:
error C2039: 'MessageBoxA' : is not a member of 'System::Windows::Forms'
کد:
) error C2660: 'System::Windows::Forms::Control::Show' : function does not take 1 arguments
يه سوال ديگه هم داشتم مي خواستم بدونم كار با بانك اطلاعاتي تو vs c++.net چفدر با vb.net متفاوته؟
دوباره سلام.
فکر میکنم شما در CppManaged از کد مدیریت نشده استفاده میکنین.
به عبارت دیگه مثلا از MessageBox API استفاده میکنین و این تشابه اسم بین این API و متود MessageBox
از Net. باعث این مشکل شده. کدتون رو بررسی کنین و ببینین جای از header ی استفاده نکردین. مثلا Windows.h
(یا باقی header ها )
البته میتونین از کدمدیریت نشده در کد مدیریت شده استفاده کنین.
برای رفع این مشکل میتونین از ماکروی undef# استفاده کنین. به شکل زیر و قبل از فراخوانی متود MessageBox
کد:#undef MessageBox
اما در مورد سوال دومتون :
به غیر از Syntax زبان ها هیچ فرقی باهم نمیکنن.
اگه دقت کنین تمامی زبان های Net. مثل #C و VB و ++C و یا #J از کلاس های Net. برای توسعه برنامه ها استفاده میکنن. بنابراین اگه شما نمونه ای برای دسترسی به یه بانک دارین با کمی تغییر میتونین از اون در زبان دیگه
ای استفاده کنین. اما روش بهتری هم وجود داره. اونم استفاده از ClassLibrary مجوعه Net. هست.
به راحتی یه Dll ای که در VB نوشتین رو میتونین در #C استفاده کنین. واقعا به راحتی امکان پذیر هست.
تنها با چند کلیک!!!
د ر مورد messagebox بعد از استفاده از undef ديگه خطاهاي گفته شده رو نمي ده ولي موقع اجرا messagebox رو هم نشون نمي ده !يعني با كليك روي دكمه اي كه كد undef messagebox رو براش تعريف كردم هيچ اتفاقي نمي افته !
سه سوال برام به وجود اومده:
اول اينكه چرا نشون نمي ده ؟
دوم : undef چه كاري انجام ميده و اگه بخوايم ازش استفاده نكنيم چه راه حلي وجود داره؟
و سوم اينكه : مي شه فرق manage code و unmanage code رو توضيح بدين . اصلا به چه كد يا پروژه اي مديريت شده و به كدوم مديريت نشده مي گن و فرقشون چيه
و ديگه اينكه منظورتون رو از اين جمله متوجه نشدم:
نقل قول:
کدتون رو بررسی کنین و ببینین جای از header ی استفاده نکردین. مثلا Windows.h
(یا باقی header ها )
وقتی از undef استفاده میکنین اسمی که قبلا با استفاده از define تعریف شده
از بین میره. در مورد برنامه ی شما من فکر میکنم از MessageBox ApI استفاده شده.
واگه اون رو در تعریفش ببینین بعد از فراخوانی این api از با استفاده از define تابع MessageBoxW
که برای Unicode ها هم به کار میره به صورت MessageBox تعریف شده.
اما در مورد کار کردنش من مطمئن هستم . اگه براتون امکان داره در مورد نوع پروژه ای ایجاد کردین توضیح
بدین و بهتر اینکه که کدی که نوشتین رو برام بذارین. (source کامل)
اما در مورد کدهای مدیریت شده و مدیریت نشده (ManagedCoode & UnmanagedCode)
به طور خیلی ساده میشه گفت که شما برنامه هایی رو که با استفاد از MFC یا ++VC مینویسن مدیریت نشده
و کدهایی که در Net. مینویسین مدیریت شده هستند به شرطی که با CLR اجرا بشن.
اگه با ++C کار کرده باشین وقتی بخواین یه نمونه از یه Object مثلا یه کلاس بسازین به شکل زیر عمل میکنین:
الان شما یه نمونه از کلاس دارین. اما مشکلی که وجود داره اینه که کد بالا روی Heap ایجاد میشه نه Stack.کد:Class *myClass = new Class();
(Stack رو سیستم عامل کنترل میکنه.)
بنابراین وقتی شما کارتون با این نمونه تموم بشه خودتون اونرو باید از حافظه آزاد کنین. به شکل زیر :
به این مفهوم هست که مدیریت حافظه در برنامه ای که مینویسین با شماست نه کامپایلر .کد:delete myClass;
ممکنه تو مثال بالا زیاد مهم به نظر نیاد چون میشه این طور گفت که کافیه در پایان برنامه (Deconstructor)
این نمونه ها رو delete میکنیم. اما مشکل اینجاست که اگه در اثر یه Bug کلاس تون از حافظه آزاد بشه، نمونه
هایی که از کلاس دارین هنوز وجود دارن و به کلاس اشاره دارن. خب در این جا کافیه که برنامه اجرا بشه تا
یه فاجعه پیش بیاد.
اما CLR در Net. این کار رو بعده داره (gc یا Garbage Collector ). که استفاده از یه شمارنده این کار رو انجام
میده. علاوه براین فشرده سازی Heap هم به عهده ی CLR هست.
اگه دقت کنین وقتی در Net. میخواین یه نمونه از کلاس بسازین از gc__ یا gcnew (در 2003 و 2005 )
به این شکل عمل میکنین :
می بینین که در تمامی کد از delete استفاده نشده و gc همون کار رو به عهده داره.کد:
VC++2003
__gc class Class
{
}
Class *myClass = new Class()
VC++2005
ref class Class
{
}
Class ^nyClass = gcnew Class()
البته این دو نوع کد موارد اشترکی هم باهم دارن و اونم استفاده از WinAPI هست. وفقط ساختار و روش دسترسی
و مدیریت اونها با هم متفاوت هست.
توضیحش خیلی مفصل تر از اینهاست.
امیدوارم توضیحات روشن باشن.
گفتم که میتونین در Mcode میتونین از UMcode استفاده کنین.
کافیه به ClassLibrary یه Header خودتون اضافه کنین. احتمالش خیلی زیاد که چنین مشکلاتی پیش بیاد.
با سلام
اول از هر چيزممنون از راهنمايي كاملتون
در مورد كد پروژه چون طولاني است نمي تونم اينجا بذارم فقط توضيحي كه مي تونم بدم اينه كه من يه dll آماده دارم كه بايد يه سري ويژگي ها و توابع و فرم به اون اضافه كنم و از اونجايي كه وقتي مي خواستم به اين dllيه فرمnet. اضافه كنم خطاي زير رو مي داد:
کد:managed components can only be added to managed projects .please convert the project to managed
فكر مي كنم از كد مديريت نشده استفاده مي كنه ولي mfc dll نيست چون اگه بخوام فرم mfcبهش اضافه كنم خطايي مبني بر اينكه "فرم mfc application تنها به پروژه هاي mfcمي تواند اضافه شود "ميد هد
براي حل مشكل اضافه كردن فرم net. همونطور كه قبلا گفتيد use managed extensionرو yes كردم و mscorlib.dll هم به هدر كلاس اضافه كردم(آيا با اين كار Dll من به كد مديريت شده تبديل شد؟) و اضافه كردن فرم بدون مشكل انجام شد. حالا من كلاسي از نوع فرم net. دارم
کد:public __gc class winform : public System::Windows::Forms::Form
كه هدر اونو به dll اضافه كردم شايد اونجوريكه من برداشت كردم منظورتون از
همين باشه اگه درست نيست بهم بگين و راه حل مشكل رو چي پيشنهاد مي كنيد؟نقل قول:
گفتم که میتونین در Mcode میتونین از UMcode استفاده کنین.
کافیه به ClassLibrary یه Header خودتون اضافه کنین. احتمالش خیلی زیاد که چنین مشکلاتی پیش بیاد.
حالا حدس مي زنيد اين dll از چه نوعي است و چگونه ساخته شده و مشكل messagebox چطور حل مي شود . اينو هم بگم كه دستور
undef MessageBox # رو هم تو هدر كلاسم (جايي كه كلاس تعريف شده) در روال كليك دكمه و هم در dll امتحان كردم ولي با اينكه خطايي ازش نمي گيره اجراشم نمي كنه
ببينيد يه لينك اين پايينه به نظرتون مشكل منو حل مي كنه چون من زياد ازش سر در نياوردم
[ برای مشاهده لینک ، با نام کاربری خود وارد شوید یا ثبت نام کنید ]
راستش رو بخواین خیلی مشکله بشه در مورد پروژه ای با این تعاریف بدون دیدنش نظر داد.
چون هر بار شما پستی میذارین توش یه مطلب جدید هست!!!
اما با توضیحاتی که شما دادین و اینکه خطایی که مبنی براین :
"فرم mfc application تنها به پروژه هاي mfcمي تواند اضافه شود " میتونه یه Win32Dll باشه.
که برای اضافه کردن Form به اون باید از طریق Resource ها این کار رو انجام بدین. البته اجباری نیست.
اما نمیشه به اون کلاس های MFC رو اضافه کرد. مگر در هنگام ایجاد این نوع Dll اجازه ی استفاده از MFC
رو بدیم.
احتمالا نتونستم خوب در مورد ManagedCode و UnmanagedCode توضیح بدم.نقل قول:
آيا با اين كار Dll من به كد مديريت شده تبديل شد؟
با اضافه کردن مثلا یه Dll از مجموعه ی Net. به پروژه ای که مدیریت شده نیست ،
( Win32App-Dll , MFCApp-Dll-ActiveXDll , Cpp Code) پروژه تون به یه پروژه ی مدیریت شده تبدیل نمیشه.
شما در کدتون میتونین هم مدیرت شده کار کنین و هم مدیریت نشده. اما وقتی دارین ترکیبی کار میکنین و یا
اینکه مدیریت شده مینویسن باید برنامه رو با استفاده از CLR اجرا کنین. (Common Language Runtime)
در حقیقت کد مدیریت شده بدون CLR معنی نداره.
شما از خود MessageBox استفاده کنین. مثلا به این شکل :
کد:MessageBox(null,"Test!","Caption",1);
اگه میشه بگین این Dll ای که دارین روش کار میکنین مربوط به چی میشه و شما از کجا گرفتینش.
(چون دارین رو Source ش کار میکنین.)
در مورد آدرسی که گذاشتین باید بگم یه سایت فوق العاده مشهور ، که نمونه های واقعا عالی داره.
منظورتون مشکلی که در مورد MessageBox دارین ، هست ؟نقل قول:
به نظرتون مشكل منو حل مي كنه
اگه آره ، باید بگم مشکلتون قابل حل هست اما نه به کمک این site (گرچه نمونه های ManagedCpp میتونه دید
بهتری به شما بده.)
و گر در مورد یادگیری منظورتون هست ، باید بگم حتما!
فقط به سوالی که تو پست قبلی گذاشتم به دقت جواب بدین.
سلام
واقعا خسته نباشيد كه با اين همه مشكل و گير سه پيچ در برنامه هنوزم پيگير هستيد
با كمال مسرت بايد بگم مشكلم با messagebox حل شد تنها كاري كه لازم بود استفاده از undef messagebox # در هدر stdafx.h بود براي استفاده از messagebox در dll و همين طور تعريف اون در هدر فرم هاي net. در اينصورت چه من show رو بنويسم و چه messageboxر و تنها به كار ببرم نمايش اون به درستي انجام مي شه
واقعا از راهنمايي ها تون ممنون
در مورد dll هم من نمي دونم از كجا اومده اين dll به من داده شده و قراره من يه سري كار روش انجام بدم
و فرم به اون اضافه كنم و براش بانك اطلاعاتي تعريف كنم. شما فكر مي كنيد كه اين Dll از نوع win32 است( با اين توضيح كه من براي اينكه بتونم به اون فرم net.اضافه كنم اول use manage extensionرو yes كردم)
اميدوارم با توضيحاتي كه در تاپيك هاي قبل دادم تا حدودي در مورد برنامه من و كاري كه قراره انجام بدم پي برده باشيد چون مي دونم تتا اتمام كار مشكلات زيادي در پيش دارم . اگه نه بگين تو يه پيام خصوصي دوباره توضيح بدم
با تشكر
سلام میشه به من کمک کنید می خوام در مورد فضای نام در ++c بدونم لطفا هر چه سریعتر به من کمک کنید
مي شه بگين در حالت كلي چند روش براي ايجاد dll در c++.net وجود داره و هر كدوم چه فرقي با هم دارن
شايد از اين طريق بتونم تشخيص بدم dll ي كه روش كار مي كنم چطور ايجاد شده
با تشكر
قبلا در موردش صحبت کردیم.
ولی دوباره براتون میذارمش :
1-Win32Dll که از این طریق میتونین Dll های استاندارد Windows ی رو ایجاد کنین که از ساختارهای Windows
استفاده میکنن. از این Dll ها میتونین در تمامی زبان های برنامه نویسی استفاده کنین.
2- MFCDll که خودش به دو دسته تقسیم میشه. Requalr و Extention
در هر دو نوع شما میتونین از کلاس های MFC کلاس های MFC استفاده کنین و در برنامه هایی قابل استفاده
هستند که از MFC یا Microsoft Foundation Classes پشتیبانی کنن. در کنار این نوع Dll ها ، MFCِDll به صورت
static و یا Shared قرار میگیرن.(گرچه نوع Regular در محدوده ی بیشتری فعالیت میکنه.)
3- نوع سوم همون ClassLibrary هست که در موردش خیلی صحبت شد.
بازم سلام
تا اونجايي كه من متوجه شدم چون Dll من از ابتدا براي اضافه شدن فرمnet. به اون خطايي مبني بر اين مي داد كه managed application فقط مي توانند به managed project اضافه بشن و نياز به yes كردن use manage extension داشت يك dll مديريت نشده بود
وبا توجه به اينكه نمي شد mfc application به اون اضافه كرد از نوع mfc dll نبود
و چون مديريت نشده است پس نمي شه از نوع class library باشه پس حتما win32dllاست ( اگه روش ديگه اي در c++.net براي ساخت dll نباشه) طبق گفته شمااگه مي شه روش ساخت يك win32dllرو به صورت مختصر توضيح بديننقل قول:
فرم mfc application تنها به پروژه هاي mfcمي تواند اضافه شود " میتونه یه Win32Dll باشه.
که برای اضافه کردن Form به اون باید از طریق Resource ها این کار رو انجام بدین. البته اجباری نیست.
اما نمیشه به اون کلاس های MFC رو اضافه کرد. مگر در هنگام ایجاد این نوع Dll اجازه ی استفاده از MFC
رو بدیم.
با تشكر
خب ، روش کار به این صورت هست :
وقتی پروژه جدید ایجاد کردین از ProjectType و ++VC گزینه ی Win32 رو انتخاب کنین.
از Tempalte گزینه Win32Project رو انتخاب کنین و اسمی براش در نظر بگیرین.
در Dialogی که باز میشه یه مرحله به جلو برین و از ApplicationType گزینه Dll رو انتخاب کنین.
میتونین اجازه بدین که Dll شما از Header های MFC هم استفاده کنه. ولی فعلا با این گزینه کار نداریم.
کافیه روی Finish کلیک کنین.
اگه کد Dll رو ببینین متوجه میشین که برای Export کردن یه تابع از درون Dll از ماکروی decspec__ استفاده
میشه. واین تفاوتی هست که یه Win32Dll با ClassLibrary داره.
در ClassLibrary شما فقط کدتون رو مینوسین و در نهایت بدون اینکه چیزی رو Export کنین به تمامی Object
های این ClassLibrary دسترسی دارین. چون به صورت یه Reference به برنامه ای که قرار ازش استفاده کنه
اضاف میشه.
سلام
ممنون از توجه تون
در مورد dll جواب منو صريح ندادين از روي جمع بنديهايي كه كردم نظر شما اينه كه اين dll قطعأ win32dll است؟
با توجه به اينكه در قسمت entrypoint اون _decspec رو نداره فقط در فايل def اين دو روال export شده اند:
کد:LIBRARY Step01
EXPORTS
acrxEntryPoint PRIVATE
acrxGetApiVersion PRIVATE
و كد entrypoint هم به صورت زير است:(استفاده از objecrarx)
کد:extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
default:
break;
}
return AcRx::kRetOK;
}
دوباره سلام.
فکر کنم از روی صحبتهایی که با هم داشتیم مشخص بود.
بله! این یه Win32Dll سفارشی برای Cad هست. (به EntryPoint ش توجه کنین.)
اما در مورد declspec__ :
در موردش چندین بار صحبت کردیم. اگه هم به اسناد Arx مراجعه کنین میبینین که به این نکته اشاره کرده
یا از DEF فایل و یا از declspec__ استفاده کنین. که هر دو اینها برای Export یه تابع خاص از یه Dll به کار میرن.
ممنون از توجه تون
بازم به مشكل جديدي برخورد كردم وقتي پروژه رو تو vs باز ميكنم تا روش كار انجام بدم وقتي مي خوام فرم رو باز كنم تا تغييراتي روش بدم مثلا كامپوننتي اضافه و كم كنم فرم رو نشون نمي ده به جاي اون يه صفحه سفيد با علامت error مي ياد (دايره قرمزي با ضربدر سفيد) كه خطاي زير رو داره:
MCppCodeDomParser Error:
وقتي هم پروژه رو مي بندم و دوباره باز مي كنم و يا سيستم رو ري ست مي كنم مشكل همچنان باقيه
خطا در توضيح بيشتر به صورت زير است:
an error acuured while loading the document . fix
the error and then try loading the document a again the error message follows
: MCppCodeDOMParser Error
ممنون از توجه تون
بازم به مشكل جديدي برخورد كردم وقتي پروژه رو تو vs باز ميكنم تا روش كار انجام بدم وقتي مي خوام فرم رو باز كنم تا تغييراتي روش بدم مثلا كامپوننتي اضافه و كم كنم فرم رو نشون نمي ده به جاي اون يه صفحه سفيد با علامت error مي ياد (دايره قرمزي با ضربدر سفيد) كه خطاي زير رو داره:
MCppCodeDomParser Error:
وقتي هم پروژه رو مي بندم و دوباره باز مي كنم و يا سيستم رو ري ست مي كنم مشكل همچنان باقيه
خطا در توضيح بيشتر به صورت زير است:
an error acuured while loading the document . fix
the error and then try loading the document a again the error message follows
: MCppCodeDOMParser Error
اما موقع اجرا مشكلي نداره و امكان ويرايش كد هم وجود داره تنها نمي شه فرم رو تو محيط vsديد و ويرايش كرد
بازم سلام
من به يه چيزي پي بردم كه نمي دونم درسته يا نه . فكر مي كنم وقتي كه به( void InitializeComponent(void
چيزي اضافه مي كنم چنين مشكلي پيش مي ياد مثلا وقتي oleDbConnection1->Open() رو به انتهاي اين روال اضافه مي كنم
اين مورد رو هم تو جستجو هام پيدا كردم:
نقل قول:
for no apparent reason when trying to open a form in designer mode the
following
error is occuring:
'An error occurred when loading the document. Fix the error and reload the
document. The error message follows:
MCppCodeDomParser error'
The solution still builds and runs ok and controls can be added or modified
programatically but no 'designer' facility available.
اگر درست فكر مي كنم بگين من بايد open كردن connection رو كجا قرار بدم كه مجبور نباشم تو هر روال مثل كليك دكمه كه با بانك كار دارم اونو باز و انتهاي روال اونو ببندم؟ تو vb.net من اين كد رو تو قسمت pageload مي گذلشتم و مشكلي هم پيش نمي اومدنقل قول:
There might be some lines of code in the InitializeComponent method of your
Form that cannot be parsed back by the Form Designer.
Have you added yourself some lines of code to this method?
If yes, I would suggest you to comment them out step by step until the Form
Designer reopens again. It may help you find out the lines that cannot be
parsed.
اگر درست نيست بگين مشكل لود فرم چطور حل مي شه و اصلا چرا پيش مي ياد
ممنون از توجه تون
دوباره سلام.
بابت این همه تاخیر میبخشین.
البته امیدوارم مشکل هایی که براتون پیش اومده بود حل شده باشن
نقل قول:
MCppCodeDOMParser Error
در مورد این error باید بگم به نظر میرسه که شما designer تون رودستکاری کردین.
وقتی کنترلی رو فرمتون اضافه میکنین در Designer کدی به برنامهاضافه میشه
اگه تونستین تغییراتی که در Designer وجود داره رو پیدا کنیناصلاحشون کنین. و اگه نشد تنها راهی که وجود
داره اینکه یه پروژه جدید ایجاد کنین و کدهای قبلی تون رو در اینپروژه جدید کپی کنین.
خب خیلی جالبه! من اول پست ها ی قبلیتون رو خوندم !
شما دقیقا Designer رو دستکاری کردین!!!
برای اینکه در هنگام Load شدن فرمتون بتونین کدی رو اجرا کنین باید اون رو در مثلا در Constructor کلاس
Form قرار بدین. مثلا در جایی که TODO قرار گرفته :
کد:
public:
Form1(void)
**
InitializeComponent();
//
//TODO: Add the constructor code here
//
سلام
خسته نباشيد
در مورد كد مربوط به connectionطبق گفته شما كد رو به صورت زير تغيير دادم:
ولي مشكلي كه پيش مي ياد اينه كه تو روال هاي مربوط به كامپوننتها مثل روال كليك button اين متغير( oleDbConnection1 ) شناخته شده نيستکد:public:
Form1(void)
{
InitializeComponent();
String* myConnString = S"Integrated Security=SSPI;Data Source=(local);Initial Catalog=cad;Provider=SQLOLEDB.1;Persist Security Info=False";
OleDbConnection* oleDbConnection1 = new OleDbConnection(myConnString);
oleDbConnection1->open();
}
protected:
نمي دونم شايد منظور شما رو متوجه نشدم
هدف من اينه كه اين تعريف connectionstring و باز كردن بانك يكبار انجام بشه نه اينكه در هر روال مجبور باشم دوباره كاري كنم
بازم ممنون از توجهتون
کاری که انجام دادین درسته.
اما field ی که تعریف کردین (oleDbConnection1 ) باید یه public Field باشه به طوری که تمامی متود های
کلاستون ، بتونن ازشون استفاده کنن.
کد:
public:
Form1(void)
{
String* myConnString = S"connection string"
oleDbConnection1 = new OleDbConnection(myConnString);
oleDbConnection1->open();
}
.
.
.
private:
OleDbConnection* oleDbConnection1;
سلام دوباره
ممنون مشكلم حل شد(البته كدي رو كه قرمز كرده بوديد oleDbConnection1 = new OleDbConnection(myConnString); رو هم گذاشتم چون بدون اون خطا مي داد نمي دونم منظور شما همين بود يا نه .البته به نظرم مي ياد اگه هر دو كدي رو كه شما قرمز كرديد بنويسيم دوبار oledbconnection رو تعريف كرديم اينطور نيست؟
فقط يه سوال برام پيش اومده اگه شما مي گين بايد oledbconnection1 به صورت public باشه كه تو همه روالها شناخته شده بشه. پس چرا اونو توprivate تعريف كرديم و تو public مقداردهي؟
و ديگه اينكه براي اتصال رشته اتصال رو به connectionمون نسبت نداديم پس چطور متوجه مي شه به كدوم بانك بايد وصل بشه؟
مثلا اگه بخوايم از دو بانك استفاده كنيم و دو رشته اتصال تو كد تعريف كنيم با ايجاد يك connection به صورتي كه تو privateگذاشتين به دو بانك وصل مي شه؟
دوباره سلام.کدهایی رو که به رنگ قرمز نوشتم ، برای این بود که تغییرات رو نشون بدم.شما متغییر رو public تعریف میکنین و اولین بار در متود Form از اون یه نمونه میسازین و بعد میتونین از این نمونه در سایر متود ها استفاده کنین. وقتی Field ی رو به صورت private تعریف کنین فقط در کلاس مورد نظر دیده میشه. اگه بخواین از این Field در سایرکلاسها استفاده کنین ، امکانش وجود نداره.بنابراین وقتی Field مورد نظر رو به صورت private تعریف کنین ، میتونین در تمامی متود کلاس استفاده کنین.چون رشته ای که تو کدتون گذاشتین طولانی بود ، من دیگه تکرارش نکردم. ولی مطمئنا باید این رشته وجود داشته باشه. میتونین کاری که گفتین رو انجام بدین.فرق بین private و public تنها در oscope شون هست.اگه تنها یه کلاس دارین و از متغغیر هایی که تعریف میکنین تنها در همین کلاس استفاده میکنین ، از privateاستفاده کنین.
ممنون
چون اسم اين تاپيك نمايش فرم در dllاست ديگه سوالات بانك رو اينجا مطرح نمي كنم
ولي در مورد private اگه من كد رو به صورت زير بنويسم:
اگه يه class form .netديگه به پروژه اضافه كنم . مي تونم بدون تعريف دوبارهoledbconnection1 تو هدر اون به بانك وصل بشم؟کد:public:
Form1(void)
{
String* myConnString = S"connection string"
oleDbConnection1 = new OleDbConnection(myConnString);
oleDbConnection1->open();
}
.
.
.
public:
OleDbConnection* oleDbConnection1;
بازهم با messagebox مشكل پيدا كردم ولي ايندفعه مي خوام از messagebox خروجي بگيرم يعني كدي به صورت زير داشته باشم كه اگه كاربر okاز messageboxرو كليك كرد يه سري كد خاص اجرا بشه :
کد:if (MessageBox(NULL,"رشته","عنوان",MB_YESNO)==IDYES)
{
ولي موقع buildكردن با خطاي زير مواجه مي شوم :
error C2514: 'System::Windows::Forms::MessageBox' : class has no constructors
ولي اگه messageboxرو به صورت زير به كار ببرم مشكلي ندارم :
البته طبق پستهاي قبل #undef MessageBox رو لحاظ كردم مي خواستم بدونم ايم مشكل چرا به وجود مي ياد و راه حل رفعش چيهکد:MessageBox::Show("رشته","عنوان",
MessageBoxButtons::OK,
MessageBoxIcon::Information);
سوال ديگه اينكه من در كد اولي متد showرو استفاده نكردم پس اگه فرض كنيم تعريف درست اجرا مي شد messageboxنمايش داده مي شد؟
دوباره سلام.
مشکلی که پیش میاد به دلیل استفاده از undef# هست.
برای استفاده مجدد از MessageBox باید دوباره اون رو define کنین. البته با استفاده از دو ماکرو pragma و
push_macro و pop_macro که استفاده ازش مقداری دردسر داره.
اگه نظر من رو بخواین ساده ترین راه استفاده از MessageBoxW و یا MessageBoxA هست.
اگه به تعریف این دو تابع در Header شون توجه کنین چیزی شبیه این رو میبینین :
که در صورتی که از Unicode استفاده کنین (که شما استفاده میکنین) باید از MessageBoxW استفاده بشه.کد:
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
یعنی به جای استفاده از MessageBox بنویسین MessageBoxW . به این شکل :
برای استفاده از T_ باید tchar.h رو به ابتدای برنامه اضافه کنین.کد:
MessageBoxW(null,_T(your-string),_T(your-string),MB_YESNO)
ضمنا در property پروژه تون character Set رو روی Use Unicode بذارین.
كد رو طبق گفته شما به صورت زير تغيير دادم:
و charactersetرو هم همينطور ولي خطاي زير رو ايجاد كرد:کد:int k;
k =MessageBoxW(NULL,_T("رشته"),_T("پيام"),MB_YESNO);
Step01 error LNK2001: unresolved external symbol "int __stdcall MessageBoxW(struct HWND__ *,unsigned short const *,unsigned short const *,unsigned int)" (?MessageBoxW@@$$J216YGHPAUHWND__@@PBG1I@Z)
Step01 fatal error LNK1120: 1 unresolved externals