سؤال منع التطبيقات من سرقة التركيز


هل هناك أي حلول لمنع سرقة التطبيقات من النافذة النشطة؟

هذا أمر مزعج بشكل خاص عندما أقوم ببدء تطبيق ، قم بالتبديل للقيام بشيء آخر ويبدأ التطبيق الجديد في تلقي نصف نص من النص.


178
2017-08-05 08:48


الأصل


@ Ivo Windows 7 في حالتي ، ولكن أعتقد أن كل إصدارات WindowsUs ستكون ذات صلة - svandragt
قام الوسيط بدمج هذا السؤال: superuser.com/questions/199821/... مع التيار الحالي. هذا خطأ ، لا تنطبق الإجابة على السؤال الحالي على windows 7 ، لذلك لا ينبغي دمجها. حتى الآن لم أجد حلًا لهذه المشكلة في Windows 7 - Alex Angelico
هذا هو واحد من بلدي عدد واحد أزيز الحيوانات الأليفة مع كل واجهة المستخدم الرسومية التي سبق لي استخدامها. أنت تكتب و blam ، بعض مربع bleeping يسرق التركيز ونحو نصف ضغطات المفاتيح الخاصة بك تذهب إلى مكان آخر. كنت أعتقد أن منفذي أنظمة النوافذ قد برزت خارج هذا واحد من عقود مضت. إذا كان هناك نشاط في نافذة ، فقم بتأخير تعرض النافذة الجديدة. مثلا لا تكتب أي شيء على واجهة المستخدم الرسومية حتى ثلاث أو أربع ثوانٍ منذ الضغط على الزر الأخير أو ضغط المفاتيح في الإطار المركّز حاليًا. دوه! - Kaz
This is especially annoying when I'm starting an application, switch to do something else and the new application starts receiving half a sentence of text.إنه أمر مزعج أكثر عندما يظهر مربع حوار ينبثق عنك دون قصد ، حتى دون رؤية الرسالة لأنك حدث للضغط Space أو Enter أثناء كتابة الجملة. - Synetech
هذا في الواقع أكثر من مزعج ، أود أن أقول إنه خطر أمني. لا يوجد شيء لإيقاف تطبيق ما عندما تظهر في وسط كتابة كلمة مرور والاستيلاء على المدخلات الخاصة بك. - Chris Peacock


الأجوبة:


هذا غير ممكن بدون واسع التلاعب في Windows الداخلي وتحتاج إلى الحصول عليها.

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

ليس كل مطور يتخذ القرارات الصائبة عندما يتعلق الأمر بهذا الموضوع.

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

منذ فترة وجيزة أجريت بحثًا مستفيضًا حول حل هذه المشكلة مرة واحدة وإلى الأبد (وفشلت). يمكن العثور على نتيجة بحثي على صفحة مشروع إزعاج.

يتضمن المشروع أيضًا تطبيقًا يحاول بشكل متكرر جذب التركيز عن طريق الاتصال بـ:

switch( message ) {
  case WM_TIMER:
    if( hWnd != NULL ) {
      // Start off easy
      // SetForegroundWindow will not move the window to the foreground,
      // but it will invoke FlashWindow internally and, thus, show the
      // taskbar.
      SetForegroundWindow( hWnd );

      // Our application is awesome! It must have your focus!
      SetActiveWindow( hWnd );

      // Flash that button!
      FlashWindow( hWnd, TRUE );
    }
    break;

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

الطريقة التي حاولت حلها هي تحميل DLL في كل عملية جديدة وربط مكالمات API التي تتسبب في تنشيط نوافذ أخرى.
الجزء الأخير هو الجزء السهل ، بفضل مكتبات واجهة برمجة التطبيقات الرائعة الموجودة هناك. اعتدت على عظيم جدا مكتبة موهوك:

#include "stdafx.h"
#include "mhook-2.2/mhook-lib/mhook.h"

typedef NTSTATUS( WINAPI* PNT_QUERY_SYSTEM_INFORMATION ) ( 
  __in       SYSTEM_INFORMATION_CLASS SystemInformationClass,     
  __inout    PVOID SystemInformation, 
  __in       ULONG SystemInformationLength, 
  __out_opt  PULONG ReturnLength    
);

// Originals
PNT_QUERY_SYSTEM_INFORMATION OriginalFlashWindow   = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "FlashWindow" );

PNT_QUERY_SYSTEM_INFORMATION OriginalFlashWindowEx = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "FlashWindowEx" );

PNT_QUERY_SYSTEM_INFORMATION OriginalSetForegroundWindow = 
  (PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress( 
  ::GetModuleHandle( L"user32" ), "SetForegroundWindow" );

// Hooks
BOOL WINAPI
HookedFlashWindow(
  __in  HWND hWnd,
  __in  BOOL bInvert
  ) {
  return 0;
}

BOOL WINAPI 
HookedFlashWindowEx(
  __in  PFLASHWINFO pfwi
  ) {
  return 0;
}

BOOL WINAPI 
HookedSetForegroundWindow(
  __in  HWND hWnd
  ) {
  // Pretend window was brought to foreground
  return 1;
}


BOOL APIENTRY 
DllMain( 
  HMODULE hModule,
  DWORD   ul_reason_for_call,
  LPVOID  lpReserved
  ) {
  switch( ul_reason_for_call ) {
    case DLL_PROCESS_ATTACH:
      Mhook_SetHook( (PVOID*)&OriginalFlashWindow,         HookedFlashWindow );
      Mhook_SetHook( (PVOID*)&OriginalFlashWindowEx,       HookedFlashWindowEx );
      Mhook_SetHook( (PVOID*)&OriginalSetForegroundWindow, HookedSetForegroundWindow );
      break;

    case DLL_PROCESS_DETACH:
      Mhook_Unhook( (PVOID*)&OriginalFlashWindow );
      Mhook_Unhook( (PVOID*)&OriginalFlashWindowEx );
      Mhook_Unhook( (PVOID*)&OriginalSetForegroundWindow );
      break;
  }
  return TRUE;
}

من الاختبارات التي أجريتها في ذلك الوقت ، كان هذا عملاً رائعًا. باستثناء جزء من تحميل DLL في كل عملية جديدة. كما يمكن للمرء أن يتخيل ، وهذا شيء لا يمكن الاستخفاف به. اعتدت AppInit_DLLs النهج في ذلك الوقت (وهو ببساطة غير كافية).

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

بالإضافة إلى مشكلة حقن DLL ، هناك أيضًا طريقة لسرقة التركيز لم أتناولها في تطبيق Google Code. قام أحد زملاء العمل ببعض الأبحاث الإضافية وقام بتغطية هذه الطريقة. تم مناقشة المشكلة على SO: https://stackoverflow.com/questions/7430864/windows-7-prevent-application-from-losing-focus


45
2018-03-24 09:56



هل تعتقد أن هذا الحل الخاص بك يمكن نقله إلى جافا؟ لقد كنت أبحث وأسأل أسئلة ولكنني لم أجد شيئًا. ربما يمكنني استيراد مكتبة هوك نفسها في جافا باستخدام jne؟ - Tomáš Zato
@ TomášZato: لا توجد فكرة. أنا لا استخدم هذا الرمز بنشاط. - Der Hochstapler
أحاول ترجمة أنها C ++ على الأقل (ثم حقن / إزالة DLL المترجمة من Java). لكن هذا لا ينجح أيضًا. لا أريد مناقشته هنا في التعليقات ، ولكن إذا كان بإمكانك مساعدتي بالفعل في الحصول على عمل ، سأكون رشيقا جدا! لقد أنشأت غرفة دردشة ، إذا حصلت على ذلك للعمل ، فسنقوم بنشر تعليق حول كيفية القيام بذلك هنا: chat.stackexchange.com/rooms/21637/... - Tomáš Zato


في ويندوز 7 ، و ForegroundLockTimeout لم يعد التحقق من إدخال التسجيل ، يمكنك التحقق من ذلك باستخدام "مراقبة العمليات". في الواقع ، في نظام التشغيل Windows 7 يمنعك من تغيير إطار المقدمة. اذهب واقرأ حول تفاصيلها، فقد كان هناك منذ ويندوز 2000.

ومع ذلك، تمتص الوثائق ويطاردون بعضهم البعض ويجدون طرقاً حول ذلك.

لذلك ، هناك شيء عربات التي تجرها الدواب مستمرة SetForegroundWindow، أو وظائف API مماثلة ...

الطريقة الوحيدة للقيام بهذا بشكل صحيح هو جعل تطبيق صغير الذي يدعو بشكل دوري LockSetForegroundWindow، مما يؤدي إلى تعطيل أي مكالمات إلى وظيفة واجهة برمجة التطبيقات (buggy).

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


23
2018-03-22 09:52



هل لدى أي شخص حالة استخدام قابلة للتكرار في Windows 7؟ بالنظر إلى أن الناس بدلاً من ذلك يختبرون العكس (على سبيل المثال ، غالبًا ما أجد أن Windows متطلبًا مخفيًا خلف نافذتي الحالية) وأنني لم أتمكن بعد من رؤية ذلك يحدث في Windows 7 ، فسيكون الأمر مزعجًا جدًا لكتابة تطبيق ولكنك غير قادر على قم بتجريبه. علاوة على ذلك ، وكما تقول مايكروسوفت ، لم يعد يجب أن يحدث هذا مع Windows 7. في أحسن الأحوال ، اكتشف الناس أنه يمكن فقط تبديل تركيز لوحة المفاتيح عن طريق الصدفة ، فإن مكالمة API هذه ستصلح ذلك ، لكنني لا أعرف كيفية اختبار ما إذا كان يعمل بالفعل. . - Tom Wijsman
يقوم المثبت (على أساس InnoSetup) بتشغيل عمليات أخرى وإمكانات أخرى (مخفية) أخرى ، لكني لا أعرف ما يعتمد عليه منشئ الإعداد. - Daniel Beck♦
TomWijsman: افتح regedit ، ابحث عن بعض النصوص العشوائية التي لن يتم العثور عليها. انتقل إلى تطبيق آخر وابدأ في الكتابة. عند الانتهاء من البحث ، سوف يقوم regedit بسرقة التركيز. - endolith
endolith: لا يمكن استنساخه ، باستخدام Windows 8 Replase Preview هنا على الرغم من ذلك. ما هو نظام التشغيل الذي تستخدمه؟ في حالتي يسلط الضوء فقط على التطبيق في القاع ولكن لا يقاطع تصفح بلدي على الإطلاق ... - Tom Wijsman
نعم ، Win7 برو 64 بت. والتركيز على السرقة أكثر سوءًا بالنسبة للعمليات المرتفعة ، نظرًا لأنها تلتقط الضغط <Enter> في الوقت الذي لا يجب فيه ذلك ، وأنت تخبره بخرطوم النظام الخاص بك عن طريق الخطأ. لا شيء يجب أبدا تكون قادرة على سرقة التركيز. - endolith


هناك خيار في TweakUI من الذي يفعل هذا. ويمنع معظم الحيل المعتادة التي يستخدمها مُطورو البرامج المشكوك فيهم في فرض التركيز على تطبيقاتهم.

إنها حرب أسلحة مستمرة ، لذا لا أعرف ما إذا كانت تعمل في كل شيء.

تحديث: بالنسبة الى EndangeredMassa، TweakUI لا يعمل على ويندوز 7.


18
2017-08-05 09:12



هو tweakui متوافق مع ويندوز 7؟ - frankster
frankster. لا توجد فكرة ، آسف ، أظن أنها ليست كذلك. تحميل البرنامج وتجربته. أبلغني إذا كنت تعرف ذلك. - Simon P Stevens
حتى باستخدام إعدادات التسجيل التي لا تعمل مجموعات TweakUI على Win7. - EndangeredMassa
EndangeredMassa أي مفتاح التسجيل هو ذلك؟ - n611x007
مفتاح التسجيل هو HKEY_CURRENT_USER \ Control Panel \ Desktop \ ForegroundLockTimeout (بالمللي ثانية). ونعم ، لا يعمل في نظام التشغيل Windows 7 بعد الآن. - foo


أعتقد أن بعض الارتباك قد يكون موجودًا ، حيث توجد طريقتان "سرقة التركيز": (1) نافذة قادمة إلى المقدمة ، و (2) نافذة تتلقى ضربات المفاتيح.

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

يجب أن تنقسم المناقشة هنا بين XP و 7.

ويندوز إكس بي

في XP هناك اختراق التسجيل يجعل XP يعمل بنفس Windows 7 في منع التطبيقات من سرقة التركيز:

  1. استخدم regedit للانتقال إلى: HKEY_CURRENT_USER\Control Panel\Desktop.
  2. انقر نقرا مزدوجا فوق ForegroundLockTimeout وتعيين قيمتها بالنظام الست عشري لـ 30d40.
  3. اضغط OK (موافق) واخرج regedit.
  4. أعد تشغيل الكمبيوتر حتى تسري التغييرات.

ويندوز 7

(تنطبق المناقشة أدناه في الغالب على XP أيضًا.)

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

في ويندوز 7 لا يوجد سوى تعديل واحد ممكن لسلوك ويندوز نفسه ، وهو لاستخدام ال MS-Windows يختلط بسرقة الفأرة، حيث ينتقل التركيز و / أو التنشيط دائمًا إلى النوافذ أسفل المؤشر. يمكن إضافة تأخير لتجنب ظهور التطبيقات على سطح المكتب.
انظر هذا المقال: ويندوز 7 - ماوس تحوم يجعل نافذة نشطة - تمكين.

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

يمكنك استخدام البرنامج النصي VBS متضمن في رمز VB الذي يحدد من الذي يسرق التركيزالذي استخدمه المؤلف لتحديده الجاني كمحدّث "الاتصال بالمنزل" لبرنامج طابعة.

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

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

[تصحيح]

كما تقاعدت مايكروسوفت معرض الأرشيف ، هنا هو رمز VB أعلاه مستنسخة:

Declare Auto Function GetForegroundWindow Lib "user32.dll" () As Integer
Declare Auto Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Integer, ByRef procid As Integer) As UInteger

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.RichTextBox1.AppendText("Starting up at " & Now & vbCrLf)
    End Sub

    Private Sub GoingAway(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate, Me.LostFocus

        Dim hwnd As Integer = GetForegroundWindow()
        ' Note that process_id will be used as a ByRef argument
        ' and will be changed by GetWindowThreadProcessId
        Dim process_id As Integer = 1
        GetWindowThreadProcessId(hwnd, process_id)

        If (process_id <> 1) Then
            Dim appExePath As String = Process.GetProcessById(process_id).MainModule.FileName() 
            Me.RichTextBox1.AppendText("Lost focus at " & Now & " due to " & appExePath & vbCrLf)
        Else
            Me.RichTextBox1.AppendText("Lost focus due to unknown cause.")
        End If

    End Sub

14
2018-06-09 09:22



"إذا تم حظر هذه النافذة ، فلن تفهم أبدًا سبب عدم إنهاء هذه النسخة مطلقًا" هذا ليس صحيحًا. السلوك الصحيح هو إخطار المستخدم برمز شريط المهام الوامض (أو ربما منبثق منبثق أو تنبيه محمص أو شيء ما). يقصد بمقاطعة المستخدم باستخدام نافذة تعترض ضغطات المفاتيح الخاصة به أن يُخبر برنامج مكافحة الفيروسات باتخاذ إجراء واحد أو آخر بشكل عشوائي. بالتأكيد ليست طريقة جيدة لفعل الأشياء. - endolith
"إذا تم حظر هذه النافذة ، فلن تفهم أبدًا سبب عدم إنهاء هذه النسخة مطلقًا" هذا ليس صحيحًا. السلوك الصحيح هو إعلام المستخدم برمز شريط المهام الوامض ...   كانت هناك أوقات نقرت فيها على زر أو شيء ما في برنامج جارٍ يؤدي إلى إنشاء مربع حوار مشروط جديد (على سبيل المثال ، فتح الملف) ، ولكن بعد ذلك أقوم بالتبديل إلى برنامج آخر قبل إنشاء الحوار. وكنتيجة لذلك ، يكون مربع الحوار مخفيًا ولا يمكن تبديل البرنامج الآخر ولا يمكن استبعاد مربع الحوار. لا زر شريط المهام ولا Alt-Tab يعمل. فقط إجبار الحوار على الجبهة. - Synetech
Synetech: في بعض الأحيان يكون الحل الوحيد لحوار غير الجبهة هو قتل المهمة. خوارزميات التركيز في ويندوز هي رديئة حقا. - harrymc
harrymc ، لم أضطر إلى اللجوء إلى قتل أحد التطبيقات. أنا فقط أدير برنامج التلاعب بالنوافذ (WinSpy ++ هل الخدعة رائعة فقط) وإخفاء النافذة أمامك ، ثم يمكنني استبعاد مربع الحوار المعلق ، ثم إعادة إظهار النافذة المخفية. هذا غير مناسب ، لكنه أفضل من قتل أي من العمليات. - Synetech
harrymc ، ليس في الحقيقة ؛ قتل التطبيق وفقدان الأشياء فقط يجعل المزيد من البخار ، وإذا كان هو حوار مشروط (الذي قفل النافذة الأصل وليس لديه زر شريط المهام) ، فإنه لن تظهر في Alt+Tab قائمة ، و ، في تجربتي ، نافذة لديها فتح مربع حوار مشروط لا دائما (أبدا؟) إظهار الحوار مشروط مع Alt+Tab، خاصة إذا لم يكن للحوار أي تغيير للحصول على التركيز. :-| - Synetech


غاكس لديه حل ممكن:

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

ال المراجع المحترف موقع لديه معلومات عن   كيفية منع هذا من الحدوث.   أسهل طريقة لمنع التركيز   سرقة هي استخدام واجهة المستخدم Tweak التي لديها   إعداد يسمى "منع"   تطبيقات من سرقة التركيز ".   التحقق من هذا الخيار يمنع ذلك   التطبيقات الأخرى المنبثقة فجأة و   سرقة بؤرة النافذة أنت   يعمل حاليا في.

هذا يعمل فقط عند التطبيق   قد تم التقليل من قبل. بدلا من   سرقة التركيز سوف فلاش   عدد المرات التي يمكن تعريفها   في نفس القائمة في قرص واجهة المستخدم. اذا أنت   لا تريد استخدام Tweak UI يمكنك   تغيير الإعداد في ويندوز   التسجيل.

انتقل إلى مفتاح التسجيل   HKEY_CURRENT_USER> لوحة التحكم>   سطح المكتب وتغيير   قيمة ForegroundLockTimeout إلى 30d40   (سداسي عشري) أو 200000 (عشري). ال   مفتاح ForeGroundFlashCount يحدد   مقدار ومضات نافذة للتنبيه   المستخدم حيث 0 يعني غير محدود.


2
2017-08-05 09:13



هذا لا يعمل على أي نظام تشغيل بعد XP. تم تعيين قيمة السجل هذه بالفعل (بشكل افتراضي ، على ما أعتقد) ولا تعمل على أي حال. - EndangeredMassa
فقط لإثبات أني في Windows 7 (64 بت) ، والتي تعاني من سرقة التركيز (VS 2012 عندما يكون نشطًا في النهاية ، مثال f'r) ، وكان اقتراح التسجيل أعلاه موجودًا بالفعل في المكان. التأكيد الفني في هذه الإجابة: superuser.com/a/403554/972 - Michael Paulukonis