لماذا لا ينبغي أن تستخدم مقبض أثناء إنشاء المكون أو البث؟

StackOverflow https://stackoverflow.com/questions/582721

سؤال

أريد أن أجعل عنصر تحكم VCL مخصص يلتف سطح تقديم SDL من خلال وظيفة SDL_CREATEWINDOWFROM. يأخذ SDL_CREATEWINDOWFROM مقبض HWND موجود ويضع سياق تقديم عالية الأداء (يحتوي على العديد من التراجع، بما في ذلك DirectX و OpenGL) على ذلك.

يقول HELPFILE "لا تشير إلى خاصية المقبض أثناء إنشاء المكون أو البث". لكنه لا يقول السبب. تقول أن المرة الأولى التي تحاول فيها الوصول إلى خاصية المقبض، فسوف تتصل باليدين باليدين للتأكد من وجود مقبض صالح.

لذلك لدي سؤالان. 1: ما هو السبب وراء عدم الرجوع إلى خاصية المقبض أثناء إنشاء المكون؟ 2. إذا كانت نقطة التحكم بأكملها هي لف سطح التقديم الذي يتطلب تهيئة HWND، متى تكون آمنة لإجراء التهيئة التي يجب أن تحدث (من الناحية المثالية) أثناء الإبداع / البث؟

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

المحلول

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

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

إذا كنت بحاجة إلى الرجوع إلى المقبض بشكل صحيح من داخل STERTER خاصية، يجب عليك التحقق مما إذا تم إنشاء المقبض عن طريق التحقق من HandleAlLocated، وفقط عند الإشارة إليه. إذا كنت بحاجة إلى إجراء بعض التغييرات العلمية في المقبض مثل استدعاء setwindowlong () أو شيء ما، فعليك "ذاكرة التخزين المؤقت" التي تحتاج إلى ذلك في مثيل المكون ثم تجاوز الإنجيل وتطبيق هذه الإعدادات في هذه النقطة. خيار آخر هو إرجاء جميع الوصول إلى الوصول أثناء التدفق (إذا كان Csloading في Componentstate ثم) حتى يتم استدعاء الطريقة الافتراضية المحملة.

أخيرا، يجب أن تكون على دراية بالحالات التي قد يحتاج فيها مؤشرك إلى إعادة إنشاؤها. يمكن أن يحدث هذا إذا كان النموذج المحيطي أو مقبض مكون الأصل يمر بعملية إعادة التخزين. حتى أكثر من الإصدارات الحديثة من Windows، كانت الطريقة الوحيدة لتغيير بعض إشارات النوافذ هي تدمير المقبض وإعادة إنشاء إشارات جديدة في مكالمة CreateWindowEx (). هناك العديد من المكونات التي لا تزال تفعل هذا. أنت تعرف إذا كنت في وضع إعادة تخزين عن طريق التحقق (CSRecreating في ControlState).

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

نصائح أخرى

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

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

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