Jump to content

Incus J

Members
  • Content Count

    157
  • Joined

  • Last visited

Everything posted by Incus J

  1. Incus J

    TWebBrowser Edge Engine Unavailable

    I'm unsure how to get FMX TWebBrowser to use the Edge engine instead of the older IE engine. I've set its WindowsEngine property to EdgeOnly (Delphi 11). But I'm seeing a runtime error "Edge browser engine unavailable". Edge is installed. I think in the past a .dll file was required (?) I'm not sure whether this is still the case. After a Google search I looked in Delphi's Redist folder - but can't see anything that looks promising there. (On a vaguely related note - is there a way to z-order web controls in FMX? I'd like to place some controls so that they partially overlap TWebBrowser - appear on top of the web content - but they get clipped.)
  2. When I create and run a Windows Store App, my application icon looks very small on the taskbar, compared to other application icons. It appears to be surrounded by a grey background too, instead of transparent. After reading around a bit, I suspect I'm getting a 'plated' icon. How can I get an 'unplated' app icon instead? I'm using Delphi Rio 10.3 to generate the appx file, and have provided the required UWP 44x44 and 150x150 icons, in addition to the main app icon (which contains 16x16, 24x24, 48x48 and 256x256 images) in Delphi's Options.
  3. Incus J

    Choose a Folder dialog

    Does Delphi 10.4 FMX have a built in routine or component to display a Choose a Folder dialog? I can see dialog components to open and save a file, but not to select a folder. If there isn't anything built in, how might I achieve this? I'm looking for something that will work on both Windows and macOS. I have found some code online, and the Windows side of it works, but it looks fairly elaborate, and the macOS code crashes the app with Exception class 6. So perhaps there is an easier approach using existing routines. I'm running 10.4 Update 1 at present.
  4. I'm reading up on interfaces, and trying to understand when a reference counted object will be freed. var MyObject:IMyInterface; begin if TSomeclass.CreateAndReturnAnObject(var MyObject) then begin //Do something with MyObject end; end; //MyObject is freed automatically here? If CreateAndReturnAnObject creates an object of type TMyInterface (which implements IMyInterface) and returns it via the MyObject parameter, will the object still exist immediately after CreateAndReturnAnObject returns - or will it have fallen out of scope? How about if I omit 'var' from the parameter? Since MyObject starts of as nil, I'm guessing it can't have its reference count auto-incremented until after it is created, so will it cease to exist once CreateAndReturnAnObject completes, in which case I can't 'Do something with MyObject', or does the compiler know to keep it around somehow?
  5. Incus J

    Interface Reference counting

    No. It would not return anything at all, because the parameter is being passed in by value, not by var reference. Ah - so that is a key difference to, for example, passing in an parameter of type TStringlist - even without 'var' I think an object such as TStringlist gets passed by reference (?)
  6. TWebBrowser and TEdgeBrowser VCL components have a property named UserDataFolder/EdgeUserDataFolder which sets a folder for the Edge engine (WebView2) to write session data. TWebBrowser FMX component does not expose this property, and the component defaults to using the app executable folder to write session data. That default value is problematic because the Program Files folder where the app is installed to is not writable. So I need to set a different location. I know the UserDataFolder property is in there somewhere, so I'm hopeful that I can surface it somehow. But I'm having trouble navigating through the FMX.WebBrowser code since it branches and calls services depending on the platform and engine - FindDeclaration only gets me so far. How can I access and set the Edge UserDataFolder when using the FMX TWebBrowser component?
  7. Incus J

    How to set FMX TWebBrowser UserDataFolder?

    A global setting sounds promising. FMX.WebBrowser.Win.TGlobalEdgeBrowserSettings.UserDataFolder:='(my path)'; That's giving me an error of Undeclared identifier TGlobalEdgeBrowserSettings at the moment. That class doesn't seem to be present in the FMX.WebBrowser.Win unit. I'll have a look around for it elsewhere - maybe it's moved in 11.3?
  8. Incus J

    Interface Reference counting

    So much to learn - and so many opportunities to make mistakes that will still compile while unwittingly shooting myself in the foot 🙂 I didn't even know an untyped var parameter was permitted - in my specific case it would be typed, as below, but I can see myself doing something like accidentally specifying a type of TMyInterface instead of IMyInterface due to a momentary distraction, tiredness or loss of focus. Yes, sorry - that's a typo on my part, should have been: if SomeclassInstance.CreateAndReturnAnObject(MyObject) then begin My understanding now is that the first version of the declaration below (with var) would successfully auto-reference count and retain MyObject on return, whereas the second version would end up returning (a pointer to?) an instance of MyObject that had just been freed: function TSomeclass.CreateAndReturnAnObject(var MyObject:IMyInterface):boolean; begin MyObject:=TMyInterface.Create; result:=true; end; //MyObject retained. vs function TSomeclass.CreateAndReturnAnObject(MyObject:IMyInterface):boolean; begin MyObject:=TMyInterface.Create; result:=true; end; //MyObject vapourises here. When an interfaced object (e.g. MyObject) goes out of scope and is automatically freed, does it get nil assigned to it, or does it behave the same as non-interfaced objects which keep a dangling pointer to the freed instance after SomeObject.Free (unless SomeObject.FreeAndNil is used to free it)?
  9. Incus J

    Interface Reference counting

    Thank you - that's a good clear explanation. I'll have a go at your suggestion and step through with the debugger to see what actually happens. That does make sense, though I like to have a boolean return value to test success against in a compact way: if TSomeclass.CreateAndReturnAnObject(var MyObject) then begin vs MyObject := TSomeclass.CreateAndReturnAnObject; if Assigned(MyObject) then begin ...but perhaps there's a better approach?
  10. Incus J

    How to set FMX TWebBrowser UserDataFolder?

    Yes, with VCL TWebBrowser EdgeUserDataFolder defaults to a path beginning with %LOCALAPPDATA%...etc... and this can be customised. Unfortunately with FMX TWebBrowser the default seems to be the folder of the app executable instead. So I'm trying to find a way to surface and set the underlying UserDataFolder property (defined in TEdgeBrowserHelper) for an FMX TWebBrowser. That way I can: Set the FMX TWebBrowser engine to IEOnly at design time At runtime my app can set Edge UserDataFolder to my new desired (writable) path - and only then: Switch the engine to EdgeOnly so it will initialize WebView2 with my new path. I'm not sure how to (re-)call it. Note that as things initially stand it will not have been called successfully yet.
  11. Incus J

    How to set FMX TWebBrowser UserDataFolder?

    If I subclass FMX.TWebBrowser e.g. TWebBrowserPlus=class(TWebBrowser) can I surface and access Private member FWeb ? I thought perhaps I could simply redeclare FWeb like this: type TWebBrowserPlus=class(TWebBrowser) private FWeb: ICustomBrowser; //redeclare private ancestor field to surface it in my subclass...? ...but that doesn't seem to work.
  12. Incus J

    How to set FMX TWebBrowser UserDataFolder?

    That would make sense. So far I've navigated: TWinNativeWebBrowser.CreateHandle calls TWinNativeWebBrowser.CreateWebView which calls TWinNativeWebBrowser.InitializeWebView which calls CreateCoreWebView2EnvironmentWithOptions I've yet to find the bit where FMX.TWebBrowser calls TWinNativeWebBrowser.CreateHandle - but there must be a connection between those two somewhere. I've noticed there's a TEdgeBrowserHelper = class helper for TWinNativeWebBrowser which has: property UserDataFolder: string read GetUserDataFolder write SetUserDataFolder; ...that's the property I'm after I think. Now I need to figure out how to access that property from my FMX application, when all I have is my instance of FMX.TWebBrowser on a form. Could I do something like TMyWebBrowser=class(TWebBrowser) and then cast TMyWebBrowser(WebBrowser1) to get at its internals?
  13. var fmt:TFormatSettings; dt:TDate; begin fmt:=TFormatSettings.Create('en-GB'); fmt.DateSeparator:='/'; fmt.ShortDateFormat:='mmm/d/yyyy'; dt:=StrToDate('Feb/7/2023',fmt); end; I'm having trouble converting dates in a string to TDate. The above test code raises an EConvertError - 'Feb/7/2023' is not a valid date. Where am I going wrong?
  14. Incus J

    Puzzled by StrToDate

    Thank you for the suggestions and code example - I will have an explore. Yes I agree TStringlist is slightly heavy for the job - though I do find it useful when stepping through code in the debugger as there is a visualiser to display the contents. I started out with a dynamic array, but got confused trying to pass the array into and out of subroutines, and the TArray type seemed to lack useful methods such as myArray.IndexOf ...basically my lack of experience with arrays led me to switch to TStringlist to save time! My main reason for rolling my own is that I've discovered the built in StrToDate function differs in behaviour between Delphi versions - so I want to create my own function that I can rely on to maintain the same behaviour going forward.
  15. Incus J

    Puzzled by StrToDate

    Yes - at the moment I have a private InitialParse subroutine that basically attempts to grab three date components from whatever string it is fed, and drops them into a TStringlist (e.g. from 'Feb 7th, ''23' it will extract 'Feb' and '7th' and '23'). What to do with those three components (how to interpret them) is decided later. It works, but if necessary this subroutine could be made much stricter in terms of what it will accept as input. class procedure TDateUtils.InitialParse(s: string; var ts:TStringlist); {Pull three components from the date string.} var i:integer; c:char; bSkip:boolean; sPart:string; begin sPart:=''; bSkip:=true; for i:=1 to Length(s) do begin c:=s[i]; if c.IsLetterOrDigit then begin if bSkip then begin bSkip:=false; AddPart(ts,sPart); end; sPart:=sPart+c; end else bSkip:=true; end; AddPart(ts,sPart); while ts.Count<3 do ts.Add('0'); //Ensure 3 date components. end; class procedure TDateUtils.AddPart(var ts:TStringlist; var s:string); {Add a complete component e.g. '7th' to the list.} begin if s<>'' then begin if ts.Count<3 then ts.Add(s); s:=''; //Reset. end; end; It could also handle the 'more than three components present' situation more efficiently.
  16. When I try to run (deploy) an FMX macOS app from Alexandria 11.2 I get the following error message: "Unable to start LLDB kernel: 'Symbolic link target does not exist: /Applications/PAServer-22.0.app ... Xcode.app ... Versions/3.8/Python3. Please make sure that the target exists or update the link to point to the new location of the Python 3 installation'. On the Windows side I have Alexandria 11.2 on a Windows 10 VM (VMWare Fusion 11.5.6). On the Mac side I have PAServer22 Version 13.2.11.7 on macOS Catalina 10.15.7 Pretty sure I had this working in an earlier release of Alexandria(?). Everything runs fine with Delphi 10.4.1 and PAServer21 on the same system. I'm guessing I need Python 3, or if that's already present, some way to tell PAServer where Python 3 is located? Edit: A look inside the package contents of Xcode.app reveals Python 3 is located in ... Frameworks/Python3.framework/Versions/3.7/Python3 So 3.7 vs 3.8 - I wonder whether it actually requires 3.8 or whether there's a way to point it to 3.7 ?
  17. 🙂 Updating to a different version of Xcode seems to have solved it. Finding a suitable combination of Delphi, PAServer, Xcode, macOS and Fusion versions that will all play nicely together can be tricky.
  18. The IDE copied a PAServer package into the scratch-dir folder for me, which I then installed - so yes it likely is the one from the Delphi program files folder. I'm currently downloading a version of Xcode that I think includes Python 3.8 and still supports Catalina. Thank you for the link - I'll try the package you suggested from the website, as that might be a quick fix - before I resort to trying to update Xcode.
  19. Incus J

    Puzzled by StrToDate

    I've created a general purpose string to date function that is quite tolerant and can parse a variety of date strings using just a couple of parameters like this: 'February 7th, ''23', TDateOrder.doMDY Its current tolerance for variations (e.g. 'Feb 7 2023' '02/07/23' "7th.02 '23") risks it getting creative if fed a string that isn't really a date, but I can tighten it up later if it needs to be stricter (famous last words - what could possibly go wrong).
  20. Incus J

    Puzzled by StrToDate

    I agree FMX tends to change more between versions, and it can be a challenge to keep up. But to clarify (hopefully) - my development system is HiDPI and I find when I open any existing VCL form in Alexandria it modifies the position and dimension values (the actual stored x/y/width/height) of all objects on the form. The forms then no longer work on older versions of Windows (e.g. 7/8) - so I avoid Alexandria for VCL projects. Don't get me wrong - I love the look of the HiDPI IDE in Alexandria, and FMX forms behave fine in it, but feel I can not use it for VCL projects. I may have strayed off topic.
  21. Incus J

    Puzzled by StrToDate

    Thank you for all the responses. I'm in 10.4.1 and so far can't get either mmm nor MMM to parse the months - but this is an FMX project, so I can probably risk taking it into 11 Alexandria. My general take away from this is that the behaviour of Delphi's built in StrToDate function differs between versions, and might be buggy. I think I'm going to roll my own StrToDate function, since ideally I'd like to parse dates containing characters like commas too, such as "Feb 7, 2023". Interestingly I found that VarToDateTime (variant to date time) parses dates with commas OK on Windows, but sadly not on macOS - so I'm guessing the OS provides the conversion for that function.
  22. I recently installed Delphi 10.4 and migrated my settings across from Delphi 10.3 via a .idesettings file. After that I uninstalled Delphi 10.3 as I figured I wouldn't need the previous version any more. This might have been a mistake: All the Windows 10 file associations for Delphi (.dproj .dpr etc.) disappeared. How can I reinstate them - does Delphi have a repair option?
  23. I’m perhaps a bit late with this observation, but notice that the Association of Software Professionals organisation (formerly Association of Shareware Professionals) was dissolved at the end of 2021 - and the PAD 4.0 file specification released to the public domain in January 2022. I was never a member of the ASP, but used PAD 3.11 files to publish information about my software online for years. Kind of parted company when PAD 4.0 migrated everything behind closed doors. I still maintain PAD 3.11 files for some software, in case any download sites still poll them for updates. Just wondered what people’s thoughts were, and what any modern alternative to PAD files might be these days?
  24. In OverbyteIcsHttpServ, the error procedures such as THttpConnection.Answer404 are called from various places in the code and have hard coded HTML. I'd like to serve my own error document instead. Is there a built in mechanism to supply a custom HTML error document for errors such as 404, 403 ?
  25. Perfect - I had missed the virtual nature of Answer404 - Thank you!
×