Kast2k Опубликовано 14 октября, 2019 Поделиться Опубликовано 14 октября, 2019 (изменено) Добрый день! Delphi 10.2 Tokyo. С FMX разбираюсь всего пару-тройку недель и возможно пока не понимаю его принципов работы. Есть сканер на андроиде Honeywell. В FMX рисую для него приложение по получению и обработке штрих-кодов. Есть основная форма и вспомогательная (принимающая данные со сканера). Дочернюю форму вызываю так: procedure TMainForm.btnSaveToStoreClick(Sender: TObject); var f:TfrmScanWindow; begin f:=TfrmScanWindow.Create(Application); try f.Show; finally // FreeAndNil(f); end; end; Далее, в дочерней форме следующий код: type JNativeActivitySubclass = interface; JNativeActivitySubclassClass = interface(JActivityClass) ['{829C77FB-08F1-4D19-9782-3C58EECAAAAA}'] {Methods} //function init: JFMXNativeActivity; cdecl; end; [JavaSignature('com/winarhi/nativeactivitysubclass/NativeActivitySubclass')] JNativeActivitySubclass = interface(JActivity) ['{2FA559EC-D1D7-46AA-9C52-FEFC6B3AAAAA}'] {Methods} procedure WA_75e_DoScan; procedure WA_75e_Create_aidcManager; procedure WA_75e_Destroy_aidcManager; end; TJNativeActivitySubclass = class(TJavaGenericImport<JNativeActivitySubclassClass, JNativeActivitySubclass>) end; TfrmScanWindow = class(TForm) Label1: TLabel; MemoData: TMemo; btnAgree: TButton; btnCancel: TButton; btnFinish: TButton; Panel1: TPanel; Panel2: TPanel; Timer1: TTimer; procedure btnFinishClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormShow(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { Private declarations } ARNBarCode : string; procedure MemoAddText(const AText:string); public { Public declarations } procedure ActivateScanner; procedure RegisterDelphiNativeMethods; procedure onBarCodeCompleteThreadSwitcher; procedure onBarCodeFailThreadSwitcher; end; var frmScanWindow: TfrmScanWindow; implementation uses FMX.Helpers.Android, Androidapi.NativeActivity, formScanComplete; {$R *.fmx} procedure onBarCodeCompleteNative(PEnv: PJNIEnv; This: JNIObject; BarCode: JNIString); cdecl; begin frmScanWindow.MemoAddText('onBarCodeCompleteNative start'); // НЕ работает TThread.Synchronize(TThread.CurrentThread, procedure() begin frmScanWindow.MemoData.Lines.Add('onBarCodeCompleteNative start'); frmScanWindow.MemoData.Repaint; end); // НЕ работает // Log.d('Thread (Main: %.8x, Current: %.8x, Java:%.8d (%2:.8x), POSIX:%.8x)', // [MainThreadID, TThread.CurrentThread.ThreadID, TJThread.JavaClass.currentThread.getId]); frmScanWindow.ARNBarCode := JNIStringToString(PEnv, BarCode); // работает TThread.Synchronize(TThread.CurrentThread, frmScanWindow.onBarCodeCompleteThreadSwitcher); // НЕ работает end; procedure onBarCodeFailNative(PEnv: PJNIEnv; This: JNIObject; BarCode: JNIString); cdecl; begin frmScanWindow.MemoAddText('onBarCodeFailNative start'); // НЕ работает // Log.d('Thread (Main: %.8x, Current: %.8x, Java:%.8d (%2:.8x), POSIX:%.8x)', // [MainThreadID, TThread.CurrentThread.ThreadID, TJThread.JavaClass.currentThread.getId]); frmScanWindow.ARNBarCode := JNIStringToString(PEnv, BarCode); // работает // Log.d('Calling Synchronize'); TThread.Synchronize(TThread.CurrentThread, frmScanWindow.onBarCodeFailThreadSwitcher); // НЕ работает end; procedure TfrmScanWindow.ActivateScanner; begin RegisterDelphiNativeMethods; TJNativeActivitySubclass.Wrap(PANativeActivity(System.DelphiActivity)^.clazz).WA_75e_Create_aidcManager; MemoAddText('Activated'); // работает end; procedure TfrmScanWindow.FormShow(Sender: TObject); begin MemoAddText('Pre-activate'); // работает ActivateScanner; end; procedure TfrmScanWindow.MemoAddText(const AText: string); begin MemoData.Lines.BeginUpdate; try MemoData.Lines.Add(AText); finally MemoData.Lines.EndUpdate; end; end; procedure TfrmScanWindow.onBarCodeCompleteThreadSwitcher; begin MemoAddText('onBarCodeCompleteThreadSwitcher'); // НЕ работает MemoAddText(ARNBarCode); // НЕ работает ShowMessage(ARNBarCode); // работает end; procedure TfrmScanWindow.onBarCodeFailThreadSwitcher; begin MemoAddText('onBarCodeFailThreadSwitcher'); // НЕ работает MemoAddText('Barcode Scan Failed ' + ARNBarCode); // НЕ работает end; procedure TfrmScanWindow.RegisterDelphiNativeMethods; var PEnv: PJNIEnv; ActivityClass: JNIClass; NativeMethods: array[0..1] of JNINativeMethod; begin Log.d('Starting the registration JNI stuff'); PEnv := TJNIResolver.GetJNIEnv; Log.d('Registering interop methods'); NativeMethods[0].Name := 'onBarCodeCompleteNative'; NativeMethods[0].Signature := '(Ljava/lang/String;)V'; NativeMethods[0].FnPtr := @onBarCodeCompleteNative; NativeMethods[1].Name := 'onBarCodeFailNative'; NativeMethods[1].Signature := '()V'; NativeMethods[1].FnPtr := @onBarCodeFailNative; ActivityClass := PEnv^.GetObjectClass( PEnv, PANativeActivity(System.DelphiActivity).clazz); PEnv^.RegisterNatives(PEnv, ActivityClass, @NativeMethods[0], 2); PEnv^.DeleteLocalRef(PEnv, ActivityClass); Log.d('Interop Methods Registered'); end; procedure TfrmScanWindow.Timer1Timer(Sender: TObject); begin MemoAddText(FormatDateTime('hh:nn:ss',Now)); // работает end; Поясните, пожалуйста, что я делаю не так. Если весь этот код вызывать в основной форме, то всё работает и в memo я вижу полученные данные баркода. При вызове из дочерней - нет. При попытке вызвать ShowModal я получаю ошибку Not implemented for this platform. Изменено 14 октября, 2019 пользователем Kast2k Цитата Ссылка на комментарий
0 Kast2k Опубликовано 14 октября, 2019 Автор Поделиться Опубликовано 14 октября, 2019 (изменено) Простите за беспокойство, разобрался. Надо было в главной форме вместо такого var f:TfrmScanWindow; begin f:=TfrmScanWindow.Create(nil); try f.Show; finally // FreeAndNil(f); end; Указать как begin frmScanWindow:=TfrmScanWindow.Create(nil); try frmScanWindow.Show; finally end; И форму выкинуть из auto-create Изменено 14 октября, 2019 пользователем Kast2k Ingalime 1 Цитата Ссылка на комментарий
1 krapotkin Опубликовано 14 октября, 2019 Поделиться Опубликовано 14 октября, 2019 (изменено) ну, есть идеи, как бы модифицировать код, но и так сойдет я бы перефразировал if frmScanWindow = nil then frmScanWindow := TFrmScanWindow.Create(NIL); frmScanwindow.showModal( procedure (const AResult:TModalResult) begin if AResult = mrOK then begin ....... и может быть даже FreeAndNil(frmScanwindow); end; end); Изменено 14 октября, 2019 пользователем krapotkin Ingalime, Yarpda и qz5 3 Цитата Ссылка на комментарий
Вопрос
Kast2k
Добрый день!
Delphi 10.2 Tokyo.
С FMX разбираюсь всего пару-тройку недель и возможно пока не понимаю его принципов работы.
Есть сканер на андроиде Honeywell.
В FMX рисую для него приложение по получению и обработке штрих-кодов.
Есть основная форма и вспомогательная (принимающая данные со сканера). Дочернюю форму вызываю так:
procedure TMainForm.btnSaveToStoreClick(Sender: TObject); var f:TfrmScanWindow; begin f:=TfrmScanWindow.Create(Application); try f.Show; finally // FreeAndNil(f); end; end;
Далее, в дочерней форме следующий код:
Поясните, пожалуйста, что я делаю не так.
Если весь этот код вызывать в основной форме, то всё работает и в memo я вижу полученные данные баркода. При вызове из дочерней - нет.
При попытке вызвать ShowModal я получаю ошибку Not implemented for this platform.
Ссылка на комментарий
2 ответа на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.