سؤال

تشغيل على XP. لدي عميل يتصل بالمكالمات CoInitializeEx(NULL, COINIT_MULTITHREADED), ، يحمل كائن DCOM (محلي) ، ويعلق واجهة حدث بحيث يمكن لكائن DCOM إرسال الأحداث. يشبه العميل كثيرًا مثل المفكرة مع مربع نص متعدد الخطوط يغطي منطقة العميل لعرض رسائل الأحداث. فيما يلي المكالمات التي تنشئ قفلًا:

  • مكالمات العميل p->DoStuff() على كائن DCOM.
  • مكالمات كائن DCOM c->DoStuffEvent() على العميل أثناء المعالجة DoStuff().
  • يرسل العميل ملف EM_REPLACESEL رسالة إلى مربع نص الطفل لعرضها "الأشياء تحدث"

يتجمد العميل على SendMessage(EM_REPLACESEL). دعوة العميل إلى p->DoStuff() يتم على الخيط الرئيسي بينما SendMessage(EM_REPLACESEL) يتم على موضوع مختلف. أنا متأكد من أن هذا له علاقة بالمشكلة.

هل يمكن لأحد أن يشرح سبب القفل وكيف يمكنني العمل من حوله؟ يتم ترميز كائنات العميل و DCOM من قبلي في MSVC/ATL ، حتى أتمكن من تعديلهما حسب الحاجة.

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

المحلول

يبدو أن النافذة تم إنشاؤها بواسطة الخيط الرئيسي. هذا هو الموضوع الوحيد الذي يمكنه استدعاء نافذة بروك. عندما انت SendMessage من الخيط الآخر ، ما يفعله بالفعل لوضع الرسالة في قائمة انتظار مؤشر الترابط الرئيسي ثم انتظر حتى يتصل الموضوع الرئيسي GetMessage أو PeekMessage. داخل المكالمة إلى GetMessage أو PeekMessage, ، يلاحظ Windows التقاطع المتقاطع SendMessage ويمرر تلك الرسالة إلى نافذة بروك ، ثم يستيقظ الخيط الثاني ويتيح لها المتابعة.

إذا كنت لا تهتم بقيمة إرجاع SendMessage(EM_REPLACESEL), ، يمكنك استخدام SendNotifyMessage في حين أن. ولكن إذا قمت بذلك ، فأنت بحاجة إلى التأكد من أن السلسلة التي تمر بها EM_REPLACESEL لا تزال الرسالة صالحة عند تسليم الرسالة أخيرًا.

نصائح أخرى

وفقا ل SendMessage الوثائق ، لا يعود SendMessage حتى يتم الانتهاء من الوظيفة. إنه متزامن. أعتقد أنه يتم الرد دائمًا على موضوع واجهة المستخدم أيضًا. إذا كنت ترغب في القيام بتمرير رسالة غير متزامن ، فيجب عليك استخدامه postmessage.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top