الأعراض

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

السبب

تحدث هذه المشكلة عاده عند تنفيذ حلقه استرداد الرسالة كنتيجة الإجراءات التي يتم تنفيذها للتمرير عند تلقي أحدي رسائل اعلام شريط التمرير. عند التمرير ، يتم بدء حلقه استرداد رسالة داخلية في Windows. ان مهمة التكرار الحلقي للرسالة هي الاستمرار في تعقب التمرير وإرسال رسائل الاعلام والWM_HSCROLL والWM_VSCROLL. يتم إنهاء التمرير بمجرد تلقي WM_LBUTTONUP. إذا تم بدء حلقه رسالة أخرى اثناء التمرير ، سيتم استرداد الWM_LBUTTONUP بواسطة التكرار الحلقي للرسالة ، ونظرا لأنه لا يمكنه الوصول إلى التكرار الحلقي لاسترداد الرسالة الداخلية لشريط التمرير ، فلا يمكن إرسال WM_LBUTTONUP بشكل صحيح. التالي ، لا يتم تلقي الWM_LBUTTONUP بواسطة الرسائل الداخلية ريتريفير ، ولا يتم إنهاء التمرير أبدا. التطبيق الذي يتم تمريره لا يحتاج إلى استرداد الرسائل بشكل واضح لتتسبب هذه المشكلة. يمكن ان يتسبب الاتصال بأي من الدالات التالية أو معالجه اي رسالة تحتوي علي حلقه استرداد الرسالة ، اثناء التمرير ، بإمكان الWM_LBUTTONUP فقدانها. تقع الدالات المدرجة أدناه في هذه الفئة:

DialogBox() DialogBoxIndirect() DialogBoxIndirectParam() DialogBoxParam() GetMessage() MessageBox() PeekMessage()

الحل

اثناء التمرير ، يجب الا يتم استرداد الرسالة الWM_LBUTTONUPه من قائمه الانتظار بواسطة اي حلقه استرداد للرسائل غير الفترة الداخلية لشريط التمرير. قد ياتي التطبيق عبر هذه المشكلة كما يلي:

  • يطبق أحد التطبيقات التكرار الحلقي لاسترداد الرسائل لتنفيذ معالجه الخلفية ، علي سبيل المثال ، معالجه الخلفية اثناء تنفيذ الطلاء لوقت معين.

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

الحلول البديلة الممكنة

هناك نوعان من الحلول البديلة المذكورة أدناه. يتم استخدام الحل البديل الأول من قبل العديد من التطبيقات التي يتم إنهاؤها و Windows ؛ ومع ذلك ، ضمن ظروف نادره ، قد لا يكون الحل البديل الأول واحدا مجديا. في هذه الحالة ، قد يتم استخدام الحل البديل الثاني. ومع ذلك ، يرجى محاولة تجنب تطبيق استرداد الرسالة تماما اثناء التمرير.

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

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

مثال يوضح الحل البديل 1

تطبيق لديه اجراء طلاء معقد. الاتصال بالسكرولويندوو () ، للتمرير ، وإنشاء رسائل الرسام. تحدث المعالجة الخلفية اثناء الرسم.

  1. عند تلقي رسالة الWM_PAINT ، قم بما يلي:

    1. اتصل بالبيجينبينت ().

    2. انسخ ريكت التي تم ابطالها إلى متغير ريكت عمومي (علي سبيل المثال ، جركباينت) لاستخدامها في الخطوة 2. سيكون جركباينت ريكت العمومية اتحادا لريكت (جركباينت) الذي تم الحصول عليه مسبقا والذي تم ابطاله (ps). ستشبه التعليمه البرمجية التالية ما يلي:

               RECT grcPaint;    // Should be initialized before getting the                           // first paint message.            :            :         UnionRect(&grcPaint, &ps.rcPaint,&grcPaint);
    3. اتصل بالفاليداتيريكت () مع ركباينت.

    4. اتصل بالاندبينت ().

    5. تعيين المؤقت.

    بهذه الطريقة ، لم يتم إنشاء المزيد من رسائل الWM_PAINT ، لأنه لا توجد مناطق غير صالحه ، وتم اعداد جهاز ضبط الوقت ، مما يؤدي إلى إنشاء رسائل WM_TIMER.

  2. عند تلقي رسالة WM_TIMER ، حدد متغير ريكت العمومي ؛ إذا لم يكن فارغا ، فخذ مقطعا وقم بطلاءه. ثم قم بضبط متغير ريكت العمومي بحيث لا يشمل المنطقة المطلية.

  3. بمجرد ان يكون متغير ريكت العام فارغا ، قم بإنهاء المؤقت.

مثال يوضح الحل البديل 2

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

  1. التحقق واسترداد الرسائل المرتبطة فقط للحصول علي البيانات المطلوبة.

  2. البحث عن WM_LBUTTONUP من دون ازالته من قائمه الانتظار ؛ إذا كانت موجودة في قائمه الانتظار ، فقم بفصلها. والا ، فقم باسترداد كل الرسائل وإرسالها.

  3. استرداد كل الرسائل التي يقل عمرها عن WM_LBUTTONUP وأكبر من WM_LBUTTONUP ، ولكن لا تقم باسترداد WM_LBUTTONUP.

مزيد من المعلومات

خطوات لأعاده إنتاج المشكلة

فيما يلي تسلسل الاحداث الرائدة في فقدان الرسالة الWM_LBUTTONUPه:

  1. انقر فوق شريط التمرير باستخدام الماوس.

  2. الخطوة 1 تنشئ رسالة WM_NCLBUTTONDOWN.

  3. تؤدي الخطوة 2 إلى بدء حلقه رسالة Windows الداخلية. يبحث هذا التكرار الحلقي للرسالة عن الرسائل ذات الصلة بشريط التمرير. هذا التكرار الحلقي للرسالة هو إنشاء رسائل WM_HSCROLLه أو WM_VSCROLL مناسبه. تنتهي حلقه الرسالة ويتم التمرير مره واحده عند تلقي WM_LBUTTONUP.

  4. عند تلقي الWM_HSCROLL أو رسالة الWM_VSCROLL ، سيحصل التطبيق اما علي حلقه استرداد الرسالة مباشره أو يقوم باستدعاء الدالات التي تنتج عن استرداد الرسائل.

  5. تتم أزاله WM_LBUTTONUP من قائمه الانتظار بواسطة حلقه الرسالة المذكورة في الخطوة 4. يتم إرسال WM_LBUTTONUP بعد ذلك.

  6. بما انه يتم إرسال رسالة الWM_LBUTTONUP الخطوة 5 في مكان آخر وكانت حلقه استرداد الرسائل الداخلية المذكورة في الخطوة 3 لا يتلقيها. تبحث حلقه الرسالة في الخطوة 3 عن الWM_LBUTTONUP لإيقاف التمرير. لأنه لم يتم تلقيه ، سيتابع شريط التمرير التمرير.

هل تحتاج إلى مزيد من المساعدة؟

توسيع المهارات

استكشاف التدريب >

الحصول على الميزات الجديدة أولاً

الانضمام إلى MICROSOFT INSIDERS >

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

ما مدى رضاك عن جودة اللغة؟
ما الذي أثّر في تجربتك؟

نشكرك على ملاحظاتك!

×