কীভাবে ফায়ারমনকিতে "কোনও অ্যাক্টিভেট" ফর্ম তৈরি করবেন


147

এক্সকোডে আপনার এনএসভিউ সাবক্লাসে এই পদ্ধতিগুলি যুক্ত করে উইন্ডোটি ক্লিক করার সময় সক্রিয় হওয়া থেকে রোধ করতে পারে:

- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent )theEvent {
    return YES;
}
- (BOOL)acceptsFirstMouse:(NSEvent )theEvent {
    return YES; 
}
- (void)mouseDown:(NSEvent )theEvent {
    [[[NSApp]] preventWindowOrdering]; 
}

উইন্ডোজ প্ল্যাটফর্মে এটি এই সাধারণ কোড দ্বারা সম্পন্ন হয়:

HWND hWnd = FindWindowW((String("FM") + fmxForm->ClassName()).c_str(), 
    fmxForm->Caption.c_str());

SetWindowLong(hWnd, GWL_EXSTYLE,
    GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_NOACTIVATE);

আমার এফএমএক্স টিএফর্মটি ক্লিক করার সময় এটি সক্রিয় হওয়ার জন্য কীভাবে আমি এনএসভিউতে সাবক্লাস করতে পারি?

আমি কীভাবে ফায়ারমনকিতে " না অ্যাক্টিভেট " ফর্ম তৈরি করতে পারি ?


3
নিশ্চিত না যে এটি ফায়ারমনকি-তেও প্রযোজ্য কিনা, বা এটি আপনার প্রশ্নের যথাযথ উত্তর দেয় কিনা তবে আপনি এই উদাহরণটি একবার দেখতে চাইতে পারেন: delphi.about.com/od/delphitips2008/qt/ex_noactivate.htm
TildalWave

থানকিউ, তবে এটি কেবল উইন্ডোজের পক্ষে এবং সহজ উপায়টি হ'ল উপরের "সেট উইন্ডো লং" দ্বারা বর্ণিত আমার সমাধান, প্রশ্নটি ম্যাকোস সম্পর্কে।
এমএইচ তাকিয়া


ডিভন: এই লিঙ্কটি কীভাবে আমাকে সহায়তা করতে পারে?
এমএইচ তাকিয়া

WBAR কে ধন্যবাদ, এটি দ্বিতীয় অনুগ্রহ!
এমএইচ তাকিয়া

উত্তর:


13

এটি ব্যবহার সম্ভব NSPanel সঙ্গে NSNonactivatingPanelMask পতাকা। এফএমএক্স ফর্মের এনএসভিউ এনএসপ্যানেলের সন্তান হওয়া উচিত। আমি একটি সহায়ক ক্লাস লিখেছি যা উইন্ডোজ এবং ম্যাক প্ল্যাটফর্ম উভয়ের জন্য কাজ করে ( এক্সই 4 তে কাজ করে ):

unit NoActivateForm;

interface

uses Fmx.Forms, Fmx.Types
{$IFDEF POSIX}
    , Macapi.AppKit
{$ENDIF}
    ;

type TNoActivateForm = class
private
    form: TForm;
{$IFDEF POSIX}
    panel: NSPanel;
    timer: TTimer;  // for simulating mouse hover event
{$ENDIF}
    procedure SetPosition(const x, y: Integer);
    procedure GetPosition(var x, y: Integer);
    procedure SetDimensions(const width, height: Integer);
    procedure SetLeft(const Value: Integer);
    procedure SetTop(const Value: Integer);
    procedure SetHeight(const Value: Integer);
    procedure SetWidth(const Value: Integer);
    procedure SetVisible(const Value: Boolean);
    function GetLeft: Integer;
    function GetTop: Integer;
    function GetHeight: Integer;
    function GetWidth: Integer;
    function GetVisible: Boolean;
{$IFDEF POSIX}
    procedure OnTimer(Sender: TObject);
{$ENDIF}
public
    constructor Create(AForm: TForm);
    destructor Destroy; override;
    property Left: Integer read GetLeft write SetLeft;
    property Top: Integer read GetTop write SetTop;
    property Height: Integer read GetHeight write SetHeight;
    property Width: Integer read GetWidth write SetWidth;
    property Visible: Boolean read GetVisible write SetVisible;
end;

implementation
uses
    Classes, System.Types
{$IFDEF MSWINDOWS}
    , Winapi.Windows;
{$ELSE}
    , Macapi.CocoaTypes, FMX.Platform.Mac, Macapi.CoreGraphics, Macapi.CoreFoundation;
{$ENDIF}

constructor TNoActivateForm.Create(AForm: TForm);
{$IFDEF POSIX}
var
    rect: NSRect;
    bounds: CGRect;
    window: NSWindow;
    style: integer;
    panelCount: integer;
begin
    form := AForm;
    form.Visible := false;
    bounds := CGDisplayBounds(CGMainDisplayID);
    rect := MakeNSRect(form.Left, bounds.size.height - form.Top - form.Height,
        form.ClientWidth, form.ClientHeight);
    style := NSNonactivatingPanelMask;
    style := style or NSHUDWindowMask;
    panel := TNSPanel.Wrap(
        TNSPanel.Alloc.initWithContentRect(rect, style, NSBackingStoreBuffered,
        true));
    panel.setFloatingPanel(true);
    //panel.setHasShadow(false); optional
    window := WindowHandleToPlatform(form.Handle).Wnd;

    panel.setContentView(TNSView.Wrap(window.contentView));
    TNSView.Wrap(window.contentView).retain;

    timer := TTimer.Create(form.Owner);
    timer.OnTimer := OnTimer;
    timer.Interval := 50;
end;
{$ELSE}
var hWin: HWND;
begin
    form := AForm;
    form.TopMost := true;
    hWin := FindWindow(PWideChar('FM' + form.ClassName), PWideChar(form.Caption));
    if hWin <> 0 then
        SetWindowLong(hWin, GWL_EXSTYLE,
            GetWindowLong(hWin, GWL_EXSTYLE) or WS_EX_NOACTIVATE);
end;
{$ENDIF}

destructor TNoActivateForm.Destroy;
{$IFDEF POSIX}
begin
    panel.release;
end;
{$ELSE}
begin
end;
{$ENDIF}

procedure TNoActivateForm.SetPosition(const x, y: Integer);
{$IFDEF POSIX}
var point: NSPoint;
    screen: CGRect;
begin
    screen := CGDisplayBounds(CGMainDisplayID);
    point.x := x;
    point.y := round(screen.size.height) - y - form.height;
    panel.setFrameOrigin(point);
end;
{$ELSE}
begin
    form.Left := x;
    form.Top := y;
end;
{$ENDIF}

procedure TNoActivateForm.GetPosition(var x, y: Integer);
{$IFDEF POSIX}
var screen: CGRect;
begin
    screen := CGDisplayBounds(CGMainDisplayID);
    x := round(panel.frame.origin.x);
    y := round(screen.size.height - panel.frame.origin.y - panel.frame.size.height);
end;
{$ELSE}
begin
    x := form.Left;
    y := form.Top;
end;
{$ENDIF}

procedure TNoActivateForm.SetDimensions(const width, height: Integer);
{$IFDEF POSIX}
var size: NSSize;
begin
    size.width := width;
    size.height := height;
    panel.setContentSize(size);
end;
{$ELSE}
begin
    form.width := width;
    form.height := height;
end;
{$ENDIF}

procedure TNoActivateForm.SetLeft(const Value: Integer);
begin
    SetPosition(Value, Top);
end;

procedure TNoActivateForm.SetTop(const Value: Integer);
begin
    SetPosition(Left, Value);
end;

procedure TNoActivateForm.SetHeight(const Value: Integer);
begin
    SetDimensions(Width, Value);
end;

procedure TNoActivateForm.SetWidth(const Value: Integer);
begin
    SetDimensions(Value, Height);
end;

procedure TNoActivateForm.SetVisible(const Value: Boolean);
begin
{$IFDEF POSIX}
    panel.setIsVisible(Value);
{$ELSE}
    form.visible := Value;
{$ENDIF}
end;

function TNoActivateForm.GetLeft: Integer;
var x, y: Integer;
begin
    GetPosition(x, y);
    result := x;
end;

function TNoActivateForm.GetTop: Integer;
var x, y: Integer;
begin
    GetPosition(x, y);
    result := y;
end;

function TNoActivateForm.GetHeight: Integer;
begin
{$IFDEF POSIX}
    result := round(panel.frame.size.height);
{$ELSE}
    result := form.Height;
{$ENDIF}
end;

function TNoActivateForm.GetWidth: Integer;
begin
{$IFDEF POSIX}
    result := round(panel.frame.size.width);
{$ELSE}
    result := form.Width;
{$ENDIF}
end;

function TNoActivateForm.GetVisible: Boolean;
begin
{$IFDEF POSIX}
    result := panel.isVisible();
{$ELSE}
    result := form.visible;
{$ENDIF}
end;

{$IFDEF POSIX}
procedure TNoActivateForm.OnTimer(Sender: TObject);
var event: CGEventRef;
    point: CGPoint;
    form_rect: TRectF;
    client_point, mouse_loc: TPointF;
    shift: TShiftState;
begin
    event := CGEventCreate(nil);
    point := CGEventGetLocation(event);
    CFRelease(event);
    mouse_loc.SetLocation(point.x, point.y);
    if Visible = true then
    begin
        form_rect := RectF(0, 0, form.Width, form.Height);
        client_point.X := mouse_loc.X - Left;
        client_point.Y := mouse_loc.y - Top;
        if PtInRect(form_rect, client_point) then
            form.MouseMove(shift, client_point.x, client_point.y)
        else
            form.MouseLeave();
    end;
end;
{$ENDIF}

end.

উপরের ইউনিটের ব্যবহার:

TNoActivateForm *naKeyboard; // global scope    
void __fastcall TfrmKeyboard::TfrmKeyboard(TObject *Sender)
{
    naKeyboard = new TNoActivateForm(frmKeyboard); // frmKeyboard is a normal fmx form
    naKeyboard->Visible = true;
}

যদি frmKeyboard আপনার মূল ফর্ম হয় তবে উপরের কোডটি ফর্ম কনস্ট্রাক্টরে রাখবেন না, এটি অনশোতে রাখার পরামর্শ দেওয়া হচ্ছে।

এখানে চিত্র বর্ণনা লিখুন

দ্রষ্টব্য : উইন্ডোহ্যান্ডলটোপ্ল্যাটফর্মটি XE3 তে উপস্থিত রয়েছে বলে মনে হচ্ছে না যাতে সেই লাইনটি প্রতিস্থাপন করা যায়

window := NSWindow(NSWindowFromObjC(FmxHandleToObjC(Form.Handle)));

1
দুর্দান্ত সমাধানের জন্য ধন্যবাদ - উইন্ডো হ্যান্ডলেটপ্লেফর্মটি XE3-তে বিদ্যমান বলে মনে হচ্ছে না যাতে সেই লাইনটি উইন্ডো দিয়ে প্রতিস্থাপন করা যায়: = এনএসউইন্ডো (এনএসওয়াইন্ডোফ্রোমজবিসি (এফএমএক্সহ্যান্ডলিটোওবিজিসি (ফর্ম.হ্যান্ডল)));
ডেভিড পিটারস

2

এটি ফোকাস করা রোধ করতে ফর্ম মাউস হ্যান্ডলিং বন্ধ করতে পারেন। আপনার ফর্ম ধরে ধরে মাইফর্ম বলা হয়:

uses fmx.platform.mac, macapi.appkit;
.
.
Var nswin:nswindow;
.
.  
NSWin:= NSWindow(NSWindowFromObjC(FmxHandleToObjC(myform.Handle))); { get the NSWindow }
NSWin.setIgnoresMouseEvents(true);                                 { ignore mouse events }
NSWin.setAcceptsMouseMovedEvents(false);

এতে সামান্য সমস্যা আছে যে এটি মাউসের ডান ক্লিককে থামায় না। যদি সমস্যা হয় তবে আপনাকে ফর্মের মধ্যে মোসডাউন ইভেন্টটির প্রতিক্রিয়া জানাতে হবে এবং প্রধান ফর্মগুলিকে মাউসডাউন কল করতে হবে যাতে এটি মাউস ইভেন্টটি হারাবে না। যেহেতু ডান মাউস নীচে মাউস ইভেন্টগুলি ক্যাপচার করবে, আপনার তখন মাউস সরানো এবং মাউস আপ ইভেন্টগুলিকেও সাড়া দিতে হবে - সেগুলি আপনার মূল ফর্মে ফরোয়ার্ড করে। যদিও এটি মাউসটিকে ডান ক্লিকে ক্যাপচার করে, তবুও এটি ফর্মটিকে ফোকাস করবে না।

ডেভ পিটার্স ডিপি সফটওয়্যার


ভুল, কাজ করে না। ফর্ম ক্লিকে কীবোর্ড ফোকাস পরিবর্তন করে।
এমএইচ তাকিয়া

আচ্ছা এটি ফোকাস পাচ্ছে না তবে যা ঘটে তা হ'ল যে কোনও মাউস ক্লিকগুলি তার নীচের যে কোনওটিতে ফর্মটি দিয়ে যায়। যদি আপনি এই ব্যবস্থা করতে পারেন যে নন ফোকাস ফর্মটিতে টপমস্ট সম্পত্তি সেট রয়েছে এবং আপনার নিজের মূল ফর্মের কেবল একটি ফাঁকা অংশ এর নীচে থাকে তবে এটি কার্যকর হবে। আপনার যদি উইন্ডোর নীচে কোনও প্রধান ফর্ম নিয়ন্ত্রণ থাকে তবে যখন আপনি নন-ফোকাস উইন্ডোটি নেই তেমন আচরণ করে আপনি মাউস ক্লিক করবেন তখন সেগুলি ফোকাস পাবে। একইভাবে যদি উইন্ডোটি ডেস্কটপের উপরে স্থাপন করা হয় তবে ডেস্কটপ মাউস ক্লিক পায় এবং আপনার অ্যাপ্লিকেশন ফোকাস হারিয়ে ফেলে।
ডেভিড পিটারস

নোট করুন যে আমার মাউসের ইভেন্টগুলি দরকার। আমি মাউস ইভেন্ট উপেক্ষা করতে পারবেন না। আমি একটি বোতামে ক্লিক করতে চাই, এছাড়াও যখন মাউস পয়েন্টার একটি নিয়ন্ত্রণে প্রবেশ করে তখন আমি ফায়ারমনকি অ্যানিমেশন রাখতে চাই। ধরে নিন যে আমি একটি ভার্চুয়াল কীবোর্ড তৈরি করতে চাই, অগ্রভাগ অ্যাপ্লিকেশনটি (উদাহরণস্বরূপ) টেক্সটএডিট। আমি যখন আমার এফএমএক্স ফর্মের একটি বোতামে ক্লিক করি তখন একটি কীবোর্ড ইভেন্ট উত্পন্ন হবে এবং একটি অক্ষর টাইপ হবে।
এমএইচ তাকিয়া
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.