2012-04-19 17 views
9

"मेरे पास एक डेल्फी 2007 प्रोजेक्ट है जो विंडोस एक्सपी, विस्टा और कई वर्षों से" 7 "पर ठीक चल रहा है, तो सिस्टमवाइड हॉट कुंजी" सिस्टम-वाइड "नहीं है। यह डेल्फी 5 से अपग्रेड था, इस प्रकार "मेनफॉर्मऑन टास्कबार" डिफ़ॉल्ट रूप से "झूठा" था (मैंने कभी इसे डीपीआर में नहीं बदला)। इस परिदृश्य में, सिस्टम-व्यापी हॉट कुंजी ने मुख्य रूप के ऑनक्रेट ईवेंट हैंडलर में निम्न कोड के साथ "सिस्टम-वाइड" काम किया।डेल्फी 2007 - "मेनफॉर्मऑन टास्कबार: = ट्रू"

HotKey_xyz := GlobalAddAtom('Hotkey_xyz'); 
if NOT RegisterHotKey(Self.Handle, HotKey_xyz, MOD_CONTROL, VK_F12) then 
    ShowMessage('Unable to register Control-F12 as system-wide hot key') ; 

(I have GlobalDeleteAtom() and UnregisterHotKey() in Form.OnDestroy as expected.) 

अब, मैं टास्कबार पर अपने स्वयं के बटन को दिखाने के लिए एक प्रपत्र की जरूरत है, तो मैं "Application.MainFormOnTaskBar: = यह सच है" सेट डीपीआर में। यह उम्मीद के रूप में काम करता है। हालांकि, इस पक्ष प्रभाव है कि नियंत्रण-F12 सिस्टम-वाइड काम नहीं करता है, यह केवल तभी कारगर अपने आवेदन ध्यान केंद्रित किया (हां, तो यह नहीं "सिस्टम-वाइड" अब है।)

मैं बड़े पैमाने पर खोज की है नेट को कुछ सबूत मिलते हैं कि क्यों/क्यों "MainFormOnTaskBar" कुछ सबफॉर्म/मोडल फॉर्म व्यवहार को प्रभावित करता है। हालांकि, मुझे उपरोक्त वर्णित "सिस्टम-वाइड हॉट की" समस्या पर इसके प्रभाव के बारे में कुछ भी नहीं मिला है। मैंने मेनफॉर्मऑन टास्कबार के साथ अपने एप्लिकेशन का परीक्षण और पुनः परीक्षण किया है, जबकि सत्य और गलत पर सेट किया गया है जबकि बाकी सब ठीक वही रहता है। मैं सकारात्मक रूप से सत्यापित कर सकता हूं कि उपरोक्त वर्णित समस्या सिस्टम-व्यापी हॉट कुंजी के साथ MainFormOnTaskBar ध्वज से संबंधित है।

मैं काम के आसपास के बारे में किसी भी मार्गदर्शन की सराहना करता हूं। मुझे दोनों की आवश्यकता है - एक सिस्टम-व्यापी गर्म कुंजी और टास्कबार पर अपने बटन के साथ एक फॉर्म।

आपको बहुत बहुत धन्यवाद।

+0

क्या आप इसे * नई * परियोजना के साथ डुप्लिकेट कर सकते हैं? मैं नहीं कर सका .. –

+0

मैं इसे फिर से पेश नहीं कर सकता। क्या आप अधिक कोड पोस्ट कर सकते हैं? (और संभवतः 'Self.Handle' को 'ApplicationHandkey' कॉल में' एप्लिकेशन। हैंडल 'में बदलने का प्रयास करें?' WM_HOTKEY' संदेश अभी भी आपके फॉर्म पर पहुंच जाएगा, क्योंकि एप्लिकेशन का संदेश हैंडलर इसके साथ कुछ नहीं करता है ; इसे सामान्य रूप से आपके फॉर्म पर भेजा जाएगा।) –

+0

@ केनहाइट: यदि 'कुंजी। हैंडल' हॉट कुंजी को पंजीकृत करने के लिए उपयोग किया जाता है, तो' WM_HOTKEY' संदेशों को सीधे या अप्रत्यक्ष रूप से TForm पर निर्देशित नहीं किया जाएगा। उन्हें 'TAplication' के लिए निर्देशित किया जाएगा, इसलिए उन संदेशों को पकड़ने के लिए जिन्हें आपको 'TApplication.OnMessage' ईवेंट और/या' TApplication.HookMainWindow() 'विधि का उपयोग करना है। –

उत्तर

14

TApplication.MainFormOnTaskbar सिस्टम-व्यापी हॉटकी पर बिल्कुल प्रभाव नहीं पड़ता है। मैं सकारात्मक पुष्टि कर सकता हूं। संदेशों को ध्यान में रखते हुए MainFormOnTaskbar पर ध्यान दिए बिना, इस पर ध्यान दिए बिना कि ऐप केंद्रित है या नहीं, आदि। तो जो कुछ भी आप देख रहे हैं वह वह नहीं है जो आपको लगता है।

सबसे अधिक संभावना, फार्म के Handle बस अपनी पीठ के पीछे से निर्मित किया जा रहा है के बाद आप RegisterHotKey() कहा जाता है, ताकि आप HWND कि WM_HOTKEY संदेश प्राप्त होता है खो देते हैं। OnCreate ईवेंट का उपयोग करने के बजाय, आपको फॉर्म के CreateWindowHandle() और DestroyWindowHandle() विधियों को ओवरराइड करना चाहिए ताकि यह सुनिश्चित किया जा सके कि हॉट की हमेशा फॉर्म के वर्तमान HWND के लिए पंजीकृत है, इससे कोई फर्क नहीं पड़ता कि इससे क्या होता है (आपको हमेशा ऐसा करना चाहिए जब भी आप किसी भी प्रकार का डेटा जोड़ते हैं फार्म के Handle), उदाहरण के लिए:

type 
    TForm1 = class(TForm) 
    private 
    HotKey_xyz: WORD; 
    procedure WMHotKey(var Message: TMessage); message WM_HOTKEY; 
    protected 
    procedure CreateWindowHandle(const Params: TCreateParams); override; 
    procedure DestroyWindowHandle; override; 
    end; 

procedure TForm1.CreateWindowHandle(const Params: TCreateParams); 
begin 
    inherited; 
    HotKey_xyz := GlobalAddAtom('Hotkey_xyz'); 
    if HotKey_xyz <> 0 then 
    RegisterHotKey(Self.Handle, HotKey_xyz, MOD_CONTROL, VK_F12); 
end; 

procedure TForm1.DestroyWindowHandle(const Params: TCreateParams); 
begin 
    if HotKey_xyz <> 0 then 
    begin 
    UnregisterHotKey(Self.Handle, HotKey_xyz); 
    GlobalDeleteAtom(HotKey_xyz); 
    HotKey_xyz := 0; 
    end; 
    inherited; 
end; 

procedure TForm1.WMHotKey(var Message: TMessage); 
begin 
    ... 
end; 

एक बेहतर विकल्प है, सिर्फ गर्म महत्वपूर्ण संदेश से निपटने के लिए AllocateHWnd() उपयोग करने के लिए एक अलग समर्पित HWND आवंटित करने के लिए (तो आप OnCreate और OnDestroy घटनाओं फिर से उपयोग कर सकते हैं) है जैसे:

type 
    TForm1 = class(TForm) 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    private 
    HotKey_xyz: WORD; 
    HotKeyWnd: HWND; 
    procedure HotKeyWndProc(var Message: TMessage); 
    end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    HotKeyWnd := AllocateHwnd(HotKeyWndProc); 
    HotKey_xyz := GlobalAddAtom('Hotkey_xyz'); 
    if HotKey_xyz <> 0 then 
    RegisterHotKey(HotKeyWnd, HotKey_xyz, MOD_CONTROL, VK_F12); 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    if HotKey_xyz <> 0 then 
    begin 
    UnregisterHotKey(HotKeyWnd, HotKey_xyz); 
    GlobalDeleteAtom(HotKey_xyz); 
    HotKey_xyz := 0; 
    end; 
    if HotKeyWnd <> 0 then 
    begin 
    DeallocateHWnd(HotKeyWnd); 
    HotKeyWnd := 0; 
    end; 
end; 

procedure TForm1.HotKeyWndProc(var Message: TMessage); 
begin 
    if Message.Msg = WM_HOTKEY then 
    begin 
    ... 
    end else 
    Message.Result := DefWindowProc(HotKeyWnd, Message.Msg, Message.WParam, Message.LParam); 
end; 
+1

+1 'AllocHWnd' कोड उदाहरण के लिए अकेले)। अच्छा - मैंने इसे पहले कभी ऐसा नहीं देखा है। मैं इसे भविष्य के संदर्भ के लिए चिह्नित कर दूंगा। –

+0

@ रेमी: इसके लिए बहुत बहुत धन्यवाद: CreateWindowHandle() और DestroyWindowHandle() विधियों - जो चाल है। तो, आप पर्याप्त धन्यवाद नहीं कर सकते हैं। मैं "AllocateWnd()" का पता लगाऊंगा - मुझे उस पर और शिक्षा की आवश्यकता है! मैं यूपी को अपना जवाब देना चाहता था लेकिन स्टैक ओवरफ्लो का कहना है कि ऐसा करने के लिए मेरे पास पर्याप्त "प्रतिष्ठा" नहीं है। – JayM

+0

@ सभी: उन सभी लोगों के लिए धन्यवाद जिन्होंने टिप्पणी की और मेरी विवाद का परीक्षण करने में समय लगाया कि मेनफॉर्मऑन टास्कबार ध्वज अपराधी था - मैं शिक्षित हूं कि यह नहीं है। दोबारा, मैं इस समुदाय के समर्थन और मदद करने की इच्छा की बहुत सराहना करता हूं। – JayM