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

the_king

مدیرکل انجمن
سلامی مجدد
استاد علی ، الان اینی که گفتم ، درسته؟
من الان فکر میکنم ، بازم عجیبه برام .
مثلا فرض کنیم دو تا کنترل TransparentControl را روی پنل ای داریم . وقتی موس را روی هر کدوم از شی TransparentControl میبریم ، بگیم که فقط اون بخشی از پنل که فقط همون کنترل TransparentControl هست را Invalidate کنه . پس قسمت دیگه ی پنل که یکی دیگه از کنترل TransparentControl هست ، اصلا Invalidate نمیشه که بخواد تغییری کنه!
اگر در مورد TransparentControl خودتون حرف نمی زدید و روال عادی Invalidate شدن ها رو در نظر میگرفتیم، بله، حرفتون کاملا صحیح بود، چون Invalidate ای که شامل یک ناحیه مشخص میشه به اصطلاح رسم رو Clip می کنه به اون ناحیه و رسم فقط اون ناحیه Clip بروز میشه و بقیه قسمت ها نادیده گرفته میشه. اما در مورد TransparentControl شما که اینطور نیست، چون همانطور که قبلا هم متذکر شدم نباید ترتیب رسم پنجره ها رو بهم بزنید، همونکاری که شما در کلاس تون انجام میدهید. شما میایید ترتیب رسم پنجره ها رو قاطی پاتی میکنید، از یک طرف میایید میگید فقط یکجای خاص Invalidate بشه و از طرف دیگه پنجره ای که تو باغ نیست و اصلا ربطی به اون ناحیه نداره رو وادار به Invalidate می کنید.
شما در کدتون AllParents_Invalidated رو دارید، مگه نه؟ با OnParentChange مشخصا کنترل رو وادار می کنید که برای هر Invalidate شدن والدش AllParents_Invalidated رو اجرا کنه و مجددا رسم بشه، یعنی اگه برای رسم شهرام والدش Invalidate کرده به بهرام و بهزاد هم میگه خودتون رو Invalidate کنین، در حالی که رسم زیر بهرام و بهزاد نه پاک شده بوده و نه تغییری کرده بوده چون شما یک ناحیه دیگه رو Invalidate کرده بودید.
بهرام و بهزاد مجبور میشن رسم نیمه شفاف خودشون رو مجددا روی رسم قبلی خودشون بکشن و پر رنگ ترش کنن.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
اگر در مورد TransparentControl خودتون حرف نمی زدید و روال عادی Invalidate شدن ها رو در نظر میگرفتیم، بله، حرفتون کاملا صحیح بود، چون Invalidate ای که شامل یک ناحیه مشخص میشه به اصطلاح رسم رو Clip می کنه به اون ناحیه و رسم فقط اون ناحیه Clip بروز میشه و بقیه قسمت ها نادیده گرفته میشه. اما در مورد TransparentControl شما که اینطور نیست، چون همانطور که قبلا هم متذکر شدم نباید ترتیب رسم پنجره ها رو بهم بزنید، همونکاری که شما در کلاس تون انجام میدهید. شما میایید ترتیب رسم پنجره ها رو قاطی پاتی میکنید، از یک طرف میایید میگید فقط یکجای خاص Invalidate بشه و از طرف دیگه پنجره ای که تو باغ نیست و اصلا ربطی به اون ناحیه نداره رو وادار به Invalidate می کنید.
شما در کدتون AllParents_Invalidated رو دارید، مگه نه؟ با OnParentChange مشخصا کنترل رو وادار می کنید که برای هر Invalidate شدن والدش AllParents_Invalidated رو اجرا کنه و مجددا رسم بشه، یعنی اگه برای رسم شهرام والدش Invalidate کرده به بهرام و بهزاد هم میگه خودتون رو Invalidate کنین، در حالی که رسم زیر بهرام و بهزاد نه پاک شده بوده و نه تغییری کرده بوده چون شما یک ناحیه دیگه رو Invalidate کرده بودید.
بهرام و بهزاد مجبور میشن رسم نیمه شفاف خودشون رو مجددا روی رسم قبلی خودشون بکشن و پر رنگ ترش کنن.

سلام
خیلی ممنون استاد علی
من هر چی فکر میکنم ، توضیحات شما را هم بررسی میکنم ، بازم دلیلش را متوجه نمیشم.
من این کد را یه کم تغییر دادم و براتون در اینجا پیوست میکنم . تغییرش هم فقط توی تابع EventOperation بود که ورودی متد زیر را تغییر دادم :


کد:
this.Parent.Invalidate(this.Bounds);

تا فقط parent ای که Invalidate میشه ، فقط همون قسمتی که کنترل جاری TransparentControl هست را Invalidate کنه . جاهایی که نیاز نبود را کامنت کردم موقتا.
ببینید ؛ الان من توی کدهام بصورت کلی گفتم که هر وقت ، هر والدِ TransparentControl ، عمل Invalidate را انجام داد ، کنترل (جاری) TransparentControl را هم Invalidate کنه . چون مثلا وقتی فرم مون minimize و بعد maximize بشه یا کلا کاری روش انجام بشه که عمل Invalidate را انجام بده ، کنترل های فرزندش مثل TransparentControl (در هر سطح از لایه ای) هم نمیدونم چرا باعث میشه فقط پاک بشن (یعنی رسم مجدد نمیشن) . واسه همین گفتم بعد از اینکه والدِ TransparentControl ، عمل Invalidate را انجام داد ، کنترل TransparentControl هم Invalidate بشه تا مجددا رسم بشه. این از این ، که تا اینجا هیچ مشکلی نباید باشه . درسته؟

اما همچنین گفتم رویداد های MouseEnter و MouseDown و MouseUp و MouseLeave از کنترل TransparentControl هم وقتی انجام شدن (چون 3 بیت مپ مختلف برای رسم در 3 رویداد مختلف دارم و برای اینکه روی رسم قبلی ، رسمی انجام نشه و فقط رسم بیت مپ در اون رویداد مورد نظر رسم بشه) ، کنترل والدش را Invalidate کن منتها این بار فقط اون بخشی از کنترل والد را Invalidate کن که مکان و اندازه (کلا Bound) کنترل جاریِ TransparentControl وجود داره. :green: خوب ، در خط قبل هم گفتم هر وقت parent اش Invalidate شد ، کنترل جاری (که شامل هر کنترل TransparentControl دیگه ای در اون والد میشه) را هم مجددا Invalidate و رسم کنه و این در صورتی هه که بقیه ی جاهایی که کنترل های دیگه ی TransparentControl ، اون رویدادهای MouseEnter و MouseDown و MouseUp و MouseLeave براشون انجام نشده بود ، در اون قسمت bound والدش ، اصلا عمل Invalidate انجام نشده بود و پاک نشده بودن اما رسم شدن پس روی رسم قبلی ، رسم شدن . :green:
الان تازه یادم اومد.

پس مشکل من اینه که برای هر Invalidate شدن والد ، حتما نباید کنترل جاری TransparentControl ، رسم بشه . اما هنوزم یه کم گنگ هه برام و باید فکر کنم ببینم چجوری باید الگوریتمش را تغییر بدم تا درست شه. میشه یه کم توی تغییر الگوریتمش کمکم کنید؟
پس حالا که مشکل را متوجه شدم ، فایل را پیوست نمیکنم .
خیلی ممنون
 

SajjadKhati

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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
استاد علی ، آخرین تغییرات را دادم ، یه نگاهی میکنین اگه اشکالی به نظرتون رسید رو بگین و طریقه ی رفع اش هم همینطور؟
من تست کردم ، مشکل خاصی نداشت جز اینکه موقعی که کنترل را جابجا میکنم ، گاها و خیلی تک و توک ، روی بعضی از شی های کنترل TransparentControl ، رسم مجددی که باعث کلفت تر شدنشون بشه ، انجام میشه (یعنی انگار parent اش invalidate نمیشه بسیار تک و توک) . در صورتی که من در متد OnLocationChange ، والدش را هم invalidate کردم.
کلاس اش با آخرین بروزرسانی رو براتون توی این پست پیوست میکنم .
با تشکر
 

پیوست ها

  • TransparentControl.rar
    8.4 کیلوبایت · بازدیدها: 1

the_king

مدیرکل انجمن
استاد علی ، آخرین تغییرات را دادم ، یه نگاهی میکنین اگه اشکالی به نظرتون رسید رو بگین و طریقه ی رفع اش هم همینطور؟
من تست کردم ، مشکل خاصی نداشت جز اینکه موقعی که کنترل را جابجا میکنم ، گاها و خیلی تک و توک ، روی بعضی از شی های کنترل TransparentControl ، رسم مجددی که باعث کلفت تر شدنشون بشه ، انجام میشه (یعنی انگار parent اش invalidate نمیشه بسیار تک و توک) . در صورتی که من در متد OnLocationChange ، والدش را هم invalidate کردم.
کلاس اش با آخرین بروزرسانی رو براتون توی این پست پیوست میکنم .
با تشکر
مساله رسم این کنترل ها به این سادگی ها حل شدنی نیست، مخصوصا وقتی زیرش کنترلی باشه که مثل کنترل خودتون روال غیر عادی داشته باشه دیگه حل شدنش خیلی سخته. پس توقع نداشته باشید که رسم کنترل تون همیشه و در همه شرایط درست جواب بده. اما حداقل باید برای شرایط عادی و مرسوم کاری کنید کنترل تون درست رسم کنه.
اگه دنبال اشکال می گردید فرضا وقتی Panel ای زیرش قرار داره که Parent اش نیست :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(20, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }
که اگه نیمه اش روی اون قرار بگیره میتونه بدتر هم بشه :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(65, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
مساله رسم این کنترل ها به این سادگی ها حل شدنی نیست، مخصوصا وقتی زیرش کنترلی باشه که مثل کنترل خودتون روال غیر عادی داشته باشه دیگه حل شدنش خیلی سخته. پس توقع نداشته باشید که رسم کنترل تون همیشه و در همه شرایط درست جواب بده. اما حداقل باید برای شرایط عادی و مرسوم کاری کنید کنترل تون درست رسم کنه.
اگه دنبال اشکال می گردید فرضا وقتی Panel ای زیرش قرار داره که Parent اش نیست :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(20, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }
که اگه نیمه اش روی اون قرار بگیره میتونه بدتر هم بشه :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(65, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }

خیلی ممنون
چرا این جوری هه؟
من یه پنل میذارم و این کنترل های TransparentControl را فرزندش میکنم و opacity شو کم میکنم ، مشکلی نداره ولی توی کد شما چرا مشکل داره؟!
خوب شما پنل رو والدش نکردید اما موس وقتی روی کنترل TransparentControl میره ، والدش که در کد شما فرم هست و اون قسمتی اش که کنترل TransparentControl نسبت به فرم قرار داره را Invalidate میکنه پس باید رسم TransparentControl و پنل ، پاک بشه . بعدش هم که توی رویداد AllParents_Invalidated ، کنترل TransparentControl ای که موس روش رفت را Invalidate کردیم که مجدد باید رسم بشه.
دلیلش چیه؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
مساله رسم این کنترل ها به این سادگی ها حل شدنی نیست، مخصوصا وقتی زیرش کنترلی باشه که مثل کنترل خودتون روال غیر عادی داشته باشه دیگه حل شدنش خیلی سخته. پس توقع نداشته باشید که رسم کنترل تون همیشه و در همه شرایط درست جواب بده. اما حداقل باید برای شرایط عادی و مرسوم کاری کنید کنترل تون درست رسم کنه.
اگه دنبال اشکال می گردید فرضا وقتی Panel ای زیرش قرار داره که Parent اش نیست :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(20, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }
که اگه نیمه اش روی اون قرار بگیره میتونه بدتر هم بشه :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(65, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }

اون پنل پشتش را وقتی حذف میکنیم ، درست میشه .
کلا اگه کنترلی پشتش نباشه ، مشکلی نداره .
وقتی کنترلی پشتش اضافه کنیم ، مگه چه اتفاقی میافته؟ البته اصولی چندان هم نیست که یه کنترل را پشت یه کنترل دیگه بذارن.
چرا؟!

--------------------------------------------------------

ویرایش :
آها پیدا کردم .
باید اون کنترل های پشتش هم Invalidate بشن.
خوب اینم ان شاء ا... درست میکنم .
باز مشکل دیگه ای نیست؟
 
آخرین ویرایش:

the_king

مدیرکل انجمن
خیلی ممنون
چرا این جوری هه؟
من یه پنل میذارم و این کنترل های TransparentControl را فرزندش میکنم و opacity شو کم میکنم ، مشکلی نداره ولی توی کد شما چرا مشکل داره؟!
خوب شما پنل رو والدش نکردید اما موس وقتی روی کنترل TransparentControl میره ، والدش که در کد شما فرم هست و اون قسمتی اش که کنترل TransparentControl نسبت به فرم قرار داره را Invalidate میکنه پس باید رسم TransparentControl و پنل ، پاک بشه . بعدش هم که توی رویداد AllParents_Invalidated ، کنترل TransparentControl ای که موس روش رفت را Invalidate کردیم که مجدد باید رسم بشه.
دلیلش چیه؟
فرم رسم خودش رو Invalidate می کنه ولی چیزی که شما پشت کنترل تون می بینید اصلا فرم نیست، پنل ئه، فرم پشت پنل قایم شده، هر چند بار هم که فرم رو مجدد رسم کنید، پشت رسم پنل مخفی مونده.
پنل ئه که باید پیش از رسم کنترل شما رسم مجدد بشه که نمیشه چون اصلا تو جریان نیست.

اون پنل پشتش را وقتی حذف میکنیم ، درست میشه .
کلا اگه کنترلی پشتش نباشه ، مشکلی نداره .

که اونوقت شفافیت معنی نداره.

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

SajjadKhati

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


که اونوقت شفافیت معنی نداره.


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

خیلی ممنون استاد علی
الان آخرین ویرایشش ، همینی شد که در همین پست پیوست میکنم که اون مشکل آخری که گفته بودین ، رفع شد.
من که مشکل خاص دیگه ای ندیدم . حالا اگه براتون مقدر هه ، ببینین شما مشکلی ازش میبینین که بگین؟
ممنون
 

پیوست ها

  • TransparentControl.rar
    9.3 کیلوبایت · بازدیدها: 1

the_king

مدیرکل انجمن
خیلی ممنون استاد علی
الان آخرین ویرایشش ، همینی شد که در همین پست پیوست میکنم که اون مشکل آخری که گفته بودین ، رفع شد.
من که مشکل خاص دیگه ای ندیدم . حالا اگه براتون مقدر هه ، ببینین شما مشکلی ازش میبینین که بگین؟
ممنون
شما میگید ولی من که نمیبینم اشکال برطرف شده باشه :D
اولا همچنان وقتی پنل پشتش قرار داره ولی Parent اش نیست، رسم پر رنگ میشه. وقتی هم نیمه ای از کنترل روی پنل قرار داره همچنان همون حالت رسم نصفه ای پیش میاد که قبلا مشکلش بود و پا برجاست :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(65, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }

ثانیا وقتی پنل کاملا پشتش قرار داره باید یکی از اون سه تصویر انتخابی نشون داده بشه، نه اینکه قاطی شون کنه. الان یه چیزی رسم میکنه از ترکیب defaultBitmap و mouseEnterBitmap که معلوم نیست نماد چیه :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Warning.ToBitmap(), 50);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(20, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }

اولویت رسم که کدوم کنترل زیر قرار داره و کدوم رو هم که کلا کدتون اهمیتی بهش نمیده و کنترل کنارش رو از شفافیت در میاره :
کد:
       private void Form2_Load(object sender, EventArgs e)
        {
            var bmp1 = SystemIcons.Question.ToBitmap();
            var bmp2 = SystemIcons.Warning.ToBitmap();
            var bmp3 = SystemIcons.Hand.ToBitmap();
            var t1 = new TransparentControl(bmp1, bmp2, bmp3, new Point(50, 50)) { Parent = this };
            var t2 = new TransparentControl(bmp1, bmp2, bmp3, new Point(65, 50)) { Parent = this };
        }

قبلا گفتم که کار راحتی نیست.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
شما میگید ولی من که نمیبینم اشکال برطرف شده باشه :D
اولا همچنان وقتی پنل پشتش قرار داره ولی Parent اش نیست، رسم پر رنگ میشه. وقتی هم نیمه ای از کنترل روی پنل قرار داره همچنان همون حالت رسم نصفه ای پیش میاد که قبلا مشکلش بود و پا برجاست :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(65, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }

سلامی مجدد
خیلی ممنون استاد علی
یه پارامتری برای بعضی از متدهای سازنده ایجاد کردم (توی همین آخرین فایلی که در پست بالا آپلود کردم) بنام invalidateBackControls که کاربر باید در صورتی که کنترلی ، پشتِ کنترل TransparentControl قرار میگیره را بهش بده تا invalidate شون کنه :


کد:
            var bmp = TransparentControl.SetOpacity(SystemIcons.Question.ToBitmap(), 20);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(65, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50), p) { Parent = this };
            t.BringToFront();


ثانیا وقتی پنل کاملا پشتش قرار داره باید یکی از اون سه تصویر انتخابی نشون داده بشه، نه اینکه قاطی شون کنه. الان یه چیزی رسم میکنه از ترکیب defaultBitmap و mouseEnterBitmap که معلوم نیست نماد چیه :
کد:
        private void Form1_Load(object sender, EventArgs e)
        {
            var bmp = TransparentControl.SetOpacity(SystemIcons.Warning.ToBitmap(), 50);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(20, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50)) { Parent = this };
            t.BringToFront();
        }

و همچنین این هم :


کد:
            var bmp = TransparentControl.SetOpacity(SystemIcons.Warning.ToBitmap(), 50);
            var p = new Panel() { BackColor = Color.LightBlue, Bounds = new Rectangle(20, 20, 100, 100), Parent = this };
            var t = new TransparentControl(bmp, SystemIcons.Information.ToBitmap(), bmp, new Point(50, 50), p) { Parent = this };
            t.BringToFront();

اولویت رسم که کدوم کنترل زیر قرار داره و کدوم رو هم که کلا کدتون اهمیتی بهش نمیده و کنترل کنارش رو از شفافیت در میاره :
کد:
       private void Form2_Load(object sender, EventArgs e)
        {
            var bmp1 = SystemIcons.Question.ToBitmap();
            var bmp2 = SystemIcons.Warning.ToBitmap();
            var bmp3 = SystemIcons.Hand.ToBitmap();
            var t1 = new TransparentControl(bmp1, bmp2, bmp3, new Point(50, 50)) { Parent = this };
            var t2 = new TransparentControl(bmp1, bmp2, bmp3, new Point(65, 50)) { Parent = this };
        }

قبلا گفتم که کار راحتی نیست.

:green:

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

SajjadKhati

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


1.JPG

ممنون
 

SajjadKhati

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


مشاهده پیوست 112453

ممنون

سلامی مجدد
پیدا کردم .
باید پروپرتی ShowImageMargin در ContextMenuStrip را ست کرد.
خیلی ممنون
 

SajjadKhati

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

Prevent a user from deleting, moving or renaming a file

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

the_king

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

Prevent a user from deleting, moving or renaming a file

منظورم اینه که تا وقتی پروسه ی برنامه ام باز هست ، فایل های بکاپ ای که توسط برنامه ام گرفته شدن را بصورت readwrite تا آخر باز نگه دارم تا پروسه یا چیز دیگه ای نتونه حذف شون کنه.
البته ممکنه بگید که هر پروسه ی دیگه ای براحتی میتونه پروسه ی برنامه ی منو ببنده و بعد اونا را حذف کنه . میدونم ولی حالا اگه عاملش ویروس باشه که از برنامه ی من خبر نداره یا اینکه بیشتراشون خبر ندارن یا اینکه شاید راه حلی بعدا برای این هم پیدا کردم.
کلا این روش به نظرتون چطوره؟
نکته اول اینه که مهم نیست فایل x رو برای خواندن باز کنید یا خواندن و نوشتن، مهم اینه که برای دسترسی اشتراکی چه وضعیتی تعیین کنید (System.IO.FileShare) ، ممکنه شما فایلی رو برای فقط خواندن باز کنید در حالی که دسترسی اشتراکی خواندن هم ندید، یا برعکس فایلی رو برای خواندن و نوشتن باز کنید در حالی که به سایرین هم اجازه بدید همین دسترسی رو داشته باشند.
نکته دوم این فایل backup شما نیست، backup ئه VSS ئه، قراره همیشه بهش دسترسی خواندن و نوشتن داشته باشه، شما می خواهید بگید میخوام کاری کنم که VSS نتونه تغییرات لحظه ای رو توی فایل backup بنویسه؟
حالا گیرم که شدنی باشه این چیزی است که مطلوب تون باشه؟ و یادتون نره که backup شما از اون لحظه ای که ساختید اش به تدریج بروز میشه، نه اینکه همون لحظه بسازید و بعد قفل اش کنید که دیگه روش چیزی نوشته نشه.
 

the_king

مدیرکل انجمن
و اینم در نظر بگیرید که تهدید کاذب ایجاد نشه، تا حالا ویروسی شناسایی کردید که اهمیتی به وجود اون فایل backup ئه VSS شما بده؟ ویروس معمولا میاد سیستم و برنامه شما رو آلوده میکنه و بخش اساسی از کار میافتند و میره پی کارش.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنونم
استاد علی ، میگم آیا میشه بجای اینکه کاربر روی درایوی کلیک راست کنه و properties را بزنه و در سربرگ previous version ، روی بکاپی دابل کلیک کنه تا در explorer.exe ، محتویات اون بکاپ نشون داده بشه ، کد این قضیه را داخل برنامه ام بنویسم (و کاربر با دابل کلیک کردن در لیست بکاپ ها در برنامه ام ، بکاپ مربوط به اون نرم افزار رو در explorer.exe باز کنه) ؟
من توی آدرس همه ی بکاپ هام در explorer که دیدم ، بصورت اشتراکی همه شون قسمت اول آدرس شون این جوری بود :


کد:
"\\localhost\D" + نام درایو + "$\@GMT-"+ تاریخ میلادی+ "-" + زمان بر حسب جی ام تی
مثال برای یکی از بکاپ ها در درایو D :
\\localhost\D$\@GMT-2019.06.02-08.57.12

من توی explorer تست کردم (نه از درون برنامه ام) و کپی کردم و paste کردم ، جواب داد .
حالا میگم این فرمول بالا را اگه توی همه ی کامپیوتر ها بکار بره ، جواب میده؟ همه ی اطلاعات بالا را میشه از VssSnapshotProperties بدست آورد بجز اون آخری هه که زمان بر حسب gmt هست (که حالا ببینم چی کارش میشه کرد)


و هم اینکه میشه برای هر بکاپی که ایجاد میکنم ، یه نام ای در نظر بگیرم که بعدا موقع جستجو ، در شی VssSnapshotProperties نمایش بده؟ اگه آره چجوری؟ ای کاش یه پروپرتیس اضافه مثل Tag داشتن همه شون .
 

SajjadKhati

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

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنونم
استاد علی ، میگم آیا میشه بجای اینکه کاربر روی درایوی کلیک راست کنه و properties را بزنه و در سربرگ previous version ، روی بکاپی دابل کلیک کنه تا در explorer.exe ، محتویات اون بکاپ نشون داده بشه ، کد این قضیه را داخل برنامه ام بنویسم (و کاربر با دابل کلیک کردن در لیست بکاپ ها در برنامه ام ، بکاپ مربوط به اون نرم افزار رو در explorer.exe باز کنه) ؟
من توی آدرس همه ی بکاپ هام در explorer که دیدم ، بصورت اشتراکی همه شون قسمت اول آدرس شون این جوری بود :


کد:
"\\localhost\D" + نام درایو + "$\@GMT-"+ تاریخ میلادی+ "-" + زمان بر حسب جی ام تی
مثال برای یکی از بکاپ ها در درایو D :
\\localhost\D$\@GMT-2019.06.02-08.57.12

من توی explorer تست کردم (نه از درون برنامه ام) و کپی کردم و paste کردم ، جواب داد .
حالا میگم این فرمول بالا را اگه توی همه ی کامپیوتر ها بکار بره ، جواب میده؟ همه ی اطلاعات بالا را میشه از VssSnapshotProperties بدست آورد بجز اون آخری هه که زمان بر حسب gmt هست (که حالا ببینم چی کارش میشه کرد)


و هم اینکه میشه برای هر بکاپی که ایجاد میکنم ، یه نام ای در نظر بگیرم که بعدا موقع جستجو ، در شی VssSnapshotProperties نمایش بده؟ اگه آره چجوری؟ ای کاش یه پروپرتیس اضافه مثل Tag داشتن همه شون .

سلامی مجدد
من کد زیر را مینویسم :


کد:
Process.Start("\\localhost\\F$\\@GMT-2019.06.05-13.53.25");

با اونکه آدرس همچین بکاپی وجود داره و هم اینکه توی explorer.exe که این آدرس را مینویسم ، این آدرس را باز میکنه ولی در کد سی شارپ بالا ، ارور زیر را میده :

کد:
System.ComponentModel.Win32Exception: 'The system cannot find the file specified'

کاریش میشه کرد؟

-----------------------------------------------------------------

ویرایش :

درست شد . حواسم نبود که توی برنامه نویسی وقتی دو تا بک اسلش میخواد ، باید چهار تا بذارم :


کد:
Process.Start("\\\\localhost\\F$\\@GMT-2019.06.05-13.53.25");

حالا حساب کردن زمان gmt از زمان کامپیوتر میمونه !
 
آخرین ویرایش:

the_king

مدیرکل انجمن
خیلی ممنونم
استاد علی ، میگم آیا میشه بجای اینکه کاربر روی درایوی کلیک راست کنه و properties را بزنه و در سربرگ previous version ، روی بکاپی دابل کلیک کنه تا در explorer.exe ، محتویات اون بکاپ نشون داده بشه ، کد این قضیه را داخل برنامه ام بنویسم (و کاربر با دابل کلیک کردن در لیست بکاپ ها در برنامه ام ، بکاپ مربوط به اون نرم افزار رو در explorer.exe باز کنه) ؟
من توی آدرس همه ی بکاپ هام در explorer که دیدم ، بصورت اشتراکی همه شون قسمت اول آدرس شون این جوری بود :


کد:
"\\localhost\D" + نام درایو + "$\@GMT-"+ تاریخ میلادی+ "-" + زمان بر حسب جی ام تی
مثال برای یکی از بکاپ ها در درایو D :
\\localhost\D$\@GMT-2019.06.02-08.57.12

من توی explorer تست کردم (نه از درون برنامه ام) و کپی کردم و paste کردم ، جواب داد .
حالا میگم این فرمول بالا را اگه توی همه ی کامپیوتر ها بکار بره ، جواب میده؟ همه ی اطلاعات بالا را میشه از VssSnapshotProperties بدست آورد بجز اون آخری هه که زمان بر حسب gmt هست (که حالا ببینم چی کارش میشه کرد)

الزاما نه، در ضمن GMT درسته از که از نظر معنی و مفهوم معادل UTC نیست، ولی از نظر مقداری یکی هستند، UTC رو هم که با ToUniversalTime بدست میارید :
DateTime.ToUniversalTime Method (System)

و هم اینکه میشه برای هر بکاپی که ایجاد میکنم ، یه نام ای در نظر بگیرم که بعدا موقع جستجو ، در شی VssSnapshotProperties نمایش بده؟ اگه آره چجوری؟ ای کاش یه پروپرتیس اضافه مثل Tag داشتن همه شون .
نام رو برای اشاره در برای برنامه خودتون در نظر بگیرید و همراه ID اون backup در جایی ثبت کنید که یک GUID منحصر بفرد ئه.
 

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

بالا