مشاركة ‏‫التكرارات الحلقية للرسائل بين Win32 و WPF

يصف هذا الموضوع كيفية تطبيق تكرار حلقي للرسالة من أجل التشغيل التفاعلي مع Windows Presentation Foundation (WPF)، إما باستخدام كشف تكرار حلقى للرسالة موجود في Dispatcher أو بإنشاء تكرار حلقي للرسالة منفصل على جانب Win32 من تعليمات برمجية التشغيل التفاعلي الخاص بك.

ComponentDispatcher و التكرار الحلقي للرسالة

سيناريو عادي للتشغيل التفاعلي و دعم حدث لوحة المفاتيح هو تنفيذ IKeyboardInputSink, أو إنشاء فئة فرعية من فئات بالفعل تطبق IKeyboardInputSink, مثل HwndSource أو HwndHost. ومع ذلك، دعم مُستقبِل لوحة المفاتيح لا يخاطب كل احتياجات التكرار الحلقي للرسالة المحتملة التي ممكن تكون لديك عند إرسال الرسائل وتلقيها عبر حدود التشغيل التفاعلي. للمساعدة في إضفاء الطابع الرسمي على بنية التكرار الحلقي للرسالة، Windows Presentation Foundation (WPF) يوفر فئة ComponentDispatcher التي تعرِّف بروتوكول بسيط ليتبعه التكرار الحلقي للرسالة.

ComponentDispatcher هي فئة ثابتة تكشف عدة أعضاء. نطاق كل أسلوب مربوط ضمنيًا بمؤشر ترابط المستدعي. التكرار الحلقي للرسالة يجب أن يستدعي رسالة بعض من واجهات API في الأوقات الهامة (كما هو معرف في المقطع التالي).

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

استدعاء أساليب ComponentDispatcher على مؤشر الترابط سيستدعي فقط معالجات الأحداث التي تم تسجيلها على هذا المؤشر للترابط.

كتابة التكرار الحلقى للرسائل

التالي هي قائمة من أعضاء ComponentDispatcher التي ستستخدمها إذا قمت بكتابة التكرار الحلقة للرسالة الخاص بك:

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

  • PopModal: يجب أن يستدعي التكرار الحلقي للرسالة الخاص بك هذا للإشارة إلى أن مؤشر الترابط اصبح غير مشروط..

  • RaiseIdle: يجب أن لديك تكرار حلقي رسالة يتصل هذا الخيار للإشارة إلى أنComponentDispatcherيجب رفعThreadIdleحدث. ComponentDispatcher will not raise ThreadIdle if IsThreadModal هو true, but message loops may choose إلى call RaiseIdle even if ComponentDispatcher cannot respond إلى it while in modal state.

  • RaiseThreadMessage: يجب أن يستدعي التكرار الحلقي للرسالة الخاص بك هذا للإشارة إلى أن رسالة جديدة متوفرة. قيمة الإرجاع تشير إلى ما إذا مستمع حدث ComponentDispatcher قام بمعالجة الرسالة. في حالة أن يقوم RaiseThreadMessage بإرجاع true (مُعالج) ينبغي على المرسل عدم القيام بأي إجراء مع الرسالة. إذا كانت قيمة الإرجاع false ، المتوقع من المرسل استدعاء Win32 دالة TranslateMessage ، ثم استدعاء DispatchMessage.

استخدام ComponentDispatcher و معالجة الرسائل الموجودة

التالي هو قائمة من أعضاء ComponentDispatcher التي سيتم استخدامها إذا كنت تعتمد على التكرار الحلقى للرسالة WPF الموروث.

  • IsThreadModal: إرجاع ما إذا كان تطبيق قد ذهبت مشروط (على سبيل المثال، تكرار حلقي رسالة المشروطة قد تم دفع). ComponentDispatcherيمكن مقطع صوتي هذه الحالة بما يوفر الفئة عددPushModalوPopModalالمكالمات من تكرار حلقي رسالة.

  • أحداث ThreadFilterMessage و ThreadPreprocessMessage يتبع القواعد القياسية لاستدعاءات المفوض. يتم استدعاء التفويضات بترتيب غير محدد , و يتم استدعاء كل المفوضين حتى إذا كان الأول يُعلِّم أنه تم معالجة الرسالة.

  • ThreadIdle: يشير إلى المناسبة و الوقت الفعال لخامل المعالجة (هناك أية رسائل غير ذلك معلقة لمؤشر الترابط). ThreadIdleلن raهوed إذا كان مؤشر ترابط هو Modal.

  • ThreadFilterMessage: يتم رفعها لكل الرسائل التي تعالجها مضخة الرسالة.

  • ThreadPreprocessMessage: يتم رفعها لكل الرسائل التي لم يتم معالجتها أثناء ThreadFilterMessage.

تعتبر الرسالة مُعالجة بعد حدث ThreadFilterMessage أو حدث ThreadPreprocessMessage، معلمة handled الممررة حسب المرجع في بيانات الحدث هي true. يجب أن تتجاهل معالجات الأحداث الرسالة إذ handled هو true ، لأن ذلك يعني أن معالج مختلف قام بمعالجة الرسالة أولاً. معالجات الأحداث لكلاً من الأحداث يمكن أن تقوم بتعديل الرسالة. يجب إرسال المرسل الرسالة تم و الرسالة الأصلية بدون تغيير لا. ThreadPreprocessMessage هو delivered إلى all listeners, but the architectural intention هو that only the إلىp-level window containing the HWND at which the messages targeted should invoke تعليمات برمجية in response إلى the message.

كيفية معاملة HwndSource لأحداث ComponentDispatcher

إذا كان HwndSource هو إطار المستوى الأعلى (لا يوجد أصل HWND) ، سيتم تسجيله مع ComponentDispatcher. إذا تم رفع ThreadPreprocessMessage و إذا كانت الرسالة مخصصة إلى HwndSource أو الإطارات التابعة, يقوم HwndSource باستدعاء IKeyboardInputSink.TranslateAccelerator الخاص به، TranslateChar ، تسلسل تلقى لوحة المفاتيح OnMnemonic.

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

إذا تم استدعاء WndProc على HwndSource بدون استدعاء أولاً أسلوب تلقى لوحة مفاتيح مناسب, سيتلقى التطبيق الخاص بك أحداث لوحة مفاتيح ذو مستوى أعلى مثل KeyDown. ومع ذلك، لا يتم استدعاء متلقي لوحة المفاتيح الذي circumvents ميزات طراز إدخال لوحة المفاتيح المطلوب مثل دعم مفتاح الوصول. قد يحدث هذا لأن التكرار الحلقى للرسالة لم يقوم بإعلام مؤشر الترابط ذو الصلة بشكل صحيح على ComponentDispatcher, أو لأن الأصل HWND لم يستدعي استجابات متلقي لوحة المفاتيح المناسبة.

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

راجع أيضًا:

المرجع

ComponentDispatcher

IKeyboardInputSink

المبادئ

نظرة عامة حول التشغيل التفاعلي ل Win32 و WPF

نموذج مؤشر الترابط

نظرة عامة حول المدخلات