تحريك النافذة بدون شريط العنوان

This article is available in English too, check it out here.

كود: Geming.Samples.FormDragging.zip

مقدمة

درسنا اليوم يتكلم عن كيفية تحريك النافذة Window بدون شريط العنوان Title Bar.

Window Title Bar and Body

ربما تكون لاحظت أن هناك بعض البرامج التي تسمح للمستخدم بتحريك نافذتها بدون استخدام شريط العنوان. فعلى سبيل المثال برنامج Windows Media Player وبرنامج Winamp وأيضا برنامج. فهذه البرامج أصلا ليس لها شريط عنوان فهي تسمح للمستخدم بتحريكها من خلال جسمها وليس من خلال شريط العنوان الخاص بها. وأيضا من البرامج المميزة برنامج Windows Live Messenger فهذا البرنامج يقوم بإخفاء شريط العنوان الخاص به حتى يقوم المستخدم بضغط زر Alt فيظهر شريط القوائم وشريط العنوان. وأيضا فبرنامج Windows Live Messenger يسمح لك بتحريك نوافذه بدون استخدام شريط العنوان أو على الأقل من شكل مبتكر يسمح لك بتحريك الشاشة من خلاله كصورة مثلا كبديل لشريط العنوان.

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

الفكرة

نظريا، لا يمكنك تحريك النافذة بدون شريط العنوان. ولكن، يمكنك ذلك عن طريق محاكاة عملية التحريك والتي تتكون من الضغط بزر الماوس الأيسر على شريط العنوان ثم التحريك مع الاستمرار في الضغط وهكذا تتم عملية سحب أو تحريك النافذة. فبدلا من جعل المستخدم يقوم بالضغط على شريط العنوان سوف نجعله يقوم بسحب النافذة من خلال جسمها أي أنه سوف يقوم بالضغط على جسم النافذة والسحب ومن خلال الكود سوف نقوم بعملية المحاكاة وبالتالي يكون ضغطه على جسم النافذة كأنه يضغط على شريط العنوان وبالتالي يمكنه تحريك النافذة من خلال جسم النافذة.

لتطبيق عملية المحاكاة سوف نستخدم الدالة SendMessage() وهي دالة خاصة بالويندوز أي دالة Win32 API Function. تستخدم هذه الدالة لإرسال أمر معين (رسالة Message معينة) إلى عنصر معين. كما يمكنك إضافة خيارات معينة إلى هذه الرسالة لتنفيذ الأمر المعين. فعلى سبيل المثال، لمحاكاة عملية الضغط على شريط العنوان سوف نقوم بإرسال الأمر (الرسالة) WM_NCLBUTTONDOWN إلى النافذة نفسها ومع هذه الرسالة سوف نقوم بتحديد الاختيار HTCAPTION. وبالتالي سوف نقوم بمحاكاة الضغط بالزر الأيسر (WM_NCLBUTTONDOWN) على شريط العنوان (HTCAPTION) وهكذا. وهذا الكود بالطبع سوف يوضع في المكان المعين الذي نرغب بجعله بدل شريط العنوان. فمثلا إذا كنا نرغب بالسماح للمستخدم بتحريك النافذة من جسمها سوف نقوم بإضافة الكود الخاص بنا في حدث Event الضغط بالماوس MouseDown الخاص بالفورمة Form. أما في حالة أننا نريد أن نسمح للمستخدم بتحريك النافذة من خلال عنصر صورة PictureBox مثلا، سوف نقوم بإضافة الكود في الحدث MouseDown الخاص بهذا العنصر. وهكذا…

التطبيق

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

  1. افتح مشروع جديد من نوع Windows Forms Application.
  2. من خلال شاشة خصائص الفورمة حدد خاصية FormBorderStyle لتصبح None وبالتالي يختفي شريط العنوان.
  3. من خلال شاشة خصائص الفورمة أيضا قم بالانتقال إلى الأحداث الخاصة بالفورمة وقم بالضغط على الحدث MouseDown مرتين لإظاهره في شاشة الكود. الشكل التالي يوضح شاشة خصائص الفورمة في وضع الأحداث Events.
    Selecting MouseDown Event
  4. الآن قم بإضافة هذا الكود إلى الحدث MouseDown:
    // C#
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    ReleaseCapture();
    SendMessage(this.Handle,
        WM_NCLBUTTONDOWN,
        HTCAPTION, 0);
}
    ' VB.NET
Private Sub Form1_Load _
        (ByVal sender As Object, ByVal e As EventArgs) _
        Handles MyBase.Load
    ReleaseCapture()
    SendMessage(Me.Handle, _
        WM_NCLBUTTONDOWN, _
        HTCAPTION, 0)
End Sub

ثم قم بعد ذلك بإضافة هذا الكود إلى الفورمة نفسها أي ليس داخل أي حدث أو دالة:

    // C#
[DllImport("user32.dll")]
    static extern int SendMessage(
    IntPtr hWnd,
    int Msg,
    int wParam,
    int lParam);
[DllImport("user32.dll")]
static extern bool ReleaseCapture();
const int WM_NCLBUTTONDOWN = 0xA1; // 161
const int HTCAPTION = 2;
    ' VB.NET
Declare Function SendMessage Lib "user32.dll" ( _
    ByVal hWnd As IntPtr, _
    ByVal Msg As Integer, _
    ByVal wParam As Integer, _
    ByVal lParam As Integer) As Integer
Declare Auto Function ReleaseCapture _
Lib "user32.dll" () As Boolean
Const WM_NCLBUTTONDOWN As Integer = 161
Const HTCAPTION As Integer = 2

والآن قم بتشغيل البرنامج وتجربته.

معالجة الأخطاء

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

والحل أن تقوم بوضع الكود الموجود في حدث MouseDown الخاصة بالفورمة في كل حدث MouseDown لكل عنصر آخر على النافذة ترغب في أن تسمح للمستخدم بتحريك الشاشة من خلاله كعنصر عنوان Label مثلا.

أو طريقة أخرى وذلك لاختصار الكود وجعله أسهل وهي وضع الكود الموجود في حدث MouseDown في دالة جديدة خاصة به لنفرض أن يكون اسمها مثلا DragForm() ثم بعد ذلك تقوم بالنداء على هذه الدالة من كل حدث MouseDown لكل عنصر ترغب في السماح للمستخدم بتحريك النافذة من خلاله وهكذا.

مثال

أما الآن فهذا مثال يوضح ما شرحناه وهو عبارة عن برنامج بسيط بالـ C# يسمح للمستخدم بتحريك الفورمة من خلال جسمها. تم تصميم خلفية بسيطة للفورمة ووضعها كخلفية وليس بداخل صورة. هذه صورة من المثال:

Moving Form without Title Bar Sample Snapshot

تحميل المثال

مواضيع مشابهة:

اخترنا لك:

أحدث المواضيع:

هل أعجبتك؟ شارك بها...
  • Besada Hanna

    Dear Eng Mohammed

    Congratulations on the new site
    a good idea to start publishing lessons in arabic
    but i preferred the english site
    just like magic

    good article and hope for more great work

    your brother
    Besada

  • Besada Hanna

    Dear Eng Mohammed

    Congratulations on the new site
    a good idea to start publishing lessons in arabic
    but i preferred the english site
    just like magic

    good article and hope for more great work

    your brother
    Besada

  • Yes it is. We are making every effort to bring Just Like a Magic to everyone in this world.

    Thanks Hanna

  • Yes it is. We are making every effort to bring Just Like a Magic to everyone in this world.

    Thanks Hanna

  • Pingback: Moving a Form without the Title Bar | Just Like a Magic()

  • h.wasef

    ماشاء الله شغل جميل أتمني لك التوفيق الدائم ان شاء الله