بتـــــاريخ : 1/13/2011 7:21:49 PM
الفــــــــئة
  • الحـــــــــــاسب
  • التعليقات المشاهدات التقييمات
    0 1032 0


    خدعوك فقالوا ...

    الناقل : elmasry | العمر :42 | الكاتب الأصلى : تركي العسيري | المصدر : www.al-asiri.com

    كلمات مفتاحية  :

    الغالبية الساحقة من كتب البرمجة (ومنها كتابي المغبون) تدعي جزافا بأن عملية فتح نافذة أخرى على نمط Modal Window (أي فتحها بالطريقة ShowDialog()‎ وليس Show()‎) يؤدي الى وقف تنفيذ النافذة الفاتحة Caller Window حتى تغلق النافذة المفتوحة Callee Window:


    Basic:
    Dim f As New Form2

    f.ShowDialog()
    ' الكود التالي لن يتم تنفيذه حتى يتم اغلاق
    ' Form2 النافذة



    C#:
    Form2 f = new Form2();

    f.ShowDialog();
    // الكود التالي لن يتم تنفيذه حتى يتم اغلاق
    // Form2 النافذة




    إن ما يحدث في الشيفرة السابقة وقف وهمي لتنفيذها وليس حقيقي، فالكود الذي سيتم ايقاف عمله هو التابع لنفس الدورة الخاصة بحلقة الرسائل Message Loop والتي تعتبر القلب النابض الذي يبقي النافذة على قيد الحياة (مبرمجي Windows API يفهمون ما أعني تماما)، وحتى تكتشف الخدعة التي وقعت بها طيلة السنين السابقة، جرب واكتب في حدث -مثلا- الرسم Paint شيئا مثل:

    Basic:
    Dim gr As Graphics = e.Graphics
    gr.Clear(Me.BackColor)
    gr.DrawString(Now.ToString("hh:mm:ss"), Me.Font, Brushes.Black, 0, 0)


    C#:
    Graphics gr = e.Graphics;
    gr.Clear(this.BackColor);
    gr.DrawString(DateTime.Now.ToString("hh:mm:ss"), this.Font, Brushes.Black, 0f, 0f);


    ستلاحظ يا أيها الزائر العزيز او الزائرة الجميلة أن أي سبب يؤدي الى اعادة رسم النافذة سيقود فورا الى تفجير حدثها Paint، مما يعني ان النافذة لا زالت تستقبل أحداثا وكأن شيئا لم يحدث!


    أزيدك من الشعر قصيدة (وليس بيت)، عندما تقوم بفتح نافذة باستخدام ShowDialog()‎ وتحاول نقر النافذة الفاتحة لها حتى تفجر حدثها Click او DoubleClick فأنت تعلم أن معمارية نظام التشغيل تمنعك من هذا وستظهر صوت جرس Beep، ولكني لازلت أحذرك بأن ((جميع)) الأحداث لا تزال قابلة للتفجير، ولو تحاول مثلا تفجير حدثها Click بطريقة ملتوية عن طريق الدالة SendMessage()‎ مثلا:

    Basic:
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA"
          (ByVal Hwnd As IntPtr, ByVal wMsg As Integer,
           ByVal wParam As Integer, ByVal lParam As Integer) As Integer

    Private Const WM_LBUTTONUP As Integer = &H202
    Private Const WM_LBUTTONDOWN As Integer = &H201
    ...
    ...
    ...

    SendMessage(CallerForm.Handle, WM_LBUTTONDOWN, 1&, 0)
    SendMessage(CallerForm.Handle, WM_LBUTTONUP, 1&, 0)





    C#:
    [System.Runtime.InteropServices.DllImport("user32",
          EntryPoint = "SendMessageA", SetLastError = true,
          ExactSpelling = true)]
    private static extern int SendMessage(IntPtr Hwnd, int wMsg, int wParam, int lParam);

    private const int WM_LBUTTONDOWN = 0x201;
    private const int WM_LBUTTONUP = 0x202;
    ...
    ...
    ...


    Form2.SendMessage(this.CallerForm.Handle, WM_LBUTTONDOWN, 1, 0);
    Form2.SendMessage(this.CallerForm.Handle, WM_LBUTTONUP, 1, 0);



    سيتم تفجير الحدث! ولو وجدت أحداث أخرى متكررة غير متعلقة بالنافذة بشكل مباشر (كإستخدام أداة Timer) سيتم تفجير حدثها دائما، لذلك وجب عليك الحذر فقد يتم فتح نفس النافذة اكثر من مرة بـ ShowDailog()‎ وتحدث أمور لا يمكن تخيلها!

    يمكنك
    إنزال هذا المثال الذي يظهر كم كنت مخدوع .. مخدوع .. مخدوع .. يا ولدي




    -- تركي

    كلمات مفتاحية  :

    تعليقات الزوار ()