Jump to content

Gary

Members
  • Content Count

    128
  • Joined

  • Last visited

Everything posted by Gary

  1. Gary

    MyDAC : Unknown column error

    +1 for JonRobertson & ertank I use UniDac as well and you use the "AddField" Menu selection not the "NewField" Menu. I am always forgetting to set the Options.KeepDesignConnected property as well.
  2. Gary

    Advise the component for editing tables

    @Shrinavat Looks great! Years ago I used X-Data and one thing I miss is the master Detail in grid. Looks like Steema has this, and at an affordable price. While the Rosinsky DBGrid is very capable the show stopper for me are the Dialogs that he has produced. Your end users can customize the grid at runtime as much as you can at design time. Extremely impressive.
  3. Gary

    Advise the component for editing tables

    Not Free only $70.00 and includes source Delphi and C++ Builder VCL components - DBGrid, DBTreeView, DBCheckListBox, StringGrid, HTML Label, HTML ListView (rosinsky.cz)
  4. Compare your library path for 32 and 64 bit components Tools->Options->Language->Delphi->Library
  5. Hello all, How do you test if a FDConnection using SQLite is connected to an actual Database? If I drop a FDConnection on a form, set it's DriverName SQLite, leave the Params->Database property empty and connect there is no error. This code shows the "Connected' Message procedure TForm1.Button1Click(Sender: TObject); begin if FDConnection1.Connected then ShowMessage('Connected'); end;
  6. Hello all, I am trying to separate my UI from the rest of my application. I want to use an interfaced listener on my main form and pass a reference to it around to parts of the application that need input from the user. I have no problem with the InputBox or MsgDialog as they don't take too many parameters, however I want to use TMSTaskDialog as well (Different listener since requires 3rd party). The problem I am having is that the TaskDialog has so many options that I want to pass a record with all the parameters. I only have a problem with TStrings. I get memory leak on close. Work in progress but here are the relevant parts. TTaskDialogParams = record DisplayedButtons : TPsTaskDialogDisplayedButtons; Title: String; Instruction: string; Content: string; Options: TPsTaskDialogOptions; CustomButtons : TStringList; Icon: TPsTaskDialogIcon; FResultCallBack: TProc<TTaskDialogReturnParams>; procedure Clear; class operator Initialize (out Dest: TTaskDialogParams); class operator Finalize (var Dest: TTaskDialogParams); end; IPsFNCTaskDialogUIListener = interface ['{BA6ABA84-F3EE-4421-856F-42E76C878D3B}'] procedure ExecuteDialog(const Params : TTaskDialogParams); end; procedure TTaskDialogParams.Clear; begin CustomButtons.Clear; CustomButtons.Free; end; class operator TTaskDialogParams.Finalize(var Dest: TTaskDialogParams); begin // Dest.CustomButtons.Free; end; class operator TTaskDialogParams.Initialize(out Dest: TTaskDialogParams); begin Dest.CustomButtons := TStringList.Create; end; In listener I set string params by enumerating through the recordsStringList. procedure TPsFNCTaskDialogUIListener.ExecuteDialog(const Params : TTaskDialogParams); begin SetDialogParams(Params); FTaskDialog.Execute; Params.Clear; // FTaskDialog.CustomButtons.Clear; end; Then show it procedure TPsFNCTaskDialogUIListener.ExecuteDialog(const Params : TTaskDialogParams); begin SetDialogParams(Params); FTaskDialog.Execute; Params.Clear; // FTaskDialog.CustomButtons.Clear; end; Some code in there is things I have tried to no avail. Any help would be appreciated. I tried this before and gave up and used an Interfaced Class instead.
  7. From FastMM --------------------------------2023/12/28 22:32:03-------------------------------- A memory block has been leaked. The size is: 84 This block was allocated by thread 0x6A4, and the stack trace (return addresses) at the time was: 9371E6 [System.pas][System][@GetMem$qqri][4960] 938957 [System.pas][System][TObject.NewInstance][18324] 93905A [System.pas][System][@ClassCreate$qqrpvzc][19654] 9F9C30 [System.Classes.pas][System.Classes][Classes.TStringList.Create][8121] 94C231 [FastMM4.pas][FastMM4][UpdateHeaderAndFooterCheckSums$qqrp29Fastmm4.TFullDebugBlockHeader][9153] 94D214 [FastMM4.pas][FastMM4][DebugGetMem$qqri][9731] EA116F [int.PsFNCTaskDialogUIListener.pas][Int.PsFNCTaskDialogUIListener][Psfnctaskdialoguilistener.TTaskDialogParams._op_Initialize][66] 108E6E5 [PsFNCTaskDialogUIListener.pas][PsFNCTaskDialogUIListener][TPsFNCTaskDialogUIListener.SetDialogParams][32] 108E827 [PsFNCTaskDialogUIListener.pas][PsFNCTaskDialogUIListener][TPsFNCTaskDialogUIListener.ExecuteDialog][47] 108F3C9 [USender.pas][USender][TfrmSender.tbtnTaskDialogClick][77] C0CF34 [FMX.Controls.pas][FMX.Controls][Controls.TControl.GetHeight][5512] The block is currently used for an object of class: System.Classes.TStringList The allocation number is: 296325 Current memory dump of 256 bytes starting at pointer address 7E6DB770: 20 B9 9C 00 00 00 00 00 50 B9 30 7F 6C E3 1B 7F 00 00 00 00 00 00 00 00 2C 00 22 00 3D 00 0E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 8C AF 78 80 80 80 80 80 80 80 80 00 00 00 00 51 BB 6D 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 85 04 00 9F A8 93 00 3C AD 93 00 A2 CC 93 00 F2 E6 08 01 27 E8 08 01 C9 F3 08 01 34 CF C0 00 9D AB C0 00 77 D6 CB 00 F4 B2 C0 00 D4 65 E8 00 A4 06 00 00 A4 06 00 00 02 72 93 00 59 A9 93 00 28 C5 93 00 E2 D3 C0 00 39 8B 93 00 6E 89 93 00 A5 90 93 00 2E 9A CB 00 B3 57 E5 00 ED 92 93 00 45 C0 E8 00 48 00 00 00 B0 04 02 00 CB 3D A4 8E 8C 7C 0C 01 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 . . . . . P 0 l . . . . . . . . . , . " . = . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x . . . . Q m ~ . . . . . . . . . . . . . . . . . . . < . . . . ' . . . . 4 . . w . . e . . . . . . . . r . Y . ( . . 9 . n . . . . W . . E . H . . . . . . = | . . --------------------------------2023/12/28 22:32:03-------------------------------- A memory block has been leaked. The size is: 20 This block was allocated by thread 0x6A4, and the stack trace (return addresses) at the time was: 9371E6 [System.pas][System][@GetMem$qqri][4960] 93A89F [System.pas][System][@NewUnicodeString$qqri][26024] 93AD3C [System.pas][System][@UStrAsg$qqrr20System.UnicodeStringx20System.UnicodeString][26946] 9F6F30 [System.Classes.pas][System.Classes][Classes.TStrings.Create][6729] 9F9C3D [System.Classes.pas][System.Classes][Classes.TStringList.Create][8122] 94D214 [FastMM4.pas][FastMM4][DebugGetMem$qqri][9731] EA116F [int.PsFNCTaskDialogUIListener.pas][Int.PsFNCTaskDialogUIListener][Psfnctaskdialoguilistener.TTaskDialogParams._op_Initialize][66] 108E6E5 [PsFNCTaskDialogUIListener.pas][PsFNCTaskDialogUIListener][TPsFNCTaskDialogUIListener.SetDialogParams][32] 108E827 [PsFNCTaskDialogUIListener.pas][PsFNCTaskDialogUIListener][TPsFNCTaskDialogUIListener.ExecuteDialog][47] 108F3C9 [USender.pas][USender][TfrmSender.tbtnTaskDialogClick][77] C0CF34 [FMX.Controls.pas][FMX.Controls][Controls.TControl.GetHeight][5512] The block is currently used for an object of class: UnicodeString The allocation number is: 296326 Current memory dump of 256 bytes starting at pointer address 7F1BE360: B0 04 02 00 01 00 00 00 02 00 00 00 0D 00 0A 00 00 00 AA 4B E7 F7 80 80 00 00 00 00 A1 FF 1B 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5F BF 04 00 E6 71 93 00 57 89 93 00 5A 90 93 00 7F 21 E8 00 12 EE E8 00 31 8A E8 00 1F 40 E8 00 63 40 E8 00 6E EE E8 00 62 DF A0 00 6B 8A 93 00 A4 06 00 00 A4 06 00 00 02 72 93 00 75 89 93 00 A5 90 93 00 E5 21 E8 00 6B 8A 93 00 35 38 E8 00 02 72 93 00 75 89 93 00 A5 90 93 00 F7 10 A8 00 6B 8A 93 00 14 00 00 00 DC E2 E6 00 4C 29 7E 8F 8C 7C 0C 01 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 B3 D6 81 70 00 00 00 00 C1 E9 1B 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9F BF 04 00 E6 71 93 00 57 89 93 00 5A 90 93 00 73 35 E3 00 1B 35 E3 00 51 C4 E2 00 13 C5 E2 00 3E 3F E8 00 D1 F1 E8 00 0A 3A E8 00 02 72 93 00 . . . . . . . . . . . . . . . . . K . . . . . . . . . . . . . . . . . . . . . _ . . q . W . Z . ! . . . 1 . . @ . c @ . n . b . k . . . . . . . . r . u . . ! . k . 5 8 . . r . u . . . . k . . . . . . L ) ~ | . . p . . . . . . . . . . . . . . . . . . . . . . . q . W . Z . s 5 . . 5 . Q . . . > ? . . . : . . r . --------------------------------2023/12/28 22:32:03-------------------------------- This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer): 13 - 20 bytes: UnicodeString x 1 69 - 84 bytes: System.Classes.TStringList x 1 Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".
  8. Sorry copied same block twice Here is the other part procedure TPsFNCTaskDialogUIListener.SetDialogParams(Params: TTaskDialogParams); begin ClearDialog; FTaskDialog.Title := Params.Title; FTaskDialog.Instruction := Params.Instruction; FTaskDialog.Icon := TTMSFNCTaskDialogIcon(Params.Icon); FTaskDialog.Options := TTMSFNCTaskDialogOptions(params.Options); for var s : String in params.CustomButtons do FTaskDialog.CustomButtons.Add(s); end;
  9. Gary

    Help with Query at run time

    @Columbo This is such a great sample app! Fine the way it is but simple enough that you can use it to experiment as you move forward. How about letting your users see your Dino's in the order they want? procedure TfrmDino.Reorder; begin tblPLife.Close; if rgSort.ItemIndex = 0 then tblPLife.SQL[1] := 'ORDER BY record;' else tblPLife.SQL[1] := 'ORDER BY name;'; tblPLife.Open; LoadList; LoadImages; end;
  10. Gary

    Free profiler?

    Sampling Profiler - DelphiTools
  11. Gary

    Help with Query at run time

    Setting designtime components can be very helpful, try this: Open the connection and table. Right click table and select FieldsEditor... Right Click FieldsEditor and select AddAllFields Notice the field objects are added to the form definition (tblPLifename) Click the dropdown of the FieldName on your DBEdits and notice you have a list to choose from, no typing in the field name where simple typo can derail you. Also you can now do this: No more tblPLife.FieldByName('name').AsString
  12. Gary

    Help with Query at run time

    I redownloaded the finished program and it works fine! I must have tried one of the others.
  13. Gary

    Help with Query at run time

    BTW Congratulations on your first project, and I have to say it's a beauty. Most first projects are dull and boring. However.... Your final project crashes on my computer, it will only run on your system! Reason is a common mistake that has bitten me many times. Your Database path is still hard coded to your system. If you proudly load it on a flash drive (as you should) and show it, it will crash(very embarrassing). See the procedure OpenConnection in my earlier post. You still need it hard coded to work with it in design mode, so the habit I have gotten into is to always set Connected to False and Database to an empty string first thing in the OnCreate event. Then make sure to use runtime function to get Database location before connecting.
  14. Gary

    Help with Query at run time

    First param is a string so name needs quotes 'name' You can leave the last param empty, but then they have to match exactly. That works here where you are selecting from a list, however I like to be more forgiving as to case as it can frustrate users if values are capitalized and they just type lowercase. You can eliminate both iSelect and sName and the assignment calls like this: tblPLife.Locate('name', lbxData.Items[lbxData.ItemIndex], [loCaseInsensitive]); Link is for 12.0 change Athens to Alexandria, but in this case no different Data.DB.TDataSet.Locate - RAD Studio API Documentation (embarcadero.com) Data.DB.TLocateOptions - RAD Studio API Documentation (embarcadero.com)
  15. @Uwe Raabe That sounds good, but it simply is not the case unless something has changed. Some time ago I decided after having paid for the Pro version as a hobbyist, that I would be satisfied with the version I was running and did not renew my subscription. 2 months later I changed my computer name from the default Desktopxxx to a more recognizable name. That invalidated my license, and I needed an install bump. I could not get Embarcadero to do it no matter who I talked to. They eventually allowed me to renew the license at the renew rate instead of full price, even though I was outside the grace period. Of course they backdated it 2 months as well. I consider Delphi ransomware, at least the renewal (Ransom) is not that high. I prefer Delphi to anything else I have tried. It's far easier for someone without a formal computer science education, at least the connection between code and UI. Embarcadero's policy on this is reprehensible and probably illegal. Any company with an install limit policy should be required to allow their users to deactivate/reactivate installs. I have several other software programs that do just that, and even when I have forgotten to do that, a simple email to support to move the license gets a quick response, with a reminder to remember to do it myself 🙂 I even have an original Delphi 2009 Pro CD in the case with Codegear serial numbers on it that I cannot register.
  16. Gary

    Help with Query at run time

    I added a panel to the top image set align to all right width to 50 Caption -- font color clCream Panel color to your label's font color $0000023F (keep trying for exact match to your brown) and got rid of all borders. Add code to Panel OnClick JonRobertson's suggestion may be better to minimize the form but I don't have experience either. Add to top image OnMouseDown event for dragging procedure TfrmDino.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); const SC_DRAGMOVE = $F012; begin if Button = mbLeft then begin ReleaseCapture; Perform(WM_SYSCOMMAND, SC_DRAGMOVE, 0); end; end;
  17. Gary

    Help with Query at run time

    @Columbo My 2 cents: Beautiful UI BTW. I don't like to do anything in a form's OnCreate event that I don't have to, it has caused me trouble in the past as things may not always be created before I use them. Nor do I ever open Databases there, use the OnShow if you must, even better have a dedicated button. Break things down into separate procedures and assign them to events. I added a combobox for the search and implemented the search with a simple RecNo assignment. Things I changed it the Object inspector: Form WindowState = wsNormal Position = poScreenCenter CustomTitleBar = False // You cannot move it around or Min Max with this set true ComboBox DropDownCount = 15 //However many you want unit Dinobase_u; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Imaging.jpeg, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.ComCtrls, System.ImageList, Vcl.ImgList, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Phys.SQLiteDef, FireDAC.Stan.ExprFuncs, FireDAC.Phys.SQLiteWrapper.Stat, FireDAC.VCLUI.Wait, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.Client, Data.DB, FireDAC.Comp.DataSet, Vcl.DBCtrls, Vcl.Mask, Vcl.Buttons; type TfrmDino = class(TForm) pnlTitlebar: TPanel; Image1: TImage; pnlHeader: TPanel; Image2: TImage; lblName: TLabel; lblMeaning: TLabel; lblPronounce: TLabel; lblPeriod: TLabel; lblMainGroup: TLabel; pnlFooter: TPanel; Footer: TImage; lblSize: TLabel; lblLived: TLabel; lblDiet: TLabel; lblFossils: TLabel; PLTabSheet: TPageControl; TabSheet1: TTabSheet; SizeComp: TTabSheet; dinoImage: TImage; dinoSize: TImage; conPLife: TFDConnection; tblPLife: TFDTable; Datasource1: TDataSource; lblRecno: TLabel; btnExit: TBitBtn; dbeName: TDBEdit; dbeMeaning: TDBEdit; dbePronounciation: TDBEdit; dbePeriod: TDBEdit; dbeMainGroup: TDBEdit; dbeSize: TDBEdit; dbeLived: TDBEdit; dbeDiet: TDBEdit; dbeFossils: TDBEdit; dbmFactfile: TDBMemo; dbeRecno: TDBEdit; DBNavigator1: TDBNavigator; cbxSearch: TComboBox; procedure btnExitClick(Sender: TObject); procedure cbxSearchClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure tblPLifeAfterScroll(DataSet: TDataSet); private { Private declarations } procedure OpenConnection; procedure OpenTable; procedure LoadList; procedure LoadImages; public { Public declarations } end; var frmDino: TfrmDino; implementation {$R *.dfm} uses System.IOUtils, VCL.Dialogs; const DINO_DB = 'dino.db'; procedure TfrmDino.btnExitClick(Sender: TObject); //Exit Button begin Close; end; procedure TfrmDino.cbxSearchClick(Sender: TObject); begin //Search... is at ItemIndex[0] and we load the list from the table so //a 1 for 1 on the count so nop searching needs to be done just //set the Tables RecNo it is write as well as read property tblPLife.RecNo := cbxSearch.ItemIndex; //Set combobox back to Search... cbxSearch.ItemIndex := 0; //if you do not like the search box selected set focus to any control dbeName.SetFocus; end; procedure TfrmDino.FormShow(Sender: TObject); begin OpenConnection; OpenTable; LoadList; //Images will be loaded when record changes after this LoadImages; end; procedure TfrmDino.LoadImages; var lName : String; begin lName := tblPLife.FieldByName('name').AsString; // Load the dino image and display it dinoImage.Picture.LoadFromFile('dino_images\' + lName + '.jpg'); // Load the size image and display it dinoSize.Picture.LoadFromFile('dino_size\' + lName + '_size' + '.jpg'); end; procedure TfrmDino.LoadList; begin cbxSearch.Items.Clear; cbxSearch.Items.Add('Search...'); //Disable all data aware controls so the UI does not repaint //as we load the list tblPLife.DisableControls; try tblPLife.First; while not tblPLife.Eof do begin cbxSearch.Items.Add(tblPLife.FieldByName('name').AsString); tblPLife.Next; end; finally tblPLife.First; tblPLife.EnableControls; end; end; procedure TfrmDino.OpenConnection; begin conPLife.Params.Database := ExtractFilePath(Application.ExeName) + DINO_DB; try conPLife.Connected := True; Except on E: EDatabaseError do begin ShowMessage('Error connecting to: ' + conPLife.Params.Database + ': ' + E.Message); end; end; end; procedure TfrmDino.OpenTable; begin try tblPLife.Open Except on E: EDatabaseError do begin ShowMessage('Error opening table with: ' + E.Message); end; end; end; procedure TfrmDino.tblPLifeAfterScroll(DataSet: TDataSet); begin //if Controls are disabled we are loading the list and don't want //to load images if not tblPLife.ControlsDisabled then LoadImages; end; end.
  18. Gary

    Help with Query at run time

    I was able to get it. However it will throws an error when trying to open database. The database opens in DB Browser so it's a valid database. You should include the project files.
  19. Gary

    Help with Query at run time

    I think JonRobertson has identified the problem. In his post he recommends you use one dataset and one datasource. Do you have multiple dataset's? If you are still using the FDQuery with parameters, as well as a table that could be the problem. They have different use cases and mixing them will cause you frustration! The Parameterized query will only ever return one record. You cannot use a DBNavigator since there is only one record, there is no prior or next record, the one record is the first as well as the last. This is fine for searching a table. When your user presses the search button you can update your query from the edit and load the data as well as your images. However, with an interface like this how will your users see any other entries unless they know, and as you mentioned can spell the name they are looking for? You cannot navigate your database table with a parameterized query. If you managed to get this working with the query you have much more going on. For what you want you should use a Table or "Select *" in your query. Now your dataset will have all the records from the table and you can hook up a DBNavigator. As you use the buttons to move from one record to another the Dataset's (Table or Query since they both descend from TDataset) AfterScroll event will be fired, you can load your images or any other custom data display you have here. To search for a particular record, you use the Locate method of the dataset passing the value from your search edit. if not DataSetName.Locate('name', Edit.Text, [loCaseInsensitive]); then ShowMessage(Edit.Text + ' not found.'); Locate returns true or false so you can check it. If successful the dataset will move to the record, your data aware controls will display the data and the Dataset's AfterScroll event will be called and the images will be loaded. You should post your code with your questions, at least the procedure you are working on.
  20. Gary

    Help with Query at run time

    Yes, I would like to see the data. As Stano said, there is another way to accomplish your objective, always is in Delphi. Using the Query is always better in a Client/Server environment. In your use case your data is local and I don't think with the small amount of data the performance would suffer. It is muck easier in this case to use DB controls and a Table. No SQL at all. You use the Locate method of the DataSet to search for specific items, and that allows you to hook up the navigator and just scroll through the table.
  21. Gary

    Help with Query at run time

    How is all working fine different than compiled?
  22. Gary

    Help with Query at run time

    Couple of things to check. Is the dbEdit field set properly? Are you still using the parameterized query? If so there will only be one record in your dataset, so no records for the navigator to move to, in fact if you are using the parameterized query the navigator is pointless it only works on a set of records.
  23. Gary

    Help with Query at run time

    Use the DataSource DataChange event, (Object Inspector Event tab) put your image loading procedure there. It will be called every time the record changes. Not sure how you get the record number into the edit as it's not a field? You can add code to update a label in the DataChange event also, Label.Caption :='Record Number: " + Query.RecNo.ToString. If you want to get fancy with the names you can try iterating through the records and filling a comboBox with the names. Then use it's on change event to trigger your lookup. Your users will just select from a list (Have fun researching that 🙂 ).
  24. I just got all cross platforms working the other day. XCode had an update today and I think the Simulator was updated to 17.2? Anyway now I can no longer deploy to it. PAServer is working as I can still deploy to MacOS. Anyone else have same problem? Both versions Delphi 11.3 Windows 11 Delphi 12 Windows 11 Virtualbox [PAClient Error] Error: E6664 /Users/sheltons/PAServer/scratch-dir/gshel-MacMini/Project1.launchscreen/Assets: error: The operation couldn’t be completed. Failed to locate any simulator runtime matching options: {[PAClient Error] Error: E6664 BuildVersionString = 21C52; [PAClient Error] Error: E6664 Platforms = ( [PAClient Error] Error: E6664 "com.apple.platform.iphonesimulator" [PAClient Error] Error: E6664 ); [PAClient Error] Error: E6664 VersionString = "17.2"; [PAClient Error] Error: E6664 } [PAClient Error] Error: E6664 Failure Reason: Failed to locate any simulator runtime matching options: { [PAClient Error] Error: E6664 BuildVersionString = 21C52; [PAClient Error] Error: E6664 Platforms = ( [PAClient Error] Error: E6664 "com.apple.platform.iphonesimulator" [PAClient Error] Error: E6664 ); [PAClient Error] Error: E6664 VersionString = "17.2"; [PAClient Error] Error: E6664 }
  25. Gary

    IOS Simulator 17.2 Problem

    @Dave Nottage That did it. Thanks a million! Glad I started here. Not sure what I think of this Mobil development, IDE seems so fragile.
×