विंडोज इंटर्नल्स के व्यापक हेरफेर के बिना यह संभव नहीं है और आपको इसे खत्म करने की आवश्यकता है।
दैनिक कंप्यूटर उपयोग में कुछ क्षण आते हैं जब यह वास्तव में महत्वपूर्ण होता है कि आप ऑपरेटिंग सिस्टम को एक और करने से पहले एक कार्रवाई करें। ऐसा करने के लिए, इसे कुछ खिड़कियों पर अपना ध्यान केंद्रित करने की आवश्यकता है। विंडोज में, इस व्यवहार पर नियंत्रण काफी हद तक आपके द्वारा उपयोग किए जाने वाले व्यक्तिगत कार्यक्रमों के डेवलपर्स के लिए छोड़ दिया जाता है।
प्रत्येक डेवलपर इस विषय पर आने पर सही निर्णय नहीं लेता है।
मुझे पता है कि यह बहुत निराशाजनक और कष्टप्रद है, लेकिन आप अपना केक नहीं खा सकते हैं और इसे भी खा सकते हैं। आपके दैनिक जीवन में संभवत: ऐसे कई मामले हैं, जहाँ आप ध्यान केंद्रित करने के साथ पूरी तरह से ठीक हैं, एक निश्चित यूआई तत्व या एक आवेदन के लिए स्थानांतरित किया जा रहा है जो यह अनुरोध करता है कि फोकस उस पर लॉक रहे। लेकिन ज्यादातर एप्लिकेशन कुछ हद तक बराबर होते हैं जब यह तय करने की बात आती है कि अभी लीड कौन है और सिस्टम कभी परफेक्ट नहीं हो सकता।
कुछ समय पहले मैंने इस मुद्दे को एक बार और सभी (और असफल) को हल करने पर गहन शोध किया था। मेरे शोध का परिणाम झुंझलाहट परियोजना पृष्ठ पर पाया जा सकता है ।
प्रोजेक्ट में एक एप्लिकेशन भी शामिल है जो बार-बार कॉल करके ध्यान खींचने की कोशिश करता है:
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;
जैसा कि हम इस स्निपेट से देख सकते हैं, मेरा शोध भी उपयोगकर्ता इंटरफ़ेस व्यवहार के अन्य पहलुओं पर केंद्रित था जो मुझे पसंद नहीं है।
जिस तरह से मैंने इसे हल करने की कोशिश की वह हर नई प्रक्रिया में एक डीएलएल को लोड करने और एपीआई कॉल को हुक करने के लिए है जिससे एक और खिड़कियां सक्रिय हो जाती हैं।
अंतिम भाग एक आसान है, भयानक एपीआई हुकिंग पुस्तकालयों के लिए धन्यवाद। मैं बहुत महान mhook पुस्तकालय का इस्तेमाल किया :
#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 कोड पर कार्यान्वयन में शामिल नहीं किया था। एक सहकर्मी ने वास्तव में कुछ अतिरिक्त शोध किया और उस पद्धति को कवर किया। समस्या पर SO पर चर्चा की गई: https://stackoverflow.com/questions/7430864/windows-7-prevent-application-from-losing-focus