Pat Foley
Members-
Content Count
403 -
Joined
-
Last visited
-
Days Won
2
Everything posted by Pat Foley
-
How about low code drap n drop using Delphi IDE and VCL. Drop timage on the form Set the following form properties under F11 Key Color = clMoneyGreen TransparentColor = True TransparentColorValue = clMoneyGreen procedure TForm10.Timer1Timer(Sender: TObject); begin Image1.left := ScreenToClient(Mouse.CursorPos).X - Image1.width div 2; Image1.Top := ScreenToClient(Mouse.CursorPos).Y - Image1.Height div 2; end;
-
Maybe clicking in Projects window is needed.
-
How about mainunit and unit9 listing the DataModule named DM in this example. Button1Click in mainunit calls buildEmailList that has two tables as arguments. Note in button1click the tables used are in DM. in the buildEmaillList procedure only tables passed are used. Button2Click should get you started. π //unit9 //... // TDM = class(TDataModule) // MyTable: TFDMemTable; // emailsTable: TFDMemTable; Uses unit9; procedure TForm8.buildEmailList(SourceTable, EmailTable: TfdmemTable); begin EmailTable.Open; SourceTable.Close; end; procedure TForm8.Button1Click(Sender: TObject); begin buildEmailList(DM.MyTable, DM.emailsTable); end; procedure TForm8.Button2Click(Sender: TObject); var bigtable: TFDMemTable; EmailsNeedtoSend: TFDMemTable; begin bigtable := DM.MyTable; EmailsNeedtoSend := DM.emailsTable; end;
-
Better to use reference... { Once instance is created you use references to it.. procedure TForm5.Button1Click(Sender: TObject); var sourceDM: dm5.TDataModule6; dmLog: TStrings; begin dmLog := sourceDM.dm6log; //or just dmLog := dm5.TDataModule6 ... //in dm5's TDataModule6 has stringlist for logging dm6log: Tstrings;
-
I guess 50% back. The accept cookie text should be another concern on viewing blog. https://blogs.embarcadero.com/ The cookie text reads Clicking on do not sell my personal information returns: "You really want to opt out." Hopefully this is not implicit when using the help. Since I have a subscription they have more personal information to sell.
-
Argument prefixed with vowel should be An if following an English style guide. I would use argArgument here. Since argument is 3 syllable word passing 3 syllable argument names help readability when procedure variables are not 3 syllable. L prefix or scoping would be used to avoid other similar named properties in UI. Like Width or Enabled. Otherwise, L is not needed when arguments are prefixed with 'a' IMHO. Short variable names. Longer Names input a,b,c. Either preface with 'in', arguments allready done with arg. iterator i,j,k Cap per current style. graphic w,h scope with Rect output should be x,y,z; preface with 'out'.
-
More efficient string handling
Pat Foley replied to parallax's topic in Algorithms, Data Structures and Class Design
Not getting how that works? Using streaming appears to help reduce exe growth. // Lifted from Remy L DP post procedure TForm4.Button5Click(Sender: TObject); var //FS: TFileStream; // FS: TBufferedFileStream; //saves a little Reader: TStreamReader; FN, data, s: string; eT, vLinesCounter: Int64; begin et := GetTickCount64; vLinesCounter:= 0; FN := 'C:\2022\2021VAERSData\2021VAERSDATAutf8.csv'; //lactually just changed all (?) to (') 87xxx of the things FS := TBufferedFileStream.Create(FN,fmOpenRead or fmShareDenyWrite); try Reader := TStreamReader.Create(FS); Try while not Reader.EndOfStream do begin StringGrid1.rows[vLinesCounter].StrictDelimiter := True; StringGrid1.rows[vLinesCounter].CommaText := Reader.ReadLine; Inc(vLinesCounter); if vLinesCounter mod 20000 = 0 then caption := vLinesCounter.tostring; end; Finally Reader.Free End; finally FS.Free; end; StringGrid1.rowcount := vLinesCounter + 3; eT := GetTickCount64 - eT; Caption := vLinesCounter.tostring + ' Records loaded to SG in ' + (eT/1000).tostring + ' seconds.'; end; // For viewing cropped text in D procedure TForm4.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin memo1.Lines.Text := StringGrid1.Cells[aCol, aRow]; end; //New L code loads in 7 seconds procedure TForm1.Button3Click(Sender: TObject); var et: int64; begin if OpenDialog1.Execute then FN := OpenDialog1.FileName else exit; et := GetTickCount64; SG.LoadFromCSVFile(FN); et := GetTickCount64 - eT; Memo1.lines.add(eT.tostring); end; -
More efficient string handling
Pat Foley replied to parallax's topic in Algorithms, Data Structures and Class Design
Hey I had D in 32 platform switching up to 64 I able to load all data into StringGrid π You setting SG.rowcount to big Number. Running the L exe the UI hung at 300000 lines but kept going. Running the D64 exe it grew in size albeit slowly. // D10.4.2 code runs 746,xxx in 42 seconds on i5 procedure TForm4.Button4Click(Sender: TObject); var FN: TextFile; Row: Integer; s: string; eT: int64; begin Row := 0; eT := GetTickCount64; AssignFile(FN, 'C:\2022\2021VAERSData\2021VAERSDATA.csv'); Reset(FN); while not Eof(FN) do begin Readln(FN, s); StringGrid1.Rows[Row].StrictDelimiter := True; StringGrid1.Rows[Row].commaText := s; Inc(Row); end; eT := GetTickCount64 - eT; caption :=Row.tostring + 'records loaded in' + eT.ToString + ' Msecs'; end; -
More efficient string handling
Pat Foley replied to parallax's topic in Algorithms, Data Structures and Class Design
//Thanks to Ralph of team B old post function MMFileToString(const AFilename: string): string; var hFile: THandle; hFileMap: THandle; hiSize: DWORD; loSize: DWORD; text: string; view: pointer; begin Result := ''; if AFilename = '' then Exit; if not FileExists(AFilename) then Exit; // Open the file. hFile := CreateFile(PChar(AFilename), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hFile <> INVALID_HANDLE_VALUE then begin loSize := GetFileSize(hFile, @hiSize); // File was opened successfully, now map it: hFileMap := CreateFileMapping(hFile, nil, PAGE_READONLY, hiSize, loSize, 'TextForString'); if (hFileMap <> 0) then begin if (GetLastError() = ERROR_ALREADY_EXISTS) then begin MessageDlg('Mapping already exists - not created.', mtWarning, [mbOk], 0); CloseHandle(hFileMap) end else begin try // File mapped successfully, now // map a view of the file into the address space: view := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); if (view <> nil) then begin // View mapped successfully. CloseHandle(hFile); // Close file handle - as long is view is open it will persist. SetLength(Result, loSize); Move(view^, Result[1], loSize); end else MessageDlg('Unable to map view of file. ' + SysErrorMessage(GetLastError), mtWarning, [mbOk], 0); finally UnmapViewOfFile(view); // Close view; CloseHandle(hFileMap); // Close mapping; end end end else begin MessageDlg('Unable to create file mapping. ' + SysErrorMessage(GetLastError), mtWarning, [mbOk], 0); end; end else begin MessageDlg('Unable to open file. ' + SysErrorMessage(GetLastError), mtWarning, [mbOk], 0); end; end; { TForm1 } //L has procedure TForm1.btnFixDateClick(Sender: TObject); var r, Cutoff: Integer; s: string; begin for r := 0 to sl.count - 1 do begin s := SG.Cells[1,r+1]; Cutoff := length(s)-5; s := '2021/' + copy(s,1,Cutoff ); SG.Cells[1,r+1] := s; end; end; //note need to set strictDelimiter each time. Delphi too. //for losing the " procedure TForm1.btnmapDataSGClick(Sender: TObject); var c,r,i: integer; et: int64; begin et := GetTickCount64; sl := TStringList.Create; sl.Capacity:= 750000; sl.text := MMFileToString('C:\2022\2021VAERSData\2021VAERSDATA.csv'); c := sl.Count; for r := 0 to c -1 do begin SG.Rows[r].StrictDelimiter:= True; SG.rows[r].CommaText := sl[r]; if r mod 5000 = 0 then btnmapDataSG.caption := 'r:' + r.ToString + ' c:' + c.tostring; end; et := GetTickCount64 - et; memo1.lines[0] := format('done loading in %f',[et/1000]); end; //view cropped data in cell with memo. Delphi NA procedure TForm1.SGBeforeSelection(Sender: TObject; aCol, aRow: Integer); begin memo1.text := SG.Cells[aCol,aRow]; end; Above is Lazarus code I was to only load 145000 lines in D or got 'out of memory errors' with bigger files the L exe swells to 3500 when loading the data. It loaded 748,xxx records in the SG in 12.78 seconds. One could cut the file up with Notepad++ or excel Or load a Tarray<recordwith38strings> reading the file in line by line. Making the commatext with arecord do format('%s1,...%38', [s1,..s38]); -
Almost. I use a custom Desktop that hides the side bars and messages across bottom. Just hide the side bars and save desktop. I named mine Startup layout since its used to add controls to the form and see more code when making a new application using <F12> to switch. A side effect is the object inspector gains height when invoked from flyout view or <F11> key. This is in 10.4.2. Above gives about same size view as a second view window.
-
Omni Thread Library resources
Pat Foley replied to David Schwartz's topic in Algorithms, Data Structures and Class Design
These fragments may help.. Jobs: Tlist<TProc>; .... for var job: TProc in Jobs do job(); //TProc(job); //parens help compiler and old VBers to know whats going on. Using dictionary allows using components directly may be of use. //source Remu Lebeau:) https://stackoverflow.com/questions/64145742/cannot-change-tedit-text-in-delphi TtextPair = Tpair<Tcomponent, Tcomponent>; .... Edits: TList<TtextPair>; tp: TtextPair; begin for tp in Edits do begin Edit := TEdit(tp.Key); dLabel := TLabel(tp.Value); var I: NativeInt; for I := 1 to Length(Edit.text) do if ((Edit.text[I] = ' ') and (I <> Edit.tag)) then begin dLabel.Transparent := False; dLabel.Color := clYellow; dLabel.caption := 'gap at pos ' + I.tostring; Edit.tag := I; break; end -
The difference between a mathematician and an engineer is the engineer uses pictures. We use some very abstract concepts to solve efforts and flows using first principles and plot to chart when needed. Process control scheme for brewery or a sewage plant might be source of model to use. The rumen reticulated* could be reduced to flash tank, holding tank, settling tank with vents and reflux. The process variables are moved between tanks and then computed. The variables are made persistent by list of pointers loaded at runtime to use with procedures and save state and used in UI. The ash or minerals passing through helps decide if the stool is sinker or floater. *networked
-
procedure TEventBoss.moveMouse(AC: Tcontrol); const gravity =-9.8;//gravity wind = 17; //West wind derecho force buoyancy = 62; //lbs floated in firken of displaced snowmelt buoyancySteamAir = 18/28; //MW of water/Mw of Air assume water returns as hailStones; //:( XYtolerance = 6; var eX, //MouseXError eY, X, Y: integer;// nativeInt; vtX, vtY: integer;//terminal velocity newMousePT: TPoint; MainF : TControl; begin X := AC.CLientOrigin.X + AC.Width div 2; Y := AC.CLientOrigin.Y + AC.Height div 2; eX := round(0.4 * (x - mouse.CursorPos.X + wind)); eY := round(0.4 * (y - mouse.cursorPos.y - gravity)); vtX := 12 + sign(eX) * wind div 2; vtY := 8 + sign(eY) * trunc(-Gravity) div 2; eX := Min (abs (eX),vtX) * sign(eX); eY := Min (abs (eY),vtY) * sign(eY); newMousePT.X := mouse.CursorPos.x + eX; newMousePT.Y := Mouse.CursorPos.y + eY; mouse.CursorPos := newMousePT; If (abs(eX) + abs(eY)) < XYtolerance then // MN for XYtolerance; moveMousetoInstance := nil; if AC.parent = nil then MainF := AC else if AC.Parent.Parent = nil then MainF := AC.Parent else MainF := AC.Parent.Parent; // following adjusts for the ocean domain // form floats up after "submerging" into water if newMousePT.Y > Screen.Height - buoyancy * 3 then MainF.top := MainF.Top - abs(eY); // following adjusts for the troposphere domain // form floats on denser air if newMousePT.Y < Screen.DesktopTop + round(buoyancySteamAir * 350) then MainF.top := MainF.Top + abs(eY); // form in left ditch pull it out a little each timer event. if newMousePT.X < 0 then MainF.Left := MainF.Left + abs(eX); if newMousePT.X > screen.width then MainF.Left := MainF.Left - abs(eX); end; This code example shows code that moves the mouse to a component on a form when it is opened. When Y is small the form floats in air domain. When Y is big form floats in water domain The example shows how the errors eX and wY, caused by the influence of wind and gravity*, is solved by integrating the error correction over time into mouse path as it moves towards the control. When movemousetoInstance is nil the timer skips the call to movemouse in the timer routine. Chemical tensions could be modeled in your rumen domain. Further setting initial conditions and saved model state would be good allowing the model converge quickly. I thinking about the cruft, would the pH be locally lower with carbonic acid working on what's floating or is it floated by CO2 offgas? * Imaginary use of green energy to power the mouse.
-
The source needs documented as to the sources used for model. If source is based on work of researchers at Public Universities or use reverse engineered patented technology. The documentation helps when other company patents similar technology and puts first company out of business with a Patent suite. The value of program like this could be extended by including ear tag information on each cow which allow better documentation of the pharma given to each animal. Some farmers like the tag program but the packing houses do not. Hopefully a program like this could be used for public good and allow inspection of data by researchers. One example of good technology on dairy cows. The modern milker machine senses exactly when the cow milked out--over milking makes for an unhappy cow. When milk production decreased in an area, researchers found that a modern milker when powered by poorly grounded mains supply would shock the cow.
-
EReadError "Property does not exist"
Pat Foley replied to John Kouraklis's topic in Delphi IDE and APIs
Have you tried a search in Windows Explorer looking for mycontrol.dcu? check the filedatetime of dcu(s) found. Use Projects>build all Projects and see which one recompiles. Next open code window and click on mycontrol in uses cause to open it. then hover over the tab to see the file's path in the hint. Since you have mycontrol open put a breakpoint on Tmycontrol.create and see if it is called. For some reason I need to set Target "Release configuration - ... platform" search path then setting "Value from ""Release...xxx platforms"" needs to have all config path set for each config. directly setting Search path does not take -
How about using a ProjectGroup with multiple dpr/dprojs that share a code base. Just select the project to compile in upper righthand window. Also works when running second IDE. This works fairly well on the VCL side except need different Exe names and only one debug at a time. IDE will prompt when time/date by other IDE. I compiled to an Android and in another IDE compiled a VCL program in the group with the caveat the fmx VCL library didn't load. One Android Studio uses 3.5 gig-why not load a few lithe Delphi IDEs! Added able to load fmx library plus use <ctr> b keys to switch projects!
-
StyleControls: how to single-click 2nd button?
Pat Foley replied to corneliusdavid's topic in Delphi Third-Party
In this example the first click moves the focus to underlying form, then the button on the underlying form can be clicked. It would better to fix the "flow" of the program--have the dropdown drill in with a list selection or escape with a cancel button. -
SudokuHelper - Example for uncoupled design via interfaces
Pat Foley replied to PeterBelow's topic in I made this
Does that mean a push push and remember to pop pop when using Turbo C ? There was a way to connect the buss to a i/o breakout board using the parallel printer port after cutting a few diodes off... To bring it up to 486 spec here's this https://chapmanworld.com/2018/02/09/lockless-multi-threading-in-delphi/- 38 replies
-
- interfaces
- uncoupled design
-
(and 2 more)
Tagged with:
-
Here's a http://delphiforfun.org/programs/oscilloscope.htm program that reads audio from the sound card. The code uses a TP library. It compiles in Laz with a little work. π
-
Where's the RestDebugger fit on your favorite additions to Delphi. Thanks for your DelphiCon presentation on it. We can only assume the Booksmarks are floating off shore on container ship... Hopefully they can unship and ship by Christmas. π
-
showstopper on 10.4.2
-
Class Instance vs Object Instance
Pat Foley replied to bravesofts's topic in Algorithms, Data Structures and Class Design
The previous code I posted was based on Marco's Sydney book comments about changing event assignments at runtime. I think the OP is wanting to use reference. Here is further example procedure TForm30.Button1Click(Sender: TObject); var A: Double; ptrA: PDouble; ptrB: PDouble; ppB: PDouble; pC: PDouble; F, pF: TForm; refF: Tform; begin new(ptrB); //http://rvelthuis.de/articles/articles-pointers.html ptrB^ := 2.02; //initialize value in new instance location ppB := ptrB; // second PDouble get address of first PDouble; Showmessage(ppB^.tostring); A:= 1.01; ptrA := @A; // PDouble given address of double named A showmessage(ptrA^.tostring); pC := ptrB; // Use reference to store pB value; ptrB^ := ptrA^; //overwrite pB with ptrA value ptrA^ := pC^; //overwrite ptrA data showmessage(ptrA^.tostring); // Delphi hides the explicit details of above in VCL // but accessing the properties of components can be done with above. F := TForm.create(self); pF := F; // pF is reference no create needed! pF.Caption := 'EZ PZ'; refF := pF; // refF is a reference refF.Show; Dispose(ptrB); //manual dispose //pF.free; commenting out allows new form each button click! end; -
Class Instance vs Object Instance
Pat Foley replied to bravesofts's topic in Algorithms, Data Structures and Class Design
what happen at runtime when we are declaring some Objects ? i mο»Ώean exactly this Declaration : vObj_Instance: TClass_Type; does this Allocate something in Memory ? or system resources .... No it does not I think you want a reference. Here is example where several forms have created and they may have Comboboxes in them. We use screen to find the forms and component list to find a combobox for the demo. procedure TEventBoss.showComboBoxDropDowns; var I,C: integer; F: TForm; //Ctrl: TControl; //hint need learn about the child lists in here plus Parent prop!// ComboBox: TcomboBox; begin with Screen do begin // access the applications forms here for I := 0 to formCount - 1 do begin F := Forms; // point F to form instance for C := 0 to F.ComponentCount - 1 do if F.Components[C] is TCombobox then begin ComboBox := F.Components[C] as TcomboBox; F.Show; F.BringToFront; ComboBox.Show; The 'found' combo box instance is told to show //how? The ref has its address.// sleep(1200); caption := F.Name; ComboBox.Perform(CB_ShowdropDown,1,0); sleep(1200); ComboBox.Perform(CB_ShowdropDown,0,0); break; end; end; end; end; -
Unsure about class segmentation error. To use the location demo on my phone I need to touch the (..)menu located in in the center of app title. Under 10.2 the menu was on the left. I would try one of the demos or a simple hello world program on the new device to learn what it likes.
-
Just a guess is the new phone setup for allowing debugging/connecting to PC.