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

the_king

مدیرکل انجمن
خیلی ممنون
در این روش ، به آلفا احتیاج پیدا کنم ، چی میشه؟

چیزی نمیشه جز اینکه شما اگه مجبور به رسم مجدد روی پنجره کنترل تون بشید اون رسمی که قبلا انجام داده بودید و هنوز پاک نشده رو همچنان دارید و اگر رویش چیزی بکشید پر رنگ ترش میکنید. یعنی فکر نکنید که بعد از Invalidate کردن پشت کنترل مثل سابق رسم میشه و شما با خیال آسوده روی اون رسم نیمه شفاف تون رو میکنید. یکبار با رنگ نیمه شفاف مثلا با new Pen(Color.FromArgb(70, 255, 0, 0), 4f) رسم انجام بدید تا متوجه بشید Invalidate کردن های مکرر چه تاثیری داره.

شما برای اینکه پنجره تون رسم اش حفظ بشه، مجبور هستید که بعد از هر رسمی که زیرش اتفاق بیافته یعنی هر رسمی روی کنترل های زیرش، مجددا رویش رسم انجام بدید و دیگه بافر گرافیکی یا حتی قابلیت آماده ای مثل DoubleBuffered نمیتونه کمک تون کنه تا مانع پرپر زدن بشید. WS_EX_TRANSPARENT دقیقا روشی برای شفاف کردن پنجره نیست، برای نادیده گرفتن پنجره است، انگار که موقع رسم شدن زیرش چیزی روی اون نیست. ترتیب رسم پنجره ها رو تغییر میده تا پنجره کنترل شما تا زمانی که چیزی داخلش رسم نکنید رنگش نکنه و پشتش رو نشون بده.

دقیقا متوجه ی منظورتون نشدم
منظورم اینه :
مشاهده پیوست 112314

اون حاشیه ی قرمز داره ، شی کنترلی هه که من paint شو رسم کردم (ضلع سمت راست اش که نداره را در نظر نگیرید) . بعد از اینکه این کنترل را اضافه کردم ، بعدش به Front بقیه ی کنترل ها آوردم :

کد:
        private void Button12_Click(object sender, EventArgs e)
        {
            CustomControl customControl = new CustomControl();
            customControl.Bounds = new Rectangle(new Point(30, 70), new Size(150, 70));
            customControl.BackColor = Color.Red;

            this.panel1.Controls.Add(customControl);
            customControl.BringToFront();
}

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

the_king

مدیرکل انجمن
استاد علی ، جواب پست بالا را بی زحمت میدین؟
بعد اینکه دکمه میخوام طراحی کنم ، به نظرتون شکل اش را در فتوشاپ طراحی کنم و بعد اون فایل را لود کنم یا توی سی شارپ ، با کدنویسی گرافیکش را بسازم؟ البته شکل هایی که نیاز به طراحی توی فتوشاپ نداره و با کدنویسی به راحتی انجام میشه ، منظورمه.
یعنی ، کدوم حالت ، اصولی تره و شما کدوم حالت را انجام میدین؟
ممنون
بستگی به نوع تغییراتی داره که تو گرافیک دکمه دارید و توسط مشخصه ها باید قابل تغییر باشه. فرضا اگه قرار باشه کادری دور دکمه رسم بشه که ضخامت و رنگش در مشخصه ای تعیین میشه دیگه فتوشاپ نمیتونه کمک تون کنه.
اما اگه دکمه گرافیک پیچیده ای داره یا وابستگی خاصی به مشخصه ها نداره، طبعا با فتوشاپ طراحی کردنش میتونه علاوه بر ساده تر کردن کارتون، رسم رو هم سریعتر کنه چون رسم کردن مکرر یکسری تابع گرافیکی احتمالا کندتر از رسم فقط یک تصویر میشه، علاوه بر این امکان Skin پذیر کردن هم به کنترل تون اضافه میشه.
ایجاد برنامه های زیبا در Vb

بعد اینکه استاد علی ، در کد زیر :

کد:
        private void BtnPointer1_Click(object sender, EventArgs e)
        {
            unsafe
            {
                int number = 1444;
                int* pointer = &number;
                MessageBox.Show(((int)pointer).ToString());
                number = 95;
                pointer = &number;
                MessageBox.Show(((int)pointer).ToString());
            }
        }

متغییر number ، در هر دو باری که مقدار گرفت ، آیا در هر بار ، آدرس جدیدی خواهد داشت؟ یعنی در هر بار ، شی جدیدی میسازه؟ یا صرفا مقدارش ، در همون خونه ی قبلی اش ویرایش میشه؟ کد بالا انگار آدرس را در هر بار ، یکی نشون میده. کلا مقدار متغییر ، چون از نوع استراکچر هست ، در همونجا ویرایش میشه؟
بعد اینکه چرا بعد از اینکه بلاک متغییر تموم شد (مثلا رویداد تموم شد) و دوباره روش کلیک میکنیم ، باز هم در دفعات بعدی ، همون آدرس را نشون میده؟
در مورد استفاده مجدد از حافظه ای که number اختصاص یافته، قاعدتا بله، شما 95 رو به عنوان یک مقدار کپی میکنید در حافظه ای که قبلا به متغیر تخصیص داده شده بود، یعنی اگر int یک مگابایت حافظه اشغال میکرد، یک مگابایت کپی داده انجام میدادید، بنابر این حافظه اش در طول بلاک همون قبلی ئه باقی میمونه و number = 95 شبیه int number = 95 و ساختن یک متغیر با حافظه جدید نیست. اما در مورد آدرسش که ثابت بمونه نه،همچین تضمینی وجود نداره. GC هر زمان که لازم بدونه میتونه اون حافظه رو به بخش دیگری منتقل کنه، گرچه در زمان کوتاهی که شما صرف اجرای این کدتون میکنید همچین اتفاقی خیلی بعیده، ولی اصل رو بر این باید بگذارید که GC همچین تضمینی نکرده که آدرس حافظه ای که به متغیر اختصاص داده شده ثابت بمونه. ممکنه جابجاش کنه و آدرسش عوض بشه. اگر نیازی به همچین تضمینی دارید قاعدتا از کلمه کلیدی fixed استفاده می کنید :
fixed Statement - C# Reference

و در مورد اجرای مجددا اون بلاک، کلا شما نمی توانید از روی اجرای کدتون برای مدیریت حافظه GC قضاوتی بکنید که فرضا همون آدرس قبلی رو بکار میبره. قبلا در این مورد صحبت کردیم، غیر قابل پیش بینی ئه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
چیزی نمیشه جز اینکه شما اگه مجبور به رسم مجدد روی پنجره کنترل تون بشید اون رسمی که قبلا انجام داده بودید و هنوز پاک نشده رو همچنان دارید و اگر رویش چیزی بکشید پر رنگ ترش میکنید. یعنی فکر نکنید که بعد از Invalidate کردن پشت کنترل مثل سابق رسم میشه و شما با خیال آسوده روی اون رسم نیمه شفاف تون رو میکنید. یکبار با رنگ نیمه شفاف مثلا با new Pen(Color.FromArgb(70, 255, 0, 0), 4f) رسم انجام بدید تا متوجه بشید Invalidate کردن های مکرر چه تاثیری داره.

شما برای اینکه پنجره تون رسم اش حفظ بشه، مجبور هستید که بعد از هر رسمی که زیرش اتفاق بیافته یعنی هر رسمی روی کنترل های زیرش، مجددا رویش رسم انجام بدید و دیگه بافر گرافیکی یا حتی قابلیت آماده ای مثل DoubleBuffered نمیتونه کمک تون کنه تا مانع پرپر زدن بشید. WS_EX_TRANSPARENT دقیقا روشی برای شفاف کردن پنجره نیست، برای نادیده گرفتن پنجره است، انگار که موقع رسم شدن زیرش چیزی روی اون نیست. ترتیب رسم پنجره ها رو تغییر میده تا پنجره کنترل شما تا زمانی که چیزی داخلش رسم نکنید رنگش نکنه و پشتش رو نشون بده.


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

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

the_king

مدیرکل انجمن
خیلی ممنون
ای بابا . تازه خوشحال شده بودم که به چیز دلخواهم رسیدم ، این invalidate نشدنش که گفتین ، دقیق زد توی مرکز ذوق ام .

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

نگفتم راهی نداره، اونکه کار دشواری نیست، از پنجره والد درخواست رسم مجدد کادر مورد نظر و کنترل های داخلش رو میکنید. و البته از پر پر زدن ها لذت میبرید.

در wpf ، کنترلی بدون پنجره نیست؟ (تا شفاف باشه)
پاسخ هایی که می نویسم رو نمی خونید :
بله ولی در نظر بگیرید که اینها دو تا راهکار کلی ئه، نه جزئی و روش های مختلفی برای پیاده سازی دارند با جزئیات کاملا متفاوت.
من نمیتونم همینطور کلی براتون روشی رو پیشنهاد کنم، باید با توجه به نرم افزاری که دارید طراحی می کنید و نیازی که داره و زمان و هزینه ای که صرف اش میشه تصمیم بگیرید.
در پیاده سازی روش ها ریزه کاری ها خیلی متفاوت هستند. فرضا خیلی تفاوت هست بین کنترل های داخل Photoshop و Firefox و Adobe Flash و WPF و ...
یک پروژه در WPF بسازید و چند تا کنترل داخلش قرار بدهید و در اجرا داخلش دنبال پنجره ها بگردید و ببینید چیزی پیدا می کنید.
 

SU-57

Active Member
سلام استاد علی

1- اینکه کد ها در سی شارپ مدیریت شده هستند به چه معناست؟ یعنی از چه لحاظ مدیریت شده هستند؟ و همین طور کدهای Unmanaged از چه لحاظ مدیریت نشده هستند؟

2- شما فرمودین ما می تونیم بین محیط Managed و Unmanaged ارتباط برقرار کنیم ولی کد Managed همون Managed می مونه. دو سوال:
الف- در جمله بالا واژه محیط درست تره یا کد
ب- آیا همون طور که کد Managed به Unmanaged تبدیل نمی شه بر عکسش هم درسته؟

3- طبق آموزش ها ما نمی تونیم همه dll های Unmanaged رو وارد سی شارپ کنیم. حالا اون dll هایی که می تونیم وارد سی شارپ کنیم باید چه ویژگی هایی داشته باشند یا از چه زبانی باشند که بتونیم وارد سی شارپ کنیم.

4- وقتی یک پروژه رو کامپایل می کنیم فقط به فایل های exe و dll تبدیل میشن یا به فایل های دیگه ای هم تبدیل میشن. اگه میشن پسوندشون چی هست؟ و اینکه درست اینه که بگیم پروژه کامپایل می شه یا Solution

5- ما می تونیم در یک Solution که یک پروژه ایجاد کردیم به هر تعداد ممکن Form ایجاد کنیم و روی این فرم ها کنترل های مختلف. حالا اگه می تونیم پس چه نیازی به ایجاد دو یا چند پروژه در یک Solution هست؟ اگه می شه یک نرم افزار مثال بزنید که شامل چندین پروژه باشه و هر پروژه شامل چندین فرم. اگه چنین برنامه ای هست نمی شه با یک پروژه درستش کرد؟
 

the_king

مدیرکل انجمن
سلام استاد علی

1- اینکه کد ها در سی شارپ مدیریت شده هستند به چه معناست؟ یعنی از چه لحاظ مدیریت شده هستند؟ و همین طور کدهای Unmanaged از چه لحاظ مدیریت نشده هستند؟
منظور از مدیریت شده معنای تحت کنترل بودنه. یک ماشین مجازی برای اجرای برنامه های NET. هست که هر چیزی که مربوط به اجرای داخل خودشه از محیط بیرون ماشین مجازی دور نگه میداره. ماشین مجازی روی کدی که بیرون از محیط خودش اجرا میشه کنترل نداره. اون چیزی که داخل محیط ماشین مجازی قرار گرفته تحت کنترلش قرار داره و Managed ئه و هر آنچه داخلش نیست، تحت کنترل اش قرار نداره و Unmanaged ئه. فرضا اون حافظه ای که برای متغیر #C استفاده می کنید تحت کنترل ئه و Managed ئه و اون حافظه ای که برای اجرا کردن یک دستور API ویندوز یا یک برنامه خارجی مثل ماشین حساب ویندوز بکار میره، تحت کنترل اش نیست و Unmanaged ئه.

2- شما فرمودین ما می تونیم بین محیط Managed و Unmanaged ارتباط برقرار کنیم ولی کد Managed همون Managed می مونه. دو سوال:
الف- در جمله بالا واژه محیط درست تره یا کد
ب- آیا همون طور که کد Managed به Unmanaged تبدیل نمی شه بر عکسش هم درسته؟
هر دو درسته، چون بهر حال کد Managed داخل محیط Managed قرار داره و کد Unmanaged در محیط Unmanaged، ولی ارتباط بین دو محیط مفهوم تره تا ارتباط بین دو تا کد.
تبدیل نمیشه، چون اجرا کننده اش تغییر نمی کنه، کد Managed همیشه Managed میمونه چون اجرا کننده اش ماشین مجازیه و کد Unmanaged هم همیشه Unmanaged میمونه چون اجرا کننده اش ماشین مجازی نیست. غیر از این هم نمیتونه باشه چون اصلا ماشین مجازی جز کد ماشین مخصوص خودش چیز دیگری رو متوجه نمیشه که بخواد اجرا کنه.

3- طبق آموزش ها ما نمی تونیم همه dll های Unmanaged رو وارد سی شارپ کنیم. حالا اون dll هایی که می تونیم وارد سی شارپ کنیم باید چه ویژگی هایی داشته باشند یا از چه زبانی باشند که بتونیم وارد سی شارپ کنیم.
وارد کردن رو به یک شیوه خاص محدود کردید که مختص یک گروه خاص از کتابخانه ها است و به همون جهت میگید برای بقیه گروه ها که با اون روش سازگار نیستند نمی توانیم واردش کنیم. من نمیدونم منظورتون کدوم آموزش و به چه شیوه ای است اما به هر حال کتابخانه dll حتی اگه بصورت مستقیم توسط کد #C تون قابل استفاده نباشه با استفاده از یک کد واسطه قابل استفاده است. مهمتر اینه که ببینید قراره با اون dll چه کاری انجام بدید.
کلا شما می توانید از همه کتابخانه های dll بالاخره به روشی استفاده ای بکنید اما نه به یک روش ثابت که برای همه کتابخانه ها جواب بده.
زبان مبدا مهم نیست، کامپایلر مبدا مهمه، این دو تا با هم فرق دارند، فرضا ممکنه زبان مبدا ++C باشه ولی دو تا کامپایلر ++C متفاوت از روی یک کد ++C کتابخانه های dll متفاوتی بسازند که تفاوت های زیادی با هم دارند، همونطور که ویژوال استدیو های قدیمی با ویژوال استدیو های جدید از این نظر فرق دارند.

4- وقتی یک پروژه رو کامپایل می کنیم فقط به فایل های exe و dll تبدیل میشن یا به فایل های دیگه ای هم تبدیل میشن. اگه میشن پسوندشون چی هست؟ و اینکه درست اینه که بگیم پروژه کامپایل می شه یا Solution
پسوند اینجا خیلی تعیین کننده نیست، داخلشون مطرحه. dll از نظر داخلی شباهت زیادی به exe داره چون هر دو فایل اجرایی هستند، حتی بعضی از exe ها بصورت کتابخانه dll هم استفاده می شوند، نباید روی پسوند متمرکز بشید.
نهایتا کد کامپایل میشه، وقتی پروژه رو کامپایل می کنید کد های داخل پروژه رو کامپایل کردید، وقتی Solution رو کامپایل می کنید همه کد های داخل پروژه های درون اون Solution رو کامپایل می کنید. چیزی اینجا اشتباه یا بهتر و بدتر نیست.

5- ما می تونیم در یک Solution که یک پروژه ایجاد کردیم به هر تعداد ممکن Form ایجاد کنیم و روی این فرم ها کنترل های مختلف. حالا اگه می تونیم پس چه نیازی به ایجاد دو یا چند پروژه در یک Solution هست؟ اگه می شه یک نرم افزار مثال بزنید که شامل چندین پروژه باشه و هر پروژه شامل چندین فرم. اگه چنین برنامه ای هست نمی شه با یک پروژه درستش کرد؟
حداقل سه تا کاربرد مهم در این قضیه چند پروژه ای بودن Soluton هست.
درسته که شما در یک پروژه چندین فرم می سازید، ولی کل پروژه شما فقط از یک نوع خاص ئه و کل اش با تنظیمات کامپایل مخصوص اون پروژه کامپایل میشه و این برای پروژه های بزرگ یا چند قسمتی محدودیته.
فرضا شما دارید یک کتابخانه میسازید که فرضا کارش رسم کردن نمودار ئه. خود این پروژه باید از نوع کتابخانه باشه، ولی موقع کد نویسی و برای تست کردن کدتون کتابخانه کافی نیست و نیاز به یک پروژه عادی ویندوز هم دارید که بتوانید کتابخانه تون رو داخلش وارد کنید و اجراشو بررسی کنید. این چیزی نیست که فقط در یک پروژه قابل اجرا باشه، چون پروژه یا باید کتابخانه باشه یا کتابخانه نباشه. اینجا شما در Solution تون دو تا پروژه قرار میدهید، یکی اش اون کتابخانه تون و دیگری یک پروژه عادی برای آزمون اون کتابخانه که پروژه کتابخانه رو هم داخلش به عنوان Reference اضافه می کنید و همینطور که کد کتابخانه تون کامل میشه، استفاده عملی شو تست می کنید.

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

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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سلام استاد علی

1- اینکه کد ها در سی شارپ مدیریت شده هستند به چه معناست؟ یعنی از چه لحاظ مدیریت شده هستند؟ و همین طور کدهای Unmanaged از چه لحاظ مدیریت نشده هستند؟

2- شما فرمودین ما می تونیم بین محیط Managed و Unmanaged ارتباط برقرار کنیم ولی کد Managed همون Managed می مونه. دو سوال:
الف- در جمله بالا واژه محیط درست تره یا کد
ب- آیا همون طور که کد Managed به Unmanaged تبدیل نمی شه بر عکسش هم درسته؟

3- طبق آموزش ها ما نمی تونیم همه dll های Unmanaged رو وارد سی شارپ کنیم. حالا اون dll هایی که می تونیم وارد سی شارپ کنیم باید چه ویژگی هایی داشته باشند یا از چه زبانی باشند که بتونیم وارد سی شارپ کنیم.

4- وقتی یک پروژه رو کامپایل می کنیم فقط به فایل های exe و dll تبدیل میشن یا به فایل های دیگه ای هم تبدیل میشن. اگه میشن پسوندشون چی هست؟ و اینکه درست اینه که بگیم پروژه کامپایل می شه یا Solution

5- ما می تونیم در یک Solution که یک پروژه ایجاد کردیم به هر تعداد ممکن Form ایجاد کنیم و روی این فرم ها کنترل های مختلف. حالا اگه می تونیم پس چه نیازی به ایجاد دو یا چند پروژه در یک Solution هست؟ اگه می شه یک نرم افزار مثال بزنید که شامل چندین پروژه باشه و هر پروژه شامل چندین فرم. اگه چنین برنامه ای هست نمی شه با یک پروژه درستش کرد؟

سلام
تا جایی که بلدم را جواب میدم ، تکمیلی ترش را استاد علی خواستن ، میگن.

۱) بخاطر اینکه کدش بجای اینکه در سیستم عامل بصورت مستقیم اجرا بشه ، در ماشین مجازی اجرا میشه :

virtual machin in c# - Google Search
۲)
الف) کد درسته
ب) بله . کدها به هم تبدیل نمیشن. برای ارتباط برقرار کردن در سی شارپ با کدهای unmanaged (هر چند در سطح ساده اش میشه بصورت مستقیم ، با اتریباتسی _که فکر نکنم فعلا باهاش آشنا باشین- میشه این کار را کرد اما در سطح پیشرفته تر) از کلاس Marshal برای ارتباط با کدهای unmanaged در کدهای managed ، استفاده میکنن.

۳) اغلب شون رو میشه استفاده کرد . غیر از اونایی که معمولا در سطح هسته های سیستم عامل نوشته شدن . شاید اونها را هم تا حدودی بشه.

۵) بله میشه هر چقدر خواستیم ، فرم ایجاد کنیم.
معمولا شاید زمانی پروژه ی دیگه ای توی سولوشن بسازت که نیاز به ارتباط زیادی با پروژه ی قبلی نداشته باشه اما در عین حال ، بدون ارتباط هم نباشه. تقریبا ، هر دو کار جداگانه ی خودشونو کنن.
 
آخرین ویرایش:

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد علی
فقط در این نوع کنترل (که شفاف ساختم و در جریانید) ، چرا کنترل والدش را Invalidate کنیم ، این کنترل مون (که داخلش هست) ، transparent میشه ولی اگه خود همین کنترل را Invalidate کنیم ، transparent نمیشه؟!

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

بعد اینکه تفاوت در دیتابیس sqlite و access در چیه؟ یا به عبارتی ، در چه مواقعی از دیتابیس sqlite استفاده میشه و در چه مواردی از دیتابیس access ؟ به نظرتون دیتابیس sqlite برای پروژه ام (که آفلاین هست یعنی با اینترنت در تماس نیست) مناسب تره یا دیتابیس access ؟
 

the_king

مدیرکل انجمن
خیلی ممنون استاد علی
فقط در این نوع کنترل (که شفاف ساختم و در جریانید) ، چرا کنترل والدش را Invalidate کنیم ، این کنترل مون (که داخلش هست) ، transparent میشه ولی اگه خود همین کنترل را Invalidate کنیم ، transparent نمیشه؟!

به ترتیب رسم ها توجه کنید، برای اینکه کنترل تون شفاف دیده بشه باید اول هر چه زیرش هست به روال عادی رسم بشه و بعد کنترل شما رسم اش رو روی اون انجام بده. اگر موقع Invalidate کردن کنترل تون چیزی از رسم زیرش پاک شده باشه یا بقایایی از رسم قبلی کنترل خودتون مونده باشه، احتمال خراب شدن نتیجه ترسیم هست.
حالا اگر فقط کنترل خودتون رو Invalidate کنید، فرض رو بر این گذاشتید که الان چیزی که در کادر پنجره اش دارید رسم کامل و دستکاری نشده زیرشه (که الزاما نیست).
ولی اگر درخواست Invalidate شدن پنجره والد و فرزندانش رو بکنید از خود پنجره والد تا فرزند ها که خود کنترل تون هم شامل شون میشه با ترتیب منطقی یکی یکی Invalidate میشن.
بعد اینکه به نظرتون این پروژه مو (این پروژه ی بکاپ و بعدش ان شاءا... پروژه ی اتوران) را بصورت 3 لایه بنویسم؟ هر چند یه چیزهای اولیه از برنامه نویسی 3 لایه میدونم و مسلط نیستم . توی یه آموزش دیدم فقط 3 کلاس ؛ یکی برای ارتباط با دیتابیس (لایه اول) ، یکی برای مقداردهی اون کلاس (لایه دوم) و یکی هم برای ui ساخته شده بود(که همون کلاس فرم بود) (البته یه همچین کاری را میخوام انجام بدم). اما در یه آموزش دیگه ، لایه ی اول ، خودش از چندین کلاس تشکیل شد ، لایه ی دوم ، از دو کلاس که یکی اش با کلاس ui و یکی دیگه اش با کلاس های دیتابیس (لایه ی سوم) ارتباط داشت ، ساخته شد.
نظری ندارم. قطعا برای کسی که از برنامه نهایی استفاده می کنه تفاوتی نمی کنه که پروژه تون رو چند لایه نوشتید، با بیست کلاس کد نویسی کردید یا هزار تا کلاس، تنهایی نوشتید یا نصفش رو شما و نصفش رو دوست تون نوشته. اینها چیزی که است که خودتون و با تمایلات شخصی در موردشون تصمیم می گیرید و تاثیر تفاوت هاشون هم فقط برای خودتون محسوسه. مواردی نیستند که شخص دیگری بهتون پیشنهاد بده یا توصیه ای بکنه.

بعد اینکه تفاوت در دیتابیس sqlite و access در چیه؟ یا به عبارتی ، در چه مواقعی از دیتابیس sqlite استفاده میشه و در چه مواردی از دیتابیس access ؟ به نظرتون دیتابیس sqlite برای پروژه ام (که آفلاین هست یعنی با اینترنت در تماس نیست) مناسب تره یا دیتابیس access ؟
نمیشه اینطوری نتیجه گیری کرد که اگر فلان حالت باشه باید حتما از فلان چیز استفاده کنید، ولی کلا اگر حجم براتون مساله است، باید در نظر بگیرید که کسی که از برنامه تون استفاده میکنه برای دسترسی به پایگاه داده Access یا باید خود Microsoft Access رو نصب کرده باشه و یا Microsoft Access Runtime رو پیوست برنامه تون کنید که حجم کمی هم نداره :
Download Microsoft Access 2016 Runtime from Official Microsoft Download Center
در کل اگه دنبال یک پایگاه داده سبک هستید که هر چیزی که برای اجرا لازم داره رو هم پیوست برنامه تون کنید، بهتره SQLite رو با SQL Server Compact مقایسه کنید، نه Access. اینکه کدومشون رو هم انتخاب کنید کاملا برمبنای سلیقه شخصیه.
 

SajjadKhati

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

the_king

مدیرکل انجمن
خیلی ممنون استاد علی.
هر چند قبل از این هم یه کم درباره ی این مبحث بحث کردیم ولی این یه نوع سئوال دیگه هست.
اینکه ما کلا زمانی که میخوایم پروسه ی برنامه مون از پردازنده ی گرافیک برای پردازش استفاده کنه ، باید از رابط های گرافیکی ای مثل opengl و directx و اینها استفاده کنیم دیگه؟ درسته؟ از opencl هم میشه؟
چون بصورت عادی فقط پردازنده ی cpu را پروسه مون درگیر میکنه.
توی اینها ، opengl از همه راحت تره؟
نمیدونم. قطعا OpenCL مناسبتره چون DirectX و OpenGL برای پردازش گرافیک دو بعدی سه بعدی طراحی شدن، نه پردازش همه منظوره با پردازشگر کارت گرافیکی. اما سادگی و سختی شون رو نمیدونم.
اولا پروسه تون همینطوری هر کاری رو نمیتونه با پردازنده گرافیکی انجام بده، باید خیلی تخصصی متمرکز بشید روی موضوع. در ضمن باید از کسی این سوال ها رو بپرسید که همچین تجربه ای رو بصورت جامع داشته و از همه اینها استفاده کرده باشه و بتونه مقایسه شون کنه. اینها چیزی نیست که من بتونم در موردشون نظر بدم.
 

SajjadKhati

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

the_king

مدیرکل انجمن
خیلی ممنون استاد علی
گفته بودین برای اینکه در MessageBox ، فارسی رو درست از راست به چپ ساپورت کنه (وقتی یه متن انگلیسی در میان متن فارسی مینویسیم و ترتیبش خراب میشه) ، باید کلا خودمون یه دیالوگ طراحی کنیم ؟ انگار نمیشد تنظیمات MessageBox را راست به چپ کرد دیگه . درسته؟
من همچین حرفی زدم؟ عجب. یادم نمیاد همچین چیزی گفته باشم، در مورد تغییر نام دکمه ها یادم هست سوالی شده باشه ولی این چیزی که شما میگید اصلا حرف من نیست، تکذیب می کنم.
دو تا تنظیم MessageBoxOptions.RightAlign و MessageBoxOptions.RtlReading مربوط به این موارد ئه.
کد:
            MessageBox.Show("این یک متن Farsi می باشد.", "فارسی"
                , MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد علی
ببخشید مزاحم میشم هی.
اون پارامتر چهارم رو حواسم نبود .
میگم یه فرمی ساختم که میخوام اصلا border نداشته باشه (تا هم قشنگتر بشه و هم آیکون های خودم را بذارم) یعنی FormBorderStyle اش روی None باشه و هم این قابلیت رو داشته باشه تا کاربر بتونه فرم را تغییر اندازه بده و ریسایز کنه. میدونید هم اگه FormBorderStyle اش روی None باشه ، قابلیت ریسایز فرم از دست میره . من بعد از قرار دادن FormBorderStyle روی None ، این کد رو در کلاس فرم نوشتم :

کد:
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams creatParams = base.CreateParams;
                creatParams.Style |= this.WS_SIZEBOX;
                return creatParams;
            }
        }

مشکلات اصلی حل شد . یعنی ریسایز میشه اما قسمت بالای فرم (حدود 5 پیکسل بالای فرم) ، باز یه نوار نازک داره که همه ی کنترل ها میان زیرش :


1.JPG

برای اینکه اون نوار بالا را برداریم ، راهی دیگه نیست؟
تنها راهش اینه که بعد از ست کردن مقدار None ، خودم از رویدادهای موس و اینها ، کدهای resize کردن را بنویسم یا روش ساده تری هم هست؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بعد اینکه استاد علی ، من این کد رو پیدا کردم که دیگه کلا مشکل مو حل کرد اما متوجه نشدم کد رو (در فرم این رو نوشتم) :

کد:
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x84)
            {  // Trap WM_NCHITTEST
                Point pos = new Point(m.LParam.ToInt32());
                pos = this.PointToClient(pos);

                if (pos.X >= this.ClientSize.Width - cGrip && pos.Y >= this.ClientSize.Height - cGrip)
                {
                    m.Result = (IntPtr)17; // HTBOTTOMRIGHT
                    return;
                }
            }
            base.WndProc(ref m);
        }

How to move and resize a form without a border?

یه توضیحی میتونین بدین درباره ی هر خط اش؟
مثلا من توی اینجا گشتم :
Message Constants - Windows applications

اما مقدار msg برابر 0x84 پیدا نکردم.
همینطور خط pos = this.PointToClient(pos) و مخصوصا خط m.Result = (IntPtr)17 و return; (چرا اونجا return گذاشت تا ادامه ی کد اجرا نشه و نمیذاشت چی میشد؟)
 

the_king

مدیرکل انجمن
برای اینکه اون نوار بالا را برداریم ، راهی دیگه نیست؟
تنها راهش اینه که بعد از ست کردن مقدار None ، خودم از رویدادهای موس و اینها ، کدهای resize کردن را بنویسم یا روش ساده تری هم هست؟
معمولا از این روش که شما نوشتید استفاده نمی کنند چون از یک طرف به ویژوال استدیو گفتید فرم کادر نداشته باشه و از طرف دیگه خودتون بصورت دستی جلوی اعمال این استایل رو گرفتید و WS_SIZEBOX رو بهش اضافه کردین. نتیجه فرمی است که یک کادر نامناسب داره.
چون خودتون WM_NCHITTEST رو پیدا کردید نیازی به راهنمایی بیشتری نیست.

بعد اینکه استاد علی ، من این کد رو پیدا کردم که دیگه کلا مشکل مو حل کرد اما متوجه نشدم کد رو (در فرم این رو نوشتم) :

کد:
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x84)
            {  // Trap WM_NCHITTEST
                Point pos = new Point(m.LParam.ToInt32());
                pos = this.PointToClient(pos);

                if (pos.X >= this.ClientSize.Width - cGrip && pos.Y >= this.ClientSize.Height - cGrip)
                {
                    m.Result = (IntPtr)17; // HTBOTTOMRIGHT
                    return;
                }
            }
            base.WndProc(ref m);
        }

How to move and resize a form without a border?
یه توضیحی میتونین بدین درباره ی هر خط اش؟
قبلا اشاره کردم که برای اینکه مشخص بشه فلان نقطه جزئی از پنجره هست یا نه یک آزمونی انجام میشه بنام Hit Test. این کد روال اون Hit Test رو تغییر میده تا حاشیه پنجره رو برای تغییر ابعاد معرفی کنه، نه بخشی از محیط کلاینت پنجره. اگه شرح اون پیام رو بخونید متوجه میشید که چطور اینکار رو میکنه.
WM_NCHITTEST message - Windows applications
مثلا من توی اینجا گشتم :
Message Constants - Windows applications

اما مقدار msg برابر 0x84 پیدا نکردم.
این پیام پنجره نیست، پیام ماوس ئه. برای همین اونجا که گشتید پیداش نکردید.
Mouse Input Notifications - Windows applications

همینطور خط pos = this.PointToClient(pos) و مخصوصا خط m.Result = (IntPtr)17 و return; (چرا اونجا return گذاشت تا ادامه ی کد اجرا نشه و نمیذاشت چی میشد؟)
شما وقتی روی فرم تون یا داخل پنل یا کلا هر پنجره ای موقعیتی رو مشخص میکنید مرجع خود پنجره است و (0,0) نقطه چپ-بالای همون پنجره است، یعنی مبنای موقعیت Client ئه و نه صفحه نمایش. شما هر چقدر هم که فرم تون رو جابجا کنید Location اون دکمه ای که داخلش قرار داره موقعیت ثابتی رو نشون میده چون مبناش Client ئه، نه Screen.
ولی وقتی دارید از MousePosition.X و MousePosition.Y و کلا پیام هایی که مربوط به خود پنجره تون نیست استفاده می کنید دیگه مبنا Client نیست، Screen ئه و (0,0) اش موقعیت چپ-بالای Desktop ئه. اگر بخواهید بین ایندو مبنا تبدیل انجام بدید PointToClient و PointToScreen و RectangleToClient و RectangleToScreen بکار برده میشه. و چون pos ای که از WM_NCHITTEST میاد بر مبنای Screen بوده باید به Client تبدیل بشه تا با ClientSize قابل مقایسه باشه.
اگه شرح WM_NCHITTEST رو بخونید معنی اون (IntPtr)17 رو میفهمید. return کرده چون نمیخواد در این شرایط خاص base.WndProc(ref m) اجرا بشه و دخالت کنه. اگه بخواد base.WndProc(ref m) اجرا بشه دیگه دخالتش در WM_NCHITTEST به باد میره و روتین پیشفرض کاری رو میکنه که یک پنجره عادی بدون کادر میکنه.
 

SajjadKhati

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


قبلا اشاره کردم که برای اینکه مشخص بشه فلان نقطه جزئی از پنجره هست یا نه یک آزمونی انجام میشه بنام Hit Test. این کد روال اون Hit Test رو تغییر میده تا حاشیه پنجره رو برای تغییر ابعاد معرفی کنه، نه بخشی از محیط کلاینت پنجره. اگه شرح اون پیام رو بخونید متوجه میشید که چطور اینکار رو میکنه.
WM_NCHITTEST message - Windows applications

این پیام پنجره نیست، پیام ماوس ئه. برای همین اونجا که گشتید پیداش نکردید.
Mouse Input Notifications - Windows applications


شما وقتی روی فرم تون یا داخل پنل یا کلا هر پنجره ای موقعیتی رو مشخص میکنید مرجع خود پنجره است و (0,0) نقطه چپ-بالای همون پنجره است، یعنی مبنای موقعیت Client ئه و نه صفحه نمایش. شما هر چقدر هم که فرم تون رو جابجا کنید Location اون دکمه ای که داخلش قرار داره موقعیت ثابتی رو نشون میده چون مبناش Client ئه، نه Screen.
ولی وقتی دارید از MousePosition.X و MousePosition.Y و کلا پیام هایی که مربوط به خود پنجره تون نیست استفاده می کنید دیگه مبنا Client نیست، Screen ئه و (0,0) اش موقعیت چپ-بالای Desktop ئه. اگر بخواهید بین ایندو مبنا تبدیل انجام بدید PointToClient و PointToScreen و RectangleToClient و RectangleToScreen بکار برده میشه. و چون pos ای که از WM_NCHITTEST میاد بر مبنای Screen بوده باید به Client تبدیل بشه تا با ClientSize قابل مقایسه باشه.
اگه شرح WM_NCHITTEST رو بخونید معنی اون (IntPtr)17 رو میفهمید. return کرده چون نمیخواد در این شرایط خاص base.WndProc(ref m) اجرا بشه و دخالت کنه. اگه بخواد base.WndProc(ref m) اجرا بشه دیگه دخالتش در WM_NCHITTEST به باد میره و روتین پیشفرض کاری رو میکنه که یک پنجره عادی بدون کادر میکنه.

سلامی مجدد
خیلی ممنون از لینک تون . خیلی کمک کرد.
چیزی که من متوجه شدم ، اینه . ببینین درسته ؟ :
پس اولا پیام WM_NCHITTEST ، مقدارش 0x84 هه و دوما مربوط میشه به زمانی که موس را روی اون کنترل و پنجره ای (لزوما پنجره ی والد نیست . هر پنجره ای که موس روش بود) که جابجا میکنیم ، به اون کنترل و پنجره ، پیام WM_NCHITTEST داده میشه. اما وقتی موس بیرون از اون کنترل و پنجره باشه ، دیگه بهش پیام داده نمیشه .

حالا ، من مقدار m.LParam در کد بالا را متوجه نشدم . توی توضیحاتش (در سایت) نوشته که به تنهایی ، هم شامل مختصات x و هم مختصات y نسبت به صفحه نمایش هست اما من دقیق متوجه نشدم چرا یه عدد گذاشتن و وقتی خودمون میخونیمش ، چجوری باید از اون عدد بفهمیم که مقدار x و y اش ، هر کدومش بصورت جداگانه چقدر هست؟
بالاخره اینکه مقدار m.LParam ، هر عددی که باشه ، با متد PointToClient در اون کنترل ، میشه مختصات موس را به نسبت اون کنترل (نسبت موس به گوشه ی چپ بالای اون کنترل) متوجه شد . درسته؟ حالا اگه بخوایم به نسبت خود همون مختصات مانیتور ، از m.LParam مختصات را بدست بیاریم ، باید چی کار کنیم؟ از خود متد سازنده ی استراکچر Point باید استفاده کنیم؟

توی اون شرط if هم که میگه اگه موس در قسمت گوشه ی پایین سمت راست (16 پیکسل به سمت داخل) بود ، عملیات را انجام بده .
m.Result که همون Return value در همون لینکی که دادین هست ، اگه برابر 17 باشه ، کاربر میتونه از گوشه ی پایین سمت راست ، پنجره را resize کنه .
return هم که دلیلش را توضیح دادین.
درسته؟
 

the_king

مدیرکل انجمن
سلامی مجدد
خیلی ممنون از لینک تون . خیلی کمک کرد.
چیزی که من متوجه شدم ، اینه . ببینین درسته ؟ :
پس اولا پیام WM_NCHITTEST ، مقدارش 0x84 هه و دوما مربوط میشه به زمانی که موس را روی اون کنترل و پنجره ای (لزوما پنجره ی والد نیست . هر پنجره ای که موس روش بود) که جابجا میکنیم ، به اون کنترل و پنجره ، پیام WM_NCHITTEST داده میشه. اما وقتی موس بیرون از اون کنترل و پنجره باشه ، دیگه بهش پیام داده نمیشه .
بله، ولی لزوما ربطی به جابجا شدن ماوس نداره، فرضا موقعی که کلیکی صورت میگیره یا پنجره ای میخواد بدونه زیر فلان موقعیت چه پنجره ای قرار داره و ... هم همچین پیامی ارسال میشه.

حالا ، من مقدار m.LParam در کد بالا را متوجه نشدم . توی توضیحاتش (در سایت) نوشته که به تنهایی ، هم شامل مختصات x و هم مختصات y نسبت به صفحه نمایش هست اما من دقیق متوجه نشدم چرا یه عدد گذاشتن و وقتی خودمون میخونیمش ، چجوری باید از اون عدد بفهمیم که مقدار x و y اش ، هر کدومش بصورت جداگانه چقدر هست؟
قالب پیام های بین پنجره ها یکجور بیشتر نیست، نمیشه که برای فلان پیام چهار تا پارامتر باشه و برای بهمان پیام پنج تا. هر مقداری که پیام لازمه ارسال کنه باید به طریقی داخل همون دو پارامتر wParam و lParam ارسالش کنه، هر پیامی که میخواد باشه همینه، حالا اگه لازم شد بصورت اشاره گر به یک ساختار دیگه. و چون فرض کردن مختصات ماوس در یک مقدار 32 بیتی جا میشه، نصف 16 بیتی پارامتری رو اختصاص دادن به x و نصف دیگه شو به y. طراحانش به نظرشون این روش مناسب بوده. تفکیک شون هم به همون صورت ترکیب شون ساده است، بیت ها رو هم که نمی افته که بگیم قاطی میشه. مثلا همون Keys در KeyData که چند کلید کنترلی با یک کلید عادی فرضا مجموعا چهار کلید ترکیب میشن و تفکیک میشن.
مقدار ترکیبی رو با 0x0000FFFF که AND کنید (n & 65535) نصفه پایینی اش بدست میاد که همون X ئه.
اگه مقدار ترکیبی رو 16 بیت به سمت راست Shift کنید و از سر احتیاط با 0x0000FFFF مقدار رو AND کنید تا بیت علامت تاثیری نداشته نباشه، نصفه بالایی بدست میاد (n >> 16 & 65535) که همون Y ئه.
ترکیب شون هم با OR کردن x و y ای که 16 بیت به سمت چپ Shift پیدا کرده بدست میاد (y << 16 | x) البته به شرطی که مقادیر x و y از محدوده 16 بیت فراتر نباشن.

بالاخره اینکه مقدار m.LParam ، هر عددی که باشه ، با متد PointToClient در اون کنترل ، میشه مختصات موس را به نسبت اون کنترل (نسبت موس به گوشه ی چپ بالای اون کنترل) متوجه شد . درسته؟ حالا اگه بخوایم به نسبت خود همون مختصات مانیتور ، از m.LParam مختصات را بدست بیاریم ، باید چی کار کنیم؟ از خود متد سازنده ی استراکچر Point باید استفاده کنیم؟
در کدتون که همین مقدار هست، اگه نبود که نمی توانستید PointToClient رو رویش اجرا کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
آها ممنون.
پس 2 بایت از اون 4 بایت را به مختصات x و 2 بایت دیگه شو به y اختصاص دادن.
--------------
من یه کلاس ساختم که از کنترل Panel ارث بری میکنه. میخوام وقتی موس رو روی این کنترل درگ میکنیم (کلیک میکنیم و جابجا میکنیم) ، کنترل والدش که فرم هست ، جابجا بشه (البته از روش کد زیر) .
در کد زیر ، وقتی موس رو روی Panel میبرم ، یه پیام شخصی به فرم ارسال میکنه (در کنترل Panel ام) :


کد:
    class MovablePanel : Panel
    {
        [DllImportAttribute("User32.dll", EntryPoint = "SendMessage")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr WParam, IntPtr LParam);
        private const int WM_NCHITTEST = 0x84;
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_NCHITTEST)
            {
                MovablePanel.SendMessage(this.Parent.Handle, 1024, new IntPtr(0), new IntPtr(1));
            }
            base.WndProc(ref m);
        }
    }

در کنترل فرم ام :

کد:
        private const int WM_NCHITTEST = 0x84;
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 1024)
            {
                m.Result = (IntPtr)2;
                return;
            }
            base.WndProc(ref m);
        }

پیام به کنترل فرم میرسه اما با کد m.Result = (IntPtr)2 ، جابجا نمیشه . چرا؟ این کد رو میشه تغییر داد تا کار کنه؟ اگه آره ، چجوری؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
بعد اینکه استاد علی ، من نام پروژه ام را از VSS به PoshtibangirTolo تغییر دادم .
حالا توی تسک منیجر ، در قسمت اول ، همون نام Vss هست اما متن فرم که PoshtibangirTolo هست :

1.JPG

چی کار باید کرد تا اون نوشته ی VSS در تسک منیجر هم به Poshtibangir Tolo تغییر کنه؟
 

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

بالا