سؤال

من واجهة برمجة تطبيقات Win32 الأصلية باستخدام C ++ هل هناك طريقة لتحديد ما إذا كانت النافذة المرتبطة بـ HWND لا تزال صالحة؟

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

المحلول

يمكنك استخدام API Win32 Iswindow.

لا ينصح به لاستخدامه على الرغم من سببين:

  1. يمكن إعادة استخدام مقابض Windows بمجرد تدمير النافذة ، لذلك لا تعرف ما إذا كان لديك مقبض لنافذة مختلفة تمامًا أم لا.
  2. يمكن أن تتغير الدولة مباشرة بعد هذه المكالمة وستظن أنها صالحة ، لكنها قد لا تكون صالحة حقًا.

من MSDN (نفس الرابط على النحو الوارد أعلاه):

يجب ألا يستخدم الخيط Iswindow لنافذة لم تنشئها لأنه يمكن تدمير النافذة بعد استدعاء هذه الوظيفة. علاوة على ذلك ، نظرًا لإعادة تدوير مقابض النوافذ ، يمكن أن يشير المقبض إلى نافذة مختلفة.

ماذا يمكن ان يفعل؟

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

يمكنك أيضًا إنشاء خطاف Windows للكشف عند حدوث رسائل معينة ، ولكن هذا ربما يكون مبالغة لمعظم الاحتياجات.

نصائح أخرى

هذا السؤال قديم ، لكنني كنت بحاجة إلى هذه الوظيفة بنفسي وكانت بخيبة أمل بعض الشيء بعد القراءة عن التحذيرات. ومع ذلك ، بعد القيام بمزيد من الحفر ، يبدو أن كل شيء على ما يرام. ما لم تكن تتعامل مع برنامج 16bit ، يبدو أن Iswindow هو الطريق للذهاب. يبدو أن مشكلة إعادة استخدام المعالجة قد تم معالجتها بشكل كافٍ وفقًا لهذا:

http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx

لذلك ، بسبب عداد إعادة استخدام 16bit العليا ، من غير المرجح أن تواجه مشكلة إعادة استخدام النافذة.

يمكنك استخدام iswindow () أو حاول أيضًا إرسال رسالة WM_NULL SendMessage(HWND ، WM_NULL) ومعرفة ما إذا كان ناجحًا.

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

الحل الوحيد الذي أعرفه لإنشاء نظام واسع خُطَّاف هذا يبحث عن الرسائل التي تشير إلى نافذة تم تدميرها (WM_Close ، WM_Destroy). بعد ذلك ، يمكنك مقارنة مقبض نافذة الرسائل مع تلك التي تحتفظ بها لمعرفة ما إذا كان أي من النوافذ التي تهتم بها تتأثر. انظر هنا لمزيد من المعلومات حول السنانير واسعة النظام.

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

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

استخدم RegisterWindowMessage لتسجيل الرسالة ، باستخدام اسم فريد بما فيه الكفاية.

ربما مزيج من IsWindow, FindWindow و GetWindowThreadProcessId سيكون أكثر دقة

HWND windowHandle = FindWindow(NULL, TEXT("window_title"));
LPDWORD oldpid = 0;
GetWindowThreadProcessId(windowHandle, &oldpid);
//after some time
if (IsWindow(windowHandle))
{
    LPDWORD newpid = 0;
    GetWindowThreadProcessId(windowHandle, &newpid);
    if (newpid == oldpid)
    {
        //the window is still running
    }else
    {
        //the window exists but has changed
    }
}
if(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
     // do stuff
 }

سوف تحقق مما إذا كانت النافذة موجودة ولها الاسم المناسب

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