گفتگو هایی در باب سی شارپ

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام مجدد
استاد علی ، چرا توی این کد وقتی در نخ جدید ، تایمر رو فراخونی میکنیم ، کار نمیکنه؟ هر دو نوع overload متد SuspendThread3 رو تست کردم با دو نوع فراخونی متفاوت تایمر، ولی نشد :


کد:
    public partial class Form1 : Form
    {
        Thread suspendThread_2;

        public Form1()
        {
            InitializeComponent();
            threadDelegate2 = new ParameterizedThreadStart(SuspendThread3);
        }

        public void SuspendThread3()
        {
            MessageBox.Show("1");
            timerSuspendThread.Enabled = true;
            //MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in thread");

            suspendThread_2.Suspend();
            MessageBox.Show("2");
            suspendThread_2.Suspend();
            MessageBox.Show("3");
            suspendThread_2.Suspend();
            MessageBox.Show("4");
        }

        public void SuspendThread3(object controlObj)
        {
            MessageBox.Show("1");
            ((System.Windows.Forms.Timer)controlObj).Enabled = true;
            //MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in thread");

            suspendThread_2.Suspend();
            MessageBox.Show("2");
            suspendThread_2.Suspend();
            MessageBox.Show("3");
            suspendThread_2.Suspend();
            MessageBox.Show("4");
        }

        private void btnThread3Timer_Suspend_Click(object sender, EventArgs e)
        {
            suspendThread_2 = new Thread(threadDelegate2);
            suspendThread_2.Start(timerSuspendThread);
            MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in function");
        }

        private void timerSuspendThread_Tick(object sender, EventArgs e)
        {
            MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in timer");
            if (suspendThread_2.ThreadState != System.Threading.ThreadState.Stopped)
            {
                suspendThread_2.Resume();
            }
        }
    }

ولی وقتی در خط سوم متد SuspendThread3 ، کد MessageBox.Show رو از کامنت در میارم ، تایمر هم اجرا میشه. چرا و مشکلش چیه ؟؟!!!
دوم اینکه چرا در یک نخ مجزا و جدید (مثلا همین SuspendThread3 که بدون آرگومان هست) ، اگه یه شی ای بدیم که به کنترل Form1 مربوط میشه (مثلا this یا مثلا this.Handel و از این جور چیزا) ، ارور میده که از یک نخ دیگه دارین به نخی که کنترل Form1 رو فراخونی کردین ، دسترسی پیدا میکنین و یه همچین اروری (عکس ارور رو پیوست کردم) . یعنی توی این متد اگه فراخونی شه ، ارور میده: چرا؟ :

کد:
public void SuspendThread3(object controlObj)
        {
            MessageBox.Show("1");
            ((System.Windows.Forms.Timer)controlObj).Enabled = true;
            MessageBox.Show(owner: this, text: suspendThread_2.ThreadState.ToString(), caption: "in thread");
            suspendThread_2.Suspend();
        }

ولی اگه با استفاده از دلیگیت ParameterizedThreadStart ، در ورودی اون متد (نخ) ، شی رو بصورت object بدیم ، مشکلی وجود نداره
و اینکه کلا با چه شی هایی دقیقا مشکل داره؟ من فقط دیدم با شی Form1 (یعنی this) و شی Intptr (یعنی this.Handel) مشکل داره .
 

پیوست ها

  • Capture.JPG
    Capture.JPG
    38.4 کیلوبایت · بازدیدها: 2

the_king

مدیرکل انجمن
ممنون استاد علی
میگم الان توی پردازنده ها که نخ وجود داره (مثلا پردازنده های 2 یا 4 یا 8 نخی) ، همین قضیه ی نخ ها هستن که استفاده میکنیم؟ یعنی مثلا پردازنده ی 4 نخی ، همزمان میتونه 4 نخ رو اجرا کنه؟
اگه آره ، 2 تا سئوال دارم :
بله ولی چند تا نکته وجود داره، اولا یک هسته معمولا معادل یک نخ اجرایی نیست، فرضا یک هسته می تونه دو نخ همزمان رو اجرا کنه، یعنی یک پردازنده 4 هسته ای جمعا 8 نخی ئه. ثانیا پردازنده معمولا نمی تونه روی دو تا هسته مجزا نخ های یک پروسه رو اجرا کنه، باید روی یک هسته اجرا بشن، معنی اش اینه که اگه برنامه تون 10 تا نخ هم باشه، روی یک هسته و فقط دو تا نخ همزمان کار می کنه. اگه پردازنده 4 هسته ای باشه تنها از یک چهارم توان پردازنده کار می کشه.
برنامه هایی که برای استفاده از سیستم های چند هسته ای طراحی می شوند اصول خاصی رو رعایت می کنند، اولا مناسب هر برنامه ای نیست و ثانیا بیشتر از یک پروسه دارند، یعنی فرضا از یه فایل اجرایی بیش از یک نسخه رو اجرا می کنند، برای اینکار هماهنگی پروسه ها و نخ ها خودش مساله مهمیه.

اول اینکه اگه مثلا 4 نخ همزمان نوشته باشیم (که همه شونو Start زده باشیم پی در پی) ، ولی پردازنده ، 2 نخی باشه ؛ اول میاد 2 تای اولی رو اجرا و بعد ، 2 تای دیگه رو اجرا میکنه دیگه؟
اولا همانطور که گفتم در نظر بگیرید که هر هسته فرضا 2 نخ رو همزمان اجرا می کنه. اگه تعداد نخ های سیستم واگذار شده به یک نخ فیزیکی پردازنده رو در نظر بگیرید، یه کسر کوچیکی از ثانیه یکی شون رو اجرا می کنه، متوقف اش می کنه، میره سراغ نخ بعدی و یه کسری از ثانیه اونو اجرا می کنه و ... عملا همزمانی اجرا فقط برای نخ های فیزیکی ئه، اون چیزی که بین این هزاران نخ سیستم می بینید واقعا اجرای موازی نیست. سوئیچ کردن های فوق العاده سریع ئه.
دوم اینکه پس توی Task Manager توی سربرگ Performance چیه که یه قسمت نوشته Thread و عددی بالای 1000 همیشه نوشته میشه و دائم تغییر میکنه؟ مثلا الان برای من نوشته 1384 که دائم هم تغییر میکنه! اگه تعداد کل نخ های نوشته شده در برنامه ها و سیستم عامل و اپلیکشن هایی باشه که تا حالا اجرا شد ، پس نباید کم بشه ولی این مدام در حال کم و زیاد شدنه !
اولا خیلی از سرویس ها مدام اجرا می شوند و متوقف می شوند، یعنی تعداد پروسه ها و در نتیجه نخ ها ثابت نیست. ثانیا اگر یک پروسه ای هم مدام در حال اجرا است، دلیل نمیشه که تعداد نخ های درخواستی اش ثابت بشه، فرضا زمانی که یک رویدااد خاص رخ داد درخواست نخ جدید می کنه و بعد چند لحظه که کار نخ تموم شد نخ نابود میشه. اینطوری نیست که همون اول اجرا 10 تا نخ بسازه و تا آخر اجرا همون 10 نخ در حال اجرا بمونه.
 

the_king

مدیرکل انجمن
سلام مجدد
استاد علی ، چرا توی این کد وقتی در نخ جدید ، تایمر رو فراخونی میکنیم ، کار نمیکنه؟ هر دو نوع overload متد SuspendThread3 رو تست کردم با دو نوع فراخونی متفاوت تایمر، ولی نشد :


کد:
    public partial class Form1 : Form
    {
        Thread suspendThread_2;

        public Form1()
        {
            InitializeComponent();
            threadDelegate2 = new ParameterizedThreadStart(SuspendThread3);
        }

        public void SuspendThread3()
        {
            MessageBox.Show("1");
            timerSuspendThread.Enabled = true;
            //MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in thread");

            suspendThread_2.Suspend();
            MessageBox.Show("2");
            suspendThread_2.Suspend();
            MessageBox.Show("3");
            suspendThread_2.Suspend();
            MessageBox.Show("4");
        }

        public void SuspendThread3(object controlObj)
        {
            MessageBox.Show("1");
            ((System.Windows.Forms.Timer)controlObj).Enabled = true;
            //MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in thread");

            suspendThread_2.Suspend();
            MessageBox.Show("2");
            suspendThread_2.Suspend();
            MessageBox.Show("3");
            suspendThread_2.Suspend();
            MessageBox.Show("4");
        }

        private void btnThread3Timer_Suspend_Click(object sender, EventArgs e)
        {
            suspendThread_2 = new Thread(threadDelegate2);
            suspendThread_2.Start(timerSuspendThread);
            MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in function");
        }

        private void timerSuspendThread_Tick(object sender, EventArgs e)
        {
            MessageBox.Show(suspendThread_2.ThreadState.ToString(), "in timer");
            if (suspendThread_2.ThreadState != System.Threading.ThreadState.Stopped)
            {
                suspendThread_2.Resume();
            }
        }
    }

ولی وقتی در خط سوم متد SuspendThread3 ، کد MessageBox.Show رو از کامنت در میارم ، تایمر هم اجرا میشه. چرا و مشکلش چیه ؟؟!!!
دوم اینکه چرا در یک نخ مجزا و جدید (مثلا همین SuspendThread3 که بدون آرگومان هست) ، اگه یه شی ای بدیم که به کنترل Form1 مربوط میشه (مثلا this یا مثلا this.Handel و از این جور چیزا) ، ارور میده که از یک نخ دیگه دارین به نخی که کنترل Form1 رو فراخونی کردین ، دسترسی پیدا میکنین و یه همچین اروری (عکس ارور رو پیوست کردم) . یعنی توی این متد اگه فراخونی شه ، ارور میده: چرا؟ :

کد:
public void SuspendThread3(object controlObj)
        {
            MessageBox.Show("1");
            ((System.Windows.Forms.Timer)controlObj).Enabled = true;
            MessageBox.Show(owner: this, text: suspendThread_2.ThreadState.ToString(), caption: "in thread");
            suspendThread_2.Suspend();
        }

ولی اگه با استفاده از دلیگیت ParameterizedThreadStart ، در ورودی اون متد (نخ) ، شی رو بصورت object بدیم ، مشکلی وجود نداره
و اینکه کلا با چه شی هایی دقیقا مشکل داره؟ من فقط دیدم با شی Form1 (یعنی this) و شی Intptr (یعنی this.Handel) مشکل داره .
نخ شما اجازه نداره که کمپوننت Timer روی فرم رو Enable کنه، قبلا عرض کردم خدمتتون، کنترل ها و کمپوننت های روی فرم معمولا از نخ دیگه ای قابل دسترسی نیستند، بجز برخی از پروپرتی ها. در حالت کلی از اینکار اجتناب کنید. یه لیست باکس روی فرم قرار بدید :
کد:
    public partial class Form1 : Form
    {
        Thread suspendThread_2;
        ParameterizedThreadStart threadDelegate2;

        private void ShowInfo(object info)
        {
            if (InvokeRequired)
            {
                Invoke(new ParameterizedThreadStart(ShowInfo), info);
            }
            else
            {
                listBox1.Items.Add(info);
                listBox1.TopIndex = listBox1.Items.Count - 1;
            }
        }

        private void StartTimer(object timer)
        {
            ((System.Windows.Forms.Timer)timer).Enabled = true;
        }

        public Form1()
        {
            InitializeComponent();
            threadDelegate2 = new ParameterizedThreadStart(SuspendThread3);
        }

        public void SuspendThread3()
        {
            ShowInfo("1");
            Invoke(new ParameterizedThreadStart(StartTimer), timerSuspendThread);
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in thread");
            suspendThread_2.Suspend();
            ShowInfo("2");
            suspendThread_2.Suspend();
            ShowInfo("3");
            suspendThread_2.Suspend();
            ShowInfo("4");
        }

        public void SuspendThread3(object controlObj)
        {
            ShowInfo("1");
            Invoke(new ParameterizedThreadStart(StartTimer), controlObj);
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in thread");
            suspendThread_2.Suspend();
            ShowInfo("2");
            suspendThread_2.Suspend();
            ShowInfo("3");
            suspendThread_2.Suspend();
            ShowInfo("4");
        }

        private void btnThread3Timer_Suspend_Click(object sender, EventArgs e)
        {
            suspendThread_2 = new Thread(threadDelegate2);
            suspendThread_2.Start(timerSuspendThread);
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in function");
        }

        private void timerSuspendThread_Tick(object sender, EventArgs e)
        {
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in timer");
            if (suspendThread_2.ThreadState != System.Threading.ThreadState.Stopped)
            {
                suspendThread_2.Resume();
            }
        }
    }
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
نخ شما اجازه نداره که کمپوننت Timer روی فرم رو Enable کنه، قبلا عرض کردم خدمتتون، کنترل ها و کمپوننت های روی فرم معمولا از نخ دیگه ای قابل دسترسی نیستند، بجز برخی از پروپرتی ها.
سلام
ممنون استاد علی
خوب ، چرا؟
دوم اینکه فقط اعضای کنترل ها وکمپوننت ها هستن؟
بعد اینکه ، راه حلش ، استفاده از همون متد Invoke هستش دیگه؟ که متدی رو در نخ اصلی اجرا میکنه
بعد اینکه ، این جوری نخ درست کردن که خیلی سخت میشه . مثلا آدم بخواد 100 تا متد و پروپرتی از اعضای کنترل و کمپوننت رو فراخونی کنه ، باید 100 بار توی متد Invoke این کار رو کنه؟! این جوری عطایش به لقایش میصرفه
:green:

در حالت کلی از اینکار اجتناب کنید. یه لیست باکس روی فرم قرار بدید :
کد:
    public partial class Form1 : Form
    {
        Thread suspendThread_2;
        ParameterizedThreadStart threadDelegate2;

        private void ShowInfo(object info)
        {
            if (InvokeRequired)
            {
                Invoke(new ParameterizedThreadStart(ShowInfo), info);
            }
            else
            {
                listBox1.Items.Add(info);
                listBox1.TopIndex = listBox1.Items.Count - 1;
            }
        }

        private void StartTimer(object timer)
        {
            ((System.Windows.Forms.Timer)timer).Enabled = true;
        }

        public Form1()
        {
            InitializeComponent();
            threadDelegate2 = new ParameterizedThreadStart(SuspendThread3);
        }

        public void SuspendThread3()
        {
            ShowInfo("1");
            Invoke(new ParameterizedThreadStart(StartTimer), timerSuspendThread);
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in thread");
            suspendThread_2.Suspend();
            ShowInfo("2");
            suspendThread_2.Suspend();
            ShowInfo("3");
            suspendThread_2.Suspend();
            ShowInfo("4");
        }

        public void SuspendThread3(object controlObj)
        {
            ShowInfo("1");
            Invoke(new ParameterizedThreadStart(StartTimer), controlObj);
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in thread");
            suspendThread_2.Suspend();
            ShowInfo("2");
            suspendThread_2.Suspend();
            ShowInfo("3");
            suspendThread_2.Suspend();
            ShowInfo("4");
        }

        private void btnThread3Timer_Suspend_Click(object sender, EventArgs e)
        {
            suspendThread_2 = new Thread(threadDelegate2);
            suspendThread_2.Start(timerSuspendThread);
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in function");
        }

        private void timerSuspendThread_Tick(object sender, EventArgs e)
        {
            ShowInfo(suspendThread_2.ThreadState.ToString() + " in timer");
            if (suspendThread_2.ThreadState != System.Threading.ThreadState.Stopped)
            {
                suspendThread_2.Resume();
            }
        }
    }

این متد InvokeRequired رو قشنگ نفهمیدم . توی توضیحاتش گفته ، چک میکنه ببینه که آیا فراخونی باید در متد Invoke صورت بگیره یا نه؟ درست گفتم؟ اگه آره ، منظورش اینه که فراخونی متد جاری رو چک میکنه که نیاز به استفاده در متد Invoke داره؟ مثلا ما بخوایم بدونیم فرضا همون پروپرتی Enable در کلاس Timer نیاز به فراخونی در متد Invoke داره ، باید چی کار کنیم؟
 

the_king

مدیرکل انجمن
سلام
ممنون استاد علی
خوب ، چرا؟

چون Thread-Safe نیستند. این واژه Thread-Safe از نظر فنی یعنی طراحی کد طوری صورت گرفته که اجرای موازی اش در چندین نخ مشکلی ایجاد نمی کنه. کنترل و کامپوننت های روی فرم طراحی Thread-Safe ندارند، خاص #C و NET. هم نیست. از همون ابتدا که سیستم عامل ویندوز طراحی میشد فرض رو بر این قرار دادند که یک نخ اجرا کننده عملیات فرم ئه و Thread-Safe رو برای کنترل های روی فرم در نظر نگرفته اند.

دوم اینکه فقط اعضای کنترل ها وکمپوننت ها هستن؟

عملیات عمومی روی فرم چیز خاصی بجز اینها نیست، اگر مورد دیگه ای سراغ دارید که مربوط به عملیات فرم ها است اونها رو هم جز همین ها در نظر بگیرید.


بعد اینکه ، راه حلش ، استفاده از همون متد Invoke هستش دیگه؟ که متدی رو در نخ اصلی اجرا میکنه

بله دیگه، در کل یا باید کنترلی بسازید و بکار ببرید که خودش Thread-Safe باشه و یا از کنترل هایی که Thread-Safe نیستند فقط توسط Thread اصلی شون کار بگیرید. راه حل دیگه نداره.
کد این کنترل ها مثل کد هایی است که خودتان می نویسید، این یه مثال ساده است :
کد:
        private int x = 0;

        private void Test()
        {
            int y = x;
            x = y + 1;
        }
این متد به سادگی مقدار x رو یک واحد افزایش میده ولی برای اجرای یک نخ طراحی شده. اگر دو تا نخ مجزا بخواهند Test رو اجرا کنند، هیچ تضمینی وجود نداره که قابل از پایان اجرای یک نخ، نخ بعدی اجراش رو شروع نکنه و در نتیجه ممکنه در مجموع x دو واحد افزایش پیدا نکنه. ممکنه همون لحظه که اجرای نخ اولی سطر یکم رو رد کرد دومی اجراش شروع بشه و تموم بشه. مقدار x توسط نخ دوم یک واحد افزایش پیدا کرده ولی در نخ اولی مقدار y مقدار قبلی x باقی مونده و افزایشی نداشته. در نتیجه نخ اول مقدار x رو یک واحد افزایش میده و حاصل عملیات نخ دوم نادیده گرفته میشه. همچین کدی Thread-Safe نیست، چون برای دسترسی همزمان به منبع x به اصطلاح انحصار متقابل رو رعایت نکرده. مباحث موازی سازی و انحصار متقابل خیلی مفصل اند، اندازه چندین کتاب مطلب دارند.


بعد اینکه ، این جوری نخ درست کردن که خیلی سخت میشه . مثلا آدم بخواد 100 تا متد و پروپرتی از اعضای کنترل و کمپوننت رو فراخونی کنه ، باید 100 بار توی متد Invoke این کار رو کنه؟! این جوری عطایش به لقایش میصرفه
:green:
این چیزی که میگید سخته ربطی به نخ ساختن نداره، کار بیخود و اضافی است. اگر بخواهید 100 تا نخ بسازید که اصلا کار تون اشتباهه، اما اگر بخواهید چهار تا نخ بسازید که در هر کدوم 100 تا پروپرتی چک بشه، خوب چهار تا Invoke لازم دارید، نه 100 تا Invoke . اینکه بیایید برای 100 تا پروپرتی دونه دونه Invoke بسازید عملا همون ساختن کنترل Thread-Safe ئه، که نه مرسوم ئه و نه لازم و نه کارایی مناسبی داره. معمولا تغییر مقادیر پروپرتی ها باعث تغییر ظاهر گرافیکی میشه، اگر قرار باشه کاری مرتبط با ظاهر گرافیکی فرم باشه اصلا چه دلیلی داره که در نخ مجزایی انجام بشه، نخ ساختن برای کاری است که قرار پشت پرده انجام بشه، برای کاری که قراره جلوی چشم کاربر انجام بشه که نخ مجزا نمیخواد.

این متد InvokeRequired رو قشنگ نفهمیدم . توی توضیحاتش گفته ، چک میکنه ببینه که آیا فراخونی باید در متد Invoke صورت بگیره یا نه؟ درست گفتم؟ اگه آره ، منظورش اینه که فراخونی متد جاری رو چک میکنه که نیاز به استفاده در متد Invoke داره؟ مثلا ما بخوایم بدونیم فرضا همون پروپرتی Enable در کلاس Timer نیاز به فراخونی در متد Invoke داره ، باید چی کار کنیم؟
بله، دقیقا کاری که می کنه چک می کنه که نخ فعلی همون نخ اصلی فرم هست یا نه، اگه بود که false رو برمی گردونه (یعنی نیازی به Invoke نبوده) وگرنه true بر می گردونه. کارش در همین حد ساده است. هیچ مشخصاتی در مورد پروپرتی ها نداره، همانطور که وقتی شما پروپرتی می سازید در توضیحاتش ننوشته اید که Thread-Safe هست یا نه، همچین اطلاعاتی در دسترس InvokeRequired هم نیست.
این InvokeRequired داره بر اساس مقایسه نخ ها تصمیم می گیره، نه پروپرتی ها، برایش پروپرتی خاصی مطرح نیست. اولا Timer یک کمپوننت ئه و کنترل نیست، پس خودش Invoke نداره و هیچ کاربردی برای InvokeRequired نداره. ثانیا شما با Form.InvokeRequired فقط این رو تشخیص می دهید که الان در اجرای نخ اصلی فرم هستید یا خیر. روی هیچ پروپرتی خاصی نمی توانید چک اختصاصی انجام بدید، عرض کردم، همواره فرض رو بر این قرار بدید که Thread-Safe نیستند، مگر در حالتی که طبق تجربه می دانید فلان مورد خاص رو شامل نمیشه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
ممنون
استاد علی ، نمیشه توی سی شارپ ، بجای اینکه وقتی میخوایم کنترلی (مثلا دکمه) رو به پروژه اضافه کنیم ، اینکه نام شی کانتینر مورد نظر رو ببریم (که بعد با استفاده از پروپرتی Controls اش ، کنترل مون رو اضافه کنیم) ، بجاش شی ای از Intptr یا شماره ای که کلا شامل هندل فرم یا کنتینر مورد نظر هست رو ببریم و از این طریق بشه کنترلی به کانتینرمون اضافه کنیم؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
ممنون
استاد علی ، نمیشه توی سی شارپ ، بجای اینکه وقتی میخوایم کنترلی (مثلا دکمه) رو به پروژه اضافه کنیم ، اینکه نام شی کانتینر مورد نظر رو ببریم (که بعد با استفاده از پروپرتی Controls اش ، کنترل مون رو اضافه کنیم) ، بجاش شی ای از Intptr یا شماره ای که کلا شامل هندل فرم یا کنتینر مورد نظر هست رو ببریم و از این طریق بشه کنترلی به کانتینرمون اضافه کنیم؟

پیدا کردم استاد علی
متد استاتیک Control.FromHandle که آرگومان Intptr میگیره ، این کار رو میکنه
تبدیل عدد به IntPtr هم که ضمنی صورت میگیره
مثال رو برای خودم میزارم :


کد:
public void ChangeFormSize(int hWnd, int widthPar, int heightPar)
        {
            IntPtr myIntptr = (IntPtr)hWnd;
            Form myFrm = (Form)Form.FromHandle(myIntptr);
            myFrm.Size = new Size(widthPar, heightPar);
        }

میگم این متدهای استاتیک هم معضلی شدنا . همیشه از غافله ی جستجوهام عقب میمونن . یعنی چون عادت دارم بیشتر با متدهای معمولی کار کنم ، اصلا فراموش میکنم توی جستجوهایی که میکنم ، متدهای استاتیک رو هم جستجو کنم :green:
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
کد بالا رو که بصورت یه dll در اتوپلی درست میکنم ، اگه با استفاده از خود همین dll سی شارپ و کلا با متدهای دات نت ، فرم ایجاد کنم و هندل همون فرم ایجاد شده توسط دات نت رو از اتوپلی به این dll بدم ، مشکلی نداره ولی اگه هندل فرم ای که توسط اتوپلی بوجود اومد رو بهش بدم ، کد بالا کار نمیکنه . یعنی دیگه شی Form در بالا ، در این صورت ، null میشه . چرا؟
راه کاری برای حل اش وجود داره؟
 

the_king

مدیرکل انجمن
کد بالا رو که بصورت یه dll در اتوپلی درست میکنم ، اگه با استفاده از خود همین dll سی شارپ و کلا با متدهای دات نت ، فرم ایجاد کنم و هندل همون فرم ایجاد شده توسط دات نت رو از اتوپلی به این dll بدم ، مشکلی نداره ولی اگه هندل فرم ای که توسط اتوپلی بوجود اومد رو بهش بدم ، کد بالا کار نمیکنه . یعنی دیگه شی Form در بالا ، در این صورت ، null میشه . چرا؟
راه کاری برای حل اش وجود داره؟

Control.FromHandle یکی از امکانات داخل NET. ئه، قرار نیست بتونه بر اساس هر Handle ای شیء کنترل بسازه. با SetParent می توانید Parent کنترل رو بر اساس Handle شون عوض کنید، ربطی هم به NET. بودن و نبودن نداره :
کد:
        [DllImport("user32.dll")]
        private static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        private void button1_Click(object sender, EventArgs e)
        {
            SetParent(listBox1.Handle, panel2.Handle);
        }
کلا اگه می خواهید با امکانات اساسی ویندوز کار کنید باید از API ویندوز استفاده کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
Control.FromHandle یکی از امکانات داخل NET. ئه، قرار نیست بتونه بر اساس هر Handle ای شیء کنترل بسازه. با SetParent می توانید Parent کنترل رو بر اساس Handle شون عوض کنید، ربطی هم به NET. بودن و نبودن نداره :
کد:
        [DllImport("user32.dll")]
        private static extern int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        private void button1_Click(object sender, EventArgs e)
        {
            SetParent(listBox1.Handle, panel2.Handle);
        }
کلا اگه می خواهید با امکانات اساسی ویندوز کار کنید باید از API ویندوز استفاده کنید.

ممنون استاد علی
ولی من قشنگ متوجه نشدم
من منظورم ، پرنت کردن یه کنترل به کنترل دیگه نبود
منظورم اینه که چی کار باید کرد که وقتی هندل فرم ساخته شده در اتوپلی رو به سی شارپ بدیم ، کار کنه؟ (وقتی هندل فرم ساخته شده در سی شارپ رو از اتوپلی باز به خود سی شارپ میدیم ، مشکلی نداره)
هندل فرم های دات نت با فرم های غیر دات نت مگه فرق دارن؟!
 

the_king

مدیرکل انجمن
ممنون استاد علی
ولی من قشنگ متوجه نشدم
من منظورم ، پرنت کردن یه کنترل به کنترل دیگه نبود
منظورم اینه که چی کار باید کرد که وقتی هندل فرم ساخته شده در اتوپلی رو به سی شارپ بدیم ، کار کنه؟ (وقتی هندل فرم ساخته شده در سی شارپ رو از اتوپلی باز به خود سی شارپ میدیم ، مشکلی نداره)
هندل فرم های دات نت با فرم های غیر دات نت مگه فرق دارن؟!
Handle ها فرقی ندارن ولی اون چیزی که شما میگید کار نمی کنه Handle که نیست، متد FromHandle کلاس System.Windows.Forms.Control ئه.
و نیازی به توضیح نیست که System.Windows.Forms.Control یک کلاس NET. ئه. برای Window ای که بیرون از NET. ساخته شده شیء Control ای وجود نداره که بخواهید با FromHandle برگردانده بشه.
شما با FromHandle شیء Control که نمی سازید، شیء ای که هست رو دریافت می کنید. وقتی شیء ای وجود نداره چطور برگردونده بشه؟
اگه کاری رو می خواهید با Handle ها بکنید باید با متد هایی انجام بدید که مرتبط باهاش باشند.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام
ممنون استاد علی . یعنی الان توی دات نت راهی نیست؟ کلا یا باید فرم هایی که با اتوپلی ساخته میشه (که زبان غیر دات نت هست) رو از زبان های غیر دات نت کنترل کرد یا اگه از زبان های دات نت مدیریت میکنیم ، باید از طریق api ها باشه؟
-----------------------------
یه سئوال اینکه کد زیر :

کد:
private void button6_Click(object sender, EventArgs e)
        {
            int[] myOldArray = new int[] { 10, 20, 30 };
            int[] myNewArray = myOldArray;
            myNewArray[0] = 245;
            MessageBox.Show(myOldArray[0] + "");
           
            int[] myOldArrayCollect = new int[] { 10, 20, 30 };
            int[] myNewArrayCollect = myOldArrayCollect;
            myNewArrayCollect = new int[] { 245, 871, 683 };  // کلمه ی کلیدی new باعث میشه که آدرس حافظه ی جدید در رم گرفته بشه
            MessageBox.Show(myOldArrayCollect[0] + "");

            StringBuilder myOldStringBuilder = new StringBuilder("salam");
            StringBuilder myNewStringBuilder = myOldStringBuilder;
            myNewStringBuilder[0] = '[';
            MessageBox.Show(myOldStringBuilder[0].ToString());

            string myOldString = "salam";
            string myNewString = myOldString;
            myNewString = "khodahafez";  // کلمه ی کلیدی new باعث میشه که آدرس حافظه ی جدید در رم گرفته بشه
            MessageBox.Show(myOldString);
        }

من ازش این نتیجه رو میگیرم که کلمه ی کلیدی new کلا باعث میشه حافظه ی جدیدی گرفته بشه . یعنی به این صورت که اگه از قبل ، حافظه ای برای شی ای در نظر گرفته شده بود ، اگه دوباره اون شی رو new کنیم ، باعث نمیشه که حافظه ی قبلی خودش رو در رم از دست بده (درسته؟) بلکه باعث میشه حافظه ی جدید دیگه ای در رم براش در نظر بگیره (در صورتی که حافظه ی قبلی رو که در نظر گرفته بود رو پاک یا اور رایت نکرد و هنوز در رم باقی هست) و به شی مون به آدرس جدید در رم اشاره کنه بنابراین چون اشاره گرش رو به آدرس حافظه ی قبلی از دست داد ، من فکر میکردم که حافظه ی قبلی رو اور رایت کرد در صورتی که این طور نیست . درسته؟
 

the_king

مدیرکل انجمن
سلام
ممنون استاد علی . یعنی الان توی دات نت راهی نیست؟ کلا یا باید فرم هایی که با اتوپلی ساخته میشه (که زبان غیر دات نت هست) رو از زبان های غیر دات نت کنترل کرد یا اگه از زبان های دات نت مدیریت میکنیم ، باید از طریق api ها باشه؟
بعید میدونم همچین راهی باشه، فرمی که توی اتوپلی می سازید یک پنجره است ولی Form در NET. فقط یک پنجره نیست، خیلی از پروپرتی هاش مخصوص خودش اند.
یه سئوال اینکه کد زیر :

کد:
private void button6_Click(object sender, EventArgs e)
        {
            int[] myOldArray = new int[] { 10, 20, 30 };
            int[] myNewArray = myOldArray;
            myNewArray[0] = 245;
            MessageBox.Show(myOldArray[0] + "");
          
            int[] myOldArrayCollect = new int[] { 10, 20, 30 };
            int[] myNewArrayCollect = myOldArrayCollect;
            myNewArrayCollect = new int[] { 245, 871, 683 };  // کلمه ی کلیدی new باعث میشه که آدرس حافظه ی جدید در رم گرفته بشه
            MessageBox.Show(myOldArrayCollect[0] + "");

            StringBuilder myOldStringBuilder = new StringBuilder("salam");
            StringBuilder myNewStringBuilder = myOldStringBuilder;
            myNewStringBuilder[0] = '[';
            MessageBox.Show(myOldStringBuilder[0].ToString());

            string myOldString = "salam";
            string myNewString = myOldString;
            myNewString = "khodahafez";  // کلمه ی کلیدی new باعث میشه که آدرس حافظه ی جدید در رم گرفته بشه
            MessageBox.Show(myOldString);
        }

من ازش این نتیجه رو میگیرم که کلمه ی کلیدی new کلا باعث میشه حافظه ی جدیدی گرفته بشه . یعنی به این صورت که اگه از قبل ، حافظه ای برای شی ای در نظر گرفته شده بود ، اگه دوباره اون شی رو new کنیم ، باعث نمیشه که حافظه ی قبلی خودش رو در رم از دست بده (درسته؟) بلکه باعث میشه حافظه ی جدید دیگه ای در رم براش در نظر بگیره (در صورتی که حافظه ی قبلی رو که در نظر گرفته بود رو پاک یا اور رایت نکرد و هنوز در رم باقی هست) و به شی مون به آدرس جدید در رم اشاره کنه بنابراین چون اشاره گرش رو به آدرس حافظه ی قبلی از دست داد ، من فکر میکردم که حافظه ی قبلی رو اور رایت کرد در صورتی که این طور نیست . درسته؟
هیچ دلیلی برای اینکه حافظه قبلی Overwrite بشه وجود نداره، اصلا ماهیت حافظه اونطور موقعیت های ثابت نیست، مدام در حال جابجایی و تغییر ئه. ممکنه در حین اجرای کد بارها آدرس حافظه یک متغیر در حافظه RAM توسط GC تغییر کنه. تمامی مدیریت حافظه Managed در دست Garbage Collector یا همون GC ئه. قبلا در موردش صحبت کردیم، حافظه ای که دیگه اشاره گری بهش وجود نداشته باشه و بلااستفاده باشه نهایتا از حافظه آزاد میشه ولی اینکه کی اینکار صورت بگیره به اختیار GC ئه. نه پاکسازی آنی صورت می گیره و نه ضمانتی برای overwrite شدن و نشدن وجود داره.
ولی یک امر بدیهی ئه. اینکه به یک متغیر مقدار جدید تخصیص بدید، هیچ ارتباطی با مقدار قبلی اش نداره. یعنی برای GC حتی اهمیتی نداره که حافظه مقدار قبلی اش کجا بود که حالا بخواد overwrite اش بکنه یا نکنه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بعید میدونم همچین راهی باشه، فرمی که توی اتوپلی می سازید یک پنجره است ولی Form در NET. فقط یک پنجره نیست، خیلی از پروپرتی هاش مخصوص خودش اند.

هیچ دلیلی برای اینکه حافظه قبلی Overwrite بشه وجود نداره، اصلا ماهیت حافظه اونطور موقعیت های ثابت نیست، مدام در حال جابجایی و تغییر ئه. ممکنه در حین اجرای کد بارها آدرس حافظه یک متغیر در حافظه RAM توسط GC تغییر کنه. تمامی مدیریت حافظه Managed در دست Garbage Collector یا همون GC ئه. قبلا در موردش صحبت کردیم، حافظه ای که دیگه اشاره گری بهش وجود نداشته باشه و بلااستفاده باشه نهایتا از حافظه آزاد میشه ولی اینکه کی اینکار صورت بگیره به اختیار GC ئه. نه پاکسازی آنی صورت می گیره و نه ضمانتی برای overwrite شدن و نشدن وجود داره.
ولی یک امر بدیهی ئه. اینکه به یک متغیر مقدار جدید تخصیص بدید، هیچ ارتباطی با مقدار قبلی اش نداره. یعنی برای GC حتی اهمیتی نداره که حافظه مقدار قبلی اش کجا بود که حالا بخواد overwrite اش بکنه یا نکنه.

ممنون
آها پس چون در مثال بالا ، در آخر ، هنوز یک اشاره گری (از دو اشاره گر) ازش به مقدار قبلی باقی میمونه (چون فقط یک شی ، new میشد و یکی دیگه به همون شی قبلی اشاره میکرد) ، GC اوررایت اش نمیکنه در غیر این صورت اگه اشاره گری باقی نمونه ، ممکنه موقع ایجاد شی جدید ، قبلی رو اوررایت کنه یا نکنه . درسته؟
 

the_king

مدیرکل انجمن
ممنون
آها پس چون در مثال بالا ، در آخر ، هنوز یک اشاره گری (از دو اشاره گر) ازش به مقدار قبلی باقی میمونه (چون فقط یک شی ، new میشد و یکی دیگه به همون شی قبلی اشاره میکرد) ، GC اوررایت اش نمیکنه در غیر این صورت اگه اشاره گری باقی نمونه ، ممکنه موقع ایجاد شی جدید ، قبلی رو اوررایت کنه یا نکنه . درسته؟
قطعا مادامی که اشاره گری به یک شیء اشاره کنه حافظه اش بصورت خودکار آزاد نمیشه، ولی اصلا این بحث overwrite شدن در مورد GC هیچ موضوعیتی نداره، نه در این مثال و نه در سایر موارد.
گفتم که، ساختن شیء جدید هیچ ارتباطی با overwrite شدن حافظه شیء قبلی نداره. حافظه سیستم اونقدر محدود نیست که GC برای تخصیص حافظه به شیء جدید چشم اش به حافظه شیء قبلی باشه. آزاد شدن حافظه اشیاء بلامصرف یک عملیات تدریجی است با یک زمانبندی غیر قابل پیشبینی و با تاخیر.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
استاد علی ، واقعا از سی شارپ راهی نیست که پنجره های دیگه رو مدیریت کرد؟ مثلا پنجره ی Task Manager رو بشه minimize یا maximize و یا کنترل های داخل اش رو دستکاری و یا close کرد؟!! (البته بجز استفاده از کلاس Proccess
پس توی سی شارپ ، ویروس نویسی باید با مشکل رو به رو بشه چون یکی از انواع ویروس های سطحی یا معمولی ، حداقل دستکاری پنجره های دیگه هست ! با اتوپلی (کمپوننت اتوات و حتی پلاگین های دیگه) میشه این کارها رو کرد !
گذشته از خوبی هایی که سی شارپ داره ولی واقعا دردسر داره وقتی آدم میخواد با کدها و کنترل های Unmanaged و Native Windows کار کنه
حالا اصلا معلوم نیست شدنی هست یا نه
ولی به نظرم امکان نداره نشدنی باشه ها . اصلا برنامه نویسی واسه همین کاراست دیگه . یه زبان وقتی نتونه کنترل کامل کامپیوتر رو اونم هم سیستم عامل و هم زبانی که خود مایکروسافت نوشت رو در اختیار برنامه نویس بذاره که دیگه ....
هر دفعه برای برقراری ارتباط اتوپلی و سی شارپ ، داستان داریم :green:
 

the_king

مدیرکل انجمن
استاد علی ، واقعا از سی شارپ راهی نیست که پنجره های دیگه رو مدیریت کرد؟ مثلا پنجره ی Task Manager رو بشه minimize یا maximize و یا کنترل های داخل اش رو دستکاری و یا close کرد؟!! (البته بجز استفاده از کلاس Proccess
پس توی سی شارپ ، ویروس نویسی باید با مشکل رو به رو بشه چون یکی از انواع ویروس های سطحی یا معمولی ، حداقل دستکاری پنجره های دیگه هست ! با اتوپلی (کمپوننت اتوات و حتی پلاگین های دیگه) میشه این کارها رو کرد !
کلاس Process ربطی به مدیریت پنجره ها نداره. شما با توابع API می توانید هر پنجره ای رو Maximize یا Minimize کنید. در MSDN بخش مربوط به Window رو ببینید. لیست تمامی توابع مدیریت پنجره موجود اند.
مدیریت پنجره جزو ویژگی های اساسی ویروس ها هم نیست. ویروس از اسمش خصوصیت اصلی اش مشخصه، حتی ویروس های معمولی این قابلیت رو دارند خودشون رو به سایر فایل های اجرایی می چسبانند و آلوده اش می کنند، قطعا اتوپلی ای که برای کارهای ابتدایی هم نیاز به پلاگین داشته باشه در این حد نیست که بخواهید با یک زبان برنامه نویسی مقایسه اش کنید، اتوپلی که ابزار برنامه نویسی نیست.
شما یک نرم افزار ابتدایی اتوران ساز به نام اتوپلی رو که نه ابزار برنامه نویسی است و نه کاربردی برای برنامه نویسی داره رو می خواهید با یک زبان سطح بالای برنامه نویسی ارتباط بدید. مثل اینکه بخواهید هواپیمای مسافربری رو برای هدایت توسط کودکان مهد کودک بکار ببرید. اگه شدنی هم باشه خنده دار ئه. اگه کاربر اتوپلی سواد برنامه نویسی مناسب رو نداشته باشه که نمیتونه از #C استفاده درستی بکنه. اگه هم دانش اش رو داشته باشه که برای برنامه نویسی نیازی به اتوپلی نداره.

گذشته از خوبی هایی که سی شارپ داره ولی واقعا دردسر داره وقتی آدم میخواد با کدها و کنترل های Unmanaged و Native Windows کار کنه

هیچ سختی ای نداره، تا حالا انجامش نداده اید که بخواهید بسنجید. مثل برنامه نویسی هستید که از ویژوال بیسیک 6 به 6 ++Visual C مهاجرت کرده باشه. انجام ساده ترین کارها براش سخت به نظر میاد چون تا حالا صرفا یکسری کار های ابتدایی رو با چند کلیک و بدون ورود به دنیای سیستم عامل ویندوز انجام داده. شما تا حالا واقعا کد نویسی Native نکرده اید، اون توابع API از چشم تون پنهان بوده. حالا تازه می خواهید درگیر اش بشوید.
عادت کرده اید به انجام کارهای ابتدایی و اونم با استفاده از پلاگین. وقتی تا حالا یک نمونه پروژه چند هزار خطی Native ننوشته اید چطور می توانید قضاوت کنید که برای ارتباط برقرار کردن باهاش چند خط کد لازمه؟ شما تا حالا هر کدی که تو اتوپلی اجرا کردید با کمک یک پلاگین بوده، قطعا اگه بخواهید یک پروژه کامل بنویسید باید چند نفر برنامه نویس استخدام کنید که براتون پلاگین بنویسند. اینکار که برنامه نویسی نیست.
برای هر برنامه نویسی که از عادت محیط ویژوال و ابتدایی به این مباحث وارد بشه این سختی وجود داره، مربوط به عادت ها است، فقط همین.


حالا اصلا معلوم نیست شدنی هست یا نه
ولی به نظرم امکان نداره نشدنی باشه ها . اصلا برنامه نویسی واسه همین کاراست دیگه . یه زبان وقتی نتونه کنترل کامل کامپیوتر رو اونم هم سیستم عامل و هم زبانی که خود مایکروسافت نوشت رو در اختیار برنامه نویس بذاره که دیگه ....
هر دفعه برای برقراری ارتباط اتوپلی و سی شارپ ، داستان داریم :green:
لطفا در مورد چیزی که دانش کافی در موردش ندارید انتقاد نکنید، حالا چه به شوخی و چه جدی. نظر شخصی تون محترم ئه ولی پشتوانه علمی و منطقی نداره.
شما باید قبلش با یک زبانی سابقه کنترل کامل کامپیوتر رو داشته اید که بخواهید توانایی های زبان #C رو نقد کنید. یا باید سالها سابقه برنامه نویسی حرفه ای داشته باشید که بخواهید حاصل زحمات برنامه نویسان مایکروسافت رو نقد کنید. همانطور که مسخره کردن اتوپلی کار درستی نیست که متاسفانه بعضی همکارها انجام می دهند. تا وقتی عیار و ملاک سنجش شما اتوپلی باشه هیچ درک درستی از توانایی یک زبان برنامه نویسی نخواهید داشت، نه #C و نه هیچ زبان برنامه نویسی دیگه ای. و این رو فکر کنم حداقل چند بار در این فروم گفتم و باز تکرار می کنم، توانایی های یک ابزار برنامه نویسی بیشتر از همه به خود برنامه نویس اش بستگی داره، نه چیز دیگه ای.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
لطفا در مورد چیزی که دانش کافی در موردش ندارید انتقاد نکنید، حالا چه به شوخی و چه جدی. نظر شخصی تون محترم ئه ولی پشتوانه علمی و منطقی نداره.

سلام
ممنون استاد علی
از اینکه گفتم "حالا اصلا معلوم نیست شدنی هست یا نه" ، خوب مشخص هست که نظر خاصی ندادم و گفتم که نمیدونم .
اگه میدونین ، ممنون میشم کدش رو بدین .مثلا پروپرتی Text در هر پنجره ی دیگه ای (مثلا پنجره ی Task Manager) رو توسط سی شارپ ، تغییر بدین . با API منظورم نیست . با API اگه میخواد باشه که خوب همه ی کارها با API ها شدنی هست و با هر زبانی و البته کار کردن باهاش به نسبت کلاس های سی شارپ سخت تر هست . منظورم با استفاده از کلاس های سی شارپ و تا میشه ، هندل (مثلا هندل پنجره ی Task Manager که با استفاده از کلاس Proccess گرفته میشه) یه پنجره رو به کلاس کنترل یا Form تبدیل و بعد باهاش کار بشه یا کلا هر روش دیگه ای که حالا نمیدونم


شما باید قبلش با یک زبانی سابقه کنترل کامل کامپیوتر رو داشته اید که بخواهید توانایی های زبان #C رو نقد کنید. یا باید سالها سابقه برنامه نویسی حرفه ای داشته باشید که بخواهید حاصل زحمات برنامه نویسان مایکروسافت رو نقد کنید. همانطور که مسخره کردن اتوپلی کار درستی نیست که متاسفانه بعضی همکارها انجام می دهند. تا وقتی عیار و ملاک سنجش شما اتوپلی باشه هیچ درک درستی از توانایی یک زبان برنامه نویسی نخواهید داشت، نه #C و نه هیچ زبان برنامه نویسی دیگه ای. و این رو فکر کنم حداقل چند بار در این فروم گفتم و باز تکرار می کنم، توانایی های یک ابزار برنامه نویسی بیشتر از همه به خود برنامه نویس اش بستگی داره، نه چیز دیگه ای.

از نقد کردن چقدر ناراحت شدین :green:
من که گفتم امکان نداره نشدنی باشه (که حتما من نمیدونم)
من که وابستگی ای به اتوپلی یا لوا ندارم و اصلا هم چه نقد درست یا غلط ، منو ناراحت نمیکنه (ممکنه برای کسی که نقد غلط میکنه ، براش توضیح بدم تا نقاط ضعف و قوت اش رو پیدا کنه ولی ناراحتی کجا بود؟!:wink:)
خودم ضعف های اتوپلی و هم لوا رو گفتم و میگم . منظور منم از حرف های بالا ، اصلا قیاس اتوپلی با ویژال استودیو و همینطور قیاس لوا با سی شارپ نبود . خودم میدونم فرقشون این قدره که قابل قیاس نیستن .
اصلا اتوپلی رو ول کنین .
منظورم کلا این بود که چجوری میشه یه هندلی رو گرفت و تبدیل کرد جوری که بشه با کلاس های خود سی شارپ ، با اون ویندوز کار کرد . بدون API
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلامی مجدد
استاد علی ، میگم من فرمی که توسط سی شارپ درست میکنم و بعد هندلش رو برای اتوپلی میفرستم ، اتوپلی راحت با توابع اش میتونه با این ویندوز تعامل برقرار کنه و دستکاری اش کنه
پس چرا این قضیه یک طرفه هست و با وجودی که اتوپلی میتونه با پنجره های دات نت کار کنه ، سی شارپ نمیتونه با پنجره های غیر دات نت کار کنه؟!
به جان خودم ، این مقایسه ی اتوپلی با سی شارپ نیست که ناراحت بشین ها . فقط سئوال هه برام که چرا یه طرفه هست . من حدس میزدم وقتی سی شارپ نتونه کار کنه ، اتوپلی و لوا هم طبعا نمیتونه با فرم های سی شارپ کار کنه که حدسم غلط بود
 

the_king

مدیرکل انجمن
سلامی مجدد
استاد علی ، میگم من فرمی که توسط سی شارپ درست میکنم و بعد هندلش رو برای اتوپلی میفرستم ، اتوپلی راحت با توابع اش میتونه با این ویندوز تعامل برقرار کنه و دستکاری اش کنه
پس چرا این قضیه یک طرفه هست و با وجودی که اتوپلی میتونه با پنجره های دات نت کار کنه ، سی شارپ نمیتونه با پنجره های غیر دات نت کار کنه؟!
به جان خودم ، این مقایسه ی اتوپلی با سی شارپ نیست که ناراحت بشین ها . فقط سئوال هه برام که چرا یه طرفه هست . من حدس میزدم وقتی سی شارپ نتونه کار کنه ، اتوپلی و لوا هم طبعا نمیتونه با فرم های سی شارپ کار کنه که حدسم غلط بود
اتوپلی با فرم NET. تون ارتباط برقرار نمی کنه، با همون توابع API و بر اساس یک Handle کار می کنه و در حد همون امکانات، مثلا شما در فرم تون Anchor دارید، KeyPreview دارید، اینها پروپرتی های Form های NET. اند، همه پنجره ها Handle دارند ولی این پروپرتی ها خاص NET. ئه. اتوپلی که نمی تونه به این شیء Form و این پروپرتی ها دسترسی داشته باشه، میتونه؟ شما آیکون پنجره های NET. رو با کدوم دستور اتوپلی عوض می کنید؟ Opacity پنجره های NET. رو که بدون دستورات API نمیشه تغییر داد، حالا یا با پلاگین یا بدون پلاگین. کتابخانه های زیادی برای NET. موجود اند که شامل توابع پنجره با استفاده از API ویندوز هستند و شما می توانید در پروژه هایتان بهشان رفرنس بدهید، شما اینها رو جزو #C حساب می کنید؟
این توابعی که شما در اتوپلی بکار می برید کتابخانه اند، اونها رو با کمک توابع API نوشته اند، جزو دستورات زبان اسکریپتی اتوپلی که نیستند.
شما فراخوانی دستور API از داخل #C رو جزو کد نویسی به زبان #C حساب نمی کنید، اما کتابخانه ناقص Window اتوپلی رو جزو زبان اتوپلی حساب می کنید، فقط به این خاطر که از قبل آماده است. کلاس Process رو جزو زبان #C حساب می کنید، چون از قبل کتابخانه اش در پروژه تان رفرنس داده شده، در حالی که Process ربطی به #C نداره، جزئی از محتویات کتابخانه های استاندارد NET. ئه. کل کلمات کلیدی زبان #C اینها است، هر چی بجز اینها ربطی به زبان #C نداره :
C# Keywords
اتوپلی هم مثل سایر نرم افزار ها است، بدون توابع API ویندوز نمی تونه با هیچ پنجره ای ارتباط برقرار کنه.
 

جدیدترین ارسال ها

بالا