يمكنني تعليق إعادة رسم شكل حتى لقد أنجزت كافة التحديثات؟

StackOverflow https://stackoverflow.com/questions/615781

سؤال

وعن طريق C # و. NET 2.0، أنا باستخدام شكل غير منتظم الشكل (TransparencyKey، FormBorderStyle = بلا، الخ ...) وتريد السماح "طبيعية" واسطة تحدها.

ويمكنني تغيير لون الخلفية الافتراضي من الجير يمكنني تغيير FormBorderStyle إلى FixedSingle I تغيير TransparencyKey إلى Colour.None

وUnfortuanately هذا يبدو فوضى كاملة على الشاشة مع صورة القفز بضعة بكسل أسفل وإلى الجانب وشكل الأخضر الجير.

وأعتقد أن سبب ذلك شكل يجري إعادة رسم بعد كل سطر من التعليمات البرمجية، غير أنه من الممكن تعليق رسم شكل حتى لقد جعلت التغييرات الخاص بي، وبعد ذلك فقط إعادة رسم شكل واحد؟

وG

هل كانت مفيدة؟

المحلول

والجواب جديد: تجاوز WndProc ومنع رسالة WM_PAINT أثناء تطبيق خصائص النافذة الجديدة

والجواب قديم.: تجاوز WndProc، ومنع رسالة WM_ERASEBKGND

وشرح ما يقوم به الرمز أدناه:

عند ينتقض المنطقة النافذة، يرسل Windows سلسلة من الرسائل إلى عنصر التحكم الذي يؤدي إلى رسمت طازجة القطعة. رسالة في وقت مبكر من هذه السلسلة هي WM_ERASEBKGND. عادة، ردا على هذه الرسالة، والسيطرة يرسم نفسه بلون واحد. وفي وقت لاحق، ردا على رسالة WM_PAINT (والذي يستهلك عادة من قبلنا في حال OnPaint) ويتم الرسم الفعلي. إذا كان هذا الرسم هو غير تافهة سوف يكون هناك تأخير قبل أن يتم تحديث القطعة وستحصل على وميض مزعج.

وعند النظر إلى التعليمات البرمجية الخاصة بك مرة أخرى كنت حل واضح لمشكلة مختلفة. جرب هذا مثال جديد. فإنه سيتم منع هذه اللوحة من النموذج / السيطرة إذا علم bAllowPaint هو ضبطه.

و <م> NEW مثال:

    private const int WM_PAINT = 0x000F;

    protected override void WndProc(ref Message m)
    {
        if ((m.Msg != WM_PAINT) ||
            (bAllowPaint && m.Msg == WM_PAINT))
        {
            base.WndProc(ref m);
        }
    }

و <م> OLD مثال:

    private const int WM_ERASEBKGND = 0x0014;

    protected override void WndProc(ref Message m)
    {
        if (m.Msg != WM_ERASEBKGND) // ignore WM_ERASEBKGND
        {
            base.WndProc(ref m);
        }
    }

نصائح أخرى

وحاول الملكية Form.DoubleBuffered. تعيين إلى 'true'.

وأيضا، إذا كان النموذج الخاص بك لديه أي عناصر التحكم التابعة، أيضا تعيين DoubleBuffered إلى true لأولئك، وكذلك (والأطفال الأطفال وغيرها، وأسفل الخط).

وأخيرا، ندعو SuspendLayout قبل التغييرات وResumeLayout بعد ذلك. نضع في اعتبارنا هذا يؤثر فقط على وضع ضوابط الطفل. إذا كنت تفعل أي عرف رسم الملكية DoubleBuffered سوف اعطيكم المزيد من ضجة لباك.

وأنت تقوم بتعديل الخصائص التي لها تأثير كبير ليس على النموذج. TransparencyKey وFormBorderStyle تتطلب تغيير بت نمط الإطار. نوافذ لا تسمح هذه البتات النمط إلى أن تتغير. أشكال النوافذ تطبق عليها عن طريق تدمير تماما النافذة وإعادة إنشاء من الصفر. خدعة متقنة، ولكن ذلك يستغرق وقتا طويلا وسيتم شكل طلاؤها في كل مرة قمت بتغيير النمط. مما تسبب في المؤثرات البصرية غير سارة تراه.

وجرب هذا: 1. تعيين التعتيم إلى 0 بحيث يصبح شكل غير مرئي 2. تغيير ون_الخلفية، لا مشكلة 3. تغيير FormBorderStyle، ويحصل على صوغه نافذة 4. تغيير TransparencyKey، ويحصل على صوغه نافذة 5. تغيير التعتيم على 1، ويحصل على صوغه النافذة، ثم مرئية

وعلى سبيل المثال:

  this.Opacity = 0;
  this.BackColor = Color.FromKnownColor(KnownColor.Control);
  this.FormBorderStyle = FormBorderStyle.Sizable;
  this.TransparencyKey = Color.Empty;
  this.Opacity = 1;

وإذا كان كل فشل ذلك، قد تتمكن من محاولة بعض القرصنة lowlevel من خلال منع جميع المشاركات الطلاء إلى النموذج الخاص بك.

تحذير: أنا لا تشجيع استخدام هذه الطريقة، ولكن يمكنك أن تجرب ذلك إذا كنت تريد حقا أن. وقد ساعدني في الماضي.

Win32.LockWindowUpdate(this.Handle);
try
{
   //make your changes here
}
finally
{
  //release the lock
  Win32.LockWindowUpdate((IntPtr)0);
}

ويعتمد هذا الرمز على رمز دعم التالية:

public class Win32
{
  private Win32() { }

    /// <summary>
    /// Lock ore relase the wndow for updating.
    /// </summary>
    [DllImport("user32")]
    public static extern int LockWindowUpdate(HWND hwnd);
 }

وهناك طريقة لإرسال جميع "صورة" من النموذج إلى الشاشة في خطوة واحدة هي لتمكين DoubleBuffer.

في منشئ يمكنك تعيين ControlStyles

وVB.NET:

SetStyle(ControlStyles.DoubleBuffer, True)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top