Jump to content

Alexander Halser

Members
  • Content Count

    59
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by Alexander Halser

  1. Alexander Halser

    Work with PDF documents

    PDFium lib does all you need. We use it with an internal application that deals with PDF pages. Add or remove pages, split pages into several smaller ones, re-combine smaller pages into one printer page. PDFium can extract text as well.
  2. Alexander Halser

    Mouse events not triggered, caused by styled TMainMenu?

    tested with polardark_win and polarlight_win styles I confirm that it works for me with the styles included in Delphi and those premium styles available for download when you have an active subscription. That's why I asked the OP where the dark styles origins from. Maybe it is an older style? My argument is that if a simply outdated style compiles just fine and looks good on screen, but generates potential runtime issues that may cause problems I would have never expected and that are difficult to find, then we're in for future problems with FMX styles
  3. Alexander Halser

    Mouse events not triggered, caused by styled TMainMenu?

    ChildForm is not released, StyleBookLight don't contain data Where do you see a problem here? Form2 is auto-created and auto-released, StyleBookLight is not required to produce the problem. I had some similar problem using an old 10.2 style That worries me ... what happens if a project that includes a TStylebook with a previously up-to-date style gets updated to a new Delphi version? Does that mean it compiles just fine but fails at runtime with mysterious errors? How does one test an app for potential problems like the one above? I'd like to know where it comes from before using FMX styles.
  4. Alexander Halser

    Mouse events not triggered, caused by styled TMainMenu?

    Fascinating example... thanks a lot! I am currently experimenting with FMX styles and very much appreciate this. It's got something to do with the dark style - the style itself damages the runtime functionality. I can duplicate the issue with Delphi 11.0, both 32 and 64 bit, it is reproducible with the dark style (only). Switching back to the light style makes it work again. My first guess was that it has to do with TStyleBook. It is apparent that the second form does not pick up the style, so I thought it may have to do with this issue. But this is not the case. So I loaded my own dark skin into your dark stylebook. Guess what? Works like a charm, despite not applying the style to the second window. There is, that's for sure, some flaw in the dark style you are using. Fascinating this is possible at all... I did not think it was. Where does your dark style come from?
  5. Alexander Halser

    Detecting MouseUp When Outside The Form

    FMX doesn't auto-capture the control the mouse went down on. But you can do this manually, either by TForm.MouseCapture (that's for the form itself) or with TForm.SetCaptured(AnyControl) - this is for a particular control on the form. procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin if (Sender <> self) then SetCaptured(TControl(Sender)) else MouseCapture; memo1.lines.add(Sender.Classname + ' mouse down'); end; procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin ReleaseCapture; memo1.lines.add(Sender.Classname + ' mouse up'); end; Setting the mouse capture is important if you do anything in MouseDown that interacts with the control being clicked. Without capture, the user may click (mouse-down) on Panel1, move it, and release it on Panel2. The MouseUp will come from Panel2 in this case, or no mouse-up at all. By setting the mouse capture, you are guaranteed that you'll receive a MouseUp from that control that is being captured. VCL does this automatically, FMX does not. If you don't need the MouseDown on form level, but just for particular controls, use TControl.AutoCapture instead.
  6. Alexander Halser

    Access TStringGrid InplaceEditor

    I was about to suggest to create a custom inplace editor. But the form that contains the TStringGrid does get KeyDown notifications, even when editing content. Out of curiosity, I wanted to know the internal structure of the grid, when it's editing. procedure TForm2.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState); var ctl: tfmxobject; s: string; begin if key = vkF5 then begin ctl := activecontrol; while ctl <> form2 do begin s := '> ' +ctl.classname + S; ctl := ctl.Parent; end; showmessage(s); end; end; It says: TStringGrid > TGridScrollContent > TDefaultEditor So if you check the OnKeyDown on form level and detect that ActiveControl is a TDefaultEditor with a TStringGrid as grandparent, you should be all set. Aren't you?
  7. I need some FMX functionality in a VCL app. An FMX Windows DLL should handle the task. So far, the (FMX) DLL is working, but... Loading a TBitmap in the initialization of the DLL fails. The host application (actually the DLL) comes up with a general error. Loading the TBitmap at a later point in time (e.g. triggered by the host app) works. Unfortunately, the real DLL is a bit more complex and stripping all the "initialization" from all units is not an option. Static vs. dynamic loading of the DLL by the host VCL app does not make a difference. I've also tried ShareMem (not convinced it would change anything), but to give it a try: same result. Stripped down to the core, the entire DLL code is in the screenshot below. To me, it looks as if the GDI+ or DirectX environment is not loaded, when the DLL initializes. Is this a general limitation or could that be worked around by forcing earlier loading of GDI+/DirectX?
  8. Alexander Halser

    Firemonkey DLL: loading a TBitmap in initialization fails (solved)

    You are certainly right. But the real DLL is more complex and involves 3rd party components, which happen to load TBitmaps in the initialization. Quite common, I'd say, and I wouldn't have considered it scary. But obviously, it is
  9. Alexander Halser

    Firemonkey DLL: loading a TBitmap in initialization fails (solved)

    Si Señor! Winapi.GDIOBJ instead of FMX.Graphics does the trick. And saves a few megabytes. Thank you very much for the hint, Uwe! To sum up the solution... If an FMX DLL requires drawing capabilities in the initialization (that requirement might be triggered by 3rd party units), then the VCL host application must load GDI+ before loading the DLL: In the VCL host app, include Winapi.GDIOBJ to init GDI+ Load the FMX DLL dynamically (static linking would cause the DLL to load first, before host can load GDI+) If the host app is FMX and not VCL, it loads GDI+ by default. In this case, point (1) is void, but dynamic loading of the DLL is still required.
  10. Alexander Halser

    Firemonkey DLL: loading a TBitmap in initialization fails (solved)

    Update, a partial solution, and a question... Observations with an FMX host app + FMX dll: The FMX DLL requires GDI+/DirectX in the intialization section. It creates an FMX.TBitmap and loads an image. To do this, it requires a GDI+/DirectX canvas. Such a DLL cannot be statically linked, fullstop. Not even with an FMX host application, despite the FMX host does initialize GDI+/DirectX. The reason is that statically linked DLLs get loaded before the host app can initialize GDI+/DirectX. Solution for FMX host + FMX dll: link the DLL dynamically, let the host app initialize GDI+/DirectX (as it does by default), then load the DLL. Result: the initialization of the DLL works, because GDI+/DirectX is already available (loaded by the FMX host). Observations with a VCL host app + FMX dll: It's obvious that GDI+/DirectX must be initialized by the host app before the DLL gets loaded. Dynamic DLL loading is therefore a must. The VCL host does not - at least not by default - initialize GDI+/DirectX, because it does not require it. Question: can we force the VCL host to deliberately load GDI+/DirectX, which is required by the DLL? Answer: yes, we can by including FMX.Graphics into the VCL section. Technically, that works (and the compiler does not complain). VCL host app test unit, modified: Note, that the VCL app references FMX.Graphics. This adds about 7mb to the EXE and seems to work. Is this a reliable construct? Or is there a different way to invoke (just) GDI+/DirectX in the host app, without all the FMX.Graphics overhead? unit VCL_hostUnit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, FMX.Graphics; { <--- This works and intializes GDI+/DirectX for the DLL. But will this work reliably? } type TVCLForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; TLoadImage = function(Filename: PChar): Boolean; var VCLForm1: TVCLForm1; dllHandle: Cardinal; LoadImageFunc: TLoadImage; implementation {$R *.dfm} function LoadDLL: Boolean; begin dllHandle := LoadLibrary('TestDLL.dll') ; @LoadImageFunc := GetProcAddress(dllHandle, 'LoadImage') ; end; procedure TVCLForm1.Button1Click(Sender: TObject); begin if LoadDLL then LoadImageFunc('C:\Users\Alexander\Documents\Embarcadero\Studio\Projects\fmx-dll-test\test.png') else Showmessage('DLL not loaded'); end; initialization dllHandle := 0; finalization if dllHandle <> 0 then FreeLibrary(dllHandle) ; end.
  11. Alexander Halser

    Firemonkey DLL: loading a TBitmap in initialization fails (solved)

    Hello programmerdelphi2k! I should have been more precise: Delphi 11.0 Win32 (not 64 bit) The DLL is 100% FMX, so TBitmap is an FMX.Graphics.TBitmap The host app is 100% VCL Host and DLL do not exchange bitmaps, nor other complex data structures. They exchange PChars and function results. When the host app starts and the DLL loads, I get the message "Load DLL" and after that: "Exception EAccessViolation in Module TestDLL.dll at 0000842F." Host app (VCL 32 bit, 1 form): unit hostUnit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; function LoadImage(Filename: PChar): Boolean; external 'TestDLL.dll'; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin LoadImage('C:\Users\Alexander\Documents\Embarcadero\Studio\Projects\fmx-dll-test\test.png'); end; end. DLL Code: library TestDLL; uses FMX.Forms, FMX.Graphics, FMX.Dialogs; {$R *.res} function LoadImage(Filename: PChar): Boolean; var dummy: FMX.Graphics.TBitmap; begin dummy := FMX.Graphics.TBitmap.Create; dummy.LoadFromFile(Filename); dummy.Free; Showmessage('Image loaded'); end; exports LoadImage; var dummy: FMX.Graphics.TBitmap; begin Showmessage('Load DLL'); dummy := FMX.Graphics.TBitmap.Create; //This line included, the DLL fails to load: // dummy.LoadFromFile('C:\Users\Alexander\Documents\Embarcadero\Studio\Projects\fmx-dll-test\test.png'); dummy.Free; end. HostApp.zip
  12. I am currently working on some legacy code that uses simple TLists with object references and custom sort. This has worked and still works perfectly in 32 bit. But in 64 bit output, the list is not sorted (correctly), although it compiles without any errors. The form contains a couple of TShapes with different widths. The code below is supposed to sort and rearrange them by width. In 32 bit, the sort is ok. In 64 bit it's random. In fact, the function SortByWidth is called with item1 and item2 being the same (here: pointing to the same TShape). I am concerned and want to understand what's going on and why this does not work in 64 bit. There are more modern ways to sort a TList or use dictionaries. But this is legacy code that contains sorting functions of this kind in several places. procedure TForm2.BtnSortClick(Sender: TObject); function SortByWidth(const item1, item2: TShape): Integer; begin result := item1.width - item2.width; end; var AList: TList; i: Integer; begin AList := TList.Create; try for i := 0 to ComponentCount-1 do if (Components[i] is TShape) then AList.Add(Components[i]); AList.Sort(@SortByWidth); //what is wrong about this in 64 bit? for i := 0 to AList.Count-1 do TShape(AList[i]).Top := 30 + (40 * i); finally AList.Free; end; end;
  13. @Uwe Raabe & Günter: Thank you, that does the trick! This saves me a lot of code-rewriting 🙂 function SortShapesByWidth(const item1, item2: TShape): Integer; begin result := item1.width - item2.width; end; procedure TForm2.BtnSortClick(Sender: TObject); var AList: TList; i: Integer; begin AList := TList.Create; try for i := 0 to ComponentCount-1 do if (Components[i] is TShape) then AList.Add(Components[i]); AList.Sort(@SortShapesByWidth); for i := 0 to AList.Count-1 do TShape(AList[i]).Top := 30 + (40 * i); finally AList.Free; end; end;
  14. Alexander Halser

    MacOS: Library not loaded: ?^???

    The heading is not a typo. I've taken over Mac development from a colleague who recently left, so Delphi/Mac is pretty new to me. I'm running Delphi 10.4 Seattle with all patches and have a new Macbook running Monterey with Xcode 12.5.1. My basic "hello world" test app compiles and deploys successfully. But it doesn't start on the Mac. When started manually, it flickers for a moment, then terminates. PAServer reveals the underlying problem: dyld[xxxx]: Library not loaded: ?^??? Referenced from: /Users/alexander/PAServer/scratch-dir/Alexander-MacProfile/MacTest.app/Contents/MacOS/MacTest Reason: tried: '?^???' (no such file) The app obviously has a reference to "?^???" which is not found. But where does this come from? My current configuration: Delphi 10.4 with all patches MacOS Monterey with Xcode 12.5.1 (after realizing that Xcode 13 is not compatible I managed to install and run 12.5.1) Delphi SDK Manager: MacOSX 11.3 The app compiles and deploys successfully, both in Release and Debug mode. It just doesn't run. I'm pretty much stuck here... Google delivers plenty of results for "library not loaded" but none of them deals with a string called "?^???". PS: When changing the encoding of the (very simply) main unit from ANSI to UTF8, this slightly affects the error message. The UTF8 variant looks for a library called "?^;?[" instead of "?^???". Any hints where to look for this?
  15. Alexander Halser

    MacOS: Library not loaded: ?^???

    I am afraid I cannot help much. As described in the referenced thread... (I haven't changed this configuration since it got it working) iOS 15.1 - FMX - Delphi-PRAXiS [en] (delphipraxis.net) Reformatted the Mac, installed maOS Big Sur, an older version of Xcode. Things now work as advertised with Delphi 11. Delphi 11 plus November and January patch Hardware: M1 (2020) Mac running macOS Big Sur Xcode 13.2
  16. I've taken over a legacy project from a friend, that needs a structural redesign. The application basically does file analysis and modification. It is currently a GUI app with everything built into the main executable. I would like to split that and am thinking of multiple EXEs. One that resembles the GUI, a console application that executes one particular task. On top of that, it needs a Windows service to execute scheduled tasks automatically, if no user is logged in. What is the best practice to accomplish this? Bi-directional communication is a must and could be done with custom messages and console output. Any other thoughts? Plugin system via DLL? Runtime packages? My thoughts about the general design so far: EXE1 (the GUI app) EXE2 (the non-GUI Windows service) EXE3 (the console app that executes tasks, can be used stand-alone in console mode and must run in multiple instances) EXE1 and EXE2 would both call the console EXE3. However, the tasks being executed can be quite long (from minutes to hours), so bi-directional communication is required. And while a task is being executed, it is not feasible to simply kill the thread in order to stop it. EXE3 must complete or roll back the detail, it's currently working on. Furthermore, EXEs should run without installation (except for the Windows service, that is). If EXE3 was, for instance, a COM server, this wouldn't work, would it? We could of course build everything into every EXE and separate the functionality in the code design. But I don't like the idea in general and multi-threaded execution is easier to handle with separate processes - in particular if the GUI app and the Windows service run at the same time, but must not execute the same task twice.
  17. Thank you for all your answers! I have used memory mapped files in the past, which works just fine in many situations, so this is definitely among the options. I'm also going to explore pipes, which I am not very familiar. Interesting idea! Console output is of course the most simple solution, but I did not think of console input. I like this idea because of its simplicity. Because back in my mind (not yet on the map) is the idea to make the execution part platform-independent from the beginning. If that requires a completely separate GUI part for MacOS/Linux (no plans for iOS/Android here) or can be done in one FMX app, is another story.
  18. I'm trying to get my MacOS app notarized and have applied for an Apple Developer ID certificate, which has been issued, downloaded, etc. Well, in the process of trying to get this thing to work I'm now completely stuck. Delphi tells me that when deploying the app, there are ambiguous certificate matches. Indeed there are: Xcode shows me that there are 2 Developer ID certificates for my company. When logging in to developer.apple.com, there are even three... Please don't ask me how I managed to add them (I don't remember what I did all day today in order to get it working). Question: How do I get rid of the duplicate certificates? There's no "Remove" button anywhere.
  19. Alexander Halser

    MacOS: How to remove ambiguous Developer ID certificates?

    Thanks, Doug! Please tell me how to do that, and I'll be eternally grateful. Apple documentation says, that in order to revoke a certificate, you must contact product-security@apple.com. They find themselves not responsible and have redirected me to Apple Developer support. But support doesn't feel responsible either and suggested to contact product-security@apple.com. That email conversion has been going back and forth for more than a week now. No result yet. Maybe I should contact Embarcadero and ask them to build a new version of Delphi, that handles ambiguous certificates better. Or does it already? If Delphi did not specify the developer ID certificate by name, I could just use the existing one(s) and don't care about duplicates.
  20. Alexander Halser

    MacOS: How to remove ambiguous Developer ID certificates?

    Funny you say that, Sherlock! I did. And they answered. Do you want a bonmot? Apple responded: Uhm. Additional certificates?
  21. On MacOS when using a TMainMenu that integrates into the Apple system menu bar, sub-menus automatically close the entire menu when clicked, as illustrated in the screenshot. My configuration: Delphi 11 MacOS Big Sur Before I get into this really deep, could someone please confirm (or not) that this is a Delphi bug? Ideally with Delphi 11 plus an older version. Steps to reproduce the issue: Create a new project Drop a TMainMenu on the form Add several menu items with subitems No onclick handlers required, just go and run on MacOS This bug occurs on the native Apple menu only. The bug occurs with all menu items that represent a submenu. There's no such problem with TPopupMenu and there's no problem on Windows with TMainMenu at all.
  22. Alexander Halser

    MacOS bug: TMainMenu subitems auto-close on click

    Wow, you are right! Apple's Terminal app does have direct click handlers for some submenu items. Well, if Apple does it, it must be a feature and can't be a bug, can it? Now we've to find a way in Delphi to make this feature optional...
  23. Alexander Halser

    iOS 15.1

    Update: Reformatted the Mac, installed maOS Big Sur, an older version of Xcode. Things now work as advertised with Delphi 11. But I am wondering what the underlying problem is and if anyone has managed to make this configuration work. The Mac is an M1 (2020), not an Intel machine. This configuration works: Delphi 11 plus November and January patch Hardware: M1 (2020) Mac running macOS Big Sur Xcode 13.2 Not working configuration: Delphi 11 plus November and January patch Hardware: M1 (2020) Mac running macOS Monterey Xcode 12.5.1 / 13.0 / 13.2 / 13.4.1
  24. Alexander Halser

    iOS 15.1

    Following... I have the same problem with macOS and macOS ARM. Current config: Delphi 11 plus November and January patch MacOS Monterey 12.4 Xcode 13.4.1 (replace with 12.5.1, 13.0, you name it, all combinations tried)
  25. Alexander Halser

    MacOS: Library not loaded: ?^???

    Thread closed. My problem is almost identical with the one described here: iOS 15.1 - FMX - Delphi-PRAXiS [en] (delphipraxis.net) The switch from Delphi 10.4 to 11 helped to make some tiny progress and get the remote debugging to work. And the remote debugger tells me a bit more than question marks, it says: dyld[7422]: Library not loaded: \x90\x81\x17\x06-\xb4 Process MacTest (7422)
×