यह स्पष्ट रूप से डिजाइन द्वारा है। 'Ribbonactnctrls.pas' से नमूना कोड स्निपेट:
procedure TRibbonBaseButtonControl.Click;
begin
inherited;
SetFocus(Application.MainForm.Handle);
end;
जैसा कि आप देख कोई शर्त जाँच की है कि मदद मिलेगी हमें कॉल से बचने कर रहे हैं। मेनू आइटम चयन और कुंजी प्रेस हैंडलर में भी वही कोड है।
मैं शायद फोकस कॉल पर टिप्पणी करने वाले स्रोत को संशोधित करता हूं, और यह देखने का प्रयास करता हूं कि कोई दुष्प्रभाव हैं या नहीं।
एक विकल्प के रूप में आप मुख्य रूप से स्विच करने के बाद फोकस को अपने फॉर्म पर वापस बहाल कर सकते हैं। मान लीजिए 'ActionList1' है TActionList कि नहीं मुख्य फार्म पर मानक कार्यों में शामिल हैं:
type
TForm2 = class(TForm)
..
procedure ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
private
..
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
PostMessage(Handle, WM_SETFOCUS, WPARAM(True), 0);
end;
हालांकि यह मुख्य रूप के कारण कुछ समय के लिए हर बार एक कार्रवाई निष्पादित किया जाता है फ़्लैश जाएगा। यदि आप यह नहीं चाहते हैं, तो आप डिज़ाइन को बदल सकते हैं ताकि मुख्य फ़ॉर्म जानता हो कि उसे अवांछित फोकस मिल रहा है, और नकली है कि यह केंद्रित नहीं है।
unit1 में:
const
UM_CANCELIGNOREFOCUS = WM_USER + 7;
type
TForm1 = class(TForm)
..
private
FIgnoreFocus: Boolean;
procedure UMCancelIgnoreFocus(var Msg: TMessage); message UM_CANCELIGNOREFOCUS;
procedure WMNCActivate(var Msg: TWMNCActivate); message WM_NCACTIVATE;
public
property IgnoreFocus: Boolean write FIgnoreFocus;
end;
...
uses Unit2;
procedure TForm1.WMNCActivate(var Msg: TWMNCActivate);
begin
Msg.Result := 0;
if not (Msg.Active and FIgnoreFocus) then
inherited;
end;
procedure TForm1.UMCancelIgnoreFocus(var Msg: TMessage);
begin
FIgnoreFocus := False;
TForm(Msg.WParam).SetFocus;
end;
unit2 में
:
uses
unit1;
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
Form1.IgnoreFocus := True;
PostMessage(Form1.Handle, UM_CANCELIGNOREFOCUS, NativeInt(Self), 0);
end;
बहरहाल, यह काफी अगर आप परियोजना स्रोत में 'MainFormOnTaskBar' सेट नहीं है, है तो मुख्य रूप के बाद से न केवल फोकस हासिल करेगा बल्कि सामने लाया जाएगा। इस मामले में दोनों फॉर्म अपने जेड-ऑर्डर को जमा करके अवांछित फोकस परिवर्तन/सक्रियण का जवाब दे सकते हैं। कोड तो unit1 के लिए बन जाएगा:
const
UM_CANCELIGNOREFOCUS = WM_USER + 7;
type
TForm1 = class(TForm)
..
private
FIgnoreFocus: Boolean;
procedure UMCancelIgnoreFocus(var Msg: TMessage); message UM_CANCELIGNOREFOCUS;
procedure WMNCActivate(var Msg: TWMNCActivate); message WM_NCACTIVATE;
procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging);
message WM_WINDOWPOSCHANGING;
public
property IgnoreFocus: Boolean read FIgnoreFocus write FIgnoreFocus;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses Unit2;
procedure TForm1.WMNCActivate(var Msg: TWMNCActivate);
begin
Msg.Result := 0;
if not (Msg.Active and FIgnoreFocus) then
inherited;
end;
procedure TForm1.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
begin
inherited;
if FIgnoreFocus then
Msg.WindowPos.flags := Msg.WindowPos.flags or SWP_NOZORDER;
end;
procedure TForm1.UMCancelIgnoreFocus(var Msg: TMessage);
begin
FIgnoreFocus := False;
TForm(Msg.WParam).SetFocus;
end;
और unit2 के लिए:
type
TForm2 = class(TForm)
..
procedure ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
private
procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging);
message WM_WINDOWPOSCHANGING;
public
end;
var
Form2: TForm2;
implementation
uses
unit1;
{$R *.dfm}
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
Form1.IgnoreFocus := True;
PostMessage(Form1.Handle, UM_CANCELIGNOREFOCUS, NativeInt(Self), 0);
end;
procedure TForm2.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
begin
inherited;
if Form1.IgnoreFocus then
Msg.WindowPos.flags := Msg.WindowPos.flags or SWP_NOZORDER;
end;
एक रिबन आपका मुख्य रूप में एक यूआई तत्व होने के लिए लक्षित है, यह वास्तव में करता है फार्म "संशोधित" यह है में जोड़ा। यदि आप अपने प्रोग्राम के मुख्य रूप के अलावा कहीं कहीं रिबन डालते हैं, और यह एप्लिकेशन पर फ़ोकस भेज रहा है। मेनफॉर्म, मैं आश्चर्यचकित नहीं हूं; यह उम्मीद करता है कि यह मुख्य रूप का हिस्सा है। वीसीएल स्रोत कोड के साथ आता है ताकि आप इकाई को खोल सकें और देख सकें कि क्या आप प्रश्न में कोड पा सकते हैं या नहीं। –
जिस एप्लिकेशन को मैं डिजाइन कर रहा हूं वह "आउटलुक" अनुभव के लिए जा रहा है, जो इसके कार्यान्वयन में, मुख्य कार्यक्रम के लिए रिबन का उपयोग करता है और ईमेल, कैलेंडर आइटम, संपर्क इत्यादि बनाने के लिए एक अलग रिबन का उपयोग करता है। जब भी मैं Outlook रिबन क्रिया का उपयोग करता हूं एक ईमेल में, यह मेरे फोकस को मुख्य Outlook विंडो पर वापस नहीं भेजता है। मैंने ट्रिबोन घटक के लिए स्रोत को देखने का थोड़ा सा प्रयास किया है, लेकिन यह स्वीकार्य रूप से थोड़ा मोटा है। मैं यह देखने के लिए ऐसा करना जारी रखूंगा कि क्या यह पता चल सकता है कि यह कहां हो रहा है, और यदि मैं इस व्यवहार को ओवरराइड कर सकता हूं।इस प्रकार, हालांकि, मुझे कोई भाग्य नहीं मिला है। – Aaron
मुझे एक बग की तरह बहुत जोर से लगता है। वह व्यवहार नहीं होना चाहिए। यदि आप एक साधारण ऐप में repro कर सकते हैं तो आपको इसे QC –