Jump to content

Incus J

Members
  • Content Count

    90
  • Joined

  • Last visited

Community Reputation

3 Neutral

Technical Information

  • Delphi-Version
    Delphi 10.4 Sydney

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Incus J

    Choose a Folder dialog

    FMX.Dialogs function SelectDirectory(const Caption: string; const Root: string; var Directory: string): Boolean; Thank you f.m - that's exactly what I'm looking for!
  2. Incus J

    Choose a Folder dialog

    Thank you Remy, Wil, f.m, The code I found online is the same fmxexpress example Wil mentions above, so I've been playing around with it. If I comment out the following block, then it works without crashing the app: if ADir <> '' then begin LInitialDir := TNSURL.Create; LInitialDir.initFileURLWithPath(NSSTR(ADir)); LOpenDir.setDirectoryURL(LInitialDir); end; The crash was occurring on LInitialDir.initFileURLWithPath(NSSTR(ADir)); and when I stepped through the code ADir appeared to be '' empty, so I'm not sure how this block was executing at all. I guess without this block I'm losing the capability for specifying an initial starting folder. I also get a warning that NSSTR is deprecated, but the suggested replacement StrToNSStr is not recognised. Is there an easy way to query which system unit a function might be in?
  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. TMyClassType = class of TMyClass; Can the metaclass type TMyClassType be passed into a function as a parameter? TMetaClass...? function CreateAnObjectByClassName(ClassName:string; BaseClass:TMetaClass..?):TPersistent; begin result := BaseClass(GetClass(ClassName)).Create; end; If that's possible, then I can have the caller provide the base class (the ancestor which introduced the virtual constructor) like this: object := CreateAnObjectByClassName('TMyClass2', TMyClassType); I'm not sure what type BaseClass would be - I don't think it's just a TClass.
  5. Thank you Stefan - I'll take a look at that too - looks like a different approach. Seems quite complex at a glance.
  6. Thank you Remy - I'll give that a try! From what you've said, I'm guessing it is not going to be possible to make a 'very general' CreateAnObjectByClassName function, because of the necessity to hard code the TMyClassType cast?
  7. I have a class descended from TInterfacedPersistent like this: type TMyClass=class(TInterfacedPersistent,IMyInterface); …and several classes descended from this, all registered with RegisterClasses([TMyClass1, TMyClass2, …etc…]); I’d like to make a very general function to create instances of these (and other classes) at runtime, by simply passing in a string containing the class name: function CreateAnObjectByClassName(AClassName:string):TPersistent; begin result := GetClass(AClassName).Create; end; This kind of works, except that when creating the object, it looks like its ancestor TObject.Create constructor is called, instead of TMyClass2.Create; When I step through the code at runtime I end up at constructor TObject.Create; in the System unit. As a result the newly created object is not initialised correctly. Having just the class name (e.g. 'TMyClass2') as a string, how can I create a genuine instance of that class, as if I had hard coded TMyClass2.Create; ?
  8. Incus J

    How to obtain a path to a folder inside the app bundle?

    That's very useful - thank you!
  9. Incus J

    How to obtain a path to a folder inside the app bundle?

    I've found a post from April 2019 by Dave Nottage that looks like it might be adapted to do the trick: // Bit of a "hack" to get the exact paths of the pdf files deployed to /Contents/Resources/Startup LSourceName := TPath.GetDirectoryName(ParamStr(0)); LSourceName := TPath.Combine(StringReplace(LSourceName, '/MacOS', '', []), 'Resources/Startup/' + AFileName); ...seems to work OK 🙂. Would make a nice addition to the built in TPath class: class function TPath.GetAppResourcesPath:string; var appPath:string; begin appPath:=TPath.GetDirectoryName(ParamStr(0)); result:=TPath.Combine(StringReplace(appPath,'/MacOS','',[]),'Resources/Startup/'); end; ...though it would need adapting further to produce a sane result on all supported platforms.
  10. I’ve added a folder of sample images to an FMX application. They appear listed in the Deployment manager. When the app is deployed on macOS, these images are included inside the application bundle in Contents/Resources/Startup/ How can I obtain a normal directory path to this internal folder, for internal use by the application? For example is there something like TPath.GetInternalResourcesFolder; ? I’m looking for the path to the folder only, rather than a full path to one single image file, so my app can load up all sample images in that folder when it starts up, without me having to reference each image filename individually in code.
  11. I've just tried your suggestion, and it works perfectly. I don't think I would ever have thought to look under .Model for a SelectText method. It even scrolls the line into view, and it works when the memo is ReadOnly too. Thank you Lajos!
  12. Incus J

    Calculate the width of a Popup Menu?

    I'd like to calculate the width of a Popup Menu before it is displayed, so that I can position and align it accurately when I call its .Popup(x,y) method. function CalcPopupMenuWidth(popup : TPopupMenu) : single; var i : integer; w : single; item : TMenuItem; begin result := 0; for i := 0 to popup.ItemsCount-1 do begin item := popup.Items[i]; w := popup.Items[i].Width; if w > result then result := w; end; end; The above approach iterates over the individual menu items, to determine the widest item. It almost works, in that it calculates the width correctly, but only after the Popup Menu has been displayed once. If the Popup Menu has never been displayed (yet) then this code always returns a value of 50. I'm guessing maybe that's a default width for a TMenuItem, which gets updated with the actual width shortly before it is displayed. How can I calculate the dimensions of a Popup Menu before displaying it?
  13. Incus J

    TButton : How to display the assigned Popup Menu?

    I'll go with the above code for now, until I find a better way to do it. I'm just trying to figure out how to calculate the width of the Popup Menu before it appears, so I can align it centrally or right-aligned. At the moment it displays left aligned (to the left edge of the button) - right aligned to the right edge of the button would be particularly useful as the button is positioned at the very right hand side of the form. I could do with a property like : PopupMenu.Width; //no such property TMenuItem has CalcSize and CalcRenderSize so perhaps I could iterate over the Items to determine a value for the widest Menu Item.
  14. Incus J

    TButton : How to display the assigned Popup Menu?

    TButton.DropDownMenu looks to be the right thing to use for a VCL application. The FMX TButton doesn't have that property though, so perhaps FMX lacks this capability.
  15. Incus J

    TButton : How to display the assigned Popup Menu?

    Yes, I'm probably trying to use it for something other than intended (this happens to me quite a lot). Still, click a button for a menu to appear, must be a fairly common requirement. I'll see whether FMX offers another control better suited for this. Ah - I've just seen your last reply, thank you - I will take a look.
×